@@ -7,11 +7,10 @@ package kotlinx.coroutines
7
7
import kotlinx.coroutines.internal.*
8
8
import kotlinx.coroutines.scheduling.*
9
9
import org.junit.*
10
- import java.lang.Math .*
10
+ import java.io .*
11
11
import java.util.*
12
12
import java.util.concurrent.atomic.*
13
13
import kotlin.coroutines.*
14
- import kotlin.math.*
15
14
import kotlin.test.*
16
15
17
16
private val VERBOSE = systemProp(" test.verbose" , false )
@@ -23,13 +22,13 @@ public actual val isStressTest = System.getProperty("stressTest")?.toBoolean() ?
23
22
24
23
public val stressTestMultiplierSqrt = if (isStressTest) 5 else 1
25
24
25
+ private const val SHUTDOWN_TIMEOUT = 1_000L // 1s at most to wait per thread
26
+
26
27
/* *
27
28
* Multiply various constants in stress tests by this factor, so that they run longer during nightly stress test.
28
29
*/
29
30
public actual val stressTestMultiplier = stressTestMultiplierSqrt * stressTestMultiplierSqrt
30
31
31
- public val stressTestMultiplierCbrt = cbrt(stressTestMultiplier.toDouble()).roundToInt()
32
-
33
32
@Suppress(" ACTUAL_WITHOUT_EXPECT" )
34
33
public actual typealias TestResult = Unit
35
34
@@ -52,7 +51,10 @@ public actual typealias TestResult = Unit
52
51
* }
53
52
* ```
54
53
*/
55
- public actual open class TestBase actual constructor() {
54
+ public actual open class TestBase (private var disableOutCheck : Boolean ) {
55
+
56
+ actual constructor (): this (false )
57
+
56
58
public actual val isBoundByJsTestTimeout = false
57
59
private var actionIndex = AtomicInteger ()
58
60
private var finished = AtomicBoolean ()
@@ -62,9 +64,15 @@ public actual open class TestBase actual constructor() {
62
64
private lateinit var threadsBefore: Set <Thread >
63
65
private val uncaughtExceptions = Collections .synchronizedList(ArrayList <Throwable >())
64
66
private var originalUncaughtExceptionHandler: Thread .UncaughtExceptionHandler ? = null
65
- private val SHUTDOWN_TIMEOUT = 1_000L // 1s at most to wait per thread
67
+ /*
68
+ * System.out that we redefine in order to catch any debugging/diagnostics
69
+ * 'println' from main source set.
70
+ * NB: We do rely on the name 'previousOut' in the FieldWalker in order to skip its
71
+ * processing
72
+ */
73
+ private lateinit var previousOut: PrintStream
66
74
67
- /* *
75
+ /* *
68
76
* Throws [IllegalStateException] like `error` in stdlib, but also ensures that the test will not
69
77
* complete successfully even if this exception is consumed somewhere in the test.
70
78
*/
@@ -117,7 +125,7 @@ public actual open class TestBase actual constructor() {
117
125
}
118
126
119
127
/* *
120
- * Asserts that this it the last action in the test. It must be invoked by any test that used [expect].
128
+ * Asserts that this is the last action in the test. It must be invoked by any test that used [expect].
121
129
*/
122
130
public actual fun finish (index : Int ) {
123
131
expect(index)
@@ -137,6 +145,16 @@ public actual open class TestBase actual constructor() {
137
145
finished.set(false )
138
146
}
139
147
148
+ private object TestOutputStream : PrintStream(object : OutputStream () {
149
+ override fun write(b: Int ) {
150
+ error("Detected unexpected call to 'println' from source code")
151
+ }
152
+ })
153
+
154
+ fun println (message : Any? ) {
155
+ previousOut.println (message)
156
+ }
157
+
140
158
@Before
141
159
fun before () {
142
160
initPoolsBeforeTest()
@@ -147,6 +165,10 @@ public actual open class TestBase actual constructor() {
147
165
e.printStackTrace()
148
166
uncaughtExceptions.add(e)
149
167
}
168
+ if (! disableOutCheck) {
169
+ previousOut = System .out
170
+ System .setOut(TestOutputStream )
171
+ }
150
172
}
151
173
152
174
@After
@@ -158,14 +180,17 @@ public actual open class TestBase actual constructor() {
158
180
}
159
181
// Shutdown all thread pools
160
182
shutdownPoolsAfterTest()
161
- // Check that that are now leftover threads
183
+ // Check that are now leftover threads
162
184
runCatching {
163
185
checkTestThreads(threadsBefore)
164
186
}.onFailure {
165
187
setError(it)
166
188
}
167
189
// Restore original uncaught exception handler
168
190
Thread .setDefaultUncaughtExceptionHandler(originalUncaughtExceptionHandler)
191
+ if (! disableOutCheck) {
192
+ System .setOut(previousOut)
193
+ }
169
194
if (uncaughtExceptions.isNotEmpty()) {
170
195
makeError(" Expected no uncaught exceptions, but got $uncaughtExceptions " )
171
196
}
0 commit comments