summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEndi Sukma Dewata <edewata@redhat.com>2011-12-01 01:13:26 -0600
committerEndi S. Dewata <edewata@redhat.com>2011-12-05 19:40:45 +0000
commit343a8af9f302fbdcc183db88676e5a281641208f (patch)
treefb47a9b29a4fadc219e54e9747b4e9097b90cce7
parentd325f2de0e5c3c5f4f3d690cc571c11f178d7212 (diff)
downloadpki-343a8af9f302fbdcc183db88676e5a281641208f.tar.gz
pki-343a8af9f302fbdcc183db88676e5a281641208f.tar.xz
pki-343a8af9f302fbdcc183db88676e5a281641208f.zip
Added JUnit report generator.
A custom JUnit test runner has been added to capture test results and generate XML reports. Ticket #36
-rw-r--r--pki/base/common/test/CMakeLists.txt11
-rw-r--r--pki/base/common/test/com/netscape/test/TestListener.java233
-rw-r--r--pki/base/common/test/com/netscape/test/TestRunner.java23
-rw-r--r--pki/cmake/Modules/JUnit.cmake22
4 files changed, 283 insertions, 6 deletions
diff --git a/pki/base/common/test/CMakeLists.txt b/pki/base/common/test/CMakeLists.txt
index 4f3ebf7b..8618bd02 100644
--- a/pki/base/common/test/CMakeLists.txt
+++ b/pki/base/common/test/CMakeLists.txt
@@ -51,6 +51,8 @@ set(pki-common-test_SRCS
com/netscape/cmscore/request/RequestTest.java
com/netscape/cmscore/test/CMSBaseTestCase.java
com/netscape/cmscore/test/TestHelper.java
+ com/netscape/test/TestListener.java
+ com/netscape/test/TestRunner.java
)
set(CMAKE_JAVA_INCLUDE_PATH
@@ -64,6 +66,7 @@ set(CMAKE_JAVA_TARGET_VERSION ${APPLICATION_VERSION})
# build test jar file
# TODO: create CMake function to compile without building jar file
+# TODO: build test only when the test is invoked
set(CMAKE_JAR_CLASSES_PREFIX com/netscape)
add_jar(pki-common-test ${pki-common-test_SRCS})
add_dependencies(pki-common-test
@@ -72,11 +75,15 @@ add_dependencies(pki-common-test
)
# create test target
+# do not include xalan and xerces in class path
# TODO: create CMake function to find all JUnit test classes
add_junit_test(test-pki-common
CLASSPATH
${pki-common-test_JAR_FILE}
- ${CMAKE_JAVA_INCLUDE_PATH}
+ ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR}
+ ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR} ${PKI_CMSCORE_JAR} ${PKI_CMSBUNDLE_JAR}
+ ${LDAPJDK_JAR} ${SERVLET_JAR} ${VELOCITY_JAR}
+ ${JSS_JAR} ${OSUTIL_JAR} ${SYMKEY_JAR} ${JUNIT_JAR}
TESTS
com.netscape.certsrv.authentication.AuthTokenTest
com.netscape.certsrv.request.AgentApprovalsTest
@@ -87,6 +94,8 @@ add_junit_test(test-pki-common
com.netscape.cmscore.request.RequestQueueTest
com.netscape.cmscore.request.RequestRecordTest
com.netscape.cmscore.request.RequestTest
+ REPORTS_DIR
+ reports
)
# include test into the main test
diff --git a/pki/base/common/test/com/netscape/test/TestListener.java b/pki/base/common/test/com/netscape/test/TestListener.java
new file mode 100644
index 00000000..1322f414
--- /dev/null
+++ b/pki/base/common/test/com/netscape/test/TestListener.java
@@ -0,0 +1,233 @@
+package com.netscape.test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintStream;
+import java.net.InetAddress;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.junit.runner.Description;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
+
+public class TestListener extends RunListener {
+
+ DateFormat dateFormat;
+
+ DocumentBuilderFactory docBuilderFactory;
+ DocumentBuilder docBuilder;
+ Document document;
+
+ TransformerFactory transFactory;
+ Transformer trans;
+
+ String reportsDir;
+
+ Element testSuiteElement;
+ long testSuiteStartTime;
+
+ Element testCaseElement;
+ long testCaseStartTime;
+
+ String currentTestSuiteName;
+
+ long testCount;
+ long successCount;
+ long failureCount;
+
+ PrintStream stdOut;
+ PrintStream stdErr;
+
+ ByteArrayOutputStream out;
+ ByteArrayOutputStream err;
+
+ public TestListener() throws Exception {
+
+ dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+ dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
+
+ docBuilderFactory = DocumentBuilderFactory.newInstance();
+ docBuilder = docBuilderFactory.newDocumentBuilder();
+
+ transFactory = TransformerFactory.newInstance();
+ trans = transFactory.newTransformer();
+ trans.setOutputProperty(OutputKeys.INDENT, "yes");
+
+ reportsDir = System.getProperty("junit.reports.dir");
+ }
+
+ public void testRunFinished(Result result) throws Exception {
+ if (currentTestSuiteName != null) {
+ finishTestSuite(); // finish last suite
+ }
+ }
+
+ public void testStarted(Description description) throws Exception {
+
+ String testSuiteName = description.getClassName();
+
+ if (currentTestSuiteName == null) {
+ startTestSuite(testSuiteName); // start first suite
+
+ } else if (!currentTestSuiteName.equals(testSuiteName)) {
+ finishTestSuite(); // finish old suite
+ startTestSuite(testSuiteName); // start new suite
+ }
+
+ currentTestSuiteName = testSuiteName;
+
+ startTestCase(description);
+ }
+
+ public void testFinished(Description description) throws Exception {
+ finishTestCase();
+ recordTestCaseSuccess();
+ }
+
+ public void testFailure(Failure failure) throws Exception {
+ finishTestCase();
+ recordTestCaseFailure(failure);
+ }
+
+ public void startTestSuite(String testSuiteName) throws Exception {
+
+ testSuiteStartTime = System.currentTimeMillis();
+
+ document = docBuilder.newDocument();
+
+ // test suite
+ testSuiteElement = document.createElement("testsuite");
+ document.appendChild(testSuiteElement);
+
+ testSuiteElement.setAttribute("name", testSuiteName);
+ testSuiteElement.setAttribute("timestamp",
+ dateFormat.format(new Date(testSuiteStartTime)));
+ testSuiteElement.setAttribute("hostname",
+ InetAddress.getLocalHost().getHostName());
+
+ // system properties
+ Element propertiesElement = document.createElement("properties");
+ testSuiteElement.appendChild(propertiesElement);
+
+ for (String name : System.getProperties().stringPropertyNames()) {
+ Element propertyElement = document.createElement("property");
+ propertyElement.setAttribute("name", name);
+ propertyElement.setAttribute("value", System.getProperty(name));
+ propertiesElement.appendChild(propertyElement);
+ }
+
+ // reset counters
+ testCount = 0;
+ successCount = 0;
+ failureCount = 0;
+
+ // redirect outputs
+ stdOut = System.out;
+ out = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(out, true));
+
+ stdErr = System.err;
+ err = new ByteArrayOutputStream();
+ System.setErr(new PrintStream(err, true));
+ }
+
+ public void finishTestSuite() throws Exception {
+
+ double time = (System.currentTimeMillis() - testSuiteStartTime) / 1000.0;
+ testSuiteElement.setAttribute("time", "" + time);
+
+ // save counters
+ long errorCount = testCount - successCount - failureCount;
+
+ testSuiteElement.setAttribute("tests", "" + testCount);
+ testSuiteElement.setAttribute("failures", "" + failureCount);
+ testSuiteElement.setAttribute("errors", "" + errorCount);
+
+ // save outputs
+ System.setOut(stdOut);
+ System.setErr(stdErr);
+
+ Element systemOutElement = document.createElement("system-out");
+ testSuiteElement.appendChild(systemOutElement);
+
+ systemOutElement.appendChild(
+ document.createCDATASection(out.toString())
+ );
+
+ Element systemErrElement = document.createElement("system-err");
+ testSuiteElement.appendChild(systemErrElement);
+
+ systemErrElement.appendChild(
+ document.createCDATASection(err.toString())
+ );
+
+ // write to file
+ FileWriter fw = new FileWriter(
+ reportsDir + File.separator + "TEST-" + currentTestSuiteName + ".xml"
+ );
+ StreamResult sr = new StreamResult(fw);
+ DOMSource source = new DOMSource(document);
+ trans.transform(source, sr);
+ fw.close();
+ }
+
+ public void startTestCase(Description description) throws Exception {
+
+ testCaseStartTime = System.currentTimeMillis();
+
+ testCaseElement = document.createElement("testcase");
+ testSuiteElement.appendChild(testCaseElement);
+
+ testCaseElement.setAttribute("classname", description.getClassName());
+ testCaseElement.setAttribute("name", description.getMethodName());
+
+ testCount++;
+ }
+
+ public void finishTestCase() throws Exception {
+ double time = (System.currentTimeMillis() - testCaseStartTime) / 1000.0;
+ testCaseElement.setAttribute("time", "" + time);
+ }
+
+ public void recordTestCaseSuccess() throws Exception {
+ successCount++;
+ }
+
+ public void recordTestCaseFailure(Failure failure) throws Exception {
+
+ Element failureElement = document.createElement("failure");
+ testCaseElement.appendChild(failureElement);
+
+ Description description = failure.getDescription();
+ String exceptionName = failure.getException().getClass().getName();
+
+ failureElement.setAttribute("message", failure.getMessage());
+ failureElement.setAttribute("type", exceptionName);
+
+ Text messageElement = document.createTextNode(
+ exceptionName + ": " +failure.getMessage() + "\n\tat " +
+ description.getClassName() + "." + description.getMethodName() + "()"
+ );
+ failureElement.appendChild(messageElement);
+
+ failureCount++;
+ }
+}
diff --git a/pki/base/common/test/com/netscape/test/TestRunner.java b/pki/base/common/test/com/netscape/test/TestRunner.java
new file mode 100644
index 00000000..7eb4bfd3
--- /dev/null
+++ b/pki/base/common/test/com/netscape/test/TestRunner.java
@@ -0,0 +1,23 @@
+package com.netscape.test;
+
+import org.junit.internal.RealSystem;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+
+public class TestRunner {
+
+ public Result run(String... args) throws Exception {
+
+ JUnitCore core = new JUnitCore();
+ core.addListener(new TestListener());
+
+ return core.runMain(new RealSystem(), args);
+ }
+
+ public static void main(String... args) throws Exception {
+
+ TestRunner runner = new TestRunner();
+ Result result = runner.run(args);
+ System.exit(result.wasSuccessful() ? 0 : 1);
+ }
+}
diff --git a/pki/cmake/Modules/JUnit.cmake b/pki/cmake/Modules/JUnit.cmake
index 936dd000..84faa687 100644
--- a/pki/cmake/Modules/JUnit.cmake
+++ b/pki/cmake/Modules/JUnit.cmake
@@ -28,11 +28,13 @@ function(add_junit_test TARGET_NAME)
set(SEPARATOR ":")
endif(WIN32 AND NOT CYGWIN)
+ set(REPORTS_DIR "reports")
+
foreach (ARG ${ARGN})
- if (ARG MATCHES "CLASSPATH" OR ARG MATCHES "TESTS")
+ if (ARG MATCHES "(CLASSPATH|TESTS|REPORTS_DIR)")
set(TYPE ${ARG})
- else (ARG MATCHES "TESTS")
+ else (ARG MATCHES "(CLASSPATH|TESTS|REPORTS_DIR)")
if (TYPE MATCHES "CLASSPATH")
set(CLASSPATH "${CLASSPATH}${SEPARATOR}${ARG}")
@@ -40,14 +42,24 @@ function(add_junit_test TARGET_NAME)
elseif (TYPE MATCHES "TESTS")
set(TESTS ${TESTS} ${ARG})
- endif(TYPE MATCHES "TESTS")
+ elseif (TYPE MATCHES "REPORTS_DIR")
+ set(REPORTS_DIR ${ARG})
+
+ endif(TYPE MATCHES "CLASSPATH")
- endif(ARG MATCHES "CLASSPATH" OR ARG MATCHES "TESTS")
+ endif(ARG MATCHES "(CLASSPATH|TESTS|REPORTS_DIR)")
endforeach(ARG)
add_custom_target(${TARGET_NAME}
- COMMAND ${CMAKE_Java_RUNTIME} -classpath ${CLASSPATH} org.junit.runner.JUnitCore ${TESTS}
+ COMMAND
+ mkdir -p "${REPORTS_DIR}"
+ COMMAND
+ ${CMAKE_Java_RUNTIME}
+ -Djunit.reports.dir=${REPORTS_DIR}
+ -classpath ${CLASSPATH}
+ com.netscape.test.TestRunner
+ ${TESTS}
)
endfunction(add_junit_test)