package main import ( "net" "testing" "time" "dragontcp/internal/cover" "dragontcp/internal/wire" ) func TestAdaptiveSizerRecoversFromMinimum(t *testing.T) { opts := chunkClientOptions{ startSize: 64, minSize: 32, maxSize: 1024, adaptive: true, adaptSuccesses: 2, } s := newAdaptiveSizer("test", 64, opts) _, next := s.Failure(64) if next != 32 { t.Fatalf("failure should reduce 64 -> 32, got %d", next) } for i := 0; i < 16; i++ { s.Success(32) } if got := s.Current(); got <= 32 { t.Fatalf("adaptive controller remained stuck at minimum: %d", got) } } func TestReconnectAutoLearnsFromRealReuseFailure(t *testing.T) { ln, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } defer ln.Close() serverErr := make(chan error, 1) go func() { first, err := ln.Accept() if err != nil { serverErr <- err return } if _, err := wire.ReadRequest(first); err != nil { serverErr <- err return } if err := wire.WriteResponse(first, wire.StatusOK, nil); err != nil { serverErr <- err return } _ = first.Close() // Force the next logical request to reconnect. second, err := ln.Accept() if err != nil { serverErr <- err return } defer second.Close() if _, err := wire.ReadRequest(second); err != nil { serverErr <- err return } serverErr <- wire.WriteResponse(second, wire.StatusOK, nil) }() lane := newRequestLane(ln.Addr().String(), 0, 1, time.Second, 0, cover.Profile{}) defer lane.Close() if !lane.autoReconnect || lane.reconnectEvery != 0 { t.Fatalf("auto lane started auto=%t reconnectEvery=%d", lane.autoReconnect, lane.reconnectEvery) } var sid wire.SessionID if status, _, err := lane.single(wire.ModeProbe, sid, 1, nil); err != nil || status != wire.StatusOK { t.Fatalf("first request status=%d err=%v", status, err) } if status, _, err := lane.single(wire.ModeProbe, sid, 2, nil); err != nil || status != wire.StatusOK { t.Fatalf("retried request status=%d err=%v", status, err) } if lane.reconnectEvery != 1 || lane.pc != nil { t.Fatalf("auto lane did not learn single-request mode: reconnectEvery=%d pc=%v", lane.reconnectEvery, lane.pc) } if err := <-serverErr; err != nil { t.Fatal(err) } } func TestReconnectZeroMeansPersistent(t *testing.T) { lane := newRequestLane("127.0.0.1:1", 0, 0, 0, 0, cover.Profile{}) if lane.reconnectEvery != 0 { t.Fatalf("reconnectEvery=%d, want 0", lane.reconnectEvery) } } func TestBPAutoStartsPersistent(t *testing.T) { lane := newBPLane("127.0.0.1:1", 0, 1, time.Second, cover.Profile{}) if !lane.autoReconnect || lane.reconnectEvery != 0 { t.Fatalf("BP auto lane started auto=%t reconnectEvery=%d", lane.autoReconnect, lane.reconnectEvery) } }