//go:build linux package transport import ( "testing" "omnisocketgo/cmd/internal/latencylog" "omnisocketgo/cmd/internal/protocol" ) func TestKCPLinuxPacketDebugLogsKernelEvents(t *testing.T) { senderPacketLogger := &recordingKCPPacketDebugLogger{} receiverPacketLogger := &recordingKCPPacketDebugLogger{} sender, accepted, cleanup := newKCPConnPair(t, nil, nil, senderPacketLogger, receiverPacketLogger) defer cleanup() msg := protocol.Message{ Type: protocol.MessageTypeText, ID: 1, From: "peer-a", To: "peer-b", Body: []byte("hello kcp linux"), } sendErr := make(chan error, 1) go func() { sendErr <- sender.Send(msg) }() receiver := awaitAcceptedKCPConn(t, accepted) if _, err := receiver.Receive(); err != nil { t.Fatalf("receiver.Receive() error = %v", err) } if err := <-sendErr; err != nil { t.Fatalf("sender.Send() error = %v", err) } waitForKCPPacketRecords(t, senderPacketLogger, func(records []KCPPacketDebugRecord) bool { return hasKCPPacketEvent(records, latencylog.EventATXSched) && hasKCPPacketEvent(records, latencylog.EventATXSoftware) }, "sender tx kernel timestamp records") waitForKCPPacketRecords(t, receiverPacketLogger, func(records []KCPPacketDebugRecord) bool { return hasKCPPacketEvent(records, latencylog.EventBRXSoftware) }, "receiver rx kernel timestamp records") senderRecords := senderPacketLogger.Records() receiverRecords := receiverPacketLogger.Records() assertKCPPacketRecord(t, senderRecords, latencylog.EventATXSched, true) assertKCPPacketRecord(t, senderRecords, latencylog.EventATXSoftware, true) assertKCPPacketRecord(t, receiverRecords, latencylog.EventBRXSoftware, false) } func hasKCPPacketEvent(records []KCPPacketDebugRecord, wantEvent string) bool { for _, record := range records { if record.Event == wantEvent { return true } } return false } func assertKCPPacketRecord(t *testing.T, records []KCPPacketDebugRecord, wantEvent string, wantUDPTXID bool) { t.Helper() for _, record := range records { if record.Event != wantEvent { continue } if record.TSUnixNano <= 0 { t.Fatalf("record %s timestamp must be positive: %+v", wantEvent, record) } if record.PacketBytes <= 0 { t.Fatalf("record %s packet bytes must be positive: %+v", wantEvent, record) } if record.KCPConv == nil { t.Fatalf("record %s missing kcp_conv: %+v", wantEvent, record) } if len(record.Segments) == 0 { t.Fatalf("record %s missing parsed segments: %+v", wantEvent, record) } if wantUDPTXID && record.UDPTXID == nil { t.Fatalf("record %s missing udp_tx_id: %+v", wantEvent, record) } if !wantUDPTXID && record.UDPTXID != nil { t.Fatalf("record %s unexpected udp_tx_id: %+v", wantEvent, record) } return } t.Fatalf("missing KCP packet debug event %s in %+v", wantEvent, records) }