/* +----------------------------------------------------------------------+ | Class: CLauncher | | | | Developper: Eric Gavaldo (eric.gavaldo@xqual.com) | | Version: 1.4 | +----------------------------------------------------------------------+ */ package com.xqual.xlauncher.nunit; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.Vector; import com.xqual.xagent.launcher.CExecutionStep; import com.xqual.xagent.launcher.CLauncher; import com.xqual.xagent.launcher.CParamParsingException; import com.xqual.xagent.launcher.CReturnStatus; import com.xqual.xagent.launcher.runner.CRunner; import com.xqual.xagent.launcher.runner.IRunner; import com.xqual.xcommon.CAttribute; import com.xqual.xcommon.IConstantsResults; import com.xqual.xcommon.utils.CFileUtils; import com.xqual.xcommon.utils.CUtils; /** * The CLauncherImpl implementation of ILauncher for NUnit. * @author egavaldo */ public class CLauncherImpl extends CLauncher implements IConstantsResults { // +==============================================================+ // | Attributes | // +==============================================================+ static final String TRACE_HEADER = "{nunit } "; // parameters impacting executing at run time set by the test operator private String testRootPath; private String dotNetVersion; private String assemblyName; private String nunitConsolePath; private String nunitInterpreter; private File workingDir; private static final String NUNIT_CONSOLE_RUNNER = CUtils.getExecutableName("nunit-console"); // +==============================================================+ // | Constructors | // +==============================================================+ public CLauncherImpl() { super(TRACE_HEADER); } // +==============================================================+ // | Methods | // +==============================================================+ @Override public CReturnStatus initialize(int sutId, String sutName, String sutVersion) { setSutDetails(sutId, sutName, sutVersion); setDefaultTestcaseMustBeCreated(true); // if there is not testcase, let the systems create a default one // check the configuration sent by the manager printConfiguration(); Vector executionSteps = new Vector(); try { // retrieve the parameters we need // section related to the SUT, independant from NUnit testRootPath = getStringParamValue("General", "Test root path"); // i.e. C:/Program Files/NUnit 2.5.2/bin/net-2.0/tests assemblyName = getStringParamValue("General", "Assembly dll"); // i.e. nutil.util.tests.dll // section related to NUnit dotNetVersion = getStringParamValue("NUnit", ".NET version"); // i.e. 2.0 nunitConsolePath = getStringParamValue("NUnit", "NUnit console path"); // i.e. C:/Program Files/NUnit 2.5.2 nunitInterpreter = nunitConsolePath + "/bin/net-" + dotNetVersion + "/" + NUNIT_CONSOLE_RUNNER; } catch (CParamParsingException e) { traceln(LOG_PRIORITY_SEVERE, "parsing error during initialization"); executionSteps.add(new CExecutionStep(RESULT_FAILURE, "Exception during initialize: " + e.getMessage())); return new CReturnStatus(RESULT_FAILURE, executionSteps); } return new CReturnStatus(RESULT_SUCCESS, executionSteps); } @Override public CReturnStatus preRun(int testId, String testPath, String testName, Vector attributes, String additionalInfo) { traceln(LOG_PRIORITY_INFO, "preRun testId=" + testId + " testPath=" + testPath + " [" + testName + "]..."); Vector executionSteps = new Vector(); return new CReturnStatus(RESULT_SUCCESS, executionSteps); } @Override public CReturnStatus run(int testId, String testPath, String testName, int testcaseIndex, String testcaseName, String additionalInfo) { traceln(LOG_PRIORITY_INFO, "run testId=" + testId + " testPath=" + testRootPath + "/" + testPath + "/" + testName + " testcaseIndex=" + testcaseIndex + "..."); Vector executionSteps = new Vector(); workingDir = new File(testRootPath); // +------------------------------------+ // | Interpret the script // +------------------------------------+ File nUnitTraceFile = new File("nunit_traces.txt"); if (nUnitTraceFile.exists()) nUnitTraceFile.delete(); try { nUnitTraceFile.createNewFile(); } catch (IOException e) { traceln(LOG_PRIORITY_SEVERE, "Could not create file \"nunit_traces.txt\"..."); } // +------------------------------------+ // | Run the NUnit test class // +------------------------------------+ // "C:/Program Files/NUnit 2.5.2/bin/net-2.0/nunit-console.exe" /run:NUnit.Util.Tests.TestAgencyTests "C:/Program Files/NUnit 2.5.2/bin/net-2.0/tests/nunit.util.tests.dll" // <------------------- nunitInterpreter --------------------> <-- testPath --> <-- testName -> <------------------ testRootPath -------------> <-- assemblyName --> // TODO: use the xml report instead of parsing the console CRunner junitRunner = new CRunner("[" + testId + "] "+ testPath + "." + testName, CFileUtils.quoteFilePath(nunitInterpreter) + " " + "/run:" + testPath + "." + testName + " " + CFileUtils.quoteFilePath(testRootPath + "/" + assemblyName), workingDir); // here we redirect the output to a file for later parsing short result = junitRunner.requestAction(IRunner.START_PROCESS, IRunner.WAIT_END_OF_EXECUTION, nUnitTraceFile); // +------------------------------------+ // | Add the output console to the test // +------------------------------------+ addAttachment(nUnitTraceFile); if (result == RESULT_FAILURE) { executionSteps.add(new CExecutionStep(RESULT_FAILURE, "execution process failed")); parseResultFile(executionSteps); // to have the details anyway return new CReturnStatus(RESULT_FAILURE, executionSteps); } else { executionSteps.add(new CExecutionStep(RESULT_SUCCESS, "execution process succeeded")); return parseResultFile(executionSteps); } } @Override public CReturnStatus postRun(int testId, String testPath, String testName) { traceln(LOG_PRIORITY_INFO, "postRun testId=" + testId + " testPath=" + testPath + ":" + testName + "..."); Vector executionSteps = new Vector(); executionSteps.add(new CExecutionStep(RESULT_SUCCESS, "postRun: succeeded")); return new CReturnStatus(RESULT_SUCCESS, executionSteps); } @Override public CReturnStatus terminate() { Vector executionSteps = new Vector(); executionSteps.add(new CExecutionStep(RESULT_SUCCESS, "Terminate")); return new CReturnStatus(RESULT_SUCCESS, executionSteps); } // +--------------------------+ // ¦ Utilities ¦ // +--------------------------+ private CReturnStatus parseResultFile(Vector executionSteps) { // parse the result file to get the result and the execution steps File resultFile = new File("nunit_traces.txt"); if (!resultFile.exists()) { traceln(LOG_PRIORITY_SEVERE, "Result file not found!"); executionSteps.add(new CExecutionStep(RESULT_FAILURE, "run: result file not found!")); return new CReturnStatus(RESULT_FAILURE, executionSteps); } else { executionSteps.add(new CExecutionStep(RESULT_SUCCESS, "run: result file found")); } String line; boolean errorDetected = false; boolean notRunDetected = false; try { FileInputStream fileInputStream = new FileInputStream(resultFile); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream)); while ((line = bufferedReader.readLine()) != null) { line = line.trim(); System.out.println(">" + line); if (line.startsWith("Tests run:")) { String[] array = line.split(","); int errorCount = getCountFromBuffer(array[1]); int failureCount = getCountFromBuffer(array[2]); int inconclusiveCount = getCountFromBuffer(array[3]); executionSteps.add(new CExecutionStep(errorCount > 0 ? RESULT_FAILURE: RESULT_SUCCESS, "errorCount: " + errorCount)); executionSteps.add(new CExecutionStep(failureCount > 0 ? RESULT_FAILURE: RESULT_SUCCESS, "failureCount: " + failureCount)); executionSteps.add(new CExecutionStep(RESULT_UNKNOWN, "inconclusiveCount: " + inconclusiveCount)); if (errorCount+failureCount+inconclusiveCount > 0) { executionSteps.add(new CExecutionStep(RESULT_FAILURE, line)); errorDetected = true; } else { executionSteps.add(new CExecutionStep(RESULT_SUCCESS, line)); } } else if (line.startsWith(" Not run:")) { String[] array = line.split(","); int notRunCount = getCountFromBuffer(array[0]); executionSteps.add(new CExecutionStep(RESULT_UNKNOWN, "notRunCount: " + notRunCount)); if (notRunCount > 0) { executionSteps.add(new CExecutionStep(RESULT_UNKNOWN, line)); notRunDetected = true; } else { executionSteps.add(new CExecutionStep(RESULT_SUCCESS, line)); } } else { //traceln(LOG_PRIORITY_SEVERE, "unknown tag!"); } } } catch (Exception e) { traceln(LOG_PRIORITY_SEVERE, "exception whle parsing the result file: " + e); executionSteps.add(new CExecutionStep(RESULT_FAILURE, "Exception while parsing the result file: " + e)); errorDetected = true; } if (errorDetected) { return new CReturnStatus(RESULT_FAILURE, executionSteps); } else if (notRunDetected) { return new CReturnStatus(RESULT_UNKNOWN, executionSteps); } else{ return new CReturnStatus(RESULT_SUCCESS, executionSteps); } } private int getCountFromBuffer(String input) { String[] array = input.split(":"); return Integer.parseInt(array[1].trim()); } }