Package com.skaringa.perftest

Source Code of com.skaringa.perftest.PerfTestSuite

package com.skaringa.perftest;

import java.io.File;
import java.util.Date;
import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import com.skaringa.javaxml.NoImplementationException;
import com.skaringa.javaxml.ObjectTransformer;
import com.skaringa.javaxml.ObjectTransformerFactory;
import com.skaringa.perftest.config.PerfTestParams;
import com.skaringa.perftest.config.PerfTestSuiteParams;
import com.skaringa.util.Log;

/**
* Program to execute performance tests.
* A test suite contains a number of tests.
* The suite and the tests can be configured by an XML file.
* Tests can be executed in sequential order or parallel in different threads.
* The result is written to XML and HTML files.
*/
public final class PerfTestSuite {

  private String _name;

  // transformer for xml in/output
  private ObjectTransformer _trans = null;

  // transformer for html output
  private ObjectTransformer _htmlTrans = null;
  // name of resource with transformation instructions for html output
  private String _xsltResource;

  private PerfTestSuiteParams _suite = null;
  private Class _testClass;

  /**
   * ctor
   * @param name The name of the suite.
   * It must match the name of the config file without .xml.
   *
   */
  public PerfTestSuite(String name) {
    _name = name;
  }

  /**
   * ctor
   * @param name The name of the suite.
   * It must match the name of the config file without .xml.
   * @param xsltResource The name of the resource with
   * transformation instructions for html output.
   *
   */
  public PerfTestSuite(String name, String xsltResource) {
    _name = name;
    _xsltResource = xsltResource;
  }

  /**
   * Setup this test suite.
   */
  public void setup() {
    // read the configuration
    File configFile = new File(_name + ".xml");
    if (!configFile.canRead()) {
      Log.error(
        "No readable configuration file found for suite with name: " + _name);
      return;
    }

    try {
      initObjectTransformer();
      _suite =
        (PerfTestSuiteParams) _trans.deserialize(new StreamSource(configFile));
      if (_suite.name != null && _suite.name.length() > 0) {
        _name = _suite.name;
      }

      if (_suite.testclass == null || _suite.testclass.length() == 0) {
        Log.error("Attribute testclass is not defined.");
        return;
      }
    }
    catch (Exception e) {
      Log.error("Can't setup test: " + e);
    }

    // load the test class
    try {
      _testClass = Class.forName(_suite.testclass);
    }
    catch (ClassNotFoundException e) {
      Log.error("Test class " + _suite.testclass + " not found in CLASSPATH.");
    }

    // obtain info for OS and  JVM
    _suite.os =
      System.getProperty("os.name")
        + " "
        + System.getProperty("os.version")
        + " / "
        + System.getProperty("os.arch");
    _suite.jvm =
      System.getProperty("java.version")
        + " "
        + System.getProperty("java.vendor");

    // obtain info of JAXP implementation
    obtainJAXPImplInfo();

    Log.info(
      "Test suite "
        + _name
        + " for class "
        + _suite.testclass
        + " has been set up.");
  }

  /**
   * Run the test suite.
   * Dependend on the attribute parallel, the tests are run in sequential order
   * or by executing parallel threads.
   */
  public void run() {
    if (_testClass == null) {
      Log.error("Suite was not set up properly.");
      return;
    }

    _suite.testDate = new Date();

    // invoke all defined tests
    Map allTests = new Hashtable();
    ThreadGroup perftestThreadGroup = new ThreadGroup("perftestThreadGroup");

    int numberOfTests = _suite.perftests.length;
    for (int i = 0; i < numberOfTests; ++i) {
      try {
        PerfTest perftest = (PerfTest) _testClass.newInstance();
        perftest.setParams(_suite.perftests[i]);

        allTests.put(perftest.getTestId(), perftest);
        _suite.perftests[i].id = perftest.getTestId();

        // run the test

        if (_suite.parallel) {
          // execute the test as a new thread
          perftest.start();
          try {
            Thread.sleep(100);
          }
          catch (InterruptedException e) {
          }
        }
        else {
          // execute the test in the current thread
          perftest.run();
        }
      }
      catch (InstantiationException e) {
        Log.error("Failed to create test: " + e);
        _suite.perftests[i].error = true;
      }
      catch (IllegalAccessException e) {
        Log.error("Failed to create test: " + e);
        _suite.perftests[i].error = true;
      }
    }

    if (_suite.parallel) {
      Log.info("waiting for the tests to finish ...");
    }

    // collect the test results
    for (int i = 0; i < numberOfTests; ++i) {

      // get the id of the test
      String id = _suite.perftests[i].id;

      // get the test object
      PerfTest perftest = (PerfTest) allTests.get(id);

      if (_suite.parallel) {
        try {
          // join the test thread and wait for it to finish
          perftest.join();
        }
        catch (InterruptedException e) {
          Log.error(e);
        }
      }

      // add the result to perftest VO
      long time = perftest.getTime() / perftest.getLoopCount();
      _suite.perftests[i].time = time;
      _suite.perftests[i].error = perftest.getError();

    }
  }

  /**
   * Write the XML result file for this suite.
   * @param outputFile The result file.
   */
  public void writeResultXML(File outputFile) {
    if (_testClass == null) {
      Log.error("Suite was not set up properly.");
      return;
    }
    try {
      Log.info("Writing xml result file " + outputFile.toString());
      _trans.serialize(_suite, new StreamResult(outputFile));
      Log.info("done.");
    }
    catch (Exception e) {
      Log.error("Can't write resulting XML: " + e);
    }
  }

