    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package javax.jdo.util;
    19
    20  import java.lang.reflect.Constructor;
    21  import java.lang.reflect.InvocationTargetException;
    22  import java.io.PrintStream;
    23
    24  import junit.framework.Test;
    25  import junit.framework.TestResult;
    26  import junit.framework.TestSuite;
    27  import junit.textui.ResultPrinter;
    28  import junit.textui.TestRunner;
    29
    30  /**
    31   * TestRunner class for running a single test or a test suite in batch
    32   * mode. The format of the test output is specified by the result printer
    33   * class. The main method sets an exit code according to the test result:
    34   * <ul>
    35   * <li><code>0</code>: success
    36   * <li><code>1</code>: failure, the test shows an unexpected behavior
    37   * <li><code>2</code>: exception, the test throws an unhandled excption
    38   * </ul>
    39   *
    40   * @author Michael Bouschen
    41   */
    42  public class BatchTestRunner
    43      extends TestRunner
    44  {
    45      /** Name of the system property to specify the result printer class. */
    46      public static final String RESULTPRINTER_PROPERTY = "ResultPrinterClass";
    47
    48      /** Default of the system property ResultPrinterClass. */
    49      public static final String RESULTPRINTER_DEFAULT = BatchResultPrinter.class.getName();
    50
    51      /**
    52       * Constructor.
    53       * It creates a result printer instance based on the system property
    54       * and delegates to the constructor taking a result printer argument.
    55       */
    56      public BatchTestRunner() {
    57      	super();
    58          setPrinter(getResultPrinter());
    59      }
    60
    61      /**
    62       * Constructor. USes teh specified resultPrinter to format the test result.
    63       */
    64      public BatchTestRunner(ResultPrinter resultPrinter) {
    65          super(resultPrinter);
    66      }
    67
    68      /** Runs all test methods from the specified class. */
    69      public static void run(Class clazz) {
    70          run(new TestSuite(clazz));
    71      }
    72
    73      /** Runs the specified test. */
    74      public static TestResult run(Test test) {
    75  		return new BatchTestRunner().doRun(test);
    76      }
    77
    78  	/**	Runs the specified test and waits until the user types RETURN. */
    79  	public static void runAndWait(Test suite) {
    80  		new BatchTestRunner().doRun(suite, true);
    81  	}
    82
    83  	/**
    84       * Runs in batch mode and sets an exit code. If the specified String
    85       * array includes a single fully qualified class name, this test class
    86       * is executed. If it is empty it runs the TestListSuite.
    87       */
    88      public static void main(String args[]) {
    89  		BatchTestRunner aTestRunner= new BatchTestRunner();
    90  		try {
    91              /*
    92              if ((args == null) || args.length == 0)
    93                  args = new String[] { TestListSuite.class.getName() };
    94              */
    95  			TestResult r = aTestRunner.start(args);
    96  			if (!r.wasSuccessful())
    97  				System.exit(FAILURE_EXIT);
    98  			System.exit(SUCCESS_EXIT);
    99  		} catch(Exception e) {
    100 			System.err.println(e.getMessage());
    101 			System.exit(EXCEPTION_EXIT);
    102 		}
    103 	}
    104
    105     /** Returns a result printer instance. n instance of tCheck the system property */
    106     protected ResultPrinter getResultPrinter() {
    107       	String className =  System.getProperty(RESULTPRINTER_PROPERTY);
    108         if (className != null) {
    109             className = className.trim();
    110             if (className.length() != 0) {
    111                 String msg = null;
    112                 try {
    113                     // get class instance
    114                     Class clazz = Class.forName(className);
    115                     // constructor taking PrintStream arg
    116                     Constructor ctor = clazz.getConstructor(
    117                         new Class[] { PrintStream.class } );
    118                     // create instance
    119                     return (ResultPrinter)ctor.newInstance(
    120                         new Object[] { System.out });
    121                 }
    122                 catch (ClassNotFoundException ex) {
    123                     // specified ResultPrinter class not
    124                     msg = "Cannot find specified result printer class " +
    125                         className + ".";
    126                 }
    127                 catch (NoSuchMethodException ex) {
    128                     msg = "Class " + className +
    129                         " does not provide constructor taking a PrintStream.";
    130                 }
    131                 catch (InstantiationException ex) {
    132                     msg = "Class " + className + " is abstract.";
    133                 }
    134                 catch (IllegalAccessException ex) {
    135                     msg = "Constructor taking a PrintStream of class " +
    136                         className + " is not accessible.";
    137                 }
    138                 catch (InvocationTargetException ex) {
    139                     msg = "Constructor call results in exception " + ex + ".";
    140                 }
    141
    142                 // ResultPrinter class specified, but not avaiable
    143                 System.out.println(msg);
    144                 ResultPrinter printer = getDefaultResultPrinter();
    145                 System.out.println("Using default result printer of class " +
    146                                    printer.getClass().getName());
    147             }
    148         }
    149
    150         // ResultPrinter class not specified => use default
    151         return getDefaultResultPrinter();
    152     }
    153
    154     /**
    155      * Returns an instance of the default result printer class
    156      * BatchResultPrinter.
    157      */
    158     protected ResultPrinter getDefaultResultPrinter() {
    159         return new BatchResultPrinter(System.out);
    160     }
    161
    162
    163 }
    164