Commit cfa8e19f by ibaker Committed by Ian Baker

Use parameterization in most extractor tests

Part of what makes these tests hard to deal with (imo) is being
unable to easily run a specific config, or seeing exactly which one
failed (because you always see only the first failure).

I put the parameters as a method on ExtractorAsserts to
reduce the boiler-plate required in each test class.

I'll migrate the extension FlacExtractorTest in a follow-up CL

PiperOrigin-RevId: 307785380
parent 1b6a32f2
Showing with 422 additions and 98 deletions
......@@ -22,7 +22,6 @@ import static com.google.android.exoplayer2.extractor.amr.AmrExtractor.frameSize
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.fail;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.extractor.Extractor;
import com.google.android.exoplayer2.extractor.PositionHolder;
......@@ -31,16 +30,29 @@ import com.google.android.exoplayer2.testutil.FakeExtractorInput;
import com.google.android.exoplayer2.testutil.FakeExtractorOutput;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
import java.util.List;
import java.util.Random;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameter;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
/** Unit test for {@link AmrExtractor}. */
@RunWith(AndroidJUnit4.class)
// TODO(ibaker): Split this into two test classes: one parameterized, and one not.
@RunWith(ParameterizedRobolectricTestRunner.class)
public final class AmrExtractorTest {
private static final Random RANDOM = new Random(1234);
@Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void sniff_nonAmrSignature_returnFalse() throws IOException {
AmrExtractor amrExtractor = setupAmrExtractorWithOutput();
......@@ -172,25 +184,29 @@ public final class AmrExtractorTest {
@Test
public void extractingNarrowBandSamples() throws Exception {
ExtractorAsserts.assertBehavior(
createAmrExtractorFactory(/* withSeeking= */ false), "amr/sample_nb.amr");
createAmrExtractorFactory(/* withSeeking= */ false), "amr/sample_nb.amr", assertionConfig);
}
@Test
public void extractingWideBandSamples() throws Exception {
ExtractorAsserts.assertBehavior(
createAmrExtractorFactory(/* withSeeking= */ false), "amr/sample_wb.amr");
createAmrExtractorFactory(/* withSeeking= */ false), "amr/sample_wb.amr", assertionConfig);
}
@Test
public void extractingNarrowBandSamples_withSeeking() throws Exception {
ExtractorAsserts.assertBehavior(
createAmrExtractorFactory(/* withSeeking= */ true), "amr/sample_nb_cbr.amr");
createAmrExtractorFactory(/* withSeeking= */ true),
"amr/sample_nb_cbr.amr",
assertionConfig);
}
@Test
public void extractingWideBandSamples_withSeeking() throws Exception {
ExtractorAsserts.assertBehavior(
createAmrExtractorFactory(/* withSeeking= */ true), "amr/sample_wb_cbr.amr");
createAmrExtractorFactory(/* withSeeking= */ true),
"amr/sample_wb_cbr.amr",
assertionConfig);
}
private byte[] newWideBandAmrFrameWithType(int frameType) {
......
......@@ -16,20 +16,32 @@
package com.google.android.exoplayer2.extractor.flac;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameter;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
/** Unit tests for {@link FlacExtractor}. */
@RunWith(AndroidJUnit4.class)
@RunWith(ParameterizedRobolectricTestRunner.class)
public class FlacExtractorTest {
@Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void sample() throws Exception {
ExtractorAsserts.assertBehavior(
FlacExtractor::new,
/* file= */ "flac/bear.flac",
assertionConfig,
ApplicationProvider.getApplicationContext(),
/* dumpFilesPrefix= */ "flac/bear_flac");
}
......@@ -39,6 +51,7 @@ public class FlacExtractorTest {
ExtractorAsserts.assertBehavior(
FlacExtractor::new,
/* file= */ "flac/bear_with_id3.flac",
assertionConfig,
ApplicationProvider.getApplicationContext(),
/* dumpFilesPrefix= */ "flac/bear_with_id3_enabled_flac");
}
......@@ -48,6 +61,7 @@ public class FlacExtractorTest {
ExtractorAsserts.assertBehavior(
() -> new FlacExtractor(FlacExtractor.FLAG_DISABLE_ID3_METADATA),
/* file= */ "flac/bear_with_id3.flac",
assertionConfig,
ApplicationProvider.getApplicationContext(),
/* dumpFilesPrefix= */ "flac/bear_with_id3_disabled_flac");
}
......@@ -57,6 +71,7 @@ public class FlacExtractorTest {
ExtractorAsserts.assertBehavior(
FlacExtractor::new,
/* file= */ "flac/bear_no_seek_table_no_num_samples.flac",
assertionConfig,
ApplicationProvider.getApplicationContext(),
/* dumpFilesPrefix= */ "flac/bear_no_seek_table_no_num_samples_flac");
}
......@@ -66,6 +81,7 @@ public class FlacExtractorTest {
ExtractorAsserts.assertBehavior(
FlacExtractor::new,
/* file= */ "flac/bear_with_vorbis_comments.flac",
assertionConfig,
ApplicationProvider.getApplicationContext(),
/* dumpFilesPrefix= */ "flac/bear_with_vorbis_comments_flac");
}
......@@ -75,6 +91,7 @@ public class FlacExtractorTest {
ExtractorAsserts.assertBehavior(
FlacExtractor::new,
/* file= */ "flac/bear_with_picture.flac",
assertionConfig,
ApplicationProvider.getApplicationContext(),
/* dumpFilesPrefix= */ "flac/bear_with_picture_flac");
}
......@@ -84,6 +101,7 @@ public class FlacExtractorTest {
ExtractorAsserts.assertBehavior(
FlacExtractor::new,
/* file= */ "flac/bear_one_metadata_block.flac",
assertionConfig,
ApplicationProvider.getApplicationContext(),
/* dumpFilesPrefix= */ "flac/bear_one_metadata_block_flac");
}
......@@ -93,6 +111,7 @@ public class FlacExtractorTest {
ExtractorAsserts.assertBehavior(
FlacExtractor::new,
/* file= */ "flac/bear_no_min_max_frame_size.flac",
assertionConfig,
ApplicationProvider.getApplicationContext(),
/* dumpFilesPrefix= */ "flac/bear_no_min_max_frame_size_flac");
}
......@@ -102,6 +121,7 @@ public class FlacExtractorTest {
ExtractorAsserts.assertBehavior(
FlacExtractor::new,
/* file= */ "flac/bear_no_num_samples.flac",
assertionConfig,
ApplicationProvider.getApplicationContext(),
/* dumpFilesPrefix= */ "flac/bear_no_num_samples_flac");
}
......@@ -111,6 +131,7 @@ public class FlacExtractorTest {
ExtractorAsserts.assertBehavior(
FlacExtractor::new,
/* file= */ "flac/bear_uncommon_sample_rate.flac",
assertionConfig,
ApplicationProvider.getApplicationContext(),
/* dumpFilesPrefix= */ "flac/bear_uncommon_sample_rate_flac");
}
......
......@@ -15,17 +15,28 @@
*/
package com.google.android.exoplayer2.extractor.flv;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameter;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
/** Unit test for {@link FlvExtractor}. */
@RunWith(AndroidJUnit4.class)
@RunWith(ParameterizedRobolectricTestRunner.class)
public final class FlvExtractorTest {
@Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void sample() throws Exception {
ExtractorAsserts.assertBehavior(FlvExtractor::new, "flv/sample.flv");
ExtractorAsserts.assertBehavior(FlvExtractor::new, "flv/sample.flv", assertionConfig);
}
}
......@@ -15,44 +15,57 @@
*/
package com.google.android.exoplayer2.extractor.mkv;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameter;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
/** Tests for {@link MatroskaExtractor}. */
@RunWith(AndroidJUnit4.class)
@RunWith(ParameterizedRobolectricTestRunner.class)
public final class MatroskaExtractorTest {
@Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void mkvSample() throws Exception {
ExtractorAsserts.assertBehavior(MatroskaExtractor::new, "mkv/sample.mkv");
ExtractorAsserts.assertBehavior(MatroskaExtractor::new, "mkv/sample.mkv", assertionConfig);
}
@Test
public void mkvSample_withSubripSubtitles() throws Exception {
ExtractorAsserts.assertBehavior(MatroskaExtractor::new, "mkv/sample_with_srt.mkv");
ExtractorAsserts.assertBehavior(
MatroskaExtractor::new, "mkv/sample_with_srt.mkv", assertionConfig);
}
@Test
public void mkvSample_withHtcRotationInfoInTrackName() throws Exception {
ExtractorAsserts.assertBehavior(
MatroskaExtractor::new, "mkv/sample_with_htc_rotation_track_name.mkv");
MatroskaExtractor::new, "mkv/sample_with_htc_rotation_track_name.mkv", assertionConfig);
}
@Test
public void mkvFullBlocksSample() throws Exception {
ExtractorAsserts.assertBehavior(MatroskaExtractor::new, "mkv/full_blocks.mkv");
ExtractorAsserts.assertBehavior(MatroskaExtractor::new, "mkv/full_blocks.mkv", assertionConfig);
}
@Test
public void webmSubsampleEncryption() throws Exception {
ExtractorAsserts.assertBehavior(
MatroskaExtractor::new, "mkv/subsample_encrypted_noaltref.webm");
MatroskaExtractor::new, "mkv/subsample_encrypted_noaltref.webm", assertionConfig);
}
@Test
public void webmSubsampleEncryptionWithAltrefFrames() throws Exception {
ExtractorAsserts.assertBehavior(MatroskaExtractor::new, "mkv/subsample_encrypted_altref.webm");
ExtractorAsserts.assertBehavior(
MatroskaExtractor::new, "mkv/subsample_encrypted_altref.webm", assertionConfig);
}
}
......@@ -16,36 +16,49 @@
package com.google.android.exoplayer2.extractor.mp3;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameter;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
/** Unit test for {@link Mp3Extractor}. */
@RunWith(AndroidJUnit4.class)
@RunWith(ParameterizedRobolectricTestRunner.class)
public final class Mp3ExtractorTest {
@Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void mp3SampleWithXingHeader() throws Exception {
ExtractorAsserts.assertBehavior(Mp3Extractor::new, "mp3/bear-vbr-xing-header.mp3");
ExtractorAsserts.assertBehavior(
Mp3Extractor::new, "mp3/bear-vbr-xing-header.mp3", assertionConfig);
}
@Test
public void mp3SampleWithCbrSeeker() throws Exception {
ExtractorAsserts.assertBehavior(
Mp3Extractor::new, "mp3/bear-cbr-variable-frame-size-no-seek-table.mp3");
Mp3Extractor::new, "mp3/bear-cbr-variable-frame-size-no-seek-table.mp3", assertionConfig);
}
@Test
public void mp3SampleWithIndexSeeker() throws Exception {
ExtractorAsserts.assertBehavior(
() -> new Mp3Extractor(Mp3Extractor.FLAG_ENABLE_INDEX_SEEKING),
"mp3/bear-vbr-no-seek-table.mp3");
"mp3/bear-vbr-no-seek-table.mp3",
assertionConfig);
}
@Test
public void trimmedMp3Sample() throws Exception {
ExtractorAsserts.assertBehavior(Mp3Extractor::new, "mp3/play-trimmed.mp3");
ExtractorAsserts.assertBehavior(Mp3Extractor::new, "mp3/play-trimmed.mp3", assertionConfig);
}
@Test
......@@ -53,6 +66,7 @@ public final class Mp3ExtractorTest {
ExtractorAsserts.assertBehavior(
Mp3Extractor::new,
/* file= */ "mp3/bear-id3.mp3",
assertionConfig,
ApplicationProvider.getApplicationContext(),
/* dumpFilesPrefix= */ "mp3/bear-id3-enabled");
}
......@@ -62,6 +76,7 @@ public final class Mp3ExtractorTest {
ExtractorAsserts.assertBehavior(
() -> new Mp3Extractor(Mp3Extractor.FLAG_DISABLE_ID3_METADATA),
/* file= */ "mp3/bear-id3.mp3",
assertionConfig,
ApplicationProvider.getApplicationContext(),
/* dumpFilesPrefix= */ "mp3/bear-id3-disabled");
}
......
......@@ -15,7 +15,6 @@
*/
package com.google.android.exoplayer2.extractor.mp4;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
......@@ -25,21 +24,34 @@ import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameter;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
/** Unit test for {@link FragmentedMp4Extractor}. */
@RunWith(AndroidJUnit4.class)
@RunWith(ParameterizedRobolectricTestRunner.class)
public final class FragmentedMp4ExtractorTest {
@Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void sample() throws Exception {
ExtractorAsserts.assertBehavior(
getExtractorFactory(ImmutableList.of()), "mp4/sample_fragmented.mp4");
getExtractorFactory(ImmutableList.of()), "mp4/sample_fragmented.mp4", assertionConfig);
}
@Test
public void sampleSeekable() throws Exception {
ExtractorAsserts.assertBehavior(
getExtractorFactory(ImmutableList.of()), "mp4/sample_fragmented_seekable.mp4");
getExtractorFactory(ImmutableList.of()),
"mp4/sample_fragmented_seekable.mp4",
assertionConfig);
}
@Test
......@@ -49,37 +61,40 @@ public final class FragmentedMp4ExtractorTest {
getExtractorFactory(
Collections.singletonList(
new Format.Builder().setSampleMimeType(MimeTypes.APPLICATION_CEA608).build()));
ExtractorAsserts.assertBehavior(extractorFactory, "mp4/sample_fragmented_sei.mp4");
ExtractorAsserts.assertBehavior(
extractorFactory, "mp4/sample_fragmented_sei.mp4", assertionConfig);
}
@Test
public void sampleWithAc3Track() throws Exception {
ExtractorAsserts.assertBehavior(
getExtractorFactory(ImmutableList.of()), "mp4/sample_ac3_fragmented.mp4");
getExtractorFactory(ImmutableList.of()), "mp4/sample_ac3_fragmented.mp4", assertionConfig);
}
@Test
public void sampleWithAc4Track() throws Exception {
ExtractorAsserts.assertBehavior(
getExtractorFactory(ImmutableList.of()), "mp4/sample_ac4_fragmented.mp4");
getExtractorFactory(ImmutableList.of()), "mp4/sample_ac4_fragmented.mp4", assertionConfig);
}
@Test
public void sampleWithProtectedAc4Track() throws Exception {
ExtractorAsserts.assertBehavior(
getExtractorFactory(ImmutableList.of()), "mp4/sample_ac4_protected.mp4");
getExtractorFactory(ImmutableList.of()), "mp4/sample_ac4_protected.mp4", assertionConfig);
}
@Test
public void sampleWithEac3Track() throws Exception {
ExtractorAsserts.assertBehavior(
getExtractorFactory(ImmutableList.of()), "mp4/sample_eac3_fragmented.mp4");
getExtractorFactory(ImmutableList.of()), "mp4/sample_eac3_fragmented.mp4", assertionConfig);
}
@Test
public void sampleWithEac3jocTrack() throws Exception {
ExtractorAsserts.assertBehavior(
getExtractorFactory(ImmutableList.of()), "mp4/sample_eac3joc_fragmented.mp4");
getExtractorFactory(ImmutableList.of()),
"mp4/sample_eac3joc_fragmented.mp4",
assertionConfig);
}
private static ExtractorFactory getExtractorFactory(final List<Format> closedCaptionFormats) {
......
......@@ -15,23 +15,35 @@
*/
package com.google.android.exoplayer2.extractor.mp4;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameter;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
/** Tests for {@link Mp4Extractor}. */
@RunWith(AndroidJUnit4.class)
@RunWith(ParameterizedRobolectricTestRunner.class)
public final class Mp4ExtractorTest {
@Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void mp4Sample() throws Exception {
ExtractorAsserts.assertBehavior(Mp4Extractor::new, "mp4/sample.mp4");
ExtractorAsserts.assertBehavior(Mp4Extractor::new, "mp4/sample.mp4", assertionConfig);
}
@Test
public void mp4SampleWithSlowMotionMetadata() throws Exception {
ExtractorAsserts.assertBehavior(Mp4Extractor::new, "mp4/sample_android_slow_motion.mp4");
ExtractorAsserts.assertBehavior(
Mp4Extractor::new, "mp4/sample_android_slow_motion.mp4", assertionConfig);
}
/**
......@@ -40,26 +52,27 @@ public final class Mp4ExtractorTest {
*/
@Test
public void mp4SampleWithMdatTooLong() throws Exception {
ExtractorAsserts.assertBehavior(Mp4Extractor::new, "mp4/sample_mdat_too_long.mp4");
ExtractorAsserts.assertBehavior(
Mp4Extractor::new, "mp4/sample_mdat_too_long.mp4", assertionConfig);
}
@Test
public void mp4SampleWithAc3Track() throws Exception {
ExtractorAsserts.assertBehavior(Mp4Extractor::new, "mp4/sample_ac3.mp4");
ExtractorAsserts.assertBehavior(Mp4Extractor::new, "mp4/sample_ac3.mp4", assertionConfig);
}
@Test
public void mp4SampleWithAc4Track() throws Exception {
ExtractorAsserts.assertBehavior(Mp4Extractor::new, "mp4/sample_ac4.mp4");
ExtractorAsserts.assertBehavior(Mp4Extractor::new, "mp4/sample_ac4.mp4", assertionConfig);
}
@Test
public void mp4SampleWithEac3Track() throws Exception {
ExtractorAsserts.assertBehavior(Mp4Extractor::new, "mp4/sample_eac3.mp4");
ExtractorAsserts.assertBehavior(Mp4Extractor::new, "mp4/sample_eac3.mp4", assertionConfig);
}
@Test
public void mp4SampleWithEac3jocTrack() throws Exception {
ExtractorAsserts.assertBehavior(Mp4Extractor::new, "mp4/sample_eac3joc.mp4");
ExtractorAsserts.assertBehavior(Mp4Extractor::new, "mp4/sample_eac3joc.mp4", assertionConfig);
}
}
......@@ -18,38 +18,49 @@ package com.google.android.exoplayer2.extractor.ogg;
import static com.google.android.exoplayer2.testutil.TestUtil.getByteArray;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.testutil.ExtractorAsserts.ExtractorFactory;
import com.google.android.exoplayer2.testutil.FakeExtractorInput;
import java.io.IOException;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameter;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
/** Unit test for {@link OggExtractor}. */
@RunWith(AndroidJUnit4.class)
// TODO(ibaker): Split this into OggExtractorSniffTest and OggExtractorTest after parameterization,
// otherwise we'll be running all the sniff tests multiple times.
@RunWith(ParameterizedRobolectricTestRunner.class)
public final class OggExtractorTest {
private static final ExtractorFactory OGG_EXTRACTOR_FACTORY = OggExtractor::new;
@Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void opus() throws Exception {
ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear.opus");
ExtractorAsserts.assertBehavior(OggExtractor::new, "ogg/bear.opus", assertionConfig);
}
@Test
public void flac() throws Exception {
ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear_flac.ogg");
ExtractorAsserts.assertBehavior(OggExtractor::new, "ogg/bear_flac.ogg", assertionConfig);
}
@Test
public void flacNoSeektable() throws Exception {
ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear_flac_noseektable.ogg");
ExtractorAsserts.assertBehavior(
OggExtractor::new, "ogg/bear_flac_noseektable.ogg", assertionConfig);
}
@Test
public void vorbis() throws Exception {
ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear_vorbis.ogg");
ExtractorAsserts.assertBehavior(OggExtractor::new, "ogg/bear_vorbis.ogg", assertionConfig);
}
@Test
......@@ -97,6 +108,6 @@ public final class OggExtractorTest {
.setSimulateUnknownLength(true)
.setSimulatePartialReads(true)
.build();
ExtractorAsserts.assertSniff(OGG_EXTRACTOR_FACTORY.create(), input, expectedResult);
ExtractorAsserts.assertSniff(new OggExtractor(), input, expectedResult);
}
}
......@@ -15,17 +15,26 @@
*/
package com.google.android.exoplayer2.extractor.rawcc;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import com.google.android.exoplayer2.util.MimeTypes;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
/** Tests for {@link RawCcExtractor}. */
@RunWith(AndroidJUnit4.class)
@RunWith(ParameterizedRobolectricTestRunner.class)
public final class RawCcExtractorTest {
@ParameterizedRobolectricTestRunner.Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@ParameterizedRobolectricTestRunner.Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void rawCcSample() throws Exception {
Format format =
......@@ -34,6 +43,7 @@ public final class RawCcExtractorTest {
.setCodecs("cea608")
.setAccessibilityChannel(1)
.build();
ExtractorAsserts.assertBehavior(() -> new RawCcExtractor(format), "rawcc/sample.rawcc");
ExtractorAsserts.assertBehavior(
() -> new RawCcExtractor(format), "rawcc/sample.rawcc", assertionConfig);
}
}
......@@ -15,27 +15,38 @@
*/
package com.google.android.exoplayer2.extractor.ts;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameter;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
/** Unit test for {@link Ac3Extractor}. */
@RunWith(AndroidJUnit4.class)
@RunWith(ParameterizedRobolectricTestRunner.class)
public final class Ac3ExtractorTest {
@Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void ac3Sample() throws Exception {
ExtractorAsserts.assertBehavior(Ac3Extractor::new, "ts/sample.ac3");
ExtractorAsserts.assertBehavior(Ac3Extractor::new, "ts/sample.ac3", assertionConfig);
}
@Test
public void eAc3Sample() throws Exception {
ExtractorAsserts.assertBehavior(Ac3Extractor::new, "ts/sample.eac3");
ExtractorAsserts.assertBehavior(Ac3Extractor::new, "ts/sample.eac3", assertionConfig);
}
@Test
public void eAc3jocSample() throws Exception {
ExtractorAsserts.assertBehavior(Ac3Extractor::new, "ts/sample_eac3joc.ec3");
ExtractorAsserts.assertBehavior(Ac3Extractor::new, "ts/sample_eac3joc.ec3", assertionConfig);
}
}
......@@ -15,17 +15,28 @@
*/
package com.google.android.exoplayer2.extractor.ts;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameter;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
/** Unit test for {@link Ac4Extractor}. */
@RunWith(AndroidJUnit4.class)
@RunWith(ParameterizedRobolectricTestRunner.class)
public final class Ac4ExtractorTest {
@Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void ac4Sample() throws Exception {
ExtractorAsserts.assertBehavior(Ac4Extractor::new, "ts/sample.ac4");
ExtractorAsserts.assertBehavior(Ac4Extractor::new, "ts/sample.ac4", assertionConfig);
}
}
......@@ -15,30 +15,42 @@
*/
package com.google.android.exoplayer2.extractor.ts;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameter;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
/** Unit test for {@link AdtsExtractor}. */
@RunWith(AndroidJUnit4.class)
@RunWith(ParameterizedRobolectricTestRunner.class)
public final class AdtsExtractorTest {
@Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void sample() throws Exception {
ExtractorAsserts.assertBehavior(AdtsExtractor::new, "ts/sample.adts");
ExtractorAsserts.assertBehavior(AdtsExtractor::new, "ts/sample.adts", assertionConfig);
}
@Test
public void sample_with_id3() throws Exception {
ExtractorAsserts.assertBehavior(AdtsExtractor::new, "ts/sample_with_id3.adts");
ExtractorAsserts.assertBehavior(AdtsExtractor::new, "ts/sample_with_id3.adts", assertionConfig);
}
@Test
public void sample_withSeeking() throws Exception {
ExtractorAsserts.assertBehavior(
() -> new AdtsExtractor(/* flags= */ AdtsExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING),
"ts/sample_cbs.adts");
"ts/sample_cbs.adts",
assertionConfig);
}
// https://github.com/google/ExoPlayer/issues/6700
......@@ -46,6 +58,7 @@ public final class AdtsExtractorTest {
public void sample_withSeekingAndTruncatedFile() throws Exception {
ExtractorAsserts.assertBehavior(
() -> new AdtsExtractor(/* flags= */ AdtsExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING),
"ts/sample_cbs_truncated.adts");
"ts/sample_cbs_truncated.adts",
assertionConfig);
}
}
......@@ -15,22 +15,34 @@
*/
package com.google.android.exoplayer2.extractor.ts;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameter;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
/** Unit test for {@link PsExtractor}. */
@RunWith(AndroidJUnit4.class)
@RunWith(ParameterizedRobolectricTestRunner.class)
public final class PsExtractorTest {
@Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void sampleWithH262AndMpegAudio() throws Exception {
ExtractorAsserts.assertBehavior(PsExtractor::new, "ts/sample_h262_mpeg_audio.ps");
ExtractorAsserts.assertBehavior(
PsExtractor::new, "ts/sample_h262_mpeg_audio.ps", assertionConfig);
}
@Test
public void sampleWithAc3() throws Exception {
ExtractorAsserts.assertBehavior(PsExtractor::new, "ts/sample_ac3.ps");
ExtractorAsserts.assertBehavior(PsExtractor::new, "ts/sample_ac3.ps", assertionConfig);
}
}
......@@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat;
import android.util.SparseArray;
import androidx.annotation.Nullable;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.extractor.Extractor;
......@@ -37,34 +36,49 @@ import com.google.android.exoplayer2.testutil.FakeTrackOutput;
import com.google.android.exoplayer2.testutil.TestUtil;
import com.google.android.exoplayer2.util.ParsableByteArray;
import com.google.android.exoplayer2.util.TimestampAdjuster;
import java.util.List;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameter;
import org.robolectric.ParameterizedRobolectricTestRunner.Parameters;
/** Unit test for {@link TsExtractor}. */
@RunWith(AndroidJUnit4.class)
@RunWith(ParameterizedRobolectricTestRunner.class)
public final class TsExtractorTest {
@Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void sampleWithH262AndMpegAudio() throws Exception {
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_h262_mpeg_audio.ts");
ExtractorAsserts.assertBehavior(
TsExtractor::new, "ts/sample_h262_mpeg_audio.ts", assertionConfig);
}
@Test
public void sampleWithH264AndMpegAudio() throws Exception {
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_h264_mpeg_audio.ts");
ExtractorAsserts.assertBehavior(
TsExtractor::new, "ts/sample_h264_mpeg_audio.ts", assertionConfig);
}
@Test
public void sampleWithH264NoAccessUnitDelimiters() throws Exception {
ExtractorAsserts.assertBehavior(
() -> new TsExtractor(FLAG_DETECT_ACCESS_UNITS),
"ts/sample_h264_no_access_unit_delimiters.ts");
"ts/sample_h264_no_access_unit_delimiters.ts",
assertionConfig);
}
@Test
public void sampleWithH265() throws Exception {
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_h265.ts");
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_h265.ts", assertionConfig);
}
@Test
......@@ -72,7 +86,7 @@ public final class TsExtractorTest {
// TODO(internal: b/153539929) Re-enable when ExtractorAsserts is less strict around repeated
// formats and seeking.
public void sampleWithScte35() throws Exception {
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_scte35.ts");
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_scte35.ts", assertionConfig);
}
@Test
......@@ -80,38 +94,41 @@ public final class TsExtractorTest {
// TODO(internal: b/153539929) Re-enable when ExtractorAsserts is less strict around repeated
// formats and seeking.
public void sampleWithAit() throws Exception {
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_ait.ts");
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_ait.ts", assertionConfig);
}
@Test
public void sampleWithAc3() throws Exception {
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_ac3.ts");
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_ac3.ts", assertionConfig);
}
@Test
public void sampleWithAc4() throws Exception {
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_ac4.ts");
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_ac4.ts", assertionConfig);
}
@Test
public void sampleWithEac3() throws Exception {
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_eac3.ts");
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_eac3.ts", assertionConfig);
}
@Test
public void sampleWithEac3joc() throws Exception {
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_eac3joc.ts");
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_eac3joc.ts", assertionConfig);
}
@Test
public void sampleWithLatm() throws Exception {
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_latm.ts");
ExtractorAsserts.assertBehavior(TsExtractor::new, "ts/sample_latm.ts", assertionConfig);
}
@Test
public void streamWithJunkData() throws Exception {
ExtractorAsserts.assertBehavior(
TsExtractor::new, "ts/sample_with_junk", ApplicationProvider.getApplicationContext());
TsExtractor::new,
"ts/sample_with_junk",
assertionConfig,
ApplicationProvider.getApplicationContext());
}
@Test
......
......@@ -16,18 +16,27 @@
package com.google.android.exoplayer2.extractor.wav;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.testutil.ExtractorAsserts;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.ParameterizedRobolectricTestRunner;
/** Unit test for {@link WavExtractor}. */
@RunWith(AndroidJUnit4.class)
@RunWith(ParameterizedRobolectricTestRunner.class)
public final class WavExtractorTest {
@ParameterizedRobolectricTestRunner.Parameters(name = "{0}")
public static List<Object[]> params() {
return ExtractorAsserts.configs();
}
@ParameterizedRobolectricTestRunner.Parameter(0)
public ExtractorAsserts.Config assertionConfig;
@Test
public void sample() throws Exception {
ExtractorAsserts.assertBehavior(WavExtractor::new, "wav/sample.wav");
ExtractorAsserts.assertBehavior(WavExtractor::new, "wav/sample.wav", assertionConfig);
}
@Test
......@@ -35,12 +44,13 @@ public final class WavExtractorTest {
ExtractorAsserts.assertBehavior(
WavExtractor::new,
"wav/sample_with_trailing_bytes.wav",
assertionConfig,
ApplicationProvider.getApplicationContext(),
/* dumpFilesPrefix= */ "wav/sample.wav");
}
@Test
public void sample_imaAdpcm() throws Exception {
ExtractorAsserts.assertBehavior(WavExtractor::new, "wav/sample_ima_adpcm.wav");
ExtractorAsserts.assertBehavior(WavExtractor::new, "wav/sample_ima_adpcm.wav", assertionConfig);
}
}
......@@ -27,7 +27,10 @@ import com.google.android.exoplayer2.extractor.PositionHolder;
import com.google.android.exoplayer2.extractor.SeekMap;
import com.google.android.exoplayer2.testutil.FakeExtractorInput.SimulatedIOException;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
/**
* Assertion methods for {@link Extractor}.
......@@ -35,8 +38,60 @@ import java.io.IOException;
public final class ExtractorAsserts {
/**
* A factory for {@link Extractor} instances.
* Returns a list of arrays containing {@link Config} objects to exercise different extractor
* paths.
*
* <p>This is intended to be used from tests using {@code ParameterizedRobolectricTestRunner} or
* {@code org.junit.runners.Parameterized}.
*/
public static List<Object[]> configs() {
return Arrays.asList(
new Object[] {new Config(true, false, false, false)},
new Object[] {new Config(true, false, false, true)},
new Object[] {new Config(true, false, true, false)},
new Object[] {new Config(true, false, true, true)},
new Object[] {new Config(true, true, false, false)},
new Object[] {new Config(true, true, false, true)},
new Object[] {new Config(true, true, true, false)},
new Object[] {new Config(true, true, true, true)},
new Object[] {new Config(false, false, false, false)});
}
/** A config of different environments to simulate and extractor behaviour to test. */
public static class Config {
/**
* Whether to sniff the data by calling {@link Extractor#sniff(ExtractorInput)} prior to
* consuming it.
*/
public final boolean sniffFirst;
/** Whether to simulate IO errors. */
public final boolean simulateIOErrors;
/** Whether to simulate unknown input length. */
public final boolean simulateUnknownLength;
/** Whether to simulate partial reads. */
public final boolean simulatePartialReads;
private Config(
boolean sniffFirst,
boolean simulateIOErrors,
boolean simulateUnknownLength,
boolean simulatePartialReads) {
this.sniffFirst = sniffFirst;
this.simulateIOErrors = simulateIOErrors;
this.simulateUnknownLength = simulateUnknownLength;
this.simulatePartialReads = simulatePartialReads;
}
@Override
public String toString() {
return Util.formatInvariant(
"sniff=%s,ioErr=%s,unknownLen=%s,partRead=%s",
sniffFirst, simulateIOErrors, simulateUnknownLength, simulatePartialReads);
}
}
/** A factory for {@link Extractor} instances. */
public interface ExtractorFactory {
Extractor create();
}
......@@ -66,8 +121,7 @@ public final class ExtractorAsserts {
}
/**
* Asserts that an extractor behaves correctly given valid input data. Can only be used from
* Robolectric tests.
* Asserts that an extractor behaves correctly given valid input data.
*
* <ul>
* <li>Calls {@link Extractor#seek(long, long)} and {@link Extractor#release()} without calling
......@@ -136,6 +190,77 @@ public final class ExtractorAsserts {
}
/**
* Asserts that an extractor consumes valid input data successfully under the conditions specified
* by {@code config}.
*
* <p>The output of the extractor is compared against prerecorded dump files whose names are
* derived from the {@code file} parameter.
*
* @param factory An {@link ExtractorFactory} which creates instances of the {@link Extractor}
* class which is to be tested.
* @param file The path to the input sample.
* @param config Details on the environment to simulate and behaviours to assert.
* @throws IOException If reading from the input fails.
*/
public static void assertBehavior(ExtractorFactory factory, String file, Config config)
throws IOException {
assertBehavior(factory, file, config, ApplicationProvider.getApplicationContext());
}
/**
* Asserts that an extractor consumes valid input data successfully successfully under the
* conditions specified by {@code config}.
*
* <p>The output of the extractor is compared against prerecorded dump files whose names are
* derived from the {@code file} parameter.
*
* @param factory An {@link ExtractorFactory} which creates instances of the {@link Extractor}
* class which is to be tested.
* @param file The path to the input sample.
* @param config Details on the environment to simulate and behaviours to assert.
* @param context To be used to load the sample file.
* @throws IOException If reading from the input fails.
*/
public static void assertBehavior(
ExtractorFactory factory, String file, Config config, Context context) throws IOException {
assertBehavior(factory, file, config, context, file);
}
/**
* Asserts that an extractor consumes valid input data successfully successfully under the
* conditions specified by {@code config}.
*
* <p>The output of the extractor is compared against prerecorded dump files.
*
* @param factory An {@link ExtractorFactory} which creates instances of the {@link Extractor}
* class which is to be tested.
* @param file The path to the input sample.
* @param config Details on the environment to simulate and behaviours to assert.
* @param context To be used to load the sample file.
* @param dumpFilesPrefix The dump files prefix prepended to the dump files path.
* @throws IOException If reading from the input fails.
*/
public static void assertBehavior(
ExtractorFactory factory, String file, Config config, Context context, String dumpFilesPrefix)
throws IOException {
// Check behavior prior to initialization.
Extractor extractor = factory.create();
extractor.seek(0, 0);
extractor.release();
// Assert output.
byte[] fileData = TestUtil.getByteArray(context, file);
assertOutput(
factory.create(),
dumpFilesPrefix,
fileData,
context,
config.sniffFirst,
config.simulateIOErrors,
config.simulateUnknownLength,
config.simulatePartialReads);
}
/**
* Calls {@link #assertOutput(Extractor, String, byte[], Context, boolean, boolean, boolean,
* boolean)} with all possible combinations of "simulate" parameters with {@code sniffFirst} set
* to true, and makes one additional call with the "simulate" and {@code sniffFirst} parameters
......@@ -163,11 +288,11 @@ public final class ExtractorAsserts {
}
/**
* Asserts that {@code extractor} consumes {@code data} successfully and that its output for
* various initial seek times and for a known and unknown length matches prerecorded dump files.
* Asserts that an extractor consumes valid input data successfully under the specified
* conditions.
*
* @param extractor The {@link Extractor} to be tested.
* @param dumpFilesPrefix The dump files prefix appended to the dump files path.
* @param dumpFilesPrefix The dump files prefix prepended to the dump files path.
* @param data Content of the input file.
* @param context To be used to load the sample file.
* @param sniffFirst Whether to sniff the data by calling {@link Extractor#sniff(ExtractorInput)}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment