Package org.apache.sling.junit.impl.servlet

Source Code of org.apache.sling.junit.impl.servlet.XmlRenderer

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.sling.junit.impl.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;

import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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 junit.runner.BaseTestRunner;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.junit.Renderer;
import org.apache.sling.junit.RendererFactory;
import org.apache.sling.junit.TestSelector;
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 org.w3c.dom.Text;

/** XML renderer for JUnit servlet */
@Component(immediate=false)
@Service
public class XmlRenderer extends RunListener implements Renderer, RendererFactory {
   
    /**
     * This renderer's extension
     */
    public static final String EXTENSION = "xml";

  /**
   * Writer used for output.
   */
  private PrintWriter output;

  /**
   * The XML document.
   */
  private Document doc;

  /**
   * The wrapper for the testsuites.
   */
  private Element suitesElement;

  /**
   * The wrapper for the whole testsuite.
   */
  private Element rootElement;

  /**
   * Table to track tests.
   */
  private Hashtable<Description, Element> testElements = new Hashtable<Description, Element>();

  /**
   * List to track falures.
   */
  private ArrayList<Description> failures = new ArrayList<Description>();

  /**
   * Table to track test run times.
   */
  Hashtable<Description, Long> tests = new Hashtable<Description, Long>();

  /**
   * Test Suite name.
   */
  private String name;

  /**
   * Start time for the test suite.
   */
  private long suiteStartTime = 0;

  /**
   * Counter of test suites.
   */
  private int testSuiteCount = 0;

    /** @inheritDoc */
    public Renderer createRenderer() {
        return new XmlRenderer();
    }

    /** @inheritDoc */
    public boolean appliesTo(TestSelector selector) {
        return EXTENSION.equals(selector.getExtension());
    }

    /** @inheritDoc */
    public String getExtension() {
        return EXTENSION;
    }

    /** @inheritDoc */
  public void setup(HttpServletResponse response, String pageTitle) throws IOException, UnsupportedEncodingException {
        if(output != null) {
            throw new IllegalStateException("Output Writer already set");
        }
    suiteStartTime = System.currentTimeMillis();

    response.setContentType("text/xml");
    response.setCharacterEncoding("UTF-8");
    output = response.getWriter();

    doc = getDocumentBuilder().newDocument();

    suitesElement = doc.createElement("testsuites");

  }  

    /** @inheritDoc */
  public void info(String cssClass, String str) {
  }

    /** @inheritDoc */
  public void list(String cssClass, Collection<String> data) {
  }

    /** @inheritDoc */
  public void title(int level, String title) {
    if (level == 3)
      name = title;
  }
 
    /** @inheritDoc */
    public void link(String info, String url, String method) {
    }

    /** @inheritDoc */
  public void cleanup() {
    if (testSuiteCount > 1) {
      output.println(getStringFromElement(suitesElement));
    } else {
      output.println(getStringFromElement(rootElement));
    }
    output = null;
  }
 
    /** @inheritDoc */
    public RunListener getRunListener() {
        return this;
    }

  @Override
  public void testFailure(Failure failure) throws Exception {
    super.testFailure(failure);
    failures.add(failure.getDescription());

    Element nested = doc.createElement("failure");
    Element currentTest = testElements.get(failure.getDescription());

    currentTest.appendChild(nested);

    String message = failure.getMessage();
    if (message != null && message.length() > 0) {
      nested.setAttribute("message", message);
    }
    nested.setAttribute("type", failure.getClass().getName());

    String strace = getException(failure.getException());
    strace = BaseTestRunner.getFilteredTrace(strace);
    Text trace = doc.createTextNode(strace);
    nested.appendChild(trace);       

  }

  @Override
  public void testFinished(Description description) throws Exception {
    super.testFinished(description);

    Long startTime = tests.get(description);
    long totalTime = System.currentTimeMillis() - startTime.longValue();

    Element currentTest = (Element) testElements.get(description);

    currentTest.setAttribute("time", String.valueOf(totalTime / 1000.0));  

  }

  @Override
  public void testIgnored(Description description) throws Exception {
    super.testIgnored(description);
  }

  @Override
  public void testRunFinished(Result result) throws Exception {
    super.testRunFinished(result);
    String cssClass = "testRun ";
    if(result.getFailureCount() > 0) {
      cssClass += "failure";
    } else if(result.getIgnoreCount() > 0) {
      cssClass += "ignored";
    } else {
      cssClass += "success";
    }

    long suiteEndTime = System.currentTimeMillis();

    rootElement.setAttribute("name", name);

    rootElement.setAttribute("timestamp", String.valueOf(suiteEndTime));

    rootElement.setAttribute("hostname", getHostname());

    rootElement.setAttribute("tests", "" + result.getRunCount());
    rootElement.setAttribute("failures", "" + result.getFailureCount());
    //rootElement.setAttribute("errors", "" + result.getIgnoreCount());
    rootElement.setAttribute(
        "time", "" + ((suiteEndTime - suiteStartTime) / 1000.0));


  }

  @Override
  public void testRunStarted(Description description)
  throws Exception {
    super.testRunStarted(description);

    testSuiteCount++;
    rootElement = doc.createElement("testsuite");
    suitesElement.appendChild(rootElement);

    // Output properties
    Element propsElement = doc.createElement("properties");
    rootElement.appendChild(propsElement);       

  }

  @Override
  public void testStarted(Description description) throws Exception {
    super.testStarted(description);
    tests.put(description, new Long(System.currentTimeMillis()));

    Element currentTest = doc.createElement("testcase");
    String n = description.getDisplayName();
    n = n.substring(0, n.indexOf("("));
    currentTest.setAttribute("name",
        n == null ? "unknown" : n);
    currentTest.setAttribute("classname",description.getClassName());
    rootElement.appendChild(currentTest);
    testElements.put(description, currentTest);       

  }

  /**
   * Create a DocumentBuilder.
   * @return a DocumentBuilder.
   */
  public static DocumentBuilder getDocumentBuilder() {
    try {
      return DocumentBuilderFactory.newInstance().newDocumentBuilder();
    } catch (Exception exc) {
      throw new ExceptionInInitializerError(exc);
    }
  }  

  /**
   * Convert an Element to a String representation
   * @param element
   * @return a String representation
   */
  public static String getStringFromElement(Element element) {
    try {
      TransformerFactory tf = TransformerFactory.newInstance();
      Transformer trans = tf.newTransformer();
      StringWriter sw = new StringWriter();
      trans.transform(new DOMSource(element), new StreamResult(sw));
      String elementString = sw.toString();
      return elementString;
    } catch (TransformerConfigurationException e) {
      System.err.println(getException(e));
    } catch (TransformerException e) {
      System.err.println(getException(e));
    }
    return "";
  }

  /**
   * get the local hostname
   * @return the name of the local host, or "localhost" if we cannot work it out
   */
  private String getHostname()  {
    try {
      return InetAddress.getLocalHost().getHostName();
    } catch (UnknownHostException e) {
      return "localhost";
    }
  } 

  /**
   * Convert a Throwable object to its stack trace representation
   *
   * @param t Throwable object
   * @return String representation of the Throwable object
   */
  public static String getException(Throwable t) {
    StringWriter sw = new StringWriter();
    t.printStackTrace(new PrintWriter(sw));

    return sw.getBuffer().toString();
  } // getException     

}
TOP

Related Classes of org.apache.sling.junit.impl.servlet.XmlRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.