Add contract tests for DataSource#getResponseHeaders

PiperOrigin-RevId: 408840409
This commit is contained in:
ibaker 2021-11-10 12:01:41 +00:00 committed by Ian Baker
parent d1e12dcddf
commit ded68ed981
2 changed files with 86 additions and 0 deletions

View File

@ -20,6 +20,7 @@ import androidx.media3.test.utils.DataSourceContractTest;
import androidx.media3.test.utils.HttpDataSourceTestEnv;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.runner.RunWith;
@ -43,4 +44,8 @@ public class DefaultHttpDataSourceContractTest extends DataSourceContractTest {
protected Uri getNotFoundUri() {
return Uri.parse(httpDataSourceTestEnv.getNonexistentUrl());
}
@Override
@Ignore("internal b/205811776")
public void getResponseHeaders_noNullKeysOrValues() {}
}

View File

@ -19,6 +19,7 @@ import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Util.castNonNull;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@ -40,10 +41,12 @@ import androidx.media3.datasource.DataSourceException;
import androidx.media3.datasource.DataSourceUtil;
import androidx.media3.datasource.DataSpec;
import androidx.media3.datasource.TransferListener;
import com.google.common.base.Ascii;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.junit.Ignore;
import org.junit.Rule;
@ -505,6 +508,62 @@ public abstract class DataSourceContractTest {
assertThat(dataSource.getUri()).isNull();
}
@Test
public void getResponseHeaders_noNullKeysOrValues() throws Exception {
ImmutableList<TestResource> 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 {
dataSource.open(new DataSpec(resource.getUri()));
Map<String, List<String>> responseHeaders = dataSource.getResponseHeaders();
assertThat(responseHeaders).doesNotContainKey(null);
assertThat(responseHeaders.values()).doesNotContain(null);
for (List<String> value : responseHeaders.values()) {
assertThat(value).doesNotContain(null);
}
} finally {
dataSource.close();
}
additionalFailureInfo.setInfo(null);
}
}
@Test
public void getResponseHeaders_caseInsensitive() throws Exception {
ImmutableList<TestResource> 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 {
dataSource.open(new DataSpec(resource.getUri()));
Map<String, List<String>> responseHeaders = dataSource.getResponseHeaders();
for (String key : responseHeaders.keySet()) {
// TODO(internal b/205811776): Remove this when DefaultHttpDataSource is fixed to not
// return a null key.
if (key == null) {
continue;
}
String caseFlippedKey = invertAsciiCaseOfEveryOtherCharacter(key);
assertWithMessage("key='%s', caseFlippedKey='%s'", key, caseFlippedKey)
.that(responseHeaders.get(caseFlippedKey))
.isEqualTo(responseHeaders.get(key));
}
} finally {
dataSource.close();
}
additionalFailureInfo.setInfo(null);
}
}
@Test
public void getResponseHeaders_isEmptyWhileNotOpen() throws Exception {
ImmutableList<TestResource> resources = getTestResources();
@ -550,6 +609,28 @@ public abstract class DataSourceContractTest {
}
}
private static String invertAsciiCaseOfEveryOtherCharacter(String input) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
result.append(i % 2 == 0 ? invertAsciiCase(input.charAt(i)) : input.charAt(i));
}
return result.toString();
}
/**
* Returns {@code c} in the opposite case if it's an ASCII character, otherwise returns {@code c}
* unchanged.
*/
private static char invertAsciiCase(char c) {
if (Ascii.isUpperCase(c)) {
return Ascii.toLowerCase(c);
} else if (Ascii.isLowerCase(c)) {
return Ascii.toUpperCase(c);
} else {
return c;
}
}
/** Information about a resource that can be used to test the {@link DataSource} instance. */
public static final class TestResource {