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