# DataSourceContractTest

Artifact: [androidx.media3:media3-test-utils](https://developer.android.com/jetpack/androidx/releases/media3) [View Source](https://cs.android.com/search?q=file:androidx/media3/test/utils/DataSourceContractTest.java+class:androidx.media3.test.utils.DataSourceContractTest)

*** ** * ** ***


```
@UnstableApi
abstract class DataSourceContractTest
```

<br />

*** ** * ** ***

A collection of contract tests for `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource` implementations.

Subclasses should only include the logic necessary to construct the DataSource (overriding either `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#createDataSource()` or `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#createDataSources()`) and allow it to successfully read data (overriding `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getTestResources()`. They shouldn't include any new `https://junit.org/junit4/javadoc/latest/org/junit/Test.html` methods - implementation-specific tests should be in a separate class.

Most implementations should pass all these tests. If necessary, subclasses can disable tests by overriding the `https://junit.org/junit4/javadoc/latest/org/junit/Test.html` method with a no-op implementation. It's recommended (but not required) to also annotate this `https://junit.org/junit4/javadoc/latest/org/junit/Ignore.html` so that JUnit correctly reports the test as skipped/ignored instead of passing.

## Summary

| ### Nested types |
|---|
| `class https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest.FakeTransferListener : https://developer.android.com/reference/kotlin/androidx/media3/datasource/TransferListener` A `https://developer.android.com/reference/kotlin/androidx/media3/datasource/TransferListener` that only keeps track of the transferred bytes. |
| `class https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest.TestResource` Information about a resource that can be used to test the `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource` instance. |
| `class https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest.TestResource.Builder` Builder for `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest.TestResource` instances. |

| ### Public constructors |
|---|
| `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#DataSourceContractTest()()` |

| ### Public functions |
|---|---|
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#dataSpecWithEndPositionOutOfRange_readsToEnd()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#dataSpecWithLength_readExpectedRange()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#dataSpecWithLength_readUntilEndInTwoParts()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#dataSpecWithPositionAndLength_readExpectedRange()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#dataSpecWithPositionAtEndAndLength_readsZeroBytes()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#dataSpecWithPositionAtEnd_readsZeroBytes()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#dataSpecWithPositionOutOfRange_throwsPositionOutOfRangeException()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#dataSpecWithPosition_readUntilEnd()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getResponseHeaders_caseInsensitive()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getResponseHeaders_isEmptyWhileNotOpen()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getResponseHeaders_noNullKeysOrValues()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getResponseHeaders_resourceNotFound_isEmptyWhileNotOpen()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getResponseHeaders_returnsExpectedValues()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getUri_resourceNotFound_returnsNullIfNotOpened()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getUri_returnsExpectedValueOnlyWhileOpen()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#resourceNotFound()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#resourceNotFound_transferListenerCallbacks()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#transferListenerCallbacks()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#unboundedDataSpecWithGzipFlag_readUntilEnd()()` `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSpec#FLAG_ALLOW_GZIP()` should either be ignored by `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource` implementations, or correctly handled (i.e. the data is decompressed before being returned from `https://developer.android.com/reference/kotlin/androidx/media3/common/DataReader#read(byte[],int,int)`). |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#unboundedDataSpec_readExpectedBytesWithOffset()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#unboundedDataSpec_readUntilEnd()()` |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `@https://junit.org/junit4/javadoc/latest/org/junit/Test.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#uriSchemeIsCaseInsensitive()()` |

| ### Protected functions |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource!` | `@https://checkerframework.org/api/com/google/errorprone/annotations/ForOverride.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#createDataSource()()` Creates and returns an instance of the `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource`. |
| `(https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-mutable-list/index.html)https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-list/index.html<https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource!>!` | `@https://checkerframework.org/api/com/google/errorprone/annotations/ForOverride.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#createDataSources()()` Creates and returns a list of instances of the `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource`. |
| `(https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-mutable-list/index.html)https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-list/index.html<https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest.TestResource!>!` | `@https://checkerframework.org/api/com/google/errorprone/annotations/ForOverride.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getNotFoundResources()()` Returns a non-empty list of `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest.TestResource` that don't resolve. |
| `https://developer.android.com/reference/android/net/Uri.html!` | `@https://checkerframework.org/api/com/google/errorprone/annotations/ForOverride.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getNotFoundUri()()` Returns a `https://developer.android.com/reference/android/net/Uri.html` that doesn't resolve. |
| `abstract https://guava.dev/releases/snapshot-android/api/docs/com/google/common/collect/ImmutableList.html<https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest.TestResource!>!` | `@https://checkerframework.org/api/com/google/errorprone/annotations/ForOverride.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getTestResources()()` Returns `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest.TestResource` instances. |
| `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource?` | `@https://checkerframework.org/api/com/google/errorprone/annotations/ForOverride.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getTransferListenerDataSource()()` Returns the `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource` that will be included in the `https://developer.android.com/reference/kotlin/androidx/media3/datasource/TransferListener` callbacks for the `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource` most recently created by `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#createDataSource()`. |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html` | `@https://checkerframework.org/api/com/google/errorprone/annotations/ForOverride.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#unboundedReadsAreIndefinite()()` Returns whether the `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource` will continue reading indefinitely for unbounded `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSpec`. |

| ### Public properties |
|---|---|
| `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/AdditionalFailureInfo!` | `@https://junit.org/junit4/javadoc/latest/org/junit/Rule.html https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#additionalFailureInfo()` |

## Public constructors

### DataSourceContractTest

```
DataSourceContractTest()
```

## Public functions

### dataSpecWithEndPositionOutOfRange_readsToEnd

```
@Test
fun dataSpecWithEndPositionOutOfRange_readsToEnd(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### dataSpecWithLength_readExpectedRange

```
@Test
fun dataSpecWithLength_readExpectedRange(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### dataSpecWithLength_readUntilEndInTwoParts

```
@Test
fun dataSpecWithLength_readUntilEndInTwoParts(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### dataSpecWithPositionAndLength_readExpectedRange

```
@Test
fun dataSpecWithPositionAndLength_readExpectedRange(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### dataSpecWithPositionAtEndAndLength_readsZeroBytes

```
@Test
fun dataSpecWithPositionAtEndAndLength_readsZeroBytes(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### dataSpecWithPositionAtEnd_readsZeroBytes

```
@Test
fun dataSpecWithPositionAtEnd_readsZeroBytes(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### dataSpecWithPositionOutOfRange_throwsPositionOutOfRangeException

```
@Test
fun dataSpecWithPositionOutOfRange_throwsPositionOutOfRangeException(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### dataSpecWithPosition_readUntilEnd

```
@Test
fun dataSpecWithPosition_readUntilEnd(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### getResponseHeaders_caseInsensitive

```
@Test
fun getResponseHeaders_caseInsensitive(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### getResponseHeaders_isEmptyWhileNotOpen

```
@Test
fun getResponseHeaders_isEmptyWhileNotOpen(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### getResponseHeaders_noNullKeysOrValues

```
@Test
fun getResponseHeaders_noNullKeysOrValues(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### getResponseHeaders_resourceNotFound_isEmptyWhileNotOpen

```
@Test
fun getResponseHeaders_resourceNotFound_isEmptyWhileNotOpen(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### getResponseHeaders_returnsExpectedValues

```
@Test
fun getResponseHeaders_returnsExpectedValues(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### getUri_resourceNotFound_returnsNullIfNotOpened

```
@Test
fun getUri_resourceNotFound_returnsNullIfNotOpened(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### getUri_returnsExpectedValueOnlyWhileOpen

```
@Test
fun getUri_returnsExpectedValueOnlyWhileOpen(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### resourceNotFound

```
@Test
fun resourceNotFound(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### resourceNotFound_transferListenerCallbacks

```
@Test
fun resourceNotFound_transferListenerCallbacks(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### transferListenerCallbacks

```
@Test
fun transferListenerCallbacks(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### unboundedDataSpecWithGzipFlag_readUntilEnd

```
@Test
fun unboundedDataSpecWithGzipFlag_readUntilEnd(): Unit
```

`https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSpec#FLAG_ALLOW_GZIP()` should either be ignored by `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource` implementations, or correctly handled (i.e. the data is decompressed before being returned from `https://developer.android.com/reference/kotlin/androidx/media3/common/DataReader#read(byte[],int,int)`).

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### unboundedDataSpec_readExpectedBytesWithOffset

```
@Test
fun unboundedDataSpec_readExpectedBytesWithOffset(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### unboundedDataSpec_readUntilEnd

```
@Test
fun unboundedDataSpec_readUntilEnd(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### uriSchemeIsCaseInsensitive

```
@Test
fun uriSchemeIsCaseInsensitive(): Unit
```

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

## Protected functions

### createDataSource

```
@ForOverride
protected fun createDataSource(): DataSource!
```

Creates and returns an instance of the `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource`.

Only one of `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#createDataSource()` and `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#createDataSources()` should be implemented.

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### createDataSources

```
@ForOverride
protected fun createDataSources(): (Mutable)List<DataSource!>!
```

Creates and returns a list of instances of the `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource`.

Only one of `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#createDataSource()` and `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#createDataSources()` should be implemented.

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### getNotFoundResources

```
@ForOverride
protected fun getNotFoundResources(): (Mutable)List<DataSourceContractTest.TestResource!>!
```

Returns a non-empty list of `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest.TestResource` that don't resolve.

This is used to test how a `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource` handles nonexistent data. Multiple entries and the rest of the `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest.TestResource` fields can be helpful for situations where the data can be "not found" for different reasons. For example in HTTP, 'server not found' generally results in a failed HTTP connection while 'file not found' generally results in a successful connection with a 404 HTTP error code and some response headers, and the handling code for these two cases may be different (and therefore worth testing separately).

Only one of `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getNotFoundUri()` and `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getNotFoundResources()` should be implemented.

### getNotFoundUri

```
@ForOverride
protected fun getNotFoundUri(): Uri!
```

Returns a `https://developer.android.com/reference/android/net/Uri.html` that doesn't resolve.

This is used to test how a `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource` handles nonexistent data.

Only one of `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getNotFoundUri()` and `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#getNotFoundResources()` should be implemented.

### getTestResources

```
@ForOverride
protected abstract fun getTestResources(): ImmutableList<DataSourceContractTest.TestResource!>!
```

Returns `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest.TestResource` instances.

Each resource will be used to exercise the `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource` instance, allowing different behaviours to be tested. Every `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest.TestResource#getExpectedBytes()` must be at least 5 bytes.

If multiple resources are returned, it's recommended to disambiguate them using `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest.TestResource.Builder#setName(java.lang.String)`.

| Throws |
|---|---|
| `https://developer.android.com/reference/java/lang/Exception.html` |   |

### getTransferListenerDataSource

```
@ForOverride
protected fun getTransferListenerDataSource(): DataSource?
```

Returns the `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource` that will be included in the `https://developer.android.com/reference/kotlin/androidx/media3/datasource/TransferListener` callbacks for the `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource` most recently created by `https://developer.android.com/reference/kotlin/androidx/media3/test/utils/DataSourceContractTest#createDataSource()`. If it's the same `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource` then `null` can be returned.

### unboundedReadsAreIndefinite

```
@ForOverride
protected fun unboundedReadsAreIndefinite(): Boolean
```

Returns whether the `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSource` will continue reading indefinitely for unbounded `https://developer.android.com/reference/kotlin/androidx/media3/datasource/DataSpec`.

## Public properties

### additionalFailureInfo

```
@Rule
val additionalFailureInfo: AdditionalFailureInfo!
```