| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| <<<<<<< Updated upstream |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| ======= |
| * |
| * https://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| >>>>>>> Stashed changes |
| * limitations under the License. |
| */ |
| |
| package org.apache.jdo.tck.util; |
| |
| import java.io.File; |
| import java.io.OutputStream; |
| import java.io.PrintStream; |
| import java.lang.reflect.Constructor; |
| import java.lang.reflect.InvocationTargetException; |
| import javax.jdo.JDOFatalException; |
| import junit.framework.Test; |
| import junit.framework.TestCase; |
| import junit.framework.TestResult; |
| import junit.framework.TestSuite; |
| import junit.textui.ResultPrinter; |
| import junit.textui.TestRunner; |
| import org.apache.jdo.tck.JDO_Test; |
| |
| /** |
| * TestRunner class for running a single test or a test suite in batch mode. The format of the test |
| * output is specified by the result printer class. The main method sets an exit code according to |
| * the test result: |
| * |
| * <ul> |
| * <li><code>0</code>: success |
| * <li><code>1</code>: failure, the test shows an unexpected behavior |
| * <li><code>2</code>: exception, the test throws an unhandled exception |
| * </ul> |
| * |
| * @author Michael Bouschen |
| */ |
| public class BatchTestRunner extends TestRunner { |
| /** Name of the system property to specify the result printer class. */ |
| public static final String RESULTPRINTER_PROPERTY = "ResultPrinterClass"; |
| |
| /** Default of the system property ResultPrinterClass. */ |
| public static final String RESULTPRINTER_DEFAULT = BatchResultPrinter.class.getName(); |
| |
| /** */ |
| public static final String LOG_DIRECTORY; |
| |
| static { |
| String directory = System.getProperty("jdo.tck.log.directory"); |
| if (directory != null && !directory.endsWith(File.separator)) { |
| directory += File.separator; |
| } |
| LOG_DIRECTORY = directory; |
| } |
| |
| /** |
| * Constructor. It creates a result printer instance based on the system property and delegates to |
| * the constructor taking a result printer argument. |
| */ |
| public BatchTestRunner() { |
| super(); |
| setPrinter(getResultPrinter()); |
| } |
| |
| /** |
| * Constructor. Uses the specified resultPrinter to format the test result. |
| * |
| * @param resultPrinter the result printer |
| */ |
| public BatchTestRunner(ResultPrinter resultPrinter) { |
| super(resultPrinter); |
| } |
| |
| /** |
| * Runs all test methods from the specified class. |
| * |
| * @param clazz class object |
| */ |
| public static void run(Class<? extends TestCase> clazz) { |
| run(new TestSuite(clazz)); |
| } |
| |
| /** |
| * Runs the specified test or test suite |
| * |
| * @param test test or test suite |
| * @return the test result |
| */ |
| public static TestResult run(Test test) { |
| return new BatchTestRunner().doRun(test); |
| } |
| |
| /** |
| * Runs the specified test and waits until the user types RETURN. |
| * |
| * @param suite suite |
| */ |
| public static void runAndWait(Test suite) { |
| new BatchTestRunner().doRun(suite, true); |
| } |
| |
| /** |
| * Runs the specified test or test suite and closes the pmf. |
| * |
| * @param test test or test suite |
| * @return the test result |
| */ |
| @Override |
| public TestResult doRun(Test test) { |
| TestResult result = null; |
| try { |
| result = doRun(test, false); |
| JDO_Test.dumpSupportedOptions(LOG_DIRECTORY + "configuration"); |
| } finally { |
| JDO_Test.closePMF(); |
| } |
| return result; |
| } |
| |
| /** |
| * Runs in batch mode and sets an exit code. If the specified String array includes a single fully |
| * qualified class name, this test class is executed. |
| * |
| * @param args command line arguments |
| */ |
| public static void main(String[] args) { |
| try { |
| TestResult r = new BatchTestRunner().start(args); |
| if (!r.wasSuccessful()) System.exit(FAILURE_EXIT); |
| System.exit(SUCCESS_EXIT); |
| } catch (Exception e) { |
| System.err.println(e.getMessage()); |
| System.exit(EXCEPTION_EXIT); |
| } |
| } |
| |
| /** |
| * Starts the test |
| * |
| * @param args arguments |
| * @return the test result |
| */ |
| @Override |
| public TestResult start(String[] args) { |
| Test suite = null; |
| if ((args == null) || args.length == 0) { |
| String conf = System.getProperty("jdo.tck.cfg"); |
| throw new JDOFatalException( |
| "Missing JDO TCK test classes for configuration '" |
| + conf |
| + "'. Please check the property 'jdo.tck.classes'."); |
| } else if (args.length == 1) { |
| suite = getTest(args[0]); |
| } else { |
| suite = getTestSuite(args); |
| } |
| return doRun(suite); |
| } |
| |
| /** |
| * Returns a JUnit TestSuite instance for the classes of the specified list of class names. |
| * |
| * @param classNames class names |
| * @return the test suite |
| */ |
| @SuppressWarnings("unchecked") |
| protected TestSuite getTestSuite(String[] classNames) { |
| TestSuite testSuite = new TestSuite(); |
| for (String className : classNames) { |
| try { |
| Class<? extends TestCase> clazz = (Class<? extends TestCase>) Class.forName(className); |
| testSuite.addTestSuite(clazz); |
| } catch (ClassNotFoundException ex) { |
| System.out.println("Cannot find test class '" + className + "'."); |
| } |
| } |
| return testSuite; |
| } |
| |
| /** |
| * Returns a result printer instance. The system property ResultPrinterClass specifies the class |
| * of the returned instance. The class must extend junit.textui.ResultPrinter. |
| * |
| * @return the result printer |
| */ |
| protected ResultPrinter getResultPrinter() { |
| String className = System.getProperty(RESULTPRINTER_PROPERTY); |
| if (className != null) { |
| className = className.trim(); |
| if (className.length() != 0) { |
| String msg = null; |
| try { |
| // get class instance |
| Class<?> clazz = Class.forName(className); |
| |
| Constructor<?> ctor = null; |
| OutputStream stream = null; |
| |
| // choose constructor taking ConsoleFileOutput arg |
| if (!Boolean.getBoolean("no.log.file")) { |
| try { |
| ctor = clazz.getConstructor(ConsoleFileOutput.class); |
| stream = new ConsoleFileOutput(); |
| } catch (NoSuchMethodException ex) { |
| ctor = null; |
| } |
| } |
| |
| // choose constructor taking PrintStream arg |
| if (ctor == null) { |
| ctor = clazz.getConstructor(PrintStream.class); |
| stream = System.out; |
| } |
| |
| return (ResultPrinter) ctor.newInstance(new Object[] {stream}); |
| } catch (ClassNotFoundException ex) { |
| // specified ResultPrinter class not |
| msg = "Cannot find specified result printer class " + className + "."; |
| } catch (NoSuchMethodException ex) { |
| msg = "Class " + className + " does not provide constructor taking a PrintStream."; |
| } catch (InstantiationException ex) { |
| msg = "Class " + className + " is abstract."; |
| } catch (IllegalAccessException ex) { |
| msg = "Constructor taking a PrintStream of class " + className + " is not accessible."; |
| } catch (InvocationTargetException ex) { |
| msg = "Constructor call results in exception " + ex + "."; |
| } |
| |
| // ResultPrinter class specified, but not available |
| System.out.println(msg); |
| ResultPrinter printer = getDefaultResultPrinter(); |
| System.out.println("Using default result printer of class " + printer.getClass().getName()); |
| } |
| } |
| |
| // ResultPrinter class not specified => use default |
| return getDefaultResultPrinter(); |
| } |
| |
| /** |
| * Returns an instance of the default result printer class BatchResultPrinter. |
| * |
| * @return the default result printer |
| */ |
| protected ResultPrinter getDefaultResultPrinter() { |
| return new BatchResultPrinter(System.out); |
| } |
| |
| /** |
| * Returns a file name which is determined by method {@link |
| * BatchTestRunner#changeFileName(String)}. The file name has suffix <code>.txt</code>. |
| * |
| * @return the file name |
| */ |
| public static String getFileName() { |
| return changeFileName("junit.txt"); |
| } |
| |
| /** |
| * Returns a file name which is constructed by values of some system properties appended by the |
| * given file name. The system properties evaluated are: |
| * |
| * <ul> |
| * <li>jdo.tck.log.directory: Specifies the directory for the file. |
| * <li>jdo.tck.database, jdo.tck.cfg: The values of these properties prepend the given file |
| * name. |
| * <li>jdo.tck.identitytype: The value of this property is replaced by <code>"app"</code> if it |
| * equals <code>"applicationidentity"</code>, else it is replaced by <code>"dsid"</code>. |
| * </ul> |
| * |
| * The returned file name is constructed as follows:<br> |
| * ${jdo.tck.log.directory}/${jdo.tck.database}-${jdo.tck.identitytype}-${jdo.tck.cfg}${given file |
| * name} Values of properties which do not exist default to <code>""</code>. |
| * |
| * @param fileName the file name |
| * @return the changed file name |
| */ |
| public static String changeFileName(String fileName) { |
| String directory = LOG_DIRECTORY; |
| String db = System.getProperty("jdo.tck.database"); |
| |
| String identityType = System.getProperty("jdo.tck.identitytype"); |
| if (identityType != null) { |
| if (identityType.equals("applicationidentity")) { |
| identityType = "app"; |
| } else { |
| identityType = "dsid"; |
| } |
| } |
| |
| String configuration = System.getProperty("jdo.tck.cfg"); |
| if (configuration != null) { |
| int index = configuration.indexOf('.'); |
| if (index != -1) { |
| configuration = configuration.substring(0, index); |
| } |
| } |
| |
| directory = fixPartialFileName(directory); |
| db = fixPartialFileName(db, '-', new String[] {identityType, configuration, fileName}); |
| identityType = fixPartialFileName(identityType, '-', new String[] {configuration, fileName}); |
| configuration = fixPartialFileName(configuration, '-', new String[] {fileName}); |
| |
| return directory + db + identityType + configuration + fileName; |
| } |
| |
| private static String fixPartialFileName(String str) { |
| if (str == null) { |
| str = ""; |
| } |
| return str; |
| } |
| |
| private static String fixPartialFileName(String str, char c, String[] values) { |
| str = fixPartialFileName(str); |
| if (!str.equals("")) { |
| for (String value : values) { |
| if (value != null && !value.equals("") && !value.startsWith(".")) { |
| str += c; |
| break; |
| } |
| } |
| } |
| return str; |
| } |
| } |