Nikolay Kasyanov
04/15/2021, 2:32 PMHttpClient
instance,
by using Reaktive helpers to “convert” coroutines into Observable
(or other Reaktive types).
To do actual asserts, Reaktive helpers like TestObserver
are used:
fun `it does whatever a spider cat does`() {
// ktorMockServerManager is just a way to configure mock engine handlers
ktorMockServerManager.enqueueRequest(
...
)
sut.doApiStuff(...)
.test()
.assertComplete()
}
The tests are completely synchronous, but as soon as I update ktor to 1.5.1 (1.5.0 is fine, though), they start failing because by the time assertComplete
is called, the underlying coroutine hasn’t yet finished, so the tests fail. If I add a sleep
call like this:
fun `it does whatever a spider cat does`() {
ktorMockServerManager.enqueueRequest(
...
)
val observer = sut.doApiStuff(...)
.test()
sleep(1000)
observer.assertComplete()
}
I wonder what change between 1.4.3 and 1.5.1 could lead to this and what’s the way around it?MockEngine
since 1.4.3, added in 1.5.1: https://github.com/ktorio/ktor/commit/a6d103f6c3f13c1a136a313112a47a6af7927137#diff-3d93b6d65cea408ebd78460acc5fea1e9fb27799795984595067d5e421f939d1Dispatchers.clientDispatcher
yields Unconfined
dispatcher, but on JVM it’s ClosableBlockingDispatcher
e5l
04/20/2021, 9:23 AMNikolay Kasyanov
04/22/2021, 9:50 AMClosableBlockingDispatcher
was added to MockEngine in ktor 1.5.1 if I remember correctly. Previously, the same coroutine would have executed immediately on the Unconfined
dispatcher.e5l
05/04/2021, 4:05 PMNikolay Kasyanov
05/04/2021, 4:06 PMcall-context:2
, here’s what I see:"call-context:2": RUNNING on thread "ktor-client-dispatcher-worker-1": RUNNING
findLoadedClass:1281, ClassLoader (java.lang)
loadClassOrNull:593, BuiltinClassLoader (jdk.internal.loader)
loadClass:579, BuiltinClassLoader (jdk.internal.loader)
loadClass:178, ClassLoaders$AppClassLoader (jdk.internal.loader)
loadClass:522, ClassLoader (java.lang)
ByteReadChannel:45, ByteChannelCtorKt (<http://io.ktor.utils.io|io.ktor.utils.io>)
respond:75, MockUtilsKt (io.ktor.client.engine.mock)
respond$default:73, MockUtilsKt (io.ktor.client.engine.mock)
invokeSuspend:37, MockHttpClientFactory$get$1$2$1 (com.careem.captain.common.networking.mockserver)
execute:61, MockEngine (io.ktor.client.engine.mock)
invokeSuspend:86, HttpClientEngine$executeWithinCallContext$2 (io.ktor.client.engine)
execute:61, MockEngine (io.ktor.client.engine.mock)
invokeSuspend:86, HttpClientEngine$executeWithinCallContext$2 (io.ktor.client.engine)
resumeWith:33, BaseContinuationImpl (kotlin.coroutines.jvm.internal)
run:106, DispatchedTask (kotlinx.coroutines)
runSafely:571, CoroutineScheduler (kotlinx.coroutines.scheduling)
executeTask:750, CoroutineScheduler$Worker (kotlinx.coroutines.scheduling)
runWorker:678, CoroutineScheduler$Worker (kotlinx.coroutines.scheduling)
run:665, CoroutineScheduler$Worker (kotlinx.coroutines.scheduling)
e5l
05/04/2021, 4:08 PMNikolay Kasyanov
05/04/2021, 4:08 PMe5l
05/04/2021, 4:08 PMCoroutineTimeout
for test to get test timeout for all hanging coroutinesNikolay Kasyanov
05/04/2021, 4:10 PMe5l
05/04/2021, 4:58 PMlouiscad
05/04/2021, 4:59 PMNikolay Kasyanov
05/04/2021, 5:00 PM