diff --git a/sdn_tests/pins_ondatra/tests/inband_sw_interface_dual_switch_test.go b/sdn_tests/pins_ondatra/tests/inband_sw_interface_dual_switch_test.go index c6e2075a7b2..d5900128f49 100644 --- a/sdn_tests/pins_ondatra/tests/inband_sw_interface_dual_switch_test.go +++ b/sdn_tests/pins_ondatra/tests/inband_sw_interface_dual_switch_test.go @@ -105,3 +105,130 @@ func mockConfigPush(t *testing.T) { calledMockConfigPush = true } + +// Tests start here. +func TestMain(m *testing.M) { + ondatra.RunTests(m, pinsbind.New) +} + +// TestGNMIInbandSwLoopbackInCnts - Check Loopback0 in-traffic counters +func TestGNMIInbandSwLoopbackInCnts(t *testing.T) { + const ( + pktsPerTry uint64 = 50 + counterUpdateDelay = 1500 * time.Millisecond + packetPayloadSize = 1000 + ) + + // Report results to TestTracker at the end. + defer testhelper.NewTearDownOptions(t).WithID("8e6b32f4-cf39-419f-ba36-db9c778ad317").Teardown(t) + + dut := ondatra.DUT(t, "DUT") + control := ondatra.DUT(t, "CONTROL") + mockConfigPush(t) + + // Select a random front panel interface EthernetX. + params := testhelper.RandomInterfaceParams{ + PortList: []string{ + dut.Port(t, "port1").Name(), + dut.Port(t, "port2").Name(), + dut.Port(t, "port3").Name(), + dut.Port(t, "port4").Name(), + }} + intf, err := testhelper.RandomInterface(t, dut, ¶ms) + if err != nil { + t.Fatalf("Failed to fetch random interface: %v", err) + } + + bad := false + i := 0 + + // Iterate up to 5 times to get a successful test. + for i = 1; i <= 5; i++ { + t.Logf("\n----- TestGNMIInbandSwLoopbackInCnts: Iteration %v -----\n", i) + bad = false + + // Read all the relevant counters initial values. + before := readCounters(t, dut, inbandSwIntfName) + + // Construct packet. + eth := &layers.Ethernet{ + SrcMAC: net.HardwareAddr{0x00, 0x11, 0x22, 0x33, 0x44, 0x55}, + DstMAC: net.HardwareAddr{0x00, 0x1a, 0x11, 0x17, 0x5f, 0x80}, + EthernetType: layers.EthernetTypeIPv4, + } + ip := &layers.IPv4{ + Version: 4, + TTL: 64, + Protocol: layers.IPProtocolTCP, + SrcIP: net.ParseIP("2.2.2.2").To4(), + DstIP: net.ParseIP(configuredIPv4Path).To4(), + } + tcp := &layers.TCP{ + SrcPort: 10000, + DstPort: 22, + Seq: 11050, + } + // Required for checksum computation. + tcp.SetNetworkLayerForChecksum(ip) + + data := make([]byte, packetPayloadSize) + for i := range data { + data[i] = 0xfe + } + payload := gopacket.Payload(data) + + buf := gopacket.NewSerializeBuffer() + + // Enable reconstruction of length and checksum fields based on packet headers. + opts := gopacket.SerializeOptions{ + FixLengths: true, + ComputeChecksums: true, + } + if err := gopacket.SerializeLayers(buf, opts, eth, ip, tcp, payload); err != nil { + t.Fatalf("Failed to serialize packet (%v)", err) + } + + // Compute the expected counters after the test. + expect := before + // Currently, counter increasing is not supported on loopback (b/197764888) + // Uncomment below 2 lines when it becomes supported. + // expect.inPkts += pktsPerTry + // expect.inOctets += pktsPerTry * uint64(len(buf.Bytes())) + + packetOut := &testhelper.PacketOut{ + EgressPort: intf, // or "Ethernet8" for testing + Count: uint(pktsPerTry), + Interval: 1 * time.Millisecond, + Packet: buf.Bytes(), + } + + p4rtClient, err := testhelper.FetchP4RTClient(t, control, control.RawAPIs().P4RT(t), nil) + if err != nil { + t.Fatalf("Failed to create P4RT client: %v", err) + } + if err := p4rtClient.SendPacketOut(t, packetOut); err != nil { + t.Fatalf("SendPacketOut operation failed for %+v (%v)", packetOut, err) + } + + // Sleep for enough time that the counters are polled after the + // transmit completes sending bytes. At 500ms we frequently + // read the counters before they're updated. + time.Sleep(counterUpdateDelay) + + // Read all the relevant counters again. + if after := readCounters(t, dut, inbandSwIntfName); *after != *expect { + showCountersDelta(t, before, after, expect) + bad = true + } + + if !bad { + break + } + } + + if bad { + t.Fatalf("\n\n----- TestGNMIInbandSwLoopbackInCnts: FAILED after %v Iterations -----\n\n", i-1) + } + + t.Logf("\n\n----- TestGNMIInbandSwLoopbackInCnts: SUCCESS after %v Iteration(s) -----\n\n", i) +}