diff --git a/app/src/androidTest/java/org/fdroid/fdroid/work/CleanCacheWorkerTest.java b/app/src/androidTest/java/org/fdroid/fdroid/work/CleanCacheWorkerTest.java index b57cd1034..e084fe6db 100644 --- a/app/src/androidTest/java/org/fdroid/fdroid/work/CleanCacheWorkerTest.java +++ b/app/src/androidTest/java/org/fdroid/fdroid/work/CleanCacheWorkerTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertTrue; /** * This test cannot run on Robolectric unfortunately since it does not support + * getting the timestamps from the files completely. *
* 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.
@@ -86,4 +87,24 @@ public class CleanCacheWorkerTest {
CleanCacheWorker.clearOldFiles(nonexistent, 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());
+ }
+ */
}
diff --git a/app/src/main/java/org/fdroid/fdroid/work/CleanCacheWorker.java b/app/src/main/java/org/fdroid/fdroid/work/CleanCacheWorker.java
index 6c84bbcf1..584b01afa 100644
--- a/app/src/main/java/org/fdroid/fdroid/work/CleanCacheWorker.java
+++ b/app/src/main/java/org/fdroid/fdroid/work/CleanCacheWorker.java
@@ -90,10 +90,11 @@ public class CleanCacheWorker extends Worker {
public Result doWork() {
Process.setThreadPriority(Process.THREAD_PRIORITY_LOWEST);
try {
- deleteExpiredApksFromCache();
- deleteStrayIndexFiles();
- deleteOldInstallerFiles();
- deleteOldIcons();
+ final Context context = getApplicationContext();
+ deleteExpiredApksFromCache(context);
+ deleteStrayIndexFiles(context);
+ deleteOldInstallerFiles(context);
+ deleteOldIcons(context);
return Result.success();
} catch (Exception e) {
return Result.failure();
@@ -105,8 +106,8 @@ public class CleanCacheWorker extends Worker {
* specified by the user in the "Keep Cache Time" preference. This removes
* any APK in the cache that is older than that preference specifies.
*/
- private void deleteExpiredApksFromCache() {
- File cacheDir = ApkCache.getApkCacheDir(getApplicationContext());
+ static void deleteExpiredApksFromCache(@NonNull Context context) {
+ File cacheDir = ApkCache.getApkCacheDir(context);
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
* actively in use.
*/
- private void deleteOldInstallerFiles() {
- File filesDir = getApplicationContext().getFilesDir();
+ static void deleteOldInstallerFiles(@NonNull Context context) {
+ File filesDir = context.getFilesDir();
if (filesDir == null) {
Utils.debugLog(TAG, "The files directory doesn't exist.");
return;
@@ -150,8 +151,8 @@ public class CleanCacheWorker extends Worker {
* This also deletes temp files that are created by
* {@link org.fdroid.fdroid.net.DownloaderFactory#create(Context, String)}, e.g. "dl-*"
*/
- private void deleteStrayIndexFiles() {
- File cacheDir = getApplicationContext().getCacheDir();
+ static void deleteStrayIndexFiles(@NonNull Context context) {
+ File cacheDir = context.getCacheDir();
if (cacheDir == null) {
Utils.debugLog(TAG, "The cache directory doesn't exist.");
return;
@@ -176,8 +177,8 @@ public class CleanCacheWorker extends Worker {
/**
* Delete cached icons that have not been accessed in over a year.
*/
- private void deleteOldIcons() {
- clearOldFiles(Utils.getImageCacheDir(getApplicationContext()), TimeUnit.DAYS.toMillis(365));
+ static void deleteOldIcons(@NonNull Context context) {
+ clearOldFiles(Utils.getImageCacheDir(context), TimeUnit.DAYS.toMillis(365));
}
/**
diff --git a/app/src/test/java/org/fdroid/fdroid/TestUtils.java b/app/src/test/java/org/fdroid/fdroid/TestUtils.java
index a24c8d7b0..478c8ca1f 100644
--- a/app/src/test/java/org/fdroid/fdroid/TestUtils.java
+++ b/app/src/test/java/org/fdroid/fdroid/TestUtils.java
@@ -8,6 +8,7 @@ import android.content.ContextWrapper;
import android.content.pm.ProviderInfo;
import android.net.Uri;
import androidx.test.core.app.ApplicationProvider;
+import org.apache.commons.io.IOUtils;
import org.fdroid.fdroid.data.Apk;
import org.fdroid.fdroid.data.ApkProvider;
import org.fdroid.fdroid.data.App;
@@ -190,4 +191,17 @@ public class TestUtils {
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
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();
+ }
+ }
}
diff --git a/app/src/test/java/org/fdroid/fdroid/work/CleanCacheWorkerTest.java b/app/src/test/java/org/fdroid/fdroid/work/CleanCacheWorkerTest.java
new file mode 100644
index 000000000..97783d7f7
--- /dev/null
+++ b/app/src/test/java/org/fdroid/fdroid/work/CleanCacheWorkerTest.java
@@ -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