Skip to content

Conversation

aSemy
Copy link
Contributor

@aSemy aSemy commented Jun 16, 2024

Use a test TimeSource in continually tests.

  • The test TimeSource uses a virtual time, so the tests run faster.
  • The elapsed duration is reproducible, so the tests can assert the specific elapsed time.
  • Use CoroutineContext to store & retrieve the TimeSource (This helps with testing both continually(duration) and continually(config) functions, and doesn't require adding an option in ContinuallyConfiguration)

Dependencies

aSemy added 6 commits June 15, 2024 11:40
TimeMarkCompat was only necessary because of a breaking change in Kotlin 1.7 - but that was 2 years ago and Kotest now requires more recent versions, so TimeMarkCompat can now be removed.

timeInMillis is only used for measuring times, so it can be replaced with stdlib `measureTime {}`/`measureTimedValue {}`
# Conflicts:
#	kotest-common/api/kotest-common.api
… they're pretty-printed using Duration#toString)
@aSemy aSemy force-pushed the adam/feat/use-test-timesource-in-continually-tests branch from b4cf86b to 28bf237 Compare June 16, 2024 07:38
Comment on lines 133 to 158
/**
* Store the [TimeSource] used by [continually].
*
* @see getContinuallyTimeSource
*/
internal class ContinuallyTimeSource(
val timeSource: TimeSource
) : CoroutineContext.Element {

override val key: CoroutineContext.Key<ContinuallyTimeSource>
get() = KEY

internal companion object {
/**
* Retrieves the [TimeSource] used by [continually].
*
* For internal Kotest testing purposes the [TimeSource] can be overridden.
* For normal usage [TimeSource.Monotonic] is used.
*/
internal suspend fun getContinuallyTimeSource(): TimeSource =
coroutineContext[KEY]?.timeSource
?: TimeSource.Monotonic

internal val KEY = object : CoroutineContext.Key<ContinuallyTimeSource> {}
}
}
Copy link
Contributor Author

@aSemy aSemy Jun 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the 'retry' tests PR #4101 I added a val timeSource to the RetryConfig.

Here I'm trying a different approach and storing the TimeSource in the CoroutineContext.

I think using the CoroutineContext is better, because it makes it easier to test any continually() functions without modifying the ABI, and it doesn't expose any options for users (even the option is guarded with @KotestInternal).

I'd like to revisit the retry tests, and refactor the eventually tests, to do the same.

"Test failed after \\d+ms; expected to pass for 3000ms; attempted 100 times\nUnderlying failure was: 100 should be < 100".toRegex()
e.message?.matches(r) ?: (false shouldBe true)
n shouldBe 11
failure shouldHaveMessage "Test failed after 360ms; expected to pass for 3s; attempted 10 times\nUnderlying failure was: expected:<true> but was:<false>"
Copy link
Contributor Author

@aSemy aSemy Jun 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor note: previously the regex assertion wasn't triggered, and wasn't correct.

I changed the expected message from Underlying failure was: 100 should be < 100 to Underlying failure was: 10 should be < 10.

@aSemy aSemy mentioned this pull request Jun 16, 2024
20 tasks
aSemy added 2 commits June 16, 2024 23:41
# Conflicts:
#	kotest-assertions/kotest-assertions-core/src/jvmTest/kotlin/io/kotest/assertions/nondeterministic/EventuallyTest.kt
#	kotest-assertions/kotest-assertions-shared/src/jvmTest/kotlin/com/sksamuel/kotest/assertions/until/UntilTest.kt
- The test TimeSource uses a virtual time, so the tests run faster.
- The elapsed duration is reproducible, so the tests can assert the specific elapsed time.
- Use CoroutineContext to store & retrieve the TimeSource (This helps with testing both `continually(duration)` and `continually(config)` functions, and doesn't require adding an option in `ContinuallyConfiguration`)
@aSemy aSemy force-pushed the adam/feat/use-test-timesource-in-continually-tests branch from 28bf237 to 7c8ebc6 Compare June 17, 2024 14:20
…n-continually-tests

# Conflicts:
#	kotest-assertions/kotest-assertions-core/src/commonMain/kotlin/io/kotest/assertions/nondeterministic/continually.kt
#	kotest-assertions/kotest-assertions-core/src/jvmTest/kotlin/io/kotest/assertions/nondeterministic/ContinuallyTest.kt
@aSemy aSemy marked this pull request as ready for review June 17, 2024 14:22
Copy link
Contributor

@OliverO2 OliverO2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing import. Style consideration optional. Otherwise looks good!

@aSemy aSemy merged commit 40da799 into master Jun 17, 2024
@aSemy aSemy deleted the adam/feat/use-test-timesource-in-continually-tests branch June 17, 2024 21:38
aSemy added a commit that referenced this pull request Jun 21, 2024
Use a test TimeSource in `eventually` tests.

- The test TimeSource uses a virtual time, so the tests run faster.
- The elapsed duration is reproducible, so the tests can assert the
specific elapsed time.
- Use CoroutineContext to store & retrieve the TimeSource (This helps
with testing both `eventually(duration)` and `eventually(config)`
functions, and doesn't require adding an option in
`EventuallyConfiguration`)


Depends on: #4105 

Related: #4109

---------

Co-authored-by: OliverO2 <Oliver.O456i@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants