Try fix EventLaunchUndispatchedTest

This commit is contained in:
Him188 2021-09-12 22:24:55 +08:00
parent 062b8766a2
commit 63fc45edd6
2 changed files with 19 additions and 8 deletions

View File

@ -14,8 +14,10 @@ package net.mamoe.mirai.event
import kotlinx.coroutines.* import kotlinx.coroutines.*
import net.mamoe.kjbb.JvmBlockingBridge import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.internal.event.EVENT_LAUNCH_UNDISPATCHED import net.mamoe.mirai.internal.event.EVENT_LAUNCH_UNDISPATCHED
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.ConcurrentLinkedQueue
import java.util.concurrent.Executors
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFails import kotlin.test.assertFails
import kotlin.test.assertSame import kotlin.test.assertSame
@ -24,10 +26,11 @@ import kotlin.test.assertSame
internal class EventLaunchUndispatchedTest : AbstractEventTest() { internal class EventLaunchUndispatchedTest : AbstractEventTest() {
internal class TestEvent : AbstractEvent() internal class TestEvent : AbstractEvent()
val originalValue = EVENT_LAUNCH_UNDISPATCHED var originalValue = EVENT_LAUNCH_UNDISPATCHED
@Test @Test
suspend fun `event runs undispatched`() { suspend fun `event runs undispatched`() {
originalValue = EVENT_LAUNCH_UNDISPATCHED
EVENT_LAUNCH_UNDISPATCHED = true EVENT_LAUNCH_UNDISPATCHED = true
doTest() doTest()
EVENT_LAUNCH_UNDISPATCHED = originalValue EVENT_LAUNCH_UNDISPATCHED = originalValue
@ -35,26 +38,34 @@ internal class EventLaunchUndispatchedTest : AbstractEventTest() {
@Test @Test
suspend fun `event runs undispatched fail`() { suspend fun `event runs undispatched fail`() {
originalValue = EVENT_LAUNCH_UNDISPATCHED
EVENT_LAUNCH_UNDISPATCHED = false EVENT_LAUNCH_UNDISPATCHED = false
assertFails { doTest() } assertFails { doTest() }
EVENT_LAUNCH_UNDISPATCHED = originalValue EVENT_LAUNCH_UNDISPATCHED = originalValue
} }
private val dispatcher = Executors.newFixedThreadPool(4).asCoroutineDispatcher()
@AfterEach
fun cleanup() {
dispatcher.close()
}
private suspend fun doTest() = coroutineScope { private suspend fun doTest() = coroutineScope {
val invoked = ConcurrentLinkedQueue<Int>() val invoked = ConcurrentLinkedQueue<Int>()
val thread = Thread.currentThread() val thread = Thread.currentThread()
val job = SupervisorJob() val job = SupervisorJob()
globalEventChannel().parentJob(job).exceptionHandler { } // printing exception to stdout is very slow globalEventChannel(dispatcher).parentJob(job).exceptionHandler {} // printing exception to stdout is very slow
.run { .run {
subscribeAlways<TestEvent>(priority = EventPriority.MONITOR) { subscribeAlways<TestEvent>(dispatcher, priority = EventPriority.MONITOR) {
assertSame(thread, Thread.currentThread()) assertSame(thread, Thread.currentThread())
invoked.add(1) invoked.add(1)
awaitCancellation() awaitCancellation()
} }
repeat(10000) { i -> repeat(1000) { i ->
subscribeAlways<TestEvent>(priority = EventPriority.MONITOR) { subscribeAlways<TestEvent>(dispatcher, priority = EventPriority.MONITOR) {
assertSame(thread, Thread.currentThread()) assertSame(thread, Thread.currentThread())
invoked.add(i + 2) invoked.add(i + 2)
awaitCancellation() awaitCancellation()
@ -62,13 +73,13 @@ internal class EventLaunchUndispatchedTest : AbstractEventTest() {
} }
} }
launch(start = CoroutineStart.UNDISPATCHED) { TestEvent().broadcast() } launch(dispatcher, start = CoroutineStart.UNDISPATCHED) { TestEvent().broadcast() }
// `launch` returns on first suspension point of `broadcast` // `launch` returns on first suspension point of `broadcast`
// if EVENT_LAUNCH_UNDISPATCHED is `true`, all listeners run to `awaitCancellation` when `broadcast` is suspended // if EVENT_LAUNCH_UNDISPATCHED is `true`, all listeners run to `awaitCancellation` when `broadcast` is suspended
// otherwise, they are put into tasks queue to be scheduled. 10000 tasks wont complete very quickly, so the following `invoked.size` check works. // otherwise, they are put into tasks queue to be scheduled. 10000 tasks wont complete very quickly, so the following `invoked.size` check works.
assertSame(thread, Thread.currentThread()) assertSame(thread, Thread.currentThread())
assertEquals(invoked.toList(), invoked.sorted()) assertEquals(invoked.toList(), invoked.sorted())
assertEquals(10000 + 1, invoked.size) assertEquals(1000 + 1, invoked.size)
job.cancel() job.cancel()
} }
} }

View File

@ -310,7 +310,7 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
} }
if (event is BotEvent) { if (event is BotEvent) {
val bot = event.bot val bot = event.bot
if (bot is QQAndroidBot) { if (bot is AbstractBot) {
bot.components[EventDispatcher].broadcast(event) bot.components[EventDispatcher].broadcast(event)
} }
} else { } else {