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