AbstractRealTimeActionTestUnit

This commit is contained in:
Karlatemp 2021-11-19 23:12:09 +08:00
parent 813d8485b6
commit 3da565ab02
No known key found for this signature in database
GPG Key ID: 21FBDDF664FF06F8
4 changed files with 138 additions and 3 deletions

View File

@ -107,7 +107,7 @@ internal open class NettyNetworkHandler(
handlePipelineException(ctx, cause)
}
})
.addLast(OutgoingPacketEncoder())
.addLast("outgoing-packet-encoder", OutgoingPacketEncoder())
.addLast(LengthFieldBasedFrameDecoder(Int.MAX_VALUE, 0, 4, -4, 4))
.addLast(ByteBufToIncomingPacketDecoder())
.addLast("raw-packet-collector", RawIncomingPacketCollector(decodePipeline))

View File

@ -14,14 +14,26 @@ import io.netty.channel.embedded.EmbeddedChannel
import io.netty.util.ReferenceCountUtil
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.io.core.buildPacket
import kotlinx.io.core.readBytes
import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.serializer
import net.mamoe.mirai.internal.AbstractBot
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.network.components.BotOfflineEventMonitor
import net.mamoe.mirai.internal.network.components.RawIncomingPacket
import net.mamoe.mirai.internal.network.handler.NetworkHandlerContext
import net.mamoe.mirai.internal.network.handler.NetworkHandlerFactory
import net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport
import net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandler
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
import net.mamoe.mirai.internal.utils.io.ProtoBuf
import net.mamoe.mirai.internal.utils.io.serialization.writeProtoBuf
import net.mamoe.mirai.utils.ExceptionCollector
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.cast
import net.mamoe.mirai.utils.error
import java.net.SocketAddress
/**
@ -72,8 +84,49 @@ internal abstract class AbstractNettyNHTest : AbstractRealNetworkHandlerTest<Tes
}
class NettyNHTestChannel(
val logger: Lazy<MiraiLogger>,
var fakeServer: (NettyNHTestChannel.(msg: Any?) -> Unit)? = null,
) : EmbeddedChannel() {
@OptIn(InternalSerializationApi::class)
fun listen(listener: (OutgoingPacket) -> Any?) {
fakeServer = { packet ->
if (packet is OutgoingPacket) {
val rsp0 = when (val rsp = listener(packet)) {
null -> null
is Unit -> null
is ByteArray -> {
RawIncomingPacket(
commandName = packet.commandName,
sequenceId = packet.sequenceId,
body = rsp
)
}
is RawIncomingPacket -> rsp
is ProtoBuf -> {
RawIncomingPacket(
commandName = packet.commandName,
sequenceId = packet.sequenceId,
body = buildPacket {
writeProtoBuf(
rsp::class.serializer().cast<KSerializer<ProtoBuf>>(),
rsp
)
}.readBytes()
)
}
else -> {
logger.value.error { "Failed to respond $rsp" }
null
}
}
if (rsp0 != null) {
pipeline().fireChannelRead(rsp0)
}
}
ReferenceCountUtil.release(packet)
}
}
public /*internal*/ override fun doRegister() {
super.doRegister() // Set channel state to ACTIVE
// Drop old handlers
@ -93,7 +146,9 @@ internal abstract class AbstractNettyNHTest : AbstractRealNetworkHandlerTest<Tes
}
}
val channel = NettyNHTestChannel()
val channel = NettyNHTestChannel(
logger = lazy { bot.logger },
)
override val network: TestNettyNH get() = bot.network as TestNettyNH
@ -107,4 +162,10 @@ internal abstract class AbstractNettyNHTest : AbstractRealNetworkHandlerTest<Tes
}
}
}
protected fun removeOutgoingPacketEncoder() {
kotlin.runCatching {
channel.pipeline().remove("outgoing-packet-encoder")
}
}
}

View File

