diff --git a/eva-accession-pipeline/src/test/java/uk/ac/ebi/eva/accession/pipeline/runner/EvaAccessionJobLauncherCommandLineRunnerTest.java b/eva-accession-pipeline/src/test/java/uk/ac/ebi/eva/accession/pipeline/runner/EvaAccessionJobLauncherCommandLineRunnerTest.java index 815d76023..a4d1998e0 100644 --- a/eva-accession-pipeline/src/test/java/uk/ac/ebi/eva/accession/pipeline/runner/EvaAccessionJobLauncherCommandLineRunnerTest.java +++ b/eva-accession-pipeline/src/test/java/uk/ac/ebi/eva/accession/pipeline/runner/EvaAccessionJobLauncherCommandLineRunnerTest.java @@ -38,7 +38,6 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; - import org.springframework.test.web.client.ExpectedCount; import org.springframework.test.web.client.MockRestServiceServer; import org.springframework.web.client.RestTemplate; @@ -47,18 +46,11 @@ import uk.ac.ebi.eva.accession.pipeline.parameters.InputParameters; import uk.ac.ebi.eva.accession.pipeline.test.BatchTestConfiguration; import uk.ac.ebi.eva.commons.batch.io.VcfReader; -import uk.ac.ebi.eva.commons.core.utils.FileUtils; import uk.ac.ebi.eva.metrics.count.CountServiceParameters; import javax.sql.DataSource; -import java.io.BufferedReader; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; import java.net.URI; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.NoSuchFileException; import java.nio.file.Path; @@ -66,19 +58,23 @@ import java.nio.file.StandardCopyOption; import java.util.Arrays; import java.util.Collections; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; import static uk.ac.ebi.eva.accession.pipeline.configuration.BeanNames.CREATE_SUBSNP_ACCESSION_JOB; import static uk.ac.ebi.eva.accession.pipeline.configuration.BeanNames.CREATE_SUBSNP_ACCESSION_STEP; +import static uk.ac.ebi.eva.accession.pipeline.runner.runnerUtil.deleteTemporaryContigAndVariantFiles; +import static uk.ac.ebi.eva.accession.pipeline.runner.runnerUtil.getOriginalVcfContent; +import static uk.ac.ebi.eva.accession.pipeline.runner.runnerUtil.injectErrorIntoTempVcf; +import static uk.ac.ebi.eva.accession.pipeline.runner.runnerUtil.remediateTempVcfError; +import static uk.ac.ebi.eva.accession.pipeline.runner.runnerUtil.useOriginalVcfFile; +import static uk.ac.ebi.eva.accession.pipeline.runner.runnerUtil.useTempVcfFile; +import static uk.ac.ebi.eva.accession.pipeline.runner.runnerUtil.writeToTempVCFFile; @RunWith(SpringRunner.class) -@ContextConfiguration(classes={BatchTestConfiguration.class}) +@ContextConfiguration(classes = {BatchTestConfiguration.class}) @TestPropertySource("classpath:accession-pipeline-test.properties") @SpringBatchTest public class EvaAccessionJobLauncherCommandLineRunnerTest { @@ -146,13 +142,13 @@ public void setUp() throws Exception { originalVcfInputFilePath = inputParameters.getVcf(); originalVcfOutputFilePath = inputParameters.getOutputVcf(); originalVcfContent = getOriginalVcfContent(originalVcfInputFilePath); - writeToTempVCFFile(originalVcfContent); + writeToTempVCFFile(originalVcfContent, tempVcfInputFileToTestFailingJobs); originalInputParametersCaptured = true; } jobRepositoryTestUtils = new JobRepositoryTestUtils(jobRepository, datasource); runner.setJobNames(CREATE_SUBSNP_ACCESSION_JOB); - deleteTemporaryContigAndVariantFiles(); - useOriginalVcfFile(); + deleteTemporaryContigAndVariantFiles(inputParameters, tempVcfOutputDir); + useOriginalVcfFile(inputParameters, originalVcfInputFilePath, vcfReader); mockServer = MockRestServiceServer.createServer(restTemplate); mockServer.expect(ExpectedCount.manyTimes(), requestTo(new URI(countServiceParameters.getUrl() + URL_PATH_SAVE_COUNT))) @@ -190,7 +186,7 @@ public void restartCompletedJobThatIsAlreadyInTheRepository() throws Exception { runner.run(); assertEquals(EvaAccessionJobLauncherCommandLineRunner.EXIT_WITHOUT_ERRORS, runner.getExitCode()); - deleteTemporaryContigAndVariantFiles(); + deleteTemporaryContigAndVariantFiles(inputParameters, tempVcfOutputDir); inputParameters.setForceRestart(true); runner.run(); @@ -198,16 +194,15 @@ public void restartCompletedJobThatIsAlreadyInTheRepository() throws Exception { } - private JobInstance runJobAandCheckResults() throws Exception { runner.run(); assertEquals(EvaAccessionJobLauncherCommandLineRunner.EXIT_WITH_ERRORS, runner.getExitCode()); JobInstance currentJobInstance = CommandLineRunnerUtils.getLastJobExecution(CREATE_SUBSNP_ACCESSION_JOB, - jobExplorer, - inputParameters.toJobParameters()) - .getJobInstance(); + jobExplorer, + inputParameters.toJobParameters()) + .getJobInstance(); StepExecution stepExecution = jobRepository.getLastStepExecution(currentJobInstance, - CREATE_SUBSNP_ACCESSION_STEP); + CREATE_SUBSNP_ACCESSION_STEP); //Ensure that only the first batch was written (batch size is 5 and error was at line#9) assertEquals(inputParameters.getChunkSize(), stepExecution.getWriteCount()); @@ -235,18 +230,19 @@ public void resumeFailingJobFromCorrectChunk() throws Exception { // C is a job with the same parameters as A run after VCF fault remediation (as part of the // runTestWithFaultInjection method), therefore should resume A and succeed. - useTempVcfFile(); - injectErrorIntoTempVcf(); + useTempVcfFile(inputParameters, tempVcfInputFileToTestFailingJobs, vcfReader); + String modifiedVcfContent = originalVcfContent.replace("76852", "76852jibberish"); + injectErrorIntoTempVcf(modifiedVcfContent, tempVcfInputFileToTestFailingJobs); JobInstance failingJobInstance = runJobAandCheckResults(); runJobBAndCheckResults(); - remediateTempVcfError(); + remediateTempVcfError(originalVcfContent, tempVcfInputFileToTestFailingJobs); runJobCAndCheckResumption(failingJobInstance); } private void runJobBAndCheckResults() throws Exception { - useOriginalVcfFile(); + useOriginalVcfFile(inputParameters, originalVcfInputFilePath, vcfReader); // Back up contig and variant files (left behind by previous unsuccessful job A) to temp folder // so as to not interfere with this job's execution which uses the original VCF file backUpContigAndVariantFilesToTempFolder(); @@ -255,18 +251,18 @@ private void runJobBAndCheckResults() throws Exception { assertEquals(EvaAccessionJobLauncherCommandLineRunner.EXIT_WITHOUT_ERRORS, runner.getExitCode()); //Restore state so that Job C can continue running after fault remediation - useTempVcfFile(); + useTempVcfFile(inputParameters, tempVcfInputFileToTestFailingJobs, vcfReader); restoreContigAndVariantFilesFromTempFolder(); } private void runJobCAndCheckResumption(JobInstance failingJobInstance) throws Exception { runner.run(); JobInstance currentJobInstance = CommandLineRunnerUtils.getLastJobExecution(CREATE_SUBSNP_ACCESSION_JOB, - jobExplorer, - inputParameters.toJobParameters()) - .getJobInstance(); + jobExplorer, + inputParameters.toJobParameters()) + .getJobInstance(); StepExecution stepExecution = jobRepository.getLastStepExecution(currentJobInstance, - CREATE_SUBSNP_ACCESSION_STEP); + CREATE_SUBSNP_ACCESSION_STEP); // Did we resume the previous failed job instance? assertEquals(failingJobInstance.getInstanceId(), currentJobInstance.getInstanceId()); @@ -275,105 +271,38 @@ private void runJobCAndCheckResumption(JobInstance failingJobInstance) throws Ex // Test resumption point - did we pick up where we left off? // Ensure all the batches other than the first batch were processed assertEquals(numberOfLinesInVcf - inputParameters.getChunkSize() - numberOfNonVariants, - stepExecution.getWriteCount()); + stepExecution.getWriteCount()); assertEquals(EvaAccessionJobLauncherCommandLineRunner.EXIT_WITHOUT_ERRORS, runner.getExitCode()); } - private void injectErrorIntoTempVcf() throws Exception { - String modifiedVcfContent = originalVcfContent.replace("76852", "76852jibberish"); - // Inject error in the VCF file to cause processing to stop at variant#9 - writeToTempVCFFile(modifiedVcfContent); - } - - private void remediateTempVcfError() throws Exception { - writeToTempVCFFile(originalVcfContent); - } - - private void useOriginalVcfFile() throws Exception { - inputParameters.setVcf(originalVcfInputFilePath); - vcfReader.setResource(FileUtils.getResource(new File(originalVcfInputFilePath))); - } - - private void useTempVcfFile() throws Exception { - // The following does not actually change the wiring of the vcfReader since the wiring happens before the tests - // This setVcf is only to facilitate identifying jobs in the job repo by parameter - // (those that use original vs temp VCF) - inputParameters.setVcf(tempVcfInputFileToTestFailingJobs.getAbsolutePath()); - /* - * Change the auto-wired VCF for VCFReader at runtime - * Rationale: - * 1) Why not use two test configurations, one for a VCF that fails validation and another for a VCF - * that won't and test resumption? - * Beginning Spring Boot 2, job resumption can only happen when input parameters to the restarted job - * is the same as the failed job. - * Therefore, a test to check resumption cannot have two different config files with different - * parameters.vcf. - * This test therefore creates a dynamic VCF and injects errors at runtime to the VCF thus preserving - * the VCF parameter but changing the VCF content. - * 2) Why not artificially inject a VcfReader exception? - * This will preclude us from verifying job resumption from a precise line in the VCF. - */ - vcfReader.setResource(FileUtils.getResource(tempVcfInputFileToTestFailingJobs)); - } private void backUpContigAndVariantFilesToTempFolder() { moveFile(Paths.get(originalVcfOutputFilePath + ".contigs"), - Paths.get(tempVcfOutputDir + "/accession-output.vcf.contigs")); + Paths.get(tempVcfOutputDir + "/accession-output.vcf.contigs")); moveFile(Paths.get(originalVcfOutputFilePath + ".variants"), - Paths.get(tempVcfOutputDir + "/accession-output.vcf.variants")); + Paths.get(tempVcfOutputDir + "/accession-output.vcf.variants")); } private void restoreContigAndVariantFilesFromTempFolder() { moveFile(Paths.get(tempVcfOutputDir + "/accession-output.vcf.contigs"), - Paths.get(Paths.get(originalVcfOutputFilePath).getParent() + "/accession-output.vcf.contigs")); + Paths.get(Paths.get(originalVcfOutputFilePath).getParent() + "/accession-output.vcf.contigs")); moveFile(Paths.get(tempVcfOutputDir + "/accession-output.vcf.variants"), - Paths.get(Paths.get(originalVcfOutputFilePath).getParent() + "/accession-output.vcf.variants")); + Paths.get(Paths.get(originalVcfOutputFilePath).getParent() + "/accession-output.vcf.variants")); } private void moveFile(Path source, Path destination) { try { Files.move(source, destination, StandardCopyOption.REPLACE_EXISTING); - } - catch (Exception ex) { + } catch (Exception ex) { if (!(ex instanceof NoSuchFileException)) { throw new RuntimeException(ex); } } } - private void writeToTempVCFFile(String modifiedVCFContent) throws IOException { - FileOutputStream outputStream = new FileOutputStream(tempVcfInputFileToTestFailingJobs.getAbsolutePath()); - GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream); - gzipOutputStream.write(modifiedVCFContent.getBytes(StandardCharsets.UTF_8)); - gzipOutputStream.close(); - } - - private String getOriginalVcfContent(String inputVcfPath) throws Exception { - StringBuilder originalVCFContent = new StringBuilder(); - - GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(inputVcfPath)); - BufferedReader reader = new BufferedReader(new InputStreamReader(gzipInputStream)); - - String read; - while ((read = reader.readLine()) != null) { - originalVCFContent.append(read).append(System.lineSeparator()); - } - return originalVCFContent.toString(); - } - - private void deleteTemporaryContigAndVariantFiles() throws Exception { - Files.deleteIfExists(Paths.get(inputParameters.getOutputVcf())); - Files.deleteIfExists(Paths.get(inputParameters.getOutputVcf() + ".variants")); - Files.deleteIfExists(Paths.get(inputParameters.getOutputVcf() + ".contigs")); - Files.deleteIfExists( - Paths.get(tempVcfOutputDir + "/accession-output.vcf.variants")); - Files.deleteIfExists( - Paths.get(tempVcfOutputDir + "/accession-output.vcf.contigs")); - } - private int getNumberOfLinesInVcfString(String vcfString) { return (int) Arrays.stream(vcfString.split(System.lineSeparator())) - .filter(line -> !line.startsWith("#")) - .count(); + .filter(line -> !line.startsWith("#")) + .count(); } } \ No newline at end of file diff --git a/eva-accession-pipeline/src/test/java/uk/ac/ebi/eva/accession/pipeline/runner/RestartFailedJobTest.java b/eva-accession-pipeline/src/test/java/uk/ac/ebi/eva/accession/pipeline/runner/RestartFailedJobTest.java index 61d320ec1..85e78a347 100644 --- a/eva-accession-pipeline/src/test/java/uk/ac/ebi/eva/accession/pipeline/runner/RestartFailedJobTest.java +++ b/eva-accession-pipeline/src/test/java/uk/ac/ebi/eva/accession/pipeline/runner/RestartFailedJobTest.java @@ -47,23 +47,13 @@ import uk.ac.ebi.eva.accession.pipeline.parameters.InputParameters; import uk.ac.ebi.eva.accession.pipeline.test.BatchTestConfiguration; import uk.ac.ebi.eva.commons.batch.io.VcfReader; -import uk.ac.ebi.eva.commons.core.utils.FileUtils; import uk.ac.ebi.eva.metrics.count.CountServiceParameters; import javax.sql.DataSource; -import java.io.BufferedReader; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; import java.net.URI; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -73,6 +63,13 @@ import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; import static uk.ac.ebi.eva.accession.pipeline.configuration.BeanNames.CREATE_SUBSNP_ACCESSION_JOB; import static uk.ac.ebi.eva.accession.pipeline.configuration.BeanNames.CREATE_SUBSNP_ACCESSION_STEP; +import static uk.ac.ebi.eva.accession.pipeline.runner.runnerUtil.deleteTemporaryContigAndVariantFiles; +import static uk.ac.ebi.eva.accession.pipeline.runner.runnerUtil.getOriginalVcfContent; +import static uk.ac.ebi.eva.accession.pipeline.runner.runnerUtil.injectErrorIntoTempVcf; +import static uk.ac.ebi.eva.accession.pipeline.runner.runnerUtil.remediateTempVcfError; +import static uk.ac.ebi.eva.accession.pipeline.runner.runnerUtil.useOriginalVcfFile; +import static uk.ac.ebi.eva.accession.pipeline.runner.runnerUtil.useTempVcfFile; +import static uk.ac.ebi.eva.accession.pipeline.runner.runnerUtil.writeToTempVCFFile; @RunWith(SpringRunner.class) @ContextConfiguration(classes = {BatchTestConfiguration.class}) @@ -146,13 +143,13 @@ public void setUp() throws Exception { originalVcfInputFilePath = inputParameters.getVcf(); originalVcfOutputFilePath = inputParameters.getOutputVcf(); originalVcfContent = getOriginalVcfContent(originalVcfInputFilePath); - writeToTempVCFFile(originalVcfContent); + writeToTempVCFFile(originalVcfContent, tempVcfInputFileToTestFailingJobs); originalInputParametersCaptured = true; } jobRepositoryTestUtils = new JobRepositoryTestUtils(jobRepository, datasource); runner.setJobNames(CREATE_SUBSNP_ACCESSION_JOB); - deleteTemporaryContigAndVariantFiles(); - useOriginalVcfFile(); + deleteTemporaryContigAndVariantFiles(inputParameters, tempVcfOutputDir); + useOriginalVcfFile(inputParameters, originalVcfInputFilePath, vcfReader); mockServer = MockRestServiceServer.createServer(restTemplate); mockServer.expect(ExpectedCount.manyTimes(), requestTo(new URI(countServiceParameters.getUrl() + URL_PATH_SAVE_COUNT))) @@ -171,18 +168,27 @@ public void tearDown() { inputParameters.setForceRestart(false); } + /* + * Separated this test from the rest of the tests in EvaAccessionJobLauncherCommandLineRunnerTest, + * as we have to Mock(Spy to be exact) on the SubmittedVariantAccessioningService bean in order to reuse the same + * without shutting down its accession generator. + * + * Ideally, we should not be Spying but rather the jobs when restarting should be using a new instance of the service. + * but it was tricky to inject, hence the workaround. + * */ @Test @DirtiesContext public void restartFailedJobThatIsAlreadyInTheRepository() throws Exception { - useTempVcfFile(); - injectErrorIntoTempVcf(); + useTempVcfFile(inputParameters, tempVcfInputFileToTestFailingJobs, vcfReader); + String modifiedVcfContent = originalVcfContent.replace("76852", "76852jibberish"); + injectErrorIntoTempVcf(modifiedVcfContent, tempVcfInputFileToTestFailingJobs); JobInstance failingJobInstance = runJobAandCheckResults(); mongoTemplate.dropCollection(SubmittedVariantEntity.class); inputParameters.setForceRestart(true); - remediateTempVcfError(); - deleteTemporaryContigAndVariantFiles(); //left behind by unsuccessful job A + remediateTempVcfError(originalVcfContent, tempVcfInputFileToTestFailingJobs); + deleteTemporaryContigAndVariantFiles(inputParameters, tempVcfOutputDir); //left behind by unsuccessful job A runJobBAndCheckRestart(failingJobInstance); } @@ -211,71 +217,4 @@ private void runJobBAndCheckRestart(JobInstance failingJobInstance) throws Excep assertNotEquals(failingJobInstance.getInstanceId(), currentJobInstance.getInstanceId()); } - private void injectErrorIntoTempVcf() throws Exception { - String modifiedVcfContent = originalVcfContent.replace("76852", "76852jibberish"); - // Inject error in the VCF file to cause processing to stop at variant#9 - writeToTempVCFFile(modifiedVcfContent); - } - - private void remediateTempVcfError() throws Exception { - writeToTempVCFFile(originalVcfContent); - } - - private void useOriginalVcfFile() throws Exception { - inputParameters.setVcf(originalVcfInputFilePath); - vcfReader.setResource(FileUtils.getResource(new File(originalVcfInputFilePath))); - } - - private void useTempVcfFile() throws Exception { - // The following does not actually change the wiring of the vcfReader since the wiring happens before the tests - // This setVcf is only to facilitate identifying jobs in the job repo by parameter - // (those that use original vs temp VCF) - inputParameters.setVcf(tempVcfInputFileToTestFailingJobs.getAbsolutePath()); - /* - * Change the auto-wired VCF for VCFReader at runtime - * Rationale: - * 1) Why not use two test configurations, one for a VCF that fails validation and another for a VCF - * that won't and test resumption? - * Beginning Spring Boot 2, job resumption can only happen when input parameters to the restarted job - * is the same as the failed job. - * Therefore, a test to check resumption cannot have two different config files with different - * parameters.vcf. - * This test therefore creates a dynamic VCF and injects errors at runtime to the VCF thus preserving - * the VCF parameter but changing the VCF content. - * 2) Why not artificially inject a VcfReader exception? - * This will preclude us from verifying job resumption from a precise line in the VCF. - */ - vcfReader.setResource(FileUtils.getResource(tempVcfInputFileToTestFailingJobs)); - } - - private void writeToTempVCFFile(String modifiedVCFContent) throws IOException { - FileOutputStream outputStream = new FileOutputStream(tempVcfInputFileToTestFailingJobs.getAbsolutePath()); - GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream); - gzipOutputStream.write(modifiedVCFContent.getBytes(StandardCharsets.UTF_8)); - gzipOutputStream.close(); - } - - private String getOriginalVcfContent(String inputVcfPath) throws Exception { - StringBuilder originalVCFContent = new StringBuilder(); - - GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(inputVcfPath)); - BufferedReader reader = new BufferedReader(new InputStreamReader(gzipInputStream)); - - String read; - while ((read = reader.readLine()) != null) { - originalVCFContent.append(read).append(System.lineSeparator()); - } - return originalVCFContent.toString(); - } - - private void deleteTemporaryContigAndVariantFiles() throws Exception { - Files.deleteIfExists(Paths.get(inputParameters.getOutputVcf())); - Files.deleteIfExists(Paths.get(inputParameters.getOutputVcf() + ".variants")); - Files.deleteIfExists(Paths.get(inputParameters.getOutputVcf() + ".contigs")); - Files.deleteIfExists( - Paths.get(tempVcfOutputDir + "/accession-output.vcf.variants")); - Files.deleteIfExists( - Paths.get(tempVcfOutputDir + "/accession-output.vcf.contigs")); - } - } \ No newline at end of file diff --git a/eva-accession-pipeline/src/test/java/uk/ac/ebi/eva/accession/pipeline/runner/runnerUtil.java b/eva-accession-pipeline/src/test/java/uk/ac/ebi/eva/accession/pipeline/runner/runnerUtil.java new file mode 100644 index 000000000..3b3975d64 --- /dev/null +++ b/eva-accession-pipeline/src/test/java/uk/ac/ebi/eva/accession/pipeline/runner/runnerUtil.java @@ -0,0 +1,84 @@ +package uk.ac.ebi.eva.accession.pipeline.runner; + +import uk.ac.ebi.eva.accession.pipeline.parameters.InputParameters; +import uk.ac.ebi.eva.commons.batch.io.VcfReader; +import uk.ac.ebi.eva.commons.core.utils.FileUtils; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +public class runnerUtil { + public static void injectErrorIntoTempVcf(String modifiedVcfContent, File tempVcfInputFile) throws Exception { + // Inject error in the VCF file to cause processing to stop at variant#9 + writeToTempVCFFile(modifiedVcfContent, tempVcfInputFile); + } + + public static void remediateTempVcfError(String originalVcfContent, File tempVcfInputFile) throws Exception { + writeToTempVCFFile(originalVcfContent, tempVcfInputFile); + } + + public static void useOriginalVcfFile(InputParameters inputParameters, String originalVcfInputFilePath, VcfReader vcfReader) throws Exception { + inputParameters.setVcf(originalVcfInputFilePath); + vcfReader.setResource(FileUtils.getResource(new File(originalVcfInputFilePath))); + } + + public static void useTempVcfFile(InputParameters inputParameters, File tempVcfInputFile, VcfReader vcfReader) throws Exception { + // The following does not actually change the wiring of the vcfReader since the wiring happens before the tests + // This setVcf is only to facilitate identifying jobs in the job repo by parameter + // (those that use original vs temp VCF) + inputParameters.setVcf(tempVcfInputFile.getAbsolutePath()); + /* + * Change the auto-wired VCF for VCFReader at runtime + * Rationale: + * 1) Why not use two test configurations, one for a VCF that fails validation and another for a VCF + * that won't and test resumption? + * Beginning Spring Boot 2, job resumption can only happen when input parameters to the restarted job + * is the same as the failed job. + * Therefore, a test to check resumption cannot have two different config files with different + * parameters.vcf. + * This test therefore creates a dynamic VCF and injects errors at runtime to the VCF thus preserving + * the VCF parameter but changing the VCF content. + * 2) Why not artificially inject a VcfReader exception? + * This will preclude us from verifying job resumption from a precise line in the VCF. + */ + vcfReader.setResource(FileUtils.getResource(tempVcfInputFile)); + } + + public static void writeToTempVCFFile(String modifiedVCFContent, File tempVcfInputFile) throws IOException { + FileOutputStream outputStream = new FileOutputStream(tempVcfInputFile.getAbsolutePath()); + GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream); + gzipOutputStream.write(modifiedVCFContent.getBytes(StandardCharsets.UTF_8)); + gzipOutputStream.close(); + } + + public static String getOriginalVcfContent(String inputVcfPath) throws Exception { + StringBuilder originalVCFContent = new StringBuilder(); + + GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(inputVcfPath)); + BufferedReader reader = new BufferedReader(new InputStreamReader(gzipInputStream)); + + String read; + while ((read = reader.readLine()) != null) { + originalVCFContent.append(read).append(System.lineSeparator()); + } + return originalVCFContent.toString(); + } + + public static void deleteTemporaryContigAndVariantFiles(InputParameters inputParameters, Path tempVcfOutputDir) throws Exception { + Files.deleteIfExists(Paths.get(inputParameters.getOutputVcf())); + Files.deleteIfExists(Paths.get(inputParameters.getOutputVcf() + ".variants")); + Files.deleteIfExists(Paths.get(inputParameters.getOutputVcf() + ".contigs")); + Files.deleteIfExists(Paths.get(tempVcfOutputDir + "/accession-output.vcf.variants")); + Files.deleteIfExists(Paths.get(tempVcfOutputDir + "/accession-output.vcf.contigs")); + } +}