0
\$\begingroup\$

As part of my testing, I have to connect to Unix server using putty and execute few unix jobs.

Feature file Steps for test scenario:

Scenario Outline: Job execution in Unix
Given I logged into unix server
When I navigate to job directory "<job_directory_path>" and submit the job "<job>"
Then I validate job run status code
And close the session

Examples: data@jobs.xlsx:jobs
| | | | |

snapshot of excelsheet jobs.xlsx
|jobdirectorypath|jobname|
|/com/home/joblist|QAWAS12|
|/com/home/joblist|QAWAS13|

Step definition file

@Given("^I logged into unix server$")
    public void i_logged_into_unix_server() throws Throwable {
        try{
             Unixcon ucon = new Unixcon.getInstance();
             uc.con_to_unix();
             System.out.println("connected");
           }catch(Exception e){
            e.printStackTrace();
           }
 
    }

    @When("^I navigate to job directory \"([^\"]*)\" and submit the job \"([^\"]*)\"$")
    public void i_navigate_to_job_directory_something_and_submit_the_job_something(String jobdirectorypath, String jobname) throws Throwable {
        try{
             Unixcon ucon = new Unixcon.getInstance();
             uc.execute_job(jobdirectorypath, jobname);
             System.out.println("job executed:"+jobname);
           }catch(Exception e){
            e.printStackTrace();
           }
    }

    @Then("^I validate job run status code$")
    public void i_validate_job_run_status_code() throws Throwable {
        try{
             Unixcon ucon = new Unixcon.getInstance();
             String status_code = String.valueOf(ucon.ch.getExitStatus());
             if(status_code == 0){
             System.out.println("Passed");
             write_to_excel("status",status_code,"Passed");
             }else{
             System.out.println("Failed");
             write_to_excel("status",status_code,"Failed");
   
           }catch(Exception e){
            e.printStackTrace();
           }
    }

    @And("^close the session$")
    public void close_the_session() throws Throwable {
       try{
             Unixcon ucon = new Unixcon.getInstance();
             ucon.close_session();
             System.out.println("closed");
             
           }catch(Exception e){
            e.printStackTrace();
           }

        
    }

Unixcon.JAVA

public class Unixcon{

public JSch jsch =null;
public Session session = nulll;
public Channel ch =null;
String host = TestProperty.getProperty("HOSTNAME");
String username = TestProperty.getProperty("USERNAME");
String password = TestProperty.getProperty("PASSWORD");
int port = TestProperty.getProperty("PORT");

private static Unixcon ucon;

public static Unixcon getInstatnce(){
  if(ucon==null){
  ucon = new Unixcon();
  }
 return ucon;
}

private Unixcon(){
 super();
}

public void con_to_unix(){

try{
jsch = new JSch();
session = jsch.getSession(username,host,port);
session.setpassword(password);
Properties p = new Properties();
p.put("StrictHostKeyChecking", "no");
session.setconfig(p);
session.connect();
}catch(Exception e)
{
e.printStackTrace();
}

}

public void execute_job(String jobdirectorypath, String jobname){
try{
ch = session.OpenChannel("exec");
((ChannelExec) ch).setCommand("cd" + jobdirectorypath +" && ./" + jobname);
ch.connect();
InputStrem in = ch.getInputStream();
BufferedReader r = new BufferedReader(new InputStreamReader(in));
String l = "";
while((l=r.readLine()) != null){
System.out.println(l);
}
}catch(Exception e){
e.printStachTrace();
}
}

public void close_session() {
try{
 if(session != null)
{
ch.disconnect();
session.disconnect();
}catch(Exception e){
e.printStachTrace();
}
}
}

Is my implementation approch correct? Please provide your suggestions for code improvement.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Methods initialise variables called "ucon" then attempt method calls on "uc". If the OP won't present compiled and tested code, why should we review it? \$\endgroup\$ Jun 22 at 12:59
  • 1
    \$\begingroup\$ @dariosicily Only the OP is allowed to edit the code in the question. As such I have rolled back your edit. \$\endgroup\$
    – Peilonrayz
    Jun 27 at 20:28
  • \$\begingroup\$ @Peilonrayz Thank you for your help and explanation. \$\endgroup\$ Jun 28 at 5:33
3
+25
\$\begingroup\$

Is my implementation approch correct?

You mean, your implementation of Unixcon.JAVA ? Then if it works as expected it may be correct but I doubt because there are some typos and invalid syntax in your code:

Strange errors

(that looks like you have not done your homework)

  • The test do a new Unixcon.getInstance(). Which is invalid because

    1. The constructor is private, so you cannot create any instance outside of the class.
    2. There are no parentheses in your constructor

    -> If you want to call a static method, you should do Unixcon.getInstance()

  • The test use getInstance() while your class declare getInstatnce()

    -> Align your names, compile and test your code before posting it.

  • Missing brackets, the if in close_session has an unbalanced bracket.

Anyway, there are some possible improvements:

Singleton

  • Your Unixcon is a singleton this means that you cannot run two processes in parallel without running in troubles.
  • Your singleton may not be unique; there are many articles explaining how to get one unique instance.

Naming

  • Java use lowerCamelCase for methods names. Rename to conToUnix, executeJob, etc...

OO Design

  • Use encapsulation to hide the implementation details. Don't expose Channel ch but provide an accessor to getExitStatus()

  • Pass the TestProperty so that you can easily connect to another host or use another means to get those values.

That's a personal opinion, but what about having a non singleton connection object that return a JobExecution when you run a job ?

/* Allow many instances and use an ssh style connection string 
 * to clarify your code. But keep another constructor that takes
 * all parameters independently.
 *
 * The UnixConnection implements AutoCloseable for a simpler code
 */  
try(UnixConnection connection = new UnixConnection("user@hostname:port", password)) {         
  JobExecution result = connection.execute("jobname", inDirectory);
  /* isSuccessful is a simple test on the exit status, but clarify 
   * the intention much more than `== 0`. 
   * Alternatively you may want to throw a `JobExceutionError` 
   * instead of playing with a status. */
  if ( result.isSuccessful() ) {
    result.getJobName();
    result.getStatus();
    result.getOutputStream(); // Or a String or an Collection/Stream/Iterable<String>
  }
} 
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.