aboutsummaryrefslogtreecommitdiffstats
path: root/kotlinx-coroutines-debug/src/junit4/CoroutinesTimeout.kt
diff options
context:
space:
mode:
Diffstat (limited to 'kotlinx-coroutines-debug/src/junit4/CoroutinesTimeout.kt')
-rw-r--r--kotlinx-coroutines-debug/src/junit4/CoroutinesTimeout.kt66
1 files changed, 66 insertions, 0 deletions
diff --git a/kotlinx-coroutines-debug/src/junit4/CoroutinesTimeout.kt b/kotlinx-coroutines-debug/src/junit4/CoroutinesTimeout.kt
new file mode 100644
index 00000000..ef81cd4b
--- /dev/null
+++ b/kotlinx-coroutines-debug/src/junit4/CoroutinesTimeout.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2016-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.coroutines.debug.junit4
+
+import kotlinx.coroutines.debug.*
+import org.junit.rules.*
+import org.junit.runner.*
+import org.junit.runners.model.*
+import java.util.concurrent.*
+
+/**
+ * Coroutines timeout rule for JUnit4 that is applied to all methods in the class.
+ * This rule is very similar to [Timeout] rule: it runs tests in a separate thread,
+ * fails tests after the given timeout and interrupts test thread.
+ *
+ * Additionally, this rule installs [DebugProbes] and dumps all coroutines at the moment of the timeout.
+ * It may cancel coroutines on timeout if [cancelOnTimeout] set to `true`.
+ *
+ * Example of usage:
+ * ```
+ * class HangingTest {
+ *
+ * @Rule
+ * @JvmField
+ * val timeout = CoroutinesTimeout.seconds(5)
+ *
+ * @Test
+ * fun testThatHangs() = runBlocking {
+ * ...
+ * delay(Long.MAX_VALUE) // somewhere deep in the stack
+ * ...
+ * }
+ * }
+ * ```
+ */
+public class CoroutinesTimeout(
+ private val testTimeoutMs: Long,
+ private val cancelOnTimeout: Boolean = false
+) : TestRule {
+
+ init {
+ require(testTimeoutMs > 0) { "Expected positive test timeout, but had $testTimeoutMs" }
+ }
+
+ companion object {
+ /**
+ * Creates [CoroutinesTimeout] rule with the given timeout in seconds.
+ */
+ public fun seconds(seconds: Int, cancelOnTimeout: Boolean = false): CoroutinesTimeout =
+ seconds(seconds.toLong(), cancelOnTimeout)
+
+ /**
+ * Creates [CoroutinesTimeout] rule with the given timeout in seconds.
+ */
+ public fun seconds(seconds: Long, cancelOnTimeout: Boolean = false): CoroutinesTimeout =
+ CoroutinesTimeout(TimeUnit.SECONDS.toMillis(seconds), cancelOnTimeout) // Overflow is properly handled by TimeUnit
+ }
+
+ /**
+ * @suppress suppress from Dokka
+ */
+ override fun apply(base: Statement, description: Description): Statement =
+ CoroutinesTimeoutStatement(base, description, testTimeoutMs, cancelOnTimeout)
+}