ATS : Running external process

The ATS ProcessExecutor class allows you to run a local or remote external process(for example some shell command) and analyze the output

 


Have some external process to run

You should try with your own external process, but for the examples on this page we will use the following simple bat file.

The content of the bat file is:

@ECHO OFF

ECHO info line one
ECHO error line one 1>&2

ECHO info line two
ECHO error line two 1>&2

ECHO info line three

The file path is "C:/Temp/test.bat". It basically sends few lines of code to the standard output and the error output



Example run

Here is our test code:

@Test
public void runExternalProcess() throws Exception {

    // in the constructor, provide the external process that will be run and optionally some arguments
    ProcessExecutor processExecutor = new ProcessExecutor( "test.bat" );

    // execute the external process and wait for its completion
    processExecutor.execute();
 }

If the commands has arguments, there are two ways to achieve it.

// with auto parsing of the command line arguments
ProcessExecutor processExecutor = new ProcessExecutor( "ls -la /tmp" );

// OR command arguments specified in a String array
ProcessExecutor processExecutor = new ProcessExecutor( "ls", new String[]{ "-la", "/tmp" } );

Now unfortunately we get some unpleasant surprise. The external process is not started and an error is logged which says:

Cannot run program "test.bat": CreateProcess error=2, The system cannot find the file specified

The problem comes from the fact that running an external process using the Process Executor is not the same as running a shell command.
When a shell console is started, it has some options set. For example it may have some options which tell the operating system where to search for the targeted applications, thus from the console window you may not need to specify the full path to the executed application.

In order to fix the current problem, you have to simply specify the full path to the application to start:

ProcessExecutor processExecutor = new ProcessExecutor( "C:\\Temp\\test.bat" );

or you can run the command in cmd or bash:

// you need to wrap the command in ' or " (only when you use the constructors without separated arguments array)
ProcessExecutor processExecutor = new ProcessExecutor( "cmd /C 'dir C:/Temp/'" );
// but if you need quotes for some internal argument, you can use ' for command wrapping and " for its arguments
ProcessExecutor processExecutor = new ProcessExecutor( "cmd /C 'dir \"C:/Program Files/\"'" );

// in bash
ProcessExecutor processExecutor = new ProcessExecutor( "/bin/bash -c 'ls -la /tmp | grep .log'" );

// or using the other constructors
ProcessExecutor processExecutor = new ProcessExecutor( "/bin/bash", new String[]{ "-c", "ls -la /tmp | grep .log" } );
ProcessExecutor processExecutor = new ProcessExecutor( "cmd", new String[]{ "/C", "dir \"C:/Program Files/\"" } );

In some cases you should strictly separate each parameter into separate String element of the array with command parameters

 


Evaluating the process execution

Almost always you will need to examine the process execution output in order to verify if it was all successful.
Or sometimes you may want to extract some data from the output and use this data in the next test steps.

For such cases you need to get the execution output:

// after the completion of the process you can call some of the following methods:

// get the process outputs(Standard and Error)
String standardOutputText = processExecutor.getStandardOutput( );
String errorOutputText = processExecutor.getErrorOutput( );
// these methods are blocking until the command completes and the STDOUT and STDERR streams are read

// if you want to get the current process outputs you can use these methods
processExecutor.getCurrentStandardOutput( );
processExecutor.getCurrentErrorOutput( );

// and to check for stream read finished with:
processExecutor.isStandardOutputFullyRead()
processExecutor.isErrorOutputFullyRead()

 


Monitoring the process execution

Some processes take significant amount of time to execute. In such cases you want to have an idea how it is going. Here are your options:

// prior to running the process you can call some of the following methods:

// route the process outputs(Standard and Error) to some local files
processExecutor.setStandardOutputFile( "C:/Temp/standard.log" );
processExecutor.setErrorOutputFile( "C:/Temp/error.log" );

// route the process outputs(Standard and Error) to the logging database
processExecutor.setLogErrorOutput( true );
processExecutor.setLogStandardOutput( true );

Each of these lines can be used separately and it gives a real time view on the process output.

 


Do something else while the external process is running

There are cases where while the process is running in background, you want to continue with some other test steps. Here is how to do it:

// start the external process, but do not wait for its completion
processExecutor.execute( false );

 


Other useful methods

You can check the other easy to use methods of this class like:

  • get exit code
  • get/set environment variables
  • kill the started process with/without its children

 


Back to parent page

Go to Table of Contents