mirror of
https://github.com/zhigang1992/AndroidVideoCache.git
synced 2026-04-26 13:05:34 +08:00
🎉 VideoCache 1.0 released
This commit is contained in:
48
test/build.gradle
Normal file
48
test/build.gradle
Normal file
@@ -0,0 +1,48 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.github.jcandksolutions.gradle:android-unit-test:2.1.1'
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url 'https://github.com/danikula/android-garden/raw/mvn-repo' }
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 21
|
||||
buildToolsVersion '22.0.1'
|
||||
|
||||
defaultConfig {
|
||||
applicationId 'com.danikula.proxycache.test'
|
||||
minSdkVersion 9
|
||||
targetSdkVersion 18 // Robolectric doesn't support API 19-21
|
||||
versionCode 1
|
||||
versionName '0.1'
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'android-unit-test'
|
||||
|
||||
// to fix AS 0.8.9+ issue (https://github.com/evant/android-studio-unit-test-plugin Troubleshooting)
|
||||
tasks.findByName("assembleDebug").dependsOn("testDebugClasses")
|
||||
|
||||
dependencies {
|
||||
compile project (':library')
|
||||
|
||||
testCompile 'junit:junit:4.10'
|
||||
testCompile 'org.robolectric:robolectric:2.4'
|
||||
testCompile 'com.squareup:fest-android:1.0.0'
|
||||
testCompile 'com.google.guava:guava-jdk5:17.0'
|
||||
testCompile('com.danikula:android-garden:2.0.11-SNAPSHOT') {
|
||||
exclude group: 'com.google.android'
|
||||
}
|
||||
}
|
||||
10
test/src/main/AndroidManifest.xml
Normal file
10
test/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.danikula.videocache.test">
|
||||
|
||||
<uses-sdk android:minSdkVersion="18" />
|
||||
|
||||
<application />
|
||||
|
||||
</manifest>
|
||||
BIN
test/src/main/assets/android.jpg
Normal file
BIN
test/src/main/assets/android.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
BIN
test/src/main/assets/phones.jpg
Normal file
BIN
test/src/main/assets/phones.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 92 KiB |
145
test/src/test/java/com/danikula/videocache/FileCacheTest.java
Normal file
145
test/src/test/java/com/danikula/videocache/FileCacheTest.java
Normal file
@@ -0,0 +1,145 @@
|
||||
package com.danikula.videocache;
|
||||
|
||||
import com.danikula.android.garden.io.Files;
|
||||
import com.danikula.android.garden.io.IoUtils;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.ASSETS_DATA_NAME;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.generate;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.getFileContent;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.getTempFile;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.loadAssetFile;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.newCacheFile;
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Alexey Danilov (danikula@gmail.com).
|
||||
*/
|
||||
@Config(manifest = "src/main/AndroidManifest.xml")
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class FileCacheTest {
|
||||
|
||||
@Test
|
||||
public void testWriteReadDiscCache() throws Exception {
|
||||
int firstPortionLength = 10000;
|
||||
byte[] firstDataPortion = generate(firstPortionLength);
|
||||
File file = newCacheFile();
|
||||
Cache fileCache = new FileCache(file);
|
||||
|
||||
fileCache.append(firstDataPortion, firstDataPortion.length);
|
||||
byte[] readData = new byte[firstPortionLength];
|
||||
fileCache.read(readData, 0, firstPortionLength);
|
||||
assertThat(readData).isEqualTo(firstDataPortion);
|
||||
byte[] fileContent = getFileContent(getTempFile(file));
|
||||
assertThat(readData).isEqualTo(fileContent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileCacheCompletion() throws Exception {
|
||||
File file = newCacheFile();
|
||||
File tempFile = getTempFile(file);
|
||||
Cache fileCache = new FileCache(file);
|
||||
assertThat(file.exists()).isFalse();
|
||||
assertThat(tempFile.exists()).isTrue();
|
||||
|
||||
int dataSize = 345;
|
||||
fileCache.append(generate(dataSize), dataSize);
|
||||
fileCache.complete();
|
||||
|
||||
assertThat(file.exists()).isTrue();
|
||||
assertThat(tempFile.exists()).isFalse();
|
||||
assertThat(file.length()).isEqualTo(dataSize);
|
||||
}
|
||||
|
||||
@Test(expected = ProxyCacheException.class)
|
||||
public void testErrorAppendFileCacheAfterCompletion() throws Exception {
|
||||
Cache fileCache = new FileCache(newCacheFile());
|
||||
fileCache.append(generate(20), 10);
|
||||
fileCache.complete();
|
||||
fileCache.append(generate(20), 10);
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppendDiscCache() throws Exception {
|
||||
File file = newCacheFile();
|
||||
Cache fileCache = new FileCache(file);
|
||||
|
||||
int firstPortionLength = 10000;
|
||||
byte[] firstDataPortion = generate(firstPortionLength);
|
||||
fileCache.append(firstDataPortion, firstDataPortion.length);
|
||||
|
||||
int secondPortionLength = 30000;
|
||||
byte[] secondDataPortion = generate(secondPortionLength * 2);
|
||||
fileCache.append(secondDataPortion, secondPortionLength);
|
||||
|
||||
byte[] wroteSecondPortion = Arrays.copyOfRange(secondDataPortion, 0, secondPortionLength);
|
||||
byte[] readData = new byte[secondPortionLength];
|
||||
fileCache.read(readData, firstPortionLength, secondPortionLength);
|
||||
assertThat(readData).isEqualTo(wroteSecondPortion);
|
||||
|
||||
readData = new byte[fileCache.available()];
|
||||
fileCache.read(readData, 0, readData.length);
|
||||
byte[] fileContent = getFileContent(getTempFile(file));
|
||||
assertThat(readData).isEqualTo(fileContent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsFileCacheCompleted() throws Exception {
|
||||
File file = newCacheFile();
|
||||
File partialFile = new File(file.getParentFile(), file.getName() + ".download");
|
||||
IoUtils.saveToFile(loadAssetFile(ASSETS_DATA_NAME), partialFile);
|
||||
Cache fileCache = new FileCache(partialFile);
|
||||
|
||||
assertThat(file.exists()).isFalse();
|
||||
assertThat(partialFile.exists()).isTrue();
|
||||
assertThat(fileCache.isCompleted()).isFalse();
|
||||
|
||||
fileCache.complete();
|
||||
|
||||
assertThat(file.exists()).isTrue();
|
||||
assertThat(partialFile.exists()).isFalse();
|
||||
assertThat(fileCache.isCompleted()).isTrue();
|
||||
assertThat(partialFile.exists()).isFalse();
|
||||
assertThat(new FileCache(file).isCompleted()).isTrue();
|
||||
}
|
||||
|
||||
@Test(expected = ProxyCacheException.class)
|
||||
public void testErrorWritingCompletedCache() throws Exception {
|
||||
File file = newCacheFile();
|
||||
IoUtils.saveToFile(loadAssetFile(ASSETS_DATA_NAME), file);
|
||||
FileCache fileCache = new FileCache(file);
|
||||
fileCache.append(generate(100), 20);
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
@Test(expected = ProxyCacheException.class)
|
||||
public void testErrorWritingAfterCompletion() throws Exception {
|
||||
File file = newCacheFile();
|
||||
File partialFile = new File(file.getParentFile(), file.getName() + ".download");
|
||||
IoUtils.saveToFile(loadAssetFile(ASSETS_DATA_NAME), partialFile);
|
||||
FileCache fileCache = new FileCache(partialFile);
|
||||
fileCache.complete();
|
||||
fileCache.append(generate(100), 20);
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
@Ignore("How to emulate file error?")
|
||||
@Test(expected = ProxyCacheException.class)
|
||||
public void testFileErrorForDiscCache() throws Exception {
|
||||
File file = new File("/system/data.bin");
|
||||
FileCache fileCache = new FileCache(file);
|
||||
Files.delete(file);
|
||||
fileCache.available();
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package com.danikula.videocache;
|
||||
|
||||
import com.danikula.android.garden.io.IoUtils;
|
||||
import com.danikula.videocache.support.AngryHttpUrlSource;
|
||||
import com.danikula.videocache.support.Response;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.ASSETS_DATA_BIG_NAME;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.ASSETS_DATA_NAME;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.HTTP_DATA_BIG_SIZE;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.HTTP_DATA_BIG_URL;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.HTTP_DATA_URL;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.generate;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.getFileContent;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.loadAssetFile;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.newCacheFile;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.readProxyResponse;
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Alexey Danilov (danikula@gmail.com).
|
||||
*/
|
||||
@Config(manifest = "src/main/AndroidManifest.xml")
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class HttpProxyCacheTest {
|
||||
|
||||
@Test
|
||||
public void testHttpProxyCache() throws Exception {
|
||||
HttpUrlSource source = new HttpUrlSource(HTTP_DATA_URL);
|
||||
File file = newCacheFile();
|
||||
HttpProxyCache proxy = new HttpProxyCache(source, new FileCache(file));
|
||||
Response response = readProxyResponse(proxy);
|
||||
assertThat(response.code).isEqualTo(200);
|
||||
assertThat(response.data).isEqualTo(getFileContent(file));
|
||||
assertThat(response.data).isEqualTo(loadAssetFile(ASSETS_DATA_NAME));
|
||||
proxy.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxyContentWithPartialCache() throws Exception {
|
||||
HttpUrlSource source = new HttpUrlSource(HTTP_DATA_URL);
|
||||
int cacheSize = 1000;
|
||||
HttpProxyCache proxy = new HttpProxyCache(source, new ByteArrayCache(new byte[cacheSize]));
|
||||
|
||||
Response proxyResponse = readProxyResponse(proxy);
|
||||
byte[] expected = loadAssetFile(ASSETS_DATA_NAME);
|
||||
Arrays.fill(expected, 0, cacheSize, (byte) 0);
|
||||
assertThat(proxyResponse.data).isEqualTo(expected);
|
||||
proxy.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMimeFromResponse() throws Exception {
|
||||
HttpUrlSource source = new HttpUrlSource("https://dl.dropboxusercontent.com/u/15506779/persistent/proxycache/android");
|
||||
HttpProxyCache proxy = new HttpProxyCache(source, new ByteArrayCache(new byte[0]));
|
||||
proxy.read(new byte[1], 0, 1);
|
||||
assertThat(source.getMime()).isEqualTo("application/octet-stream");
|
||||
proxy.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxyFullResponse() throws Exception {
|
||||
File file = newCacheFile();
|
||||
HttpProxyCache proxy = new HttpProxyCache(new HttpUrlSource(HTTP_DATA_BIG_URL), new FileCache(file));
|
||||
Response response = readProxyResponse(proxy);
|
||||
|
||||
assertThat(response.code).isEqualTo(200);
|
||||
assertThat(response.contentLength).isEqualTo(HTTP_DATA_BIG_SIZE);
|
||||
assertThat(response.contentType).isEqualTo("image/jpeg");
|
||||
assertThat(response.headers.containsKey("Accept-Ranges")).isTrue();
|
||||
assertThat(response.headers.get("Accept-Ranges").get(0)).isEqualTo("bytes");
|
||||
assertThat(response.headers.containsKey("Content-Range")).isFalse();
|
||||
assertThat(response.data).isEqualTo(getFileContent(file));
|
||||
assertThat(response.data).isEqualTo(loadAssetFile(ASSETS_DATA_BIG_NAME));
|
||||
proxy.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxyPartialResponse() throws Exception {
|
||||
int offset = 42000;
|
||||
File file = newCacheFile();
|
||||
HttpProxyCache proxy = new HttpProxyCache(new HttpUrlSource(HTTP_DATA_BIG_URL), new FileCache(file));
|
||||
Response response = readProxyResponse(proxy, offset);
|
||||
|
||||
assertThat(response.code).isEqualTo(206);
|
||||
assertThat(response.contentLength).isEqualTo(HTTP_DATA_BIG_SIZE - offset);
|
||||
assertThat(response.contentType).isEqualTo("image/jpeg");
|
||||
assertThat(response.headers.containsKey("Accept-Ranges")).isTrue();
|
||||
assertThat(response.headers.get("Accept-Ranges").get(0)).isEqualTo("bytes");
|
||||
assertThat(response.headers.containsKey("Content-Range")).isTrue();
|
||||
String rangeHeader = String.format("bytes %d-%d/%d", offset, HTTP_DATA_BIG_SIZE, HTTP_DATA_BIG_SIZE);
|
||||
assertThat(response.headers.get("Content-Range").get(0)).isEqualTo(rangeHeader);
|
||||
byte[] expectedData = Arrays.copyOfRange(loadAssetFile(ASSETS_DATA_BIG_NAME), offset, HTTP_DATA_BIG_SIZE);
|
||||
assertThat(response.data).isEqualTo(expectedData);
|
||||
assertThat(getFileContent(file)).isEqualTo(loadAssetFile(ASSETS_DATA_BIG_NAME));
|
||||
proxy.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppendCache() throws Exception {
|
||||
byte[] cachedPortion = generate(1200);
|
||||
File file = newCacheFile();
|
||||
File partialFile = new File(file.getParentFile(), file.getName() + ".download");
|
||||
IoUtils.saveToFile(cachedPortion, partialFile);
|
||||
Cache cache = new FileCache(partialFile);
|
||||
assertThat(cache.isCompleted()).isFalse();
|
||||
|
||||
HttpProxyCache proxy = new HttpProxyCache(new HttpUrlSource(HTTP_DATA_BIG_URL), cache);
|
||||
readProxyResponse(proxy);
|
||||
proxy.shutdown();
|
||||
|
||||
assertThat(cache.isCompleted()).isTrue();
|
||||
|
||||
byte[] expectedData = loadAssetFile(ASSETS_DATA_BIG_NAME);
|
||||
System.arraycopy(cachedPortion, 0, expectedData, 0, cachedPortion.length);
|
||||
assertThat(file.length()).isEqualTo(HTTP_DATA_BIG_SIZE);
|
||||
assertThat(expectedData).isEqualTo(getFileContent(file));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoTouchSource() throws Exception {
|
||||
File file = newCacheFile();
|
||||
IoUtils.saveToFile(loadAssetFile(ASSETS_DATA_BIG_NAME), file);
|
||||
FileCache cache = new FileCache(file);
|
||||
HttpProxyCache proxy = new HttpProxyCache(new HttpUrlSource(HTTP_DATA_BIG_URL), cache);
|
||||
Response response = readProxyResponse(proxy);
|
||||
proxy.shutdown();
|
||||
assertThat(response.code).isEqualTo(200);
|
||||
|
||||
proxy = new HttpProxyCache(new AngryHttpUrlSource(HTTP_DATA_BIG_URL, "image/jpeg"), new FileCache(file));
|
||||
readProxyResponse(proxy);
|
||||
assertThat(response.code).isEqualTo(200);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.danikula.videocache;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.ASSETS_DATA_BIG_NAME;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.ASSETS_DATA_NAME;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.HTTP_DATA_BIG_SIZE;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.HTTP_DATA_BIG_URL;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.HTTP_DATA_URL;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.loadAssetFile;
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Alexey Danilov (danikula@gmail.com).
|
||||
*/
|
||||
@Config(manifest = "src/main/AndroidManifest.xml")
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class HttpUrlSourceTest {
|
||||
|
||||
@Test
|
||||
public void testHttpUrlSourceRange() throws Exception {
|
||||
int offset = 1000;
|
||||
int length = 10;
|
||||
Source source = new HttpUrlSource(HTTP_DATA_URL);
|
||||
source.open(offset);
|
||||
byte[] readData = new byte[length];
|
||||
source.read(readData);
|
||||
source.close();
|
||||
byte[] expectedData = Arrays.copyOfRange(loadAssetFile(ASSETS_DATA_NAME), offset, offset + length);
|
||||
assertThat(readData).isEqualTo(expectedData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHttpUrlSourceWithOffset() throws Exception {
|
||||
int offset = 30000;
|
||||
Source source = new HttpUrlSource(HTTP_DATA_BIG_URL);
|
||||
source.open(offset);
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
int read;
|
||||
byte[] buffer = new byte[3000];
|
||||
while ((read = (source.read(buffer))) != -1) {
|
||||
outputStream.write(buffer, 0, read);
|
||||
}
|
||||
source.close();
|
||||
byte[] expectedData = Arrays.copyOfRange(loadAssetFile(ASSETS_DATA_BIG_NAME), offset, HTTP_DATA_BIG_SIZE);
|
||||
assertThat(outputStream.toByteArray()).isEqualTo(expectedData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchContentLength() throws Exception {
|
||||
Source source = new HttpUrlSource(HTTP_DATA_URL);
|
||||
assertThat(source.available()).isEqualTo(loadAssetFile(ASSETS_DATA_NAME).length);
|
||||
}
|
||||
|
||||
@Ignore("Seems Robolectric bug: MimeTypeMap.getFileExtensionFromUrl always returns null")
|
||||
@Test
|
||||
public void testMimeByUrl() throws Exception {
|
||||
assertThat(new HttpUrlSource("http://mysite.by/video.mp4").getMime()).isEqualTo("video/mp4");
|
||||
assertThat(new HttpUrlSource(HTTP_DATA_URL).getMime()).isEqualTo("image/jpeg");
|
||||
}
|
||||
}
|
||||
180
test/src/test/java/com/danikula/videocache/ProxyCacheTest.java
Normal file
180
test/src/test/java/com/danikula/videocache/ProxyCacheTest.java
Normal file
@@ -0,0 +1,180 @@
|
||||
package com.danikula.videocache;
|
||||
|
||||
import com.danikula.videocache.support.PhlegmaticByteArraySource;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.ASSETS_DATA_NAME;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.HTTP_DATA_SIZE;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.HTTP_DATA_URL;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.generate;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.getFileContent;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.loadAssetFile;
|
||||
import static com.danikula.videocache.support.ProxyCacheTestUtils.newCacheFile;
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Alexey Danilov (danikula@gmail.com).
|
||||
*/
|
||||
@Config(manifest = "/src/main/AndroidManifest.xml")
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class ProxyCacheTest {
|
||||
|
||||
@Test
|
||||
public void testNoCache() throws Exception {
|
||||
byte[] sourceData = generate(345);
|
||||
ProxyCache proxyCache = new ProxyCache(new ByteArraySource(sourceData), new ByteArrayCache());
|
||||
|
||||
byte[] buffer = new byte[sourceData.length];
|
||||
int read = proxyCache.read(buffer, 0, sourceData.length);
|
||||
|
||||
assertThat(read).isEqualTo(sourceData.length);
|
||||
assertThat(buffer).isEqualTo(sourceData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllFromCacheNoSource() throws Exception {
|
||||
byte[] cacheData = generate(34564);
|
||||
ProxyCache proxyCache = new ProxyCache(new ByteArraySource(new byte[0]), new ByteArrayCache(cacheData));
|
||||
|
||||
byte[] buffer = new byte[cacheData.length + 100];
|
||||
int read = proxyCache.read(buffer, 0, cacheData.length);
|
||||
byte[] readData = Arrays.copyOfRange(buffer, 0, cacheData.length);
|
||||
|
||||
assertThat(read).isEqualTo(cacheData.length);
|
||||
assertThat(readData).isEqualTo(cacheData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMergeSourceAndCache() throws Exception {
|
||||
byte[] sourceData = generate(2345);
|
||||
byte[] cacheData = generate(1048);
|
||||
ProxyCache proxyCache = new ProxyCache(new ByteArraySource(sourceData), new ByteArrayCache(cacheData));
|
||||
|
||||
byte[] buffer = new byte[sourceData.length];
|
||||
int read = proxyCache.read(buffer, 0, sourceData.length);
|
||||
|
||||
byte[] expected = new byte[sourceData.length];
|
||||
System.arraycopy(cacheData, 0, expected, 0, cacheData.length);
|
||||
System.arraycopy(sourceData, cacheData.length, expected, cacheData.length, sourceData.length - cacheData.length);
|
||||
assertThat(read).isEqualTo(sourceData.length);
|
||||
assertThat(buffer).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReuseCache() throws Exception {
|
||||
int size = 20000;
|
||||
byte[] sourceData = generate(size);
|
||||
Cache cache = new ByteArrayCache();
|
||||
ProxyCache proxyCache = new ProxyCache(new ByteArraySource(sourceData), cache);
|
||||
byte[] fetchedData = new byte[size];
|
||||
proxyCache.read(fetchedData, 0, size);
|
||||
assertThat(fetchedData).isEqualTo(sourceData);
|
||||
|
||||
byte[] sourceCopy = Arrays.copyOf(sourceData, size);
|
||||
byte[] newSource = generate(size);
|
||||
proxyCache = new ProxyCache(new ByteArraySource(newSource), cache);
|
||||
Arrays.fill(fetchedData, (byte) 0);
|
||||
proxyCache.read(fetchedData, 0, size);
|
||||
assertThat(fetchedData).isEqualTo(sourceCopy);
|
||||
}
|
||||
|
||||
@Test(expected = ProxyCacheException.class)
|
||||
public void testNoMoreSource() throws Exception {
|
||||
int sourceSize = 942;
|
||||
int cacheSize = 6157;
|
||||
ByteArraySource source = new ByteArraySource(generate(sourceSize));
|
||||
ByteArrayCache cache = new ByteArrayCache(generate(cacheSize));
|
||||
ProxyCache proxyCache = new ProxyCache(source, cache);
|
||||
proxyCache.read(new byte[sourceSize + cacheSize], sourceSize + cacheSize + 1, 10);
|
||||
Assert.fail();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxyWithPhlegmaticSource() throws Exception {
|
||||
int dataSize = 100000;
|
||||
byte[] sourceData = generate(dataSize);
|
||||
Source source = new PhlegmaticByteArraySource(sourceData, 200);
|
||||
ProxyCache proxyCache = new ProxyCache(source, new FileCache(newCacheFile()));
|
||||
byte[] readData = new byte[dataSize];
|
||||
proxyCache.read(readData, 0, dataSize);
|
||||
assertThat(readData).isEqualTo(sourceData);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testReadEnd() throws Exception {
|
||||
int capacity = 5323;
|
||||
Source source = new PhlegmaticByteArraySource(generate(capacity), 200);
|
||||
Cache cache = new FileCache(newCacheFile());
|
||||
ProxyCache proxyCache = new ProxyCache(source, cache);
|
||||
proxyCache.read(new byte[1], capacity - 1, 1);
|
||||
TimeUnit.MILLISECONDS.sleep(200); // wait for completion
|
||||
assertThat(cache.isCompleted()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadRandomParts() throws Exception {
|
||||
int dataSize = 123456;
|
||||
byte[] sourceData = generate(dataSize);
|
||||
Source source = new PhlegmaticByteArraySource(sourceData, 300);
|
||||
File file = newCacheFile();
|
||||
Cache cache = new FileCache(file);
|
||||
ProxyCache proxyCache = new ProxyCache(source, cache);
|
||||
Random random = new Random(System.currentTimeMillis());
|
||||
for (int i = 0; i < 100; i++) {
|
||||
int offset = random.nextInt(dataSize);
|
||||
int bufferSize = random.nextInt(dataSize / 4);
|
||||
bufferSize = Math.min(bufferSize, dataSize - offset);
|
||||
byte[] buffer = new byte[bufferSize];
|
||||
proxyCache.read(buffer, offset, bufferSize);
|
||||
byte[] dataPortion = Arrays.copyOfRange(sourceData, offset, offset + bufferSize);
|
||||
assertThat(buffer).isEqualTo(dataPortion);
|
||||
}
|
||||
proxyCache.read(new byte[1], dataSize - 1, 1);
|
||||
TimeUnit.MILLISECONDS.sleep(200); // wait for completion
|
||||
assertThat(cache.isCompleted()).isTrue();
|
||||
assertThat(sourceData).isEqualTo(getFileContent(file));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadingHttpData() throws Exception {
|
||||
Source source = new HttpUrlSource(HTTP_DATA_URL);
|
||||
ProxyCache proxyCache = new ProxyCache(source, new FileCache(newCacheFile()));
|
||||
byte[] remoteData = new byte[HTTP_DATA_SIZE];
|
||||
proxyCache.read(remoteData, 0, HTTP_DATA_SIZE);
|
||||
proxyCache.shutdown();
|
||||
|
||||
assertThat(remoteData).isEqualTo(loadAssetFile(ASSETS_DATA_NAME));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadMoreThanAvailable() throws Exception {
|
||||
byte[] data = generate(20000);
|
||||
Cache fileCache = new FileCache(newCacheFile());
|
||||
ProxyCache proxyCache = new ProxyCache(new ByteArraySource(data), fileCache);
|
||||
|
||||
byte[] buffer = new byte[15000];
|
||||
proxyCache.read(buffer, 18000, buffer.length);
|
||||
byte[] expectedData = new byte[15000];
|
||||
System.arraycopy(data, 18000, expectedData, 0, 2000);
|
||||
assertThat(buffer).isEqualTo(expectedData);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompletion() throws Exception {
|
||||
Cache cache = new FileCache(newCacheFile());
|
||||
ProxyCache proxyCache = new ProxyCache(new ByteArraySource(generate(20000)), cache);
|
||||
proxyCache.read(new byte[5], 19999, 5);
|
||||
assertThat(cache.isCompleted()).isTrue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.danikula.videocache.support;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.danikula.videocache.HttpUrlSource;
|
||||
import com.danikula.videocache.ProxyCacheException;
|
||||
|
||||
/**
|
||||
* {@link HttpUrlSource} that throws exception in all methods.
|
||||
*
|
||||
* @author Alexey Danilov (danikula@gmail.com).
|
||||
*/
|
||||
public class AngryHttpUrlSource extends HttpUrlSource {
|
||||
|
||||
public AngryHttpUrlSource(String url, String mime) {
|
||||
super(url, mime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws ProxyCacheException {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(int offset) throws ProxyCacheException {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws ProxyCacheException {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer) throws ProxyCacheException {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public String getMime() throws ProxyCacheException {
|
||||
String mime = super.getMime();
|
||||
if (!TextUtils.isEmpty(mime)) {
|
||||
return mime;
|
||||
}
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.danikula.videocache.support;
|
||||
|
||||
import com.danikula.videocache.ByteArraySource;
|
||||
import com.danikula.videocache.ProxyCacheException;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author Alexey Danilov (danikula@gmail.com).
|
||||
*/
|
||||
public class PhlegmaticByteArraySource extends ByteArraySource {
|
||||
|
||||
private final Random delayGenerator;
|
||||
private final int maxDelayMs;
|
||||
|
||||
public PhlegmaticByteArraySource(byte[] data, int maxDelayMs) {
|
||||
super(data);
|
||||
this.maxDelayMs = maxDelayMs;
|
||||
this.delayGenerator = new Random(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer) throws ProxyCacheException {
|
||||
try {
|
||||
Thread.sleep(delayGenerator.nextInt(maxDelayMs));
|
||||
} catch (InterruptedException e) {
|
||||
throw new ProxyCacheException("Error sleeping", e);
|
||||
}
|
||||
return super.read(buffer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.danikula.videocache.support;
|
||||
|
||||
import com.danikula.android.garden.io.IoUtils;
|
||||
import com.danikula.videocache.HttpProxyCache;
|
||||
import com.google.common.io.Files;
|
||||
|
||||
import org.robolectric.Robolectric;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Alexey Danilov (danikula@gmail.com).
|
||||
*/
|
||||
public class ProxyCacheTestUtils {
|
||||
|
||||
public static final String HTTP_DATA_URL = "https://dl.dropboxusercontent.com/u/15506779/persistent/proxycache/android.jpg";
|
||||
public static final String HTTP_DATA_BIG_URL = "https://dl.dropboxusercontent.com/u/15506779/persistent/proxycache/phones.jpg";
|
||||
public static final String ASSETS_DATA_NAME = "android.jpg";
|
||||
public static final String ASSETS_DATA_BIG_NAME = "phones.jpg";
|
||||
public static final int HTTP_DATA_SIZE = 4768;
|
||||
public static final int HTTP_DATA_BIG_SIZE = 94363;
|
||||
|
||||
public static byte[] getFileContent(File file) throws IOException {
|
||||
return Files.asByteSource(file).read();
|
||||
}
|
||||
|
||||
public static Response readProxyResponse(HttpProxyCache proxy) throws IOException {
|
||||
return readProxyResponse(proxy, -1);
|
||||
}
|
||||
|
||||
public static Response readProxyResponse(HttpProxyCache proxy, int offset) throws IOException {
|
||||
URL url = new URL(proxy.getUrl());
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
try {
|
||||
if (offset >= 0) {
|
||||
connection.setRequestProperty("Range", "bytes=" + offset + "-");
|
||||
}
|
||||
return new Response(connection);
|
||||
} finally {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] loadAssetFile(String name) throws IOException {
|
||||
InputStream in = Robolectric.application.getResources().getAssets().open(name);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
IoUtils.copy(in, out);
|
||||
IoUtils.closeSilently(in);
|
||||
IoUtils.closeSilently(out);
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
public static File getTempFile(File file) {
|
||||
return new File(file.getParentFile(), file.getName() + ".download");
|
||||
}
|
||||
|
||||
public static File newCacheFile() {
|
||||
return new File(Robolectric.application.getCacheDir(), UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
public static byte[] generate(int capacity) {
|
||||
Random random = new Random(System.currentTimeMillis());
|
||||
byte[] result = new byte[capacity];
|
||||
random.nextBytes(result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.danikula.videocache.support;
|
||||
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Response {
|
||||
|
||||
public final int code;
|
||||
public final byte[] data;
|
||||
public final int contentLength;
|
||||
public final String contentType;
|
||||
public final Map<String, List<String>> headers;
|
||||
|
||||
public Response(HttpURLConnection connection) throws IOException {
|
||||
this.code = connection.getResponseCode();
|
||||
this.contentLength = connection.getContentLength();
|
||||
this.contentType = connection.getContentType();
|
||||
this.headers = connection.getHeaderFields();
|
||||
this.data = ByteStreams.toByteArray(connection.getInputStream());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user