Make PluginTest work for Nextcloud as well
Only issue left was a different maximum file name length for Nextcloud
This commit is contained in:
parent
2958c8fac8
commit
30e66f368e
3 changed files with 59 additions and 14 deletions
|
@ -7,6 +7,8 @@ import com.stevesoltys.seedvault.metadata.MetadataManager
|
|||
import com.stevesoltys.seedvault.plugins.saf.DocumentsProviderBackupPlugin
|
||||
import com.stevesoltys.seedvault.plugins.saf.DocumentsProviderRestorePlugin
|
||||
import com.stevesoltys.seedvault.plugins.saf.DocumentsStorage
|
||||
import com.stevesoltys.seedvault.plugins.saf.MAX_KEY_LENGTH
|
||||
import com.stevesoltys.seedvault.plugins.saf.MAX_KEY_LENGTH_NEXTCLOUD
|
||||
import com.stevesoltys.seedvault.plugins.saf.deleteContents
|
||||
import com.stevesoltys.seedvault.settings.SettingsManager
|
||||
import com.stevesoltys.seedvault.transport.backup.BackupPlugin
|
||||
|
@ -25,9 +27,9 @@ import org.junit.Test
|
|||
import org.junit.runner.RunWith
|
||||
import org.koin.core.KoinComponent
|
||||
import org.koin.core.inject
|
||||
import java.io.IOException
|
||||
import kotlin.random.Random
|
||||
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
class PluginTest : KoinComponent {
|
||||
|
@ -48,7 +50,7 @@ class PluginTest : KoinComponent {
|
|||
fun setup() {
|
||||
every { mockedSettingsManager.getStorage() } returns settingsManager.getStorage()
|
||||
storage.rootBackupDir?.deleteContents()
|
||||
?: error("Select a storage location in the app first!")
|
||||
?: error("Select a storage location in the app first!")
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -162,7 +164,7 @@ class PluginTest : KoinComponent {
|
|||
// define key/value pair records
|
||||
val record1 = Pair(getRandomBase64(23), getRandomByteArray(1337))
|
||||
val record2 = Pair(getRandomBase64(42), getRandomByteArray(42 * 1024))
|
||||
val record3 = Pair(getRandomBase64(255), getRandomByteArray(5 * 1024 * 1024))
|
||||
val record3 = Pair(getRandomBase64(128), getRandomByteArray(5 * 1024 * 1024))
|
||||
|
||||
// write first record
|
||||
kvBackup.ensureRecordStorageForPackage(packageInfo)
|
||||
|
@ -177,7 +179,10 @@ class PluginTest : KoinComponent {
|
|||
var records = kvRestore.listRecords(token, packageInfo)
|
||||
assertEquals(1, records.size)
|
||||
assertEquals(record1.first, records[0])
|
||||
assertReadEquals(record1.second, kvRestore.getInputStreamForRecord(token, packageInfo, record1.first))
|
||||
assertReadEquals(
|
||||
record1.second,
|
||||
kvRestore.getInputStreamForRecord(token, packageInfo, record1.first)
|
||||
)
|
||||
|
||||
// write second and third record
|
||||
kvBackup.ensureRecordStorageForPackage(packageInfo)
|
||||
|
@ -187,9 +192,18 @@ class PluginTest : KoinComponent {
|
|||
// all records for package are found and returned properly
|
||||
records = kvRestore.listRecords(token, packageInfo)
|
||||
assertEquals(listOf(record1.first, record2.first, record3.first).sorted(), records.sorted())
|
||||
assertReadEquals(record1.second, kvRestore.getInputStreamForRecord(token, packageInfo, record1.first))
|
||||
assertReadEquals(record2.second, kvRestore.getInputStreamForRecord(token, packageInfo, record2.first))
|
||||
assertReadEquals(record3.second, kvRestore.getInputStreamForRecord(token, packageInfo, record3.first))
|
||||
assertReadEquals(
|
||||
record1.second,
|
||||
kvRestore.getInputStreamForRecord(token, packageInfo, record1.first)
|
||||
)
|
||||
assertReadEquals(
|
||||
record2.second,
|
||||
kvRestore.getInputStreamForRecord(token, packageInfo, record2.first)
|
||||
)
|
||||
assertReadEquals(
|
||||
record3.second,
|
||||
kvRestore.getInputStreamForRecord(token, packageInfo, record3.first)
|
||||
)
|
||||
|
||||
// delete record3 and ensure that the other two are still found
|
||||
kvBackup.deleteRecord(packageInfo, record3.first)
|
||||
|
@ -211,13 +225,17 @@ class PluginTest : KoinComponent {
|
|||
// initialize storage with given token
|
||||
initStorage(token)
|
||||
|
||||
// FIXME get Nextcloud to have the same limit
|
||||
val max = if (isNextcloud()) MAX_KEY_LENGTH_NEXTCLOUD else MAX_KEY_LENGTH
|
||||
|
||||
// define record with maximum key length and one above the maximum
|
||||
val recordMax = Pair(getRandomBase64(255), getRandomByteArray(1024))
|
||||
val recordOver = Pair(getRandomBase64(256), getRandomByteArray(1024))
|
||||
val recordMax = Pair(getRandomBase64(max), getRandomByteArray(1024))
|
||||
val recordOver = Pair(getRandomBase64(max + 1), getRandomByteArray(1024))
|
||||
|
||||
// write max record
|
||||
kvBackup.ensureRecordStorageForPackage(packageInfo)
|
||||
kvBackup.getOutputStreamForRecord(packageInfo, recordMax.first).writeAndClose(recordMax.second)
|
||||
kvBackup.getOutputStreamForRecord(packageInfo, recordMax.first)
|
||||
.writeAndClose(recordMax.second)
|
||||
|
||||
// max record is found correctly
|
||||
assertTrue(kvRestore.hasDataForPackage(token, packageInfo))
|
||||
|
@ -226,8 +244,17 @@ class PluginTest : KoinComponent {
|
|||
|
||||
// write exceeding key length record
|
||||
kvBackup.ensureRecordStorageForPackage(packageInfo)
|
||||
coAssertThrows(IllegalStateException::class.java) {
|
||||
kvBackup.getOutputStreamForRecord(packageInfo, recordOver.first).writeAndClose(recordOver.second)
|
||||
if (isNextcloud()) {
|
||||
// Nextcloud simply refuses to write long filenames
|
||||
coAssertThrows(IOException::class.java) {
|
||||
kvBackup.getOutputStreamForRecord(packageInfo, recordOver.first)
|
||||
.writeAndClose(recordOver.second)
|
||||
}
|
||||
} else {
|
||||
coAssertThrows(IllegalStateException::class.java) {
|
||||
kvBackup.getOutputStreamForRecord(packageInfo, recordOver.first)
|
||||
.writeAndClose(recordOver.second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,4 +305,8 @@ class PluginTest : KoinComponent {
|
|||
assertTrue(backupPlugin.initializeDevice(newToken = token))
|
||||
}
|
||||
|
||||
private fun isNextcloud(): Boolean {
|
||||
return backupPlugin.providerPackageName == "com.nextcloud.client"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ class DocumentsStorageTest : KoinComponent {
|
|||
fun setup() = runBlocking {
|
||||
assertNotNull("Select a storage location in the app first!", storage.rootBackupDir)
|
||||
file = storage.rootBackupDir?.createOrGetFile(context, filename)
|
||||
?: throw RuntimeException("Could not create test file")
|
||||
?: error("Could not create test file")
|
||||
}
|
||||
|
||||
@After
|
||||
|
|
|
@ -2,12 +2,16 @@ package com.stevesoltys.seedvault.plugins.saf
|
|||
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageInfo
|
||||
import android.util.Log
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import com.stevesoltys.seedvault.transport.backup.DEFAULT_QUOTA_KEY_VALUE_BACKUP
|
||||
import com.stevesoltys.seedvault.transport.backup.KVBackupPlugin
|
||||
import java.io.IOException
|
||||
import java.io.OutputStream
|
||||
|
||||
const val MAX_KEY_LENGTH = 255
|
||||
const val MAX_KEY_LENGTH_NEXTCLOUD = 228
|
||||
|
||||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
internal class DocumentsProviderKVBackup(
|
||||
private val storage: DocumentsStorage,
|
||||
|
@ -37,7 +41,8 @@ internal class DocumentsProviderKVBackup(
|
|||
override suspend fun removeDataOfPackage(packageInfo: PackageInfo) {
|
||||
// we cannot use the cached this.packageFile here,
|
||||
// because this can be called before [ensureRecordStorageForPackage]
|
||||
val packageFile = storage.currentKvBackupDir?.findFileBlocking(context, packageInfo.packageName) ?: return
|
||||
val packageFile =
|
||||
storage.currentKvBackupDir?.findFileBlocking(context, packageInfo.packageName) ?: return
|
||||
packageFile.delete()
|
||||
}
|
||||
|
||||
|
@ -54,6 +59,15 @@ internal class DocumentsProviderKVBackup(
|
|||
packageInfo: PackageInfo,
|
||||
key: String
|
||||
): OutputStream {
|
||||
check(key.length < MAX_KEY_LENGTH) {
|
||||
"Key $key for ${packageInfo.packageName} is too long: ${key.length} chars."
|
||||
}
|
||||
if (key.length > MAX_KEY_LENGTH_NEXTCLOUD) {
|
||||
Log.e(
|
||||
DocumentsProviderKVBackup::class.simpleName,
|
||||
"Key $key for ${packageInfo.packageName} is too long: ${key.length} chars."
|
||||
)
|
||||
}
|
||||
val packageFile = this.packageFile ?: throw AssertionError()
|
||||
packageFile.assertRightFile(packageInfo)
|
||||
val keyFile = packageFile.createOrGetFile(context, key)
|
||||
|
|
Loading…
Reference in a new issue