Introduce FakeExtractorInput (based loosely on RecordableExtractorInput).
- Use it to simplify a bunch of tests. - Will also replace RecordableExtractorInput in a subsequent CL. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=117220030
This commit is contained in:
parent
a1a48abe92
commit
300b58e530
@ -15,14 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer.extractor.webm;
|
package com.google.android.exoplayer.extractor.webm;
|
||||||
|
|
||||||
import com.google.android.exoplayer.C;
|
|
||||||
import com.google.android.exoplayer.extractor.DefaultExtractorInput;
|
|
||||||
import com.google.android.exoplayer.extractor.ExtractorInput;
|
import com.google.android.exoplayer.extractor.ExtractorInput;
|
||||||
import com.google.android.exoplayer.testutil.FakeDataSource;
|
import com.google.android.exoplayer.testutil.FakeExtractorInput;
|
||||||
import com.google.android.exoplayer.upstream.DataSource;
|
import com.google.android.exoplayer.testutil.TestUtil;
|
||||||
import com.google.android.exoplayer.upstream.DataSpec;
|
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
@ -140,22 +135,15 @@ public class DefaultEbmlReaderTest extends TestCase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to build an {@link ExtractorInput} from byte data.
|
* Helper to build an {@link ExtractorInput} from byte data.
|
||||||
* <p>
|
|
||||||
* Each argument must be able to cast to a byte value.
|
|
||||||
*
|
*
|
||||||
* @param data Zero or more integers with values between {@code 0x00} and {@code 0xFF}.
|
* @param data Zero or more integers with values between {@code 0x00} and {@code 0xFF}.
|
||||||
* @return An {@link ExtractorInput} from which the data can be read.
|
* @return An {@link ExtractorInput} from which the data can be read.
|
||||||
* @throws IOException If an error occurs creating the input.
|
|
||||||
*/
|
*/
|
||||||
private static ExtractorInput createTestInput(int... data) throws IOException {
|
private static ExtractorInput createTestInput(int... data) {
|
||||||
byte[] bytes = new byte[data.length];
|
return new FakeExtractorInput.Builder()
|
||||||
for (int i = 0; i < data.length; i++) {
|
.setData(TestUtil.createByteArray(data))
|
||||||
bytes[i] = (byte) data[i];
|
.setSimulateUnknownLength(true)
|
||||||
}
|
.build();
|
||||||
DataSource dataSource = new FakeDataSource.Builder().appendReadData(bytes).build();
|
|
||||||
dataSource.open(new DataSpec(Uri.parse("http://www.google.com")));
|
|
||||||
ExtractorInput input = new DefaultExtractorInput(dataSource, 0, C.LENGTH_UNBOUNDED);
|
|
||||||
return input;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,26 +16,20 @@
|
|||||||
package com.google.android.exoplayer.extractor.webm;
|
package com.google.android.exoplayer.extractor.webm;
|
||||||
|
|
||||||
import com.google.android.exoplayer.C;
|
import com.google.android.exoplayer.C;
|
||||||
import com.google.android.exoplayer.extractor.DefaultExtractorInput;
|
|
||||||
import com.google.android.exoplayer.extractor.ExtractorInput;
|
import com.google.android.exoplayer.extractor.ExtractorInput;
|
||||||
import com.google.android.exoplayer.testutil.FakeDataSource;
|
import com.google.android.exoplayer.testutil.FakeExtractorInput;
|
||||||
import com.google.android.exoplayer.upstream.DataSource;
|
import com.google.android.exoplayer.testutil.FakeExtractorInput.SimulatedIOException;
|
||||||
import com.google.android.exoplayer.upstream.DataSpec;
|
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link VarintReader}.
|
* Tests for {@link VarintReader}.
|
||||||
*/
|
*/
|
||||||
public class VarintReaderTest extends TestCase {
|
public final class VarintReaderTest extends TestCase {
|
||||||
|
|
||||||
private static final String TEST_URI = "http://www.google.com";
|
|
||||||
private static final byte MAX_BYTE = (byte) 0xFF;
|
private static final byte MAX_BYTE = (byte) 0xFF;
|
||||||
|
|
||||||
private static final byte[] DATA_1_BYTE_0 = new byte[] {(byte) 0x80};
|
private static final byte[] DATA_1_BYTE_0 = new byte[] {(byte) 0x80};
|
||||||
@ -88,12 +82,10 @@ public class VarintReaderTest extends TestCase {
|
|||||||
|
|
||||||
public void testReadVarintEndOfInputAtStart() throws IOException, InterruptedException {
|
public void testReadVarintEndOfInputAtStart() throws IOException, InterruptedException {
|
||||||
VarintReader reader = new VarintReader();
|
VarintReader reader = new VarintReader();
|
||||||
// Build an input, and read to the end.
|
// Build an input with no data.
|
||||||
DataSource dataSource = buildDataSource(new byte[1]);
|
ExtractorInput input = new FakeExtractorInput.Builder()
|
||||||
dataSource.open(new DataSpec(Uri.parse(TEST_URI)));
|
.setSimulateUnknownLength(true)
|
||||||
ExtractorInput input = new DefaultExtractorInput(dataSource, 0, C.LENGTH_UNBOUNDED);
|
.build();
|
||||||
int bytesRead = input.read(new byte[1], 0, 1);
|
|
||||||
assertEquals(1, bytesRead);
|
|
||||||
// End of input allowed.
|
// End of input allowed.
|
||||||
long result = reader.readUnsignedVarint(input, true, false, 8);
|
long result = reader.readUnsignedVarint(input, true, false, 8);
|
||||||
assertEquals(C.RESULT_END_OF_INPUT, result);
|
assertEquals(C.RESULT_END_OF_INPUT, result);
|
||||||
@ -108,9 +100,10 @@ public class VarintReaderTest extends TestCase {
|
|||||||
|
|
||||||
public void testReadVarintExceedsMaximumAllowedLength() throws IOException, InterruptedException {
|
public void testReadVarintExceedsMaximumAllowedLength() throws IOException, InterruptedException {
|
||||||
VarintReader reader = new VarintReader();
|
VarintReader reader = new VarintReader();
|
||||||
DataSource dataSource = buildDataSource(DATA_8_BYTE_0);
|
ExtractorInput input = new FakeExtractorInput.Builder()
|
||||||
dataSource.open(new DataSpec(Uri.parse(TEST_URI)));
|
.setData(DATA_8_BYTE_0)
|
||||||
ExtractorInput input = new DefaultExtractorInput(dataSource, 0, C.LENGTH_UNBOUNDED);
|
.setSimulateUnknownLength(true)
|
||||||
|
.build();
|
||||||
long result = reader.readUnsignedVarint(input, false, true, 4);
|
long result = reader.readUnsignedVarint(input, false, true, 4);
|
||||||
assertEquals(C.RESULT_MAX_LENGTH_EXCEEDED, result);
|
assertEquals(C.RESULT_MAX_LENGTH_EXCEEDED, result);
|
||||||
}
|
}
|
||||||
@ -189,9 +182,10 @@ public class VarintReaderTest extends TestCase {
|
|||||||
|
|
||||||
private static void testReadVarint(VarintReader reader, boolean removeMask, byte[] data,
|
private static void testReadVarint(VarintReader reader, boolean removeMask, byte[] data,
|
||||||
int expectedLength, long expectedValue) throws IOException, InterruptedException {
|
int expectedLength, long expectedValue) throws IOException, InterruptedException {
|
||||||
DataSource dataSource = buildDataSource(data);
|
ExtractorInput input = new FakeExtractorInput.Builder()
|
||||||
dataSource.open(new DataSpec(Uri.parse(TEST_URI)));
|
.setData(data)
|
||||||
ExtractorInput input = new DefaultExtractorInput(dataSource, 0, C.LENGTH_UNBOUNDED);
|
.setSimulateUnknownLength(true)
|
||||||
|
.build();
|
||||||
long result = reader.readUnsignedVarint(input, false, removeMask, 8);
|
long result = reader.readUnsignedVarint(input, false, removeMask, 8);
|
||||||
assertEquals(expectedLength, input.getPosition());
|
assertEquals(expectedLength, input.getPosition());
|
||||||
assertEquals(expectedValue, result);
|
assertEquals(expectedValue, result);
|
||||||
@ -199,45 +193,22 @@ public class VarintReaderTest extends TestCase {
|
|||||||
|
|
||||||
private static void testReadVarintFlaky(VarintReader reader, boolean removeMask, byte[] data,
|
private static void testReadVarintFlaky(VarintReader reader, boolean removeMask, byte[] data,
|
||||||
int expectedLength, long expectedValue) throws IOException, InterruptedException {
|
int expectedLength, long expectedValue) throws IOException, InterruptedException {
|
||||||
DataSource dataSource = buildFlakyDataSource(data);
|
ExtractorInput input = new FakeExtractorInput.Builder()
|
||||||
ExtractorInput input = null;
|
.setData(data)
|
||||||
long position = 0;
|
.setSimulateUnknownLength(true)
|
||||||
|
.setSimulateIOErrors(true)
|
||||||
|
.setSimulatePartialReads(true)
|
||||||
|
.build();
|
||||||
long result = -1;
|
long result = -1;
|
||||||
while (result == -1) {
|
while (result == -1) {
|
||||||
dataSource.open(new DataSpec(Uri.parse(TEST_URI), position, C.LENGTH_UNBOUNDED, null));
|
|
||||||
input = new DefaultExtractorInput(dataSource, position, C.LENGTH_UNBOUNDED);
|
|
||||||
try {
|
try {
|
||||||
result = reader.readUnsignedVarint(input, false, removeMask, 8);
|
result = reader.readUnsignedVarint(input, false, removeMask, 8);
|
||||||
position = input.getPosition();
|
} catch (SimulatedIOException e) {
|
||||||
} catch (IOException e) {
|
// Expected.
|
||||||
// Expected. We'll try again from the position that the input was advanced to.
|
|
||||||
position = input.getPosition();
|
|
||||||
dataSource.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertEquals(expectedLength, input.getPosition());
|
assertEquals(expectedLength, input.getPosition());
|
||||||
assertEquals(expectedValue, result);
|
assertEquals(expectedValue, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DataSource buildDataSource(byte[] data) {
|
|
||||||
FakeDataSource.Builder builder = new FakeDataSource.Builder();
|
|
||||||
builder.appendReadData(data);
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static DataSource buildFlakyDataSource(byte[] data) {
|
|
||||||
FakeDataSource.Builder builder = new FakeDataSource.Builder();
|
|
||||||
builder.appendReadError(new IOException("A"));
|
|
||||||
builder.appendReadData(new byte[] {data[0]});
|
|
||||||
if (data.length > 1) {
|
|
||||||
builder.appendReadError(new IOException("B"));
|
|
||||||
builder.appendReadData(new byte[] {data[1]});
|
|
||||||
}
|
|
||||||
if (data.length > 2) {
|
|
||||||
builder.appendReadError(new IOException("C"));
|
|
||||||
builder.appendReadData(Arrays.copyOfRange(data, 2, data.length));
|
|
||||||
}
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ public final class FakeDataSource implements DataSource {
|
|||||||
private int currentSegmentIndex;
|
private int currentSegmentIndex;
|
||||||
private long bytesRemaining;
|
private long bytesRemaining;
|
||||||
|
|
||||||
public FakeDataSource(boolean simulateUnknownLength, ArrayList<Segment> segments) {
|
private FakeDataSource(boolean simulateUnknownLength, ArrayList<Segment> segments) {
|
||||||
this.simulateUnknownLength = simulateUnknownLength;
|
this.simulateUnknownLength = simulateUnknownLength;
|
||||||
this.segments = segments;
|
this.segments = segments;
|
||||||
long totalLength = 0;
|
long totalLength = 0;
|
||||||
@ -163,7 +163,7 @@ public final class FakeDataSource implements DataSource {
|
|||||||
/**
|
/**
|
||||||
* Builder of {@link FakeDataSource} instances.
|
* Builder of {@link FakeDataSource} instances.
|
||||||
*/
|
*/
|
||||||
public static class Builder {
|
public static final class Builder {
|
||||||
|
|
||||||
private final ArrayList<Segment> segments;
|
private final ArrayList<Segment> segments;
|
||||||
private boolean simulateUnknownLength;
|
private boolean simulateUnknownLength;
|
||||||
|
@ -0,0 +1,270 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer.testutil;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer.C;
|
||||||
|
import com.google.android.exoplayer.extractor.ExtractorInput;
|
||||||
|
|
||||||
|
import android.util.SparseBooleanArray;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fake {@link ExtractorInput} capable of simulating various scenarios.
|
||||||
|
* <p>
|
||||||
|
* Read, skip and peek errors can be simulated using {@link Builder#setSimulateIOErrors)}. When
|
||||||
|
* enabled each read and skip will throw a {@link SimulatedIOException} unless one has already been
|
||||||
|
* thrown from the current position. Each peek will throw {@link SimulatedIOException} unless one
|
||||||
|
* has already been thrown from the current peek position. When a {@link SimulatedIOException} is
|
||||||
|
* thrown the read position is left unchanged and the peek position is reset back to the read
|
||||||
|
* position.
|
||||||
|
* <p>
|
||||||
|
* Partial reads and skips can be simulated using {@link Builder#setSimulatePartialReads}. When
|
||||||
|
* enabled, {@link #read(byte[], int, int)} and {@link #skip(int)} calls will only read or skip a
|
||||||
|
* single byte unless a partial read or skip has already been performed that had the same target
|
||||||
|
* position. For example, a first read request for 10 bytes will be partially satisfied by reading
|
||||||
|
* a single byte and advancing the position to 1. If the following read request attempts to read 9
|
||||||
|
* bytes then it will be fully satisfied, since it has the same target position of 10.
|
||||||
|
* <p>
|
||||||
|
* Unknown data length can be simulated using {@link Builder#setSimulateUnknownLength}. When enabled
|
||||||
|
* {@link getLength()} will return {@link C#LENGTH_UNBOUNDED} rather than the length of the data.
|
||||||
|
*/
|
||||||
|
public final class FakeExtractorInput implements ExtractorInput {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when simulating an {@link IOException}.
|
||||||
|
*/
|
||||||
|
public static final class SimulatedIOException extends IOException {
|
||||||
|
|
||||||
|
public SimulatedIOException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final byte[] data;
|
||||||
|
private final boolean simulateUnknownLength;
|
||||||
|
private final boolean simulatePartialReads;
|
||||||
|
private final boolean simulateIOErrors;
|
||||||
|
|
||||||
|
private int readPosition;
|
||||||
|
private int peekPosition;
|
||||||
|
|
||||||
|
private final SparseBooleanArray partiallySatisfiedTargetPositions;
|
||||||
|
private final SparseBooleanArray failedReadPositions;
|
||||||
|
private final SparseBooleanArray failedPeekPositions;
|
||||||
|
|
||||||
|
private FakeExtractorInput(byte[] data, boolean simulateUnknownLength,
|
||||||
|
boolean simulatePartialReads, boolean simulateIOErrors) {
|
||||||
|
this.data = data;
|
||||||
|
this.simulateUnknownLength = simulateUnknownLength;
|
||||||
|
this.simulatePartialReads = simulatePartialReads;
|
||||||
|
this.simulateIOErrors = simulateIOErrors;
|
||||||
|
partiallySatisfiedTargetPositions = new SparseBooleanArray();
|
||||||
|
failedReadPositions = new SparseBooleanArray();
|
||||||
|
failedPeekPositions = new SparseBooleanArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the read and peek positions.
|
||||||
|
*
|
||||||
|
* @param position The position to set.
|
||||||
|
*/
|
||||||
|
public void setPosition(int position) {
|
||||||
|
Assert.assertTrue(0 <= position && position < data.length);
|
||||||
|
readPosition = position;
|
||||||
|
peekPosition = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] target, int offset, int length) throws IOException {
|
||||||
|
length = getReadLength(length);
|
||||||
|
if (readFully(target, offset, length, true)) {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
return C.RESULT_END_OF_INPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean readFully(byte[] target, int offset, int length, boolean allowEndOfInput)
|
||||||
|
throws IOException {
|
||||||
|
if (!checkXFully(allowEndOfInput, readPosition, length, failedReadPositions)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
System.arraycopy(data, readPosition, target, offset, length);
|
||||||
|
readPosition += length;
|
||||||
|
peekPosition = readPosition;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readFully(byte[] target, int offset, int length) throws IOException {
|
||||||
|
readFully(target, offset, length, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int skip(int length) throws IOException {
|
||||||
|
length = getReadLength(length);
|
||||||
|
if (skipFully(length, true)) {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
return C.RESULT_END_OF_INPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean skipFully(int length, boolean allowEndOfInput) throws IOException {
|
||||||
|
if (!checkXFully(allowEndOfInput, readPosition, length, failedReadPositions)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
readPosition += length;
|
||||||
|
peekPosition = readPosition;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void skipFully(int length) throws IOException {
|
||||||
|
skipFully(length, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean peekFully(byte[] target, int offset, int length, boolean allowEndOfInput)
|
||||||
|
throws IOException {
|
||||||
|
if (!checkXFully(allowEndOfInput, peekPosition, length, failedPeekPositions)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
System.arraycopy(data, peekPosition, target, offset, length);
|
||||||
|
peekPosition += length;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void peekFully(byte[] target, int offset, int length) throws IOException {
|
||||||
|
peekFully(target, offset, length, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean advancePeekPosition(int length, boolean allowEndOfInput) throws IOException {
|
||||||
|
if (!checkXFully(allowEndOfInput, peekPosition, length, failedPeekPositions)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
peekPosition += length;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void advancePeekPosition(int length) throws IOException {
|
||||||
|
advancePeekPosition(length, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetPeekPosition() {
|
||||||
|
peekPosition = readPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getPeekPosition() {
|
||||||
|
return peekPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getPosition() {
|
||||||
|
return readPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLength() {
|
||||||
|
return simulateUnknownLength ? C.LENGTH_UNBOUNDED : data.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkXFully(boolean allowEndOfInput, int position, int length,
|
||||||
|
SparseBooleanArray failedPositions) throws IOException {
|
||||||
|
if (simulateIOErrors && !failedPositions.get(position)) {
|
||||||
|
failedPositions.put(position, true);
|
||||||
|
peekPosition = readPosition;
|
||||||
|
throw new SimulatedIOException("Simulated IO error at position: " + position);
|
||||||
|
}
|
||||||
|
if (isEof()) {
|
||||||
|
if (allowEndOfInput) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
throw new EOFException();
|
||||||
|
}
|
||||||
|
if (position + length > data.length) {
|
||||||
|
throw new IOException("Attempted to move past end of data: (" + position + " + "
|
||||||
|
+ length + ") > " + data.length);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getReadLength(int requestedLength) {
|
||||||
|
int targetPosition = readPosition + requestedLength;
|
||||||
|
if (simulatePartialReads && requestedLength > 1
|
||||||
|
&& !partiallySatisfiedTargetPositions.get(targetPosition)) {
|
||||||
|
partiallySatisfiedTargetPositions.put(targetPosition, true);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return Math.min(requestedLength, data.length - readPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isEof() {
|
||||||
|
return readPosition == data.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder of {@link FakeExtractorInput} instances.
|
||||||
|
*/
|
||||||
|
public static final class Builder {
|
||||||
|
|
||||||
|
private byte[] data;
|
||||||
|
private boolean simulateUnknownLength;
|
||||||
|
private boolean simulatePartialReads;
|
||||||
|
private boolean simulateIOErrors;
|
||||||
|
|
||||||
|
public Builder() {
|
||||||
|
data = new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setData(byte[] data) {
|
||||||
|
this.data = data;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setSimulateUnknownLength(boolean simulateUnknownLength) {
|
||||||
|
this.simulateUnknownLength = simulateUnknownLength;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setSimulatePartialReads(boolean simulatePartialReads) {
|
||||||
|
this.simulatePartialReads = simulatePartialReads;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setSimulateIOErrors(boolean simulateIOErrors) {
|
||||||
|
this.simulateIOErrors = simulateIOErrors;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FakeExtractorInput build() {
|
||||||
|
return new FakeExtractorInput(data, simulateUnknownLength, simulatePartialReads,
|
||||||
|
simulateIOErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,24 +15,18 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer.testutil;
|
package com.google.android.exoplayer.testutil;
|
||||||
|
|
||||||
import com.google.android.exoplayer.C;
|
|
||||||
import com.google.android.exoplayer.extractor.DefaultExtractorInput;
|
|
||||||
import com.google.android.exoplayer.extractor.Extractor;
|
import com.google.android.exoplayer.extractor.Extractor;
|
||||||
import com.google.android.exoplayer.extractor.ExtractorInput;
|
|
||||||
import com.google.android.exoplayer.extractor.PositionHolder;
|
import com.google.android.exoplayer.extractor.PositionHolder;
|
||||||
import com.google.android.exoplayer.upstream.DataSpec;
|
|
||||||
import com.google.android.exoplayer.util.Assertions;
|
import com.google.android.exoplayer.util.Assertions;
|
||||||
import com.google.android.exoplayer.util.Util;
|
import com.google.android.exoplayer.util.Util;
|
||||||
|
|
||||||
import android.app.Instrumentation;
|
import android.app.Instrumentation;
|
||||||
import android.net.Uri;
|
|
||||||
import android.test.InstrumentationTestCase;
|
import android.test.InstrumentationTestCase;
|
||||||
|
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,32 +38,19 @@ public class TestUtil {
|
|||||||
|
|
||||||
public static void consumeTestData(Extractor extractor, byte[] data)
|
public static void consumeTestData(Extractor extractor, byte[] data)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
ExtractorInput input = createTestExtractorInput(data);
|
FakeExtractorInput input = new FakeExtractorInput.Builder().setData(data).build();
|
||||||
PositionHolder seekPositionHolder = new PositionHolder();
|
PositionHolder seekPositionHolder = new PositionHolder();
|
||||||
int readResult = Extractor.RESULT_CONTINUE;
|
int readResult = Extractor.RESULT_CONTINUE;
|
||||||
while (readResult != Extractor.RESULT_END_OF_INPUT) {
|
while (readResult != Extractor.RESULT_END_OF_INPUT) {
|
||||||
readResult = extractor.read(input, seekPositionHolder);
|
readResult = extractor.read(input, seekPositionHolder);
|
||||||
if (readResult == Extractor.RESULT_SEEK) {
|
if (readResult == Extractor.RESULT_SEEK) {
|
||||||
input = createTestExtractorInput(data, (int) seekPositionHolder.position);
|
long seekPosition = seekPositionHolder.position;
|
||||||
|
Assertions.checkState(0 < seekPosition && seekPosition <= Integer.MAX_VALUE);
|
||||||
|
input.setPosition((int) seekPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ExtractorInput createTestExtractorInput(byte[] data) throws IOException {
|
|
||||||
return createTestExtractorInput(data, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ExtractorInput createTestExtractorInput(byte[] data, int offset)
|
|
||||||
throws IOException {
|
|
||||||
if (offset != 0) {
|
|
||||||
data = Arrays.copyOfRange(data, offset, data.length);
|
|
||||||
}
|
|
||||||
FakeDataSource dataSource = new FakeDataSource.Builder().appendReadData(data).build();
|
|
||||||
dataSource.open(new DataSpec(Uri.parse("http://www.google.com")));
|
|
||||||
ExtractorInput input = new DefaultExtractorInput(dataSource, offset, C.LENGTH_UNBOUNDED);
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] buildTestData(int length) {
|
public static byte[] buildTestData(int length) {
|
||||||
return buildTestData(length, length);
|
return buildTestData(length, length);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user