fix: tx-debug-udp 日志的写入以及发送日志调试

This commit is contained in:
2026-03-24 18:02:38 +08:00
parent 9503862eda
commit 97eb3163db
6 changed files with 570 additions and 98 deletions

View File

@@ -4,15 +4,56 @@ import (
"net"
"os"
"path/filepath"
"sync"
"testing"
"time"
"omnisocketgo/cmd/internal/latencylog"
"omnisocketgo/cmd/internal/protocol"
"omnisocketgo/cmd/internal/server"
"omnisocketgo/cmd/internal/transport"
)
// TestUDPDialAndSendText 验证 UDP 客户端可以成功连接、注册并发送文本消息。
type recordingLatencyLogger struct {
mu sync.Mutex
events []latencylog.Event
}
func (l *recordingLatencyLogger) LogEvent(event latencylog.Event) error {
l.mu.Lock()
defer l.mu.Unlock()
l.events = append(l.events, event)
return nil
}
func (l *recordingLatencyLogger) Events() []latencylog.Event {
l.mu.Lock()
defer l.mu.Unlock()
return append([]latencylog.Event(nil), l.events...)
}
type recordingUDPTXTimestampDebugLogger struct {
mu sync.Mutex
records []transport.TXTimestampDebugRecord
}
func (l *recordingUDPTXTimestampDebugLogger) LogTXTimestampDebugRecord(record transport.TXTimestampDebugRecord) error {
l.mu.Lock()
defer l.mu.Unlock()
l.records = append(l.records, record)
return nil
}
func (l *recordingUDPTXTimestampDebugLogger) Records() []transport.TXTimestampDebugRecord {
l.mu.Lock()
defer l.mu.Unlock()
return append([]transport.TXTimestampDebugRecord(nil), l.records...)
}
func TestUDPDialAndSendText(t *testing.T) {
hubAddr := startUDPTestHub(t)
@@ -28,15 +69,12 @@ func TestUDPDialAndSendText(t *testing.T) {
}
defer clientB.Close()
// 等待注册被处理
time.Sleep(50 * time.Millisecond)
// peer-a 发送文本给 peer-b
if err := clientA.SendText("peer-b", "hello from udp"); err != nil {
t.Fatalf("SendText() error = %v", err)
}
// peer-b 接收
msg := receiveUDPClientMessage(t, clientB)
if msg.Type != protocol.MessageTypeText {
t.Fatalf("message type = %s, want text", msg.Type)
@@ -46,7 +84,6 @@ func TestUDPDialAndSendText(t *testing.T) {
}
}
// TestUDPClientID 验证 ID() 返回正确的 peer 标识。
func TestUDPClientID(t *testing.T) {
hubAddr := startUDPTestHub(t)
@@ -61,7 +98,6 @@ func TestUDPClientID(t *testing.T) {
}
}
// TestUDPClientPersistMessage 验证 UDP 客户端可以将消息持久化到磁盘。
func TestUDPClientPersistMessage(t *testing.T) {
hubAddr := startUDPTestHub(t)
@@ -73,7 +109,6 @@ func TestUDPClientPersistMessage(t *testing.T) {
inboxDir := t.TempDir()
// 持久化文本消息
textMsg := protocol.Message{
Type: protocol.MessageTypeText,
ID: 1,
@@ -90,7 +125,6 @@ func TestUDPClientPersistMessage(t *testing.T) {
t.Fatalf("PersistMessage(text) returned empty path")
}
// 持久化文件消息
fileMsg := protocol.Message{
Type: protocol.MessageTypeFile,
ID: 2,
@@ -114,7 +148,6 @@ func TestUDPClientPersistMessage(t *testing.T) {
}
}
// TestUDPClientSendFile 验证 UDP 客户端可以发送文件消息。
func TestUDPClientSendFile(t *testing.T) {
hubAddr := startUDPTestHub(t)
@@ -149,8 +182,83 @@ func TestUDPClientSendFile(t *testing.T) {
}
}
// startUDPTestHub 创建并启动一个测试用 UDPHub。
func TestUDPClientBidirectionalLogsAndServerDiagnostics(t *testing.T) {
serverLogger := &recordingLatencyLogger{}
serverDebugLogger := &recordingUDPTXTimestampDebugLogger{}
hubAddr := startUDPTestHubWithOptions(
t,
server.WithUDPLogger(serverLogger),
server.WithUDPTXTimestampDebugLogger(serverDebugLogger),
)
clientALogger := &recordingLatencyLogger{}
clientADebugLogger := &recordingUDPTXTimestampDebugLogger{}
clientA, err := DialUDP(
hubAddr.String(),
"peer-a",
WithLogger(clientALogger),
WithTXTimestampDebugLogger(clientADebugLogger),
)
if err != nil {
t.Fatalf("DialUDP(peer-a) error = %v", err)
}
defer clientA.Close()
clientBLogger := &recordingLatencyLogger{}
clientBDebugLogger := &recordingUDPTXTimestampDebugLogger{}
clientB, err := DialUDP(
hubAddr.String(),
"peer-b",
WithLogger(clientBLogger),
WithTXTimestampDebugLogger(clientBDebugLogger),
)
if err != nil {
t.Fatalf("DialUDP(peer-b) error = %v", err)
}
defer clientB.Close()
time.Sleep(50 * time.Millisecond)
if err := clientA.SendText("peer-b", "hello from peer-a"); err != nil {
t.Fatalf("clientA.SendText() error = %v", err)
}
msgFromA := receiveUDPClientMessage(t, clientB)
if string(msgFromA.Body) != "hello from peer-a" {
t.Fatalf("message body = %q, want %q", string(msgFromA.Body), "hello from peer-a")
}
if err := clientB.SendText("peer-a", "hello from peer-b"); err != nil {
t.Fatalf("clientB.SendText() error = %v", err)
}
msgFromB := receiveUDPClientMessage(t, clientA)
if string(msgFromB.Body) != "hello from peer-b" {
t.Fatalf("message body = %q, want %q", string(msgFromB.Body), "hello from peer-b")
}
assertPeerEvent(t, clientBLogger.Events(), latencylog.EventBRXSoftware, "peer-a", "peer-b", msgFromA.ID)
assertPeerEvent(t, clientBLogger.Events(), latencylog.EventBAppRecv, "peer-a", "peer-b", msgFromA.ID)
assertPeerEvent(t, clientALogger.Events(), latencylog.EventBRXSoftware, "peer-b", "peer-a", msgFromB.ID)
assertPeerEvent(t, clientALogger.Events(), latencylog.EventBAppRecv, "peer-b", "peer-a", msgFromB.ID)
if len(clientADebugLogger.Records()) == 0 {
t.Fatal("clientA debug records = 0, want at least 1")
}
if len(clientBDebugLogger.Records()) == 0 {
t.Fatal("clientB debug records = 0, want at least 1")
}
if len(serverLogger.Events()) == 0 {
t.Fatal("server latency events = 0, want at least 1")
}
if len(serverDebugLogger.Records()) == 0 {
t.Fatal("server debug records = 0, want at least 1")
}
}
func startUDPTestHub(t *testing.T) *net.UDPAddr {
return startUDPTestHubWithOptions(t)
}
func startUDPTestHubWithOptions(t *testing.T, opts ...server.UDPOption) *net.UDPAddr {
t.Helper()
addr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0")
@@ -163,7 +271,7 @@ func startUDPTestHub(t *testing.T) *net.UDPAddr {
t.Fatalf("ListenUDP() error = %v", err)
}
hub, err := server.NewUDPHub(conn)
hub, err := server.NewUDPHub(conn, opts...)
if err != nil {
_ = conn.Close()
t.Fatalf("NewUDPHub() error = %v", err)
@@ -180,7 +288,6 @@ func startUDPTestHub(t *testing.T) *net.UDPAddr {
return conn.LocalAddr().(*net.UDPAddr)
}
// receiveUDPClientMessage 从 UDP 客户端接收一条消息,带超时。
func receiveUDPClientMessage(t *testing.T, client *UDPClient) protocol.Message {
t.Helper()
@@ -207,5 +314,24 @@ func receiveUDPClientMessage(t *testing.T, client *UDPClient) protocol.Message {
}
}
func assertPeerEvent(t *testing.T, events []latencylog.Event, wantEvent, wantFrom, wantTo string, wantMessageID uint64) {
t.Helper()
for _, event := range events {
if event.Event != wantEvent {
continue
}
if event.From != wantFrom || event.To != wantTo || event.MessageID != wantMessageID {
continue
}
if event.TsUnixNano <= 0 {
t.Fatalf("event %s timestamp must be positive: %+v", wantEvent, event)
}
return
}
t.Fatalf("missing event %s from %s to %s for message %d in %+v", wantEvent, wantFrom, wantTo, wantMessageID, events)
}
// Ensure transport package is used (needed for WithTXTimestampDebugLogger option).
var _ transport.TXTimestampDebugLogger = nil