1 /*
   2  * $Id$
   3  *
   4  * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
   5  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   6  *
   7  * This code is free software; you can redistribute it and/or modify it
   8  * under the terms of the GNU General Public License version 2 only, as
   9  * published by the Free Software Foundation.  Oracle designates this
  10  * particular file as subject to the "Classpath" exception as provided
  11  * by Oracle in the LICENSE file that accompanied this code.
  12  *
  13  * This code is distributed in the hope that it will be useful, but WITHOUT
  14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16  * version 2 for more details (a copy is included in the LICENSE file that
  17  * accompanied this code).
  18  *
  19  * You should have received a copy of the GNU General Public License version
  20  * 2 along with this work; if not, write to the Free Software Foundation,
  21  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  22  *
  23  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  24  * or visit www.oracle.com if you need additional information or have any
  25  * questions.
  26  */
  27 
  28 package com.sun.javatest.junit;
  29 
  30 import com.sun.javatest.Status;
  31 import com.sun.javatest.lib.MultiStatus;
  32 import java.lang.reflect.InvocationTargetException;
  33 import java.lang.reflect.Method;
  34 import java.security.AccessController;
  35 import java.security.PrivilegedAction;
  36 import java.util.Iterator;
  37 import java.util.Map;
  38 import java.util.Set;
  39 import java.util.SortedMap;
  40 import java.util.TreeMap;
  41 import java.util.Vector;
  42 
  43 import junit.framework.TestCase;
  44 
  45 /**
  46  *
  47  */
  48 public class JUnitBareMultiTest extends JUnitMultiTest {
  49 
  50     /** Creates a new instance of JUnitBareMultiTest using specified ClassLoader */
  51     public JUnitBareMultiTest(ClassLoader loader) {
  52         super(loader);
  53     }
  54 
  55     /**
  56      * Common method for running the test, used by all entry points.
  57      * <code>setTestCaseClass()</code> should have been invoked before calling this.
  58      */
  59     public Status run0(String[] argv) {
  60         MultiStatus ms = new MultiStatus(log);
  61 
  62         getListAllJunitTestCases();
  63         if (tests == null) {
  64             return Status.failed("No test cases found in test.");
  65         }
  66         Iterator iterator = ((Set)tests.entrySet()).iterator();
  67         while (iterator.hasNext()) {
  68             Method method  = (Method)((Map.Entry)iterator.next()).getValue();
  69             Status status = null;
  70             try {
  71                 status = invokeTestCase(method);
  72             } catch (Throwable e) {
  73                 printStackTrace(e);
  74                 status = Status.failed("Error in test case: " + method.getName());
  75             }
  76             ms.add(method.getName(), status);
  77         }
  78         return ms.getStatus();
  79     }
  80 
  81     /**
  82      * Entry point for direct execution, not used by the harness.
  83      * Note that the provided class name should be a subclass of TestCase.
  84      */
  85     public static void main(String args[]) {
  86         String executeClass = System.getProperty("javaTestExecuteClass");
  87         JUnitMultiTest multiTest = new JUnitBareMultiTest(ClassLoader.getSystemClassLoader());
  88         multiTest.setup(executeClass);
  89         multiTest.run0(args);
  90     }
  91 
  92     /**
  93      * Entry point for standalone mode.
  94      */
  95     protected void setup(String executeClass) {
  96         TestCase test;
  97         try {
  98             Class tc = getClassLoader().loadClass(executeClass);
  99             String name = tc.getName();
 100             String constructor = tc.getConstructors()[0].toGenericString();
 101             test = (constructor.indexOf("java.lang.String") > -1)?
 102                 (TestCase)tc.getConstructors()[0].newInstance(new Object[] {name}):
 103                 (TestCase)tc.newInstance();
 104             setTestCaseClass(test);
 105 
 106         } catch(InstantiationException e){
 107             log.println("Cannot instantiate test: " + executeClass + " (" + exceptionToString(e) + ")");
 108         } catch(InvocationTargetException e){
 109             log.println("Exception in constructor: " + executeClass + " (" + exceptionToString(e.getTargetException()) + ")");
 110         } catch(IllegalAccessException e){
 111             log.println("Cannot access test: " + executeClass + " (" + exceptionToString(e) + ")");
 112         } catch (ClassNotFoundException e){
 113             log.println("Cannot find test: " + executeClass + " (" + exceptionToString(e) + ")");
 114         }
 115     }
 116 
 117     protected void setTestCaseClass(TestCase test){
 118         testCaseClass = test;
 119     }
 120 
 121     protected Status invokeTestCase(Method m)
 122     throws IllegalAccessException, InvocationTargetException {
 123         try {
 124             testCaseClass.setName(m.getName());
 125             testCaseClass.runBare();
 126         } catch (Throwable e) {
 127 
 128             e.printStackTrace(log);
 129             return Status.failed("test case " + m.getName() +  "in test " + testCaseClass.getName()+  " failed: " + e);
 130         }
 131         return Status.passed("OKAY");
 132     }
 133 
 134     protected void getListAllJunitTestCases(){
 135         tests = new TreeMap<String,Method>();
 136         try {
 137             Method[] methods = AccessController.doPrivileged(
 138                     new PrivilegedAction<Method[]>() {
 139                         public Method[] run() {
 140                             return testCaseClass.getClass().getMethods();
 141                         }
 142                     });
 143             for (Method m: methods){
 144                 if(m == null || excludeTestCases.contains(m.getName())){
 145                     continue;
 146                 }
 147                 Class[] paramTypes = m.getParameterTypes();
 148                 Class returnType = m.getReturnType();
 149                 String name = m.getName();
 150                 if ((paramTypes.length == 0) &&
 151                         Void.TYPE.isAssignableFrom(returnType) && name.startsWith("test") ) {
 152                     tests.put(name, m);
 153                 }
 154             }
 155         } catch (Throwable e ) {
 156             tests = null;
 157         }
 158     }
 159 
 160     protected TestCase testCaseClass;
 161     protected SortedMap <String, Method> tests;
 162 
 163     protected String testCases[] = null;
 164     protected Vector excludeTestCases = new Vector();
 165 }