Skip to content

TestTimeSource/currentTime does not increase after switching to a non-delay skipping Dispatcher #4045

Open
@hfhbd

Description

@hfhbd

Describe the bug

The time source or the underlaying currentTime is not updated after switching the context to a non delay skipping dispatcher.

Our use-case: Ktor
We want to change Ktors public test framework testApplication from runBlocking to runTest, including its delay skipping behavior in tests, to align with the common test behavior of the well-known coroutines-test api.
But if the test contains a request to an external real server, Ktor executes the test on Dispatchers.Default/IO and uses a real-time clock to not mess up http connections, eg TLS handshakes.
After the request, the virtual time should be used again for user tests, but the virtual time isn't increased after the switch. This is confusing because in fact the time was increased.
It also does not work with custom user plugins testing with which could be part of the user tests, resulting into different times, see timeSource test as an example.

Provide a Reproducer

@Test
fun clock() = runTest {
  assertEquals(0, currentTime)
  delay(1.seconds)
  assertEquals(1000, currentTime)
        
  withContext(Dispatchers.IO) {
    delay(2.seconds)
  }
        
  assertEquals(3000, currentTime) // fails: expected 3000, actual 1000
  delay(1.seconds)
  assertEquals(4000, currentTime)
}

@Test
fun timeSource() = runTest {
  val timeSource = testScheduler.timeSource
  val now = timeSource.markNow()
  assertEquals(0.seconds, now.elapsedNow())
  delay(1.seconds)
  assertEquals(1.seconds, now.elapsedNow())

  val time = measureTime {
  withContext(Dispatchers.IO) {
    delay(2.seconds)
    }
  }
  assertTrue(time in (2.seconds)..(2.1.seconds))

  assertEquals(1.seconds + time, now.elapsedNow()) // fails: expected 3s, actual 1s
  delay(1.seconds)
  assertEquals(2.seconds + time, now.elapsedNow())
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions