blob: 53b2fdf29957faa693e8f6e819faaf25cdf4ab3d [file] [log] [blame]
/*
* 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);
}
}
}