https://kotlinlang.org logo
#coroutines
Title
# coroutines
c

Christophe Dongieux

03/02/2023, 8:18 PM
Hi! I don’t understand why this Coroutine test with delays fails, do you have any idea?
Copy code
@Test
fun `Foobar is foo`() = runTest {
    val job = launch {
        println("Coroutine 1: Going to sleep for 3000. currentTime = $currentTime")
        delay(3000)
        println("Coroutine 1: Delay is over. currentTime = $currentTime")
    }
    launch {
        println("Coroutine 2: Going to sleep for 1000. currentTime = $currentTime")
        delay(1000)
        println("Coroutine 2: Delay is over, cancelling other Coroutine. currentTime = $currentTime")
        job.cancel()
    }
    advanceTimeBy(500)
    println("advance 500: currentTime 1 = $currentTime")

    advanceTimeBy(500)
    println("advance 500: currentTime 2 = $currentTime")

    advanceUntilIdle()
    println("advanceUntilIdle: currentTime 3 = $currentTime")

    assertEquals(1000, currentTime)
}
The output is:
Copy code
Coroutine 1: Going to sleep for 3000. currentTime = 0
Coroutine 2: Going to sleep for 1000. currentTime = 0
advance 500: currentTime 1 = 500
advance 500: currentTime 2 = 1000
Coroutine 2: Delay is over, cancelling other Coroutine. currentTime = 1000
advanceUntilIdle: currentTime 3 = 3000

expected:<1000> but was:<3000>
Expected :1000
Actual   :3000
As Coroutine 1 is canceled I don’t understand why
currentTime 3
is 3000 instead of 1000.
m

mkrussel

03/02/2023, 8:29 PM
The call to
advanceUntilIdle
will advance the clock until all the current
delays
are completed, including the one for
3000
in the first launch.
c

Christophe Dongieux

03/02/2023, 8:31 PM
Yeah but it is cancelled after 1000. So it should be idle sooner than 3000, right?
m

mkrussel

03/02/2023, 8:33 PM
I've found in many cases just advancing the time doesn't make the coroutine wake up from
delay
, but instead I need to do
runCurrent
(not sure the name) after I do the
advanceTime
call.
c

Christophe Dongieux

03/02/2023, 8:40 PM
According to the output I pasted Coroutine 2 wakes up after its
delay(1000)
. And I can see Coroutine 1 is cancelled if I put a try/catch block around its
delay(3000)
.
m

mkrussel

03/02/2023, 8:41 PM
Might be a bug in the
advanceUntilIdle
function where it is still waiting for canceled delays.
c

Christophe Dongieux

03/02/2023, 8:48 PM
It seems someone reported the same problem here: https://kotlinlang.slack.com/archives/C1CFAFJSK/p1636822119273500
7 Views