/* * Copyright (C) 2009 The Android Open Source Project * * Licensed 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 * * 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 * limitations under the License. */ package com.google.coretests; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.PrintStream; import java.util.logging.Level; import java.util.logging.Logger; import junit.framework.Test; import junit.framework.TestFailure; import junit.framework.TestResult; import junit.framework.TestSuite; import junit.textui.TestRunner; /** * A minimalistic TestRunner implementation that silently executes a single test * method and writes a possible stack trace to a temporary file. Used for * isolating tests. */ public class CoreTestIsolator extends TestRunner { /** * Creates a new CoreTestIsolator. The superclass needs to be able to build * a proper ResultPrinter, so we pass it a null device for printing stuff. */ public CoreTestIsolator() { super(new PrintStream(new OutputStream() { @Override public void write(int oneByte) throws IOException { // Null device } })); } @Override protected TestResult createTestResult() { return new TestResult(); } /** * Provides the main entry point. First and second argument are class and * method name, respectively. Third argument is the temporary file name for * the result. Exits with one of the usual JUnit exit values. */ public static void main(String args[]) { Logger.global.setLevel(Level.OFF); CoreTestIsolator testRunner = new CoreTestIsolator(); try { TestResult r = testRunner.start(args); if (!r.wasSuccessful()) { // Store failure or error - we know there must be one Throwable failure = r.failureCount() != 0 ? ((TestFailure)r.failures().nextElement()). thrownException() : ((TestFailure)r.errors().nextElement()). thrownException(); saveStackTrace(failure, args[2]); System.exit(FAILURE_EXIT); } else { // Nothing to see here, please get along System.exit(SUCCESS_EXIT); } } catch(Exception e) { // Let main TestRunner know about execution problem saveStackTrace(e, args[2]); System.exit(EXCEPTION_EXIT); } } /** * Saves a given stack trace to a given file. */ private static void saveStackTrace(Throwable throwable, String fileName) { try { FileOutputStream fos = new FileOutputStream(fileName); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(throwable); oos.flush(); oos.close(); } catch (IOException ex) { // Ignore } } @Override protected TestResult start(String args[]) { try { Test suite = TestSuite.createTest(Class.forName(args[0]), args[1]); return doRun(suite); } catch(Exception e) { throw new RuntimeException("Unable to launch test", e); } } }