Add DataSource contract tests to verify offset and position

These tests addresses two identified gaps in the contract:
 - Ensures that the output buffer offset passed to the `DataSource.read` method is correctly applied.
 - Verifies that the position within the input stream is properly incremented when reading in two parts.

PiperOrigin-RevId: 656358935
This commit is contained in:
rohks 2024-07-26 05:08:42 -07:00 committed by Copybara-Service
parent ccf704b30b
commit 32c9d62d39
3 changed files with 66 additions and 0 deletions

View File

@ -95,6 +95,9 @@
* Leanback extension:
* Cast Extension:
* Test Utilities:
* `DataSourceContractTest` now includes tests to verify:
* Input stream `read position` is updated.
* Output buffer `offset` is applied correctly.
* Demo app:
* Remove deprecated symbols:
* Remove deprecated `Player.hasPrevious`, `Player.hasPreviousWindow()`.

View File

@ -83,6 +83,11 @@ public class UdpDataSourceContractTest extends DataSourceContractTest {
@Override
public void dataSpecWithLength_readExpectedRange() {}
@Test
@Ignore("UdpDataSource doesn't support DataSpec's position or length [internal: b/175856954]")
@Override
public void dataSpecWithLength_readUntilEndInTwoParts() {}
@Test
@Ignore("UdpDataSource doesn't support DataSpec's position or length [internal: b/175856954]")
@Override

View File

@ -151,6 +151,41 @@ public abstract class DataSourceContractTest {
});
}
@Test
public void unboundedDataSpec_readExpectedBytesWithOffset() throws Exception {
forAllTestResourcesAndDataSources(
(resource, dataSource) -> {
try {
dataSource.open(new DataSpec.Builder().setUri(resource.getUri()).build());
int offset = 2;
byte[] data = new byte[resource.getExpectedBytes().length + offset];
// Initialize the first two bytes with non-zero values.
data[0] = (byte) 0xA5;
data[1] = (byte) 0x5A;
while (offset != data.length) {
int bytesRead = dataSource.read(data, offset, resource.getExpectedBytes().length);
if (bytesRead == C.RESULT_END_OF_INPUT) {
break;
}
offset += bytesRead;
}
// Assert that the first two bytes have not been modified.
assertThat(data[0]).isEqualTo((byte) 0xA5);
assertThat(data[1]).isEqualTo((byte) 0x5A);
assertThat(offset).isEqualTo(data.length);
byte[] actualData = Arrays.copyOfRange(data, 2, data.length);
assertThat(actualData).isEqualTo(resource.getExpectedBytes());
} finally {
dataSource.close();
}
});
}
@Test
public void dataSpecWithPosition_readUntilEnd() throws Exception {
forAllTestResourcesAndDataSources(
@ -196,6 +231,29 @@ public abstract class DataSourceContractTest {
});
}
@Test
public void dataSpecWithLength_readUntilEndInTwoParts() throws Exception {
forAllTestResourcesAndDataSources(
(resource, dataSource) -> {
try {
int length = resource.getExpectedBytes().length;
dataSource.open(
new DataSpec.Builder().setUri(resource.getUri()).setLength(length).build());
byte[] firstPartData = DataSourceUtil.readExactly(dataSource, length / 2);
byte[] secondPartData = DataSourceUtil.readToEnd(dataSource);
byte[] expectedFirstPartData = Arrays.copyOf(resource.getExpectedBytes(), length / 2);
byte[] expectedSecondPartData =
Arrays.copyOfRange(resource.getExpectedBytes(), length / 2, length);
assertThat(firstPartData).isEqualTo(expectedFirstPartData);
assertThat(secondPartData).isEqualTo(expectedSecondPartData);
} finally {
dataSource.close();
}
});
}
@Test
public void dataSpecWithPositionAndLength_readExpectedRange() throws Exception {
forAllTestResourcesAndDataSources(