Remove expectedResolvedLength from DataSourceContractTest

Whether a resource resolves to a known length or not is more than just
a property of the resource & data source - for example if
`DataSpec.flags` contains `ALLOW_GZIP` then the length might be
unresolved. More generally, a `DataSource` could randomly return
`C.UNKNOWN_LENGTH` from `open()` 50% of the time and still fulfil the
`DataSource` interface. This makes it ~impossible to write a meaningful
assertion aroun this.

So this change relaxes the assertion slightly to more closely match the
definition of the `DataSource` interface.

We leave the `resolveToUnknownLength` toggle in
`WebServerDispatcher.Resource` because this is still useful for
simulating the case of a server that is serving a file it doesn't
know the length of.

PiperOrigin-RevId: 351124246
This commit is contained in:
ibaker 2021-01-11 12:08:35 +00:00 committed by Ian Baker
parent 704f006be1
commit 01ae2b047f
5 changed files with 11 additions and 45 deletions

View File

@ -48,7 +48,6 @@ public final class ContentDataSourceContractTest extends DataSourceContractTest
.setName("simple (pipe=true)") .setName("simple (pipe=true)")
.setUri(TestContentProvider.buildUri(DATA_PATH, /* pipeMode= */ true)) .setUri(TestContentProvider.buildUri(DATA_PATH, /* pipeMode= */ true))
.setExpectedBytes(completeData) .setExpectedBytes(completeData)
.setResolvesToUnknownLength(true)
.build()); .build());
} }

View File

@ -135,7 +135,6 @@ public class DefaultHttpDataSourceContractTest extends DataSourceContractTest {
.setName(name) .setName(name)
.setUri(Uri.parse(urlResolver.apply(resource.getPath()).toString())) .setUri(Uri.parse(urlResolver.apply(resource.getPath()).toString()))
.setExpectedBytes(resource.getData()) .setExpectedBytes(resource.getData())
.setResolvesToUnknownLength(resource.resolvesToUnknownLength())
.setEndOfInputExpected(!resource.resolvesToUnknownLength()) .setEndOfInputExpected(!resource.resolvesToUnknownLength())
.build(); .build();
} }

View File

@ -60,7 +60,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)
.setResolvesToUnknownLength(true)
.setEndOfInputExpected(false) .setEndOfInputExpected(false)
.build()); .build());
} }

View File

