Blame src/DllPlugInTester/DllPlugInTester.cpp

Packit Service e31359
#include <cppunit/BriefTestProgressListener.h>
Packit Service e31359
#include <cppunit/CompilerOutputter.h>
Packit Service e31359
#include <cppunit/TestPath.h>
Packit Service e31359
#include <cppunit/TestResult.h>
Packit Service e31359
#include <cppunit/TestResultCollector.h>
Packit Service e31359
#include <cppunit/TestRunner.h>
Packit Service e31359
#include <cppunit/TextOutputter.h>
Packit Service e31359
#include <cppunit/TextTestProgressListener.h>
Packit Service e31359
#include <cppunit/XmlOutputter.h>
Packit Service e31359
#include <cppunit/extensions/TestFactoryRegistry.h>
Packit Service e31359
#include <cppunit/plugin/DynamicLibraryManagerException.h>
Packit Service e31359
#include <cppunit/plugin/PlugInParameters.h>
Packit Service e31359
#include <cppunit/plugin/PlugInManager.h>
Packit Service e31359
#include <cppunit/plugin/TestPlugIn.h>
Packit Service e31359
#include <cppunit/portability/Stream.h>
Packit Service e31359
#include "CommandLineParser.h"
Packit Service e31359
Packit Service e31359
Packit Service e31359
/* Notes:
Packit Service e31359
Packit Service e31359
  Memory allocated by test plug-in must be freed before unloading the test plug-in.
Packit Service e31359
  That is the reason why the XmlOutputter is explicitely destroyed.
Packit Service e31359
 */
Packit Service e31359
Packit Service e31359
Packit Service e31359
/*! Runs the specified tests located in the root suite.
Packit Service e31359
 * \param parser Command line parser.
Packit Service e31359
 * \return \c true if the run succeed, \c false if a test failed or if a test
Packit Service e31359
 *         path was not resolved.
Packit Service e31359
 */