@ -31,7 +31,9 @@ internal abstract class AbstractNettyNHTestWithSelector : AbstractRealNetworkHan
overrideComponents[BotOfflineEventMonitor] = BotOfflineEventMonitorImpl()
}
val channel = AbstractNettyNHTest.NettyNHTestChannel()
val channel = AbstractNettyNHTest.NettyNHTestChannel(
logger = lazy { bot.logger },
)
val selector = TestSelector<TestNettyNH> {
object : TestNettyNH(bot, createContext(), createAddress()) {

View File

@ -0,0 +1,72 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.framework
import net.mamoe.mirai.internal.network.KeyWithCreationTime
import net.mamoe.mirai.internal.network.KeyWithExpiry
import net.mamoe.mirai.internal.network.WLoginSigInfo
import net.mamoe.mirai.internal.network.WLoginSimpleInfo
import net.mamoe.mirai.internal.notice.processors.GroupExtensions
import net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY
import net.mamoe.mirai.utils.hexToBytes
import org.junit.jupiter.api.BeforeEach
internal abstract class AbstractRealTimeActionTestUnit : AbstractNettyNHTest(), GroupExtensions {
@BeforeEach
internal fun prepareEnv() {
bot.client.wLoginSigInfoField = WLoginSigInfo(
uin = bot.id,
encryptA1 = "01 23 33 AF EA".hexToBytes(),
noPicSig = "55 47 20 23 54".hexToBytes(),
simpleInfo = WLoginSimpleInfo(
uin = bot.id,
imgType = EMPTY_BYTE_ARRAY,
imgFormat = EMPTY_BYTE_ARRAY,
imgUrl = EMPTY_BYTE_ARRAY,
mainDisplayName = EMPTY_BYTE_ARRAY,
),
appPri = 0,
a2ExpiryTime = 0,
a2CreationTime = 849415181,
loginBitmap = 1145141919810,
tgt = "EA 5B CE FA 6C".hexToBytes(),
tgtKey = "66 F5 A9 B8 FF".hexToBytes(),
userStSig = KeyWithCreationTime(data = "3C FF FF FF 07".hexToBytes(), creationTime = 0),
userStKey = "07 F5 A9 B8 0B".hexToBytes(),
userStWebSig = KeyWithExpiry(data = "A1 5B CE FA 60".hexToBytes(), creationTime = 0, expireTime = 0),
userA5 = KeyWithCreationTime(data = "66 CC FF AA AA".hexToBytes(), creationTime = 0),
userA8 = KeyWithExpiry(data = "65 c1 B9 7A 1F".hexToBytes(), creationTime = 0, expireTime = 0),
lsKey = KeyWithExpiry(data = "65 c1 B9 7A 1F".hexToBytes(), creationTime = 0, expireTime = 0),
sKey = KeyWithExpiry(data = "D6 B1 9C 66 3A".hexToBytes(), creationTime = 0, expireTime = 0),
userSig64 = KeyWithCreationTime(data = "D6 B1 9C 66 3A".hexToBytes(), creationTime = 0),
openId = "D6 B1 9C 66 3A".hexToBytes(),
openKey = KeyWithCreationTime(data = "B4 6E 5E 7A 3C".hexToBytes(), creationTime = 0),
vKey = KeyWithExpiry(data = "A1 34 17 48 21".hexToBytes(), creationTime = 0, expireTime = 0),
accessToken = KeyWithCreationTime(data = "12 35 87 14 A1".hexToBytes(), creationTime = 0),
aqSig = KeyWithExpiry(data = "22 0C DC AC 30".hexToBytes(), creationTime = 0, expireTime = 0),
superKey = "22 33 66 CC FF".hexToBytes(),
sid = KeyWithExpiry(data = "11 45 14 19 19".hexToBytes(), creationTime = 0, expireTime = 0),
psKeyMap = mutableMapOf(),
pt4TokenMap = mutableMapOf(),
d2 = KeyWithExpiry(data = "81 00 07 64 11".hexToBytes(), creationTime = 0, expireTime = 0),
d2Key = "404 not found!!!!!!".toByteArray(),
payToken = "What's this".toByteArray(),
pf = "> 1 + 1 == 11\n< true".toByteArray(),
pfKey = "Don't change anything if it runs".toByteArray(),
da2 = "sudo rm -rf /".toByteArray(),
wtSessionTicket = KeyWithCreationTime(data = "deluser root".toByteArray(), creationTime = 0),
wtSessionTicketKey = "500 Server Internal Error".toByteArray(),
deviceToken = "Winserver datacenter 2077".toByteArray(),
)
bot.client._bot = bot
network.setStateOK(channel)
removeOutgoingPacketEncoder()
}
}