keycloak-uncached

Merge pull request #3180 from mbaluch/master A class to generate

9/5/2016 4:37:33 AM

Details

diff --git a/testsuite/integration-arquillian/pom.xml b/testsuite/integration-arquillian/pom.xml
index 977fba8..4a4cdce 100644
--- a/testsuite/integration-arquillian/pom.xml
+++ b/testsuite/integration-arquillian/pom.xml
@@ -119,6 +119,7 @@
     
     <modules>
         <module>test-apps</module>
+        <module>test-utils</module>
         <module>servers</module>
         <module>tests</module>
     </modules>
diff --git a/testsuite/integration-arquillian/tests/pom.xml b/testsuite/integration-arquillian/tests/pom.xml
index b2ee848..3220be5 100755
--- a/testsuite/integration-arquillian/tests/pom.xml
+++ b/testsuite/integration-arquillian/tests/pom.xml
@@ -37,7 +37,7 @@
         <module>base</module>
         <module>other</module>
     </modules>
-    
+
     <properties>
         <auth.server>undertow</auth.server>
         <auth.server.undertow>true</auth.server.undertow>
@@ -178,7 +178,7 @@
                         <properties>
                             <property>
                                 <name>listener</name>
-                                <value>org.keycloak.testsuite.util.TestEventsLogger</value>
+                                <value>org.keycloak.testsuite.util.TestEventsLogger,org.keycloak.testsuite.util.junit.AggregateResultsReporter</value>
                             </property>
                         </properties>
                     </configuration>
@@ -645,6 +645,13 @@
                 </file>
             </activation>
             <dependencies>
+
+                <dependency>
+                    <groupId>org.keycloak.testsuite</groupId>
+                    <artifactId>integration-arquillian-test-utils</artifactId>
+                    <version>${project.version}</version>
+                </dependency>
+
                 <!-- TEST DEPENDENCIES -->
                 <dependency>
                     <groupId>junit</groupId>
