Forum Discussion

ramaG's avatar
ramaG
Contributor
4 years ago
Solved

Is there a script to launch WinSCP from ReadyAPI and navigate to the appropriate server logfile path

As part of our E2E testing we need to validate application logfiles on our application servers and also need to verify the same information retrieved from the browser based app/utility. Once ou...
  • TNeuschwanger's avatar
    4 years ago

    Hello ramaG,

     

    I don't have a WinSCP specific script, but I have used jsch library to access server and retrieve a log file (or execute a command on a server).  Below is sample code to be hacked up and use what you can (file transfer or execute remote command).

     

    I think it is hard to get over to a server and then start issuing commands unless you code a script on the remote server and execute it.  I found it easier just to download entire log file and process it locally than to robot through on the server where the logs reside.  Our log files are sometimes very large and are rolled over when they hit a certain size.  This technique has worked for me even though there were millions of records in the log file.  Depending on how large your log files are and how long you are willing to wait for a file transfer will determine if this technique works for you. 

     

    The jsch library will need to be obtained from "http://www.jcraft.com/jsch/" since it is not included with SoapUI (maybe these days it is but current free version does not include it).  I love this helper library and has saved me from a lot of trouble in the past. 

     

    Groovy Script Common Get File Transfer:

    import java.text.SimpleDateFormat;
    import com.jcraft.jsch.*;
    
    def readProperty(sName, pS) {
       def step = testRunner.testCase.getTestStepByName(sName);
       def propertyStr = step.getPropertyValue( pS );
       return propertyStr;
    };
    
    def writeProperty(sName, pS, pV) {
       def step = testRunner.testCase.getTestStepByName(sName);
       def propertyStr = step.setPropertyValue( pS, pV );
       return true;
    };
    
    def determinLocalOS() {   // Determine Operating System function.  Purpose is to define if this script is running locally on Windows or Linux
       def homeProp = System.getProperty("user.home");  //log.info "homeProp: " + homeProp;
       def localRtn = homeProp.contains("\\");   //log.info "localOS: " + localOS;
       return localRtn;  // boolean...  Windows = true, other = false
    };
    
    def fileTransfer(cmd, uId, svr, fileF, fileT) {   // File Transfer function.  Purpose is to execute a file transfer using the input parameters.
       def sout = new StringBuffer()
       def serr = new StringBuffer()
       log.info "CommandHarness: " + cmd;
       log.info "UserId: " + uId;
       log.info "Server: " + svr;
       log.info "FileFrom: " + fileF;
       log.info "FileTo: " + fileT;
       def cmdExecute = [cmd, uId, svr, fileF, fileT];  //
       log.info "cmdExecute: " + cmdExecute;   
       Process x = cmdExecute.execute();   // 
       x.consumeProcessOutput(sout, serr);    //  #### IMPORTANT #### This line must be here or the file transfer using PSFTP on Windows will not work for servers uslcappp03 and uslcappp04.
       x.waitFor();
       log.info "x=${x.text}";
       log.info 'sout: ' + sout;
       log.info 'serr: ' + serr;
       return "code: ${ x.exitValue()}";
    };
    
    def Session session;
    def Channel channel;
    def ChannelSftp channelSftp;
    def JSch jsch;
    
    //=========================================================================================================================================
    
    def connect(String hostName, String userName, String passCode) {
       try {
          jsch = new JSch();
          session = jsch.getSession( userName, hostName, 22 );
          session.setPassword(passCode);
          session.setTimeout(3000);
          java.util.Properties config = new java.util.Properties();
          config.put("StrictHostKeyChecking", "no");
          session.setConfig(config);
          session.connect();
          if (session.isConnected) {
             channel = session.openChannel("sftp");
             channel.connect();
             channelSftp = ( ChannelSftp ) channel;
             log.info 'Connected to: ' + hostName;
          }
       }
       catch (JSchException e) {
          log.error e.toString();
       };
    };
    
    def changeDirectory( String remotePath ) {
       try {
          log.info 'Path before ChangeDirectory is: ' + getPath();
          channelSftp.cd( remotePath );
          log.info 'Path after ChangeDirectory is: ' + getPath();
       }
       catch( Exception e ) {
          disconnect();
          log.error e.toString();
       };
    };
    
    def disconnect() {
       channelSftp.quit();
       channelSftp.disconnect();
       channel.disconnect();
       session.disconnect();
       log.info "Disconnected";
    };
    
    def boolean isConnected() {
       return session == null ? false : session.isConnected();
    };
    
    def String getPath() {
       return channelSftp.pwd()+"/";
    };
    
    def String getList(String remotePath) {
       osList = channelSftp.lstat(remotePath)+"/";
       return osList;
    };
    
    def getStat(String remotePath) {
       return channelSftp.lstat(remotePath);
    };
    
    def getFile(String rFQFN, String lFQFN) {
       log.info 'Fully qualified file name on remote server: ' + rFQFN;
       log.info 'Fully qualified file name on local computer: ' + lFQFN;
       channelSftp.get(rFQFN, lFQFN);
    };
    
    
    //=========================================================================================================================================
    
    log.info "";
    log.info 'Test Step "Groovy Script Common Get File Transfer" Begin';
    
    def remoteHost = readProperty("PropertiesRemote", "remoteLogHostPrefix") + readProperty("PropertiesRemote", "remoteLogHostIndex");  //
    def remoteUser = readProperty("PropertiesRemote", "remoteUser");
    def remotePassword = readProperty("PropertiesRemote", "remotePassword");
    def remotePath = readProperty("PropertiesRemote", "remotePath");
    def workFileName = readProperty("PropertiesRemote", "workFileName");
    def tmpDirStr = readProperty("PropertiesRemote", "tmpDirStr");
    
    def remotePathFileName = workFileName;  //
    log.info "remotePathFileName: " + remotePathFileName;
    
    def localPathFileName = tmpDirStr + workFileName;  //
    log.info "localPathFileName: " + localPathFileName;
    
    dateTimeFileStamp = new SimpleDateFormat ( "yyyy-MM-dd hh-mm-ss a" );
    dtStr = dateTimeFileStamp.format(new Date());
    
    if (determinLocalOS()) {    // boolean...  Windows = true, other = false
    //log.info "remoteHost: " + remoteHost;
    //log.info "remoteUser: " + remoteUser;
    //log.info "remotePassword: " + remotePassword;
       connect (remoteHost, remoteUser, remotePassword);
       if (isConnected()) {
          getFile(remotePathFileName, localPathFileName);
          getFile(remotePathFileName, localPathFileName + dtStr + '.txt');   // helpful for local debugging if ran multiple times.
          disconnect();
       }
       else {
          log.info 'Connection failed to: ' + remoteHost;
       };
    }
    else {
       log.info 'return code=' + fileTransfer('/usr/pservices/hudson_home/filecopy_remote2local.sh', 'webopt', remoteHost, remotePathFileName, localPathFileName);
    };
    
    log.info 'Test Step "Groovy Script Common Get File Transfer" End';
    log.info "";

     Groovy Script Common Command Execute:

    import com.jcraft.jsch.*;
    
    def readProperty(sName, pS) {
       def step = testRunner.testCase.getTestStepByName(sName);
       def propertyStr = step.getPropertyValue( pS );
       return propertyStr;
    };
    
    def writeProperty(sName, pS, pV) {
       def step = testRunner.testCase.getTestStepByName(sName);
       def propertyStr = step.setPropertyValue( pS, pV );
       return true;
    };
    
    def determinLocalOS() {   // Determine Operating System function.  Purpose is to define if this script is running locally on Windows or Linux
       def homeProp = System.getProperty("user.home");  //log.info "homeProp: " + homeProp;
       def localRtn = homeProp.contains("\\");   //log.info "localOS: " + localOS;
       return localRtn;  // boolean...  Windows = true, other = false
    };
    
    def fileExecute(cmd, uId, svr, exeCmd) {   // Command Execution function.  Purpose is to execute command on a remote server.
       def sout = new StringBuffer();
       def serr = new StringBuffer();
       log.info "CommandHarness: " + cmd;
       log.info "UserId: " + uId;
       log.info "Server: " + svr;
       log.info "Executable: " + exeCmd;
       def cmdExecute = [cmd, uId, svr, exeCmd];  //
       log.info "cmdExecute: " + cmdExecute;
       Process x = cmdExecute.execute();   //
       x.consumeProcessOutput(sout, serr);
       x.waitFor();
       log.info "x=${x.text}";
       log.info 'sout: ' + sout;
       log.info 'serr: ' + serr;
       return "code: ${ x.exitValue()}";
    };
    
    def WaitTimeSeconds(wT) {
       log.info 'wait time (seconds) = ' + wT;
       wT = wT * 1000;  // Convert seconds to milliseconds for use in commands
       done = false;
       new Thread({ sleep(wT) ; done = true }).start();
       for (count = 0; !done; ++count) {  //      log.info "Here! ${count}"
          sleep(1000);
       };  //log.info 'wT = ' + wT;
       return true;
    };
    
    def Session session;
    def Channel channel;
    def Integer executeCommand(String hostName, String userName, String passCode, String cmd) {
       log.info 'command to execute =>' + cmd + '<';
       def commandNotFinished = -1;   // -1 is returned by jsch while the command is running
       def rslt = commandNotFinished;
       try {
          def jsch = new JSch();
          session = jsch.getSession(userName, hostName, 22);
          session.setPassword(passCode);
          session.setTimeout(5000);
          java.util.Properties config = new java.util.Properties();
          config.put("StrictHostKeyChecking", "no");
          session.setConfig(config);
          session.connect();
          if (session.isConnected) {
             channel = session.openChannel("exec");
             ((ChannelExec) channel).setCommand(cmd);
             channel.connect();
             while (channel.getExitStatus() == commandNotFinished) {
                //log.info channel.getExitStatus();
                WaitTimeSeconds(2);
             };
             rslt = channel.getExitStatus().toInteger();    //log.info channel.getExitStatus();
             //log.info 'about to disconnect channel';
             channel.disconnect();
             //log.info 'about to disconnect session';
             session.disconnect();
          };
       }
       catch(Exception ex) {
          log.error "Command Execute Error: " + ex;
          if (ex.toString().contains('Auth fail')) {
             // skip the remaining test steps.  If we have a bad password, we don't want to lock out the account for some reason...
             writeProperty("PropertiesRemote", "remotePassword", '');         
             testRunner.gotoStepByName( "Groovy Script Clean Password");
          }
       };
       return rslt;
    };
    
    
    //=========================================================================================================================================
    
    log.info "";
    log.info 'Test Step "Groovy Script Common Command Execute" Begin';
    
    def remoteHost = readProperty("PropertiesRemote", "remoteLogHostPrefix") + readProperty("PropertiesRemote", "remoteLogHostIndex");  //
    log.info 'remoteHost = ' + remoteHost;
    def remoteUser = readProperty("PropertiesRemote", "remoteUser"); //log.info 'remoteUser = ' + remoteUser;
    def remotePassword = readProperty("PropertiesRemote", "remotePassword"); //log.info 'remotePassword = ' + remotePassword;
    def remoteCommand = readProperty("PropertiesRemote", "remoteCommand");
    
    if (determinLocalOS()) {    // boolean...  Windows = true, other = false
       returnCode = executeCommand(remoteHost, remoteUser, remotePassword, remoteCommand);
       log.info 'return code=' + returnCode;
       assert (returnCode == 0), "Return code from command should be zero";
    }
    else {
       log.info 'return code=' + fileExecute('/usr/pservices/hudson_home/file_execute_on_remote.sh', 'webopt', remoteHost, remoteCommand);
    };
    
    log.info 'Test Step "Groovy Script Common Command Execute" End';
    log.info "";