Fix race condition in `testFutureIsDoneAfterChildrenCompleted` (#4165)
The `foo` coroutine could be cancelled before it's started, which
would immediately trigger the `expect(3)` in `foo.invokeOnCompletion`.
This could happen before `expect(2)` and fail the test.
diff --git a/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt b/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt
index a873206..e8625dc 100644
--- a/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt
+++ b/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt
@@ -627,16 +627,15 @@
fun testFutureIsDoneAfterChildrenCompleted() = runTest {
expect(1)
val testException = TestException()
+ val latch = CountDownLatch(1)
// Don't propagate exception to the test and use different dispatchers as we are going to block test thread.
val future = future(context = NonCancellable + Dispatchers.Default) {
- val foo = async {
+ val foo = async(start = CoroutineStart.UNDISPATCHED) {
try {
delay(Long.MAX_VALUE)
42
} finally {
- withContext(NonCancellable) {
- delay(200)
- }
+ latch.await()
}
}
foo.invokeOnCompletion {
@@ -647,6 +646,7 @@
}
yield()
expect(2)
+ latch.countDown()
// Blocking get should succeed after internal coroutine completes.
val thrown = assertFailsWith<ExecutionException> { future.get() }
expect(4)