| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- # tests/test_network_stubs.py
- """NetClientStub + NetworkCtlStub: 真实环回 socket 模拟网关。"""
- import socket
- import struct
- import sys
- import threading
- import lupa.luajit21 as lj
- sys.path.insert(0, "protocol_bot")
- from encode6bitbuf_final import encode6 # type: ignore # noqa: E402
- from apilot.stubs.netclient import NetClientStub # noqa: E402
- from apilot.stubs.networkctl import NetworkCtlStub, dispatch_frame # noqa: E402
- def _build_frame(msg_id: int, body: bytes) -> bytes:
- """encode6(9×i32 header) + body。字段序对齐 wire.pack_frame。"""
- head = struct.pack("<9i", 0, msg_id, 1, 0, 0, 0, 0, len(body), 1)
- return encode6(head) + body
- def _spawn_gateway(handler):
- """启一个临时监听,handler(server_sock) 在调用线程同步完成一次会话。"""
- srv = socket.socket()
- srv.bind(("127.0.0.1", 0))
- srv.listen(1)
- port = srv.getsockname()[1]
- threading.Thread(target=handler, args=(srv,), daemon=True).start()
- return port
- def _fake_gateway_echo529(server_sock):
- """收一帧, 回一个 529 帧。body 在线缆上是 raw bytes(仅 header 编码)。"""
- conn, _ = server_sock.accept()
- try:
- conn.recv(65536) # drain client frame
- conn.sendall(_build_frame(529, b"key32/session123"))
- finally:
- conn.close()
- server_sock.close()
- def test_sendmsg_roundtrip_and_dispatch():
- port = _spawn_gateway(_fake_gateway_echo529)
- nc = NetClientStub()
- nc.connect("127.0.0.1", port)
- ctl = NetworkCtlStub(nc)
- ctl.send_msg(2001, 123456, 1, 2, 3, b"uid/key/ch/1/0", 19)
- frames = nc.tick(1.0)
- assert any(f.msg_id == 529 for f in frames), f"expected 529 in {frames}"
- rt = lj.LuaRuntime()
- rt.execute("""
- got = nil
- function on_529(msg)
- local h = msg:GetHeader()
- local data = msg:GetData()
- got = h.msgId .. ":" .. data:ReadString(5)
- end
- """)
- ctl.register_lua_handler(529, rt.eval("on_529"))
- target = next(f for f in frames if f.msg_id == 529)
- dispatch_frame(rt, ctl, target)
- assert rt.eval("got") == "529:key32"
- nc.disconnect()
- def test_register_unregister():
- """register_lua_handler 覆盖, unregister_all 清空。"""
- nc = NetClientStub()
- ctl = NetworkCtlStub(nc)
- rt = lj.LuaRuntime()
- rt.execute("function h(msg) end")
- cb = rt.eval("h")
- ctl.register_lua_handler(10, cb)
- ctl.register_lua_handler(10, cb) # 覆盖
- assert ctl.handlers[10] is cb
- ctl.unregister_all()
- assert ctl.handlers == {}
- def test_dispatch_no_handler_is_noop():
- """无 handler 的帧不抛异常。"""
- nc = NetClientStub()
- ctl = NetworkCtlStub(nc)
- from apilot.wire import Frame
- rt = lj.LuaRuntime()
- dispatch_frame(rt, ctl, Frame(recog=0, msg_id=99999, p1=0, p2=0, p3=0, tail=1, body=b""))
- def test_is_connected_and_disconnect():
- nc = NetClientStub()
- assert not nc.is_connected()
- port = _spawn_gateway(_fake_gateway_echo529)
- nc.connect("127.0.0.1", port)
- assert nc.is_connected()
- nc.disconnect()
- assert not nc.is_connected()
|