package org.broadinstitute.hellbender.tools; import htsjdk.samtools.ValidationStringency; import org.broadinstitute.hellbender.CommandLineProgramTest; import org.broadinstitute.hellbender.cmdline.StandardArgumentDefinitions; import org.broadinstitute.hellbender.exceptions.UserException; import org.broadinstitute.hellbender.testutils.ArgumentsBuilder; import org.broadinstitute.hellbender.testutils.IntegrationTestSpec; import org.broadinstitute.hellbender.testutils.SamAssertionUtils; import org.broadinstitute.hellbender.utils.Utils; import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.util.Collections; import java.util.Map; import com.google.common.collect.ImmutableMap; public class HtsgetReaderIntegrationTest extends CommandLineProgramTest { private static final String ENDPOINT = "https://htsget.ga4gh.org/reads"; private static final String FILE_ID = "A1-B000168-3_57_F-1-1_R2.mus.Aligned.out.sorted.bam"; private static final String LARGE_FILE_ID = "10X_P8_15_possorted_genome.bam"; private static final String LARGE_FILE_MD5_FILE = "md5_checksum"; @DataProvider(name = "successfulParameters") Object[][] successfulParameters() { return new Object[][] { { // basic download test ImmutableMap.of( HtsgetReader.ID_LONG_NAME, FILE_ID), "A1-B000168-3_57_F-1-1_R2.mus.Aligned.out.sorted.bam" }, { // parallel download test ImmutableMap.of( HtsgetReader.ID_LONG_NAME, FILE_ID, StandardArgumentDefinitions.INTERVALS_LONG_NAME, "chr1", HtsgetReader.NUM_THREADS_LONG_NAME, "2"), "A1-B000168-3_57_F-1-1_R2.mus.Aligned.out.sorted.bam.refname" }, { // header only ImmutableMap.of( HtsgetReader.ID_LONG_NAME, FILE_ID, HtsgetReader.CLASS_LONG_NAME, "header"), "A1-B000168-3_57_F-1-1_R2.mus.Aligned.out.sorted.bam.header" }, { // reference name without range ImmutableMap.of( HtsgetReader.ID_LONG_NAME, FILE_ID, StandardArgumentDefinitions.INTERVALS_LONG_NAME, "chr1"), "A1-B000168-3_57_F-1-1_R2.mus.Aligned.out.sorted.bam.refname" }, { // reference name with range ImmutableMap.of( HtsgetReader.ID_LONG_NAME, FILE_ID, StandardArgumentDefinitions.INTERVALS_LONG_NAME, "chr1:24000000-25000000"), "A1-B000168-3_57_F-1-1_R2.mus.Aligned.out.sorted.bam.startend" }, // TODO enable when server update goes in // { // filter by field // ImmutableMap.of( // HtsgetReader.ID_LONG_NAME, FILE_ID, // HtsgetReader.FIELDS_LONG_NAME, "QNAME"), // "A1-B000168-3_57_F-1-1_R2.mus.Aligned.out.sorted.bam.field" // } }; } // Test successful combinations of query parameters @Test(dataProvider = "successfulParameters") public void testSuccessfulParameters(final Map<String, String> params, final String expectedFileName) throws IOException { final File expected = new File(getToolTestDataDir(), expectedFileName); final File output = createTempFile("output", ".bam"); final ArgumentsBuilder args = new ArgumentsBuilder() .add(HtsgetReader.URL_LONG_NAME, ENDPOINT) .addOutput(output); params.forEach(args::add); runCommandLine(args); SamAssertionUtils.assertEqualBamFiles(output, expected, false, ValidationStringency.LENIENT); } //This test is disabled because it takes a long time. It's included in order to run it manually. @Test(enabled = false) public void testLargeFileParallelDownload() throws IOException { final String expectedMd5 = new String(Files.readAllBytes(new File(getToolTestDataDir(), LARGE_FILE_MD5_FILE).toPath())); final File output = createTempFile("output", ".bam"); final ArgumentsBuilder args = new ArgumentsBuilder() .add(HtsgetReader.URL_LONG_NAME, ENDPOINT) .add(HtsgetReader.ID_LONG_NAME, LARGE_FILE_ID) .add(HtsgetReader.NUM_THREADS_LONG_NAME, 4) .addOutput(output); runCommandLine(args); final String md5String = Utils.calculateFileMD5(output); Assert.assertEquals(md5String, expectedMd5); } @DataProvider(name = "failureParameters") Object[][] failureParameters() { return new Object[][] { { // Invalid sample id ImmutableMap.of( HtsgetReader.URL_LONG_NAME, ENDPOINT, HtsgetReader.ID_LONG_NAME, "nonexistentSample" ) }, { // Invalid endpoint ImmutableMap.of( HtsgetReader.URL_LONG_NAME, "invalidEndpoint", HtsgetReader.ID_LONG_NAME, FILE_ID ) }, { // Nonexistent contig ImmutableMap.of( HtsgetReader.URL_LONG_NAME, ENDPOINT, HtsgetReader.ID_LONG_NAME, FILE_ID, StandardArgumentDefinitions.INTERVALS_LONG_NAME, "nonexistentInterval" ) } }; } // Test parameters that result in invalid request @Test(dataProvider = "failureParameters", expectedExceptions = UserException.class) public void testFailureParameters(final Map<String, String> params) { final File output = createTempFile("output", ".bam"); final ArgumentsBuilder args = new ArgumentsBuilder() .addOutput(output); params.forEach(args::add); runCommandLine(args); } }