
org.broadinstitute.hellbender.testutils.BaseTest Maven / Gradle / Ivy
package org.broadinstitute.hellbender.testutils;
import htsjdk.samtools.util.Log;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.broadinstitute.hellbender.Main;
import org.broadinstitute.hellbender.engine.spark.SparkContextFactory;
import org.broadinstitute.hellbender.exceptions.UserException;
import org.broadinstitute.hellbender.utils.LoggingUtils;
import org.broadinstitute.hellbender.utils.gcs.BucketUtils;
import org.broadinstitute.hellbender.utils.io.IOUtils;
import org.broadinstitute.hellbender.utils.runtime.ProcessController;
import org.broadinstitute.hellbender.utils.runtime.ProcessOutput;
import org.broadinstitute.hellbender.utils.runtime.ProcessSettings;
import org.testng.Assert;
import org.testng.Reporter;
import org.testng.annotations.BeforeSuite;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
* This is the base test class for all of our test cases. All test cases should extend from this
* class; it sets up the logger, and resolves the location of directories that we rely on.
*/
public abstract class BaseTest {
static {
// set properties for the local Spark runner
System.setProperty("dataflow.spark.test.reuseSparkContext", "true");
SparkContextFactory.enableTestSparkContext();
System.setProperty("picard.useLegacyParser", "false");
}
/**
* run an external process and assert that it finishes with exit code 0
* @param processController a ProcessController to use
* @param command command to run, the 0th element must be the executable name
*/
public static void runProcess(final ProcessController processController, final String[] command) {
runProcess(processController, command, "Process exited with non-zero value. Command: "+ Arrays.toString(command) + "\n");
}
/**
* run an external process and assert that it finishes with exit code 0
* @param processController a ProcessController to use
* @param command command to run, the 0th element must be the executable name
* @param message error message to display on failure
*/
public static void runProcess(final ProcessController processController, final String[] command, final String message) {
runProcess(processController, command, null, message);
}
/**
* run an external process and assert that it finishes with exit code 0
* @param processController a ProcessController to use
* @param command command to run, the 0th element must be the executable name
* @param environment what to use as the process environment variables
* @param message error message to display on failure
*/
public static void runProcess(final ProcessController processController, final String[] command, final Map environment, final String message) {
final ProcessSettings prs = new ProcessSettings(command);
prs.getStderrSettings().printStandard(true);
prs.getStdoutSettings().printStandard(true);
prs.setEnvironment(environment);
final ProcessOutput output = processController.exec(prs);
Assert.assertEquals(output.getExitValue(), 0, message);
}
/**
* Spawn a new jvm with the same classpath as this one and run a gatk CommandLineProgram
* This is useful for running tests that require changing static state that is not allowed to change during
* a tool run but which needs to be changed to test some condition.
*
* @param toolName CommandLineProgram to run
* @param arguments arguments to provide to the tool
*/
public static void runToolInNewJVM(String toolName, ArgumentsBuilder arguments){
final String javaHome = System.getProperty("java.home");
final String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
final String classpath = System.getProperty("java.class.path");;
final List baseCommand = new ArrayList<>(Arrays.asList(
javaBin,
"-cp", classpath,
Main.class.getName(),
toolName));
baseCommand.addAll(arguments.getArgsList());
runProcess(ProcessController.getThreadLocal(), baseCommand.toArray(new String[0]));
}
@BeforeSuite
public void setTestVerbosity(){
LoggingUtils.setLoggingLevel(Log.LogLevel.WARNING);
}
public static final Logger logger = LogManager.getLogger("org.broadinstitute.gatk");
/**
* name of the google cloud project that stores the data and will run the code
* @return HELLBENDER_TEST_PROJECT env. var if defined, throws otherwise.
*/
public static String getGCPTestProject() {
return getNonNullEnvironmentVariable("HELLBENDER_TEST_PROJECT");
}
/**
* A writable GCS path where java files can be cached and temporary test files can be written,
* of the form gs://bucket/, or gs://bucket/path/.
* @return HELLBENDER_TEST_STAGING env. var if defined, throws otherwise.
*/
public static String getGCPTestStaging() {
return getNonNullEnvironmentVariable("HELLBENDER_TEST_STAGING");
}
/**
* A GCS path where the test inputs are stored.
*
* The value of HELLBENDER_TEST_INPUTS should end in a "/" (for example, "gs://hellbender/test/resources/")
*
* @return HELLBENDER_TEST_INPUTS env. var if defined, throws otherwise.
*/
public static String getGCPTestInputPath() {
return getNonNullEnvironmentVariable("HELLBENDER_TEST_INPUTS");
}
/**
* A path where the test inputs for the Funcotator LargeDataValidationTest are stored.
*
* The value of FUNCOTATOR_LARGE_TEST_INPUTS should end in a "/" (for example, "gs://hellbender/funcotator/test/resources/")
*
* @return FUNCOTATOR_LARGE_TEST_INPUTS env. var if defined, throws otherwise.
*/
public static String getFuncotatorLargeDataValidationTestInputPath() {
return getNonNullEnvironmentVariable("FUNCOTATOR_LARGE_TEST_INPUTS");
}
/**
* A local path where the service account credentials are stored
* @return GOOGLE_APPLICATION_CREDENTIALS env. var if defined, throws otherwise.
*/
public static String getGoogleServiceAccountKeyPath() {
return getNonNullEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS");
}
protected static String getNonNullEnvironmentVariable(String envVarName) {
String value = System.getenv(envVarName);
if (null == value) {
throw new UserException("For this test, please define environment variable \""+envVarName+"\"");
}
return value;
}
/**
* Returns the location of the resource directory for the command line program.
*/
public String getToolTestDataDir(){
return "src/test/resources/" +this.getClass().getPackage().getName().replace(".","/") +"/" + getTestedClassName() + "/";
}
/**
* Returns the name of the class being tested.
* The default implementation takes the simple name of the test class and removes the trailing "Test".
* Override if needed.
*/
public String getTestedClassName(){
if (getClass().getSimpleName().contains("IntegrationTest"))
return getClass().getSimpleName().replaceAll("IntegrationTest$", "");
else if (getClass().getSimpleName().contains("UnitTest"))
return getClass().getSimpleName().replaceAll("UnitTest$", "");
else
return getClass().getSimpleName().replaceAll("Test$", "");
}
/**
* @param fileName the name of a file
* @return a File resolved using getToolTestDataDir as the parent and fileName
*/
public File getTestFile(String fileName) {
return new File(getToolTestDataDir(), fileName);
}
/**
* Simple generic utility class to creating TestNG data providers:
*
* 1: inherit this class, as in
*
* private class SummarizeDifferenceTest extends TestDataProvider {
* public SummarizeDifferenceTest() {
* super(SummarizeDifferenceTest.class);
* }
* ...
* }
*
* Provide a reference to your class to the TestDataProvider constructor.
*
* 2: Create instances of your subclass. Return from it the call to getTests, providing
* the class type of your test
*
*
* {@literal @}DataProvider(name = "summaries")
* public Object[][] createSummaries() {
* new SummarizeDifferenceTest().addDiff("A", "A").addSummary("A:2");
* new SummarizeDifferenceTest().addDiff("A", "B").addSummary("A:1", "B:1");
* return SummarizeDifferenceTest.getTests(SummarizeDifferenceTest.class);
* }
*
*
* This class magically tracks created objects of this
*/
public static class TestDataProvider {
private static final Map, List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy