Skip to content

Commit 45bcb0b

Browse files
committed
Improve ChannelsConsumeTest to avoid spurious failures due to concurrency
1 parent c7d10a4 commit 45bcb0b

File tree

1 file changed

+13
-10
lines changed

1 file changed

+13
-10
lines changed

core/kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/channels/ChannelsConsumeTest.kt

+13-10
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class ChannelsConsumeTest {
2727
private val sourceList = (1..10).toList()
2828

2929
// test source with numbers 1..10
30-
private fun testSource() = produce {
30+
private fun testSource(context: CoroutineContext) = produce(context) {
3131
for (i in sourceList) {
3232
send(i)
3333
}
@@ -811,10 +811,10 @@ class ChannelsConsumeTest {
811811
fun testZip() {
812812
val expect = sourceList.zip(sourceList) { a, b -> a + 2 * b }
813813
checkTransform(expect) { ctx ->
814-
zip(testSource(), ctx) { a, b -> a + 2*b }
814+
zip(testSource(ctx), ctx) { a, b -> a + 2*b }
815815
}
816816
checkTransform(expect) { ctx ->
817-
testSource().zip(this, ctx) { a, b -> a + 2*b }
817+
testSource(ctx).zip(this, ctx) { a, b -> a + 2*b }
818818
}
819819
}
820820

@@ -832,27 +832,28 @@ class ChannelsConsumeTest {
832832
expected: ((Throwable?) -> Unit)? = null,
833833
terminal: suspend ReceiveChannel<Int>.() -> Unit
834834
) {
835-
val src = testSource()
836-
runBlocking {
835+
val src = runBlocking {
836+
val src = testSource(coroutineContext)
837837
try {
838838
// terminal operation
839839
terminal(src)
840840
// source must be cancelled at the end of terminal op
841-
assertTrue(src.isClosedForReceive, "Source must be closed")
842841
if (expected != null) error("Exception was expected")
843842
} catch (e: Throwable) {
844843
if (expected == null) throw e
845844
expected(e)
846845
}
846+
src
847847
}
848+
assertTrue(src.isClosedForReceive, "Source must be closed")
848849
}
849850

850851
private fun checkTerminalCancellation(
851852
expected: ((Throwable?) -> Unit)? = null,
852853
terminal: suspend ReceiveChannel<Int>.() -> Unit
853854
) {
854-
val src = testSource()
855-
runBlocking {
855+
val src = runBlocking {
856+
val src = testSource(coroutineContext)
856857
// terminal operation in a separate async context started until the first suspension
857858
val d = async(coroutineContext, start = CoroutineStart.UNDISPATCHED) {
858859
terminal(src)
@@ -869,6 +870,7 @@ class ChannelsConsumeTest {
869870
if (expected == null) throw e
870871
expected(e)
871872
}
873+
src
872874
}
873875
// source must be cancelled at the end of terminal op even if it was cancelled while in process
874876
assertTrue(src.isClosedForReceive, "Source must be closed")
@@ -889,8 +891,8 @@ class ChannelsConsumeTest {
889891
expect: List<R>,
890892
transform: ReceiveChannel<Int>.(CoroutineContext) -> ReceiveChannel<R>
891893
) {
892-
val src = testSource()
893-
runBlocking {
894+
val src = runBlocking {
895+
val src = testSource(coroutineContext)
894896
// transform
895897
val res = transform(src, coroutineContext)
896898
// receive nReceive elements from the result
@@ -904,6 +906,7 @@ class ChannelsConsumeTest {
904906
// then check that result is closed
905907
assertEquals(null, res.receiveOrNull(), "Result has unexpected values")
906908
}
909+
src
907910
}
908911
// source must be cancelled when runBlocking processes all the scheduled stuff
909912
assertTrue(src.isClosedForReceive, "Source must be closed")

0 commit comments

Comments
 (0)