Test settings persistence ownership, ordering and failure isolation
This commit is contained in:
1 parent
a95245e272
commit
87166db832
1 file changed
+40
+40
@@ -0,0 +1,40 @@
|
||||
package com.utun.chat.data
|
||||
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Assert.*
|
||||
import org.junit.Test
|
||||
|
||||
class SettingsOperationsTest {
|
||||
@Test fun acceptedSaveSurvivesUiCancellationAndRestartWaitsForItsCommit() = runTest {
|
||||
val owner = SettingsOperations(this) { _, _ -> }
|
||||
val committed = CompletableDeferred<Unit>(); val order = mutableListOf<String>()
|
||||
val save = owner.submit("name") { committed.await(); order.add("commit") }
|
||||
val second = owner.submit("runtime") { order.add("apply") }
|
||||
val ui = launch { save.await() }; ui.cancel()
|
||||
val restart = async { owner.awaitIdle(); order.add("restart") }
|
||||
assertTrue(order.isEmpty()); assertFalse(save.isCancelled)
|
||||
committed.complete(Unit); save.await(); second.await(); restart.await()
|
||||
assertEquals(listOf("commit", "apply", "restart"), order)
|
||||
}
|
||||
@Test fun failedPersistenceCannotRunTheFollowingRuntimeUpdateOrKillTheQueue() = runTest {
|
||||
val logs = mutableListOf<String>(); val owner = SettingsOperations(this) { _, message -> logs.add(message) }
|
||||
var runtime = false
|
||||
val failed = owner.submit("volume") { throw java.io.IOException("disk rejected"); @Suppress("UNREACHABLE_CODE") runtime = true }
|
||||
assertTrue(runCatching { failed.await() }.exceptionOrNull() is java.io.IOException)
|
||||
assertFalse(runtime); assertTrue(owner.failed.value); assertTrue(logs.any { "disk rejected" in it })
|
||||
owner.submit("retry") { runtime = true }.await()
|
||||
assertTrue(runtime); owner.dismissFailure(); assertFalse(owner.failed.value)
|
||||
}
|
||||
@Test fun cancelledBarrierWaiterCannotCancelAnAcceptedChange() = runTest {
|
||||
val owner = SettingsOperations(this) { _, _ -> }
|
||||
val gate = CompletableDeferred<Unit>(); var saved = false
|
||||
val change = owner.submit("stereo") { gate.await(); saved = true }
|
||||
val waiter = launch { owner.awaitIdle() }; waiter.cancel()
|
||||
gate.complete(Unit); change.await(); assertTrue(saved); assertFalse(change.isCancelled)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user