/*
+----------------------------------------------------------------------+
| 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());
}
}