Packit Service e31359
bool 
Packit Service e31359
runTests( const CommandLineParser &parser )
Packit Service e31359
{
Packit Service e31359
  bool wasSuccessful = false;
Packit Service e31359
  CPPUNIT_NS::PlugInManager plugInManager;
Packit Service e31359
Packit Service e31359
  // The following scope is used to explicitely free all memory allocated before
Packit Service e31359
  // unload the test plug-ins (uppon plugInManager destruction).
Packit Service e31359
  {
Packit Service e31359
    CPPUNIT_NS::TestResult controller;
Packit Service e31359
    CPPUNIT_NS::TestResultCollector result;
Packit Service e31359
    controller.addListener( &result );        
Packit Service e31359
Packit Service e31359
    // Set up outputters
Packit Service e31359
    CPPUNIT_NS::OStream *stream = &CPPUNIT_NS::stdCErr();
Packit Service e31359
    if ( parser.useCoutStream() )
Packit Service e31359
      stream = &CPPUNIT_NS::stdCOut();
Packit Service e31359
Packit Service e31359
    CPPUNIT_NS::OStream *xmlStream = stream;
Packit Service e31359
    if ( !parser.getXmlFileName().empty() )
Packit Service e31359
      xmlStream = new CPPUNIT_NS::OFileStream( parser.getXmlFileName().c_str() );
Packit Service e31359
Packit Service e31359
    CPPUNIT_NS::XmlOutputter xmlOutputter( &result, *xmlStream, parser.getEncoding() );
Packit Service e31359
    xmlOutputter.setStyleSheet( parser.getXmlStyleSheet() );
Packit Service e31359
    CPPUNIT_NS::TextOutputter textOutputter( &result, *stream );
Packit Service e31359
    CPPUNIT_NS::CompilerOutputter compilerOutputter( &result, *stream );
Packit Service e31359
Packit Service e31359
    // Set up test listeners
Packit Service e31359
    CPPUNIT_NS::BriefTestProgressListener briefListener;
Packit Service e31359
    CPPUNIT_NS::TextTestProgressListener dotListener;
Packit Service e31359
    if ( parser.useBriefTestProgress() )
Packit Service e31359
      controller.addListener( &briefListener );
Packit Service e31359
    else if ( !parser.noTestProgress() )
Packit Service e31359
      controller.addListener( &dotListener );
Packit Service e31359
Packit Service e31359
    // Set up plug-ins
Packit Service e31359
    for ( int index =0; index < parser.getPlugInCount(); ++index )
Packit Service e31359
    {
Packit Service e31359
      CommandLinePlugInInfo plugIn = parser.getPlugInAt( index );
Packit Service e31359
      plugInManager.load( plugIn.m_fileName, plugIn.m_parameters );
Packit Service e31359
    }
Packit Service e31359
Packit Service e31359
    // Registers plug-in specific TestListener (global setUp/tearDown, custom TestListener...)
Packit Service e31359
    plugInManager.addListener( &controller );
Packit Service e31359
Packit Service e31359
    // Adds the default registry suite
Packit Service e31359
    CPPUNIT_NS::TestRunner runner;
Packit Service e31359
    runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
Packit Service e31359
Packit Service e31359
    // Runs the specified test
Packit Service e31359
    try
Packit Service e31359
    {
Packit Service e31359
      runner.run( controller, parser.getTestPath() );
Packit Service e31359
      wasSuccessful = result.wasSuccessful();
Packit Service e31359
    }
Packit Service e31359
    catch ( std::invalid_argument & )
Packit Service e31359
    {
Packit Service e31359
      CPPUNIT_NS::stdCOut()  <<  "Failed to resolve test path: "  
Packit Service e31359
                             <<  parser.getTestPath() 
Packit Service e31359
                             <<  "\n";
Packit Service e31359
    }
Packit Service e31359
Packit Service e31359
    // Removes plug-in specific TestListener (not really needed but...)
Packit Service e31359
    plugInManager.removeListener( &controller );
Packit Service e31359
Packit Service e31359
    // write using outputters
Packit Service e31359
    if ( parser.useCompilerOutputter() )
Packit Service e31359
      compilerOutputter.write();
Packit Service e31359
Packit Service e31359
    if ( parser.useTextOutputter() )
Packit Service e31359
      textOutputter.write();
Packit Service e31359
Packit Service e31359
    if ( parser.useXmlOutputter() )
Packit Service e31359
    {
Packit Service e31359
      plugInManager.addXmlOutputterHooks( &xmlOutputter );
Packit Service e31359
      xmlOutputter.write();
Packit Service e31359
      plugInManager.removeXmlOutputterHooks();
Packit Service e31359
    }
Packit Service e31359
Packit Service e31359
    if ( !parser.getXmlFileName().empty() )
Packit Service e31359
      delete xmlStream;
Packit Service e31359
  }
Packit Service e31359
Packit Service e31359
  return wasSuccessful;
Packit Service e31359
}
Packit Service e31359
Packit Service e31359
Packit Service e31359
void
Packit Service e31359
printShortUsage( const std::string &applicationName )
Packit Service e31359
{
Packit Service e31359
   CPPUNIT_NS::stdCOut()  << "Usage:\n"
Packit Service e31359
             << applicationName  <<  " [-c -b -n -t -o -w] [-x xml-filename]"
Packit Service e31359
             "[-s stylesheet] [-e encoding] plug-in[=parameters] [plug-in...] [:testPath]\n\n";
Packit Service e31359
}
Packit Service e31359
Packit Service e31359
Packit Service e31359
void
Packit Service e31359
printUsage( const std::string &applicationName )
Packit Service e31359
{
Packit Service e31359
  printShortUsage( applicationName );
Packit Service e31359
  CPPUNIT_NS::stdCOut()  <<
Packit Service e31359
"-c --compiler\n"
Packit Service e31359
"	Use CompilerOutputter\n"
Packit Service e31359
"-x --xml [filename]\n"
Packit Service e31359
"	Use XmlOutputter (if filename is omitted, then output to cout or\n"
Packit Service e31359
"	cerr.\n"
Packit Service e31359
"-s --xsl stylesheet\n"
Packit Service e31359
"	XML style sheet for XML Outputter\n"
Packit Service e31359
"-e --encoding encoding\n"
Packit Service e31359
"	XML file encoding (UTF8, shift_jis, ISO-8859-1...)\n"
Packit Service e31359
"-b --brief-progress\n"
Packit Service e31359
"	Use BriefTestProgressListener (default is TextTestProgressListener)\n"
Packit Service e31359
"-n --no-progress\n"
Packit Service e31359
"	Show no test progress (disable default TextTestProgressListener)\n"
Packit Service e31359
"-t --text\n"
Packit Service e31359
"	Use TextOutputter\n"
Packit Service e31359
"-o --cout\n"
Packit Service e31359
"	Ouputters output to cout instead of the default cerr.\n"
Packit Service e31359
"-w --wait\n"
Packit Service e31359
"	Wait for the user to press a return before exit.\n"
Packit Service e31359
"filename[=\"options\"]\n"
Packit Service e31359
"	Many filenames can be specified. They are the name of the \n"
Packit Service e31359
"	test plug-ins to load. Optional plug-ins parameters can be \n"
Packit Service e31359
"	specified after the filename by adding '='.\n"
Packit Service e31359
"[:testpath]\n"
Packit Service e31359
"	Optional. Only one test path can be specified. It must \n"
Packit Service e31359
"	be prefixed with ':'. See TestPath constructor for syntax.\n"
Packit Service e31359
"\n"
Packit Service e31359
"'parameters' (test plug-in or XML filename, test path...) may contains \n"
Packit Service e31359
"spaces if double quoted. Quote may be escaped with \".\n"
Packit Service e31359
"\n"
Packit Service e31359
"Some examples of command lines:\n"
Packit Service e31359
"\n"
Packit Service e31359
"DllPlugInTesterd_dll.exe -b -x tests.xml -c simple_plugind.dll CppUnitTestPlugInd.dll\n"
Packit Service e31359
"\n"
Packit Service e31359
" Will load 2 tests plug-ins (available in lib/), use the brief test\n"
Packit Service e31359
"progress, output the result in XML in file tests.xml and also\n"
Packit Service e31359
"output the result using the compiler outputter.\n"
Packit Service e31359
"\n"
Packit Service e31359
"DllPlugInTesterd_dll.exe ClockerPlugInd.dll=\"flat\" -n CppUnitTestPlugInd.dll\n"
Packit Service e31359
"\n"
Packit Service e31359
" Will load the 2 test plug-ins, and pass the parameter string \"flat\"\n"
Packit Service e31359
"to the Clocker plug-in, disable test progress.\n\n";
Packit Service e31359
Packit Service e31359
}
Packit Service e31359
Packit Service e31359
Packit Service e31359
/*! Main
Packit Service e31359
 * 
Packit Service e31359
 * Usage: 
Packit Service e31359
 *
Packit Service e31359
 * DllPlugInTester.exe dll-filename1 [dll-filename2 [dll-filename3 ...]] [:testpath]
Packit Service e31359
 *
Packit Service e31359
 * dll-filename must be the name of the DLL. If the DLL use some other DLL, they
Packit Service e31359
 * should be in the path or in the same directory as the DLL. The DLL must export
Packit Service e31359
 * a function named "GetTestPlugInInterface" with the signature
Packit Service e31359
 * GetTestPlugInInterfaceFunction. Both are defined in:
Packit Service e31359
 * \code
Packit Service e31359
 * #include <msvc6/testrunner/TestPlugInInterface.h>
Packit Service e31359
 * \endcode.
Packit Service e31359
 *
Packit Service e31359
 * If no test path is specified, they all the test of the suite returned by the DLL
Packit Service e31359
 * are run. If a test path is specified, then only the specified test is run. The test
Packit Service e31359
 * path must be prefixed by ':'.
Packit Service e31359
 *
Packit Service e31359
 * Test paths are resolved using Test::resolveTestPath() on the suite returned by
Packit Service e31359
 * TestFactoryRegistry::getRegistry().makeTest();
Packit Service e31359
 *
Packit Service e31359
 * If all test succeed and no error happen then the application exit with code 0.
Packit Service e31359
 * If any error occurs (failed to load dll, failed to resolve test paths) or a 
Packit Service e31359
 * test fail, the application exit with code 1. If the application failed to
Packit Service e31359
 * parse the command line, it exits with code 2.
Packit Service e31359
 */
