xnet: keep working on TCPExchange test

This commit is contained in:
Patricio Whittingslow
2025-10-19 14:33:45 -03:00
parent d731106c51
commit 5c219ebbd5
+86 -29
View File
@@ -1,6 +1,7 @@
package xnet package xnet
import ( import (
"bytes"
"net/netip" "net/netip"
"testing" "testing"
@@ -11,6 +12,7 @@ import (
const ( const (
synack = tcp.FlagSYN | tcp.FlagACK synack = tcp.FlagSYN | tcp.FlagACK
pshack = tcp.FlagPSH | tcp.FlagACK
) )
func TestABC(t *testing.T) { func TestABC(t *testing.T) {
@@ -76,64 +78,119 @@ func TestABC(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
var expected = []struct { tst := tester{
fromClient bool t: t, buf: make([]byte, MTU),
flags tcp.Flags }
}{ const flagNoData = tcp.Flags(0)
noMoreData := []tcpExpectExchange{{SourceIdx: 0, WantFlags: flagNoData}, {SourceIdx: 1, WantFlags: flagNoData}}
expected := []tcpExpectExchange{
{ {
fromClient: true, SourceIdx: 0,
flags: tcp.FlagSYN, WantFlags: tcp.FlagSYN,
}, },
{ {
fromClient: false, SourceIdx: 1,
flags: synack, WantFlags: synack,
}, },
{ {
fromClient: true, SourceIdx: 0,
flags: tcp.FlagACK, WantFlags: tcp.FlagACK,
}, },
} }
var cap pcap.PacketBreakdown expected = append(expected, noMoreData...) // Ensure no data exchanged after expected.
var frms []pcap.Frame for _, wants := range expected {
var buf [MTU]byte tst.TCPExchange(wants, &client, &sv)
for _, action := range expected { }
sendData := []byte("hello")
_, err = clconn.Write(sendData)
if err != nil {
t.Fatal(err)
}
expected = []tcpExpectExchange{
{
SourceIdx: 0,
WantFlags: pshack,
WantData: sendData,
},
{
SourceIdx: 1,
WantFlags: tcp.FlagACK,
},
}
expected = append(expected, noMoreData...) // Ensure no data exchanged after expected.
for _, wants := range expected {
tst.TCPExchange(wants, &client, &sv)
}
}
type tester struct {
t *testing.T
cap pcap.PacketBreakdown
frmbuf []pcap.Frame
buf []byte
}
type tcpExpectExchange struct {
SourceIdx int
WantFlags tcp.Flags
WantData []byte
}
func (tst *tester) TCPExchange(expect tcpExpectExchange, stack1, stack2 *StackAsync) {
t := tst.t
buf := tst.buf
nodata := expect.WantFlags == 0
var n int var n int
switch action.fromClient { var err error
case true: switch expect.SourceIdx {
n, err = client.Encapsulate(buf[:], 0) case 0:
case false: n, err = stack1.Encapsulate(buf[:], 0)
n, err = sv.Encapsulate(buf[:], 0) case 1:
n, err = stack2.Encapsulate(buf[:], 0)
default:
panic("OOB")
} }
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} else if n == 0 { } else if n == 0 {
if nodata {
return // No data sent and no data expected.
}
t.Error("zero bits sent") t.Error("zero bits sent")
} }
frms, err = cap.CaptureEthernet(frms[:0], buf[:n], 0) tst.frmbuf, err = tst.cap.CaptureEthernet(tst.frmbuf[:0], buf[:n], 0)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
tfrm := getProtoFrame(frms, lneto.IPProtoTCP) tfrm := getProtoFrame(tst.frmbuf, lneto.IPProtoTCP)
if tfrm == nil { if tfrm == nil {
t.Fatal("where's the TCP?") t.Fatal("where's the TCP?")
} }
fidx, _ := tfrm.FieldByClass(pcap.FieldClassFlags) fidx, _ := tfrm.FieldByClass(pcap.FieldClassFlags)
flags, _ := tfrm.FieldAsUint(fidx, buf[:n]) flags, _ := tfrm.FieldAsUint(fidx, buf[:n])
tflags := tcp.Flags(flags) tflags := tcp.Flags(flags)
if tflags != action.flags { var payload []byte
t.Errorf("expected flags %s, got %s", action.flags.String(), tflags.String()) fidx, _ = tfrm.FieldByClass(pcap.FieldClassPayload)
if fidx > 0 {
fieldPayload := tfrm.Fields[fidx]
payload = buf[fieldPayload.FrameBitOffset*8:]
} }
switch action.fromClient { if !bytes.Equal(payload, expect.WantData) {
case true: t.Errorf("mismatched data sent, \nwant=%q\ngot=%q\n", expect.WantData, payload)
err = sv.Demux(buf[:], 0) }
case false: if tflags != expect.WantFlags {
err = client.Demux(buf[:], 0) t.Errorf("expected flags %s, got %s", expect.WantFlags.String(), tflags.String())
}
switch expect.SourceIdx {
case 0:
err = stack2.Demux(buf[:], 0)
case 1:
err = stack1.Demux(buf[:], 0)
} }
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
} }
}
func getProtoFrame(frms []pcap.Frame, proto any) *pcap.Frame { func getProtoFrame(frms []pcap.Frame, proto any) *pcap.Frame {
for i := range frms { for i := range frms {