  /**
   * Write a HTML result file for this suite.
   * This is done by an XSL transformation.
   * @param outputFile The result file.
   */
  public void writeResultHTML(File outputFile) {
    if (_testClass == null) {
      Log.error("Suite was not set up properly.");
      return;
    }
    if (_htmlTrans == null) {
      Log.error(
        "No HTML output available (possible cause: invalid stylesheet");
    }

    try {
      Log.info("Writing html result file " + outputFile.toString());

      _htmlTrans.serialize(_suite, new StreamResult(outputFile));

      Log.info("done.");
    }
    catch (Exception e) {
      Log.error("Can't write resulting HTML: " + e);
    }
  }

  /**
   * Get and configure the ObjectTransformers for the output of the results.
   * @throws NoImplementationException if no ObjectTransformers are available.
   */
  private void initObjectTransformer() throws NoImplementationException {
    if (_trans == null) {
      // Get an ObjectTransformer for reading/writing xml.
      _trans = ObjectTransformerFactory.getInstance().getImplementation();

      // The transformer should create extra line feeds in the output.
      _trans.setProperty(javax.xml.transform.OutputKeys.INDENT, "yes");
      // Use western european encoding in the XML output.
      _trans.setProperty(javax.xml.transform.OutputKeys.ENCODING, "ISO-8859-1");
      // Use a short output format.
      _trans.setProperty(
        com.skaringa.javaxml.PropertyKeys.OMIT_XSI_TYPE,
        "true");
    }
    if (_htmlTrans == null && _xsltResource != null) {
      // Get an ObjectTransformer for writing html.
      _htmlTrans = ObjectTransformerFactory.getInstance().getImplementation();

      // The transformer should create extra line feeds in the output.
      _htmlTrans.setProperty(javax.xml.transform.OutputKeys.INDENT, "yes");
      // Use western european encoding in the XML output.
      _htmlTrans.setProperty(
        javax.xml.transform.OutputKeys.ENCODING,
        "ISO-8859-1");
      // use a stylesheet for xml->html postprocessing
      _htmlTrans.setPostprocessorInstruction(
        new StreamSource(ClassLoader.getSystemResourceAsStream(_xsltResource)));
    }
  }

  /**
   * Obtain info of JAXP implementation classes.
   */
  private void obtainJAXPImplInfo() {
    try {
      SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
      _suite.saxParser = saxParser.getClass().getName();

      Transformer trans = SAXTransformerFactory.newInstance().newTransformer();
      _suite.transformer = trans.getClass().getName();
    }
    catch (Exception e) {
      Log.warn(e.toString());
    }
  }

  /**
   * Write an example configuration file.
   */
  private void writeExampleConfigFile() {

    PerfTestSuiteParams suite = new PerfTestSuiteParams();
    suite.name = "SamplePerfTestSuite";
    suite.testclass = "full.name.of.testclass";
    suite.parallel = false;
    suite.hardware = "Z80, 4 Mhz, 64 KByte Memory";
    suite.comment =
      "This is a sample configuration file for a performance test suite.";
    suite.perftests = new PerfTestParams[5];

    for (int i = 0; i < 5; ++i) {
      PerfTestParams test = new PerfTestParams();
      test.method = "testMethod" + i;
      test.loopCount = 10;
      test.dataSize = 500;
      test.dataType = "full.name.of.class.of.testobject";
      test.randomData = false;
      test.cleanup = true;

      suite.perftests[i] = test;
    }

    String fileName = _name + ".xml";
    String xsdFileName = "perftest_config.xsd";
    try {
      // get an ObjectTransformer
      initObjectTransformer();

      // Serialize the example configuration into a file.
      _trans.serialize(suite, new StreamResult(new File(fileName)));

      // write the schema definition to another file
      Vector componentTypes = new Vector();
      componentTypes.add(PerfTestParams.class);
      _trans.writeXMLSchema(
        PerfTestSuiteParams.class,
        componentTypes,
        new StreamResult(new File(xsdFileName)));
    }
    catch (Exception e) {
      Log.error(e);
      return;
    }

    System.err.println("An example configuration file was created.");
    System.err.println("Filename :" + fileName);
    System.err.println(
      "An XML schema definition of the configuaration file was saved to "
        + xsdFileName);
  }

  /**
   * Main:
   * Execute the Test Suite.
   * @param args The command line has to contain o single argument
   * which is the name of the test suite.
   */
  public static void main(String[] args) {
    String xsltResource = "com/skaringa/perftest/result.xsl";

    if (args.length == 0) {
      System.err.println(
        "usage: java " + PerfTestSuite.class.getName() + " suite_name");

      PerfTestSuite sampleSuite = new PerfTestSuite("perftest_example_config");
      sampleSuite.writeExampleConfigFile();
      System.exit(1);
    }
    for (int i = 0; i < args.length; ++i) {
      String suiteName = args[i];
      File resultXML = new File(suiteName + "-result.xml");
      File resultHTML = new File(suiteName + "-result.html");

      PerfTestSuite theSuite = new PerfTestSuite(suiteName, xsltResource);
      theSuite.setup();
      theSuite.run();
      theSuite.writeResultXML(resultXML);
      theSuite.writeResultHTML(resultHTML);
    }
  }
}
TOP

Related Classes of com.skaringa.perftest.PerfTestSuite

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.