-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Closed as not planned
Closed as not planned
Copy link
Labels
Description
When using an UnconfinedTestDispatcher, the context element for a thread local is not restored when the coroutine is suspended.
Reproduction
import kotlin.coroutines.*
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.test.*
val MyThreadLocal = ThreadLocal<String>().apply { set("initial") }
@OptIn(ExperimentalCoroutinesApi::class)
fun main() = runTest(UnconfinedTestDispatcher()) {
val toResume = CompletableDeferred<Continuation<Unit>>()
launch {
println("Initial value: ${MyThreadLocal.get()}")
withContext(MyThreadLocal.asContextElement(value = "inContext")) {
println("in withContext: ${MyThreadLocal.get()}")
suspendCoroutine { co ->
toResume.complete(co)
}
}
println("after withContext: ${MyThreadLocal.get()}")
}
toResume.await().resume(Unit)
}Expected: "after withContext: initial"
Received: "after withContext: inContext"
NOTE: Removing (UnconfinedTestDispatcher()) from the test case above produces the expected result.
This seems related to #2930 and #4121 as the repro steps are similar.