mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-23 12:38:33 +00:00
Switch the snapshot table to use incrementing versions.
This commit is contained in:
@@ -16,94 +16,97 @@ import org.thoughtcrime.securesms.testing.SignalActivityRule
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class BackupMediaSnapshotTableTest {
|
||||
|
||||
companion object {
|
||||
private const val SEQUENCE_COUNT = 100
|
||||
private const val SEQUENCE_COUNT_WITH_THUMBNAILS = 200
|
||||
}
|
||||
|
||||
@get:Rule
|
||||
val harness = SignalActivityRule()
|
||||
|
||||
@Test
|
||||
fun givenAnEmptyTable_whenIWriteToTable_thenIExpectEmptyTable() {
|
||||
val pendingSyncTime = 1L
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(), pendingSyncTime)
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(count = 100))
|
||||
|
||||
val count = getSyncedItemCount(pendingSyncTime)
|
||||
val count = getCountForLatestSnapshot(includeThumbnails = true)
|
||||
|
||||
assertThat(count).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenAnEmptyTable_whenIWriteToTableAndCommit_thenIExpectFilledTable() {
|
||||
val pendingSyncTime = 1L
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(), pendingSyncTime)
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(count = 100))
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val count = getSyncedItemCount(pendingSyncTime)
|
||||
val count = getCountForLatestSnapshot(includeThumbnails = false)
|
||||
|
||||
assertThat(count).isEqualTo(SEQUENCE_COUNT_WITH_THUMBNAILS)
|
||||
assertThat(count).isEqualTo(100)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenAFilledTable_whenIInsertSimilarIds_thenIExpectUncommittedOverrides() {
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(), 1L)
|
||||
fun givenAnEmptyTable_whenIWriteToTableAndCommit_thenIExpectFilledTableWithThumbnails() {
|
||||
val inputCount = 100
|
||||
val countWithThumbnails = inputCount * 2
|
||||
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(count = inputCount))
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val newPendingTime = 2L
|
||||
val newObjectCount = 50
|
||||
val newObjectCountWithThumbnails = newObjectCount * 2
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(newObjectCount), newPendingTime)
|
||||
val count = getCountForLatestSnapshot(includeThumbnails = true)
|
||||
|
||||
val count = SignalDatabase.backupMediaSnapshots.readableDatabase.count()
|
||||
.from(BackupMediaSnapshotTable.TABLE_NAME)
|
||||
.where("${BackupMediaSnapshotTable.LAST_SYNC_TIME} = 1 AND ${BackupMediaSnapshotTable.PENDING_SYNC_TIME} = $newPendingTime")
|
||||
.run()
|
||||
.readToSingleInt(-1)
|
||||
|
||||
assertThat(count).isEqualTo(newObjectCountWithThumbnails)
|
||||
assertThat(count).isEqualTo(countWithThumbnails)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenAFilledTable_whenIInsertSimilarIdsAndCommit_thenIExpectCommittedOverrides() {
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(), 1L)
|
||||
fun givenAFilledTable_whenIReinsertObjects_thenIExpectUncommittedOverrides() {
|
||||
val initialCount = 100
|
||||
val additionalCount = 25
|
||||
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(count = initialCount))
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val newPendingTime = 2L
|
||||
val newObjectCount = 50
|
||||
val newObjectCountWithThumbnails = newObjectCount * 2
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(newObjectCount), newPendingTime)
|
||||
// This relies on how the sequence of mediaIds is generated in tests -- the ones we generate here will have the mediaIds as the ones we generated above
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(count = additionalCount))
|
||||
|
||||
val pendingCount = getCountForPending(includeThumbnails = false)
|
||||
val latestVersionCount = getCountForLatestSnapshot(includeThumbnails = false)
|
||||
|
||||
assertThat(pendingCount).isEqualTo(additionalCount)
|
||||
assertThat(latestVersionCount).isEqualTo(initialCount)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenAFilledTable_whenIReinsertObjectsAndCommit_thenIExpectCommittedOverrides() {
|
||||
val initialCount = 100
|
||||
val additionalCount = 25
|
||||
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(count = initialCount))
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val count = SignalDatabase.backupMediaSnapshots.readableDatabase.count()
|
||||
.from(BackupMediaSnapshotTable.TABLE_NAME)
|
||||
.where("${BackupMediaSnapshotTable.LAST_SYNC_TIME} = $newPendingTime AND ${BackupMediaSnapshotTable.PENDING_SYNC_TIME} = $newPendingTime")
|
||||
.run()
|
||||
.readToSingleInt(-1)
|
||||
// This relies on how the sequence of mediaIds is generated in tests -- the ones we generate here will have the mediaIds as the ones we generated above
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(count = additionalCount))
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val total = getTotalItemCount()
|
||||
val pendingCount = getCountForPending(includeThumbnails = false)
|
||||
val latestVersionCount = getCountForLatestSnapshot(includeThumbnails = false)
|
||||
val totalCount = getTotalItemCount(includeThumbnails = false)
|
||||
|
||||
assertThat(count).isEqualTo(newObjectCountWithThumbnails)
|
||||
assertThat(total).isEqualTo(SEQUENCE_COUNT_WITH_THUMBNAILS)
|
||||
assertThat(pendingCount).isEqualTo(0)
|
||||
assertThat(latestVersionCount).isEqualTo(additionalCount)
|
||||
assertThat(totalCount).isEqualTo(initialCount)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun givenAFilledTable_whenIInsertSimilarIdsAndCommitThenDelete_thenIExpectOnlyCommittedOverrides() {
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(), 1L)
|
||||
val initialCount = 100
|
||||
val additionalCount = 25
|
||||
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(count = initialCount))
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val newPendingTime = 2L
|
||||
val newObjectCount = 50
|
||||
val newObjectCountWithThumbnails = newObjectCount * 2
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(newObjectCount), newPendingTime)
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(count = additionalCount))
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val page = SignalDatabase.backupMediaSnapshots.getPageOfOldMediaObjects(currentSyncTime = newPendingTime, pageSize = 100)
|
||||
SignalDatabase.backupMediaSnapshots.deleteMediaObjects(page)
|
||||
val page = SignalDatabase.backupMediaSnapshots.getPageOfOldMediaObjects(pageSize = 1_000)
|
||||
SignalDatabase.backupMediaSnapshots.deleteOldMediaObjects(page)
|
||||
|
||||
val total = getTotalItemCount()
|
||||
val total = getTotalItemCount(includeThumbnails = false)
|
||||
|
||||
assertThat(total).isEqualTo(newObjectCountWithThumbnails)
|
||||
assertThat(total).isEqualTo(additionalCount)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -118,7 +121,7 @@ class BackupMediaSnapshotTableTest {
|
||||
createArchiveMediaObject(seed = 2, cdn = 2)
|
||||
)
|
||||
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(localData.asSequence(), 1L)
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(localData.asSequence())
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val mismatches = SignalDatabase.backupMediaSnapshots.getMediaObjectsWithNonMatchingCdn(remoteData)
|
||||
@@ -137,13 +140,13 @@ class BackupMediaSnapshotTableTest {
|
||||
createArchiveMediaObject(seed = 2, cdn = 99)
|
||||
)
|
||||
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(localData.asSequence(), 1L)
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(localData.asSequence())
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val mismatches = SignalDatabase.backupMediaSnapshots.getMediaObjectsWithNonMatchingCdn(remoteData)
|
||||
assertThat(mismatches.size).isEqualTo(1)
|
||||
assertThat(mismatches.get(0).cdn).isEqualTo(99)
|
||||
assertThat(mismatches.get(0).digest).isEqualTo(localData.get(1).digest)
|
||||
assertThat(mismatches[0].cdn).isEqualTo(99)
|
||||
assertThat(mismatches[0].digest).isEqualTo(localData[1].digest)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -158,7 +161,7 @@ class BackupMediaSnapshotTableTest {
|
||||
createArchiveMediaObject(seed = 2, cdn = 2)
|
||||
)
|
||||
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(localData.asSequence(), 1L)
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(localData.asSequence())
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val notFound = SignalDatabase.backupMediaSnapshots.getMediaObjectsThatCantBeFound(remoteData)
|
||||
@@ -177,7 +180,7 @@ class BackupMediaSnapshotTableTest {
|
||||
createArchiveMediaObject(seed = 3, cdn = 2)
|
||||
)
|
||||
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(localData.asSequence(), 1L)
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(localData.asSequence())
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val notFound = SignalDatabase.backupMediaSnapshots.getMediaObjectsThatCantBeFound(remoteData)
|
||||
@@ -185,20 +188,110 @@ class BackupMediaSnapshotTableTest {
|
||||
assertThat(notFound.first()).isEqualTo(remoteData[1])
|
||||
}
|
||||
|
||||
private fun getTotalItemCount(): Int {
|
||||
return SignalDatabase.backupMediaSnapshots.readableDatabase.count().from(BackupMediaSnapshotTable.TABLE_NAME).run().readToSingleInt(-1)
|
||||
@Test
|
||||
fun getCurrentSnapshotVersion_emptyTable() {
|
||||
val version = SignalDatabase.backupMediaSnapshots.getCurrentSnapshotVersion()
|
||||
|
||||
assertThat(version).isEqualTo(0)
|
||||
}
|
||||
|
||||
private fun getSyncedItemCount(pendingTime: Long): Int {
|
||||
return SignalDatabase.backupMediaSnapshots.readableDatabase.count()
|
||||
@Test
|
||||
fun getCurrentSnapshotVersion_singleCommit() {
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(count = 100))
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val version = SignalDatabase.backupMediaSnapshots.getCurrentSnapshotVersion()
|
||||
|
||||
assertThat(version).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getMediaObjectsLastSeenOnCdnBeforeSnapshotVersion_noneMarkedSeen() {
|
||||
val initialCount = 100
|
||||
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(generateArchiveMediaItemSequence(count = initialCount))
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val notSeenCount = SignalDatabase.backupMediaSnapshots.getMediaObjectsLastSeenOnCdnBeforeSnapshotVersion(1).count
|
||||
|
||||
val expectedOldCountIncludingThumbnails = initialCount * 2
|
||||
|
||||
assertThat(notSeenCount).isEqualTo(expectedOldCountIncludingThumbnails)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getMediaObjectsLastSeenOnCdnBeforeSnapshotVersion_someMarkedSeen() {
|
||||
val initialCount = 100
|
||||
val markSeenCount = 25
|
||||
|
||||
val itemsToCommit = generateArchiveMediaItemSequence(count = initialCount)
|
||||
SignalDatabase.backupMediaSnapshots.writePendingMediaObjects(itemsToCommit)
|
||||
SignalDatabase.backupMediaSnapshots.commitPendingRows()
|
||||
|
||||
val normalIdsToMarkSeen = itemsToCommit.take(markSeenCount).map { it.mediaId }.toList()
|
||||
val thumbnailIdsToMarkSeen = itemsToCommit.take(markSeenCount).map { it.thumbnailMediaId }.toList()
|
||||
val allItemsToMarkSeen = normalIdsToMarkSeen + thumbnailIdsToMarkSeen
|
||||
|
||||
SignalDatabase.backupMediaSnapshots.markSeenOnRemote(allItemsToMarkSeen, 1)
|
||||
|
||||
val notSeenCount = SignalDatabase.backupMediaSnapshots.getMediaObjectsLastSeenOnCdnBeforeSnapshotVersion(1).count
|
||||
|
||||
val expectedOldCount = initialCount - markSeenCount
|
||||
val expectedOldCountIncludingThumbnails = expectedOldCount * 2
|
||||
|
||||
assertThat(notSeenCount).isEqualTo(expectedOldCountIncludingThumbnails)
|
||||
}
|
||||
|
||||
private fun getTotalItemCount(includeThumbnails: Boolean): Int {
|
||||
return if (includeThumbnails) {
|
||||
SignalDatabase.backupMediaSnapshots.readableDatabase
|
||||
.count()
|
||||
.from(BackupMediaSnapshotTable.TABLE_NAME)
|
||||
.run()
|
||||
.readToSingleInt(0)
|
||||
} else {
|
||||
SignalDatabase.backupMediaSnapshots.readableDatabase
|
||||
.count()
|
||||
.from(BackupMediaSnapshotTable.TABLE_NAME)
|
||||
.where("${BackupMediaSnapshotTable.IS_THUMBNAIL} = 0")
|
||||
.run()
|
||||
.readToSingleInt(0)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCountForLatestSnapshot(includeThumbnails: Boolean): Int {
|
||||
val thumbnailFilter = if (!includeThumbnails) {
|
||||
" AND ${BackupMediaSnapshotTable.IS_THUMBNAIL} = 0"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
|
||||
return SignalDatabase.backupMediaSnapshots.readableDatabase
|
||||
.count()
|
||||
.from(BackupMediaSnapshotTable.TABLE_NAME)
|
||||
.where("${BackupMediaSnapshotTable.LAST_SYNC_TIME} = $pendingTime AND ${BackupMediaSnapshotTable.PENDING_SYNC_TIME} = $pendingTime")
|
||||
.where("${BackupMediaSnapshotTable.SNAPSHOT_VERSION} = ${BackupMediaSnapshotTable.MAX_VERSION} AND ${BackupMediaSnapshotTable.SNAPSHOT_VERSION} != ${BackupMediaSnapshotTable.UNKNOWN_VERSION}" + thumbnailFilter)
|
||||
.run()
|
||||
.readToSingleInt(-1)
|
||||
.readToSingleInt(0)
|
||||
}
|
||||
|
||||
private fun generateArchiveMediaItemSequence(count: Int = SEQUENCE_COUNT): Sequence<ArchiveMediaItem> {
|
||||
return generateSequence(0) { seed -> if (seed < (count - 1)) seed + 1 else null }
|
||||
private fun getCountForPending(includeThumbnails: Boolean): Int {
|
||||
val thumbnailFilter = if (!includeThumbnails) {
|
||||
" AND ${BackupMediaSnapshotTable.IS_THUMBNAIL} = 0"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
|
||||
return SignalDatabase.backupMediaSnapshots.readableDatabase
|
||||
.count()
|
||||
.from(BackupMediaSnapshotTable.TABLE_NAME)
|
||||
.where("${BackupMediaSnapshotTable.IS_PENDING} != 0" + thumbnailFilter)
|
||||
.run()
|
||||
.readToSingleInt(0)
|
||||
}
|
||||
|
||||
private fun generateArchiveMediaItemSequence(count: Int): Sequence<ArchiveMediaItem> {
|
||||
return (1..count)
|
||||
.asSequence()
|
||||
.map { createArchiveMediaItem(it) }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user