diff --git a/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt b/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt index 511b1b0322..1eac741145 100644 --- a/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt +++ b/integration/kotlinx-coroutines-guava/test/ListenableFutureTest.kt @@ -749,7 +749,7 @@ class ListenableFutureTest : TestBase() { } } future.set(1) - withTimeout(60_000) { + kotlinx.coroutines.time.withTimeout(60_000) { children.forEach { it.join() } assertEquals(count, completed.get()) } diff --git a/kotlinx-coroutines-core/common/src/JobSupport.kt b/kotlinx-coroutines-core/common/src/JobSupport.kt index 2950ed9814..7dcf21e5f2 100644 --- a/kotlinx-coroutines-core/common/src/JobSupport.kt +++ b/kotlinx-coroutines-core/common/src/JobSupport.kt @@ -8,6 +8,7 @@ package kotlinx.coroutines import kotlinx.atomicfu.* import kotlinx.coroutines.internal.* import kotlinx.coroutines.selects.* +import kotlinx.coroutines.time.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* import kotlin.js.* @@ -260,6 +261,7 @@ public open class JobSupport constructor(active: Boolean) : Job, ChildJob, Paren val firstNonCancellation = exceptions.firstOrNull { it !is CancellationException } if (firstNonCancellation != null) return firstNonCancellation val first = exceptions[0] + @Suppress("DEPRECATION") if (first is TimeoutCancellationException) { val detailedTimeoutException = exceptions.firstOrNull { it !== first && it is TimeoutCancellationException } if (detailedTimeoutException != null) return detailedTimeoutException diff --git a/kotlinx-coroutines-core/common/src/Timeout.kt b/kotlinx-coroutines-core/common/src/Timeout.kt index aea57546a1..b6f6c88bc2 100644 --- a/kotlinx-coroutines-core/common/src/Timeout.kt +++ b/kotlinx-coroutines-core/common/src/Timeout.kt @@ -2,9 +2,11 @@ * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. */ @file:OptIn(ExperimentalContracts::class) +@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") package kotlinx.coroutines +import kotlin.internal.* import kotlinx.coroutines.internal.* import kotlinx.coroutines.intrinsics.* import kotlinx.coroutines.selects.* @@ -36,10 +38,17 @@ import kotlin.time.* * * @param timeMillis timeout time in milliseconds. */ +@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") +@LowPriorityInOverloadResolution +@Deprecated("Use withTimeout from the 'kotlinx-coroutines-time' package instead.", + ReplaceWith("kotlinx.coroutines.time.withTimeout(timeMillis, block)", + "kotlinx.coroutines.time"), + level = DeprecationLevel.WARNING) public suspend fun withTimeout(timeMillis: Long, block: suspend CoroutineScope.() -> T): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } + @Suppress("DEPRECATION") if (timeMillis <= 0L) throw TimeoutCancellationException("Timed out immediately") return suspendCoroutineUninterceptedOrReturn { uCont -> setupTimeout(TimeoutCoroutine(timeMillis, uCont), block) @@ -66,11 +75,17 @@ public suspend fun withTimeout(timeMillis: Long, block: suspend CoroutineSco * * > Implementation note: how the time is tracked exactly is an implementation detail of the context's [CoroutineDispatcher]. */ +@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") +@LowPriorityInOverloadResolution +@Deprecated("Use withTimeout from the 'kotlinx-coroutines-time' package instead.", + ReplaceWith("kotlinx.coroutines.time.withTimeout(timeout, block)", + "kotlinx.coroutines.time"), + level = DeprecationLevel.WARNING) public suspend fun withTimeout(timeout: Duration, block: suspend CoroutineScope.() -> T): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return withTimeout(timeout.toDelayMillis(), block) + return kotlinx.coroutines.time.withTimeout(timeout.toDelayMillis(), block) } /** @@ -99,6 +114,7 @@ public suspend fun withTimeoutOrNull(timeMillis: Long, block: suspend Corout if (timeMillis <= 0L) return null var coroutine: TimeoutCoroutine? = null + @Suppress("DEPRECATION") try { return suspendCoroutineUninterceptedOrReturn { uCont -> val timeoutCoroutine = TimeoutCoroutine(timeMillis, uCont) @@ -165,6 +181,11 @@ private class TimeoutCoroutine( /** * This exception is thrown by [withTimeout] to indicate timeout. */ +@Deprecated("Use TimeoutException from the 'kotlinx-coroutines-time' package instead.", + ReplaceWith("kotlinx.coroutines.time.TimeoutException", + "kotlinx.coroutines.time"), + level = DeprecationLevel.WARNING) +@Suppress("DEPRECATION") public class TimeoutCancellationException internal constructor( message: String, @JvmField @Transient internal val coroutine: Job? @@ -181,6 +202,7 @@ public class TimeoutCancellationException internal constructor( TimeoutCancellationException(message ?: "", coroutine).also { it.initCause(this) } } +@Suppress("DEPRECATION") internal fun TimeoutCancellationException( time: Long, coroutine: Job diff --git a/kotlinx-coroutines-core/common/src/flow/operators/Delay.kt b/kotlinx-coroutines-core/common/src/flow/operators/Delay.kt index 738fef79be..c68322d29d 100644 --- a/kotlinx-coroutines-core/common/src/flow/operators/Delay.kt +++ b/kotlinx-coroutines-core/common/src/flow/operators/Delay.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.* import kotlinx.coroutines.channels.* import kotlinx.coroutines.flow.internal.* import kotlinx.coroutines.selects.* +import kotlinx.coroutines.time.* import kotlin.jvm.* import kotlin.time.* @@ -346,7 +347,7 @@ internal fun CoroutineScope.fixedPeriodTicker(delayMillis: Long, initialDelayMil public fun Flow.sample(period: Duration): Flow = sample(period.toDelayMillis()) /** - * Returns a flow that will emit a [TimeoutCancellationException] if the upstream doesn't emit an item within the given time. + * Returns a flow that will emit a [TimeoutException] if the upstream doesn't emit an item within the given time. * * Example: * @@ -386,7 +387,7 @@ public fun Flow.timeout( private fun Flow.timeoutInternal( timeout: Duration ): Flow = scopedFlow { downStream -> - if (timeout <= Duration.ZERO) throw TimeoutCancellationException("Timed out immediately") + if (timeout <= Duration.ZERO) throw TimeoutException("Timed out immediately") val values = buffer(Channel.RENDEZVOUS).produceIn(this) whileSelect { values.onReceiveCatching { value -> @@ -398,7 +399,7 @@ private fun Flow.timeoutInternal( return@onReceiveCatching true } onTimeout(timeout) { - throw TimeoutCancellationException("Timed out waiting for $timeout") + throw TimeoutException("Timed out waiting for $timeout") } } } diff --git a/kotlinx-coroutines-core/common/src/intrinsics/Undispatched.kt b/kotlinx-coroutines-core/common/src/intrinsics/Undispatched.kt index 38e870ef9c..072dbc7fd0 100644 --- a/kotlinx-coroutines-core/common/src/intrinsics/Undispatched.kt +++ b/kotlinx-coroutines-core/common/src/intrinsics/Undispatched.kt @@ -6,6 +6,7 @@ package kotlinx.coroutines.intrinsics import kotlinx.coroutines.* import kotlinx.coroutines.internal.* +import kotlinx.coroutines.time.* import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* @@ -26,7 +27,7 @@ internal fun (suspend () -> T).startCoroutineUnintercepted(completion: Conti * It does not use [ContinuationInterceptor] and does not update the context of the current thread. */ internal fun (suspend (R) -> T).startCoroutineUnintercepted(receiver: R, completion: Continuation) { - startDirect(completion) { actualCompletion -> + startDirect(completion) { actualCompletion -> startCoroutineUninterceptedOrReturn(receiver, actualCompletion) } } @@ -96,7 +97,22 @@ internal fun ScopeCoroutine.startUndispatchedOrReturn(receiver: R, blo internal fun ScopeCoroutine.startUndispatchedOrReturnIgnoreTimeout( receiver: R, block: suspend R.() -> T ): Any? { - return undispatchedResult({ e -> !(e is TimeoutCancellationException && e.coroutine === this) }) { + return undispatchedResult({ e -> + @Suppress("DEPRECATION") !(e is TimeoutCancellationException && e.coroutine === this) + }) { + block.startCoroutineUninterceptedOrReturn(receiver, this) + } +} + +/** + * Same as [startUndispatchedOrReturn], but ignores [TimeoutException] on fast-path. + */ +internal fun ScopeCoroutine.startUndispatchedOrReturnIgnoreNewTimeout( + receiver: R, block: suspend R.() -> T +): Any? { + return undispatchedResult({ e -> + !(e is TimeoutException && e.coroutine === this) + }) { block.startCoroutineUninterceptedOrReturn(receiver, this) } } diff --git a/kotlinx-coroutines-core/common/src/time/Timeout.kt b/kotlinx-coroutines-core/common/src/time/Timeout.kt new file mode 100644 index 0000000000..e35f9eaf36 --- /dev/null +++ b/kotlinx-coroutines-core/common/src/time/Timeout.kt @@ -0,0 +1,125 @@ +/* + * Copyright 2016-2022 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + +@file:OptIn(ExperimentalContracts::class) + +package kotlinx.coroutines.time + +import kotlinx.coroutines.* +import kotlinx.coroutines.internal.* +import kotlinx.coroutines.intrinsics.* +import kotlinx.coroutines.selects.* +import kotlin.contracts.* +import kotlin.coroutines.* +import kotlin.coroutines.intrinsics.* +import kotlin.jvm.* +import kotlin.time.* + +/** + * Runs a given suspending [block] of code inside a coroutine with a specified [timeout][timeMillis] and throws + * a [TimeoutException] if the timeout was exceeded. + * If the given [timeMillis] is non-positive, [TimeoutException] is thrown immediately. + * + * The code that is executing inside the [block] is cancelled on timeout and the active or next invocation of + * the cancellable suspending function inside the block throws a [TimeoutException]. + * + * The sibling function that does not throw an exception on timeout is [withTimeoutOrNull]. + * Note that the timeout action can be specified for a [select] invocation with [onTimeout][SelectBuilder.onTimeout] clause. + * + * **The timeout event is asynchronous with respect to the code running in the block** and may happen at any time, + * even right before the return from inside the timeout [block]. Keep this in mind if you open or acquire some + * resource inside the [block] that needs closing or release outside the block. + * See the + * [Asynchronous timeout and resources][https://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html#asynchronous-timeout-and-resources] + * section of the coroutines guide for details. + * + * > Implementation note: how the time is tracked exactly is an implementation detail of the context's [CoroutineDispatcher]. + * + * @param timeMillis timeout time in milliseconds. + */ +public suspend fun withTimeout(timeMillis: Long, block: suspend CoroutineScope.() -> T): T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + if (timeMillis <= 0L) throw TimeoutException("Timed out immediately") + return suspendCoroutineUninterceptedOrReturn { uCont -> + setupTimeout(TimeoutCoroutine(timeMillis, uCont), block) + } +} + +/** + * Runs a given suspending [block] of code inside a coroutine with the specified [timeout] and throws + * a [TimeoutException] if the timeout was exceeded. + * If the given [timeout] is non-positive, [TimeoutException] is thrown immediately. + * + * The code that is executing inside the [block] is cancelled on timeout and the active or next invocation of + * the cancellable suspending function inside the block throws a [TimeoutException]. + * + * The sibling function that does not throw an exception on timeout is [withTimeoutOrNull]. + * Note that the timeout action can be specified for a [select] invocation with [onTimeout][SelectBuilder.onTimeout] clause. + * + * **The timeout event is asynchronous with respect to the code running in the block** and may happen at any time, + * even right before the return from inside the timeout [block]. Keep this in mind if you open or acquire some + * resource inside the [block] that needs closing or release outside the block. + * See the + * [Asynchronous timeout and resources][https://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html#asynchronous-timeout-and-resources] + * section of the coroutines guide for details. + * + * > Implementation note: how the time is tracked exactly is an implementation detail of the context's [CoroutineDispatcher]. + */ +public suspend fun withTimeout(timeout: Duration, block: suspend CoroutineScope.() -> T): T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return withTimeout(timeout.toDelayMillis(), block) +} + +private fun setupTimeout( + coroutine: TimeoutCoroutine, + block: suspend CoroutineScope.() -> T +): Any? { + // schedule cancellation of this coroutine on time + val cont = coroutine.uCont + val context = cont.context + coroutine.disposeOnCompletion(context.delay.invokeOnTimeout(coroutine.time, coroutine, coroutine.context)) + // restart the block using a new coroutine with a new job, + // however, start it undispatched, because we already are in the proper context + return coroutine.startUndispatchedOrReturnIgnoreNewTimeout(coroutine, block) +} + +private class TimeoutCoroutine( + @JvmField val time: Long, + uCont: Continuation // unintercepted continuation +) : ScopeCoroutine(uCont.context, uCont), Runnable { + override fun run() { + cancelCoroutine(TimeoutException(time, this)) + } + + override fun nameString(): String = + "${super.nameString()}(timeMillis=$time)" +} + +/** + * This exception is thrown by [withTimeout] to indicate timeout. + */ +public class TimeoutException internal constructor( + message: String, + @JvmField @Transient internal val coroutine: Job? +): IllegalStateException(message), CopyableThrowable { + /** + * Creates a timeout exception with the given message. + * This constructor is needed for exception stack-traces recovery. + */ + @Suppress("UNUSED") + internal constructor(message: String) : this(message, null) + + // message is never null in fact + override fun createCopy(): TimeoutException = + TimeoutException(message ?: "", coroutine).also { it.initCause(this) } +} + +internal fun TimeoutException( + time: Long, + coroutine: Job +) : TimeoutException = TimeoutException("Timed out waiting for $time ms", coroutine) diff --git a/kotlinx-coroutines-core/common/test/BuilderContractsTest.kt b/kotlinx-coroutines-core/common/test/BuilderContractsTest.kt index 5a96c54460..853494c8cd 100644 --- a/kotlinx-coroutines-core/common/test/BuilderContractsTest.kt +++ b/kotlinx-coroutines-core/common/test/BuilderContractsTest.kt @@ -34,7 +34,7 @@ class BuilderContractsTest : TestBase() { consume(wctx) val wt: Int - withTimeout(Long.MAX_VALUE) { + kotlinx.coroutines.time.withTimeout(Long.MAX_VALUE) { wt = 123 } consume(wt) diff --git a/kotlinx-coroutines-core/common/test/CancelledParentAttachTest.kt b/kotlinx-coroutines-core/common/test/CancelledParentAttachTest.kt index 9dd61b8012..be75dc221e 100644 --- a/kotlinx-coroutines-core/common/test/CancelledParentAttachTest.kt +++ b/kotlinx-coroutines-core/common/test/CancelledParentAttachTest.kt @@ -96,7 +96,7 @@ class CancelledParentAttachTest : TestBase() { testScope { coroutineScope { } } testScope { supervisorScope { } } testScope { flowScope { } } - testScope { withTimeout(Long.MAX_VALUE) { } } + testScope { kotlinx.coroutines.time.withTimeout(Long.MAX_VALUE) { } } testScope { withContext(Job()) { } } testScope { withContext(CoroutineName("")) { } } } diff --git a/kotlinx-coroutines-core/common/test/ParentCancellationTest.kt b/kotlinx-coroutines-core/common/test/ParentCancellationTest.kt index 96c5cf3f4f..8f87252798 100644 --- a/kotlinx-coroutines-core/common/test/ParentCancellationTest.kt +++ b/kotlinx-coroutines-core/common/test/ParentCancellationTest.kt @@ -90,7 +90,7 @@ class ParentCancellationTest : TestBase() { @Test fun testWithTimeoutChild() = runTest { testParentCancellation(expectParentActive = true, expectRethrows = true, runsInScopeContext = true) { fail -> - withTimeout(1000) { fail() } + kotlinx.coroutines.time.withTimeout(1000) { fail() } } } @@ -168,4 +168,4 @@ class ParentCancellationTest : TestBase() { } finish(3) } -} \ No newline at end of file +} diff --git a/kotlinx-coroutines-core/common/test/UndispatchedResultTest.kt b/kotlinx-coroutines-core/common/test/UndispatchedResultTest.kt index 34b8164472..80159d995f 100644 --- a/kotlinx-coroutines-core/common/test/UndispatchedResultTest.kt +++ b/kotlinx-coroutines-core/common/test/UndispatchedResultTest.kt @@ -21,7 +21,7 @@ class UndispatchedResultTest : TestBase() { @Test fun testWithTimeout() = runTest { - invokeTest { block -> withTimeout(Long.MAX_VALUE, block) } + invokeTest { block -> kotlinx.coroutines.time.withTimeout(Long.MAX_VALUE, block) } } @Test diff --git a/kotlinx-coroutines-core/common/test/WithTimeoutDurationTest.kt b/kotlinx-coroutines-core/common/test/WithTimeoutDurationTest.kt index 60e64f5830..f54e3212cd 100644 --- a/kotlinx-coroutines-core/common/test/WithTimeoutDurationTest.kt +++ b/kotlinx-coroutines-core/common/test/WithTimeoutDurationTest.kt @@ -6,6 +6,7 @@ package kotlinx.coroutines +import kotlinx.coroutines.time.* import kotlin.test.* import kotlin.time.* import kotlin.time.Duration.Companion.milliseconds @@ -18,7 +19,7 @@ class WithTimeoutDurationTest : TestBase() { @Test fun testBasicNoSuspend() = runTest { expect(1) - val result = withTimeout(10.seconds) { + val result = kotlinx.coroutines.time.withTimeout(10.seconds) { expect(2) "OK" } @@ -32,7 +33,7 @@ class WithTimeoutDurationTest : TestBase() { @Test fun testBasicSuspend() = runTest { expect(1) - val result = withTimeout(10.seconds) { + val result = kotlinx.coroutines.time.withTimeout(10.seconds) { expect(2) yield() expect(3) @@ -55,7 +56,7 @@ class WithTimeoutDurationTest : TestBase() { } expect(2) // test that it does not yield to the above job when started - val result = withTimeout(1.seconds) { + val result = kotlinx.coroutines.time.withTimeout(1.seconds) { expect(3) yield() // yield only now expect(5) @@ -73,9 +74,9 @@ class WithTimeoutDurationTest : TestBase() { */ @Test fun testYieldBlockingWithTimeout() = runTest( - expected = { it is CancellationException } + expected = { it is TimeoutException } ) { - withTimeout(100.milliseconds) { + kotlinx.coroutines.time.withTimeout(100.milliseconds) { while (true) { yield() } @@ -88,7 +89,7 @@ class WithTimeoutDurationTest : TestBase() { @Test fun testWithTimeoutChildWait() = runTest { expect(1) - withTimeout(100.milliseconds) { + kotlinx.coroutines.time.withTimeout(100.milliseconds) { expect(2) // launch child with timeout launch { @@ -103,7 +104,7 @@ class WithTimeoutDurationTest : TestBase() { @Test fun testBadClass() = runTest { val bad = BadClass() - val result = withTimeout(100.milliseconds) { + val result = kotlinx.coroutines.time.withTimeout(100.milliseconds) { bad } assertSame(bad, result) @@ -119,13 +120,13 @@ class WithTimeoutDurationTest : TestBase() { fun testExceptionOnTimeout() = runTest { expect(1) try { - withTimeout(100.milliseconds) { + kotlinx.coroutines.time.withTimeout(100.milliseconds) { expect(2) delay(1000.milliseconds) expectUnreached() "OK" } - } catch (e: CancellationException) { + } catch (e: TimeoutException) { assertEquals("Timed out waiting for 100 ms", e.message) finish(3) } @@ -133,10 +134,10 @@ class WithTimeoutDurationTest : TestBase() { @Test fun testSuppressExceptionWithResult() = runTest( - expected = { it is CancellationException } + expected = { it is TimeoutException } ) { expect(1) - withTimeout(100.milliseconds) { + kotlinx.coroutines.time.withTimeout(100.milliseconds) { expect(2) try { delay(1000.milliseconds) @@ -152,11 +153,11 @@ class WithTimeoutDurationTest : TestBase() { fun testSuppressExceptionWithAnotherException() = runTest { expect(1) try { - withTimeout(100.milliseconds) { + kotlinx.coroutines.time.withTimeout(100.milliseconds) { expect(2) try { delay(1000.milliseconds) - } catch (e: CancellationException) { + } catch (e: TimeoutException) { expect(3) throw TestException() } @@ -173,11 +174,11 @@ class WithTimeoutDurationTest : TestBase() { fun testNegativeTimeout() = runTest { expect(1) try { - withTimeout(-1.milliseconds) { + kotlinx.coroutines.time.withTimeout(-1.milliseconds) { expectUnreached() "OK" } - } catch (e: TimeoutCancellationException) { + } catch (e: TimeoutException) { assertEquals("Timed out immediately", e.message) finish(2) } @@ -188,7 +189,7 @@ class WithTimeoutDurationTest : TestBase() { expect(1) try { expect(2) - withTimeout(1.seconds) { + kotlinx.coroutines.time.withTimeout(1.seconds) { expect(3) throw TestException() } @@ -201,7 +202,7 @@ class WithTimeoutDurationTest : TestBase() { @Test fun testIncompleteWithTimeoutState() = runTest { lateinit var timeoutJob: Job - val handle = withTimeout(Duration.INFINITE) { + val handle = kotlinx.coroutines.time.withTimeout(Duration.INFINITE) { timeoutJob = coroutineContext[Job]!! timeoutJob.invokeOnCompletion { } } diff --git a/kotlinx-coroutines-core/common/test/WithTimeoutOrNullDurationTest.kt b/kotlinx-coroutines-core/common/test/WithTimeoutOrNullDurationTest.kt index 1f9ad46f47..944565af36 100644 --- a/kotlinx-coroutines-core/common/test/WithTimeoutOrNullDurationTest.kt +++ b/kotlinx-coroutines-core/common/test/WithTimeoutOrNullDurationTest.kt @@ -8,6 +8,7 @@ package kotlinx.coroutines import kotlinx.coroutines.channels.* +import kotlinx.coroutines.time.* import kotlin.test.* import kotlin.time.* import kotlin.time.Duration.Companion.milliseconds @@ -102,10 +103,10 @@ class WithTimeoutOrNullDurationTest : TestBase() { @Test fun testInnerTimeout() = runTest( - expected = { it is CancellationException } + expected = { it is TimeoutException } ) { withTimeoutOrNull(1000.milliseconds) { - withTimeout(10.milliseconds) { + kotlinx.coroutines.time.withTimeout(10.milliseconds) { while (true) { yield() } @@ -117,10 +118,10 @@ class WithTimeoutOrNullDurationTest : TestBase() { } @Test - fun testNestedTimeout() = runTest(expected = { it is TimeoutCancellationException }) { + fun testNestedTimeout() = runTest(expected = { it is TimeoutException }) { withTimeoutOrNull(Duration.INFINITE) { // Exception from this withTimeout is not suppressed by withTimeoutOrNull - withTimeout(10.milliseconds) { + kotlinx.coroutines.time.withTimeout(10.milliseconds) { delay(Duration.INFINITE) 1 } @@ -183,7 +184,7 @@ class WithTimeoutOrNullDurationTest : TestBase() { expect(2) try { delay(1000.milliseconds) - } catch (e: CancellationException) { + } catch (e: TimeoutException) { expect(3) } "OK" @@ -200,7 +201,7 @@ class WithTimeoutOrNullDurationTest : TestBase() { expect(2) try { delay(1000.milliseconds) - } catch (e: CancellationException) { + } catch (e: TimeoutException) { expect(3) throw TestException() } diff --git a/kotlinx-coroutines-core/common/test/WithTimeoutOrNullTest.kt b/kotlinx-coroutines-core/common/test/WithTimeoutOrNullTest.kt index 5ab8ae7df9..747b6500d5 100644 --- a/kotlinx-coroutines-core/common/test/WithTimeoutOrNullTest.kt +++ b/kotlinx-coroutines-core/common/test/WithTimeoutOrNullTest.kt @@ -8,6 +8,7 @@ package kotlinx.coroutines import kotlinx.coroutines.channels.* +import kotlinx.coroutines.time.* import kotlin.test.* class WithTimeoutOrNullTest : TestBase() { @@ -99,10 +100,10 @@ class WithTimeoutOrNullTest : TestBase() { @Test fun testInnerTimeout() = runTest( - expected = { it is CancellationException } + expected = { it is TimeoutException } ) { withTimeoutOrNull(1000) { - withTimeout(10) { + kotlinx.coroutines.time.withTimeout(10) { while (true) { yield() } @@ -114,10 +115,10 @@ class WithTimeoutOrNullTest : TestBase() { } @Test - fun testNestedTimeout() = runTest(expected = { it is TimeoutCancellationException }) { + fun testNestedTimeout() = runTest(expected = { it is TimeoutException }) { withTimeoutOrNull(Long.MAX_VALUE) { // Exception from this withTimeout is not suppressed by withTimeoutOrNull - withTimeout(10) { + kotlinx.coroutines.time.withTimeout(10) { delay(Long.MAX_VALUE) 1 } @@ -174,7 +175,7 @@ class WithTimeoutOrNullTest : TestBase() { expect(2) try { delay(1000) - } catch (e: CancellationException) { + } catch (e: TimeoutException) { expect(3) } "OK" @@ -191,7 +192,7 @@ class WithTimeoutOrNullTest : TestBase() { expect(2) try { delay(1000) - } catch (e: CancellationException) { + } catch (e: TimeoutException) { expect(3) throw TestException() } diff --git a/kotlinx-coroutines-core/common/test/WithTimeoutTest.kt b/kotlinx-coroutines-core/common/test/WithTimeoutTest.kt index 8462c96953..305dcb8410 100644 --- a/kotlinx-coroutines-core/common/test/WithTimeoutTest.kt +++ b/kotlinx-coroutines-core/common/test/WithTimeoutTest.kt @@ -7,6 +7,7 @@ package kotlinx.coroutines +import kotlinx.coroutines.time.* import kotlin.test.* class WithTimeoutTest : TestBase() { @@ -16,7 +17,7 @@ class WithTimeoutTest : TestBase() { @Test fun testBasicNoSuspend() = runTest { expect(1) - val result = withTimeout(10_000) { + val result = kotlinx.coroutines.time.withTimeout(10_000) { expect(2) "OK" } @@ -30,7 +31,7 @@ class WithTimeoutTest : TestBase() { @Test fun testBasicSuspend() = runTest { expect(1) - val result = withTimeout(10_000) { + val result = kotlinx.coroutines.time.withTimeout(10_000) { expect(2) yield() expect(3) @@ -53,7 +54,7 @@ class WithTimeoutTest : TestBase() { } expect(2) // test that it does not yield to the above job when started - val result = withTimeout(1000) { + val result = kotlinx.coroutines.time.withTimeout(1000) { expect(3) yield() // yield only now expect(5) @@ -71,9 +72,9 @@ class WithTimeoutTest : TestBase() { */ @Test fun testYieldBlockingWithTimeout() = runTest( - expected = { it is CancellationException } + expected = { it is TimeoutException } ) { - withTimeout(100) { + kotlinx.coroutines.time.withTimeout(100) { while (true) { yield() } @@ -86,7 +87,7 @@ class WithTimeoutTest : TestBase() { @Test fun testWithTimeoutChildWait() = runTest { expect(1) - withTimeout(100) { + kotlinx.coroutines.time.withTimeout(100) { expect(2) // launch child with timeout launch { @@ -101,7 +102,7 @@ class WithTimeoutTest : TestBase() { @Test fun testBadClass() = runTest { val bad = BadClass() - val result = withTimeout(100) { + val result = kotlinx.coroutines.time.withTimeout(100) { bad } assertSame(bad, result) @@ -111,13 +112,13 @@ class WithTimeoutTest : TestBase() { fun testExceptionOnTimeout() = runTest { expect(1) try { - withTimeout(100) { + kotlinx.coroutines.time.withTimeout(100) { expect(2) delay(1000) expectUnreached() "OK" } - } catch (e: CancellationException) { + } catch (e: TimeoutException) { assertEquals("Timed out waiting for 100 ms", e.message) finish(3) } @@ -125,14 +126,14 @@ class WithTimeoutTest : TestBase() { @Test fun testSuppressExceptionWithResult() = runTest( - expected = { it is CancellationException } + expected = { it is TimeoutException } ) { expect(1) - withTimeout(100) { + kotlinx.coroutines.time.withTimeout(100) { expect(2) try { delay(1000) - } catch (e: CancellationException) { + } catch (e: TimeoutException) { finish(3) } "OK" @@ -144,11 +145,11 @@ class WithTimeoutTest : TestBase() { fun testSuppressExceptionWithAnotherException() = runTest{ expect(1) try { - withTimeout(100) { + kotlinx.coroutines.time.withTimeout(100) { expect(2) try { delay(1000) - } catch (e: CancellationException) { + } catch (e: TimeoutException) { expect(3) throw TestException() } @@ -165,11 +166,11 @@ class WithTimeoutTest : TestBase() { fun testNegativeTimeout() = runTest { expect(1) try { - withTimeout(-1) { + kotlinx.coroutines.time.withTimeout(-1) { expectUnreached() "OK" } - } catch (e: TimeoutCancellationException) { + } catch (e: TimeoutException) { assertEquals("Timed out immediately", e.message) finish(2) } @@ -180,7 +181,7 @@ class WithTimeoutTest : TestBase() { expect(1) try { expect(2) - withTimeout(1000) { + kotlinx.coroutines.time.withTimeout(1000) { expect(3) throw TestException() } @@ -193,7 +194,7 @@ class WithTimeoutTest : TestBase() { @Test fun testIncompleteWithTimeoutState() = runTest { lateinit var timeoutJob: Job - val handle = withTimeout(Long.MAX_VALUE) { + val handle = kotlinx.coroutines.time.withTimeout(Long.MAX_VALUE) { timeoutJob = coroutineContext[Job]!! timeoutJob.invokeOnCompletion { } } diff --git a/kotlinx-coroutines-core/common/test/flow/channels/ChannelFlowTest.kt b/kotlinx-coroutines-core/common/test/flow/channels/ChannelFlowTest.kt index f197a214f5..f0984eaeef 100644 --- a/kotlinx-coroutines-core/common/test/flow/channels/ChannelFlowTest.kt +++ b/kotlinx-coroutines-core/common/test/flow/channels/ChannelFlowTest.kt @@ -6,6 +6,7 @@ package kotlinx.coroutines.flow import kotlinx.coroutines.* import kotlinx.coroutines.channels.* +import kotlinx.coroutines.time.* import kotlin.test.* class ChannelFlowTest : TestBase() { @@ -126,7 +127,7 @@ class ChannelFlowTest : TestBase() { launch { expect(4) collect { - withTimeout(-1) { + kotlinx.coroutines.time.withTimeout(-1) { send(it) } expectUnreached() @@ -137,7 +138,7 @@ class ChannelFlowTest : TestBase() { val flow = flowOf(1, 2, 3).bufferWithTimeout() expect(1) - assertFailsWith(flow) + assertFailsWith(flow) finish(6) } diff --git a/kotlinx-coroutines-core/common/test/flow/operators/CatchTest.kt b/kotlinx-coroutines-core/common/test/flow/operators/CatchTest.kt index ad91e49898..a2603898ef 100644 --- a/kotlinx-coroutines-core/common/test/flow/operators/CatchTest.kt +++ b/kotlinx-coroutines-core/common/test/flow/operators/CatchTest.kt @@ -61,7 +61,7 @@ class CatchTest : TestBase() { @Test fun testWithTimeoutCatch() = runTest { val flow = flow { - withTimeout(1) { + kotlinx.coroutines.time.withTimeout(1) { hang { expect(1) } } expectUnreached() diff --git a/kotlinx-coroutines-core/common/test/flow/operators/DebounceTest.kt b/kotlinx-coroutines-core/common/test/flow/operators/DebounceTest.kt index 0268a232a4..4e48c49eee 100644 --- a/kotlinx-coroutines-core/common/test/flow/operators/DebounceTest.kt +++ b/kotlinx-coroutines-core/common/test/flow/operators/DebounceTest.kt @@ -6,6 +6,7 @@ package kotlinx.coroutines.flow import kotlinx.coroutines.* import kotlinx.coroutines.channels.* +import kotlinx.coroutines.time.* import kotlin.test.* import kotlin.time.Duration.Companion.milliseconds @@ -96,10 +97,10 @@ class DebounceTest : TestBase() { } @Test - fun testUpstreamError()= testUpstreamError(TimeoutCancellationException("")) + fun testUpstreamError()= testUpstreamError(TimeoutException("")) @Test - fun testUpstreamErrorCancellation() = testUpstreamError(TimeoutCancellationException("")) + fun testUpstreamErrorCancellation() = testUpstreamError(TimeoutException("")) private inline fun testUpstreamError(cause: T) = runTest { val latch = Channel() diff --git a/kotlinx-coroutines-core/common/test/flow/operators/FlowOnTest.kt b/kotlinx-coroutines-core/common/test/flow/operators/FlowOnTest.kt index 8fba8456e8..75f425288f 100644 --- a/kotlinx-coroutines-core/common/test/flow/operators/FlowOnTest.kt +++ b/kotlinx-coroutines-core/common/test/flow/operators/FlowOnTest.kt @@ -6,6 +6,7 @@ package kotlinx.coroutines.flow import kotlinx.coroutines.* import kotlinx.coroutines.channels.* +import kotlinx.coroutines.time.* import kotlin.test.* class FlowOnTest : TestBase() { @@ -239,12 +240,12 @@ class FlowOnTest : TestBase() { val flow = flow { emit(1) yield() - withTimeout(-1) {} + kotlinx.coroutines.time.withTimeout(-1) {} emit(42) }.flowOn(NamedDispatchers("foo")).onEach { expect(1) } - assertFailsWith(flow) + assertFailsWith(flow) finish(2) } @@ -255,9 +256,9 @@ class FlowOnTest : TestBase() { hang { expect(2) } }.flowOn(NamedDispatchers("foo")).onEach { expect(1) - withTimeout(-1) {} + kotlinx.coroutines.time.withTimeout(-1) {} } - assertFailsWith(flow) + assertFailsWith(flow) finish(3) } diff --git a/kotlinx-coroutines-core/common/test/flow/operators/RetryTest.kt b/kotlinx-coroutines-core/common/test/flow/operators/RetryTest.kt index e5dde1b7fc..2af20625c6 100644 --- a/kotlinx-coroutines-core/common/test/flow/operators/RetryTest.kt +++ b/kotlinx-coroutines-core/common/test/flow/operators/RetryTest.kt @@ -75,7 +75,7 @@ class RetryTest : TestBase() { val flow = flow { if (state++ == 0) { expect(1) - withTimeout(1) { + kotlinx.coroutines.time.withTimeout(1) { hang { expect(2) } } expectUnreached() diff --git a/kotlinx-coroutines-core/common/test/flow/operators/TimeoutTest.kt b/kotlinx-coroutines-core/common/test/flow/operators/TimeoutTest.kt index 854e331f1a..5f79511659 100644 --- a/kotlinx-coroutines-core/common/test/flow/operators/TimeoutTest.kt +++ b/kotlinx-coroutines-core/common/test/flow/operators/TimeoutTest.kt @@ -6,6 +6,7 @@ package kotlinx.coroutines.flow.operators import kotlinx.coroutines.* import kotlinx.coroutines.flow.* +import kotlinx.coroutines.time.* import kotlin.test.* import kotlin.time.Duration.Companion.milliseconds @@ -27,7 +28,7 @@ class TimeoutTest : TestBase() { expect(2) val list = mutableListOf() - assertFailsWith(flow.timeout(300.milliseconds).onEach { list.add(it) }) + assertFailsWith(flow.timeout(300.milliseconds).onEach { list.add(it) }) assertEquals(listOf("A", "B", "C"), list) finish(5) } @@ -60,7 +61,7 @@ class TimeoutTest : TestBase() { expect(2) val list = mutableListOf() - flow.timeout(300.milliseconds).catch { if (it is TimeoutCancellationException) emit("-1") }.collect { list.add(it) } + flow.timeout(300.milliseconds).catch { if (it is TimeoutException) emit("-1") }.collect { list.add(it) } assertEquals(listOf("A", "B", "C", "-1"), list) finish(5) } @@ -164,7 +165,7 @@ class TimeoutTest : TestBase() { expectUnreached() }.flowOn(NamedDispatchers("upstream")).timeout(100.milliseconds) - assertFailsWith(flow) + assertFailsWith(flow) finish(3) } @@ -192,7 +193,7 @@ class TimeoutTest : TestBase() { try { MutableSharedFlow().asSharedFlow().timeout(100.milliseconds).collect() expectUnreached() - } catch (e: TimeoutCancellationException) { + } catch (e: TimeoutException) { finish(1) } } diff --git a/kotlinx-coroutines-core/common/test/flow/sharing/ShareInTest.kt b/kotlinx-coroutines-core/common/test/flow/sharing/ShareInTest.kt index cf83a50b0f..86f4305964 100644 --- a/kotlinx-coroutines-core/common/test/flow/sharing/ShareInTest.kt +++ b/kotlinx-coroutines-core/common/test/flow/sharing/ShareInTest.kt @@ -198,8 +198,8 @@ class ShareInTest : TestBase() { val started: Boolean get() = _started.value fun start() = check(_started.compareAndSet(expect = false, update = true)) fun stop() = check(_started.compareAndSet(expect = true, update = false)) - suspend fun awaitStart() = withTimeout(timeLimit) { _started.first { it } } - suspend fun awaitStop() = withTimeout(timeLimit) { _started.first { !it } } + suspend fun awaitStart() = kotlinx.coroutines.time.withTimeout(timeLimit) { _started.first { it } } + suspend fun awaitStop() = kotlinx.coroutines.time.withTimeout(timeLimit) { _started.first { !it } } } private suspend fun FlowState.track(block: suspend () -> Unit) { diff --git a/kotlinx-coroutines-core/concurrent/test/channels/BroadcastChannelSubStressTest.kt b/kotlinx-coroutines-core/concurrent/test/channels/BroadcastChannelSubStressTest.kt index 245a80c222..2959cb8394 100644 --- a/kotlinx-coroutines-core/concurrent/test/channels/BroadcastChannelSubStressTest.kt +++ b/kotlinx-coroutines-core/concurrent/test/channels/BroadcastChannelSubStressTest.kt @@ -51,7 +51,7 @@ class BroadcastChannelSubStressTest: TestBase() { check(curSent > prevSent) { "Send stalled at $curSent events" } prevSent = curSent } - withTimeout(5000) { + kotlinx.coroutines.time.withTimeout(5000) { sender.cancelAndJoin() receiver.cancelAndJoin() } diff --git a/kotlinx-coroutines-core/concurrent/test/channels/ConflatedBroadcastChannelNotifyStressTest.kt b/kotlinx-coroutines-core/concurrent/test/channels/ConflatedBroadcastChannelNotifyStressTest.kt index d9ec7ad582..fe6d98242f 100644 --- a/kotlinx-coroutines-core/concurrent/test/channels/ConflatedBroadcastChannelNotifyStressTest.kt +++ b/kotlinx-coroutines-core/concurrent/test/channels/ConflatedBroadcastChannelNotifyStressTest.kt @@ -60,7 +60,7 @@ class ConflatedBroadcastChannelNotifyStressTest : TestBase() { } } try { - withTimeout(timeLimit) { + kotlinx.coroutines.time.withTimeout(timeLimit) { senders.forEach { it.join() } broadcast.trySend(nEvents) // last event to signal receivers termination receivers.forEach { it.join() } diff --git a/kotlinx-coroutines-core/jdk8/src/time/Time.kt b/kotlinx-coroutines-core/jdk8/src/time/Time.kt index 78cf6e5305..6bcd30df9f 100644 --- a/kotlinx-coroutines-core/jdk8/src/time/Time.kt +++ b/kotlinx-coroutines-core/jdk8/src/time/Time.kt @@ -33,7 +33,7 @@ public fun Flow.sample(period: Duration): Flow = sample(period.coerceT * "java.time" adapter method for [SelectBuilder.onTimeout]. */ public fun SelectBuilder.onTimeout(duration: Duration, block: suspend () -> R): Unit = - onTimeout(duration.coerceToMillis(), block) + onTimeout(duration.coerceToMillis(), block) /** * "java.time" adapter method for [kotlinx.coroutines.withTimeout]. @@ -42,14 +42,14 @@ public suspend fun withTimeout(duration: Duration, block: suspend CoroutineS contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return kotlinx.coroutines.withTimeout(duration.coerceToMillis(), block) + return withTimeout(duration.coerceToMillis(), block) } /** * "java.time" adapter method for [kotlinx.coroutines.withTimeoutOrNull]. */ public suspend fun withTimeoutOrNull(duration: Duration, block: suspend CoroutineScope.() -> T): T? = - kotlinx.coroutines.withTimeoutOrNull(duration.coerceToMillis(), block) + withTimeoutOrNull(duration.coerceToMillis(), block) /** * Coerces the given [Duration] to a millisecond delay. diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/timeout/testStacktraceIsRecoveredFromLexicalBlockWhenTriggeredByChild.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/timeout/testStacktraceIsRecoveredFromLexicalBlockWhenTriggeredByChild.txt index ac40dc152b..5c47e4246d 100644 --- a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/timeout/testStacktraceIsRecoveredFromLexicalBlockWhenTriggeredByChild.txt +++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/timeout/testStacktraceIsRecoveredFromLexicalBlockWhenTriggeredByChild.txt @@ -1,7 +1,7 @@ -kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 200 ms +kotlinx.coroutines.time.TimeoutException: Timed out waiting for 200 ms at _COROUTINE._BOUNDARY._(CoroutineDebugging.kt) - at kotlinx.coroutines.exceptions.StackTraceRecoveryWithTimeoutTest.outerChildWithTimeout(StackTraceRecoveryWithTimeoutTest.kt:48) - at kotlinx.coroutines.exceptions.StackTraceRecoveryWithTimeoutTest$testStacktraceIsRecoveredFromLexicalBlockWhenTriggeredByChild$1.invokeSuspend(StackTraceRecoveryWithTimeoutTest.kt:40) -Caused by: kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 200 ms - at kotlinx.coroutines.TimeoutKt.TimeoutCancellationException(Timeout.kt:116) - at kotlinx.coroutines.TimeoutCoroutine.run(Timeout.kt:86) + at kotlinx.coroutines.exceptions.StackTraceRecoveryWithTimeoutTest.outerChildWithTimeout(StackTraceRecoveryWithTimeoutTest.kt) + at kotlinx.coroutines.exceptions.StackTraceRecoveryWithTimeoutTest$testStacktraceIsRecoveredFromLexicalBlockWhenTriggeredByChild$1.invokeSuspend(StackTraceRecoveryWithTimeoutTest.kt) +Caused by: kotlinx.coroutines.time.TimeoutException: Timed out waiting for 200 ms + at kotlinx.coroutines.time.TimeoutKt.TimeoutException(Timeout.kt) + at kotlinx.coroutines.time.TimeoutCoroutine.run(Timeout.kt) diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/timeout/testStacktraceIsRecoveredFromSuspensionPoint.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/timeout/testStacktraceIsRecoveredFromSuspensionPoint.txt index 9d5ddb6621..9d6c5997d4 100644 --- a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/timeout/testStacktraceIsRecoveredFromSuspensionPoint.txt +++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/timeout/testStacktraceIsRecoveredFromSuspensionPoint.txt @@ -1,10 +1,10 @@ -kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 200 ms +kotlinx.coroutines.time.TimeoutException: Timed out waiting for 200 ms at _COROUTINE._BOUNDARY._(CoroutineDebugging.kt) at kotlinx.coroutines.exceptions.StackTraceRecoveryWithTimeoutTest.suspendForever(StackTraceRecoveryWithTimeoutTest.kt:42) at kotlinx.coroutines.exceptions.StackTraceRecoveryWithTimeoutTest$outerWithTimeout$2.invokeSuspend(StackTraceRecoveryWithTimeoutTest.kt:32) at kotlinx.coroutines.exceptions.StackTraceRecoveryWithTimeoutTest.outerWithTimeout(StackTraceRecoveryWithTimeoutTest.kt:31) at kotlinx.coroutines.exceptions.StackTraceRecoveryWithTimeoutTest$testStacktraceIsRecoveredFromSuspensionPoint$1.invokeSuspend(StackTraceRecoveryWithTimeoutTest.kt:19) -Caused by: kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 200 ms - at kotlinx.coroutines.TimeoutKt.TimeoutCancellationException(Timeout.kt:116) - at kotlinx.coroutines.TimeoutCoroutine.run(Timeout.kt:86) +Caused by: kotlinx.coroutines.time.TimeoutException: Timed out waiting for 200 ms + at kotlinx.coroutines.time.TimeoutKt.TimeoutException(Timeout.kt:116) + at kotlinx.coroutines.time.TimeoutCoroutine.run(Timeout.kt:86) at kotlinx.coroutines.EventLoopImplBase$DelayedRunnableTask.run(EventLoop.common.kt:492) diff --git a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/timeout/testStacktraceIsRecoveredFromSuspensionPointWithChild.txt b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/timeout/testStacktraceIsRecoveredFromSuspensionPointWithChild.txt index 6f21cc6b30..5d6a8fbe9f 100644 --- a/kotlinx-coroutines-core/jvm/test-resources/stacktraces/timeout/testStacktraceIsRecoveredFromSuspensionPointWithChild.txt +++ b/kotlinx-coroutines-core/jvm/test-resources/stacktraces/timeout/testStacktraceIsRecoveredFromSuspensionPointWithChild.txt @@ -1,9 +1,9 @@ -kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 200 ms +kotlinx.coroutines.time.TimeoutException: Timed out waiting for 200 ms at _COROUTINE._BOUNDARY._(CoroutineDebugging.kt) at kotlinx.coroutines.exceptions.StackTraceRecoveryWithTimeoutTest.suspendForever(StackTraceRecoveryWithTimeoutTest.kt:92) at kotlinx.coroutines.exceptions.StackTraceRecoveryWithTimeoutTest$outerChild$2.invokeSuspend(StackTraceRecoveryWithTimeoutTest.kt:78) at kotlinx.coroutines.exceptions.StackTraceRecoveryWithTimeoutTest.outerChild(StackTraceRecoveryWithTimeoutTest.kt:74) at kotlinx.coroutines.exceptions.StackTraceRecoveryWithTimeoutTest$testStacktraceIsRecoveredFromSuspensionPointWithChild$1.invokeSuspend(StackTraceRecoveryWithTimeoutTest.kt:66) -Caused by: kotlinx.coroutines.TimeoutCancellationException: Timed out waiting for 200 ms - at kotlinx.coroutines.TimeoutKt.TimeoutCancellationException(Timeout.kt:116) - at kotlinx.coroutines.TimeoutCoroutine.run(Timeout.kt:86) +Caused by: kotlinx.coroutines.time.TimeoutException: Timed out waiting for 200 ms + at kotlinx.coroutines.time.TimeoutKt.TimeoutException(Timeout.kt:116) + at kotlinx.coroutines.time.TimeoutCoroutine.run(Timeout.kt:86) diff --git a/kotlinx-coroutines-core/jvm/test/RejectedExecutionTest.kt b/kotlinx-coroutines-core/jvm/test/RejectedExecutionTest.kt index 7f6d6b661c..dbef668fa7 100644 --- a/kotlinx-coroutines-core/jvm/test/RejectedExecutionTest.kt +++ b/kotlinx-coroutines-core/jvm/test/RejectedExecutionTest.kt @@ -119,7 +119,7 @@ class RejectedExecutionTest : TestBase() { withContext(executor.asCoroutineDispatcher()) { expect(2) assertExecutorThread() - withTimeout(1000) { + kotlinx.coroutines.time.withTimeout(1000) { expect(3) // atomic entry into the block (legacy behavior, it seem to be Ok with way) assertEquals(true, coroutineContext[Job]?.isCancelled) // but the job is already cancelled } @@ -168,4 +168,4 @@ class RejectedExecutionTest : TestBase() { if (thread !is CoroutineScheduler.Worker) error("Not a thread from Dispatchers.IO: $thread") assertEquals(CoroutineScheduler.WorkerState.BLOCKING, thread.state) } -} \ No newline at end of file +} diff --git a/kotlinx-coroutines-core/jvm/test/ThreadContextElementRestoreTest.kt b/kotlinx-coroutines-core/jvm/test/ThreadContextElementRestoreTest.kt index e2ab4d7282..92de110c83 100644 --- a/kotlinx-coroutines-core/jvm/test/ThreadContextElementRestoreTest.kt +++ b/kotlinx-coroutines-core/jvm/test/ThreadContextElementRestoreTest.kt @@ -54,7 +54,7 @@ class ThreadContextElementRestoreTest : TestBase() { assertEquals(null, tl.get()) } // Scenario #6: withContext(ThreadLocal) from withTimeout - withTimeout(1000) { + kotlinx.coroutines.time.withTimeout(1000) { withContext(tl.asContextElement("OK")) { block() assertEquals("OK", tl.get()) @@ -171,14 +171,14 @@ class ThreadContextElementRestoreTest : TestBase() { @Test fun testWithTimeoutDelay() = check { - withTimeout(1000) { + kotlinx.coroutines.time.withTimeout(1000) { delay(1) } } @Test fun testWithTimeoutYield() = check { - withTimeout(1000) { + kotlinx.coroutines.time.withTimeout(1000) { yield() } } diff --git a/kotlinx-coroutines-core/jvm/test/WithTimeoutChildDipspatchStressTest.kt b/kotlinx-coroutines-core/jvm/test/WithTimeoutChildDipspatchStressTest.kt index 4d440a7cae..545f98bf50 100644 --- a/kotlinx-coroutines-core/jvm/test/WithTimeoutChildDipspatchStressTest.kt +++ b/kotlinx-coroutines-core/jvm/test/WithTimeoutChildDipspatchStressTest.kt @@ -18,7 +18,7 @@ class WithTimeoutChildDispatchStressTest : TestBase() { @Test fun testChildDispatch() = runBlocking { repeat(N_REPEATS) { - val result = withTimeout(5000) { + val result = kotlinx.coroutines.time.withTimeout(5000) { // child in different dispatcher val job = launch(Dispatchers.Default) { // done nothing, but dispatches to join from another thread @@ -29,4 +29,4 @@ class WithTimeoutChildDispatchStressTest : TestBase() { assertEquals("DONE", result) } } -} \ No newline at end of file +} diff --git a/kotlinx-coroutines-core/jvm/test/WithTimeoutOrNullJvmTest.kt b/kotlinx-coroutines-core/jvm/test/WithTimeoutOrNullJvmTest.kt index cce77bb617..f0c144b487 100644 --- a/kotlinx-coroutines-core/jvm/test/WithTimeoutOrNullJvmTest.kt +++ b/kotlinx-coroutines-core/jvm/test/WithTimeoutOrNullJvmTest.kt @@ -24,7 +24,7 @@ class WithTimeoutOrNullJvmTest : TestBase() { @Test fun testIgnoredTimeout() = runTest { - val value = withTimeout(1) { + val value = kotlinx.coroutines.time.withTimeout(1) { Thread.sleep(10) 42 } diff --git a/kotlinx-coroutines-core/jvm/test/WithTimeoutOrNullThreadDispatchTest.kt b/kotlinx-coroutines-core/jvm/test/WithTimeoutOrNullThreadDispatchTest.kt index ea1ba1a9bb..06ccb8560d 100644 --- a/kotlinx-coroutines-core/jvm/test/WithTimeoutOrNullThreadDispatchTest.kt +++ b/kotlinx-coroutines-core/jvm/test/WithTimeoutOrNullThreadDispatchTest.kt @@ -4,6 +4,7 @@ package kotlinx.coroutines +import kotlinx.coroutines.time.* import kotlin.test.* import java.util.concurrent.ExecutorService import java.util.concurrent.Executors @@ -67,7 +68,7 @@ class WithTimeoutOrNullThreadDispatchTest : TestBase() { expect(3) delay(1000) expectUnreached() - } catch (e: CancellationException) { + } catch (e: TimeoutException) { expect(4) assertEquals(thread, Thread.currentThread()) throw e // rethrow @@ -79,4 +80,4 @@ class WithTimeoutOrNullThreadDispatchTest : TestBase() { } finish(6) } -} \ No newline at end of file +} diff --git a/kotlinx-coroutines-core/jvm/test/WithTimeoutThreadDispatchTest.kt b/kotlinx-coroutines-core/jvm/test/WithTimeoutThreadDispatchTest.kt index 82f5e92d62..8530262346 100644 --- a/kotlinx-coroutines-core/jvm/test/WithTimeoutThreadDispatchTest.kt +++ b/kotlinx-coroutines-core/jvm/test/WithTimeoutThreadDispatchTest.kt @@ -4,6 +4,7 @@ package kotlinx.coroutines +import kotlinx.coroutines.time.* import kotlin.test.* import java.util.concurrent.ExecutorService import java.util.concurrent.Executors @@ -63,18 +64,18 @@ class WithTimeoutThreadDispatchTest : TestBase() { expect(2) assertEquals(thread, Thread.currentThread()) try { - withTimeout(100) { + kotlinx.coroutines.time.withTimeout(100) { try { expect(3) delay(1000) expectUnreached() - } catch (e: CancellationException) { + } catch (e: TimeoutException) { expect(4) assertEquals(thread, Thread.currentThread()) throw e // rethrow } } - } catch (e: CancellationException) { + } catch (e: TimeoutException) { expect(5) assertEquals(thread, Thread.currentThread()) } @@ -82,4 +83,4 @@ class WithTimeoutThreadDispatchTest : TestBase() { } finish(7) } -} \ No newline at end of file +} diff --git a/kotlinx-coroutines-core/jvm/test/channels/BroadcastChannelMultiReceiveStressTest.kt b/kotlinx-coroutines-core/jvm/test/channels/BroadcastChannelMultiReceiveStressTest.kt index 8c9777b4af..cbc1a9669e 100644 --- a/kotlinx-coroutines-core/jvm/test/channels/BroadcastChannelMultiReceiveStressTest.kt +++ b/kotlinx-coroutines-core/jvm/test/channels/BroadcastChannelMultiReceiveStressTest.kt @@ -65,13 +65,13 @@ class BroadcastChannelMultiReceiveStressTest( println("Launching $name") receivers += launch(pool + CoroutineName(name)) { val channel = broadcast.openSubscription() - when (receiverIndex % 5) { - 0 -> doReceive(channel, receiverIndex) - 1 -> doReceiveCatching(channel, receiverIndex) - 2 -> doIterator(channel, receiverIndex) - 3 -> doReceiveSelect(channel, receiverIndex) - 4 -> doReceiveCatchingSelect(channel, receiverIndex) - } + when (receiverIndex % 5) { + 0 -> doReceive(channel, receiverIndex) + 1 -> doReceiveCatching(channel, receiverIndex) + 2 -> doIterator(channel, receiverIndex) + 3 -> doReceiveSelect(channel, receiverIndex) + 4 -> doReceiveCatchingSelect(channel, receiverIndex) + } channel.cancel() } printProgress() @@ -87,7 +87,7 @@ class BroadcastChannelMultiReceiveStressTest( println(" Sent $total events, waiting for receivers") stopOnReceive.set(total) try { - withTimeout(5000) { + kotlinx.coroutines.time.withTimeout(5000) { receivers.forEachIndexed { index, receiver -> if (lastReceived[index].get() >= total) receiver.cancel() receiver.join() @@ -96,7 +96,7 @@ class BroadcastChannelMultiReceiveStressTest( } catch (e: Exception) { println("Failed: $e") pool.dumpThreads("Threads in pool") - receivers.indices.forEach { index -> + receivers.indices.forEach { index -> println("lastReceived[$index] = ${lastReceived[index].get()}") } throw e diff --git a/kotlinx-coroutines-core/jvm/test/channels/ChannelSendReceiveStressTest.kt b/kotlinx-coroutines-core/jvm/test/channels/ChannelSendReceiveStressTest.kt index 7e55f2e602..b3e37ce77e 100644 --- a/kotlinx-coroutines-core/jvm/test/channels/ChannelSendReceiveStressTest.kt +++ b/kotlinx-coroutines-core/jvm/test/channels/ChannelSendReceiveStressTest.kt @@ -89,7 +89,7 @@ class ChannelSendReceiveStressTest( } } try { - withTimeout(timeLimit) { + kotlinx.coroutines.time.withTimeout(timeLimit) { senders.forEach { it.join() } channel.close() receivers.forEach { it.join() } diff --git a/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryNestedScopesTest.kt b/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryNestedScopesTest.kt index dbb1ead568..c232baaa31 100644 --- a/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryNestedScopesTest.kt +++ b/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryNestedScopesTest.kt @@ -9,18 +9,18 @@ class StackTraceRecoveryNestedScopesTest : TestBase() { private val TEST_MACROS = "TEST_NAME" private val expectedTrace = "kotlinx.coroutines.RecoverableTestException\n" + - "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest.failure(StackTraceRecoveryNestedScopesTest.kt:9)\n" + - "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest.access\$failure(StackTraceRecoveryNestedScopesTest.kt:7)\n" + - "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest\$createFailingAsync\$1.invokeSuspend(StackTraceRecoveryNestedScopesTest.kt:12)\n" + - "\tat _COROUTINE._BOUNDARY._(CoroutineDebugging.kt)\n" + - "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest\$callWithTimeout\$2.invokeSuspend(StackTraceRecoveryNestedScopesTest.kt:23)\n" + - "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest\$callCoroutineScope\$2.invokeSuspend(StackTraceRecoveryNestedScopesTest.kt:29)\n" + - "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest\$$TEST_MACROS\$1.invokeSuspend(StackTraceRecoveryNestedScopesTest.kt:36)\n" + - "Caused by: kotlinx.coroutines.RecoverableTestException\n" + - "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest.failure(StackTraceRecoveryNestedScopesTest.kt:9)\n" + - "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest.access\$failure(StackTraceRecoveryNestedScopesTest.kt:7)\n" + - "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest\$createFailingAsync\$1.invokeSuspend(StackTraceRecoveryNestedScopesTest.kt:12)\n" + - "\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)" + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest.failure(StackTraceRecoveryNestedScopesTest.kt:9)\n" + + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest.access\$failure(StackTraceRecoveryNestedScopesTest.kt:7)\n" + + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest\$createFailingAsync\$1.invokeSuspend(StackTraceRecoveryNestedScopesTest.kt:12)\n" + + "\tat _COROUTINE._BOUNDARY._(CoroutineDebugging.kt)\n" + + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest\$callWithTimeout\$2.invokeSuspend(StackTraceRecoveryNestedScopesTest.kt:23)\n" + + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest\$callCoroutineScope\$2.invokeSuspend(StackTraceRecoveryNestedScopesTest.kt:29)\n" + + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest\$$TEST_MACROS\$1.invokeSuspend(StackTraceRecoveryNestedScopesTest.kt:36)\n" + + "Caused by: kotlinx.coroutines.RecoverableTestException\n" + + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest.failure(StackTraceRecoveryNestedScopesTest.kt:9)\n" + + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest.access\$failure(StackTraceRecoveryNestedScopesTest.kt:7)\n" + + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest\$createFailingAsync\$1.invokeSuspend(StackTraceRecoveryNestedScopesTest.kt:12)\n" + + "\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)" private fun failure(): String = throw RecoverableTestException() @@ -34,7 +34,7 @@ class StackTraceRecoveryNestedScopesTest : TestBase() { yield() } - private suspend fun callWithTimeout(doYield: Boolean) = withTimeout(Long.MAX_VALUE) { + private suspend fun callWithTimeout(doYield: Boolean) = kotlinx.coroutines.time.withTimeout(Long.MAX_VALUE) { if (doYield) yield() callWithContext(doYield) yield() @@ -77,7 +77,8 @@ class StackTraceRecoveryNestedScopesTest : TestBase() { try { deferred.await() } catch (e: Exception) { - verifyStackTrace(e, + verifyStackTrace( + e, "kotlinx.coroutines.RecoverableTestException\n" + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest.failure(StackTraceRecoveryNestedScopesTest.kt:23)\n" + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest.access\$failure(StackTraceRecoveryNestedScopesTest.kt:7)\n" + @@ -88,11 +89,12 @@ class StackTraceRecoveryNestedScopesTest : TestBase() { "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest\$testAwaitNestedScopes\$1\$deferred\$1.invokeSuspend(StackTraceRecoveryNestedScopesTest.kt:68)\n" + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest.verifyAwait(StackTraceRecoveryNestedScopesTest.kt:76)\n" + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest\$testAwaitNestedScopes\$1.invokeSuspend(StackTraceRecoveryNestedScopesTest.kt:71)\n" + - "Caused by: kotlinx.coroutines.RecoverableTestException\n" + + "Caused by: kotlinx.coroutines.RecoverableTestException\n" + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest.failure(StackTraceRecoveryNestedScopesTest.kt:23)\n" + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest.access\$failure(StackTraceRecoveryNestedScopesTest.kt:7)\n" + "\tat kotlinx.coroutines.exceptions.StackTraceRecoveryNestedScopesTest\$createFailingAsync\$1.invokeSuspend(StackTraceRecoveryNestedScopesTest.kt:26)\n" + - "\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)") + "\tat kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)" + ) } } } diff --git a/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryWithTimeoutTest.kt b/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryWithTimeoutTest.kt index 8e628dbe90..bb4ab1ebcd 100644 --- a/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryWithTimeoutTest.kt +++ b/kotlinx-coroutines-core/jvm/test/exceptions/StackTraceRecoveryWithTimeoutTest.kt @@ -5,6 +5,7 @@ package kotlinx.coroutines.exceptions import kotlinx.coroutines.* +import kotlinx.coroutines.time.* import org.junit.* import org.junit.rules.* @@ -17,20 +18,21 @@ class StackTraceRecoveryWithTimeoutTest : TestBase() { fun testStacktraceIsRecoveredFromSuspensionPoint() = runTest { try { outerWithTimeout() - } catch (e: TimeoutCancellationException) { + } catch (e: TimeoutException) { + println(e.stackTraceToString()) verifyStackTrace("timeout/${name.methodName}", e) } } private suspend fun outerWithTimeout() { - withTimeout(200) { + kotlinx.coroutines.time.withTimeout(200) { suspendForever() } expectUnreached() } private suspend fun suspendForever() { - hang { } + hang { } expectUnreached() } @@ -38,13 +40,13 @@ class StackTraceRecoveryWithTimeoutTest : TestBase() { fun testStacktraceIsRecoveredFromLexicalBlockWhenTriggeredByChild() = runTest { try { outerChildWithTimeout() - } catch (e: TimeoutCancellationException) { + } catch (e: TimeoutException) { verifyStackTrace("timeout/${name.methodName}", e) } } private suspend fun outerChildWithTimeout() { - withTimeout(200) { + kotlinx.coroutines.time.withTimeout(200) { launch { withTimeoutInChild() } @@ -54,8 +56,8 @@ class StackTraceRecoveryWithTimeoutTest : TestBase() { } private suspend fun withTimeoutInChild() { - withTimeout(300) { - hang { } + kotlinx.coroutines.time.withTimeout(300) { + hang { } } expectUnreached() } @@ -64,13 +66,13 @@ class StackTraceRecoveryWithTimeoutTest : TestBase() { fun testStacktraceIsRecoveredFromSuspensionPointWithChild() = runTest { try { outerChild() - } catch (e: TimeoutCancellationException) { + } catch (e: TimeoutException) { verifyStackTrace("timeout/${name.methodName}", e) } } private suspend fun outerChild() { - withTimeout(200) { + kotlinx.coroutines.time.withTimeout(200) { launch { smallWithTimeout() } @@ -80,9 +82,9 @@ class StackTraceRecoveryWithTimeoutTest : TestBase() { } private suspend fun smallWithTimeout() { - withTimeout(100) { + kotlinx.coroutines.time.withTimeout(100) { suspendForever() } expectUnreached() } -} \ No newline at end of file +} diff --git a/kotlinx-coroutines-core/jvm/test/exceptions/WithContextCancellationStressTest.kt b/kotlinx-coroutines-core/jvm/test/exceptions/WithContextCancellationStressTest.kt index f148a3ae43..680a002562 100644 --- a/kotlinx-coroutines-core/jvm/test/exceptions/WithContextCancellationStressTest.kt +++ b/kotlinx-coroutines-core/jvm/test/exceptions/WithContextCancellationStressTest.kt @@ -29,7 +29,7 @@ class WithContextCancellationStressTest : TestBase() { var e1Cnt = 0 var e2Cnt = 0 - withTimeout(timeoutAfter) { + kotlinx.coroutines.time.withTimeout(timeoutAfter) { while (eCnt == 0 || e1Cnt == 0 || e2Cnt == 0) { val barrier = CyclicBarrier(4) val ctx = pool + NonCancellable @@ -64,14 +64,17 @@ class WithContextCancellationStressTest : TestBase() { eCnt++ e.checkSuppressed(e1 = e1, e2 = e2) } + is TestException1 -> { e1Cnt++ e.checkSuppressed(ex = true, e2 = e2) } + is TestException2 -> { e2Cnt++ e.checkSuppressed(ex = true, e1 = e1) } + else -> error("Unexpected exception $e") } } diff --git a/kotlinx-coroutines-core/jvm/test/flow/SharingStressTest.kt b/kotlinx-coroutines-core/jvm/test/flow/SharingStressTest.kt index 25c0c98314..1a7e263a63 100644 --- a/kotlinx-coroutines-core/jvm/test/flow/SharingStressTest.kt +++ b/kotlinx-coroutines-core/jvm/test/flow/SharingStressTest.kt @@ -109,7 +109,7 @@ class SharingStressTest : TestBase() { // let them work a bit more & make sure emitter did not hang val fromEmitIndex = emitIndex.get() val waitEmitIndex = fromEmitIndex + 100 // wait until 100 emitted - withTimeout(10000) { // wait for at most 10s for something to be emitted + kotlinx.coroutines.time.withTimeout(10000) { // wait for at most 10s for something to be emitted do { delay(random.nextLong(50L..100L)) } while (emitIndex.get() < waitEmitIndex) // Ok, enough was emitted, wait more if not diff --git a/kotlinx-coroutines-core/jvm/test/jdk8/future/FutureTest.kt b/kotlinx-coroutines-core/jvm/test/jdk8/future/FutureTest.kt index 372e79ef1d..a1d0f32a30 100644 --- a/kotlinx-coroutines-core/jvm/test/jdk8/future/FutureTest.kt +++ b/kotlinx-coroutines-core/jvm/test/jdk8/future/FutureTest.kt @@ -589,7 +589,7 @@ class FutureTest : TestBase() { } } future.complete(1) - withTimeout(60_000) { + kotlinx.coroutines.time.withTimeout(60_000) { children.forEach { it.join() } assertEquals(count, completed.get()) } diff --git a/kotlinx-coroutines-core/jvm/test/jdk8/time/DurationOverflowTest.kt b/kotlinx-coroutines-core/jvm/test/jdk8/time/DurationOverflowTest.kt index 9ab0ccf95f..a864fdd262 100644 --- a/kotlinx-coroutines-core/jvm/test/jdk8/time/DurationOverflowTest.kt +++ b/kotlinx-coroutines-core/jvm/test/jdk8/time/DurationOverflowTest.kt @@ -67,8 +67,8 @@ class DurationOverflowTest : TestBase() { @Test fun testZeroDurationWithTimeout() = runTest { - assertFailsWith { withTimeout(0L) {} } - assertFailsWith { withTimeout(Duration.ZERO) {} } + assertFailsWith { withTimeout(0L) {} } + assertFailsWith { withTimeout(Duration.ZERO) {} } } @Test diff --git a/kotlinx-coroutines-core/jvm/test/jdk8/time/WithTimeoutTest.kt b/kotlinx-coroutines-core/jvm/test/jdk8/time/WithTimeoutTest.kt index d33eaac124..1ab4f71ad3 100644 --- a/kotlinx-coroutines-core/jvm/test/jdk8/time/WithTimeoutTest.kt +++ b/kotlinx-coroutines-core/jvm/test/jdk8/time/WithTimeoutTest.kt @@ -61,8 +61,8 @@ class WithTimeoutTest : TestBase() { delay(Duration.ofSeconds(Long.MAX_VALUE)) expectUnreached() } - } catch (e: TimeoutCancellationException) { + } catch (e: TimeoutException) { finish(3) } } -} \ No newline at end of file +} diff --git a/kotlinx-coroutines-core/jvm/test/scheduling/SchedulerTestBase.kt b/kotlinx-coroutines-core/jvm/test/scheduling/SchedulerTestBase.kt index fc4436f418..5f5e66b005 100644 --- a/kotlinx-coroutines-core/jvm/test/scheduling/SchedulerTestBase.kt +++ b/kotlinx-coroutines-core/jvm/test/scheduling/SchedulerTestBase.kt @@ -91,7 +91,7 @@ abstract class SchedulerTestBase : TestBase() { @After fun after() { runBlocking { - withTimeout(5_000) { + kotlinx.coroutines.time.withTimeout(5_000) { _dispatcher?.close() } } diff --git a/kotlinx-coroutines-core/jvm/test/selects/SelectPhilosophersStressTest.kt b/kotlinx-coroutines-core/jvm/test/selects/SelectPhilosophersStressTest.kt index 22179f34ad..13e901a716 100644 --- a/kotlinx-coroutines-core/jvm/test/selects/SelectPhilosophersStressTest.kt +++ b/kotlinx-coroutines-core/jvm/test/selects/SelectPhilosophersStressTest.kt @@ -56,10 +56,10 @@ class SelectPhilosophersStressTest : TestBase() { println("Test is failing. Lock states are:") forks.withIndex().forEach { (id, mutex) -> println("$id: $mutex") } } - val eats = withTimeout(5 * TEST_DURATION) { philosophers.map { it.await() } } + val eats = kotlinx.coroutines.time.withTimeout(5 * TEST_DURATION) { philosophers.map { it.await() } } debugJob.cancel() eats.withIndex().forEach { (id, eats) -> assertTrue(eats > 0, "$id shall not starve") } } -} \ No newline at end of file +} diff --git a/kotlinx-coroutines-core/nativeDarwin/test/MainDispatcherTest.kt b/kotlinx-coroutines-core/nativeDarwin/test/MainDispatcherTest.kt index 9904f06c5f..cdab806958 100644 --- a/kotlinx-coroutines-core/nativeDarwin/test/MainDispatcherTest.kt +++ b/kotlinx-coroutines-core/nativeDarwin/test/MainDispatcherTest.kt @@ -4,6 +4,7 @@ package kotlinx.coroutines +import kotlinx.coroutines.time.* import platform.CoreFoundation.* import platform.darwin.* import kotlin.coroutines.* @@ -62,7 +63,7 @@ class MainDispatcherTest : TestBase() { @Test fun testWithTimeoutContextDelayNoTimeout() = runTestNotOnMainDispatcher { expect(1) - withTimeout(1000) { + kotlinx.coroutines.time.withTimeout(1000) { withContext(Dispatchers.Main) { assertTrue(isMainThread()) expect(2) @@ -78,17 +79,17 @@ class MainDispatcherTest : TestBase() { @Test fun testWithTimeoutContextDelayTimeout() = runTestNotOnMainDispatcher { expect(1) - assertFailsWith { - withTimeout(100) { - withContext(Dispatchers.Main) { - assertTrue(isMainThread()) - expect(2) - delay(1000) - expectUnreached() - } - } - expectUnreached() - } + assertFailsWith { + kotlinx.coroutines.time.withTimeout(100) { + withContext(Dispatchers.Main) { + assertTrue(isMainThread()) + expect(2) + delay(1000) + expectUnreached() + } + } + expectUnreached() + } assertFalse(isMainThread()) finish(3) } @@ -97,7 +98,7 @@ class MainDispatcherTest : TestBase() { fun testWithContextTimeoutDelayNoTimeout() = runTestNotOnMainDispatcher { expect(1) withContext(Dispatchers.Main) { - withTimeout(1000) { + kotlinx.coroutines.time.withTimeout(1000) { assertTrue(isMainThread()) expect(2) delay(100) @@ -112,9 +113,9 @@ class MainDispatcherTest : TestBase() { @Test fun testWithContextTimeoutDelayTimeout() = runTestNotOnMainDispatcher { expect(1) - assertFailsWith { + assertFailsWith { withContext(Dispatchers.Main) { - withTimeout(100) { + kotlinx.coroutines.time.withTimeout(100) { assertTrue(isMainThread()) expect(2) delay(1000) diff --git a/kotlinx-coroutines-debug/test/StartModeProbesTest.kt b/kotlinx-coroutines-debug/test/StartModeProbesTest.kt index c2656d346b..bb595d9aec 100644 --- a/kotlinx-coroutines-debug/test/StartModeProbesTest.kt +++ b/kotlinx-coroutines-debug/test/StartModeProbesTest.kt @@ -59,7 +59,7 @@ class StartModeProbesTest : DebugTestBase() { } private suspend fun withTimeoutHelper() { - withTimeout(Long.MAX_VALUE) { + kotlinx.coroutines.time.withTimeout(Long.MAX_VALUE) { expect(2) delay(Long.MAX_VALUE) } @@ -69,7 +69,7 @@ class StartModeProbesTest : DebugTestBase() { @Test fun testWithTimeout() = runTest { - withTimeout(Long.MAX_VALUE) { + kotlinx.coroutines.time.withTimeout(Long.MAX_VALUE) { testActiveDump( false, "StartModeProbesTest\$testWithTimeout\$1.invokeSuspend", @@ -80,7 +80,7 @@ class StartModeProbesTest : DebugTestBase() { @Test fun testWithTimeoutAfterYield() = runTest { - withTimeout(Long.MAX_VALUE) { + kotlinx.coroutines.time.withTimeout(Long.MAX_VALUE) { testActiveDump( true, "StartModeProbesTest\$testWithTimeoutAfterYield\$1.invokeSuspend", @@ -127,7 +127,8 @@ class StartModeProbesTest : DebugTestBase() { verifyPartialDump( 2, "StartModeProbesTest\$runScope\$2.invokeSuspend", - "StartModeProbesTest\$testCoroutineScope\$1\$job\$1.invokeSuspend") + "StartModeProbesTest\$testCoroutineScope\$1\$job\$1.invokeSuspend" + ) job.cancelAndJoin() finish(4) } @@ -141,13 +142,15 @@ class StartModeProbesTest : DebugTestBase() { @Test fun testLazy() = runTest({ it is CancellationException }) { - launch(start = CoroutineStart.LAZY) { } - actor(start = CoroutineStart.LAZY) { } - broadcast(start = CoroutineStart.LAZY) { } + launch(start = CoroutineStart.LAZY) { } + actor(start = CoroutineStart.LAZY) { } + broadcast(start = CoroutineStart.LAZY) { } async(start = CoroutineStart.LAZY) { 1 } - verifyPartialDump(5, "BlockingCoroutine", + verifyPartialDump( + 5, "BlockingCoroutine", "LazyStandaloneCoroutine", "LazyActorCoroutine", - "LazyBroadcastCoroutine", "LazyDeferredCoroutine") + "LazyBroadcastCoroutine", "LazyDeferredCoroutine" + ) cancel() } } diff --git a/kotlinx-coroutines-test/common/test/RunTestTest.kt b/kotlinx-coroutines-test/common/test/RunTestTest.kt index 0315543d54..9306eec0ca 100644 --- a/kotlinx-coroutines-test/common/test/RunTestTest.kt +++ b/kotlinx-coroutines-test/common/test/RunTestTest.kt @@ -7,6 +7,7 @@ package kotlinx.coroutines.test import kotlinx.coroutines.* import kotlinx.coroutines.internal.* import kotlinx.coroutines.flow.* +import kotlinx.coroutines.time.* import kotlin.coroutines.* import kotlin.test.* @@ -239,13 +240,13 @@ class RunTestTest { } } - /** Tests that [runTest] reports [TimeoutCancellationException]. */ + /** Tests that [runTest] reports [TimeoutException]. */ @Test fun testTimeout() = testResultMap({ - assertFailsWith { it() } + assertFailsWith { it() } }) { runTest { - withTimeout(50) { + kotlinx.coroutines.time.withTimeout(50) { launch { delay(1000) } diff --git a/kotlinx-coroutines-test/common/test/TestCoroutineSchedulerTest.kt b/kotlinx-coroutines-test/common/test/TestCoroutineSchedulerTest.kt index d050e9c8c0..c2c558a243 100644 --- a/kotlinx-coroutines-test/common/test/TestCoroutineSchedulerTest.kt +++ b/kotlinx-coroutines-test/common/test/TestCoroutineSchedulerTest.kt @@ -5,6 +5,7 @@ package kotlinx.coroutines.test import kotlinx.coroutines.* +import kotlinx.coroutines.time.* import kotlin.test.* import kotlin.time.* import kotlin.time.Duration.Companion.seconds @@ -241,10 +242,10 @@ class TestCoroutineSchedulerTest { asSpecificImplementation().enter() launch { try { - withTimeout(timeoutMillis) { + kotlinx.coroutines.time.withTimeout(timeoutMillis) { block() } - } catch (e: TimeoutCancellationException) { + } catch (e: TimeoutException) { caughtException = true } } diff --git a/kotlinx-coroutines-test/jvm/test/migration/RunBlockingTestOnTestScopeTest.kt b/kotlinx-coroutines-test/jvm/test/migration/RunBlockingTestOnTestScopeTest.kt index 806592079c..151aba3d2f 100644 --- a/kotlinx-coroutines-test/jvm/test/migration/RunBlockingTestOnTestScopeTest.kt +++ b/kotlinx-coroutines-test/jvm/test/migration/RunBlockingTestOnTestScopeTest.kt @@ -81,7 +81,7 @@ class RunBlockingTestOnTestScopeTest { fun testTimeout() { assertFailsWith { runBlockingTestOnTestScope { - withTimeout(50) { + kotlinx.coroutines.time.withTimeout(50) { launch { delay(1000) } diff --git a/kotlinx-coroutines-test/jvm/test/migration/RunTestLegacyScopeTest.kt b/kotlinx-coroutines-test/jvm/test/migration/RunTestLegacyScopeTest.kt index ed5b1577f5..db5566998c 100644 --- a/kotlinx-coroutines-test/jvm/test/migration/RunTestLegacyScopeTest.kt +++ b/kotlinx-coroutines-test/jvm/test/migration/RunTestLegacyScopeTest.kt @@ -181,7 +181,7 @@ class RunTestLegacyScopeTest { assertFailsWith { it() } }) { runTestWithLegacyScope { - withTimeout(50) { + kotlinx.coroutines.time.withTimeout(50) { launch { delay(1000) } diff --git a/kotlinx-coroutines-test/jvm/test/migration/TestRunBlockingTest.kt b/kotlinx-coroutines-test/jvm/test/migration/TestRunBlockingTest.kt index af3b24892a..5a17e5f024 100644 --- a/kotlinx-coroutines-test/jvm/test/migration/TestRunBlockingTest.kt +++ b/kotlinx-coroutines-test/jvm/test/migration/TestRunBlockingTest.kt @@ -57,7 +57,7 @@ class TestRunBlockingTest { assertFailsWith { runBlockingTest { assertRunsFast { - withTimeout(SLOW) { + kotlinx.coroutines.time.withTimeout(SLOW) { delay(SLOW) } } @@ -68,7 +68,7 @@ class TestRunBlockingTest { @Test fun whenUsingTimeout_doesNotTriggerWhenFast() = runBlockingTest { assertRunsFast { - withTimeout(SLOW) { + kotlinx.coroutines.time.withTimeout(SLOW) { delay(0) } } @@ -80,7 +80,7 @@ class TestRunBlockingTest { runBlockingTest { val uncompleted = CompletableDeferred() assertRunsFast { - withTimeout(SLOW) { + kotlinx.coroutines.time.withTimeout(SLOW) { uncompleted.await() } } @@ -93,7 +93,7 @@ class TestRunBlockingTest { val completed = CompletableDeferred() assertRunsFast { completed.complete(Unit) - withTimeout(SLOW) { + kotlinx.coroutines.time.withTimeout(SLOW) { completed.await() } } @@ -115,7 +115,7 @@ class TestRunBlockingTest { assertFailsWith { runBlockingTest { val deferred = async { - withTimeout(SLOW) { + kotlinx.coroutines.time.withTimeout(SLOW) { delay(SLOW) } } @@ -130,7 +130,7 @@ class TestRunBlockingTest { @Test fun whenUsingTimeout_inAsync_doesNotTriggerWhenNotDelayed() = runBlockingTest { val deferred = async { - withTimeout(SLOW) { + kotlinx.coroutines.time.withTimeout(SLOW) { delay(0) } } @@ -145,7 +145,7 @@ class TestRunBlockingTest { assertFailsWith { runBlockingTest { val job = launch { - withTimeout(1) { + kotlinx.coroutines.time.withTimeout(1) { delay(SLOW + 1) } } @@ -161,7 +161,7 @@ class TestRunBlockingTest { @Test fun whenUsingTimeout_inLaunch_doesNotTriggerWhenNotDelayed() = runBlockingTest { val job = launch { - withTimeout(SLOW) { + kotlinx.coroutines.time.withTimeout(SLOW) { delay(0) } } @@ -437,4 +437,4 @@ class TestRunBlockingTest { } } } -} \ No newline at end of file +} diff --git a/reactive/kotlinx-coroutines-jdk9/test/FlowAsPublisherTest.kt b/reactive/kotlinx-coroutines-jdk9/test/FlowAsPublisherTest.kt index b860e16209..8c80f80636 100644 --- a/reactive/kotlinx-coroutines-jdk9/test/FlowAsPublisherTest.kt +++ b/reactive/kotlinx-coroutines-jdk9/test/FlowAsPublisherTest.kt @@ -80,7 +80,7 @@ class FlowAsPublisherTest : TestBase() { fun testFlowWithTimeout() = runTest { val publisher = flow { expect(2) - withTimeout(1) { delay(Long.MAX_VALUE) } + kotlinx.coroutines.time.withTimeout(1) { delay(Long.MAX_VALUE) } }.asPublisher() try { expect(1) diff --git a/reactive/kotlinx-coroutines-jdk9/test/PublisherCompletionStressTest.kt b/reactive/kotlinx-coroutines-jdk9/test/PublisherCompletionStressTest.kt index 8462df2c6f..077fb7bf6b 100644 --- a/reactive/kotlinx-coroutines-jdk9/test/PublisherCompletionStressTest.kt +++ b/reactive/kotlinx-coroutines-jdk9/test/PublisherCompletionStressTest.kt @@ -22,7 +22,7 @@ class PublisherCompletionStressTest : TestBase() { repeat(N_REPEATS) { val count = rnd.nextInt(5) runBlocking { - withTimeout(5000) { + kotlinx.coroutines.time.withTimeout(5000) { var received = 0 range(Dispatchers.Default, 1, count).collect { x -> received++ @@ -33,4 +33,4 @@ class PublisherCompletionStressTest : TestBase() { } } } -} \ No newline at end of file +} diff --git a/reactive/kotlinx-coroutines-reactive/test/FlowAsPublisherTest.kt b/reactive/kotlinx-coroutines-reactive/test/FlowAsPublisherTest.kt index 02c9e242e9..364bcc6aa4 100644 --- a/reactive/kotlinx-coroutines-reactive/test/FlowAsPublisherTest.kt +++ b/reactive/kotlinx-coroutines-reactive/test/FlowAsPublisherTest.kt @@ -155,7 +155,7 @@ class FlowAsPublisherTest : TestBase() { fun testFlowWithTimeout() = runTest { val publisher = flow { expect(2) - withTimeout(1) { delay(Long.MAX_VALUE) } + kotlinx.coroutines.time.withTimeout(1) { delay(Long.MAX_VALUE) } }.asPublisher() try { expect(1) diff --git a/reactive/kotlinx-coroutines-reactive/test/IntegrationTest.kt b/reactive/kotlinx-coroutines-reactive/test/IntegrationTest.kt index fa039897d7..757f750c27 100644 --- a/reactive/kotlinx-coroutines-reactive/test/IntegrationTest.kt +++ b/reactive/kotlinx-coroutines-reactive/test/IntegrationTest.kt @@ -214,7 +214,7 @@ class IntegrationTest( fun testPublishWithTimeout() = runTest { val publisher = publish { expect(2) - withTimeout(1) { delay(100) } + kotlinx.coroutines.time.withTimeout(1) { delay(100) } } try { expect(1) diff --git a/reactive/kotlinx-coroutines-reactive/test/PublisherCompletionStressTest.kt b/reactive/kotlinx-coroutines-reactive/test/PublisherCompletionStressTest.kt index b16310d0cd..4ec6a6b83e 100644 --- a/reactive/kotlinx-coroutines-reactive/test/PublisherCompletionStressTest.kt +++ b/reactive/kotlinx-coroutines-reactive/test/PublisherCompletionStressTest.kt @@ -22,7 +22,7 @@ class PublisherCompletionStressTest : TestBase() { repeat(N_REPEATS) { val count = rnd.nextInt(5) runBlocking { - withTimeout(5000) { + kotlinx.coroutines.time.withTimeout(5000) { var received = 0 range(Dispatchers.Default, 1, count).collect { x -> received++ @@ -33,4 +33,4 @@ class PublisherCompletionStressTest : TestBase() { } } } -} \ No newline at end of file +} diff --git a/reactive/kotlinx-coroutines-reactor/test/FluxCompletionStressTest.kt b/reactive/kotlinx-coroutines-reactor/test/FluxCompletionStressTest.kt index 6090408f97..140363305d 100644 --- a/reactive/kotlinx-coroutines-reactor/test/FluxCompletionStressTest.kt +++ b/reactive/kotlinx-coroutines-reactor/test/FluxCompletionStressTest.kt @@ -23,7 +23,7 @@ class FluxCompletionStressTest : TestBase() { repeat(N_REPEATS) { val count = rnd.nextInt(5) runBlocking { - withTimeout(5000) { + kotlinx.coroutines.time.withTimeout(5000) { var received = 0 range(Dispatchers.Default, 1, count).collect { x -> received++ @@ -34,4 +34,4 @@ class FluxCompletionStressTest : TestBase() { } } } -} \ No newline at end of file +} diff --git a/reactive/kotlinx-coroutines-reactor/test/MonoTest.kt b/reactive/kotlinx-coroutines-reactor/test/MonoTest.kt index 2a5e5dc107..028ff533c1 100644 --- a/reactive/kotlinx-coroutines-reactor/test/MonoTest.kt +++ b/reactive/kotlinx-coroutines-reactor/test/MonoTest.kt @@ -314,7 +314,7 @@ class MonoTest : TestBase() { @Test fun testTimeout() { val mono = mono { - withTimeout(1) { delay(100) } + kotlinx.coroutines.time.withTimeout(1) { delay(100) } } try { mono.doOnSubscribe { expect(1) } diff --git a/reactive/kotlinx-coroutines-rx2/test/IntegrationTest.kt b/reactive/kotlinx-coroutines-rx2/test/IntegrationTest.kt index 8a6362ad99..e2efa8253d 100644 --- a/reactive/kotlinx-coroutines-rx2/test/IntegrationTest.kt +++ b/reactive/kotlinx-coroutines-rx2/test/IntegrationTest.kt @@ -129,7 +129,7 @@ class IntegrationTest( fun testObservableWithTimeout() = runTest { val observable = rxObservable { expect(2) - withTimeout(1) { delay(100) } + kotlinx.coroutines.time.withTimeout(1) { delay(100) } } try { expect(1) diff --git a/reactive/kotlinx-coroutines-rx2/test/ObservableCompletionStressTest.kt b/reactive/kotlinx-coroutines-rx2/test/ObservableCompletionStressTest.kt index 7e1d335028..572d629893 100644 --- a/reactive/kotlinx-coroutines-rx2/test/ObservableCompletionStressTest.kt +++ b/reactive/kotlinx-coroutines-rx2/test/ObservableCompletionStressTest.kt @@ -22,7 +22,7 @@ class ObservableCompletionStressTest : TestBase() { repeat(N_REPEATS) { val count = rnd.nextInt(5) runBlocking { - withTimeout(5000) { + kotlinx.coroutines.time.withTimeout(5000) { var received = 0 range(Dispatchers.Default, 1, count).collect { x -> received++ diff --git a/reactive/kotlinx-coroutines-rx3/test/IntegrationTest.kt b/reactive/kotlinx-coroutines-rx3/test/IntegrationTest.kt index 1302124f50..c7b94bba8f 100644 --- a/reactive/kotlinx-coroutines-rx3/test/IntegrationTest.kt +++ b/reactive/kotlinx-coroutines-rx3/test/IntegrationTest.kt @@ -129,7 +129,7 @@ class IntegrationTest( fun testObservableWithTimeout() = runTest { val observable = rxObservable { expect(2) - withTimeout(1) { delay(100) } + kotlinx.coroutines.time.withTimeout(1) { delay(100) } } try { expect(1) diff --git a/reactive/kotlinx-coroutines-rx3/test/ObservableCompletionStressTest.kt b/reactive/kotlinx-coroutines-rx3/test/ObservableCompletionStressTest.kt index c1d25bcb51..e8c234aee8 100644 --- a/reactive/kotlinx-coroutines-rx3/test/ObservableCompletionStressTest.kt +++ b/reactive/kotlinx-coroutines-rx3/test/ObservableCompletionStressTest.kt @@ -22,7 +22,7 @@ class ObservableCompletionStressTest : TestBase() { repeat(N_REPEATS) { val count = rnd.nextInt(5) runBlocking { - withTimeout(5000) { + kotlinx.coroutines.time.withTimeout(5000) { var received = 0 range(Dispatchers.Default, 1, count).collect { x -> received++ diff --git a/ui/kotlinx-coroutines-android/test/HandlerDispatcherTest.kt b/ui/kotlinx-coroutines-android/test/HandlerDispatcherTest.kt index afe6cff2f6..df4906510a 100644 --- a/ui/kotlinx-coroutines-android/test/HandlerDispatcherTest.kt +++ b/ui/kotlinx-coroutines-android/test/HandlerDispatcherTest.kt @@ -61,9 +61,14 @@ class HandlerDispatcherTest : TestBase() { mainLooper.pause() assertFalse { mainLooper.scheduler.areAnyRunnable() } val job = launch(Dispatchers.Main, start = CoroutineStart.UNDISPATCHED) { - withTimeout(1) { - expect(1) - hang { expect(3) } + try { + kotlinx.coroutines.time.withTimeout(1) { + expect(1) + hang { expect(3) } + } + } catch (e: kotlinx.coroutines.time.TimeoutException) { + expect(4) + throw CancellationException("successfully timed out", e) } expectUnreached() } @@ -72,7 +77,7 @@ class HandlerDispatcherTest : TestBase() { // Schedule cancellation mainLooper.runToEndOfTasks() job.join() - finish(4) + finish(5) } @Test