1 package org.broadinstitute.hellbender.tools.spark; 2 3 import htsjdk.samtools.SBIIndex; 4 import htsjdk.samtools.util.FileExtensions; 5 import htsjdk.samtools.util.IOUtil; 6 import org.broadinstitute.barclay.argparser.CommandLineException; 7 import org.broadinstitute.hellbender.CommandLineProgramTest; 8 import org.broadinstitute.hellbender.exceptions.UserException; 9 import org.broadinstitute.hellbender.utils.io.IOUtils; 10 import org.broadinstitute.hellbender.testutils.ArgumentsBuilder; 11 import org.testng.Assert; 12 import org.testng.annotations.DataProvider; 13 import org.testng.annotations.Test; 14 15 import java.io.File; 16 import java.io.IOException; 17 import java.nio.file.Files; 18 import java.nio.file.StandardCopyOption; 19 20 21 public class CreateHadoopBamSplittingIndexIntegrationTest extends CommandLineProgramTest{ 22 23 private final File UNSORTED_BAM = getTestFile("count_reads.bam"); 24 private final File SORTED_BAM = getTestFile("count_reads_sorted.bam"); 25 26 @DataProvider(name="indexable") getIndexableFiles()27 public Object[][] getIndexableFiles(){ 28 return new Object[][]{ 29 {UNSORTED_BAM}, 30 {SORTED_BAM} 31 }; 32 } 33 34 @Test(dataProvider = "indexable") testCreateSplittingIndex(final File bam)35 public void testCreateSplittingIndex(final File bam) throws IOException { 36 final File splittingIndex = getTempIndexFile(); 37 splittingIndex.delete(); 38 Assert.assertFalse(splittingIndex.exists()); 39 final ArgumentsBuilder args = getInputAndOutputArgs(bam, splittingIndex) 40 .addRaw("--"+ CreateHadoopBamSplittingIndex.SPLITTING_INDEX_GRANULARITY_LONG_NAME).addRaw("1"); 41 this.runCommandLine(args); 42 assertIndexIsNotEmpty(splittingIndex); 43 44 //checked in index created with 45 // ./gatk CreateHadoopBamSplittingIndex --input <filename> --splitting-index-granularity 1 46 final File expectedSplittingIndex = new File(bam.toPath() + FileExtensions.SBI); 47 48 IOUtil.assertFilesEqual(splittingIndex, expectedSplittingIndex); 49 } 50 assertIndexIsNotEmpty(final File splittingIndex)51 private static void assertIndexIsNotEmpty(final File splittingIndex) throws IOException { 52 Assert.assertTrue(splittingIndex.exists()); 53 final SBIIndex splittingBAMIndex = SBIIndex.load(splittingIndex.toPath()); 54 Assert.assertTrue(splittingBAMIndex.size() > 0 ); 55 } 56 57 @Test(expectedExceptions = CommandLineException.BadArgumentValue.class) testNegativeGranularity()58 public void testNegativeGranularity(){ 59 final ArgumentsBuilder args = getInputAndOutputArgs(SORTED_BAM, getTempIndexFile()) 60 .addRaw("--"+ CreateHadoopBamSplittingIndex.SPLITTING_INDEX_GRANULARITY_LONG_NAME).addRaw(-10); 61 this.runCommandLine(args); 62 } 63 64 @DataProvider(name="unindexable") getUnindexableFiles()65 public Object[][] getUnindexableFiles(){ 66 return new Object[][]{ 67 {getTestFile("count_reads.cram")}, 68 {getTestFile("count_reads.sam")} 69 }; 70 } 71 72 @Test(expectedExceptions = UserException.BadInput.class, dataProvider = "unindexable") testUnindexableFilesFail(final File badFile)73 public void testUnindexableFilesFail(final File badFile){ 74 final ArgumentsBuilder args = getInputAndOutputArgs(badFile, getTempIndexFile()); 75 this.runCommandLine(args); 76 } 77 78 @Test(dataProvider = "indexable") testUnspecifiedOutputProducesAdjacentIndex(final File bam)79 public void testUnspecifiedOutputProducesAdjacentIndex(final File bam) throws IOException { 80 // copy the bam file to a new temp file 81 // we're going to write an index next to it on disk, and we don't want to write into the test resources folder 82 final File bamCopy = createTempFile("copy-"+bam, ".bam"); 83 Files.copy(bam.toPath(), bamCopy.toPath(), StandardCopyOption.REPLACE_EXISTING); 84 final File expectedIndex = new File(bamCopy.toPath() + FileExtensions.SBI); 85 Assert.assertFalse(expectedIndex.exists()); 86 final ArgumentsBuilder args = new ArgumentsBuilder().addInput(bamCopy); 87 this.runCommandLine(args); 88 expectedIndex.deleteOnExit(); 89 assertIndexIsNotEmpty(expectedIndex); 90 } 91 92 @Test testBothPathsProduceSameIndex()93 public void testBothPathsProduceSameIndex() throws IOException { 94 final File splittingIndexOnly = getTempIndexFile(); 95 final ArgumentsBuilder splittingIndexOnlyArgs = getInputAndOutputArgs(SORTED_BAM, splittingIndexOnly); 96 this.runCommandLine(splittingIndexOnlyArgs); 97 assertIndexIsNotEmpty(splittingIndexOnly); 98 99 final File splittingIndexWithBai = getTempIndexFile(); 100 final ArgumentsBuilder splittingAndBaiArgs = getInputAndOutputArgs(SORTED_BAM, splittingIndexWithBai) 101 .addRaw("--"+ CreateHadoopBamSplittingIndex.CREATE_BAI_LONG_NAME); 102 this.runCommandLine(splittingAndBaiArgs); 103 assertIndexIsNotEmpty(splittingIndexWithBai); 104 105 IOUtil.assertFilesEqual(splittingIndexOnly, splittingIndexWithBai); 106 } 107 getInputAndOutputArgs(final File inputFile, final File splittingIndexWithBai)108 public ArgumentsBuilder getInputAndOutputArgs(final File inputFile, final File splittingIndexWithBai) { 109 return new ArgumentsBuilder() 110 .addInput(inputFile) 111 .addOutput(splittingIndexWithBai); 112 } 113 114 @Test testCreateWithBaiCreatesBai()115 public void testCreateWithBaiCreatesBai(){ 116 final File splittingIndex = getTempIndexFile(); 117 final File baiIndex = IOUtils.replaceExtension(splittingIndex, FileExtensions.BAI_INDEX); 118 Assert.assertFalse(baiIndex.exists()); 119 final ArgumentsBuilder args = getInputAndOutputArgs(SORTED_BAM, splittingIndex) 120 .addRaw("--" + CreateHadoopBamSplittingIndex.CREATE_BAI_LONG_NAME); 121 this.runCommandLine(args); 122 Assert.assertTrue(baiIndex.exists()); 123 } 124 125 @Test(expectedExceptions = UserException.BadInput.class) testCantCreateBaiForUnsortedFile()126 public void testCantCreateBaiForUnsortedFile(){ 127 final ArgumentsBuilder args = getInputAndOutputArgs(UNSORTED_BAM, getTempIndexFile()) 128 .addRaw("--"+ CreateHadoopBamSplittingIndex.CREATE_BAI_LONG_NAME); 129 this.runCommandLine(args); 130 } 131 getTempIndexFile()132 private static File getTempIndexFile() { 133 return createTempFile("index", "bam" + FileExtensions.SBI); 134 } 135 136 137 } 138