fix(core): harden targeted transfer recovery

This commit is contained in:
2026-08-12 18:48:13 +02:00
parent 4f09e474c5
commit 2ac9166b34
25 changed files with 3164 additions and 1509 deletions

View File

@@ -19,12 +19,12 @@ class CoreNativeLoadTest {
override fun onEvent(event: CoreEvent) = Unit
},
)
} catch (_: VnidropException.SecureStorageUnavailable) {
} catch (error: VnidropException.SecureStorageUnavailable) {
coreDir.toFile().deleteRecursively()
return
} catch (_: VnidropException.SecureStorageLocked) {
skipWhenHostCredentialStoreIsUnavailable(error)
} catch (error: VnidropException.SecureStorageLocked) {
coreDir.toFile().deleteRecursively()
return
skipWhenHostCredentialStoreIsUnavailable(error)
}
try {

View File

@@ -0,0 +1,8 @@
package com.vnidrop.app
import org.junit.Assume.assumeNoException
internal fun skipWhenHostCredentialStoreIsUnavailable(error: Throwable): Nothing {
assumeNoException("host protected credential store is unavailable", error)
throw AssertionError("JUnit assumption unexpectedly returned", error)
}

View File

@@ -1,5 +1,6 @@
package com.vnidrop.app.core
import com.vnidrop.app.skipWhenHostCredentialStoreIsUnavailable
import java.nio.file.Files
import kotlin.io.path.createTempDirectory
import kotlinx.coroutines.test.runTest
@@ -35,7 +36,7 @@ class CoreRepositoryStorageTest {
initializationError is VnidropException.SecureStorageUnavailable ||
initializationError is VnidropException.SecureStorageLocked
) {
return@runTest
skipWhenHostCredentialStoreIsUnavailable(initializationError)
}
initialized.getOrThrow()
val endpointId = repository.state.value.status?.endpointId

View File

@@ -1,5 +1,6 @@
package com.vnidrop.app.core
import com.vnidrop.app.skipWhenHostCredentialStoreIsUnavailable
import java.nio.file.Files
import kotlin.test.Test
import kotlin.test.assertEquals
@@ -41,12 +42,12 @@ class SavedDeviceCoreContractJvmSmokeTest {
sink,
network,
)
} catch (_: VnidropException.SecureStorageUnavailable) {
} catch (error: VnidropException.SecureStorageUnavailable) {
coreDir.toFile().deleteRecursively()
return
} catch (_: VnidropException.SecureStorageLocked) {
skipWhenHostCredentialStoreIsUnavailable(error)
} catch (error: VnidropException.SecureStorageLocked) {
coreDir.toFile().deleteRecursively()
return
skipWhenHostCredentialStoreIsUnavailable(error)
}
val endpointId = try {
val id = first.status().endpointId
@@ -94,14 +95,14 @@ class SavedDeviceCoreContractJvmSmokeTest {
defaultCoreLimits(),
network,
)
} catch (_: VnidropException.SecureStorageUnavailable) {
} catch (error: VnidropException.SecureStorageUnavailable) {
// Desktop hosts may lack a usable credential store; Android Keystore
// restart is covered by crates/vnidrop platform_contract_android.
coreDir.toFile().deleteRecursively()
return
} catch (_: VnidropException.SecureStorageLocked) {
skipWhenHostCredentialStoreIsUnavailable(error)
} catch (error: VnidropException.SecureStorageLocked) {
coreDir.toFile().deleteRecursively()
return
skipWhenHostCredentialStoreIsUnavailable(error)
}
try {