@ -93,7 +93,9 @@ public abstract class DataSourceContractTest {
? Util.readToEnd(dataSource) ? Util.readToEnd(dataSource)
: Util.readExactly(dataSource, resource.getExpectedBytes().length); : Util.readExactly(dataSource, resource.getExpectedBytes().length);
assertThat(length).isEqualTo(resource.getExpectedResolvedLength()); if (length != C.LENGTH_UNSET) {
assertThat(length).isEqualTo(resource.getExpectedBytes().length);
}
assertThat(data).isEqualTo(resource.getExpectedBytes()); assertThat(data).isEqualTo(resource.getExpectedBytes());
} finally { } finally {
dataSource.close(); dataSource.close();
@ -120,8 +122,8 @@ public abstract class DataSourceContractTest {
? Util.readToEnd(dataSource) ? Util.readToEnd(dataSource)
: Util.readExactly(dataSource, resource.getExpectedBytes().length - 3); : Util.readExactly(dataSource, resource.getExpectedBytes().length - 3);
if (resource.getExpectedResolvedLength() != C.LENGTH_UNSET) { if (length != C.LENGTH_UNSET) {
assertThat(length).isEqualTo(resource.getExpectedResolvedLength() - 3); assertThat(length).isEqualTo(resource.getExpectedBytes().length - 3);
} }
byte[] expectedData = byte[] expectedData =
Arrays.copyOfRange(resource.getExpectedBytes(), 3, resource.getExpectedBytes().length); Arrays.copyOfRange(resource.getExpectedBytes(), 3, resource.getExpectedBytes().length);
@ -219,19 +221,13 @@ 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 resolvesToUnknownLength;
private final boolean endOfInputExpected; private final boolean endOfInputExpected;
private TestResource( private TestResource(
@Nullable String name, @Nullable String name, Uri uri, byte[] expectedBytes, boolean endOfInputExpected) {
Uri uri,
byte[] expectedBytes,
boolean resolvesToUnknownLength,
boolean endOfInputExpected) {
this.name = name; this.name = name;
this.uri = uri; this.uri = uri;
this.expectedBytes = expectedBytes; this.expectedBytes = expectedBytes;
this.resolvesToUnknownLength = resolvesToUnknownLength;
this.endOfInputExpected = endOfInputExpected; this.endOfInputExpected = endOfInputExpected;
} }
@ -251,16 +247,6 @@ public abstract class DataSourceContractTest {
return expectedBytes; return expectedBytes;
} }
/**
* Returns the expected resolved length of this resource.
*
* <p>This is either {@link #getExpectedBytes() getExpectedBytes().length} or {@link
* C#LENGTH_UNSET}.
*/
public long getExpectedResolvedLength() {
return resolvesToUnknownLength ? C.LENGTH_UNSET : expectedBytes.length;
}
/** /**
* Returns whether {@link DataSource#read} is expected to return {@link C#RESULT_END_OF_INPUT} * Returns whether {@link DataSource#read} is expected to return {@link C#RESULT_END_OF_INPUT}
* after all the resource data are read. * after all the resource data are read.
@ -274,7 +260,6 @@ public abstract class DataSourceContractTest {
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 resolvesToUnknownLength;
private boolean endOfInputExpected; private boolean endOfInputExpected;
/** Construct a new instance. */ /** Construct a new instance. */
@ -307,16 +292,6 @@ public abstract class DataSourceContractTest {
return this; return this;
} }
/**
* Sets whether {@link DataSource#open(DataSpec)} is expected to return {@link C#LENGTH_UNSET}
* when passed the URI of this resource and a {@link DataSpec} with {@code length ==
* C.LENGTH_UNSET}.
*/
public Builder setResolvesToUnknownLength(boolean value) {
this.resolvesToUnknownLength = value;
return this;
}
/** /**
* Sets whether {@link DataSource#read} is expected to return {@link C#RESULT_END_OF_INPUT} * 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}. * after all the resource data have been read. By default, this is set to {@code true}.
@ -328,11 +303,7 @@ public abstract class DataSourceContractTest {
public TestResource build() { public TestResource build() {
return new TestResource( return new TestResource(
name, name, checkNotNull(uri), checkNotNull(expectedBytes), endOfInputExpected);
checkNotNull(uri),
checkNotNull(expectedBytes),
resolvesToUnknownLength,
endOfInputExpected);
} }
} }
} }

View File

@ -91,6 +91,9 @@ public class WebServerDispatcher extends Dispatcher {
/** /**
* Sets if the resource should resolve to an unknown length. Defaults to false. * Sets if the resource should resolve to an unknown length. Defaults to false.
* *
* <p>If true, responses to unbound requests won't include a Content-Length header and
* Content-Range headers won't include the total resource length.
*
* @return this builder, for convenience. * @return this builder, for convenience.
*/ */
public Builder resolvesToUnknownLength(boolean resolvesToUnknownLength) { public Builder resolvesToUnknownLength(boolean resolvesToUnknownLength) {
@ -133,12 +136,7 @@ public class WebServerDispatcher extends Dispatcher {
return supportsRangeRequests; return supportsRangeRequests;
} }
/** /** Returns true if the resource should resolve to an unknown length. */
* Returns true if the server shouldn't include the resource length in header responses.
*
* <p>Responses to unbound requests won't include a Content-Length header, and Content-Range
* headers won't include the total resource length.
*/
public boolean resolvesToUnknownLength() { public boolean resolvesToUnknownLength() {
return resolvesToUnknownLength; return resolvesToUnknownLength;
} }