From 9dfb46d704b47cf32abe537b3c1f368b23f1c99e Mon Sep 17 00:00:00 2001 From: Him188 <Him188@mamoe.net> Date: Mon, 31 May 2021 01:46:02 +0800 Subject: [PATCH] Make tests faster --- .../kotlin/network/AwaitStateTest.kt | 60 ++++++++++++------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/mirai-core/src/commonTest/kotlin/network/AwaitStateTest.kt b/mirai-core/src/commonTest/kotlin/network/AwaitStateTest.kt index a7126b23f..547022389 100644 --- a/mirai-core/src/commonTest/kotlin/network/AwaitStateTest.kt +++ b/mirai-core/src/commonTest/kotlin/network/AwaitStateTest.kt @@ -21,6 +21,8 @@ import org.junit.jupiter.api.Test import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.Executors import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue internal class AwaitStateTest : AbstractMockNetworkHandlerTest() { @@ -28,31 +30,34 @@ internal class AwaitStateTest : AbstractMockNetworkHandlerTest() { fun `test select onStateChanged`() = runBlockingUnit { createNetworkHandler().run { assertState(INITIALIZED) + val queue = ConcurrentLinkedQueue<NetworkHandler.State>() + launch(start = CoroutineStart.UNDISPATCHED) { + select<Unit> { + onStateChanged { + queue.add(it) + } + } + assertEquals(1, queue.size) + assertEquals(OK, queue.first()) + } launch { - delay(1000) // wait for select setState(OK) } - val queue = ConcurrentLinkedQueue<NetworkHandler.State>() - select<Unit> { - onStateChanged { - queue.add(it) - } - } - assertEquals(1, queue.size) - assertEquals(OK, queue.first()) + } } @OptIn(ExperimentalCoroutinesApi::class) @Test - fun `test whileSelect onStateChanged on demand`() = runBlockingUnit { + fun `test whileSelect onStateChanged on demand`() = runBlockingUnit(singleThreadDispatcher) { createNetworkHandler().run { assertState(INITIALIZED) val queue = ConcurrentLinkedQueue<NetworkHandler.State>() val selector = launch( CoroutineExceptionHandler { _, throwable -> if (throwable !is CancellationException) throwable.printStackTrace() - } + }, + start = CoroutineStart.UNDISPATCHED ) { while (isActive) { whileSelect { @@ -65,11 +70,10 @@ internal class AwaitStateTest : AbstractMockNetworkHandlerTest() { throw AssertionError("Terminated too early") } launch { - delay(2000) setState(OK) - delay(2000) + yield() setState(CLOSED) - delay(2000) + yield() selector.cancel() } @@ -81,11 +85,12 @@ internal class AwaitStateTest : AbstractMockNetworkHandlerTest() { } } + // single thread so we can use [yield] to transfer dispatch private val singleThreadDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher() @OptIn(ExperimentalCoroutinesApi::class) @Test - fun `test whileSelect onStateChanged drop if not listening`() = runBlockingUnit { + fun `test whileSelect onStateChanged drop if not listening`() = runBlockingUnit(singleThreadDispatcher) { createNetworkHandler().run { assertState(INITIALIZED) val queue = ConcurrentLinkedQueue<NetworkHandler.State>() @@ -96,7 +101,8 @@ internal class AwaitStateTest : AbstractMockNetworkHandlerTest() { val selector = launch( CoroutineExceptionHandler { _, throwable -> if (throwable !is CancellationException) throwable.printStackTrace() - } + }, + start = CoroutineStart.UNDISPATCHED ) { while (isActive) { whileSelect { @@ -109,11 +115,10 @@ internal class AwaitStateTest : AbstractMockNetworkHandlerTest() { } launch { - delay(2000) // 等开始 select setState(OK) - delay(2000) // 等第一次 select 结束 + yield() // yields the thread to run coroutine of select setState(CLOSED) - delay(2000) // 等第二次 select 结束 + yield() selector.cancel() } @@ -126,12 +131,23 @@ internal class AwaitStateTest : AbstractMockNetworkHandlerTest() { } @Test - fun `can await`() = runBlockingUnit { + fun `can await`() = runBlockingUnit(singleThreadDispatcher) { createNetworkHandler().run { assertState(INITIALIZED) - val job = launch { awaitState(CLOSED) } - setState(OK) + val job = launch(start = CoroutineStart.UNDISPATCHED) { + awaitState(CLOSED) + assertState(CLOSED) + } + yield() + assertTrue { job.isActive } + setState(OK) + yield() + assertTrue { job.isActive } + + setState(CLOSED) + yield() + assertFalse { job.isActive } } } } \ No newline at end of file