Packit Service e31359
int 
Packit Service e31359
main( int argc, 
Packit Service e31359
      const char *argv[] )
Packit Service e31359
{
Packit Service e31359
  const int successReturnCode = 0;
Packit Service e31359
  const int failureReturnCode = 1;
Packit Service e31359
  const int badCommadLineReturnCode = 2;
Packit Service e31359
Packit Service e31359
  // check command line
Packit Service e31359
  std::string applicationName( argv[0] );
Packit Service e31359
  if ( argc < 2 )
Packit Service e31359
  {
Packit Service e31359
    printUsage( applicationName );
Packit Service e31359
    return badCommadLineReturnCode;
Packit Service e31359
  }
Packit Service e31359
Packit Service e31359
  CommandLineParser parser( argc, argv );
Packit Service e31359
  try
Packit Service e31359
  {
Packit Service e31359
    parser.parse();
Packit Service e31359
  }
Packit Service e31359
  catch ( CommandLineParserException &e )
Packit Service e31359
  {
Packit Service e31359
    CPPUNIT_NS::stdCOut()  <<  "Error while parsing command line: "  <<  e.what()  
Packit Service e31359
                           << "\n\n";
Packit Service e31359
    printShortUsage( applicationName );
Packit Service e31359
    return badCommadLineReturnCode;
Packit Service e31359
  }
Packit Service e31359
Packit Service e31359
  bool wasSuccessful = false;
Packit Service e31359
  try
Packit Service e31359
  {
Packit Service e31359
    wasSuccessful = runTests( parser );
Packit Service e31359
  }
Packit Service e31359
  catch ( CPPUNIT_NS::DynamicLibraryManagerException &e )
Packit Service e31359
  {
Packit Service e31359
    CPPUNIT_NS::stdCOut()  << "Failed to load test plug-in:\n"
Packit Service e31359
                           << e.what() << "\n";
Packit Service e31359
  }
Packit Service e31359
Packit Service e31359
#if !defined( CPPUNIT_NO_STREAM )
Packit Service e31359
  if ( parser.waitBeforeExit() )
Packit Service e31359
  {
Packit Service e31359
    CPPUNIT_NS::stdCOut() << "Please press <RETURN> to exit\n";
Packit Service e31359
    CPPUNIT_NS::stdCOut().flush();
Packit Service e31359
    std::cin.get();
Packit Service e31359
  }
Packit Service e31359
#endif
Packit Service e31359
Packit Service e31359
  return wasSuccessful ? successReturnCode : failureReturnCode;
Packit Service e31359
}
Packit Service e31359
Packit Service e31359