DefaultTestResultListener.java

  1. /**
  2.  * Powerunit - A JDK1.8 test framework
  3.  * Copyright (C) 2014 Mathieu Boretti.
  4.  *
  5.  * This file is part of Powerunit
  6.  *
  7.  * Powerunit is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License as published by
  9.  * the Free Software Foundation, either version 3 of the License, or
  10.  * (at your option) any later version.
  11.  *
  12.  * Powerunit is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  * GNU General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with Powerunit. If not, see <http://www.gnu.org/licenses/>.
  19.  */
  20. package ch.powerunit.impl;

  21. import java.io.ByteArrayOutputStream;
  22. import java.io.File;
  23. import java.io.PrintStream;
  24. import java.util.HashMap;
  25. import java.util.Map;

  26. import javax.xml.bind.JAXBContext;
  27. import javax.xml.bind.JAXBException;

  28. import ch.powerunit.TestContext;
  29. import ch.powerunit.TestResultListener;
  30. import ch.powerunit.report.Error;
  31. import ch.powerunit.report.Failure;
  32. import ch.powerunit.report.Testcase;
  33. import ch.powerunit.report.Testsuite;
  34. import ch.powerunit.report.Testsuites;

  35. /**
  36.  * @author borettim
  37.  *
  38.  */
  39. public class DefaultTestResultListener<T> implements TestResultListener<T> {

  40.     public DefaultTestResultListener(String targetFolder) {
  41.         this(targetFolder, null);
  42.     }

  43.     public DefaultTestResultListener(String targetFolder,
  44.             PrintStream outputConsole) {
  45.         this(targetFolder, outputConsole, null);
  46.     }

  47.     public DefaultTestResultListener(String targetFolder,
  48.             PrintStream outputConsole, PowerUnit mbean) {
  49.         this.outputConsole = outputConsole;
  50.         this.targetFolder = new File(targetFolder);
  51.         this.targetFolder.mkdirs();
  52.         this.mbean = mbean;
  53.     }

  54.     private static final JAXBContext JAXB_CONTEXT;

  55.     private final StringBuilder resumedSucess = new StringBuilder();

  56.     private final StringBuilder resumedFailure = new StringBuilder();

  57.     private final StringBuilder resumedSkipped = new StringBuilder();

  58.     /**
  59.      * @return the resumed
  60.      */
  61.     public String getResumed() {
  62.         return "Success tests:\n" + resumedSucess.toString()
  63.                 + "\n\nSkipped tests:\n" + resumedSkipped.toString()
  64.                 + "\n\nFailed tests:\n" + resumedFailure.toString() + "\n";
  65.     }

  66.     /**
  67.      * @return the resumedSucess
  68.      */
  69.     public String getResumedSucess() {
  70.         return resumedSucess.toString();
  71.     }

  72.     /**
  73.      * @return the resumedFailure
  74.      */
  75.     public String getResumedFailure() {
  76.         return resumedFailure.toString();
  77.     }

  78.     /**
  79.      * @return the resumedSkipped
  80.      */
  81.     public String getResumedSkipped() {
  82.         return resumedSkipped.toString();
  83.     }

  84.     static {
  85.         try {
  86.             JAXB_CONTEXT = JAXBContext.newInstance(Testsuites.class);
  87.         } catch (JAXBException e) {
  88.             throw new IllegalArgumentException("Unable to setup jaxb "
  89.                     + e.getMessage(), e);
  90.         }
  91.     }

  92.     private boolean error = false;

  93.     private final PrintStream outputConsole;

  94.     private final Map<String, Testsuite> result = new HashMap<>();

  95.     private final Map<String, Testsuites> results = new HashMap<>();

  96.     private final Map<String, Map<String, Testcase>> resultcase = new HashMap<>();

  97.     private final File targetFolder;

  98.     private final PowerUnit mbean;

  99.     private void printf(String format, Object... args) {
  100.         if (outputConsole != null) {
  101.             outputConsole.printf(format, args);
  102.         }
  103.     }

  104.     @Override
  105.     public void notifySetStart(String setName, String parameters) {
  106.         Testsuites tss = new Testsuites();
  107.         tss.setDisabled(0);
  108.         tss.setErrors(0);
  109.         tss.setFailures(0);
  110.         tss.setName(setName);
  111.         tss.setTests(0);
  112.         tss.setTime(0L);
  113.         results.put(setName, tss);

  114.         Testsuite ts = new Testsuite();
  115.         result.put(setName, ts);
  116.         ts.setName(setName.replace('$', '.'));
  117.         ts.setDisabled(0);
  118.         ts.setErrors(0);
  119.         ts.setFailures(0);
  120.         ts.setTests(0);
  121.         ts.setTime(0L);
  122.         resultcase.put(setName, new HashMap<>());

  123.     }

  124.     @Override
  125.     public void notifySetEnd(String setName, String parameters) {
  126.         try {
  127.             File target = new File(targetFolder, setName + ".xml");
  128.             printf("Pushing test results into %1$s%n", target.getAbsolutePath());
  129.             Object o = results.get(setName);
  130.             if (results.get(setName).getTestsuite().isEmpty()) {
  131.                 o = result.get(setName);
  132.             }
  133.             if (mbean != null) {
  134.                 ByteArrayOutputStream str = new ByteArrayOutputStream();
  135.                 JAXB_CONTEXT.createMarshaller().marshal(o, str);
  136.                 mbean.addResult(new String(str.toByteArray()));
  137.             }
  138.             JAXB_CONTEXT.createMarshaller().marshal(o, target);
  139.         } catch (JAXBException e) {
  140.             throw new IllegalArgumentException("Unable to setup jaxb "
  141.                     + e.getMessage(), e);
  142.         }
  143.     }

  144.     @Override
  145.     public void notifyStart(TestContext<T> context) {
  146.         String setName = context.getSetName()
  147.                 + (context.getParameterName() == null ? "" : context
  148.                         .getParameterName());
  149.         Testsuite ts = result.get(setName);
  150.         Testcase tc = new Testcase();
  151.         tc.setName(context.getLocalTestName()
  152.                 + (context.getParameterName() == null ? "" : "["
  153.                         + context.getParameterName() + "]"));
  154.         tc.setClassname(context.getTestSuiteObject().getClass()
  155.                 .getCanonicalName());
  156.         resultcase.get(setName).put(context.getFullTestName(), tc);
  157.         ts.getTestcase().add(tc);
  158.         tc.setTime(System.currentTimeMillis());
  159.         printf("Start of test %1$s%n", context.getFullTestName());
  160.     }

  161.     @Override
  162.     public void notifySuccess(TestContext<T> context) {
  163.         String setName = context.getSetName()
  164.                 + (context.getParameterName() == null ? "" : context
  165.                         .getParameterName());
  166.         long end = System.currentTimeMillis();
  167.         Testsuite ts = result.get(setName);
  168.         Testcase tc = resultcase.get(setName).get(context.getFullTestName());
  169.         tc.setTime((end - tc.getTime()) / 1000);
  170.         ts.setTime(ts.getTime() + tc.getTime());
  171.         ts.setTests(ts.getTests() + 1);
  172.         printf("Success of test %1$s%n", context.getFullTestName());
  173.         resumedSucess.append("\t").append(context.getLocalTestName())
  174.                 .append(" of ").append(context.getSetName()).append("\n");
  175.     }

  176.     @Override
  177.     public void notifyFailure(TestContext<T> context, Throwable cause) {
  178.         String setName = context.getSetName()
  179.                 + (context.getParameterName() == null ? "" : context
  180.                         .getParameterName());
  181.         long end = System.currentTimeMillis();
  182.         Testsuite ts = result.get(setName);
  183.         Testcase tc = resultcase.get(setName).get(context.getFullTestName());
  184.         tc.setTime((end - tc.getTime()) / 1000);
  185.         ts.setTime(ts.getTime() + tc.getTime());
  186.         error = true;
  187.         ts.setFailures(ts.getFailures() + 1);

  188.         Failure f = new Failure();
  189.         tc.getFailure().add(f);
  190.         f.setType(cause.getClass().getCanonicalName());
  191.         f.setMessage(cause.getMessage());
  192.         StringBuilder stack = new StringBuilder("" + cause.getMessage())
  193.                 .append('\n');
  194.         completeStack(cause, stack);
  195.         f.setContent(stack.toString());
  196.         printf("Failure of test %1$s because of %2$s%n",
  197.                 context.getFullTestName(), cause.getMessage());
  198.         resumedFailure.append("\t").append(context.getLocalTestName())
  199.                 .append(" of ").append(context.getSetName())
  200.                 .append(" caused by ").append(cause.getMessage()).append("\n");
  201.     }

  202.     @Override
  203.     public void notifySkipped(TestContext<T> context) {
  204.         String setName = context.getSetName()
  205.                 + (context.getParameterName() == null ? "" : context
  206.                         .getParameterName());
  207.         long end = System.currentTimeMillis();
  208.         Testsuite ts = result.get(setName);
  209.         Testcase tc = resultcase.get(setName).get(context.getFullTestName());
  210.         tc.setTime((end - tc.getTime()) / 1000);
  211.         ts.setTime(ts.getTime() + tc.getTime());
  212.         ts.setDisabled(ts.getDisabled() + 1);

  213.         tc.setSkipped("Skipped");
  214.         printf("Skip of test %1$s%n", context.getFullTestName());
  215.         resumedSkipped.append("\t").append(context.getLocalTestName())
  216.                 .append(" of ").append(context.getSetName()).append("\n");
  217.     }

  218.     @Override
  219.     public void notifyError(TestContext<T> context, Throwable cause) {
  220.         String setName = context.getSetName()
  221.                 + (context.getParameterName() == null ? "" : context
  222.                         .getParameterName());
  223.         long end = System.currentTimeMillis();
  224.         Testsuite ts = result.get(setName);
  225.         Testcase tc = resultcase.get(setName).get(context.getFullTestName());
  226.         tc.setTime((end - tc.getTime()) / 1000);
  227.         ts.setTime(ts.getTime() + tc.getTime());
  228.         error = true;
  229.         ts.setErrors(ts.getErrors() + 1);

  230.         Error e = new Error();
  231.         tc.getError().add(e);
  232.         e.setType(cause.getClass().getCanonicalName());
  233.         e.setMessage(cause.getMessage());
  234.         StringBuilder stack = new StringBuilder("" + cause.getMessage())
  235.                 .append('\n');
  236.         completeStack(cause, stack);
  237.         e.setContent(stack.toString());
  238.         printf("Error of test %1$s because of %2$s%n",
  239.                 context.getFullTestName(), cause.getMessage());
  240.         resumedFailure.append("\t").append(context.getLocalTestName())
  241.                 .append(" of ").append(context.getSetName())
  242.                 .append(" caused by ").append(cause.getMessage()).append("\n");
  243.     }

  244.     /**
  245.      * @param cause
  246.      * @param stack
  247.      */
  248.     private void completeStack(Throwable cause, StringBuilder stack) {
  249.         for (StackTraceElement ste : cause.getStackTrace()) {
  250.             stack.append(ste.toString()).append('\n');
  251.         }
  252.         Throwable by = cause.getCause();
  253.         if (by != null) {
  254.             stack.append("caused by ").append(by.getMessage() + "\n");
  255.             completeStack(by, stack);
  256.         }
  257.     }

  258.     @Override
  259.     public void notifyParameterStart(String setName, String parameterName) {
  260.         Testsuites tss = results.get(setName);
  261.         Testsuite ts = new Testsuite();
  262.         result.put(setName + parameterName, ts);
  263.         ts.setName(setName + "[" + parameterName + "]");
  264.         ts.setDisabled(0);
  265.         ts.setErrors(0);
  266.         ts.setFailures(0);
  267.         ts.setTests(0);
  268.         ts.setTime(0L);
  269.         resultcase.put(setName + parameterName, new HashMap<>());
  270.         tss.getTestsuite().add(ts);
  271.     }

  272.     @Override
  273.     public void notifyParameterEnd(String setName, String parameterName) {
  274.         Testsuites tss = results.get(setName);
  275.         Testsuite ts = result.get(setName + parameterName);
  276.         tss.setDisabled(tss.getDisabled() + ts.getDisabled());
  277.         tss.setErrors(tss.getErrors() + ts.getErrors());
  278.         tss.setFailures(tss.getFailures() + ts.getFailures());
  279.         tss.setTests(tss.getTests() + ts.getTests());
  280.         tss.setTime(tss.getTime() + ts.getTime());
  281.     }

  282.     /**
  283.      * @return the error
  284.      */
  285.     public boolean isError() {
  286.         return error;
  287.     }

  288. }