add CleanCacheWorker Robolectric tests

This commit is contained in:
Hans-Christoph Steiner 2021-03-03 12:05:19 +01:00
parent ce7d241196
commit d3be7d692d
4 changed files with 141 additions and 12 deletions

View File

@ -22,6 +22,7 @@ import static org.junit.Assert.assertTrue;
/** /**
* This test cannot run on Robolectric unfortunately since it does not support * This test cannot run on Robolectric unfortunately since it does not support
* getting the timestamps from the files completely.
* <p> * <p>
* This is marked with {@link LargeTest} because it always fails on the emulator * This is marked with {@link LargeTest} because it always fails on the emulator
* tests on GitLab CI. That excludes it from the test run there. * tests on GitLab CI. That excludes it from the test run there.
@ -86,4 +87,24 @@ public class CleanCacheWorkerTest {
CleanCacheWorker.clearOldFiles(nonexistent, 1); CleanCacheWorker.clearOldFiles(nonexistent, 1);
CleanCacheWorker.clearOldFiles(null, 1); CleanCacheWorker.clearOldFiles(null, 1);
} }
/*
// TODO enable this once getImageCacheDir() can be mocked or provide a writable dir in the test
@Test
public void testDeleteOldIcons() throws IOException {
Context context = InstrumentationRegistry.getInstrumentation().getContext();
File imageCacheDir = Utils.getImageCacheDir(context);
imageCacheDir.mkdirs();
assertTrue(imageCacheDir.isDirectory());
File oldIcon = new File(imageCacheDir, "old.png");
assertTrue(oldIcon.createNewFile());
Assume.assumeTrue("test environment must be able to set LastModified time",
oldIcon.setLastModified(System.currentTimeMillis() - (DateUtils.DAY_IN_MILLIS * 370)));
File currentIcon = new File(imageCacheDir, "current.png");
assertTrue(currentIcon.createNewFile());
CleanCacheWorker.deleteOldIcons(context);
assertTrue(currentIcon.exists());
assertFalse(oldIcon.exists());
}
*/
} }

View File

