diff --git a/library/src/androidTest/java/com/google/android/exoplayer2/upstream/cache/CachedContentIndexTest.java b/library/src/androidTest/java/com/google/android/exoplayer2/upstream/cache/CachedContentIndexTest.java index 71e5a5b6d0..4fbcc92e3d 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer2/upstream/cache/CachedContentIndexTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer2/upstream/cache/CachedContentIndexTest.java @@ -163,7 +163,7 @@ public class CachedContentIndexTest extends InstrumentationTestCase { public void testEncryption() throws Exception { byte[] key = "Bar12345Bar12345".getBytes(C.UTF8_NAME); // 128 bit key - byte[] key2 = "bar12345Bar12345".getBytes(C.UTF8_NAME); // 128 bit key + byte[] key2 = "Foo12345Foo12345".getBytes(C.UTF8_NAME); // 128 bit key assertStoredAndLoadedEqual(new CachedContentIndex(cacheDir, key), new CachedContentIndex(cacheDir, key)); diff --git a/library/src/androidTest/java/com/google/android/exoplayer2/upstream/cache/SimpleCacheTest.java b/library/src/androidTest/java/com/google/android/exoplayer2/upstream/cache/SimpleCacheTest.java index 5f539c6213..001c6adc87 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer2/upstream/cache/SimpleCacheTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer2/upstream/cache/SimpleCacheTest.java @@ -16,12 +16,16 @@ package com.google.android.exoplayer2.upstream.cache; import android.test.InstrumentationTestCase; +import android.test.MoreAsserts; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.testutil.TestUtil; +import com.google.android.exoplayer2.util.Util; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.NavigableSet; +import java.util.Random; import java.util.Set; /** @@ -46,9 +50,9 @@ public class SimpleCacheTest extends InstrumentationTestCase { public void testCommittingOneFile() throws Exception { SimpleCache simpleCache = getSimpleCache(); - CacheSpan cacheSpan = simpleCache.startReadWrite(KEY_1, 0); - assertFalse(cacheSpan.isCached); - assertTrue(cacheSpan.isOpenEnded()); + CacheSpan cacheSpan1 = simpleCache.startReadWrite(KEY_1, 0); + assertFalse(cacheSpan1.isCached); + assertTrue(cacheSpan1.isOpenEnded()); assertNull(simpleCache.startReadWriteNonBlocking(KEY_1, 0)); @@ -58,20 +62,33 @@ public class SimpleCacheTest extends InstrumentationTestCase { assertEquals(0, simpleCache.getCacheSpace()); assertEquals(0, cacheDir.listFiles().length); - addCache(simpleCache, 0, 15); + addCache(simpleCache, KEY_1, 0, 15); Set cachedKeys = simpleCache.getKeys(); assertEquals(1, cachedKeys.size()); assertTrue(cachedKeys.contains(KEY_1)); cachedSpans = simpleCache.getCachedSpans(KEY_1); assertEquals(1, cachedSpans.size()); - assertTrue(cachedSpans.contains(cacheSpan)); + assertTrue(cachedSpans.contains(cacheSpan1)); assertEquals(15, simpleCache.getCacheSpace()); - cacheSpan = simpleCache.startReadWrite(KEY_1, 0); - assertTrue(cacheSpan.isCached); - assertFalse(cacheSpan.isOpenEnded()); - assertEquals(15, cacheSpan.length); + simpleCache.releaseHoleSpan(cacheSpan1); + + CacheSpan cacheSpan2 = simpleCache.startReadWrite(KEY_1, 0); + assertTrue(cacheSpan2.isCached); + assertFalse(cacheSpan2.isOpenEnded()); + assertEquals(15, cacheSpan2.length); + assertCachedDataReadCorrect(cacheSpan2); + } + + public void testReadCacheWithoutReleasingWriteCacheSpan() throws Exception { + SimpleCache simpleCache = getSimpleCache(); + + CacheSpan cacheSpan1 = simpleCache.startReadWrite(KEY_1, 0); + addCache(simpleCache, KEY_1, 0, 15); + CacheSpan cacheSpan2 = simpleCache.startReadWrite(KEY_1, 0); + assertCachedDataReadCorrect(cacheSpan2); + simpleCache.releaseHoleSpan(cacheSpan1); } public void testSetGetLength() throws Exception { @@ -83,12 +100,12 @@ public class SimpleCacheTest extends InstrumentationTestCase { simpleCache.startReadWrite(KEY_1, 0); - addCache(simpleCache, 0, 15); + addCache(simpleCache, KEY_1, 0, 15); simpleCache.setContentLength(KEY_1, 150); assertEquals(150, simpleCache.getContentLength(KEY_1)); - addCache(simpleCache, 140, 10); + addCache(simpleCache, KEY_1, 140, 10); // Check if values are kept after cache is reloaded. SimpleCache simpleCache2 = getSimpleCache(); @@ -107,16 +124,109 @@ public class SimpleCacheTest extends InstrumentationTestCase { assertEquals(150, simpleCache2.getContentLength(KEY_1)); } + public void testReloadCache() throws Exception { + SimpleCache simpleCache = getSimpleCache(); + + // write data + CacheSpan cacheSpan1 = simpleCache.startReadWrite(KEY_1, 0); + addCache(simpleCache, KEY_1, 0, 15); + simpleCache.releaseHoleSpan(cacheSpan1); + + // Reload cache + simpleCache = getSimpleCache(); + + // read data back + CacheSpan cacheSpan2 = simpleCache.startReadWrite(KEY_1, 0); + assertCachedDataReadCorrect(cacheSpan2); + } + + public void testEncryptedIndex() throws Exception { + byte[] key = "Bar12345Bar12345".getBytes(C.UTF8_NAME); // 128 bit key + SimpleCache simpleCache = getEncryptedSimpleCache(key); + + // write data + CacheSpan cacheSpan1 = simpleCache.startReadWrite(KEY_1, 0); + addCache(simpleCache, KEY_1, 0, 15); + simpleCache.releaseHoleSpan(cacheSpan1); + + // Reload cache + simpleCache = getEncryptedSimpleCache(key); + + // read data back + CacheSpan cacheSpan2 = simpleCache.startReadWrite(KEY_1, 0); + assertCachedDataReadCorrect(cacheSpan2); + } + + public void testEncryptedIndexWrongKey() throws Exception { + byte[] key = "Bar12345Bar12345".getBytes(C.UTF8_NAME); // 128 bit key + SimpleCache simpleCache = getEncryptedSimpleCache(key); + + // write data + CacheSpan cacheSpan1 = simpleCache.startReadWrite(KEY_1, 0); + addCache(simpleCache, KEY_1, 0, 15); + simpleCache.releaseHoleSpan(cacheSpan1); + + // Reload cache + byte[] key2 = "Foo12345Foo12345".getBytes(C.UTF8_NAME); // 128 bit key + simpleCache = getEncryptedSimpleCache(key2); + + // Cache should be cleared + assertEquals(0, simpleCache.getKeys().size()); + assertEquals(0, cacheDir.listFiles().length); + } + + public void testEncryptedIndexLostKey() throws Exception { + byte[] key = "Bar12345Bar12345".getBytes(C.UTF8_NAME); // 128 bit key + SimpleCache simpleCache = getEncryptedSimpleCache(key); + + // write data + CacheSpan cacheSpan1 = simpleCache.startReadWrite(KEY_1, 0); + addCache(simpleCache, KEY_1, 0, 15); + simpleCache.releaseHoleSpan(cacheSpan1); + + // Reload cache + simpleCache = getSimpleCache(); + + // Cache should be cleared + assertEquals(0, simpleCache.getKeys().size()); + assertEquals(0, cacheDir.listFiles().length); + } + private SimpleCache getSimpleCache() { return new SimpleCache(cacheDir, new NoOpCacheEvictor()); } - private void addCache(SimpleCache simpleCache, int position, int length) throws IOException { - File file = simpleCache.startFile(KEY_1, position, length); + private SimpleCache getEncryptedSimpleCache(byte[] secretKey) { + return new SimpleCache(cacheDir, new NoOpCacheEvictor(), secretKey); + } + + private static void addCache(SimpleCache simpleCache, String key, int position, int length) + throws IOException { + File file = simpleCache.startFile(key, position, length); FileOutputStream fos = new FileOutputStream(file); - fos.write(new byte[length]); - fos.close(); + try { + fos.write(generateData(key, position, length)); + } finally { + fos.close(); + } simpleCache.commitFile(file); } + private static void assertCachedDataReadCorrect(CacheSpan cacheSpan) throws IOException { + assertTrue(cacheSpan.isCached); + byte[] expected = generateData(cacheSpan.key, (int) cacheSpan.position, (int) cacheSpan.length); + FileInputStream inputStream = new FileInputStream(cacheSpan.file); + try { + MoreAsserts.assertEquals(expected, Util.toByteArray(inputStream)); + } finally { + inputStream.close(); + } + } + + private static byte[] generateData(String key, int position, int length) { + byte[] bytes = new byte[length]; + new Random((long) (key.hashCode() ^ position)).nextBytes(bytes); + return bytes; + } + }