Back to Repositories

Testing OGG Audio Format Extraction in SmartTube

This test suite validates the OggExtractor component in ExoPlayer, focusing on handling different OGG audio formats including Opus, FLAC, and Vorbis. The tests verify proper extraction behavior and format detection capabilities.

Test Coverage Overview

The test suite provides comprehensive coverage of OGG format handling:

  • Format-specific tests for Opus, FLAC, and Vorbis audio
  • FLAC seektable validation scenarios
  • Format sniffing and detection tests
  • Edge cases including invalid headers and EOF conditions

Implementation Analysis

The testing approach utilizes JUnit with AndroidJUnit4 runner for Android compatibility. Tests employ ExtractorAsserts for behavior validation and FakeExtractorInput for simulated I/O scenarios. The implementation follows a systematic pattern of testing both valid and invalid OGG container formats.

Technical Details

Key technical components include:

  • JUnit and AndroidJUnit4 test framework
  • ExtractorAsserts utility for validation
  • FakeExtractorInput for I/O simulation
  • OggTestData for header construction
  • TestUtil for byte array manipulation

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Systematic format validation across multiple codec types
  • Comprehensive error case coverage
  • Isolation of I/O operations using fake inputs
  • Clear test method naming and organization
  • Effective use of test utilities and helpers

yuliskov/smarttube

exoplayer-amzn-2.10.6/library/core/src/test/java/com/google/android/exoplayer2/extractor/ogg/OggExtractorTest.java

            
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.android.exoplayer2.extractor.ogg;

import static com.google.common.truth.Truth.assertThat;

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 com.google.android.exoplayer2.testutil.OggTestData;
import com.google.android.exoplayer2.testutil.TestUtil;
import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;

/** Unit test for {@link OggExtractor}. */
@RunWith(AndroidJUnit4.class)
public final class OggExtractorTest {

  private static final ExtractorFactory OGG_EXTRACTOR_FACTORY = OggExtractor::new;

  @Test
  public void testOpus() throws Exception {
    ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear.opus");
  }

  @Test
  public void testFlac() throws Exception {
    ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear_flac.ogg");
  }

  @Test
  public void testFlacNoSeektable() throws Exception {
    ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear_flac_noseektable.ogg");
  }

  @Test
  public void testVorbis() throws Exception {
    ExtractorAsserts.assertBehavior(OGG_EXTRACTOR_FACTORY, "ogg/bear_vorbis.ogg");
  }

  @Test
  public void testSniffVorbis() throws Exception {
    byte[] data =
        TestUtil.joinByteArrays(
            OggTestData.buildOggHeader(0x02, 0, 1000, 1),
            TestUtil.createByteArray(7), // Laces
            new byte[] {0x01, 'v', 'o', 'r', 'b', 'i', 's'});
    assertThat(sniff(data)).isTrue();
  }

  @Test
  public void testSniffFlac() throws Exception {
    byte[] data =
        TestUtil.joinByteArrays(
            OggTestData.buildOggHeader(0x02, 0, 1000, 1),
            TestUtil.createByteArray(5), // Laces
            new byte[] {0x7F, 'F', 'L', 'A', 'C'});
    assertThat(sniff(data)).isTrue();
  }

  @Test
  public void testSniffFailsOpusFile() throws Exception {
    byte[] data =
        TestUtil.joinByteArrays(
            OggTestData.buildOggHeader(0x02, 0, 1000, 0x00), new byte[] {'O', 'p', 'u', 's'});
    assertThat(sniff(data)).isFalse();
  }

  @Test
  public void testSniffFailsInvalidOggHeader() throws Exception {
    byte[] data = OggTestData.buildOggHeader(0x00, 0, 1000, 0x00);
    assertThat(sniff(data)).isFalse();
  }

  @Test
  public void testSniffInvalidHeader() throws Exception {
    byte[] data =
        TestUtil.joinByteArrays(
            OggTestData.buildOggHeader(0x02, 0, 1000, 1),
            TestUtil.createByteArray(7), // Laces
            new byte[] {0x7F, 'X', 'o', 'r', 'b', 'i', 's'});
    assertThat(sniff(data)).isFalse();
  }

  @Test
  public void testSniffFailsEOF() throws Exception {
    byte[] data = OggTestData.buildOggHeader(0x02, 0, 1000, 0x00);
    assertThat(sniff(data)).isFalse();
  }

  private boolean sniff(byte[] data) throws InterruptedException, IOException {
    FakeExtractorInput input =
        new FakeExtractorInput.Builder()
            .setData(data)
            .setSimulateIOErrors(true)
            .setSimulateUnknownLength(true)
            .setSimulatePartialReads(true)
            .build();
    return TestUtil.sniffTestData(OGG_EXTRACTOR_FACTORY.create(), input);
  }
}