From a76f5e600e7aadebe3e30ccfcae0e005612ac507 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Sat, 21 Sep 2024 22:51:21 -0400 Subject: [PATCH] Fix flakiness of the backup tests. It's possible that pending writes to the key value store (from using .apply()) may not be finished by the time we take the DB snapshot, resulting in us seeing stale data in the snapshot. Now we block on writes finishing. --- .../securesms/backup/v2/BackupRepository.kt | 2 ++ .../backup/v2/processor/RecipientBackupProcessor.kt | 2 ++ .../securesms/jobmanager/JobManager.java | 12 ++++++++++++ .../securesms/keyvalue/ReleaseChannelValues.kt | 4 ---- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt index b3e5ca9018..c8e5263678 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt @@ -165,6 +165,8 @@ object BackupRepository { private fun createSignalStoreSnapshot(baseName: String): SignalStore { val context = AppDependencies.application + SignalStore.blockUntilAllWritesFinished() + // Need to do a WAL checkpoint to ensure that the database file we're copying has all pending writes if (!KeyValueDatabase.getInstance(context).writableDatabase.fullWalCheckpoint()) { Log.w(TAG, "Failed to checkpoint WAL for KeyValueDatabase! Not guaranteed to be using the most recent data.") diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/processor/RecipientBackupProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/processor/RecipientBackupProcessor.kt index 0f225fae10..e599e5b27d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/processor/RecipientBackupProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/processor/RecipientBackupProcessor.kt @@ -41,6 +41,8 @@ object RecipientBackupProcessor { ) ) ) + } else { + Log.w(TAG, "Missing release channel id on export!") } db.recipientTable.getContactsForBackup(selfId).use { reader -> diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java index 035842ae7c..5b9b18f9b2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java @@ -59,6 +59,7 @@ public class JobManager implements ConstraintObserver.Notifier { private final Set emptyQueueListeners = new CopyOnWriteArraySet<>(); private volatile boolean initialized = false; + private volatile boolean shutdown = false; public JobManager(@NonNull Application application, @NonNull Configuration configuration) { this.application = application; @@ -123,6 +124,13 @@ public class JobManager implements ConstraintObserver.Notifier { }); } + /** + * Shuts down the job manager entirely. Should only be used for testing! + */ + public void shutdown() { + shutdown = true; + } + /** * Convenience method for {@link #addListener(JobTracker.JobFilter, JobTracker.JobListener)} that * takes in an ID to filter on. @@ -456,6 +464,10 @@ public class JobManager implements ConstraintObserver.Notifier { * it through here. */ private void runOnExecutor(@NonNull Runnable runnable) { + if (shutdown) { + return; + } + executor.execute(() -> { waitUntilInitialized(); runnable.run(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ReleaseChannelValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ReleaseChannelValues.kt index c428308e68..e2e9efc4aa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ReleaseChannelValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/ReleaseChannelValues.kt @@ -32,10 +32,6 @@ class ReleaseChannelValues(store: KeyValueStore) : SignalStoreValues(store) { putString(KEY_RELEASE_CHANNEL_RECIPIENT_ID, id.serialize()) } - fun clearReleaseChannelRecipientId() { - putString(KEY_RELEASE_CHANNEL_RECIPIENT_ID, "") - } - var nextScheduledCheck by longValue(KEY_NEXT_SCHEDULED_CHECK, 0) var previousManifestMd5 by blobValue(KEY_PREVIOUS_MANIFEST_MD5, ByteArray(0)) var highestVersionNoteReceived by integerValue(KEY_HIGHEST_VERSION_NOTE_RECEIVED, 0)