19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage junit.runner;
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.reflect.*;
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport junit.runner.*;
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport junit.framework.*;
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * An implementation of a TestCollector that loads
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * all classes on the class path and tests whether
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it is assignable from Test or provides a static suite method.
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see TestCollector
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} - Not needed for 1.0 SDK
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class LoadingTestCollector extends ClassPathTestCollector {
15f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot
16f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot    TestCaseClassLoader fLoader;
17f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot
18f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot    public LoadingTestCollector() {
19f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        fLoader= new TestCaseClassLoader();
20f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot    }
21f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot
22f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot    protected boolean isTestClass(String classFileName) {
23f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        try {
24f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot            if (classFileName.endsWith(".class")) {
25f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot                Class testClass= classFromFile(classFileName);
26f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot                return (testClass != null) && isTestClass(testClass);
27f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot            }
28f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        }
29f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        catch (ClassNotFoundException expected) {
30f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        }
31f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        catch (NoClassDefFoundError notFatal) {
32f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        }
33f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        return false;
34f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot    }
35f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot
36f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot    Class classFromFile(String classFileName) throws ClassNotFoundException {
37f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        String className= classNameFromFile(classFileName);
38f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        if (!fLoader.isExcluded(className))
39f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot            return fLoader.loadClass(className, false);
40f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        return null;
41f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot    }
42f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot
43f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot    boolean isTestClass(Class testClass) {
44f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        if (hasSuiteMethod(testClass))
45f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot            return true;
46f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        if (Test.class.isAssignableFrom(testClass) &&
47f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot                Modifier.isPublic(testClass.getModifiers()) &&
48f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot                hasPublicConstructor(testClass))
49f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot            return true;
50f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        return false;
51f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot    }
52f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot
53f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot    boolean hasSuiteMethod(Class testClass) {
54f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        try {
55f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot            testClass.getMethod(BaseTestRunner.SUITE_METHODNAME, new Class[0]);
56f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        } catch(Exception e) {
57f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot            return false;
58f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        }
59f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        return true;
60f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot    }
61f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot
62f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot    boolean hasPublicConstructor(Class testClass) {
63f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        try {
64f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot            TestSuite.getTestConstructor(testClass);
65f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        } catch(NoSuchMethodException e) {
66f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot            return false;
67f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        }
68f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot        return true;
69f1253cd68a1ef45f4bb0c15d3e2834ca8f91e03fBrett Chabot    }
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
71