@ -90,10 +90,11 @@ public class CleanCacheWorker extends Worker {
public Result doWork() { public Result doWork() {
Process.setThreadPriority(Process.THREAD_PRIORITY_LOWEST); Process.setThreadPriority(Process.THREAD_PRIORITY_LOWEST);
try { try {
deleteExpiredApksFromCache(); final Context context = getApplicationContext();
deleteStrayIndexFiles(); deleteExpiredApksFromCache(context);
deleteOldInstallerFiles(); deleteStrayIndexFiles(context);
deleteOldIcons(); deleteOldInstallerFiles(context);
deleteOldIcons(context);
return Result.success(); return Result.success();
} catch (Exception e) { } catch (Exception e) {
return Result.failure(); return Result.failure();
@ -105,8 +106,8 @@ public class CleanCacheWorker extends Worker {
* specified by the user in the "Keep Cache Time" preference. This removes * specified by the user in the "Keep Cache Time" preference. This removes
* any APK in the cache that is older than that preference specifies. * any APK in the cache that is older than that preference specifies.
*/ */
private void deleteExpiredApksFromCache() { static void deleteExpiredApksFromCache(@NonNull Context context) {
File cacheDir = ApkCache.getApkCacheDir(getApplicationContext()); File cacheDir = ApkCache.getApkCacheDir(context);
clearOldFiles(cacheDir, Preferences.get().getKeepCacheTime()); clearOldFiles(cacheDir, Preferences.get().getKeepCacheTime());
} }
@ -117,8 +118,8 @@ public class CleanCacheWorker extends Worker {
* also avoids deleting the nearby swap repo files since that might be * also avoids deleting the nearby swap repo files since that might be
* actively in use. * actively in use.
*/ */
private void deleteOldInstallerFiles() { static void deleteOldInstallerFiles(@NonNull Context context) {
File filesDir = getApplicationContext().getFilesDir(); File filesDir = context.getFilesDir();
if (filesDir == null) { if (filesDir == null) {
Utils.debugLog(TAG, "The files directory doesn't exist."); Utils.debugLog(TAG, "The files directory doesn't exist.");
return; return;
@ -150,8 +151,8 @@ public class CleanCacheWorker extends Worker {
* This also deletes temp files that are created by * This also deletes temp files that are created by
* {@link org.fdroid.fdroid.net.DownloaderFactory#create(Context, String)}, e.g. "dl-*" * {@link org.fdroid.fdroid.net.DownloaderFactory#create(Context, String)}, e.g. "dl-*"
*/ */
private void deleteStrayIndexFiles() { static void deleteStrayIndexFiles(@NonNull Context context) {
File cacheDir = getApplicationContext().getCacheDir(); File cacheDir = context.getCacheDir();
if (cacheDir == null) { if (cacheDir == null) {
Utils.debugLog(TAG, "The cache directory doesn't exist."); Utils.debugLog(TAG, "The cache directory doesn't exist.");
return; return;
@ -176,8 +177,8 @@ public class CleanCacheWorker extends Worker {
/** /**
* Delete cached icons that have not been accessed in over a year. * Delete cached icons that have not been accessed in over a year.
*/ */
private void deleteOldIcons() { static void deleteOldIcons(@NonNull Context context) {
clearOldFiles(Utils.getImageCacheDir(getApplicationContext()), TimeUnit.DAYS.toMillis(365)); clearOldFiles(Utils.getImageCacheDir(context), TimeUnit.DAYS.toMillis(365));
} }
/** /**

View File

@ -8,6 +8,7 @@ import android.content.ContextWrapper;
import android.content.pm.ProviderInfo; import android.content.pm.ProviderInfo;
import android.net.Uri; import android.net.Uri;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import org.apache.commons.io.IOUtils;
import org.fdroid.fdroid.data.Apk; import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.ApkProvider; import org.fdroid.fdroid.data.ApkProvider;
import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.App;
@ -190,4 +191,17 @@ public class TestUtils {
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue); field.set(null, newValue);
} }
public static void ls(File dir) {
Process p = null;
try {
p = Runtime.getRuntime().exec("ls -l " + dir.getAbsolutePath());
p.waitFor();
for (String line : IOUtils.readLines(p.getInputStream())) {
System.out.println(line);
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
} }

View File

@ -0,0 +1,93 @@
package org.fdroid.fdroid.work;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import org.fdroid.fdroid.BuildConfig;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.nearby.LocalRepoManager;
import org.fdroid.fdroid.shadows.ShadowLog;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Test non-time-based cache deletion methods. Robolectric is lacking full
* support for getting time from files, so methods that rely on time must be
* tested in {@code CleanCacheWorkerTest} in {@code androidTest}.
*/
@RunWith(RobolectricTestRunner.class)
public class CleanCacheWorkerTest {
public static final String TAG = "CleanCacheWorkerTest";
private static final Context CONTEXT = ApplicationProvider.getApplicationContext();
private static final File FILES_DIR = CONTEXT.getFilesDir();
@Before
public void setUp() {
ShadowLog.stream = System.out;
Preferences.setupForTests(CONTEXT);
}
@Test
public void testDeleteOldInstallerFiles() throws IOException {
Assume.assumeTrue(BuildConfig.FLAVOR.startsWith("full"));
ArrayList<File> webRootAssetFiles = new ArrayList<>();
File indexHtml = new File(FILES_DIR, "index.html");
assertTrue(indexHtml.createNewFile());
webRootAssetFiles.add(indexHtml);
for (String name : LocalRepoManager.WEB_ROOT_ASSET_FILES) {
File f = new File(FILES_DIR, name);
assertTrue(f.createNewFile());
webRootAssetFiles.add(f);
}
File apk = new File(FILES_DIR, "fake.apk");
assertTrue(apk.createNewFile());
File giantblob = new File(FILES_DIR, "giantblob");
assertTrue(giantblob.createNewFile());
File obf = new File(FILES_DIR, "fake.obf");
assertTrue(obf.createNewFile());
File zip = new File(FILES_DIR, "fake.zip");
assertTrue(zip.createNewFile());
CleanCacheWorker.deleteOldInstallerFiles(CONTEXT);
assertFalse(apk.exists());
assertFalse(giantblob.exists());
assertFalse(obf.exists());
assertFalse(zip.exists());
for (File f : webRootAssetFiles) {
assertTrue(f.exists());
}
}
/**
* Pure smoke check, Robolectric does not support file times fully.
*/
@Test
public void testDeleteExpiredApksFromCache() {
CleanCacheWorker.deleteExpiredApksFromCache(CONTEXT);
}
/**
* Pure smoke check, Robolectric does not support file times fully.
*/
@Test
public void testDeleteStrayIndexFiles() {
CleanCacheWorker.deleteStrayIndexFiles(CONTEXT);
}
/**
* Pure smoke check, Robolectric does not support file times fully.
*/
@Test
public void testDeleteOldIcons() {
CleanCacheWorker.deleteOldIcons(CONTEXT);
}
}