diff --git a/testsuite/integration-arquillian/test-utils/pom.xml b/testsuite/integration-arquillian/test-utils/pom.xml
new file mode 100644
index 0000000..c03c56b
--- /dev/null
+++ b/testsuite/integration-arquillian/test-utils/pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>integration-arquillian</artifactId>
+        <groupId>org.keycloak.testsuite</groupId>
+        <version>2.2.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>integration-arquillian-test-utils</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Test utils</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-configuration</groupId>
+            <artifactId>commons-configuration</artifactId>
+            <version>1.10</version>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/testsuite/integration-arquillian/test-utils/src/main/java/org/keycloak/testsuite/util/junit/AggregateResultsReporter.java b/testsuite/integration-arquillian/test-utils/src/main/java/org/keycloak/testsuite/util/junit/AggregateResultsReporter.java
new file mode 100644
index 0000000..a0809c1
--- /dev/null
+++ b/testsuite/integration-arquillian/test-utils/src/main/java/org/keycloak/testsuite/util/junit/AggregateResultsReporter.java
@@ -0,0 +1,269 @@
+package org.keycloak.testsuite.util.junit;
+
+import org.apache.commons.configuration.PropertiesConfiguration;
+
+import org.jboss.logging.Logger;
+
+import org.junit.Ignore;
+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.Document;
+import org.w3c.dom.Element;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Aggregates jUnit test results into a single report - XML file.
+ */
+public class AggregateResultsReporter extends RunListener {
+
+    private static final Logger LOGGER = Logger.getLogger(AggregateResultsReporter.class);
+
+    private final Document xml;
+    private final File reportFile;
+    private final boolean working;
+
+    private final AtomicInteger tests = new AtomicInteger(0);
+    private final AtomicInteger errors = new AtomicInteger(0);
+    private final AtomicInteger failures = new AtomicInteger(0);
+    private final AtomicInteger ignored = new AtomicInteger(0);
+    private final AtomicLong suiteStartTime = new AtomicLong(0L);
+
+    private final AtomicReference<Element> testsuite = new AtomicReference<Element>();
+
+    private final Map<String, Long> testTimes = new HashMap<String, Long>();
+
+    public AggregateResultsReporter() {
+        boolean working = true;
+        Document xml = null;
+        try {
+            xml = createEmptyDocument();
+        } catch (ParserConfigurationException ex) {
+            LOGGER.error("Failed to create XML DOM - reporting will not be done", ex);
+            working = false;
+        }
+
+        File reportFile = null;
+        try {
+            reportFile = createReportFile();
+        } catch (Exception ex) {
+            LOGGER.error("Failed to create log file - reporting will not be done", ex);
+            working = false;
+        }
+
+        this.working = working;
+        this.xml = xml;
+        this.reportFile = reportFile;
+    }
+
+    private Document createEmptyDocument() throws ParserConfigurationException {
+        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+        return builder.newDocument();
+    }
+
+    private File createReportFile() throws Exception {
+        PropertiesConfiguration config = new PropertiesConfiguration(System.getProperty("testsuite.constants"));
+        config.setThrowExceptionOnMissing(true);
+
+        final File logDir = new File(config.getString("log-dir"));
+        logDir.mkdirs();
+
+        final File reportFile = new File(logDir, "junit-report.xml").getAbsoluteFile();
+        reportFile.createNewFile();
+
+        return reportFile;
+    }
+
+    @Override
+    public void testRunStarted(Description description) throws Exception {
+        if (working) {
+            suiteStartTime.set(System.currentTimeMillis());
+
+            Element testsuite = xml.createElement("testsuite");
+
+            if (description.getChildren().size() == 1) {
+                testsuite.setAttribute("name", safeString(description.getChildren().get(0).getDisplayName()));
+            }
+
+            xml.appendChild(testsuite);
+            this.testsuite.set(testsuite);
+            writeXml();
+        }
+    }
+
+    @Override
+    public void testStarted(Description description) throws Exception {
+        if (working) {
+            testTimes.put(description.getDisplayName(), System.currentTimeMillis());
+        }
+    }
+
+    @Override
+    public void testFinished(Description description) throws Exception {
+        if (working) {
+            if (testTimes.containsKey(description.getDisplayName())) {
+                testsuite.get().appendChild(createTestCase(description));
+                writeXml();
+            }
+        }
+    }
+
+    @Override
+    public void testAssumptionFailure(Failure failure) {
+        if (working) {
+            ignored.incrementAndGet();
+
+            Element testcase = createTestCase(failure.getDescription());
+            Element skipped = xml.createElement("skipped");
+            skipped.setAttribute("message", safeString(failure.getMessage()));
+
+            testcase.appendChild(skipped);
+
+            testsuite.get().appendChild(testcase);
+            writeXml();
+        }
+    }
+
+    @Override
+    public void testFailure(Failure failure) throws Exception {
+        if (working) {
+            if (failure.getDescription().getMethodName() == null) {
+                // before class failed
+                for (Description child : failure.getDescription().getChildren()) {
+                    // mark all methods failed
+                    testFailure(new Failure(child, failure.getException()));
+                }
+            } else {
+                // normal failure
+                Element testcase = createTestCase(failure.getDescription());
+
+                Element element;
+                if (failure.getException() instanceof AssertionError) {
+                    failures.incrementAndGet();
+                    element = xml.createElement("failure");
+                } else {
+                    errors.incrementAndGet();
+                    element = xml.createElement("error");
+                }
+
+                testcase.appendChild(element);
+
+                element.setAttribute("type", safeString(failure.getException().getClass().getName()));
+                element.setAttribute("message", safeString(failure.getMessage()));
+                element.appendChild(xml.createCDATASection(safeString(failure.getTrace())));
+
+                testsuite.get().appendChild(testcase);
+                writeXml();
+            }
+        }
+    }
+
+    @Override
+    public void testIgnored(Description description) throws Exception {
+        if (working) {
+            ignored.incrementAndGet();
+
+            Element testcase = createTestCase(description);
+
+            Element skipped = xml.createElement("skipped");
+            skipped.setAttribute("message", safeString(description.getAnnotation(Ignore.class).value()));
+
+            testcase.appendChild(skipped);
+
+            testsuite.get().appendChild(testcase);
+            writeXml();
+        }
+    }
+
+    @Override
+    public void testRunFinished(Result result) throws Exception {
+        if (working) {
+            writeXml();
+        }
+    }
+
+    private void writeXml() {
+        Element testsuite = this.testsuite.get();
+
+        testsuite.setAttribute("tests", Integer.toString(tests.get()));
+        testsuite.setAttribute("errors", Integer.toString(errors.get()));
+        testsuite.setAttribute("skipped", Integer.toString(ignored.get()));
+        testsuite.setAttribute("failures", Integer.toString(failures.get()));
+        testsuite.setAttribute("time", computeTestTime(suiteStartTime.get()));
+
+        try {
+            Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(reportFile, false), Charset.forName("UTF-8")));
+            try {
+                Transformer t = TransformerFactory.newInstance().newTransformer();
+                t.setOutputProperty(OutputKeys.INDENT, "yes");
+                t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
+                t.transform(new DOMSource(xml), new StreamResult(writer));
+            } catch (TransformerConfigurationException ex) {
+                LOGGER.error("Misconfigured transformer", ex);
+            } catch (TransformerException ex) {
+                LOGGER.error("Unable to save XML file", ex);
+            } finally {
+                writer.close();
+            }
+        } catch (IOException ex) {
+            LOGGER.warn("Unable to open report file", ex);
+        }
+    }
+
+    private String computeTestTime(Long startTime) {
+        if (startTime == null) {
+            return "0";
+        } else {
+            long amount = System.currentTimeMillis() - startTime;
+            return String.format("%.3f", amount / 1000F);
+        }
+    }
+
+    private Element createTestCase(Description description) {
+        tests.incrementAndGet();
+
+        Element testcase = xml.createElement("testcase");
+
+        testcase.setAttribute("name", safeString(description.getMethodName()));
+        testcase.setAttribute("classname", safeString(description.getClassName()));
+        testcase.setAttribute("time", computeTestTime(testTimes.remove(description.getDisplayName())));
+
+        return testcase;
+    }
+
+    private String safeString(String input) {
+        if (input == null) {
+            return "null";
+        }
+
+        return input
+                // first remove color coding (all of it)
+                .replaceAll("\u001b\\[\\d+m", "")
+                // then remove control characters that are not whitespaces
+                .replaceAll("[\\p{Cntrl}&&[^\\p{Space}]]", "");
+    }
+}