From 674568ca11059e8d1b4b33a72f6c90a0cab1be14 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Thu, 16 Sep 2021 18:56:23 +0200 Subject: [PATCH] Use new storage API for full backups --- .../seedvault/metadata/MetadataManager.kt | 3 + .../transport/backup/BackupCoordinator.kt | 12 +++- .../transport/backup/BackupModule.kt | 2 +- .../seedvault/transport/backup/FullBackup.kt | 27 ++++---- .../transport/CoordinatorIntegrationTest.kt | 9 ++- .../seedvault/transport/TransportTest.kt | 1 + .../transport/backup/BackupCoordinatorTest.kt | 32 ++++++++-- .../seedvault/transport/backup/BackupTest.kt | 2 +- .../transport/backup/FullBackupTest.kt | 64 +++++++++---------- 9 files changed, 93 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/com/stevesoltys/seedvault/metadata/MetadataManager.kt b/app/src/main/java/com/stevesoltys/seedvault/metadata/MetadataManager.kt index 648816b4..a1a53065 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/metadata/MetadataManager.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/metadata/MetadataManager.kt @@ -219,6 +219,9 @@ internal class MetadataManager( private val mLastBackupTime = MutableLiveData() internal val lastBackupTime: LiveData = mLastBackupTime.distinctUntilChanged() + internal val salt: String + @Synchronized get() = metadata.salt + internal val isLegacyFormat: Boolean @Synchronized get() = metadata.version < VERSION diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinator.kt b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinator.kt index e0b0a939..11ded3de 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinator.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinator.kt @@ -310,7 +310,9 @@ internal class BackupCoordinator( flags: Int ): Int { state.cancelReason = UNKNOWN_ERROR - return full.performFullBackup(targetPackage, fileDescriptor, flags) + val token = settingsManager.getToken() ?: error("no token in performFullBackup") + val salt = metadataManager.salt + return full.performFullBackup(targetPackage, fileDescriptor, flags, token, salt) } suspend fun sendBackupData(numBytes: Int) = full.sendBackupData(numBytes) @@ -336,7 +338,9 @@ internal class BackupCoordinator( " because of ${state.cancelReason}" ) onPackageBackupError(packageInfo, BackupType.FULL) - full.cancelFullBackup() + val token = settingsManager.getToken() ?: error("no token in cancelFullBackup") + val salt = metadataManager.salt + full.cancelFullBackup(token, salt) } // Clear and Finish @@ -353,6 +357,8 @@ internal class BackupCoordinator( suspend fun clearBackupData(packageInfo: PackageInfo): Int { val packageName = packageInfo.packageName Log.i(TAG, "Clear Backup Data of $packageName.") + val token = settingsManager.getToken() ?: error("no token in clearBackupData") + val salt = metadataManager.salt try { kv.clearBackupData(packageInfo) } catch (e: IOException) { @@ -360,7 +366,7 @@ internal class BackupCoordinator( return TRANSPORT_ERROR } try { - full.clearBackupData(packageInfo) + full.clearBackupData(packageInfo, token, salt) } catch (e: IOException) { Log.w(TAG, "Error clearing full backup data for $packageName", e) return TRANSPORT_ERROR diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupModule.kt b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupModule.kt index 44836d47..a3fc6457 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupModule.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/BackupModule.kt @@ -29,7 +29,7 @@ val backupModule = module { } single { FullBackup( - plugin = get().fullBackupPlugin, + plugin = get(), settingsManager = get(), inputFactory = get(), crypto = get() diff --git a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/FullBackup.kt b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/FullBackup.kt index 4356ae65..e14899b2 100644 --- a/app/src/main/java/com/stevesoltys/seedvault/transport/backup/FullBackup.kt +++ b/app/src/main/java/com/stevesoltys/seedvault/transport/backup/FullBackup.kt @@ -38,7 +38,7 @@ private val TAG = FullBackup::class.java.simpleName @Suppress("BlockingMethodInNonBlockingContext") internal class FullBackup( - private val plugin: FullBackupPlugin, + private val plugin: BackupPlugin, private val settingsManager: SettingsManager, private val inputFactory: InputFactory, private val crypto: Crypto @@ -51,7 +51,7 @@ internal class FullBackup( fun getCurrentPackage() = state?.packageInfo fun getQuota(): Long { - return if (settingsManager.isQuotaUnlimited()) Long.MAX_VALUE else plugin.getQuota() + return if (settingsManager.isQuotaUnlimited()) Long.MAX_VALUE else DEFAULT_QUOTA_FULL_BACKUP } fun checkFullBackupSize(size: Long): Int { @@ -101,20 +101,24 @@ internal class FullBackup( suspend fun performFullBackup( targetPackage: PackageInfo, socket: ParcelFileDescriptor, - @Suppress("UNUSED_PARAMETER") flags: Int = 0 + @Suppress("UNUSED_PARAMETER") flags: Int = 0, + token: Long, + salt: String ): Int { if (state != null) throw AssertionError() - Log.i(TAG, "Perform full backup for ${targetPackage.packageName}.") + val packageName = targetPackage.packageName + Log.i(TAG, "Perform full backup for $packageName.") // create new state val inputStream = inputFactory.getInputStream(socket) state = FullBackupState(targetPackage, socket, inputStream) { - Log.d(TAG, "Initializing OutputStream for ${targetPackage.packageName}.") + Log.d(TAG, "Initializing OutputStream for $packageName.") + val name = crypto.getNameForPackage(salt, packageName) // get OutputStream to write backup data into val outputStream = try { - plugin.getOutputStream(targetPackage) + plugin.getOutputStream(token, name) } catch (e: IOException) { - "Error getting OutputStream for full backup of ${targetPackage.packageName}".let { + "Error getting OutputStream for full backup of $packageName".let { Log.e(TAG, it, e) } throw(e) @@ -167,15 +171,16 @@ internal class FullBackup( } @Throws(IOException::class) - suspend fun clearBackupData(packageInfo: PackageInfo) { - plugin.removeDataOfPackage(packageInfo) + suspend fun clearBackupData(packageInfo: PackageInfo, token: Long, salt: String) { + val name = crypto.getNameForPackage(salt, packageInfo.packageName) + plugin.removeData(token, name) } - suspend fun cancelFullBackup() { + suspend fun cancelFullBackup(token: Long, salt: String) { Log.i(TAG, "Cancel full backup") val state = this.state ?: throw AssertionError("No state when canceling") try { - plugin.removeDataOfPackage(state.packageInfo) + clearBackupData(state.packageInfo, token, salt) } catch (e: IOException) { Log.w(TAG, "Error cancelling full backup for ${state.packageName}", e) } diff --git a/app/src/test/java/com/stevesoltys/seedvault/transport/CoordinatorIntegrationTest.kt b/app/src/test/java/com/stevesoltys/seedvault/transport/CoordinatorIntegrationTest.kt index f5647c23..50988512 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/transport/CoordinatorIntegrationTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/transport/CoordinatorIntegrationTest.kt @@ -73,7 +73,7 @@ internal class CoordinatorIntegrationTest : TransportTest() { ) private val fullBackupPlugin = mockk() private val fullBackup = FullBackup( - plugin = fullBackupPlugin, + plugin = backupPlugin, settingsManager = settingsManager, inputFactory = inputFactory, crypto = cryptoImpl @@ -295,11 +295,13 @@ internal class CoordinatorIntegrationTest : TransportTest() { val packageMetadata = metadata.packageMetadataMap[packageInfo.packageName]!! metadata.packageMetadataMap[packageInfo.packageName] = packageMetadata.copy(backupType = BackupType.FULL) + // as we use real crypto, we need a real name for packageInfo + val name = cryptoImpl.getNameForPackage(salt, packageInfo.packageName) // return streams from plugin and app data val bOutputStream = ByteArrayOutputStream() val bInputStream = ByteArrayInputStream(appData) - coEvery { fullBackupPlugin.getOutputStream(packageInfo) } returns bOutputStream + coEvery { backupPlugin.getOutputStream(token, name) } returns bOutputStream every { inputFactory.getInputStream(fileDescriptor) } returns bInputStream every { settingsManager.isQuotaUnlimited() } returns false every { fullBackupPlugin.getQuota() } returns DEFAULT_QUOTA_FULL_BACKUP @@ -311,6 +313,7 @@ internal class CoordinatorIntegrationTest : TransportTest() { ) } returns packageMetadata every { settingsManager.getToken() } returns token + every { metadataManager.salt } returns salt coEvery { backupPlugin.getOutputStream(token, FILE_BACKUP_METADATA) } returns metadataOutputStream @@ -336,7 +339,7 @@ internal class CoordinatorIntegrationTest : TransportTest() { assertEquals(TRANSPORT_OK, restore.startRestore(token, arrayOf(packageInfo))) // finds data for full backup - every { crypto.getNameForPackage(metadata.salt, packageInfo.packageName) } returns name + every { crypto.getNameForPackage(salt, packageInfo.packageName) } returns name coEvery { backupPlugin.hasData(token, name) } returns true val restoreDescription = restore.nextRestorePackage() ?: fail() diff --git a/app/src/test/java/com/stevesoltys/seedvault/transport/TransportTest.kt b/app/src/test/java/com/stevesoltys/seedvault/transport/TransportTest.kt index d3060f94..9d441528 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/transport/TransportTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/transport/TransportTest.kt @@ -58,6 +58,7 @@ internal abstract class TransportTest { put(packageInfo.packageName, PackageMetadata(backupType = BackupType.KV)) } ) + protected val salt = metadata.salt protected val name = getRandomString(12) protected val name2 = getRandomString(23) diff --git a/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinatorTest.kt b/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinatorTest.kt index 089c5737..6f0ee3dd 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinatorTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupCoordinatorTest.kt @@ -220,6 +220,8 @@ internal class BackupCoordinatorTest : BackupTest() { @Test fun `clearing KV backup data throws`() = runBlocking { + every { settingsManager.getToken() } returns token + every { metadataManager.salt } returns salt coEvery { kv.clearBackupData(packageInfo) } throws IOException() assertEquals(TRANSPORT_ERROR, backup.clearBackupData(packageInfo)) @@ -227,16 +229,20 @@ internal class BackupCoordinatorTest : BackupTest() { @Test fun `clearing full backup data throws`() = runBlocking { + every { settingsManager.getToken() } returns token + every { metadataManager.salt } returns salt coEvery { kv.clearBackupData(packageInfo) } just Runs - coEvery { full.clearBackupData(packageInfo) } throws IOException() + coEvery { full.clearBackupData(packageInfo, token, salt) } throws IOException() assertEquals(TRANSPORT_ERROR, backup.clearBackupData(packageInfo)) } @Test fun `clearing backup data succeeds`() = runBlocking { + every { settingsManager.getToken() } returns token + every { metadataManager.salt } returns salt coEvery { kv.clearBackupData(packageInfo) } just Runs - coEvery { full.clearBackupData(packageInfo) } just Runs + coEvery { full.clearBackupData(packageInfo, token, salt) } just Runs assertEquals(TRANSPORT_OK, backup.clearBackupData(packageInfo)) @@ -288,7 +294,11 @@ internal class BackupCoordinatorTest : BackupTest() { @Test fun `metadata does not get updated when no APK was backed up`() = runBlocking { - coEvery { full.performFullBackup(packageInfo, fileDescriptor, 0) } returns TRANSPORT_OK + every { settingsManager.getToken() } returns token + every { metadataManager.salt } returns salt + coEvery { + full.performFullBackup(packageInfo, fileDescriptor, 0, token, salt) + } returns TRANSPORT_OK coEvery { apkBackup.backupApkIfNecessary(packageInfo, UNKNOWN_ERROR, any()) } returns null assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, fileDescriptor, 0)) @@ -296,7 +306,11 @@ internal class BackupCoordinatorTest : BackupTest() { @Test fun `app exceeding quota gets cancelled and reason written to metadata`() = runBlocking { - coEvery { full.performFullBackup(packageInfo, fileDescriptor, 0) } returns TRANSPORT_OK + every { settingsManager.getToken() } returns token + every { metadataManager.salt } returns salt + coEvery { + full.performFullBackup(packageInfo, fileDescriptor, 0, token, salt) + } returns TRANSPORT_OK expectApkBackupAndMetadataWrite() every { full.getQuota() } returns DEFAULT_QUOTA_FULL_BACKUP every { @@ -311,7 +325,7 @@ internal class BackupCoordinatorTest : BackupTest() { BackupType.FULL ) } just Runs - coEvery { full.cancelFullBackup() } just Runs + coEvery { full.cancelFullBackup(token, metadata.salt) } just Runs every { settingsManager.getStorage() } returns storage every { metadataOutputStream.close() } just Runs @@ -343,7 +357,11 @@ internal class BackupCoordinatorTest : BackupTest() { @Test fun `app with no data gets cancelled and reason written to metadata`() = runBlocking { - coEvery { full.performFullBackup(packageInfo, fileDescriptor, 0) } returns TRANSPORT_OK + every { settingsManager.getToken() } returns token + every { metadataManager.salt } returns salt + coEvery { + full.performFullBackup(packageInfo, fileDescriptor, 0, token, salt) + } returns TRANSPORT_OK expectApkBackupAndMetadataWrite() every { full.getQuota() } returns DEFAULT_QUOTA_FULL_BACKUP every { full.checkFullBackupSize(0) } returns TRANSPORT_PACKAGE_REJECTED @@ -356,7 +374,7 @@ internal class BackupCoordinatorTest : BackupTest() { BackupType.FULL ) } just Runs - coEvery { full.cancelFullBackup() } just Runs + coEvery { full.cancelFullBackup(token, metadata.salt) } just Runs every { settingsManager.getStorage() } returns storage every { metadataOutputStream.close() } just Runs diff --git a/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupTest.kt b/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupTest.kt index f6dc5cc6..b1f85b7c 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/transport/backup/BackupTest.kt @@ -12,6 +12,6 @@ internal abstract class BackupTest : TransportTest() { protected val outputStream = mockk() protected val encryptedOutputStream = mockk() - protected val quota = 42L + protected val quota = DEFAULT_QUOTA_FULL_BACKUP } diff --git a/app/src/test/java/com/stevesoltys/seedvault/transport/backup/FullBackupTest.kt b/app/src/test/java/com/stevesoltys/seedvault/transport/backup/FullBackupTest.kt index 4c364fbc..4e44c9bb 100644 --- a/app/src/test/java/com/stevesoltys/seedvault/transport/backup/FullBackupTest.kt +++ b/app/src/test/java/com/stevesoltys/seedvault/transport/backup/FullBackupTest.kt @@ -23,7 +23,7 @@ import kotlin.random.Random @Suppress("BlockingMethodInNonBlockingContext") internal class FullBackupTest : BackupTest() { - private val plugin = mockk() + private val plugin = mockk() private val backup = FullBackup(plugin, settingsManager, inputFactory, crypto) private val bytes = ByteArray(23).apply { Random.nextBytes(this) } @@ -38,9 +38,8 @@ internal class FullBackupTest : BackupTest() { @Test fun `checkFullBackupSize exceeds quota`() { every { settingsManager.isQuotaUnlimited() } returns false - every { plugin.getQuota() } returns quota - assertEquals(TRANSPORT_QUOTA_EXCEEDED, backup.checkFullBackupSize(quota + 1)) + assertEquals(TRANSPORT_QUOTA_EXCEEDED, backup.checkFullBackupSize(DEFAULT_QUOTA_FULL_BACKUP + 1)) } @Test @@ -63,7 +62,6 @@ internal class FullBackupTest : BackupTest() { @Test fun `checkFullBackupSize accepts min data`() { every { settingsManager.isQuotaUnlimited() } returns false - every { plugin.getQuota() } returns quota assertEquals(TRANSPORT_OK, backup.checkFullBackupSize(1)) } @@ -71,7 +69,6 @@ internal class FullBackupTest : BackupTest() { @Test fun `checkFullBackupSize accepts max data`() { every { settingsManager.isQuotaUnlimited() } returns false - every { plugin.getQuota() } returns quota assertEquals(TRANSPORT_OK, backup.checkFullBackupSize(quota)) } @@ -81,7 +78,7 @@ internal class FullBackupTest : BackupTest() { every { inputFactory.getInputStream(data) } returns inputStream expectClearState() - assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data)) + assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data, 0, token, salt)) assertTrue(backup.hasState()) assertEquals(TRANSPORT_OK, backup.finishBackup()) assertFalse(backup.hasState()) @@ -96,7 +93,7 @@ internal class FullBackupTest : BackupTest() { expectSendData(numBytes) expectClearState() - assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data)) + assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data, 0, token, salt)) assertTrue(backup.hasState()) assertEquals(TRANSPORT_QUOTA_EXCEEDED, backup.sendBackupData(numBytes)) assertTrue(backup.hasState()) @@ -115,7 +112,7 @@ internal class FullBackupTest : BackupTest() { expectSendData(numBytes2) expectClearState() - assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data)) + assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data, 0, token, salt)) assertTrue(backup.hasState()) assertEquals(TRANSPORT_OK, backup.sendBackupData(numBytes1)) assertTrue(backup.hasState()) @@ -130,12 +127,11 @@ internal class FullBackupTest : BackupTest() { every { inputFactory.getInputStream(data) } returns inputStream expectInitializeOutputStream() every { settingsManager.isQuotaUnlimited() } returns false - every { plugin.getQuota() } returns quota every { crypto.newEncryptingStream(outputStream, ad) } returns encryptedOutputStream every { inputStream.read(any(), any(), bytes.size) } throws IOException() expectClearState() - assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data)) + assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data, 0, token, salt)) assertTrue(backup.hasState()) assertEquals(TRANSPORT_ERROR, backup.sendBackupData(bytes.size)) assertTrue(backup.hasState()) @@ -148,11 +144,11 @@ internal class FullBackupTest : BackupTest() { every { inputFactory.getInputStream(data) } returns inputStream every { settingsManager.isQuotaUnlimited() } returns false - every { plugin.getQuota() } returns quota - coEvery { plugin.getOutputStream(packageInfo) } throws IOException() + every { crypto.getNameForPackage(salt, packageInfo.packageName) } returns name + coEvery { plugin.getOutputStream(token, name) } throws IOException() expectClearState() - assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data)) + assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data, 0, token, salt)) assertTrue(backup.hasState()) assertEquals(TRANSPORT_ERROR, backup.sendBackupData(bytes.size)) assertTrue(backup.hasState()) @@ -165,13 +161,13 @@ internal class FullBackupTest : BackupTest() { every { inputFactory.getInputStream(data) } returns inputStream every { settingsManager.isQuotaUnlimited() } returns false - every { plugin.getQuota() } returns quota - coEvery { plugin.getOutputStream(packageInfo) } returns outputStream + every { crypto.getNameForPackage(salt, packageInfo.packageName) } returns name + coEvery { plugin.getOutputStream(token, name) } returns outputStream every { inputFactory.getInputStream(data) } returns inputStream every { outputStream.write(ByteArray(1) { VERSION }) } throws IOException() expectClearState() - assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data)) + assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data, 0, token, salt)) assertTrue(backup.hasState()) assertEquals(TRANSPORT_ERROR, backup.sendBackupData(bytes.size)) assertTrue(backup.hasState()) @@ -185,13 +181,12 @@ internal class FullBackupTest : BackupTest() { every { inputFactory.getInputStream(data) } returns inputStream expectInitializeOutputStream() every { settingsManager.isQuotaUnlimited() } returns false - every { plugin.getQuota() } returns quota every { crypto.newEncryptingStream(outputStream, ad) } returns encryptedOutputStream every { inputStream.read(any(), any(), bytes.size) } returns bytes.size every { encryptedOutputStream.write(any()) } throws IOException() expectClearState() - assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data)) + assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data, 0, token, salt)) assertTrue(backup.hasState()) assertEquals(TRANSPORT_ERROR, backup.sendBackupData(bytes.size)) assertTrue(backup.hasState()) @@ -210,7 +205,7 @@ internal class FullBackupTest : BackupTest() { expectSendData(numBytes2) expectClearState() - assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data)) + assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data, 0, token, salt)) assertTrue(backup.hasState()) assertEquals(TRANSPORT_OK, backup.sendBackupData(numBytes1)) assertTrue(backup.hasState()) @@ -222,9 +217,10 @@ internal class FullBackupTest : BackupTest() { @Test fun `clearBackupData delegates to plugin`() = runBlocking { - coEvery { plugin.removeDataOfPackage(packageInfo) } just Runs + every { crypto.getNameForPackage(salt, packageInfo.packageName) } returns name + coEvery { plugin.removeData(token, name) } just Runs - backup.clearBackupData(packageInfo) + backup.clearBackupData(packageInfo, token, salt) } @Test @@ -232,11 +228,12 @@ internal class FullBackupTest : BackupTest() { every { inputFactory.getInputStream(data) } returns inputStream expectInitializeOutputStream() expectClearState() - coEvery { plugin.removeDataOfPackage(packageInfo) } just Runs + every { crypto.getNameForPackage(salt, packageInfo.packageName) } returns name + coEvery { plugin.removeData(token, name) } just Runs - assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data)) + assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data, 0, token, salt)) assertTrue(backup.hasState()) - backup.cancelFullBackup() + backup.cancelFullBackup(token, salt) assertFalse(backup.hasState()) } @@ -245,11 +242,12 @@ internal class FullBackupTest : BackupTest() { every { inputFactory.getInputStream(data) } returns inputStream expectInitializeOutputStream() expectClearState() - coEvery { plugin.removeDataOfPackage(packageInfo) } throws IOException() + every { crypto.getNameForPackage(salt, packageInfo.packageName) } returns name + coEvery { plugin.removeData(token, name) } throws IOException() - assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data)) + assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data, 0, token, salt)) assertTrue(backup.hasState()) - backup.cancelFullBackup() + backup.cancelFullBackup(token, salt) assertFalse(backup.hasState()) } @@ -262,7 +260,7 @@ internal class FullBackupTest : BackupTest() { expectSendData(numBytes) every { encryptedOutputStream.flush() } throws IOException() - assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data)) + assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data, 0, token, salt)) assertTrue(backup.hasState()) assertEquals(TRANSPORT_OK, backup.sendBackupData(numBytes)) assertEquals(TRANSPORT_ERROR, backup.finishBackup()) @@ -278,7 +276,7 @@ internal class FullBackupTest : BackupTest() { every { inputStream.close() } just Runs every { data.close() } just Runs - assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data)) + assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data, 0, token, salt)) assertTrue(backup.hasState()) assertEquals(TRANSPORT_OK, backup.finishBackup()) assertFalse(backup.hasState()) @@ -293,7 +291,7 @@ internal class FullBackupTest : BackupTest() { every { inputStream.close() } throws IOException() every { data.close() } just Runs - assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data)) + assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data, 0, token, salt)) assertTrue(backup.hasState()) assertEquals(TRANSPORT_OK, backup.finishBackup()) assertFalse(backup.hasState()) @@ -308,19 +306,19 @@ internal class FullBackupTest : BackupTest() { every { inputStream.close() } just Runs every { data.close() } throws IOException() - assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data)) + assertEquals(TRANSPORT_OK, backup.performFullBackup(packageInfo, data, 0, token, salt)) assertTrue(backup.hasState()) assertEquals(TRANSPORT_OK, backup.finishBackup()) assertFalse(backup.hasState()) } private fun expectInitializeOutputStream() { - coEvery { plugin.getOutputStream(packageInfo) } returns outputStream + every { crypto.getNameForPackage(salt, packageInfo.packageName) } returns name + coEvery { plugin.getOutputStream(token, name) } returns outputStream every { outputStream.write(ByteArray(1) { VERSION }) } just Runs } private fun expectSendData(numBytes: Int, readBytes: Int = numBytes) { - every { plugin.getQuota() } returns quota every { inputStream.read(any(), any(), numBytes) } returns readBytes every { crypto.newEncryptingStream(outputStream, ad) } returns encryptedOutputStream every { encryptedOutputStream.write(any()) } just Runs