Exemple de code

Cet exemple de bloc de code implémente le type de test de l'exécuteur de processus, lequel peut être utilisé pour lancer un fichier exécutable et étendre la classe ExtProcessTestLaunchBean publiée.

package com.borland.sctm.testlauncher;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import com.segue.tm.published.api.testlaunch.ExtProcessTestLaunchBean;
import com.segue.tm.published.api.testlaunch.TestLaunchResultDrain;

/**
 * Implements an Silk Central test type that can be used to launch
 * any executables, for example from a command line.
 * Extends Silk Central published process test launcher class,
 * see Silk Central API Specification (in Help -> Documentation) for
 * further details.
 */
public class ProcessExecutor extends ExtProcessTestLaunchBean {

  // test properties that will be set by Silk Central using appropriate setter 
  // methods (bean convention), 
  // property names must conform to property tags used in the XML file
  
  /**
   * Represents property <command> defined in ProcessExecutor.xml.
   */
  private String command;
  
  /**
   * Represents property <arguments> defined in ProcessExecutor.xml.
   */
  private String arguments;
  
  /**
   * Represents property <workingfolder> defined in ProcessExecutor.xml.
   */
  private String workingfolder;
  
  /**
   * Java Bean compliant setter used by Silk Central to forward the command to be
   * executed.
   * Conforms to property <command> defined in ProcessExecutor.xml.
   */
  public void setCommand(String command) {
    this.command = command;
  }

  /**
   * Java Bean compliant setter used by Silk Central to forward the arguments
   * that will be passed to the command.
   * Conforms to property <arguments> defined in ProcessExecutor.xml.
   */
  public void setArguments(String arguments) {
    this.arguments = arguments;
  }

  /**
   * Java Bean compliant setter used by Silk Central to forward the working
   * folder where the command will be executed.
   * Conforms to property <workingfolder> defined in
   * ProcessExecutor.xml.
   */
  public void setWorkingfolder(String workingfolder) {
    this.workingfolder = workingfolder;
  }

  /**
   * Main plug-in method. See Silk Central API Specification
   * (in Help &gt; Documentation) for further details.
   */
  @Override
  public boolean execute(long time, TestLaunchResultDrain context)
    throws InterruptedException {
    try {
      String[] cmd = getCommandArgs(context);
      File workingDir = getWorkingFolderFile(context);
      String[] envVariables = getEnviromentVariables(context);
      
      int processExitCode = runExternalProcess(cmd, envVariables, workingDir,
        context.getLog());      

      boolean outputXmlFound = handleOutputXmlIfExists(context); 
      
      if (! outputXmlFound && processExitCode != 0) { 
        // if no output.xml file was produced, the exit code indicates
        // success or failure
        context.publishMessage(TestLaunchResultDrain.SEVERITY_ERROR,
          "Process exited with return code "
          + String.valueOf(processExitCode));
        context.updateErrors(1, 0);
        // set error, test will get status 'failed'
      }
    } catch (IOException e) {
      // prints exception message to Messages tab in Test Run
      // Results
      context.publishMessage(TestLaunchResultDrain.SEVERITY_FATAL,
        e.getMessage());
      // prints exception stack trace to 'log.txt' that can be viewed in Files
      // tab
      e.printStackTrace(context.getLog());
      context.publishErrors(1, 0);
      return false; // set test status to 'not executed'
    }
    return true; 
  }

  /**
   * Initializes environment variables to be set additionally to those 
   * inherited from the system environment of the Execution Server.
   * @param context the test execution context
   * @return String array containing the set environment variables
   * @throws IOException
   */
  private String[] getEnviromentVariables(TestLaunchResultDrain context)
    throws IOException {
    String[] envVariables = {
      "SCTM_EXEC_RESULTSFOLDER="
      + context.getTempResultsDir().getAbsolutePath(),
      "SCTM_EXEC_SOURCESFOLDER="
      + sourceAccess().getTestContainerRootDir().getAbsolutePath(),
    };
    return envVariables;
  }

  /**
   * Let Silk Central parse the standard report xml file (output.xml) if exists.
   * See also Silk Central Web Help - Creating a Test Package. A XSD file
   * can be found in Silk Central Help -&gt; Tools -&gt; Test Package XML Schema
   * Definition File
   * @param context the test execution context
   * @return true if output.xml exists
   * @throws IOException
   */
  private boolean handleOutputXmlIfExists(TestLaunchResultDrain context)
    throws IOException {
    String outputFileName = context.getTempResultsDir().getAbsolutePath()
    + File.separator + TestLaunchResultDrain.OUTPUT_XML_RESULT_FILE;
    File outputfile = new File(outputFileName);
    boolean outputXmlExists = outputfile.exists();
    if (outputXmlExists) {
      context.parseStdResultFile(outputfile);
      context.publishMessage(TestLaunchResultDrain.SEVERITY_INFO, 
        String.format("output.xml parsed from '%s'", outputFileName));
    }
    return outputXmlExists;
  }

  /**
   * Retrieves the working folder on the Execution Server. If not configured
   * the results directory is used as working folder.
   * @param context the test execution context 
   * @return the working folder file object
   * @throws IOException
   */
  private File getWorkingFolderFile(TestLaunchResultDrain context)
    throws IOException {
    final File workingFolderFile;
    if (workingfolder != null) {
      workingFolderFile = new File(workingfolder);
    } else {
      workingFolderFile = context.getTempResultsDir();
    }
    context.publishMessage(TestLaunchResultDrain.SEVERITY_INFO,
      String.format("process is exectued in working folder '%s'",
        workingFolderFile.getAbsolutePath()));
    return workingFolderFile;
  }

  /**
   * Retrieves the command line arguments specified.
   * @param context the test execution context
   * @return an array of command line arguments 
   */
  private String[] getCommandArgs(TestLaunchResultDrain context) {
    final ArrayList<String> cmdList = new ArrayList<String>();
    final StringBuilder cmd = new StringBuilder();
    cmdList.add(command);
    cmd.append(command);
    if (arguments != null) {
      String[] lines = arguments.split("[\\r\\n]+");
      for (String line : lines) {
        cmdList.add(line);
        cmd.append(" ").append(line);
      }
    }
    context.publishMessage(TestLaunchResultDrain.SEVERITY_INFO,
      String.format("executed command '%s'", cmd.toString()));
    context.getLog().printf("start '%s'%n", cmd.toString());
    return (String[]) cmdList.toArray(new String[cmdList.size()]);
  }
}