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