CoreTestRunner.java revision 866cc5d6a9cab69c26ed0253c55b2e5f560c7ad6
1/*
2 * Copyright (C) 2009 The Android Open Source Project
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 */
16package com.google.coretests;
17
18import java.util.ArrayList;
19import java.util.List;
20import java.util.logging.Level;
21import java.util.logging.Logger;
22
23import junit.framework.Test;
24import junit.framework.TestResult;
25import junit.framework.TestSuite;
26import junit.textui.ResultPrinter;
27import junit.textui.TestRunner;
28
29/**
30 * A special TestRunner implementation that is able to filter out annotated
31 * tests and handles our known failures properly (expects them to fail).
32 * Handy when running the Core Libraries tests on Android, the bare-metal
33 * Dalvik VM, or the RI.
34 */
35public class CoreTestRunner extends TestRunner {
36
37    /**
38     * Reflects our environment.
39     */
40    private static boolean IS_DALVIK = "Dalvik".equals(
41            System.getProperty("java.vm.name"));
42
43    /**
44     * Defines the default flags for running on Dalvik.
45     */
46    private static final int DEFAULT_FLAGS_DALVIK =
47            CoreTestSuite.RUN_ANDROID_ONLY |
48            CoreTestSuite.RUN_NORMAL_TESTS |
49            CoreTestSuite.RUN_KNOWN_FAILURES |
50            CoreTestSuite.RUN_SIDE_EFFECTS |
51            CoreTestSuite.INVERT_KNOWN_FAILURES;
52
53    /**
54     * Defines the default flags for running on an RI.
55     */
56    private static final int DEFAULT_FLAGS_NON_DALVIK =
57            CoreTestSuite.RUN_NORMAL_TESTS |
58            CoreTestSuite.RUN_KNOWN_FAILURES |
59            CoreTestSuite.RUN_SIDE_EFFECTS;
60
61    /**
62     * Holds the flags specified by the user on the command line.
63     */
64    private int fFlags;
65
66    /**
67     * Holds the timeout value specified by the user on the command line.
68     */
69    private int fTimeout;
70
71    private int fStep = 1;
72
73    /**
74     * Creates a new instance of our CoreTestRunner.
75     */
76    public CoreTestRunner() {
77        super();
78    }
79
80    @Override
81    protected TestResult createTestResult() {
82        return new CoreTestResult(fFlags, fTimeout);
83    }
84
85    protected ResultPrinter createPrinter() {
86        return new CoreTestPrinter(System.out, fFlags);
87    }
88
89    /**
90     * Provides our main entry point.
91     */
92    public static void main(String args[]) {
93        Logger.global.setLevel(Level.OFF);
94
95        System.out.println(
96                "--------------------------------------------------");
97        System.out.println("Android Core Libraries Test Suite");
98        System.out.println("Version 1.0");
99        System.out.println(
100                "Copyright (c) 2009 The Android Open Source Project");
101        System.out.println("");
102
103        CoreTestRunner testRunner = new CoreTestRunner();
104        try {
105            TestResult r = testRunner.start(args);
106
107            System.out.println(
108            "--------------------------------------------------");
109
110            if (!r.wasSuccessful()) {
111                System.exit(FAILURE_EXIT);
112            } else {
113                System.exit(SUCCESS_EXIT);
114            }
115        } catch(Exception e) {
116            System.err.println(e.getMessage());
117            System.exit(EXCEPTION_EXIT);
118        }
119
120    }
121
122    @Override
123    public TestResult doRun(Test suite, boolean wait) {
124        setPrinter(createPrinter());
125
126        /*
127         * Make sure the original suite is unreachable after we have
128         * created the new one, so GC can dispose terminated tests.
129         */
130        suite = new CoreTestSuite(suite, fFlags, fStep, null);
131
132        return super.doRun(suite, wait);
133    }
134
135    /**
136     * Prints a help screen on the console.
137     */
138    private void showHelp() {
139        System.out.println("Usage: run-core-tests [OPTION]... [TEST]...");
140        System.out.println();
141        System.out.println("Where each TEST is a class name, optionally followed");
142        System.out.println("by \"#\" and a method name, and each OPTION is one of");
143        System.out.println("the following:");
144        System.out.println();
145        System.out.println("    --include-all");
146        System.out.println("    --exclude-all");
147        System.out.println("    --include-android-only");
148        System.out.println("    --exclude-android-only");
149        System.out.println("    --include-broken-tests");
150        System.out.println("    --exclude-broken-tests");
151        System.out.println("    --include-known-failures");
152        System.out.println("    --exclude-known-failures");
153        System.out.println("    --include-normal-tests");
154        System.out.println("    --exclude-normal-tests");
155        System.out.println("    --include-side-effects");
156        System.out.println("    --exclude-side-effects");
157        System.out.println();
158        System.out.println("    --known-failures-must-fail");
159        System.out.println("    --known-failures-must-pass");
160        System.out.println("    --timeout <seconds>");
161        // System.out.println("    --find-side-effect <test>");
162        System.out.println("    --isolate-all");
163        System.out.println("    --isolate-none");
164        System.out.println("    --verbose");
165        System.out.println("    --help");
166        System.out.println();
167        System.out.println("Default parameters are:");
168        System.out.println();
169
170        if (IS_DALVIK) {
171            System.out.println("    --include-android-only");
172            System.out.println("    --exclude-broken-tests");
173            System.out.println("    --include-known-failures");
174            System.out.println("    --include-normal-tests");
175            System.out.println("    --include-side-effects");
176            System.out.println("    --known-failures-must-fail");
177        } else {
178            System.out.println("    --exclude-android-only");
179            System.out.println("    --exclude-broken-tests");
180            System.out.println("    --include-known-failures");
181            System.out.println("    --include-normal-tests");
182            System.out.println("    --include-side-effects");
183            System.out.println("    --known-failures-must-pass");
184        }
185
186        System.out.println();
187    }
188
189    /**
190     * Tries to create a Test instance from the given strings. The strings might
191     * either specify a class only or a class plus a method name, separated by
192     * a "#".
193     */
194    private Test createTest(List<String> testCases) throws Exception {
195        TestSuite result = new TestSuite();
196        for (String testCase : testCases) {
197            int p = testCase.indexOf("#");
198            if (p != -1) {
199                String testName = testCase.substring(p + 1);
200                testCase = testCase.substring(0, p);
201
202                result.addTest(TestSuite.createTest(Class.forName(testCase), testName));
203            } else {
204                result.addTest(getTest(testCase));
205            }
206        }
207        return result;
208    }
209
210    @Override
211    protected TestResult start(String args[]) throws Exception {
212        List<String> testNames = new ArrayList<String>();
213        // String victimName = null;
214
215        boolean wait = false;
216
217        if (IS_DALVIK) {
218            fFlags = DEFAULT_FLAGS_DALVIK;
219        } else {
220            fFlags = DEFAULT_FLAGS_NON_DALVIK;
221        }
222
223        for (int i= 0; i < args.length; i++) {
224            if (args[i].startsWith("--")) {
225                if (args[i].equals("--wait")) {
226                    wait = true;
227                } else if (args[i].equals("--include-all")) {
228                    fFlags = fFlags | CoreTestSuite.RUN_ALL_TESTS;
229                } else if (args[i].equals("--exclude-all")) {
230                    fFlags = fFlags & ~CoreTestSuite.RUN_ALL_TESTS;
231                } else if (args[i].equals("--include-android-only")) {
232                    fFlags = fFlags | CoreTestSuite.RUN_ANDROID_ONLY;
233                } else if (args[i].equals("--exclude-android-only")) {
234                    fFlags = fFlags & ~CoreTestSuite.RUN_ANDROID_ONLY;
235                } else if (args[i].equals("--include-broken-tests")) {
236                    fFlags = fFlags | CoreTestSuite.RUN_BROKEN_TESTS;
237                } else if (args[i].equals("--exclude-broken-tests")) {
238                    fFlags = fFlags & ~CoreTestSuite.RUN_BROKEN_TESTS;
239                } else if (args[i].equals("--include-known-failures")) {
240                    fFlags = fFlags | CoreTestSuite.RUN_KNOWN_FAILURES;
241                } else if (args[i].equals("--exclude-known-failures")) {
242                    fFlags = fFlags & ~CoreTestSuite.RUN_KNOWN_FAILURES;
243                } else if (args[i].equals("--include-normal-tests")) {
244                    fFlags = fFlags | CoreTestSuite.RUN_NORMAL_TESTS;
245                } else if (args[i].equals("--exclude-normal-tests")) {
246                    fFlags = fFlags & ~CoreTestSuite.RUN_NORMAL_TESTS;
247                } else if (args[i].equals("--include-side-effects")) {
248                    fFlags = fFlags | CoreTestSuite.RUN_SIDE_EFFECTS;
249                } else if (args[i].equals("--exclude-side-effects")) {
250                    fFlags = fFlags & ~CoreTestSuite.RUN_SIDE_EFFECTS;
251                } else if (args[i].equals("--known-failures-must-fail")) {
252                    fFlags = fFlags | CoreTestSuite.INVERT_KNOWN_FAILURES;
253                } else if (args[i].equals("--known-failures-must-pass")) {
254                    fFlags = fFlags & ~CoreTestSuite.INVERT_KNOWN_FAILURES;
255                } else if (args[i].equals("--timeout")) {
256                    fTimeout = Integer.parseInt(args[++i]);
257                } else if (args[i].equals("--reverse")) {
258                    fFlags = fFlags | CoreTestSuite.REVERSE;
259                } else if (args[i].equals("--step")) {
260                    fStep = Integer.parseInt(args[++i]);
261                } else if (args[i].equals("--isolate-all")) {
262                    fFlags = (fFlags | CoreTestSuite.ISOLATE_ALL) &
263                                   ~CoreTestSuite.ISOLATE_NONE;
264                } else if (args[i].equals("--isolate-none")) {
265                    fFlags = (fFlags | CoreTestSuite.ISOLATE_NONE) &
266                                   ~CoreTestSuite.ISOLATE_ALL;
267                } else if (args[i].equals("--verbose")) {
268                    fFlags = fFlags | CoreTestSuite.VERBOSE;
269                // } else if (args[i].equals("--find-side-effect")) {
270                //    victimName = args[++i];
271                } else if (args[i].equals("--dry-run")) {
272                    fFlags = fFlags | CoreTestSuite.DRY_RUN;
273                } else if (args[i].equals("--help")) {
274                    showHelp();
275                    System.exit(1);
276                } else {
277                    unknownArgument(args[i]);
278                }
279            } else if (args[i].startsWith("-")) {
280                unknownArgument(args[i]);
281            } else {
282                testNames.add(args[i]);
283            }
284        }
285
286        if (IS_DALVIK) {
287            System.out.println("Using Dalvik VM version " +
288                    System.getProperty("java.vm.version"));
289        } else {
290            System.out.println("Using Java VM version " +
291                    System.getProperty("java.version"));
292        }
293        System.out.println();
294
295        try {
296            return doRun(createTest(testNames), wait);
297        }
298        catch(Exception e) {
299            e.printStackTrace();
300            throw new Exception("Could not create and run test suite: " + e);
301        }
302    }
303
304    private static void unknownArgument(String arg) {
305        System.err.println("Unknown argument " + arg + ", try --help");
306        System.exit(1);
307    }
308}
309