/*
* Copyright (c) 2003-2012 Fred Hutchinson Cancer Research Center
*
* 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 org.fhcrc.cpl.viewer.test;
import junit.framework.TestFailure;
import junit.framework.TestResult;
import junit.framework.TestSuite;
import java.util.*;
import java.io.File;
import org.fhcrc.cpl.viewer.util.ConvertHelper;
import org.fhcrc.cpl.toolbox.ApplicationContext;
import org.fhcrc.cpl.toolbox.test.BaseCommandTest;
import org.fhcrc.cpl.toolbox.test.TestUtilities;
public class TestRunner extends TestSuite
{
protected static String _testPackage = "org.fhcrc.cpl.viewer.test";
protected static String _testBundleName = "tests";
// Fire the static converter initializers needed by the tab loader
static
{
ConvertHelper.registerHelpers();
}
/**
* Run tests. If the "test" system property is specified, try to figure out which test
* it refers to and run that one. Otherwise run all known tests
* @param args
*/
public static void main(String args[])
{
//This is a helper utility to calculate md5 sums of files, for comparison
if (args.length > 0 && "md5sum".equalsIgnoreCase(args[0]))
{
File fileToSum = new File(args[1]);
if (!fileToSum.exists() || !fileToSum.canRead())
log("Error reading file " + fileToSum.getAbsolutePath());
else
{
ApplicationContext.infoMessage("Calculating MD5 sum...");
try
{
log(TestUtilities.calculateHexMD5SumNoWhiteSpaceNoComments(fileToSum));
}
catch(Exception e)
{
log("Failed to calculate MD5 sum: " + e.getMessage() );
e.printStackTrace(System.err);
}
}
return;
}
//check for definition of msInspect source root directory
String toolsRootDir = System.getProperty("viewer.root");
if (toolsRootDir == null || toolsRootDir.equals(""))
{
log("Property viewer.root must be set in order to run tests");
return;
}
Class[] standardTestClasses = loadStandardTestClasses();
ArrayList<BaseCommandTest> tests = new ArrayList<BaseCommandTest>();
String testName = System.getProperty("test");
if (testName != null && testName.length() > 0)
{
//Test was specified, try to instantiate it
for (Class knownClass : standardTestClasses)
{
if (knownClass.getSimpleName().equalsIgnoreCase(testName) ||
knownClass.getSimpleName().equalsIgnoreCase(testName + "Test"))
{
try
{
Object testObject = knownClass.newInstance();
if (testObject instanceof BaseCommandTest)
tests.add((BaseCommandTest) testObject);
else
log("Failure adding test class " + knownClass.getName() + ": not an instance of BaseViwerTest");
}
catch (Exception e)
{
log("Failure adding test class " + knownClass.getName());
}
break;
}
}
if (tests.size() == 0)
log("Couldn't recognize test " + testName);
}
else //no test specified, run them all
{
for (Class testClass : standardTestClasses)
{
try
{
Object testObject = testClass.newInstance();
if (testObject instanceof BaseCommandTest)
tests.add((BaseCommandTest) testObject);
else
log("Failure adding test class " + testClass.getName() + ": not an instance of BaseViwerTest");
}
catch (Exception e)
{
log("Failure adding test class " + testClass.getName());
}
}
}
if (tests.size() == 0)
{
log("No tests specified");
return;
}
if (!cleanUpTests(tests))
return;
log("========= Done cleaning up ========= \n");
if("true".equals(System.getProperty("cleanonly")))
return;
ArrayList<String> successClassNames = new ArrayList<String>();
log("========= Running tests... ========= ");
for (BaseCommandTest test : tests)
{
log("========= Running Test " + test.getClass().getSimpleName() + " =========");
TestResult result = test.run();
if (result.errorCount() == 0 && result.failureCount() == 0)
{
log("========= " + test.getClass().getSimpleName() + " test success =========");
successClassNames.add(test.getClass().getSimpleName());
}
else
{
Enumeration errors = result.errors();
while (errors.hasMoreElements())
{
System.err.println("Error:");
TestFailure failure = (TestFailure) errors.nextElement();
if (failure.exceptionMessage() != null)
System.err.println(failure.exceptionMessage());
System.err.println(failure.trace());
}
log("Test " + test.getClass().getSimpleName() + " failed, " + result.errorCount() + " errors.");
log("==================================================================");
log("Test Suite Failed. ");
log(successClassNames.size() + " tests succeeded");
for (String successTestName : successClassNames)
log("\t" + successTestName);
log("Test " + test.getClass().getSimpleName() + " failed.");
System.exit(result.errorCount() + result.failureCount());
}
}
log("All " + successClassNames.size() + " tests passed");
closeLog();
}
/**
* Clean up after all tests
* @param tests
* @return
*/
public static boolean cleanUpTests(ArrayList<BaseCommandTest> tests)
{
//Clean up after all tests. At this level, we know we want to depopulate the
//scratch directories
log("========= Cleaning up after all tests... =========");
for (BaseCommandTest test : tests)
{
log("Cleaning up test " + test.getClass().getSimpleName());
try
{
test.cleanup();
}
catch (Exception e)
{
log("Exception when cleaning up prior to executing test:");
log(e.getMessage());
e.printStackTrace(System.err);
log("Please clean up manually before trying again.");
return false;
}
}
return true;
}
/**
* Load the standard test classes specified in the resource bundle
* @return
*/
protected static Class[] loadStandardTestClasses()
{
List<Class> testClassList = new ArrayList<Class>();
ResourceBundle testResourceBundle =
ResourceBundle.getBundle(_testPackage + "." +
_testBundleName);
Enumeration propertyNames = testResourceBundle.getKeys();
String propertyName = null;
while(propertyNames.hasMoreElements())
{
propertyName = (String) propertyNames.nextElement();
if ("true".equalsIgnoreCase(testResourceBundle.getString(propertyName)))
{
Class testClass = null;
try
{
testClass = Class.forName(_testPackage + "." + propertyName);
}
catch (Exception e)
{
try
{
//todo: what if someone wants a test in another package?
testClass = Class.forName(_testPackage + ".commandline." + propertyName);
}
catch (Exception x)
{
ApplicationContext.errorMessage("Exception loading test module with name " +
propertyName, x);
}
}
if (testClass != null)
{
testClassList.add(testClass);
}
}
}
return testClassList.toArray(new Class[testClassList.size()]);
}
/**
* Write a lot message
* @param mesg
*/
protected static void log(String mesg)
{
TestUtilities.log(mesg);
}
/**
* Close the log file
*/
protected static void closeLog()
{
TestUtilities.closeLog();
}
}