Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TestCoroutineScheduler: Make it a TimeSource #3086

Closed
hfhbd opened this issue Dec 15, 2021 · 1 comment
Closed

TestCoroutineScheduler: Make it a TimeSource #3086

hfhbd opened this issue Dec 15, 2021 · 1 comment
Assignees
Labels

Comments

@hfhbd
Copy link
Contributor

hfhbd commented Dec 15, 2021

Already todo, and is very useful to avoid manually increasing TestTimeSource
Use case:
testing timebased caching, timed retries, windowing, date time apis (using Clock)

class TimeCache(val timeSource: TimeSource = TimeSource.Monotonic, val valid: Duration = 1.seconds) {
    private var counter = 0
    private var cache: Data? = null

    suspend fun get(): Data {
        if (cache != null && cache!!.requestAt.elapsedNow() < valid) {
            return cache!!
        }
        cache = null
        return requestServer().also {
            cache = it
        }
    }

    private suspend fun requestServer(): Data {
        delay(3.seconds)
        return Data(counter.also { counter += 1 }, timeSource.markNow())
    }
}

data class Data(val data: Int, val requestAt: TimeMark)

@Test
fun blockingImprecise() = runBlocking {
    val cache = TimeCache()
    assertEquals(0, cache.get().data)
    delay(2.seconds)
    assertEquals(1, cache.get().data)
    delay(0.5.seconds)
    assertEquals(1, cache.get().data)
}

@Test
fun blockingManuallyPrecise() = runBlocking {
    val ts = TestTimeSource()
    val cache = TimeCache(ts)
    assertEquals(0, cache.get().data)
    delay(2.seconds)
    ts += 2.seconds
    assertEquals(1, cache.get().data)
    delay(0.5.seconds)
    ts += 0.5.seconds
    assertEquals(1, cache.get().data)
}

@Test
fun skippingManuallyPrecise() = runTest {
    val ts = TestTimeSource()
    val cache = TimeCache(ts)
    assertEquals(0, cache.get().data)
    delay(2.seconds)
    ts += 2.seconds
    assertEquals(1, cache.get().data)
    delay(0.5.seconds)
    ts += 0.5.seconds
    assertEquals(1, cache.get().data)
}

@Test
fun expectedPrecise() = runTest {
    val cache = TimeCache(timeSource)
    assertEquals(0, cache.get().data)
    delay(2.seconds)
    assertEquals(1, cache.get().data)
    delay(0.5.seconds)
    assertEquals(1, cache.get().data)
}

private val TestScope.timeSource: TimeSource get() = object : AbstractLongTimeSource(DurationUnit.MILLISECONDS) {
    override fun read(): Long = currentTime
}
@dkhalanskyjb
Copy link
Collaborator

Fixed in 1.6.0-RC3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants