package com.danikula.videocache.file; import com.danikula.android.garden.io.Files; import com.danikula.videocache.BaseTest; import com.danikula.videocache.Cache; import com.danikula.videocache.ProxyCacheException; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; import java.io.File; import java.io.IOException; 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 com.google.common.io.Files.write; import static org.fest.assertions.api.Assertions.assertThat; /** * @author Alexey Danilov (danikula@gmail.com). */ public class FileCacheTest extends BaseTest { @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[(int)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"); write(loadAssetFile(ASSETS_DATA_NAME), partialFile); write(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(); write(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"); write(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(); } @Test public void testTrimAfterCompletionForTotalCountLru() throws Exception { File cacheDir = newCacheFile(); DiskUsage diskUsage = new TotalCountLruDiskUsage(2); byte[] data = loadAssetFile(ASSETS_DATA_NAME); saveAndCompleteCache(diskUsage, data, new File(cacheDir, "0.dat"), new File(cacheDir, "1.dat"), new File(cacheDir, "2.dat") ); waitForAsyncTrimming(); assertThat(new File(cacheDir, "0.dat")).doesNotExist(); } @Test public void testTrimAfterCompletionForTotalSizeLru() throws Exception { File cacheDir = newCacheFile(); byte[] data = loadAssetFile(ASSETS_DATA_NAME); DiskUsage diskUsage = new TotalSizeLruDiskUsage(data.length * 3 - 1); saveAndCompleteCache(diskUsage, data, new File(cacheDir, "0.dat"), new File(cacheDir, "1.dat"), new File(cacheDir, "2.dat") ); waitForAsyncTrimming(); File deletedFile = new File(cacheDir, "0.dat"); assertThat(deletedFile).doesNotExist(); } private void saveAndCompleteCache(DiskUsage diskUsage, byte[] data, File... files) throws ProxyCacheException, IOException { for (File file : files) { FileCache fileCache = new FileCache(file, diskUsage); fileCache.append(data, data.length); fileCache.complete(); assertThat(file).exists(); } } private void waitForAsyncTrimming() throws InterruptedException { Thread.sleep(100); } }