diff --git a/library/core/src/test/java/com/google/android/exoplayer2/upstream/UdpDataSourceContractTest.java b/library/core/src/test/java/com/google/android/exoplayer2/upstream/UdpDataSourceContractTest.java index 7ac3305043..65b34eef53 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/upstream/UdpDataSourceContractTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/upstream/UdpDataSourceContractTest.java @@ -29,6 +29,7 @@ import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import org.junit.Before; +import org.junit.Ignore; import org.junit.runner.RunWith; /** {@link DataSource} contract tests for {@link UdpDataSource}. */ @@ -72,6 +73,29 @@ public class UdpDataSourceContractTest extends DataSourceContractTest { return Uri.parse("udp://notfound.invalid:12345"); } + @Override + @Ignore("UdpDataSource doesn't support DataSpec's position or length [internal: b/175856954]") + public void dataSpecWithPosition_readUntilEnd() {} + + /** + * Finds a free UDP port in the range of unreserved ports 50000-60000 that can be used from the + * test or throws an {@link IllegalStateException} if no port is available. + * + *

There is no guarantee that the port returned will still be available as another process may + * occupy it in the mean time. + */ + private static int findFreeUdpPort() { + for (int i = 50000; i <= 60000; i++) { + try { + new DatagramSocket(i).close(); + return i; + } catch (SocketException e) { + // Port is occupied, continue to next port. + } + } + throw new IllegalStateException(); + } + /** * A {@link TransferListener} that triggers UDP packet transmissions back to the UDP data source. */ @@ -109,23 +133,4 @@ public class UdpDataSourceContractTest extends DataSourceContractTest { @Override public void onTransferEnd(DataSource source, DataSpec dataSpec, boolean isNetwork) {} } - - /** - * Finds a free UDP port in the range of unreserved ports 50000-60000 that can be used from the - * test or throws an {@link IllegalStateException} if no port is available. - * - *

There is no guarantee that the port returned will still be available as another process may - * occupy it in the mean time. - */ - private static int findFreeUdpPort() { - for (int i = 50000; i <= 60000; i++) { - try { - new DatagramSocket(i).close(); - return i; - } catch (SocketException e) { - // Port is occupied, continue to next port. - } - } - throw new IllegalStateException(); - } } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/DataSourceContractTest.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/DataSourceContractTest.java index 27e0fd594d..5fb0472b91 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/DataSourceContractTest.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/DataSourceContractTest.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.testutil; +import static com.google.android.exoplayer2.util.Assertions.checkArgument; import static com.google.android.exoplayer2.util.Assertions.checkNotNull; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; @@ -29,6 +30,7 @@ import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Util; import com.google.common.collect.ImmutableList; import java.io.IOException; +import java.util.Arrays; import java.util.List; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.junit.Ignore; @@ -86,10 +88,7 @@ public abstract class DataSourceContractTest { DataSource dataSource = createDataSource(); try { long length = dataSource.open(new DataSpec(resource.getUri())); - byte[] data = - resource.isEndOfInputExpected() - ? Util.readToEnd(dataSource) - : Util.readExactly(dataSource, resource.getExpectedBytes().length); + byte[] data = readToEnd(dataSource, resource); assertThat(length).isEqualTo(resource.getExpectedResolvedLength()); assertThat(data).isEqualTo(resource.getExpectedBytes()); @@ -100,6 +99,34 @@ public abstract class DataSourceContractTest { } } + @Test + public void dataSpecWithPosition_readUntilEnd() throws Exception { + ImmutableList resources = getTestResources(); + Assertions.checkArgument(!resources.isEmpty(), "Must provide at least one test resource."); + + for (int i = 0; i < resources.size(); i++) { + additionalFailureInfo.setInfo(getFailureLabel(resources, i)); + TestResource resource = resources.get(i); + DataSource dataSource = createDataSource(); + try { + long length = + dataSource.open( + new DataSpec.Builder().setUri(resource.getUri()).setPosition(3).build()); + byte[] data = readToEnd(dataSource, resource); + + if (resource.getExpectedResolvedLength() != C.LENGTH_UNSET) { + assertThat(length).isEqualTo(resource.getExpectedResolvedLength() - 3); + } + byte[] expectedData = + Arrays.copyOfRange(resource.getExpectedBytes(), 3, resource.getExpectedBytes().length); + assertThat(data).isEqualTo(expectedData); + } finally { + dataSource.close(); + } + additionalFailureInfo.setInfo(null); + } + } + @Test public void resourceNotFound() throws Exception { DataSource dataSource = createDataSource(); @@ -121,6 +148,13 @@ public abstract class DataSourceContractTest { } } + private static byte[] readToEnd(DataSource dataSource, TestResource expectedResource) + throws IOException { + return expectedResource.isEndOfInputExpected() + ? Util.readToEnd(dataSource) + : Util.readExactly(dataSource, expectedResource.getExpectedBytes().length); + } + /** Information about a resource that can be used to test the {@link DataSource} instance. */ public static final class TestResource { @@ -204,8 +238,13 @@ public abstract class DataSourceContractTest { return this; } - /** Sets the expected contents of this resource. */ + /** + * Sets the expected contents of this resource. + * + *

Must be at least 5 bytes. + */ public Builder setExpectedBytes(byte[] expectedBytes) { + checkArgument(expectedBytes.length >= 5); this.expectedBytes = expectedBytes; return this; }