Simplify Resource.isEndOfInputExpected

- Make it a property of the DataSource, not of the resource.
- Apply it only when a contract test reads using an
  unbounded DataSpec.

PiperOrigin-RevId: 358997735
This commit is contained in:
olly 2021-02-23 09:35:43 +00:00 committed by marcbaechinger
parent 691ac39fcb
commit b4b22d9808
2 changed files with 31 additions and 52 deletions

View File

@ -53,6 +53,11 @@ public class UdpDataSourceContractTest extends DataSourceContractTest {
return udpDataSource; return udpDataSource;
} }
@Override
protected boolean unboundedReadsAreIndefinite() {
return true;
}
@Override @Override
protected ImmutableList<TestResource> getTestResources() { protected ImmutableList<TestResource> getTestResources() {
return ImmutableList.of( return ImmutableList.of(
@ -60,7 +65,6 @@ public class UdpDataSourceContractTest extends DataSourceContractTest {
.setName("local-udp-unicast-socket") .setName("local-udp-unicast-socket")
.setUri(Uri.parse("udp://localhost:" + findFreeUdpPort())) .setUri(Uri.parse("udp://localhost:" + findFreeUdpPort()))
.setExpectedBytes(data) .setExpectedBytes(data)
.setEndOfInputExpected(false)
.build()); .build());
} }

View File

@ -75,6 +75,14 @@ public abstract class DataSourceContractTest {
return null; return null;
} }
/**
* Returns whether the {@link DataSource} will continue reading indefinitely for unbounded {@link
* DataSpec DataSpecs}.
*/
protected boolean unboundedReadsAreIndefinite() {
return false;
}
/** /**
* Returns {@link TestResource} instances. * Returns {@link TestResource} instances.
* *
@ -94,7 +102,7 @@ public abstract class DataSourceContractTest {
protected abstract Uri getNotFoundUri(); protected abstract Uri getNotFoundUri();
@Test @Test
public void unboundedDataSpec_readEverything() throws Exception { public void unboundedDataSpec_readUntilEnd() throws Exception {
ImmutableList<TestResource> resources = getTestResources(); ImmutableList<TestResource> resources = getTestResources();
Assertions.checkArgument(!resources.isEmpty(), "Must provide at least one test resource."); Assertions.checkArgument(!resources.isEmpty(), "Must provide at least one test resource.");
@ -105,9 +113,9 @@ public abstract class DataSourceContractTest {
try { try {
long length = dataSource.open(new DataSpec(resource.getUri())); long length = dataSource.open(new DataSpec(resource.getUri()));
byte[] data = byte[] data =
resource.isEndOfInputExpected() unboundedReadsAreIndefinite()
? Util.readToEnd(dataSource) ? Util.readExactly(dataSource, resource.getExpectedBytes().length)
: Util.readExactly(dataSource, resource.getExpectedBytes().length); : Util.readToEnd(dataSource);
if (length != C.LENGTH_UNSET) { if (length != C.LENGTH_UNSET) {
assertThat(length).isEqualTo(resource.getExpectedBytes().length); assertThat(length).isEqualTo(resource.getExpectedBytes().length);
@ -134,9 +142,9 @@ public abstract class DataSourceContractTest {
dataSource.open( dataSource.open(
new DataSpec.Builder().setUri(resource.getUri()).setPosition(3).build()); new DataSpec.Builder().setUri(resource.getUri()).setPosition(3).build());
byte[] data = byte[] data =
resource.isEndOfInputExpected() unboundedReadsAreIndefinite()
? Util.readToEnd(dataSource) ? Util.readExactly(dataSource, resource.getExpectedBytes().length - 3)
: Util.readExactly(dataSource, resource.getExpectedBytes().length - 3); : Util.readToEnd(dataSource);
if (length != C.LENGTH_UNSET) { if (length != C.LENGTH_UNSET) {
assertThat(length).isEqualTo(resource.getExpectedBytes().length - 3); assertThat(length).isEqualTo(resource.getExpectedBytes().length - 3);
@ -163,10 +171,7 @@ public abstract class DataSourceContractTest {
try { try {
long length = long length =
dataSource.open(new DataSpec.Builder().setUri(resource.getUri()).setLength(4).build()); dataSource.open(new DataSpec.Builder().setUri(resource.getUri()).setLength(4).build());
byte[] data = byte[] data = Util.readToEnd(dataSource);
resource.isEndOfInputExpected()
? Util.readToEnd(dataSource)
: Util.readExactly(dataSource, /* length= */ 4);
assertThat(length).isEqualTo(4); assertThat(length).isEqualTo(4);
byte[] expectedData = Arrays.copyOf(resource.getExpectedBytes(), 4); byte[] expectedData = Arrays.copyOf(resource.getExpectedBytes(), 4);
@ -195,10 +200,7 @@ public abstract class DataSourceContractTest {
.setPosition(2) .setPosition(2)
.setLength(2) .setLength(2)
.build()); .build());
byte[] data = byte[] data = Util.readToEnd(dataSource);
resource.isEndOfInputExpected()
? Util.readToEnd(dataSource)
: Util.readExactly(dataSource, /* length= */ 2);
assertThat(length).isEqualTo(2); assertThat(length).isEqualTo(2);
byte[] expectedData = Arrays.copyOfRange(resource.getExpectedBytes(), 2, 4); byte[] expectedData = Arrays.copyOfRange(resource.getExpectedBytes(), 2, 4);
@ -216,7 +218,7 @@ public abstract class DataSourceContractTest {
* {@link DataSource#read(byte[], int, int)}). * {@link DataSource#read(byte[], int, int)}).
*/ */
@Test @Test
public void gzipFlagDoesntAffectReturnedData() throws Exception { public void unboundedDataSpecWithGzipFlag_readUntilEnd() throws Exception {
ImmutableList<TestResource> resources = getTestResources(); ImmutableList<TestResource> resources = getTestResources();
Assertions.checkArgument(!resources.isEmpty(), "Must provide at least one test resource."); Assertions.checkArgument(!resources.isEmpty(), "Must provide at least one test resource.");
@ -232,9 +234,9 @@ public abstract class DataSourceContractTest {
.setFlags(DataSpec.FLAG_ALLOW_GZIP) .setFlags(DataSpec.FLAG_ALLOW_GZIP)
.build()); .build());
byte[] data = byte[] data =
resource.isEndOfInputExpected() unboundedReadsAreIndefinite()
? Util.readToEnd(dataSource) ? Util.readExactly(dataSource, resource.getExpectedBytes().length)
: Util.readExactly(dataSource, resource.getExpectedBytes().length); : Util.readToEnd(dataSource);
if (length != C.LENGTH_UNSET) { if (length != C.LENGTH_UNSET) {
assertThat(length).isEqualTo(resource.getExpectedBytes().length); assertThat(length).isEqualTo(resource.getExpectedBytes().length);
@ -297,10 +299,10 @@ public abstract class DataSourceContractTest {
.onTransferStart(callbackSource, castNonNull(reportedDataSpec), reportedNetwork); .onTransferStart(callbackSource, castNonNull(reportedDataSpec), reportedNetwork);
inOrder.verifyNoMoreInteractions(); inOrder.verifyNoMoreInteractions();
if (resource.isEndOfInputExpected()) { if (unboundedReadsAreIndefinite()) {
Util.readToEnd(dataSource);
} else {
Util.readExactly(dataSource, resource.getExpectedBytes().length); Util.readExactly(dataSource, resource.getExpectedBytes().length);
} else {
Util.readToEnd(dataSource);
} }
// Verify sufficient onBytesTransferred() callbacks have been triggered before closing the // Verify sufficient onBytesTransferred() callbacks have been triggered before closing the
// DataSource. // DataSource.
@ -334,14 +336,11 @@ public abstract class DataSourceContractTest {
@Nullable private final String name; @Nullable private final String name;
private final Uri uri; private final Uri uri;
private final byte[] expectedBytes; private final byte[] expectedBytes;
private final boolean endOfInputExpected;
private TestResource( private TestResource(@Nullable String name, Uri uri, byte[] expectedBytes) {
@Nullable String name, Uri uri, byte[] expectedBytes, boolean endOfInputExpected) {
this.name = name; this.name = name;
this.uri = uri; this.uri = uri;
this.expectedBytes = expectedBytes; this.expectedBytes = expectedBytes;
this.endOfInputExpected = endOfInputExpected;
} }
/** Returns a human-readable name for the resource, for use in test failure messages. */ /** Returns a human-readable name for the resource, for use in test failure messages. */
@ -360,25 +359,11 @@ public abstract class DataSourceContractTest {
return expectedBytes; return expectedBytes;
} }
/**
* Returns whether {@link DataSource#read} is expected to return {@link C#RESULT_END_OF_INPUT}
* after all the resource data are read.
*/
public boolean isEndOfInputExpected() {
return endOfInputExpected;
}
/** Builder for {@link TestResource} instances. */ /** Builder for {@link TestResource} instances. */
public static final class Builder { public static final class Builder {
private @MonotonicNonNull String name; private @MonotonicNonNull String name;
private @MonotonicNonNull Uri uri; private @MonotonicNonNull Uri uri;
private byte @MonotonicNonNull [] expectedBytes; private byte @MonotonicNonNull [] expectedBytes;
private boolean endOfInputExpected;
/** Construct a new instance. */
public Builder() {
this.endOfInputExpected = true;
}
/** /**
* Sets a human-readable name for this resource which will be shown in test failure messages. * Sets a human-readable name for this resource which will be shown in test failure messages.
@ -405,18 +390,8 @@ public abstract class DataSourceContractTest {
return this; return this;
} }
/**
* Sets whether {@link DataSource#read} is expected to return {@link C#RESULT_END_OF_INPUT}
* after all the resource data have been read. By default, this is set to {@code true}.
*/
public Builder setEndOfInputExpected(boolean expected) {
this.endOfInputExpected = expected;
return this;
}
public TestResource build() { public TestResource build() {
return new TestResource( return new TestResource(name, checkNotNull(uri), checkNotNull(expectedBytes));
name, checkNotNull(uri), checkNotNull(expectedBytes), endOfInputExpected);
} }
} }
} }