From 2a60f932de73ff77ea69f7653aa2b1f73f80d0e4 Mon Sep 17 00:00:00 2001 From: Darren Loher Date: Tue, 5 Sep 2023 20:42:13 -0700 Subject: [PATCH 01/43] Enable firmware validation for transceiver (#2091) --- .../tests/telemetry_inventory_test/telemetry_inventory_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/platform/tests/telemetry_inventory_test/telemetry_inventory_test.go b/feature/platform/tests/telemetry_inventory_test/telemetry_inventory_test.go index 00ed8402bc1..9a8136eba04 100644 --- a/feature/platform/tests/telemetry_inventory_test/telemetry_inventory_test.go +++ b/feature/platform/tests/telemetry_inventory_test/telemetry_inventory_test.go @@ -236,7 +236,7 @@ func TestHardwareCards(t *testing.T) { mfgDateValidation: false, swVerValidation: false, hwVerValidation: true, - fwVerValidation: false, + fwVerValidation: true, rrValidation: false, operStatus: oc.PlatformTypes_COMPONENT_OPER_STATUS_UNSET, parentValidation: false, From 69fcf72cea2423391199469a2b259ab7b3d915e8 Mon Sep 17 00:00:00 2001 From: jasdeep-hundal Date: Wed, 6 Sep 2023 09:48:26 -0700 Subject: [PATCH 02/43] Add port PMD type to binding proto (#2090) Fixes https://github.com/openconfig/featureprofiles/issues/1440 --- topologies/binding/binding.go | 7 +++++ topologies/proto/binding.proto | 3 ++ topologies/proto/binding/binding.pb.go | 43 +++++++++++++++++--------- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/topologies/binding/binding.go b/topologies/binding/binding.go index 692d5f4e6be..a00485e5297 100644 --- a/topologies/binding/binding.go +++ b/topologies/binding/binding.go @@ -384,6 +384,13 @@ func ports(tports []*opb.Port, bports []*bindpb.Port) (map[string]*binding.Port, } p.Speed = bport.Speed } + // Populate the PMD type if configured. + if bport.Pmd != opb.Port_PMD_UNSPECIFIED { + if p.PMD != opb.Port_PMD_UNSPECIFIED && p.PMD != bport.Pmd { + return nil, fmt.Errorf("binding port PMD type %v and testbed port PMD type %v do not match", bport.Pmd, p.PMD) + } + p.PMD = bport.Pmd + } } } for id, p := range portmap { diff --git a/topologies/proto/binding.proto b/topologies/proto/binding.proto index 9496aefb493..c5703b84624 100644 --- a/topologies/proto/binding.proto +++ b/topologies/proto/binding.proto @@ -149,4 +149,7 @@ message Port { // Speed of the port. ondatra.Port.Speed speed = 3; + + // PMD type of the port. + ondatra.Port.Pmd pmd = 4; } diff --git a/topologies/proto/binding/binding.pb.go b/topologies/proto/binding/binding.pb.go index d15e6b03297..e141489742e 100644 --- a/topologies/proto/binding/binding.pb.go +++ b/topologies/proto/binding/binding.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 +// protoc-gen-go v1.26.0 // protoc v3.21.12 // source: binding.proto @@ -346,7 +346,7 @@ func (x *Device) GetVendor() proto.Device_Vendor { if x != nil { return x.Vendor } - return proto.Device_Vendor(0) + return proto.Device_VENDOR_UNSPECIFIED } func (x *Device) GetHardwareModel() string { @@ -525,6 +525,8 @@ type Port struct { Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // Speed of the port. Speed proto.Port_Speed `protobuf:"varint,3,opt,name=speed,proto3,enum=ondatra.Port_Speed" json:"speed,omitempty"` + // PMD type of the port. + Pmd proto.Port_Pmd `protobuf:"varint,4,opt,name=pmd,proto3,enum=ondatra.Port_Pmd" json:"pmd,omitempty"` } func (x *Port) Reset() { @@ -577,7 +579,14 @@ func (x *Port) GetSpeed() proto.Port_Speed { if x != nil { return x.Speed } - return proto.Port_Speed(0) + return proto.Port_SPEED_UNSPECIFIED +} + +func (x *Port) GetPmd() proto.Port_Pmd { + if x != nil { + return x.Pmd + } + return proto.Port_PMD_UNSPECIFIED } var File_binding_proto protoreflect.FileDescriptor @@ -676,17 +685,19 @@ var file_binding_proto_rawDesc = []byte{ 0x65, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x65, 0x72, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x46, - 0x69, 0x6c, 0x65, 0x22, 0x55, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x69, 0x6c, 0x65, 0x22, 0x7a, 0x0a, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x2e, 0x53, 0x70, - 0x65, 0x65, 0x64, 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x2f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x66, 0x69, - 0x6c, 0x65, 0x73, 0x2f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x65, 0x64, 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x03, 0x70, 0x6d, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, + 0x61, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x2e, 0x50, 0x6d, 0x64, 0x52, 0x03, 0x70, 0x6d, 0x64, 0x42, + 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, + 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, + 0x69, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -710,6 +721,7 @@ var file_binding_proto_goTypes = []interface{}{ (*Port)(nil), // 4: openconfig.testing.Port (proto.Device_Vendor)(0), // 5: ondatra.Device.Vendor (proto.Port_Speed)(0), // 6: ondatra.Port.Speed + (proto.Port_Pmd)(0), // 7: ondatra.Port.Pmd } var file_binding_proto_depIdxs = []int32{ 2, // 0: openconfig.testing.Binding.duts:type_name -> openconfig.testing.Device @@ -728,11 +740,12 @@ var file_binding_proto_depIdxs = []int32{ 3, // 13: openconfig.testing.Device.otg:type_name -> openconfig.testing.Options 5, // 14: openconfig.testing.Device.vendor:type_name -> ondatra.Device.Vendor 6, // 15: openconfig.testing.Port.speed:type_name -> ondatra.Port.Speed - 16, // [16:16] is the sub-list for method output_type - 16, // [16:16] is the sub-list for method input_type - 16, // [16:16] is the sub-list for extension type_name - 16, // [16:16] is the sub-list for extension extendee - 0, // [0:16] is the sub-list for field type_name + 7, // 16: openconfig.testing.Port.pmd:type_name -> ondatra.Port.Pmd + 17, // [17:17] is the sub-list for method output_type + 17, // [17:17] is the sub-list for method input_type + 17, // [17:17] is the sub-list for extension type_name + 17, // [17:17] is the sub-list for extension extendee + 0, // [0:17] is the sub-list for field type_name } func init() { file_binding_proto_init() } From c165aa648c7ecd7fa0f2f0dea51a2a5bbef2bcb4 Mon Sep 17 00:00:00 2001 From: ANISH-GOTTAPU <48308607+ANISH-GOTTAPU@users.noreply.github.com> Date: Thu, 7 Sep 2023 04:08:31 +0530 Subject: [PATCH 03/43] OTG RT5.4: Add FEC related config (#2083) * add FEC related config * address review comment --- .../aggregate_forwarding_viable_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/feature/interface/aggregate/otg_tests/aggregate_forwarding_viable_test/aggregate_forwarding_viable_test.go b/feature/interface/aggregate/otg_tests/aggregate_forwarding_viable_test/aggregate_forwarding_viable_test.go index 894a19b9030..625ada24cdc 100644 --- a/feature/interface/aggregate/otg_tests/aggregate_forwarding_viable_test/aggregate_forwarding_viable_test.go +++ b/feature/interface/aggregate/otg_tests/aggregate_forwarding_viable_test/aggregate_forwarding_viable_test.go @@ -365,6 +365,21 @@ func (tc *testArgs) configureATE(t *testing.T) { } } + // Disable FEC for 100G-FR ports because Novus does not support it. + p100gbasefr := []string{} + for _, p := range tc.atePorts { + if p.PMD() == ondatra.PMD100GBASEFR { + p100gbasefr = append(p100gbasefr, p.ID()) + } + } + + if len(p100gbasefr) > 0 { + l1Settings := tc.top.Layer1().Add().SetName("L1").SetPortNames(p100gbasefr) + l1Settings.SetAutoNegotiate(true).SetIeeeMediaDefaults(false).SetSpeed("speed_100_gbps") + autoNegotiate := l1Settings.AutoNegotiation() + autoNegotiate.SetRsFec(false) + } + dstDev := tc.top.Devices().Add().SetName(agg.Name()) dstEth := dstDev.Ethernets().Add().SetName(ateDst.Name + ".Eth").SetMac(ateDst.MAC) dstEth.Connection().SetLagName(agg.Name()) From d1bdbd77b8e973544bca7da67777f6b9ad17a57c Mon Sep 17 00:00:00 2001 From: rszarecki <46606165+rszarecki@users.noreply.github.com> Date: Thu, 7 Sep 2023 10:51:17 -0700 Subject: [PATCH 04/43] DP-1.14 TestPlan: QoS DSCP transparecny with ECN (#2076) --- .../ecn/otg_tests/DSCP-transparency/README.md | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 feature/qos/ecn/otg_tests/DSCP-transparency/README.md diff --git a/feature/qos/ecn/otg_tests/DSCP-transparency/README.md b/feature/qos/ecn/otg_tests/DSCP-transparency/README.md new file mode 100644 index 00000000000..6eec6f86e7a --- /dev/null +++ b/feature/qos/ecn/otg_tests/DSCP-transparency/README.md @@ -0,0 +1,128 @@ + +# DP-1.14: DSCP transperency with ECN + +## Summary + +This test evaluates if all 64 combination of DSCP bits are transparently handled while ECN bits are rewritten. + +## Testbed type + +* TESTBED_DUT_ATE_4LINKS + +## Procedure + +### Testbed configuration +* Connect DUTPort1 with OTGPort1, DUTPort2 with OTGPort2, DUTPort2 with OTGPort2; Assigne IPv4 and IPv6 addresses on all. +* All 3 ports are of the same speed (100GE) +* Configure QoS + * DSCP classifier for IPv4 and IPv4 as below: + |DSCP (dec)|Traffic-group| + |--|--| + |48-63|NC1| + |32-47|AF4| + |24-31|AF3| + |16-23|AF2| + |8-15|AF1| + |4-7|BE0| + |0-3|BE1| + * 7 queues and 7 corresponding forwarding group + * Scheduler policy with + * one scheduler of STRICT priority type serving NC1 queue + * one scheduler of WRR type serving 6 queues AF4, AF3, AF2, AF1, BE0, BE1 with equal weights 10:10:10:10:10:10 respectivly + * queue-management profile of WRED type with: + * min-treshold: 80KB + * max-treshold: 3MB + * max-drop-percentage: 100 + * ecn: enabled + * attach queue-management profile to queues NC1, AF4, AF3, AF2, AF1, BE0, BE1; + * attach scheduler-map to DUTPort3 egress + * attach classifier to DUTPort1 nad DUTPort2 ingress + +### Sub Test #1 - No-Congestion +* Generate 64 flows of traffic form ATEPort1 toward ATEPort3 + * each flow has distinct DSCP value + * every packet has ECT(0) set + * all flows of equal bps rate. + * total load - 60% (60Gbps) +* wait 1 minutes; stop traffic generation. +* Verify using DUTPort3 telemetry that: + * no drops are seen in any of queues on DUTPort3 + * all queues reports non-zero transmit packets, octets. +* Verify on ATEPort3 that all flows are recived w/o DSCP modification -all 64 values are observed +* verify on ATEPort3 that all recived packet has ECT(0) ECN value +### Sub Test #2 - Congestion +* Generate 64 flows of traffic form ATEPort1 and 64 flows of traffic form ATEPort2 toward ATEPort3 + * each flow form ATEPort1 has distinct DSCP value + * each flow form ATEPort2 has distinct DSCP value + * every packet has ECT(0) set + * all flows are of equal bps rate. + * Offered load: + * ATEPort1 - 60% (60Gbps) + * ATEPort2 - 60% (60Gbps) + * Note: egress port is congested, so do all queues but NC1 (SP) +* wait 1 minutes; stop traffic generation. +* Verify using DUTPort3 telemetry that: + * Drops are seen in all queues except NC1 on DUTPort3 + * all queues reports non-zero transmit packets, octets. +* Verify on ATEPort3 that all flows are recived w/o DSCP modification - all 64 values are observed +* verify on ATEPort3 that: + * all recived packets with DSCP 48-63 has ECT(0) value + * vast majority (almost all) packets with DSCP 0-47 has CE ECN value. +### Sub Test #3 - NC1 congestion +* Generate 16 flows of traffic form ATEPort1 and 16 flows of traffic form ATEPort2 toward ATEPort3 + * each flow form ATEPort1 has distinct DSCP value from 48-63 range + * each flow form ATEPort2 has distinct DSCP value from 48-63 range + * every packet has ECT(0) set + * all flows are of equal bps rate. + * Offered load: + * ATEPort1 - 60% (60Gbps) + * ATEPort2 - 60% (60Gbps) + * Note: egress port is congested, so do NC1 (SP) queue +* wait 1 minutes; stop traffic generation. +* Verify using DUTPort3 telemetry that: + * Drops are seen in NC1 queue on DUTPort3 + * all queues but NC1 reports nzero transmit packets, octets. + * NC1 queue reports non-zero transmit packets, octets. +* Verify on ATEPort3 that all flows are recived w/o DSCP modification - all 16 values are observed. +* verify on ATEPort3 that: + * all recived packets with DSCP has CE value + +## Config Parameter Coverage + + * qos/classifiers/classifier/terms/term/conditions/ipv4/config/dscp-set + * qos/classifiers/classifier/terms/term/conditions/ipv6/config/dscp-set + * qos/classifiers/classifier/terms/term/actions/config/target-group + * qos/queues/queue/config/name + * qos/forwarding-groups/forwarding-group/config/name + * qos/forwarding-groups/forwarding-group/config/output-queue + * qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/priority + * qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/sequence + * qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/id + * qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type + * qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue + * qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight + * qos/queue-management-profiles/queue-management-profile/wred/uniform/config/enable-ecn + * qos/queue-management-profiles/queue-management-profile/wred/uniform/config/max-drop-probability-percent + * qos/queue-management-profiles/queue-management-profile/wred/uniform/config/max-threshold + * qos/queue-management-profiles/queue-management-profile/wred/uniform/config/min-threshold + * qos/interfaces/interface/output/queues/queue/config/name + * qos/interfaces/interface/output/queues/queue/config/queue-management-profile + * qos/interfaces/interface/output/scheduler-policy/config/name + * qos/interfaces/interface/input/classifiers/classifier/config/name + * qos/interfaces/interface/input/classifiers/classifier/config/type + +## Telemetry Parameter Coverage + + * qos/interfaces/interface/output/queues/queue/state/dropped-octets + * qos/interfaces/interface/output/queues/queue/state/dropped-pkts + * qos/interfaces/interface/output/queues/queue/state/name + * qos/interfaces/interface/output/queues/queue/state/transmit-octets + * qos/interfaces/interface/output/queues/queue/state/transmit-pkts + +## Protocol/RPC Parameter Coverage + + * NONE. + +## Required DUT platform + +* FFF From bf85ae217512399b5fb8bb642eb6928ef62d00e2 Mon Sep 17 00:00:00 2001 From: Nicole Jiang <134450120+nicjiang2023@users.noreply.github.com> Date: Thu, 7 Sep 2023 13:46:59 -0700 Subject: [PATCH 05/43] Code commit for Health-1.1: Generic Health Check (#1862) * Code commit for Health-1.1: Generic Health Check * Fix check failures for Check for Rundata * Fix Rundata Check failure * Fix Rundata Check failure * Implement for Health-1.1 Generic Health Check * Fix conflict issue of metadata.proto and metadata.pb.go * Implement review comments and add new deviations for Health-1.1 * Update README.md for Health-1.1 * Add missing periods to metadata.proto * Implement review comments for Health-1.1 * Update metadata.textproto removed the extra space * Update metadata.pb.go * Update metadata.textproto * Update system_generic_health_check_test.go * Update deviations.go * Update metadata.proto * Update metadata.pb.go * Addressing review comments from @greg-dennis * Implemented comments for health-1.1 * Fix typo issue for health-1.1 * Fix bug and remove deviation 1. fix bug(TestSystemAlarms): when there's no alarms, script should not get fail. Use LookupAll to replace GetAll. 2. remove devation qos_input_drop_counter_unsupported 3. add dut.Vendor case in TestNoQueueDrop * Fix Static Analysis Failure for health-1.1 * Implement review comments for health-1.1 1. Import golang.org/x/exp/slices 2. Update func sortedInterfaces: use slices.Sort(interfaces) 3. Remove func contains 4. Update TestControllerCardsNoHighCPUSpike: use slices.Contains 5. Update TestLineCardsNoHighCPUSpike: use slices.Contains * Implement review comments for health-1.1 1. Add value 0 checking 2. Add t.Run 3. Remove switch vendor --------- Co-authored-by: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> Co-authored-by: Arul Kumar Sekar <128646204+arulkumarsekar@users.noreply.github.com> Co-authored-by: Girish Subramanian <103155016+sgirishj@users.noreply.github.com> --- .../system_generic_health_check/README.md | 84 ++ .../metadata.textproto | 20 + .../system_generic_health_check_test.go | 750 ++++++++++++++++++ internal/deviations/deviations.go | 39 + proto/metadata.proto | 16 + proto/metadata_go_proto/metadata.pb.go | 158 +++- 6 files changed, 1032 insertions(+), 35 deletions(-) create mode 100644 feature/experimental/system/health/tests/system_generic_health_check/README.md create mode 100644 feature/experimental/system/health/tests/system_generic_health_check/metadata.textproto create mode 100644 feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go diff --git a/feature/experimental/system/health/tests/system_generic_health_check/README.md b/feature/experimental/system/health/tests/system_generic_health_check/README.md new file mode 100644 index 00000000000..7e7c8e7ab70 --- /dev/null +++ b/feature/experimental/system/health/tests/system_generic_health_check/README.md @@ -0,0 +1,84 @@ +# Health-1.1: Generic Health Check + +## Summary + +Generic Health Check + +## Procedure + +* Capture the generic health check of the DUT, used modularly in pre/post and during various different tests: + * No system/kernel/process/component coredumps + * No high CPU spike or usage on control or forwarding plane + * No high memory utilization or usage on control or forwarding plane + * No processes/daemons high CPU/Memory utilization + * No generic drop counters + * QUEUE drops + * Interfaces + * VOQ + * Fabric drops + * ASIC drops + * No flow control frames tx/rx + * No CRC or Layer 1 errors on interfaces + * No config commit errors + * No system level alarms + * In spec hardware should be in proper state + * No hardware errors + * Major Alarms + * No HW component or SW processes crash +* TODO: + * DDOS/COPP violations + * No memory leaks + * No system errors or logs + * No CRC or Layer 1 errors fabric links + +## Config Parameter Coverage + +N/A + +## Telemetry Parameter Coverage + +* /components/component/state/oper-status +* /components/component/cpu/utilization/state/avg +* /components/component/state/memory +* /system/processes/process/state/cpu-utilization +* /system/processes/process/state/memory-utilization +* /qos/interfaces/interface/input/queues/queue/state/dropped-pkts +* /qos/interfaces/interface/output/queues/queue/state/dropped-pkts +* /qos/interfaces/interface/input/virtual-output-queues/voq-interface/queues/queue/state/dropped-pkts +* /interfaces/interface/state/counters/in-discards +* /interfaces/interface/state/counters/in-errors +* /interfaces/interface/state/counters/in-multicast-pkts +* /interfaces/interface/state/counters/in-unknown-protos +* /interfaces/interface/state/counters/out-discards +* /interfaces/interface/state/counters/out-errors +* /interfaces/interface/state/oper-status +* /interfaces/interface/state/admin-status +* /interfaces/interface/state/counters/out-octets +* /interfaces/interface/state/description +* /interfaces/interface/state/type +* /interfaces/interface/state/counters/out-octets/in-fcs-errors +* /interfaces/interface/subinterfaces/subinterface/state/counters/in-discards +* /interfaces/interface/subinterfaces/subinterface/state/counters/in-errors +* /interfaces/interface/subinterfaces/subinterface/state/counters/in-unknown-protos +* /interfaces/interface/subinterfaces/subinterface/state/counters/out-discards +* /interfaces/interface/subinterfaces/subinterface/state/counters/out-errors +* /interfaces/interface/subinterfaces/subinterface/state/counters/out-octets/in-fcs-errors +* /interfaces/interface/ethernet/state/counters/in-mac-pause-frames +* /interfaces/interface/ethernet/state/counters/out-mac-pause-frames +* /interfaces/interface/ethernet/state/counters/in-crc-errors +* /interfaces/interface/ethernet/state/counters/in-block-errors +* /components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/acl-drops +* /components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/forwarding-policy +* /components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/fragment-total-drops +* /components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/incorrect-software-state +* /components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/invalid-packet +* /components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/no-label +* /components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/no-nexthop +* /components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/no-route +* /components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/rate-limit +* /components/component/integrated-circuit/pipeline-counters/drop/interface-block/state/in-drops +* /components/component/integrated-circuit/pipeline-counters/drop/interface-block/state/out-drops +* /components/component/integrated-circuit/pipeline-counters/drop/interface-block/state/oversubscription +* /components/component/integrated-circuit/pipeline-counters/drop/fabric-block/state/lost-packets + +## Protocol/RPC Parameter Coverage \ No newline at end of file diff --git a/feature/experimental/system/health/tests/system_generic_health_check/metadata.textproto b/feature/experimental/system/health/tests/system_generic_health_check/metadata.textproto new file mode 100644 index 00000000000..f63d54ca10c --- /dev/null +++ b/feature/experimental/system/health/tests/system_generic_health_check/metadata.textproto @@ -0,0 +1,20 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "a01b6e65-3b45-4e0c-a71d-f451c07fec6b" +plan_id: "Health-1.1" +description: "Generic Health Check" +testbed: TESTBED_DUT +platform_exceptions: { + platform: { + vendor: JUNIPER + } + deviations: { + controller_card_cpu_utilization_unsupported: true + linecard_cpu_utilization_unsupported: true + consistent_component_names_unsupported: true + fabric_drop_counter_unsupported: true + linecard_memory_utilization_unsupported: true + qos_voq_drop_counter_unsupported: true + } +} diff --git a/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go b/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go new file mode 100644 index 00000000000..46ec8f358cd --- /dev/null +++ b/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go @@ -0,0 +1,750 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package system_generic_health_check_test + +import ( + "context" + + "regexp" + "testing" + "time" + + "github.com/openconfig/featureprofiles/internal/components" + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ondatra/raw" + "github.com/openconfig/ygnmi/ygnmi" + "golang.org/x/exp/slices" + + fpb "github.com/openconfig/gnoi/file" + hpb "github.com/openconfig/gnoi/healthz" + tpb "github.com/openconfig/gnoi/types" +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +var ( + vendorCoreFilePath = map[ondatra.Vendor]string{ + ondatra.JUNIPER: "/var/core/", + ondatra.CISCO: "/misc/disk1/", + ondatra.NOKIA: "/var/core/", + } + vendorCoreFileNamePattern = map[ondatra.Vendor]*regexp.Regexp{ + ondatra.JUNIPER: regexp.MustCompile(".*.tar.gz"), + ondatra.CISCO: regexp.MustCompile("/misc/disk1/.*core.*"), + ondatra.NOKIA: regexp.MustCompile("/var/core/coredump-.*"), + } +) + +const ( + cpuType = oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_CPU + lineCardType = oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_LINECARD + fabricCardType = oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_FABRIC + controllerCardType = oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_CONTROLLER_CARD +) + +// coreFileCheck function is used to check if cores are found on the DUT. +func coreFileCheck(t *testing.T, dut *ondatra.DUTDevice, gnoiClient raw.GNOI, sysConfigTime uint64, retry bool) { + t.Helper() + t.Log("Checking for core files on DUT") + + dutVendor := dut.Vendor() + // vendorCoreFilePath and vendorCoreProcName should be provided to fetch core file on dut. + if _, ok := vendorCoreFilePath[dutVendor]; !ok { + t.Fatalf("Please add support for vendor %v in var vendorCoreFilePath ", dutVendor) + } + if _, ok := vendorCoreFileNamePattern[dutVendor]; !ok { + t.Fatalf("Please add support for vendor %v in var vendorCoreFileNamePattern.", dutVendor) + } + + in := &fpb.StatRequest{ + Path: vendorCoreFilePath[dutVendor], + } + validResponse, err := gnoiClient.File().Stat(context.Background(), in) + if err != nil { + if retry { + t.Logf("Retry GNOI request to check %v for core files on DUT", vendorCoreFilePath[dutVendor]) + validResponse, err = gnoiClient.File().Stat(context.Background(), in) + } + if err != nil { + t.Fatalf("Unable to stat path %v for core files on DUT, %v", vendorCoreFilePath[dutVendor], err) + } + } + + // Check cores creation time is greater than test start time. + for _, fileStatsInfo := range validResponse.GetStats() { + if fileStatsInfo.GetLastModified() > sysConfigTime { + coreFileName := fileStatsInfo.GetPath() + r := vendorCoreFileNamePattern[dutVendor] + if r.MatchString(coreFileName) { + t.Logf("INFO: Found core %v on DUT.", coreFileName) + } + } + in = &fpb.StatRequest{ + Path: fileStatsInfo.GetPath(), + } + validResponse, err := gnoiClient.File().Stat(context.Background(), in) + if err != nil { + t.Fatalf("Unable to stat path %v for core files on DUT, %v", vendorCoreFilePath[dutVendor], err) + } + for _, fileStatsInfo := range validResponse.GetStats() { + coreFileName := fileStatsInfo.GetPath() + r := vendorCoreFileNamePattern[dutVendor] + if r.MatchString(coreFileName) { + t.Logf("INFO: Found core %v on DUT.", coreFileName) + } + } + } +} + +func sortedInterfaces(ports []*ondatra.Port) []string { + var interfaces []string + for _, port := range ports { + interfaces = append(interfaces, port.Name()) + } + slices.Sort(interfaces) + return interfaces +} + +func removeElement(list []string, element string) []string { + for i := 0; i < len(list); i++ { + if list[i] == element { + list = append(list[:i], list[i+1:]...) + i-- // Adjust index to account for removed element + } + } + return list +} + +func TestCheckForCoreFiles(t *testing.T) { + dut := ondatra.DUT(t, "dut") + timestamp := uint64(time.Now().UTC().Unix()) + gnoiClient := dut.RawAPIs().GNOI().Default(t) + coreFileCheck(t, dut, gnoiClient, timestamp, true) +} + +func TestComponentStatus(t *testing.T) { + dut := ondatra.DUT(t, "dut") + + controllerCards := components.FindComponentsByType(t, dut, controllerCardType) + lineCards := components.FindComponentsByType(t, dut, lineCardType) + fabricCards := components.FindComponentsByType(t, dut, fabricCardType) + checkComponents := append(controllerCards, lineCards...) + checkComponents = append(checkComponents, fabricCards...) + if len(checkComponents) == 0 { + t.Errorf("ERROR: No component has been found.") + } + gnoiClient := dut.RawAPIs().GNOI().New(t) + // check oper-status of the components is Active. + for _, component := range checkComponents { + t.Run(component, func(t *testing.T) { + val, present := gnmi.Lookup(t, dut, gnmi.OC().Component(component).OperStatus().State()).Val() + if !present { + t.Errorf("ERROR: Get component %s oper-status failed", component) + } else { + t.Logf("INFO: Component %s oper-status: %s", component, val) + } + // use gNOI to check components health status is not "unhealthy". + if deviations.ConsistentComponentNamesUnsupported(dut) { + t.Skipf("Skipping test due to deviation consistent_component_names_unsupported") + } + + componentName := map[string]string{"name": component} + req := &hpb.GetRequest{ + Path: &tpb.Path{ + Elem: []*tpb.PathElem{ + {Name: "components"}, + { + Name: "component", + Key: componentName, + }, + }, + }, + } + validResponse, err := gnoiClient.Healthz().Get(context.Background(), req) + if err != nil { + t.Errorf("ERROR: %v", err) + } else { + t.Logf("INFO: Component %s Healthz Status: %s", component, validResponse.GetComponent().Status) + } + }) + } +} + +func TestControllerCardsNoHighCPUSpike(t *testing.T) { + dut := ondatra.DUT(t, "dut") + deviceName := dut.Name() + + if deviations.ControllerCardCPUUtilizationUnsupported(dut) { + t.Skipf("Skipping test due to deviation controller_card_cpu_utilization_unsupported") + } + + controllerCards := components.FindComponentsByType(t, dut, controllerCardType) + cpuCards := components.FindComponentsByType(t, dut, cpuType) + if len(controllerCards) == 0 || len(cpuCards) == 0 { + t.Errorf("ERROR: No controllerCard or cpuCard has been found.") + } + for _, cpu := range cpuCards { + t.Run(cpu, func(t *testing.T) { + query := gnmi.OC().Component(cpu).State() + timestamp := time.Now().Round(time.Second) + component := gnmi.Get(t, dut, query) + cpuParent := component.GetParent() + if cpuParent == "" { + t.Errorf("ERROR: can't find parent information for CPU card %v", component) + } + + if slices.Contains(controllerCards, cpuParent) { + // Remove parent from the list of check cards. + controllerCards = removeElement(controllerCards, cpuParent) + cpuUtilization := component.GetCpu().GetUtilization() + if cpuUtilization.Avg == nil { + t.Errorf("ERROR: %s %s %s Type %-20s - CPU utilization data not available", + timestamp, deviceName, cpu, cpuParent) + } else { + t.Logf("INFO: %s %s Type %-20s %-10s - Utilization: %3d%%", timestamp, deviceName, cpu, cpuParent, cpuUtilization.GetAvg()) + } + } + }) + + } + if len(controllerCards) > 0 { + t.Errorf("ERROR: Didn't find cpu card for checkCards %s", controllerCards) + } +} + +func TestLineCardsNoHighCPUSpike(t *testing.T) { + dut := ondatra.DUT(t, "dut") + deviceName := dut.Name() + + if deviations.LinecardCPUUtilizationUnsupported(dut) { + t.Skipf("Skipping test due to deviation linecard_cpu_ultilization_unsupported") + } + + lineCards := components.FindComponentsByType(t, dut, lineCardType) + cpuCards := components.FindComponentsByType(t, dut, cpuType) + if len(lineCards) == 0 || len(cpuCards) == 0 { + t.Errorf("ERROR: No controllerCard or cpuCard has been found.") + } + for _, cpu := range cpuCards { + t.Run(cpu, func(t *testing.T) { + timestamp := time.Now().Round(time.Second) + query := gnmi.OC().Component(cpu).State() + component := gnmi.Get(t, dut, query) + + cpuParent := component.GetParent() + if cpuParent == "" { + t.Errorf("ERROR: can't find parent information for CPU card %v", component) + } + + // If cpu card's parent is line card, check cpu ultilization. + if slices.Contains(lineCards, cpuParent) { + // Remove parent from the list of check cards. + lineCards = removeElement(lineCards, cpuParent) + // Fetch CPU utilization data. + cpuUtilization := component.GetCpu().GetUtilization() + if cpuUtilization.Avg == nil { + t.Errorf("ERROR: %s %s %s Type %-20s - CPU utilization data not available", + timestamp, deviceName, cpu, cpuParent) + } else { + t.Logf("INFO: %s %s Type %-20s %-10s - Utilization: %3d%%", timestamp, deviceName, cpu, cpuParent, cpuUtilization.GetAvg()) + } + } + }) + } + + if len(lineCards) > 0 { + t.Errorf("ERROR: Didn't find cpu card for checkCards %s", lineCards) + } +} + +func TestComponentsNoHighMemoryUtilization(t *testing.T) { + dut := ondatra.DUT(t, "dut") + deviceName := dut.Name() + description := "Component" + + controllerCards := components.FindComponentsByType(t, dut, controllerCardType) + lineCards := components.FindComponentsByType(t, dut, lineCardType) + cardList := append(controllerCards, lineCards...) + if len(cardList) == 0 { + t.Errorf("ERROR: No card has been found.") + } + for _, component := range cardList { + t.Run(component, func(t *testing.T) { + query := gnmi.OC().Component(component).State() + timestamp := time.Now().Round(time.Second) + componentState := gnmi.Get(t, dut, query) + componentType := componentState.GetType() + if componentType == lineCardType && deviations.LinecardMemoryUtilizationUnsupported(dut) { + t.Skipf("INFO: Skipping test for linecard component %s due to deviation linecard_memory_utilization_unsupported", component) + } + + memoryState := componentState.GetMemory() + if memoryState == nil { + t.Errorf("ERROR: %s - Device: %s - %s: %-40s - Type: %-20s - Memory data not available", + timestamp, deviceName, description, component, componentType) + } else { + memoryAvailable := memoryState.GetAvailable() + memoryUtilized := memoryState.GetUtilized() + memoryUtilization := uint8((memoryUtilized * 100) / (memoryAvailable + memoryUtilized)) + t.Logf("INFO: %s - Device: %s - %s: %-40s - Type: %-20s - Utilization: %3d%%", timestamp, deviceName, description, component, componentType, memoryUtilization) + } + }) + } +} + +func TestSystemProcessNoHighCPUSpike(t *testing.T) { + dut := ondatra.DUT(t, "dut") + deviceName := dut.Name() + + query := gnmi.OC().System().ProcessAny().State() + const description = "System CPU Process" + + timestamp := time.Now().Round(time.Second) + results := gnmi.GetAll(t, dut, query) + for _, result := range results { + processName := result.GetName() + t.Run(processName, func(t *testing.T) { + if result.CpuUtilization == nil { + t.Errorf("%s %s ERROR: %s process %-40s utilization not available", timestamp, deviceName, description, processName) + } else { + t.Logf("%s %s INFO: %s process %-40s utilization: %3d%%", timestamp, deviceName, description, processName, result.GetCpuUtilization()) + } + }) + } +} + +func TestSystemProcessNoHighMemorySpike(t *testing.T) { + dut := ondatra.DUT(t, "dut") + deviceName := dut.Name() + + query := gnmi.OC().System().ProcessAny().State() + const description = "System Process Memory" + + currentTime := time.Now().Round(time.Second) + processes := gnmi.GetAll(t, dut, query) + for _, process := range processes { + processName := process.GetName() + t.Run(processName, func(t *testing.T) { + if process.MemoryUtilization != nil { + t.Logf("%s %s INFO: %s - Process: %-40s - Utilization: %3d%%", currentTime, deviceName, description, processName, process.GetMemoryUtilization()) + } else { + t.Errorf("%s %s ERROR: %s - Process: %-40s - Utilization data not available", currentTime, deviceName, description, processName) + } + }) + } +} + +func TestNoQueueDrop(t *testing.T) { + dut := ondatra.DUT(t, "dut") + type testCase struct { + desc string + path string + counters []*ygnmi.Value[uint64] + } + interfaces := sortedInterfaces(dut.Ports()) + t.Logf("Interfaces: %s", interfaces) + for _, intf := range interfaces { + t.Run(intf, func(t *testing.T) { + qosInterface := gnmi.OC().Qos().Interface(intf) + cases := []testCase{ + { + desc: "Queue Input Dropped packets", + path: "/qos/interfaces/interface/input/queues/queue/state/dropped-pkts", + counters: gnmi.LookupAll(t, dut, qosInterface.Input().QueueAny().DroppedPkts().State()), + }, + { + desc: "Queue Output Dropped packets", + path: "/qos/interfaces/interface/output/queues/queue/state/dropped-pkts", + counters: gnmi.LookupAll(t, dut, qosInterface.Output().QueueAny().DroppedPkts().State()), + }, + { + desc: "Queue input voq-output-interface dropped packets", + path: "/qos/interfaces/interface/input/virtual-output-queues/voq-interface/queues/queue/state/dropped-pkts", + counters: gnmi.LookupAll(t, dut, qosInterface.Input().VoqInterfaceAny().QueueAny().DroppedPkts().State()), + }, + } + for _, c := range cases { + t.Run(c.desc, func(t *testing.T) { + if dut.Vendor() == ondatra.JUNIPER && c.desc == "Queue Input Dropped packets" { + t.Skipf("INFO: Skipping test due to %s does not support %s", dut.Vendor(), c.path) + } + if deviations.QOSVoqDropCounterUnsupported(dut) && c.desc == "Queue input voq-output-interface dropped packets" { + t.Skipf("INFO: Skipping test due to deviation qos_voq_drop_counter_unsupported") + } + if len(c.counters) == 0 { + t.Errorf("%s Interface %s Telemetry Value is not present", c.desc, intf) + } + for queueID, dropPkt := range c.counters { + dropCount, present := dropPkt.Val() + if !present { + t.Errorf("%s Interface %s %s Telemetry Value is not present", c.desc, intf, dropPkt.Path) + } else { + t.Logf("%s Interface %s, Queue %d has %d drop(s)", dropPkt.Path.GetOrigin(), intf, queueID, dropCount) + } + } + }) + } + }) + } +} + +func TestNoAsicDrop(t *testing.T) { + dut := ondatra.DUT(t, "dut") + + query := gnmi.OC().ComponentAny().IntegratedCircuit().PipelineCounters().Drop().State() + asicDrops := gnmi.LookupAll(t, dut, query) + if len(asicDrops) == 0 { + t.Fatalf("ERROR: No asic drop path exist") + } + + for _, asicDrop := range asicDrops { + component := asicDrop.Path.GetElem()[1].GetKey()["name"] + t.Run("Component "+component, func(t *testing.T) { + drop, _ := asicDrop.Val() + if drop.InterfaceBlock != nil { + if drop.InterfaceBlock.InDrops == nil { + t.Errorf("ERROR: InDrops counter is not present") + } else { + t.Logf("INFO: InDrops counter: %d", drop.InterfaceBlock.GetInDrops()) + } + if drop.InterfaceBlock.OutDrops == nil { + t.Errorf("ERROR: OutDrops counter is not present") + } else { + t.Logf("INFO: OutDrops counter: %d", drop.InterfaceBlock.GetInDrops()) + } + if drop.InterfaceBlock.Oversubscription == nil { + t.Errorf("ERROR: Oversubscription counter is not present") + } else { + t.Logf("INFO: Oversubscription counter: %d", drop.InterfaceBlock.GetInDrops()) + } + } + if drop.LookupBlock != nil { + if drop.LookupBlock.AclDrops == nil { + t.Errorf("ERROR: AclDrops counter is not present") + } else { + t.Logf("INFO: AclDrops counter: %d", drop.LookupBlock.GetAclDrops()) + } + if drop.LookupBlock.ForwardingPolicy == nil { + t.Errorf("ERROR: ForwardingPolicy is not present") + } else { + t.Logf("INFO: GetForwardingPolicy counter: %d", drop.LookupBlock.GetForwardingPolicy()) + } + if drop.LookupBlock.FragmentTotalDrops == nil { + t.Errorf("ERROR: FragmentTotalDrops is not present") + } else { + t.Logf("INFO: FragmentTotalDrops: %d", drop.LookupBlock.GetFragmentTotalDrops()) + } + if drop.LookupBlock.IncorrectSoftwareState == nil { + t.Errorf("ERROR: IncorrectSoftwareState counter is not present") + } else { + t.Logf("INFO: IncorrectSoftwareState counter: %d", drop.LookupBlock.GetIncorrectSoftwareState()) + } + if drop.LookupBlock.InvalidPacket == nil { + t.Errorf("ERROR: InvalidPacket counter is not present") + } else { + t.Logf("INFO: InvalidPacket counter: %d", drop.LookupBlock.GetInvalidPacket()) + } + if drop.LookupBlock.LookupAggregate == nil { + t.Errorf("ERROR: LookupAggregate counter is not present") + } else { + t.Logf("INFO: LookupAggregate counter: %d", drop.LookupBlock.GetLookupAggregate()) + } + if drop.LookupBlock.NoLabel == nil { + t.Errorf("ERROR: NoLabel counter is not present") + } else { + t.Logf("INFO: NoLabel counter: %d", drop.LookupBlock.GetNoLabel()) + } + if drop.LookupBlock.NoNexthop == nil { + t.Errorf("ERROR: NoNexthop counter is not present") + } else { + t.Logf("INFO: NoNexthop counter: %d", drop.LookupBlock.GetNoNexthop()) + } + if drop.LookupBlock.NoRoute == nil { + t.Errorf("ERROR: NoRoute counter is not present") + } else { + t.Logf("INFO: NoRoute counter: %d", drop.LookupBlock.GetNoNexthop()) + } + if drop.LookupBlock.RateLimit == nil { + t.Errorf("ERROR: RateLimit counter is not present") + } else { + t.Logf("INFO: RateLimit counter: %d", drop.LookupBlock.GetRateLimit()) + } + } + }) + } +} + +func TestInterfaceStatus(t *testing.T) { + dut := ondatra.DUT(t, "dut") + + interfaces := sortedInterfaces(dut.Ports()) + t.Logf("Interfaces: %s", interfaces) + for _, intf := range interfaces { + t.Run(intf, func(t *testing.T) { + query := gnmi.OC().Interface(intf).State() + root := gnmi.Get(t, dut, query) + t.Logf("INFO: Interface %s: \n", intf) + if root.OperStatus == oc.Interface_OperStatus_NOT_PRESENT { + t.Errorf("ERROR: Oper status is not present") + } else { + t.Logf("INFO: Oper status: %s", root.GetOperStatus()) + } + if root.AdminStatus == oc.Interface_AdminStatus_UNSET { + t.Errorf("ERROR: Admin status is not set") + } else { + t.Logf("INFO: Admin status: %s", root.GetAdminStatus()) + } + if root.Type == oc.IETFInterfaces_InterfaceType_UNSET { + t.Errorf("ERROR: Type is not present") + } else { + t.Logf("INFO: Type: %s", root.GetType()) + } + if root.Description == nil { + t.Errorf("ERROR: Description is not present") + } else { + t.Logf("INFO: Description: %s", root.GetType()) + } + if root.GetCounters().OutOctets == nil { + t.Errorf("ERROR: Counter OutOctets is not present") + } else { + t.Logf("INFO: Counter OutOctets: %d", root.GetCounters().GetOutOctets()) + } + if root.GetCounters().InMulticastPkts == nil { + t.Errorf("ERROR: Counter InMulticastPkts is not present") + } else { + t.Logf("INFO: Counter InMulticastPkts: %d", root.GetCounters().GetInMulticastPkts()) + } + if root.GetCounters().InDiscards == nil { + t.Errorf("ERROR: Counter InDiscards is not present") + } else { + t.Logf("INFO: Counter InDiscards: %d", root.GetCounters().GetInDiscards()) + } + if root.GetCounters().InErrors == nil { + t.Errorf("ERROR: Counter InErrors is not present") + } else { + t.Logf("INFO: Counter InErrors: %d", root.GetCounters().GetInErrors()) + } + if root.GetCounters().InUnknownProtos == nil { + t.Errorf("ERROR: Counter InUnknownProtos is not present") + } else { + t.Logf("INFO: Counter InUnknownProtos: %d", root.GetCounters().GetInUnknownProtos()) + } + if root.GetCounters().OutDiscards == nil { + t.Errorf("ERROR: Counter OutDiscards is not present") + } else { + t.Logf("INFO: Counter OutDiscards: %d", root.GetCounters().GetOutDiscards()) + } + if root.GetCounters().OutErrors == nil { + t.Errorf("ERROR: Counter OutErrors is not present") + } else { + t.Logf("INFO: Counter OutErrors: %d", root.GetCounters().GetOutErrors()) + } + if root.GetCounters().InFcsErrors == nil { + t.Errorf("ERROR: Counter InFcsErrors is not present") + } else { + t.Logf("INFO: Counter InFcsErrors: %d", root.GetCounters().GetInFcsErrors()) + } + }) + } +} + +func TestInterfacesubIntfs(t *testing.T) { + dut := ondatra.DUT(t, "dut") + + interfaces := sortedInterfaces(dut.Ports()) + t.Logf("Interfaces: %s", interfaces) + for _, intf := range interfaces { + t.Run(intf, func(t *testing.T) { + subIntfIndexes := gnmi.LookupAll(t, dut, gnmi.OC().Interface(intf).SubinterfaceAny().Index().State()) + for _, index := range subIntfIndexes { + subIntfIndex, present := index.Val() + if !present { + t.Fatalf("ERROR: subIntf index value doesn't exist") + } + subIntfPath := gnmi.OC().Interface(intf).Subinterface(subIntfIndex) + subIntfState := gnmi.Get(t, dut, subIntfPath.State()) + subIntf := subIntfState.GetName() + + t.Run(subIntf, func(t *testing.T) { + intfState := gnmi.Get(t, dut, gnmi.OC().Interface(intf).State()) + if subIntfState.OperStatus == oc.Interface_OperStatus_NOT_PRESENT { + t.Errorf("ERROR: Oper status is not up") + } else { + t.Logf("INFO: Oper status: %s", subIntfState.GetOperStatus()) + } + + if subIntfState.AdminStatus == oc.Interface_AdminStatus_UNSET { + t.Errorf("ERROR: Admin status is not up") + } else { + t.Logf("INFO: Admin status: %s", subIntfState.GetAdminStatus()) + } + + if subIntfState.Description == nil { + t.Errorf("ERROR: Description is not present") + } else { + t.Logf("INFO: Description: %s", subIntfState.GetDescription()) + } + + if subIntfState.GetCounters().OutOctets == nil && intfState.GetCounters().OutOctets == nil { + t.Errorf("ERROR: Counter OutOctets is not present on interface %s, %s", subIntf, intf) + } + + if subIntfState.GetCounters().InMulticastPkts == nil && intfState.GetCounters().InMulticastPkts == nil { + t.Errorf("ERROR: Counter InMulticastPkts is not present on interface %s, %s", subIntf, intf) + } + + counters := subIntfPath.Counters() + parentCounters := gnmi.OC().Interface(intf).Counters() + + cases := []struct { + desc string + counter ygnmi.SingletonQuery[uint64] + parentCounter ygnmi.SingletonQuery[uint64] + }{ + { + desc: "InDiscards", + counter: counters.InDiscards().State(), + parentCounter: parentCounters.InDiscards().State(), + }, + { + desc: "InErrors", + counter: counters.InErrors().State(), + parentCounter: parentCounters.InErrors().State(), + }, + { + desc: "InUnknownProtos", + counter: counters.InUnknownProtos().State(), + parentCounter: parentCounters.InUnknownProtos().State(), + }, + { + desc: "OutDiscards", + counter: counters.OutDiscards().State(), + parentCounter: parentCounters.OutDiscards().State(), + }, + { + desc: "OutErrors", + counter: counters.OutErrors().State(), + parentCounter: parentCounters.OutErrors().State(), + }, + { + desc: "InFcsErrors", + counter: counters.InFcsErrors().State(), + parentCounter: parentCounters.InFcsErrors().State(), + }, + } + + for _, c := range cases { + t.Run(c.desc, func(t *testing.T) { + if val, present := gnmi.Lookup(t, dut, c.counter).Val(); present { + t.Logf("INFO: %s: %d", c.counter, val) + } else if pVal, pPresent := gnmi.Lookup(t, dut, c.parentCounter).Val(); pPresent { + t.Logf("INFO: %s: %d", c.parentCounter, pVal) + } else { + t.Errorf("ERROR: Neither %s nor %s is present", c.counter, c.parentCounter) + } + }) + } + }) + } + }) + } +} + +func TestInterfaceEthernetNoDrop(t *testing.T) { + dut := ondatra.DUT(t, "dut") + + interfaces := sortedInterfaces(dut.Ports()) + t.Logf("Interfaces: %s", interfaces) + for _, intf := range interfaces { + t.Run(intf, func(t *testing.T) { + counters := gnmi.OC().Interface(intf).Ethernet().Counters() + cases := []struct { + desc string + counter ygnmi.SingletonQuery[uint64] + }{ + { + desc: "InCrcErrors", + counter: counters.InCrcErrors().State(), + }, + { + desc: "InMacPauseFrames", + counter: counters.InMacPauseFrames().State(), + }, + { + desc: "OutMacPauseFrames", + counter: counters.OutMacPauseFrames().State(), + }, + { + desc: "InBlockErrors", + counter: counters.InBlockErrors().State(), + }, + } + + for _, c := range cases { + t.Run(c.desc, func(t *testing.T) { + if val, present := gnmi.Lookup(t, dut, c.counter).Val(); present { + t.Logf("INFO: %s: %d", c.counter, val) + } else { + t.Errorf("ERROR: %s is not present", c.counter) + } + }) + } + }) + } +} + +func TestSystemAlarms(t *testing.T) { + dut := ondatra.DUT(t, "dut") + query := gnmi.OC().System().AlarmAny().State() + alarms := gnmi.LookupAll(t, dut, query) + if len(alarms) > 0 { + for _, a := range alarms { + val, _ := a.Val() + alarmSeverity := val.GetSeverity() + // Checking for major system alarms. + if alarmSeverity == oc.AlarmTypes_OPENCONFIG_ALARM_SEVERITY_MAJOR { + t.Logf("INFO: System Alarm with severity %s seen: %s", alarmSeverity, val.GetText()) + } + } + } +} + +func TestFabricDrop(t *testing.T) { + dut := ondatra.DUT(t, "dut") + t.Logf("INFO: Check no fabric drop") + if deviations.FabricDropCounterUnsupported(dut) { + t.Skipf("INFO: Skipping test due to deviation fabric_drop_counter_unsupported") + } + query := gnmi.OC().ComponentAny().IntegratedCircuit().PipelineCounters().Drop().FabricBlock().State() + t.Logf("query %s", query) + fabricBlocks := gnmi.GetAll(t, dut, query) + if len(fabricBlocks) == 0 { + t.Fatalf("ERROR: %s is not present", query) + } + for _, fabricBlock := range fabricBlocks { + drop := fabricBlock.GetLostPackets() + if fabricBlock.LostPackets == nil { + t.Errorf("ERROR: Fabric drops is not present") + } else { + t.Logf("INFO: Fabric drops: %d", drop) + } + } +} diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 774ac2e6bbf..468c2fd2c62 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -551,3 +551,42 @@ func ISISLspLifetimeIntervalRequiresLspRefreshInterval(dut *ondatra.DUTDevice) b func AggregateLoopbackModeRequiresMemberPortLoopbackMode(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetAggregateLoopbackModeRequiresMemberPortLoopbackMode() } + +// LinecardCPUUtilizationUnsupported returns if the device does not support telemetry path +// /components/component/cpu/utilization/state/avg for linecards' CPU card. +// Default value is false. +func LinecardCPUUtilizationUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetLinecardCpuUtilizationUnsupported() +} + +// ConsistentComponentNamesUnsupported returns if the device does not support consistent component names for GNOI and GNMI. +// Default value is false. +func ConsistentComponentNamesUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetConsistentComponentNamesUnsupported() +} + +// ControllerCardCPUUtilizationUnsupported returns if the device does not support telemetry path +// /components/component/cpu/utilization/state/avg for controller cards' CPU card. +// Default value is false. +func ControllerCardCPUUtilizationUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetControllerCardCpuUtilizationUnsupported() +} + +// FabricDropCounterUnsupported returns if the device does not support counter for fabric block lost packets. +// Default value is false. +func FabricDropCounterUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetFabricDropCounterUnsupported() +} + +// LinecardMemoryUtilizationUnsupported returns if the device does not support memory utilization related leaves for linecard components. +// Default value is false. +func LinecardMemoryUtilizationUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetLinecardMemoryUtilizationUnsupported() +} + +// QOSVoqDropCounterUnsupported returns if the device does not support telemetry path +// /qos/interfaces/interface/input/virtual-output-queues/voq-interface/queues/queue/state/dropped-pkts. +// Default value is false. +func QOSVoqDropCounterUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetQosVoqDropCounterUnsupported() +} diff --git a/proto/metadata.proto b/proto/metadata.proto index 6891e7c9ada..65009878e67 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -300,6 +300,22 @@ message Metadata { // LoopbackMode on aggregate interface. // Arista: partnerissuetracker.corp.google.com/297391260 bool aggregate_loopback_mode_requires_member_port_loopback_mode = 97; + // Device does not support telemetry path + // /components/component/cpu/utilization/state/avg for linecards' CPU card. + bool linecard_cpu_utilization_unsupported = 98; + // Device does not support consistent component names for GNOI and GNMI. + bool consistent_component_names_unsupported = 99; + // Device does not support telemetry path + // /components/component/cpu/utilization/state/avg for controller cards' + // CPU card. + bool controller_card_cpu_utilization_unsupported = 100; + // Device does not support counter for fabric block lost packets. + bool fabric_drop_counter_unsupported = 101; + // Device does not support memory utilization related leaves for linecard components. + bool linecard_memory_utilization_unsupported = 102; + // Device does not support telemetry path + // /qos/interfaces/interface/input/virtual-output-queues/voq-interface/queues/queue/state/dropped-pkts. + bool qos_voq_drop_counter_unsupported = 103; // Reserved field numbers and identifiers. reserved 84, 9, 28; diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index e1f880fcde7..f34dd5455c6 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 -// protoc v3.21.12 +// protoc-gen-go v1.31.0 +// protoc v3.6.1 // source: metadata.proto package metadata_go_proto @@ -565,6 +565,22 @@ type Metadata_Deviations struct { // LoopbackMode on aggregate interface. // Arista: partnerissuetracker.corp.google.com/297391260 AggregateLoopbackModeRequiresMemberPortLoopbackMode bool `protobuf:"varint,97,opt,name=aggregate_loopback_mode_requires_member_port_loopback_mode,json=aggregateLoopbackModeRequiresMemberPortLoopbackMode,proto3" json:"aggregate_loopback_mode_requires_member_port_loopback_mode,omitempty"` + // Device does not support telemetry path + // /components/component/cpu/utilization/state/avg for linecards' CPU card. + LinecardCpuUtilizationUnsupported bool `protobuf:"varint,98,opt,name=linecard_cpu_utilization_unsupported,json=linecardCpuUtilizationUnsupported,proto3" json:"linecard_cpu_utilization_unsupported,omitempty"` + // Device does not support consistent component names for GNOI and GNMI. + ConsistentComponentNamesUnsupported bool `protobuf:"varint,99,opt,name=consistent_component_names_unsupported,json=consistentComponentNamesUnsupported,proto3" json:"consistent_component_names_unsupported,omitempty"` + // Device does not support telemetry path + // /components/component/cpu/utilization/state/avg for controller cards' + // CPU card. + ControllerCardCpuUtilizationUnsupported bool `protobuf:"varint,100,opt,name=controller_card_cpu_utilization_unsupported,json=controllerCardCpuUtilizationUnsupported,proto3" json:"controller_card_cpu_utilization_unsupported,omitempty"` + // Device does not support counter for fabric block lost packets. + FabricDropCounterUnsupported bool `protobuf:"varint,101,opt,name=fabric_drop_counter_unsupported,json=fabricDropCounterUnsupported,proto3" json:"fabric_drop_counter_unsupported,omitempty"` + // Device does not support memory utilization related leaves for linecard components. + LinecardMemoryUtilizationUnsupported bool `protobuf:"varint,102,opt,name=linecard_memory_utilization_unsupported,json=linecardMemoryUtilizationUnsupported,proto3" json:"linecard_memory_utilization_unsupported,omitempty"` + // Device does not support telemetry path + // /qos/interfaces/interface/input/virtual-output-queues/voq-interface/queues/queue/state/dropped-pkts. + QosVoqDropCounterUnsupported bool `protobuf:"varint,103,opt,name=qos_voq_drop_counter_unsupported,json=qosVoqDropCounterUnsupported,proto3" json:"qos_voq_drop_counter_unsupported,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1208,6 +1224,48 @@ func (x *Metadata_Deviations) GetAggregateLoopbackModeRequiresMemberPortLoopback return false } +func (x *Metadata_Deviations) GetLinecardCpuUtilizationUnsupported() bool { + if x != nil { + return x.LinecardCpuUtilizationUnsupported + } + return false +} + +func (x *Metadata_Deviations) GetConsistentComponentNamesUnsupported() bool { + if x != nil { + return x.ConsistentComponentNamesUnsupported + } + return false +} + +func (x *Metadata_Deviations) GetControllerCardCpuUtilizationUnsupported() bool { + if x != nil { + return x.ControllerCardCpuUtilizationUnsupported + } + return false +} + +func (x *Metadata_Deviations) GetFabricDropCounterUnsupported() bool { + if x != nil { + return x.FabricDropCounterUnsupported + } + return false +} + +func (x *Metadata_Deviations) GetLinecardMemoryUtilizationUnsupported() bool { + if x != nil { + return x.LinecardMemoryUtilizationUnsupported + } + return false +} + +func (x *Metadata_Deviations) GetQosVoqDropCounterUnsupported() bool { + if x != nil { + return x.QosVoqDropCounterUnsupported + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1271,7 +1329,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd2, 0x36, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbc, 0x3a, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1302,7 +1360,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xa6, 0x2f, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0x90, 0x33, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -1679,37 +1737,67 @@ var file_metadata_proto_rawDesc = []byte{ 0x6f, 0x64, 0x65, 0x18, 0x61, 0x20, 0x01, 0x28, 0x08, 0x52, 0x33, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x50, 0x6f, - 0x72, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x4a, 0x04, - 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, - 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, - 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, - 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, - 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, - 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, - 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, - 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, - 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, - 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, - 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, - 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, - 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, - 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, - 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x22, 0x6d, 0x0a, - 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, - 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, - 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, - 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, - 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, - 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x4f, + 0x0a, 0x24, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x75, + 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x62, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x6c, 0x69, + 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x43, 0x70, 0x75, 0x55, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, + 0x53, 0x0a, 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, + 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x63, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x23, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6f, + 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x12, 0x5c, 0x0a, 0x2b, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, + 0x65, 0x72, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x75, 0x74, 0x69, 0x6c, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x18, 0x64, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x43, 0x70, 0x75, 0x55, 0x74, 0x69, 0x6c, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x12, 0x45, 0x0a, 0x1f, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x5f, 0x64, 0x72, 0x6f, + 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x65, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x66, 0x61, 0x62, + 0x72, 0x69, 0x63, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x55, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x55, 0x0a, 0x27, 0x6c, 0x69, 0x6e, + 0x65, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x75, 0x74, 0x69, + 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x18, 0x66, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x6c, 0x69, 0x6e, 0x65, + 0x63, 0x61, 0x72, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x74, 0x69, 0x6c, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x12, 0x46, 0x0a, 0x20, 0x71, 0x6f, 0x73, 0x5f, 0x76, 0x6f, 0x71, 0x5f, 0x64, 0x72, 0x6f, 0x70, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x18, 0x67, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x71, 0x6f, 0x73, 0x56, + 0x6f, 0x71, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x55, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, + 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, + 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa7, 0x01, + 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, + 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, + 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, + 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, + 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, + 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, + 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, + 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, + 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, + 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, + 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, + 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, + 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, + 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, + 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, + 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From 969281fad4ebad38a2a70a93859087c84828801b Mon Sep 17 00:00:00 2001 From: divyarema <134387379+divyarema@users.noreply.github.com> Date: Fri, 8 Sep 2023 03:16:48 +0530 Subject: [PATCH 06/43] RT-2.6: IS-IS Hello-Padding enabled at interface level (#1964) * initial commit for RT2.6 * Addressing review comments of RT2.6 * Updated RT2.6 with OTG files * Update isis_interface_hello_padding_enable_test.go Updated SetMtu and SetPrefix with uint32 --------- Co-authored-by: Mohana Co-authored-by: Arul Kumar Sekar <128646204+arulkumarsekar@users.noreply.github.com> --- .../README.md | 99 ++++ ...sis_interface_hello_padding_enable_test.go | 516 ++++++++++++++++++ .../metadata.textproto | 43 ++ 3 files changed, 658 insertions(+) create mode 100644 feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/README.md create mode 100644 feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/isis_interface_hello_padding_enable_test.go create mode 100644 feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/metadata.textproto diff --git a/feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/README.md b/feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/README.md new file mode 100644 index 00000000000..0a0d6fe16b1 --- /dev/null +++ b/feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/README.md @@ -0,0 +1,99 @@ +# RT-2.6: IS-IS Hello-Padding enabled at interface level + +## Summary + +* Base IS-IS functionality and adjacency establishment. +* Verifies isis adjacency by changing MTU. + +## Procedure + +* Configure IS-IS for ATE port-1 and DUT port-1. +* Configure DUT with global hello-padding enabled. +* Ensure that adjacencies are established with: + * Interface level hello padding is enabled. + * Verify that IPv4 and IPv6 IS-ISIS adjacency comes up fine. + * Verify the output of ST path displaying the status of ISIS hello padding. + * If we change the MTU on either side, then adjacency should not come up. + * Verify that IPv4 and IPv6 prefixes that are advertised by ATE correctly installed into DUTs route and forwarding table. + * TODO-Verify the Hellos are sent with Padding during adjacency turn-up if the padding is enabled adaptively/sometimes. + * Ensure that IPv4 and IPv6 prefixes that are advertised as part of an (emulated) neighboring system are installed into the DUT routing table, and validate that packets are sent and received to them. + +## Config Parameter coverage + +* For prefix: + + * /network-instances/network-instance/protocols/protocol/isis/ + +* Parameters: + + * global/config/authentication-check + * global/config/net + * global/config/level-capability + * global/config/hello-padding + * global/afi-safi/af/config/enabled + * levels/level/config/level-number + * levels/level/config/enabled + * levels/level/authentication/config/enabled + * levels/level/authentication/config/auth-mode + * levels/level/authentication/config/auth-password + * levels/level/authentication/config/auth-type + * interfaces/interface/config/interface-id + * interfaces/interface/config/enabled + * interfaces/interface/config/circuit-type + * interfaces/interface/timers/config/csnp-interval + * interfaces/interface/timers/config/lsp-pacing-interval + * interfaces/interface/levels/level/config/level-number + * interfaces/interface/levels/level/timers/config/hello-interval + * interfaces/interface/levels/level/timers/config/hello-multiplier + * interfaces/interface/levels/level/hello-authentication/config/auth-mode + * interfaces/interface/levels/level/hello-authentication/config/auth-password + * interfaces/interface/levels/level/hello-authentication/config/auth-type + * interfaces/interface/levels/level/hello-authentication/config/enabled + * interfaces/interface/afi-safi/af/config/afi-name + * interfaces/interface/afi-safi/af/config/safi-name + * interfaces/interface/afi-safi/af/config/metric + * interfaces/interface/afi-safi/af/config/enabled + +## Telemetry Parameter coverage + +* For prefix: + + * /network-instances/network-instance/protocols/protocol/isis/ + +* Parameters: + + * global/state/hello-padding + * interfaces/interface/state/hello-padding + * interfaces/interface/levels/level/adjacencies/adjacency/state/adjacency-state + * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-ipv4-address + * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-ipv6-address + * interfaces/interface/levels/level/adjacencies/adjacency/state/system-id + * interfaces/interface/levels/level/adjacencies/adjacency/state/area-address + * interfaces/interface/levels/level/adjacencies/adjacency/state/dis-system-id + * interfaces/interface/levels/level/adjacencies/adjacency/state/local-extended-circuit-id + * interfaces/interface/levels/level/adjacencies/adjacency/state/multi-topology + * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-circuit-type + * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-extended-circuit-id + * interfaces/interface/levels/level/adjacencies/adjacency/state/neighbor-snpa + * interfaces/interface/levels/level/adjacencies/adjacency/state/nlpid + * interfaces/interface/levels/level/adjacencies/adjacency/state/priority + * interfaces/interface/levels/level/adjacencies/adjacency/state/restart-status + * interfaces/interface/levels/level/adjacencies/adjacency/state/restart-support + * interfaces/interface/levels/level/adjacencies/adjacency/state/restart-suppress + * interfaces/interface/levels/level/afi-safi/af/state/afi-name + * interfaces/interface/levels/level/afi-safi/af/state/metric + * interfaces/interface/levels/level/afi-safi/af/state/safi-name + * interfaces/interface/levels/level/afi-safi/af/state/metric + * levels/level/system-level-counters/state/auth-fails + * levels/level/system-level-counters/state/auth-type-fails + * levels/level/system-level-counters/state/corrupted-lsps + * levels/level/system-level-counters/state/database-overloads + * levels/level/system-level-counters/state/exceed-max-seq-nums + * levels/level/system-level-counters/state/id-len-mismatch + * levels/level/system-level-counters/state/lsp-errors + * levels/level/system-level-counters/state/manual-address-drop-from-area + * levels/level/system-level-counters/state/max-area-address-mismatches + * levels/level/system-level-counters/state/own-lsp-purges + * levels/level/system-level-counters/state/part-changes + * levels/level/system-level-counters/state/seq-num-skips + * levels/level/system-level-counters/state/spf-runs diff --git a/feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/isis_interface_hello_padding_enable_test.go b/feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/isis_interface_hello_padding_enable_test.go new file mode 100644 index 00000000000..da0917ca321 --- /dev/null +++ b/feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/isis_interface_hello_padding_enable_test.go @@ -0,0 +1,516 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package isis_interface_hello_padding_enable_test + +import ( + "fmt" + "net" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/open-traffic-generator/snappi/gosnappi" + "github.com/openconfig/featureprofiles/internal/attrs" + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/otgutils" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + otg "github.com/openconfig/ondatra/otg" + "github.com/openconfig/ygnmi/ygnmi" + "github.com/openconfig/ygot/ygot" +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +const ( + plenIPv4 = 30 + plenIPv6 = 126 + isisInstance = "DEFAULT" + dutAreaAddress = "49.0001" + ateAreaAddress = "49.0002" + dutSysID = "1920.0000.2001" + ateSystemID = "640000000001" + password = "google" + v4Route1 = "203.0.113.0" + v6Route1 = "2001:db8::203:0:113:0" + v4Route = "203.0.113.0/30" + v6Route = "2001:db8::203:0:113:0/126" + v4IP = "203.0.113.1" + v6IP = "2001:db8::203:0:113:1" + v4Metric = 100 + v6Metric = 100 + v4NetName = "isisv4Net" + v6NetName = "isisv6Net" + v4FlowName = "v4Flow" + v6FlowName = "v6Flow" +) + +var ( + dutPort1Attr = attrs.Attributes{ + Desc: "DUT to ATE port1 ", + IPv4: "192.0.2.1", + IPv6: "2001:db8::192:0:2:1", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + MTU: 1500, + } + atePort1attr = attrs.Attributes{ + Name: "ATE to DUT port1 ", + IPv4: "192.0.2.2", + IPv6: "2001:db8::192:0:2:2", + MAC: "02:00:01:01:01:01", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + MTU: 1500, + } + dutPort2Attr = attrs.Attributes{ + Desc: "DUT to ATE port2 ", + IPv4: "192.0.2.5", + IPv6: "2001:db8::192:0:2:5", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + atePort2attr = attrs.Attributes{ + Name: "ATE to DUT port2", + IPv4: "192.0.2.6", + IPv6: "2001:db8::192:0:2:6", + MAC: "02:00:02:01:01:01", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } +) + +// configureDUT configures all the interfaces on the DUT. +func configureDUT(t *testing.T) { + t.Helper() + dc := gnmi.OC() + dut := ondatra.DUT(t, "dut") + + i1 := dutPort1Attr.NewOCInterface(dut.Port(t, "port1").Name(), dut) + + t.Log("Pushing interface config on DUT port1") + gnmi.Replace(t, dut, dc.Interface(i1.GetName()).Config(), i1) + + i2 := dutPort2Attr.NewOCInterface(dut.Port(t, "port2").Name(), dut) + t.Log("Pushing interface config on DUT port2") + gnmi.Replace(t, dut, dc.Interface(i2.GetName()).Config(), i2) + + if deviations.ExplicitPortSpeed(dut) { + fptest.SetPortSpeed(t, dut.Port(t, "port1")) + fptest.SetPortSpeed(t, dut.Port(t, "port2")) + } +} + +// configureISIS configures isis on DUT. +func configureISIS(t *testing.T, dut *ondatra.DUTDevice, intfName string) { + t.Helper() + d := &oc.Root{} + configPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, isisInstance) + netInstance := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + prot := netInstance.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, isisInstance) + prot.Enabled = ygot.Bool(true) + isis := prot.GetOrCreateIsis() + globalISIS := isis.GetOrCreateGlobal() + + // Global configs. + globalISIS.Net = []string{fmt.Sprintf("%v.%v.00", dutAreaAddress, dutSysID)} + globalISIS.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) + globalISIS.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) + globalISIS.LevelCapability = oc.Isis_LevelType_LEVEL_2 + globalISIS.AuthenticationCheck = ygot.Bool(true) + globalISIS.HelloPadding = oc.Isis_HelloPaddingType_ADAPTIVE + + // Level configs. + level := isis.GetOrCreateLevel(2) + level.Enabled = ygot.Bool(true) + level.LevelNumber = ygot.Uint8(2) + + // Authentication configs. + auth := level.GetOrCreateAuthentication() + auth.Enabled = ygot.Bool(true) + auth.AuthMode = oc.IsisTypes_AUTH_MODE_MD5 + auth.AuthType = oc.KeychainTypes_AUTH_TYPE_SIMPLE_KEY + auth.AuthPassword = ygot.String(password) + + // Interface configs. + intf := isis.GetOrCreateInterface(intfName) + intf.Enabled = ygot.Bool(true) + intf.CircuitType = oc.Isis_CircuitType_POINT_TO_POINT + intf.InterfaceId = &intfName + intf.HelloPadding = oc.Isis_HelloPaddingType_ADAPTIVE + + // Interface timers. + isisIntfTimers := intf.GetOrCreateTimers() + isisIntfTimers.CsnpInterval = ygot.Uint16(5) + isisIntfTimers.LspPacingInterval = ygot.Uint64(150) + + // Interface level configs. + isisIntfLevel := intf.GetOrCreateLevel(2) + isisIntfLevel.LevelNumber = ygot.Uint8(2) + isisIntfLevel.GetOrCreateHelloAuthentication().Enabled = ygot.Bool(true) + isisIntfLevel.GetHelloAuthentication().AuthPassword = ygot.String(password) + isisIntfLevel.GetHelloAuthentication().AuthType = oc.KeychainTypes_AUTH_TYPE_SIMPLE_KEY + isisIntfLevel.GetHelloAuthentication().AuthMode = oc.IsisTypes_AUTH_MODE_MD5 + + isisIntfLevelTimers := isisIntfLevel.GetOrCreateTimers() + isisIntfLevelTimers.HelloInterval = ygot.Uint32(5) + isisIntfLevelTimers.HelloMultiplier = ygot.Uint8(3) + + isisIntfLevel.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) + isisIntfLevel.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Metric = ygot.Uint32(v4Metric) + isisIntfLevel.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) + isisIntfLevel.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Metric = ygot.Uint32(v6Metric) + + // Interface afi-safi configs. + intf.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) + intf.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) + + t.Log("Pushing isis config on DUT") + gnmi.Replace(t, dut, configPath.Config(), prot) +} + +// configureOTG configures the interfaces and isis on OTG. +func configureOTG(t *testing.T, otg *otg.OTG) gosnappi.Config { + t.Helper() + config := otg.NewConfig(t) + port1 := config.Ports().Add().SetName("port1") + port2 := config.Ports().Add().SetName("port2") + + iDut1Dev := config.Devices().Add().SetName(atePort1attr.Name) + iDut1Eth := iDut1Dev.Ethernets().Add().SetName(atePort1attr.Name + ".Eth").SetMac(atePort1attr.MAC).SetMtu(uint32(atePort1attr.MTU)) + iDut1Eth.Connection().SetChoice(gosnappi.EthernetConnectionChoice.PORT_NAME).SetPortName(port1.Name()) + iDut1Ipv4 := iDut1Eth.Ipv4Addresses().Add().SetName(atePort1attr.Name + ".IPv4") + iDut1Ipv4.SetAddress(atePort1attr.IPv4).SetGateway(dutPort1Attr.IPv4).SetPrefix(uint32(atePort1attr.IPv4Len)) + iDut1Ipv6 := iDut1Eth.Ipv6Addresses().Add().SetName(atePort1attr.Name + ".IPv6") + iDut1Ipv6.SetAddress(atePort1attr.IPv6).SetGateway(dutPort1Attr.IPv6).SetPrefix(uint32(atePort1attr.IPv6Len)) + + iDut2Dev := config.Devices().Add().SetName(atePort2attr.Name) + iDut2Eth := iDut2Dev.Ethernets().Add().SetName(atePort2attr.Name + ".Eth").SetMac(atePort2attr.MAC) + iDut2Eth.Connection().SetChoice(gosnappi.EthernetConnectionChoice.PORT_NAME).SetPortName(port2.Name()) + iDut2Ipv4 := iDut2Eth.Ipv4Addresses().Add().SetName(atePort2attr.Name + ".IPv4") + iDut2Ipv4.SetAddress(atePort2attr.IPv4).SetGateway(dutPort2Attr.IPv4).SetPrefix(uint32(atePort2attr.IPv4Len)) + iDut2Ipv6 := iDut2Eth.Ipv6Addresses().Add().SetName(atePort2attr.Name + ".IPv6") + iDut2Ipv6.SetAddress(atePort2attr.IPv6).SetGateway(dutPort2Attr.IPv6).SetPrefix(uint32(atePort2attr.IPv6Len)) + + iDut1Dev.Isis().SetSystemId(ateSystemID).SetName("devIsis") + iDut1Dev.Isis().RouterAuth().AreaAuth().SetAuthType("md5").SetMd5(password) + iDut1Dev.Isis().RouterAuth().DomainAuth().SetAuthType("md5").SetMd5(password) + iDut1Dev.Isis().Basic().SetIpv4TeRouterId(atePort1attr.IPv4).SetEnableWideMetric(false) + iDut1Dev.Isis().Advanced().SetAreaAddresses([]string{strings.Replace(ateAreaAddress, ".", "", -1)}) + + iDut1Dev.Isis().Interfaces(). + Add(). + SetEthName(iDut1Dev.Ethernets().Items()[0].Name()). + SetName("devIsisInt"). + SetNetworkType(gosnappi.IsisInterfaceNetworkType.POINT_TO_POINT). + SetLevelType(gosnappi.IsisInterfaceLevelType.LEVEL_2). + SetMetric(10).Authentication().SetAuthType("md5").SetMd5(password) + + // netv4 is a simulated network containing the ipv4 addresses specified by targetNetwork + netv4 := iDut1Dev.Isis().V4Routes().Add().SetName(v4NetName).SetLinkMetric(10) + netv4.Addresses().Add().SetAddress(v4Route1).SetPrefix(plenIPv4) + + // netv6 is a simulated network containing the ipv6 addresses specified by targetNetwork + netv6 := iDut1Dev.Isis().V6Routes().Add().SetName(v6NetName).SetLinkMetric(10) + netv6.Addresses().Add().SetAddress(v6Route1).SetPrefix(plenIPv6) + + t.Log("Configuring v4 traffic flow ") + v4Flow := config.Flows().Add().SetName(v4FlowName) + v4Flow.Metrics().SetEnable(true) + v4Flow.TxRx().Device(). + SetTxNames([]string{iDut2Ipv4.Name()}). + SetRxNames([]string{v4NetName}) + v4Flow.Size().SetFixed(512) + v4Flow.Rate().SetPps(100) + v4Flow.Duration().SetChoice("continuous") + e1 := v4Flow.Packet().Add().Ethernet() + e1.Src().SetValue(atePort2attr.MAC) + v4 := v4Flow.Packet().Add().Ipv4() + v4.Src().SetValue(atePort2attr.IPv4) + v4.Dst().Increment().SetStart(v4IP).SetCount(1) + + t.Log("Configuring v6 traffic flow ") + v6Flow := config.Flows().Add().SetName(v6FlowName) + v6Flow.Metrics().SetEnable(true) + v6Flow.TxRx().Device(). + SetTxNames([]string{iDut2Ipv6.Name()}). + SetRxNames([]string{v6NetName}) + v6Flow.Size().SetFixed(512) + v6Flow.Rate().SetPps(100) + v6Flow.Duration().SetChoice("continuous") + e2 := v6Flow.Packet().Add().Ethernet() + e2.Src().SetValue(atePort2attr.MAC) + v6 := v6Flow.Packet().Add().Ipv6() + v6.Src().SetValue(atePort2attr.IPv6) + v6.Dst().Increment().SetStart(v6IP).SetCount(1) + + t.Logf("Pushing config to OTG and starting protocols...") + otg.PushConfig(t, config) + time.Sleep(30 * time.Second) + otg.StartProtocols(t) + + otgutils.WaitForARP(t, otg, config, "IPv4") + otgutils.WaitForARP(t, otg, config, "IPv6") + + return config +} + +// TestIsisInterfaceHelloPaddingEnable verifies adjacency with hello padding enabled. +func TestIsisInterfaceHelloPaddingEnable(t *testing.T) { + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + intfName := dut.Port(t, "port1").Name() + + // Configure interface on the DUT. + configureDUT(t) + + // Configure network Instance type on DUT. + dutConfNIPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)) + t.Log("Pushing network Instance type config on DUT") + gnmi.Replace(t, dut, dutConfNIPath.Type().Config(), oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE) + + // Configure isis on DUT. + configureISIS(t, dut, intfName) + + // Configure interface,isis and traffic on ATE. + otg := ate.OTG() + otgConfig := configureOTG(t, otg) + + if deviations.ExplicitInterfaceInDefaultVRF(dut) { + intfName = intfName + ".0" + } + statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, isisInstance).Isis() + + t.Run("Isis telemetry", func(t *testing.T) { + + adjacencyPath := statePath.Interface(intfName).Level(2).AdjacencyAny().AdjacencyState().State() + + _, ok := gnmi.WatchAll(t, dut, adjacencyPath, time.Minute, func(val *ygnmi.Value[oc.E_Isis_IsisInterfaceAdjState]) bool { + state, present := val.Val() + return present && state == oc.Isis_IsisInterfaceAdjState_UP + }).Await(t) + if !ok { + t.Fatalf("No isis adjacency reported on interface %v", intfName) + } + // Getting neighbors sysid. + sysid := gnmi.GetAll(t, dut, statePath.Interface(intfName).Level(2).AdjacencyAny().SystemId().State()) + ateSysID := sysid[0] + ateLspID := ateSysID + ".00-00" + + t.Run("HelloPadding checks", func(t *testing.T) { + if got := gnmi.Get(t, dut, statePath.Global().HelloPadding().State()); got != oc.Isis_HelloPaddingType_ADAPTIVE { + t.Errorf("FAIL- Expected global hello padding state not found, got %d, want %d", got, oc.Isis_HelloPaddingType_ADAPTIVE) + } + if got := gnmi.Get(t, dut, statePath.Interface(intfName).HelloPadding().State()); got != oc.Isis_HelloPaddingType_ADAPTIVE { + t.Errorf("FAIL- Expected interface hello padding state not found, got %d, want %d", got, oc.Isis_HelloPaddingType_ADAPTIVE) + } + // Changing MTU at ATE side + for _, d := range otgConfig.Devices().Items() { + Eth := d.Ethernets().Items()[0] + if Eth.Name() == atePort1attr.Name+".Eth" { + Eth.SetMtu(uint32(2000)) + } + } + otg.PushConfig(t, otgConfig) + otg.StartProtocols(t) + + // Adjacency check + _, found := gnmi.Watch(t, dut, statePath.Interface(intfName).Level(2).Adjacency(ateSysID).AdjacencyState().State(), time.Minute, func(val *ygnmi.Value[oc.E_Isis_IsisInterfaceAdjState]) bool { + state, present := val.Val() + return present && state == oc.Isis_IsisInterfaceAdjState_DOWN + }).Await(t) + if !found { + t.Errorf("Isis adjacency is not down on interface %v when MTU is changed", intfName) + } + + // Reverting MTU at ATE side + for _, d := range otgConfig.Devices().Items() { + Eth := d.Ethernets().Items()[0] + if Eth.Name() == atePort1attr.Name+".Eth" { + Eth.SetMtu(uint32(atePort1attr.MTU)) + } + } + otg.PushConfig(t, otgConfig) + otg.StartProtocols(t) + + // Adjacency check + _, ok := gnmi.Watch(t, dut, statePath.Interface(intfName).Level(2).Adjacency(ateSysID).AdjacencyState().State(), time.Minute, func(val *ygnmi.Value[oc.E_Isis_IsisInterfaceAdjState]) bool { + state, present := val.Val() + return present && state == oc.Isis_IsisInterfaceAdjState_UP + }).Await(t) + if !ok { + t.Fatalf("Interface %v has no level 2 isis adjacency", intfName) + } + }) + t.Run("Afi-Safi checks", func(t *testing.T) { + if got := gnmi.Get(t, dut, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).AfiName().State()); got != oc.IsisTypes_AFI_TYPE_IPV4 { + t.Errorf("FAIL- Expected afi name not found, got %d, want %d", got, oc.IsisTypes_AFI_TYPE_IPV4) + } + if got := gnmi.Get(t, dut, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).SafiName().State()); got != oc.IsisTypes_SAFI_TYPE_UNICAST { + t.Errorf("FAIL- Expected safi name not found, got %d, want %d", got, oc.IsisTypes_SAFI_TYPE_UNICAST) + } + if got := gnmi.Get(t, dut, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).AfiName().State()); got != oc.IsisTypes_AFI_TYPE_IPV6 { + t.Errorf("FAIL- Expected afi name not found, got %d, want %d", got, oc.IsisTypes_AFI_TYPE_IPV6) + } + if got := gnmi.Get(t, dut, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).SafiName().State()); got != oc.IsisTypes_SAFI_TYPE_UNICAST { + t.Errorf("FAIL- Expected safi name not found, got %d, want %d", got, oc.IsisTypes_SAFI_TYPE_UNICAST) + } + if got := gnmi.Get(t, dut, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Metric().State()); got != v4Metric { + t.Errorf("FAIL- Expected v4 unicast metric value not found, got %d, want %d", got, v4Metric) + } + if got := gnmi.Get(t, dut, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Metric().State()); got != v6Metric { + t.Errorf("FAIL- Expected v6 unicast metric value not found, got %d, want %d", got, v6Metric) + } + }) + t.Run("Adjacency state checks", func(t *testing.T) { + adjPath := statePath.Interface(intfName).Level(2).Adjacency(ateSysID) + + if got := gnmi.Get(t, dut, adjPath.SystemId().State()); got != ateSysID { + t.Errorf("FAIL- Expected neighbor system id not found, got %s, want %s", got, ateSysID) + } + want := []string{ateAreaAddress, dutAreaAddress} + if got := gnmi.Get(t, dut, adjPath.AreaAddress().State()); !cmp.Equal(got, want, cmpopts.SortSlices(func(a, b string) bool { return a < b })) { + t.Errorf("FAIL- Expected area address not found, got %s, want %s", got, want) + } + if got := gnmi.Get(t, dut, adjPath.DisSystemId().State()); got != "0000.0000.0000" { + t.Errorf("FAIL- Expected dis system id not found, got %s, want %s", got, "0000.0000.0000") + } + if got := gnmi.Get(t, dut, adjPath.LocalExtendedCircuitId().State()); got == 0 { + t.Errorf("FAIL- Expected local extended circuit id not found,expected non-zero value, got %d", got) + } + if got := gnmi.Get(t, dut, adjPath.MultiTopology().State()); got != false { + t.Errorf("FAIL- Expected value for multi topology not found, got %t, want %t", got, false) + } + if got := gnmi.Get(t, dut, adjPath.NeighborCircuitType().State()); got != oc.Isis_LevelType_LEVEL_2 { + t.Errorf("FAIL- Expected value for circuit type not found, got %s, want %s", got, oc.Isis_LevelType_LEVEL_2) + } + if got := gnmi.Get(t, dut, adjPath.NeighborIpv4Address().State()); got != atePort1attr.IPv4 { + t.Errorf("FAIL- Expected value for ipv4 address not found, got %s, want %s", got, atePort1attr.IPv4) + } + if got := gnmi.Get(t, dut, adjPath.NeighborExtendedCircuitId().State()); got == 0 { + t.Errorf("FAIL- Expected neighbor extended circuit id not found,expected non-zero value, got %d", got) + } + snpaAddress := gnmi.Get(t, dut, adjPath.NeighborSnpa().State()) + mac, err := net.ParseMAC(snpaAddress) + if !(mac != nil && err == nil) { + t.Errorf("FAIL- Expected value for snpa address not found, got %s", snpaAddress) + } + if got := gnmi.Get(t, dut, adjPath.Nlpid().State()); !cmp.Equal(got, []oc.E_Adjacency_Nlpid{oc.Adjacency_Nlpid_IPV4, oc.Adjacency_Nlpid_IPV6}) { + t.Errorf("FAIL- Expected address families not found, got %s, want %s", got, []oc.E_Adjacency_Nlpid{oc.Adjacency_Nlpid_IPV4, oc.Adjacency_Nlpid_IPV6}) + } + ipv6Address := gnmi.Get(t, dut, adjPath.NeighborIpv6Address().State()) + ip := net.ParseIP(ipv6Address) + if !(ip != nil && ip.To16() != nil) { + t.Errorf("FAIL- Expected ipv6 address not found, got %s", ipv6Address) + } + if _, ok := gnmi.Lookup(t, dut, adjPath.Priority().State()).Val(); !ok { + t.Errorf("FAIL- Priority is not present") + } + if _, ok := gnmi.Lookup(t, dut, adjPath.RestartStatus().State()).Val(); !ok { + t.Errorf("FAIL- Restart status not present") + } + if _, ok := gnmi.Lookup(t, dut, adjPath.RestartSupport().State()).Val(); !ok { + t.Errorf("FAIL- Restart support not present") + } + if _, ok := gnmi.Lookup(t, dut, adjPath.RestartStatus().State()).Val(); !ok { + t.Errorf("FAIL- Restart suppress not present") + } + }) + t.Run("System level counter checks", func(t *testing.T) { + if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().AuthFails().State()); got != 0 { + t.Errorf("FAIL- Not expecting any authentication key failure, got %d, want %d", got, 0) + } + if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().AuthTypeFails().State()); got != 0 { + t.Errorf("FAIL- Not expecting any authentication type mismatches, got %d, want %d", got, 0) + } + if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().CorruptedLsps().State()); got != 0 { + t.Errorf("FAIL- Not expecting any corrupted lsps, got %d, want %d", got, 0) + } + if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().DatabaseOverloads().State()); got != 0 { + t.Errorf("FAIL- Not expecting non zero database_overloads, got %d, want %d", got, 0) + } + if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().ExceedMaxSeqNums().State()); got != 0 { + t.Errorf("FAIL- Not expecting non zero max_seqnum counter, got %d, want %d", got, 0) + } + if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().IdLenMismatch().State()); got != 0 { + t.Errorf("FAIL- Not expecting non zero IdLen_Mismatch counter, got %d, want %d", got, 0) + } + if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().LspErrors().State()); got != 0 { + t.Errorf("FAIL- Not expecting any lsp errors, got %d, want %d", got, 0) + } + if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().MaxAreaAddressMismatches().State()); got != 0 { + t.Errorf("FAIL- Not expecting non zero MaxAreaAddressMismatches counter, got %d, want %d", got, 0) + } + if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().OwnLspPurges().State()); got != 0 { + t.Errorf("FAIL- Not expecting non zero OwnLspPurges counter, got %d, want %d", got, 0) + } + if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().SeqNumSkips().State()); got != 0 { + t.Errorf("FAIL- Not expecting non zero SeqNumber skips, got %d, want %d", got, 0) + } + if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().ManualAddressDropFromAreas().State()); got != 0 { + t.Errorf("FAIL- Not expecting non zero ManualAddressDropFromAreas counter, got %d, want %d", got, 0) + } + if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().PartChanges().State()); got != 0 { + t.Errorf("FAIL- Not expecting partition changes, got %d, want %d", got, 0) + } + if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().SpfRuns().State()); got == 0 { + t.Errorf("FAIL- Not expecting spf runs counter to be 0, got %d, want non zero", got) + } + }) + t.Run("Route checks", func(t *testing.T) { + if got := gnmi.Get(t, dut, statePath.Level(2).Lsp(ateLspID).Tlv(oc.IsisLsdbTypes_ISIS_TLV_TYPE_EXTENDED_IPV4_REACHABILITY).ExtendedIpv4Reachability().Prefix(v4Route).Prefix().State()); got != v4Route { + t.Errorf("FAIL- Expected v4 route not found in isis, got %v, want %v", got, v4Route) + } + if got := gnmi.Get(t, dut, statePath.Level(2).Lsp(ateLspID).Tlv(oc.IsisLsdbTypes_ISIS_TLV_TYPE_IPV6_REACHABILITY).Ipv6Reachability().Prefix(v6Route).Prefix().State()); got != v6Route { + t.Errorf("FAIL- Expected v6 route not found in isis, got %v, want %v", got, v6Route) + } + if got := gnmi.Get(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Afts().Ipv4Entry(v4Route).State()).GetPrefix(); got != v4Route { + t.Errorf("FAIL- Expected v4 route not found in aft, got %v, want %v", got, v4Route) + } + if got := gnmi.Get(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Afts().Ipv6Entry(v6Route).State()).GetPrefix(); got != v6Route { + t.Errorf("FAIL- Expected v6 route not found in aft, got %v, want %v", got, v6Route) + } + }) + t.Run("Traffic checks", func(t *testing.T) { + t.Logf("Starting traffic") + otg.StartTraffic(t) + time.Sleep(time.Second * 15) + t.Logf("Stop traffic") + otg.StopTraffic(t) + + otgutils.LogFlowMetrics(t, otg, otgConfig) + otgutils.LogPortMetrics(t, otg, otgConfig) + + for _, flow := range []string{v4FlowName, v6FlowName} { + t.Log("Checking flow telemetry...") + recvMetric := gnmi.Get(t, otg, gnmi.OTG().Flow(flow).State()) + txPackets := recvMetric.GetCounters().GetOutPkts() + rxPackets := recvMetric.GetCounters().GetInPkts() + lostPackets := txPackets - rxPackets + lossPct := lostPackets * 100 / txPackets + + if lossPct > 1 { + t.Errorf("FAIL- Got %v%% packet loss for %s ; expected < 1%%", lossPct, flow) + } + } + }) + }) +} diff --git a/feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/metadata.textproto b/feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/metadata.textproto new file mode 100644 index 00000000000..9079f8cccd9 --- /dev/null +++ b/feature/experimental/isis/otg_tests/isis_interface_hello_padding_enable_test/metadata.textproto @@ -0,0 +1,43 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "fec5effb-efb8-4d6c-abfb-c541ad08dd36" +plan_id: "RT-2.6" +description: "IS-IS Hello-Padding enabled at interface level" +testbed: TESTBED_DUT_ATE_2LINKS +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + isis_interface_level1_disable_required: true + missing_isis_interface_afi_safi_enable: true + explicit_port_speed: true + explicit_interface_in_default_vrf: true + missing_value_for_defaults: true + interface_enabled: true + } +} +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + ipv4_missing_enabled: true + isis_interface_level1_disable_required: true + missing_isis_interface_afi_safi_enable: true + } +} +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + omit_l2_mtu: true + missing_value_for_defaults: true + interface_enabled: true + default_network_instance: "default" + isis_instance_enabled_required: true + isis_lsp_lifetime_interval_requires_lsp_refresh_interval: true + } +} From 19cd0758ba60d1d507489da4f644b7b3701540d5 Mon Sep 17 00:00:00 2001 From: rszarecki <46606165+rszarecki@users.noreply.github.com> Date: Thu, 7 Sep 2023 15:21:33 -0700 Subject: [PATCH 07/43] DP-1.3 TestPlan: QoS ECN feature config - parameter adjustment (#1894) * restoring changes * Update to ECN config to reflect current POPGate and foreseen DCGate * fix in Juniper to aligne. * fix in path section to indicate path retaed to TODO test cases * Update qos_ecn_config_test.go * Update qos_ecn_config_test.go * Update qos_ecn_config_test.go * Update README.md * Update README.md --- .../qos/tests/qos_ecn_config_test/README.md | 99 +++++++++++++------ .../qos_ecn_config_test.go | 13 ++- 2 files changed, 74 insertions(+), 38 deletions(-) diff --git a/feature/qos/tests/qos_ecn_config_test/README.md b/feature/qos/tests/qos_ecn_config_test/README.md index 45df6d4d88b..025b4b5a595 100644 --- a/feature/qos/tests/qos_ecn_config_test/README.md +++ b/feature/qos/tests/qos_ecn_config_test/README.md @@ -8,45 +8,59 @@ Verify QoS ECN feature configuration. * Connect DUT port-1 to ATE port-1, DUT port-2 to ATE port-2. -* ECN config: +* ECN configuration paramentes: + + * This test is verifying DUT ability to accept ECN configuration with vertical buffer utilization cut-off line.\ If buffer is utilized below that cut-off value no packet is ECN CE marked.\ If buffer is utilized at of above that cut-off value all packet are ECN CE marked. * ECN profile can be created for different queues. ECN profiles per queue can be applied to the output side of interfaces. - min-threshold | max-threshold | enable-ecn | drop | weight | max-drop-probability-percent - ------------- | ------------- | ---------- | ----- | ------- | ---------------------------- - 80000 | 2^64-1 | true | false | not set | 1 - - * Note: max-threshold is set to max uint64 value 2^64-1 - or 18446744073709551615. - - * Validate that the following values can be configured - - * min-threshold - * max-threshold - * enable-ecn - * drop - * max-drop-probability-percent - - * The following OC config paths can be used to configure the above values: - - * qos/queue-management-profiles/queue-management-profile/wred/uniform/config/min-threshold - * qos/queue-management-profiles/queue-management-profile/wred/uniform/config/max-threshold - * qos/queue-management-profiles/queue-management-profile/wred/uniform/config/enable-ecn - * qos/queue-management-profiles/queue-management-profile/wred/uniform/config/weight - * qos/queue-management-profiles/queue-management-profile/wred/uniform/config/drop - * qos/queue-management-profiles/queue-management-profile/wred/uniform/config/max-drop-probability-percent - -* Interfaces - - * Validate ECN profile can be applied under output interface queue using - OC config path: - * /qos/interfaces/interface/output/queues/queue/config/queue-management-profile + Test case|min-threshold | max-threshold | enable-ecn | drop | weight | max-drop-probability-percent + |--------|------------- | ------------- | ---------- | ----- | ------- | ---------------------------- + |#1 |80KB |80KB | true | false | not set | 100 + |[TODO]#2 |3.125MB | 6.250MB* | true | false | not set | 100 + |[TODO]#3 |1% | 2% | true | false | not set | 100 + + * 6.25MB max-treshhold is selected as it represents ~500 mico-seconds of Delay bandwidth Buffer on 100GE interfaces. What is O(2%) of buffer depth, hence allows for micro-burst absorbtion without beackpressing senders and at same time leaves enough DBB for accomodate RTT ECN signaling loop delay in global network for longer burst/congestion. + +* Procedure + * Test Case #1 80KB min-threshold equal max-threshold + * Configute queue-management-profile w/ ECN paramenters as above. Attach to queue on DUT-Port1. + * Validate that the following values are set as expected using OC telemetry. + * min-threshold + * max-threshold + * min-threshold = max-threshold (vertical cut-off line) + * enable-ecn + * drop + * max-drop-probability-percent + * Validate ECN profile can be applied under output interface queue using + OC telemetry. + * [TODO]Test Case #2 Treshold in MB, min-threshold not-equal max-threshold + * Configute queue-management-profile w/ ECN paramenters as above. Attach to queue on DUT-Port1. + * Validate that the following values are set as expected using OC telemetry. + * min-threshold + * max-threshold + * enable-ecn + * drop + * max-drop-probability-percent + * Validate ECN profile can be applied under output interface queue using + OC telemetry. + * [TODO]Test Case #3 Treshold in percentage, min-threshold not-equal max-threshold + * Configute queue-management-profile w/ ECN paramenters as above. Attach to queue on DUT-Port1. + * Validate that the following values are set as expected using OC telemetry. + * min-threshold-percent + * max-threshold-percent + * enable-ecn + * drop + * max-drop-probability-percent + * Validate ECN profile can be applied under output interface queue using + OC telemetry. ## Config parameter coverage * ECN - + * [TODO] qos/queue-management-profiles/queue-management-profile/wred/uniform/config/min-threshold-percent + * [TODO] qos/queue-management-profiles/queue-management-profile/wred/uniform/config/max-threshold-percent * qos/queue-management-profiles/queue-management-profile/wred/uniform/config/min-threshold * qos/queue-management-profiles/queue-management-profile/wred/uniform/config/max-threshold * qos/queue-management-profiles/queue-management-profile/wred/uniform/config/enable-ecn @@ -59,3 +73,26 @@ Verify QoS ECN feature configuration. * /qos/interfaces/interface/input/classifiers/classifier/config/name * /qos/interfaces/interface/output/queues/queue/config/name * /qos/interfaces/interface/output/queues/queue/config/queue-management-profile + +## telemetry parameter coverage + +* ECN + + * [TODO] qos/queue-management-profiles/queue-management-profile/wred/uniform/state/min-threshold-percent + * [TODO] qos/queue-management-profiles/queue-management-profile/wred/uniform/state/max-threshold-percent + * qos/queue-management-profiles/queue-management-profile/wred/uniform/state/min-threshold + * qos/queue-management-profiles/queue-management-profile/wred/uniform/state/max-threshold + * qos/queue-management-profiles/queue-management-profile/wred/uniform/state/enable-ecn + * qos/queue-management-profiles/queue-management-profile/wred/uniform/state/weight + * qos/queue-management-profiles/queue-management-profile/wred/uniform/state/drop + * qos/queue-management-profiles/queue-management-profile/wred/uniform/state/max-drop-probability-percent + +* Interfaces + + * /qos/interfaces/interface/input/classifiers/classifier/state/name + * /qos/interfaces/interface/output/queues/queue/state/name + * /qos/interfaces/interface/output/queues/queue/state/queue-management-profile + +## platform + + * vRX diff --git a/feature/qos/tests/qos_ecn_config_test/qos_ecn_config_test.go b/feature/qos/tests/qos_ecn_config_test/qos_ecn_config_test.go index 2fb26cf00fc..8e915adc0fd 100644 --- a/feature/qos/tests/qos_ecn_config_test/qos_ecn_config_test.go +++ b/feature/qos/tests/qos_ecn_config_test/qos_ecn_config_test.go @@ -15,7 +15,6 @@ package qos_ecn_config_test import ( - "math" "testing" "github.com/openconfig/featureprofiles/internal/deviations" @@ -130,8 +129,8 @@ func testECNConfig(t *testing.T) { ecnEnabled: true, dropEnabled: false, minThreshold: uint64(80000), - maxThreshold: math.MaxUint64, - maxDropProbabilityPercent: uint8(1), + maxThreshold: uint64(80000), + maxDropProbabilityPercent: uint8(100), weight: uint32(0), } @@ -363,8 +362,8 @@ func testCiscoECNConfig(t *testing.T) { }{ ecnEnabled: true, dropEnabled: false, - minThreshold: uint64(8005632), - maxThreshold: uint64(8011776), + minThreshold: uint64(80000), + maxThreshold: uint64(80000), maxDropProbabilityPercent: uint8(100), weight: uint32(0), } @@ -614,8 +613,8 @@ func testJuniperECNConfig(t *testing.T) { ecnEnabled: true, dropEnabled: false, minThreshold: uint64(80000), - maxThreshold: math.MaxUint64, - maxDropProbabilityPercent: uint8(1), + maxThreshold: uint64(80000), + maxDropProbabilityPercent: uint8(100), weight: uint32(0), } From 394df8a531758a0e8e054d13ba1df8dbfa8934df Mon Sep 17 00:00:00 2001 From: sachendras <44847441+sachendras@users.noreply.github.com> Date: Fri, 8 Sep 2023 07:39:47 -0700 Subject: [PATCH 08/43] AFI-SAFI oc_defaults (#1776) * Create oc_defaults Summary: - When operating in "openconfig mode", NOS (network operating system) defaults should match what OC defines as the defaults i.e. BGP AFI-SAFI are not enabled by default. This test currently only verifies the defaults for ipv4-unicast and ipv6-unicast AFI-SAFI implementations. However, this test can be extended further to cover for other AFI-SAFIs as well. - The test will check for default implementations under the neighbor and peer-group hierarchies. * Update oc_defaults * Update oc_defaults * Update oc_defaults * Update oc_defaults * Rename oc_defaults to README.md * Rename feature/bgp/afi_safi/README.md to feature/bgp/afi_safi/oc_defaults/README.md * Update README.md --- feature/bgp/afi_safi/oc_defaults/README.md | 68 ++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 feature/bgp/afi_safi/oc_defaults/README.md diff --git a/feature/bgp/afi_safi/oc_defaults/README.md b/feature/bgp/afi_safi/oc_defaults/README.md new file mode 100644 index 00000000000..643d0755520 --- /dev/null +++ b/feature/bgp/afi_safi/oc_defaults/README.md @@ -0,0 +1,68 @@ +Summary: + - When operating in "openconfig mode", NOS (network operating system) defaults should match what OC defines as the defaults i.e, + - For BGP, there are no defaults for AFI-SAFI at the neighbor and peer-group levels. However at the global level the default is "false" + - This test currently only verifies the defaults for ipv4-unicast and ipv6-unicast families. However, this test can be extended further to cover for other + AFI-SAFIs as well in future. + - The test will check for default implementations under the neighbor and peer-group hierarchies and also test for inheritance rules as was specified in [pull/774](https://github.com/openconfig/public/pull/774) and [pull/815](https://github.com/openconfig/public/pull/815). + + +Topology: +ATE (Port1) <-EBGP-> (Port1) DUT (Port2) <-IBGP-> (Port2) ATE + - Connect ATE Port1 to DUT port1 (EBGP peering) + - Connect ATE Port2 to DUT port2 (IBGP peering) + +Procedure: + - [Test case-1] AFI-SAFI configurations at "neighbor level": + - Push EBGP and IBGP OC configuration to the DUT + - Configuration should include corresponding IPv4 and IPv6 neighbor configurations. + - Ensure that only IPv4-Unicast enabled boolean is made "true" for IPv4 neighbor. "IPv6-unicast enabled" boolean is left to OC default for the IPv4 peer". + - Ensure that only IPv6-Unicast enabled boolean is made "true" for IPv6 neighbor. "IPv4-unicast enabled" boolean is left to OC default for the IPv6 peer". + - Ensure that there are no AFI-SAFI configurations at the global and peer-group levels. + - On the ATE side ensure that IPv4-unicast and IPv6-unicast AFI-SAFI are enabled==true for IPv4 and IPv6 neighbors. + - verification: + - For IPv4 neighbor, ensure that the IPv4 neighborship is up and IPv6-unicast capability is not negotiated. + - For IPv6 neighbor ensure that the IPv6 neighborship is up and IPv4-unicast capability is not negotiated. + - [Test case-2] IPv4-unicast and IPv6-Unicast AFI-SAFIs enabled at peer-group level: + - Configuration at the neighbor level is same as in [Test case-1] except for IPv4-unicast and IPv6-unicast being enabled at the peer-group level + - No configuration should be made at the global AFI-SAFI level + - verification: + - For IPv4 neighbor, ensure that the IPv4 neighborship is up and both IPv4-unicast and IPv6-unicast capabilities are negotiated. + - For IPv6 neighbor ensure that the IPv6 neighborship is up and both IPv4-unicast and IPv6-unicast capabilities are negotiated. + - [Test case-4] IPv4-unicast and IPv6-Unicast AFI-SAFIs enabled at Global level: + - Configuration at the neighbor level is same as in [Test case-1] except for IPv4-unicast and IPv6-unicast being enabled at the global level + - No configuration should be made at the peer-group AFI-SAFI level + - verification: + - For IPv4 neighbor, ensure that the IPv4 neighborship is up and both IPv4-unicast and IPv6-unicast capabilities are negotiated. + - For IPv6 neighbor ensure that the IPv6 neighborship is up and both IPv4-unicast and IPv6-unicast capabilities are negotiated. + +Config Parameter coverage: + + /network-instances/network-instance/protocols/protocol/bgp/global/config/as + /network-instances/network-instance/protocols/protocol/bgp/global/config/router-id + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/auth-password + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/neighbor-address + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/peer-as + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/neighbor-address + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/config/enabled + + + /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config/auth-password + /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config/neighbor-address + /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config/peer-as + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/peer-group/peer-group-name + /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/afi-safis/afi-safi/config/enabled + + /network-instances/network-instance/protocols/protocol/bgp/global/afi-safis/afi-safi/config/enabled + +Telemetry Parameter coverage: + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/session-state + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/supported-capabilities + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/peer-type + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/peer-as + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/supported-capabilities + + /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/state/peer-type + /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/state/peer-as + /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/state/local-as + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/peer-group + From e9ad64dc6562d5eeb9b7220e667a72353a65c7f5 Mon Sep 17 00:00:00 2001 From: ANISH-GOTTAPU <48308607+ANISH-GOTTAPU@users.noreply.github.com> Date: Fri, 8 Sep 2023 21:01:22 +0530 Subject: [PATCH 09/43] OTG: Unique name for device not to overlap with Lag name (#2007) * increase ARP timeout * Unique name for device not to overlap with Lag name * arp.go to main * add port deviation for rt5.2 * Add flow label support * data refactor changes * Added deviation_ate_ipv6_flow_label_unsupported * FEC related settings * address review comment * -replaced DisableLACP member with link down -added a "clear otg config" at the beggining -rerun goimports on metadata.pb.go * regenerated metadata.pb.go --------- Co-authored-by: Octavian Petre <96260185+octpetre@users.noreply.github.com> Co-authored-by: Octavian Petre --- .../aggregate_test/aggregate_test.go | 41 +++++++--- .../balancing_test/balancing_test.go | 47 +++++++++-- internal/deviations/byexceptions.go | 20 +++++ internal/deviations/deviations.go | 6 -- proto/metadata.proto | 2 + proto/metadata_go_proto/metadata.pb.go | 82 +++++++++++-------- 6 files changed, 140 insertions(+), 58 deletions(-) diff --git a/feature/interface/aggregate/otg_tests/aggregate_test/aggregate_test.go b/feature/interface/aggregate/otg_tests/aggregate_test/aggregate_test.go index 07e067814ed..0b099850b3d 100644 --- a/feature/interface/aggregate/otg_tests/aggregate_test/aggregate_test.go +++ b/feature/interface/aggregate/otg_tests/aggregate_test/aggregate_test.go @@ -299,7 +299,23 @@ func (tc *testCase) configureATE(t *testing.T) { lagPort.Lacp().SetActorActivity("active").SetActorPortNumber(uint32(i) + 1).SetActorPortPriority(1).SetLacpduTimeout(0) } } - dstDev := tc.top.Devices().Add().SetName(agg.Name()) + + // Disable FEC for 100G-FR ports because Novus does not support it. + p100gbasefr := []string{} + for _, p := range tc.atePorts { + if p.PMD() == ondatra.PMD100GBASEFR { + p100gbasefr = append(p100gbasefr, p.ID()) + } + } + + if len(p100gbasefr) > 0 { + l1Settings := tc.top.Layer1().Add().SetName("L1").SetPortNames(p100gbasefr) + l1Settings.SetAutoNegotiate(true).SetIeeeMediaDefaults(false).SetSpeed("speed_100_gbps") + autoNegotiate := l1Settings.AutoNegotiation() + autoNegotiate.SetRsFec(false) + } + + dstDev := tc.top.Devices().Add().SetName(agg.Name() + ".dev") dstEth := dstDev.Ethernets().Add().SetName(ateDst.Name + ".Eth").SetMac(ateDst.MAC) dstEth.Connection().SetChoice(gosnappi.EthernetConnectionChoice.LAG_NAME).SetLagName(agg.Name()) dstEth.Ipv4Addresses().Add().SetName(ateDst.Name + ".IPv4").SetAddress(ateDst.IPv4).SetGateway(dutDst.IPv4).SetPrefix(uint32(ateDst.IPv4Len)) @@ -448,12 +464,18 @@ func (tc *testCase) verifyMinLinks(t *testing.T) { for _, tf := range tests { t.Run(tf.desc, func(t *testing.T) { for _, port := range tc.atePorts[1 : 1+tf.downCount] { + dp := tc.dut.Port(t, port.ID()) + if deviations.ATEPortLinkStateOperationsUnsupported(tc.ate) { + tc.setDutInterfaceWithState(t, dp, false) + defer tc.setDutInterfaceWithState(t, dp, true) + } else { + portStateAction := gosnappi.NewControlState() + portStateAction.Port().Link().SetPortNames([]string{port.ID()}).SetState(gosnappi.StatePortLinkState.DOWN) + tc.ate.OTG().SetControlState(t, portStateAction) + portStateAction.Port().Link().SetPortNames([]string{port.ID()}).SetState(gosnappi.StatePortLinkState.UP) + defer tc.ate.OTG().SetControlState(t, portStateAction) + } if tc.lagType == oc.IfAggregate_AggregationType_LACP { - - // Linked DUT and ATE ports have the same ID. - dp := tc.dut.Port(t, port.ID()) - t.Logf("Taking otg port %s down in the LAG", port.ID()) - tc.ate.OTG().DisableLACPMembers(t, port.ID()) time.Sleep(3 * time.Second) otgutils.LogLACPMetrics(t, tc.ate.OTG(), tc.top) otgutils.LogLAGMetrics(t, tc.ate.OTG(), tc.top) @@ -470,11 +492,6 @@ func (tc *testCase) verifyMinLinks(t *testing.T) { }).Await(t) } - if tc.lagType == oc.IfAggregate_AggregationType_STATIC { - // Setting admin state down on the DUT interface. Setting the otg interface down has no effect in kne - dp := tc.dut.Port(t, port.ID()) - tc.setDutInterfaceWithState(t, dp, false) - } } opStatus, statusCheckResult := gnmi.Watch(t, tc.dut, gnmi.OC().Interface(tc.aggID).OperStatus().State(), 1*time.Minute, func(y *ygnmi.Value[oc.E_Interface_OperStatus]) bool { opStatus, ok := y.Val() @@ -505,6 +522,8 @@ func TestNegotiation(t *testing.T) { for _, lagType := range lagTypes { top := ate.OTG().NewConfig(t) + // Clean otg with an empty config + ate.OTG().PushConfig(t, top) tc := &testCase{ dut: dut, diff --git a/feature/interface/aggregate/otg_tests/balancing_test/balancing_test.go b/feature/interface/aggregate/otg_tests/balancing_test/balancing_test.go index 3feec471c8e..71a4751ea5d 100644 --- a/feature/interface/aggregate/otg_tests/balancing_test/balancing_test.go +++ b/feature/interface/aggregate/otg_tests/balancing_test/balancing_test.go @@ -364,6 +364,14 @@ func generateRandomPortList(count uint) []uint32 { return a } +func generateRandomFlowLabelList(count int) []uint32 { + a := make([]uint32, count) + for index := range a { + a[index] = uint32(rand.Intn(1048575-1) + 1) + } + return a +} + func (tc *testCase) configureATE(t *testing.T) { if len(tc.atePorts) < 2 { t.Fatalf("Testbed requires at least 2 ports, got: %v", tc.atePorts) @@ -392,7 +400,22 @@ func (tc *testCase) configureATE(t *testing.T) { } agg.Protocol().Lacp().SetActorKey(1).SetActorSystemPriority(1).SetActorSystemId("01:01:01:01:01:01") - dstDev := tc.top.Devices().Add().SetName(agg.Name()) + // Disable FEC for 100G-FR ports because Novus does not support it. + p100gbasefr := []string{} + for _, p := range tc.atePorts { + if p.PMD() == ondatra.PMD100GBASEFR { + p100gbasefr = append(p100gbasefr, p.ID()) + } + } + + if len(p100gbasefr) > 0 { + l1Settings := tc.top.Layer1().Add().SetName("L1").SetPortNames(p100gbasefr) + l1Settings.SetAutoNegotiate(true).SetIeeeMediaDefaults(false).SetSpeed("speed_100_gbps") + autoNegotiate := l1Settings.AutoNegotiation() + autoNegotiate.SetRsFec(false) + } + + dstDev := tc.top.Devices().Add().SetName(agg.Name() + ".dev") dstEth := dstDev.Ethernets().Add().SetName(ateDst.Name + ".Eth").SetMac(ateDst.MAC) dstEth.Connection().SetChoice(gosnappi.EthernetConnectionChoice.LAG_NAME).SetLagName(agg.Name()) dstEth.Ipv4Addresses().Add().SetName(ateDst.Name + ".IPv4").SetAddress(ateDst.IPv4).SetGateway(dutDst.IPv4).SetPrefix(uint32(ateDst.IPv4Len)) @@ -507,6 +530,17 @@ func (tc *testCase) testFlow(t *testing.T, l3header string) { v4.Dst().SetValue(ateDst.IPv4) flow.Packet().Add().Ipv6() } + if l3header == "ipv6flowlabel" { + if deviations.ATEIPv6FlowLabelUnsupported(tc.ate) { + t.Skip("IPv6 flow label unsupported") + } + flow.TxRx().Device().SetTxNames([]string{i1 + ".IPv6"}).SetRxNames([]string{i2 + ".IPv6"}) + v6 := flow.Packet().Add().Ipv6() + v6.FlowLabel().SetValues(generateRandomFlowLabelList(250000)) + v6.Src().SetValue(ateSrc.IPv6) + v6.Dst().SetValue(ateDst.IPv6) + + } tcp := flow.Packet().Add().Tcp() tcp.SrcPort().SetValues(generateRandomPortList(65534)) @@ -589,11 +623,10 @@ func TestBalancing(t *testing.T) { desc: "IPV6inIPV4", l3header: "ipv6inipv4", }, - // TODO: flowHeader support is not available on OTG - // { - // desc: "IPV6 FlowLabel", - // l3header: []ondatra.Header{flowHeader}, - // }, + { + desc: "IPV6 FlowLabel", + l3header: "ipv6flowlabel", + }, } tc := &testCase{ dut: dut, @@ -605,9 +638,9 @@ func TestBalancing(t *testing.T) { atePorts: sortPorts(ate.Ports()), aggID: aggID, } + tc.configureATE(t) tc.configureDUT(t) t.Run("verifyDUT", tc.verifyDUT) - tc.configureATE(t) for _, tf := range tests { t.Run(tf.desc, func(t *testing.T) { diff --git a/internal/deviations/byexceptions.go b/internal/deviations/byexceptions.go index a044703b3b0..a0f9e6f83a6 100644 --- a/internal/deviations/byexceptions.go +++ b/internal/deviations/byexceptions.go @@ -32,6 +32,8 @@ var ( p4rtUnsetElectionIDPrimaryAllowed = flag.Bool("deviation_p4rt_unsetelectionid_primary_allowed", false, "Device allows unset Election ID to be primary.") p4rtBackupArbitrationResponseCode = flag.Bool("deviation_bkup_arbitration_resp_code", false, "Device sets ALREADY_EXISTS status code for all backup client responses.") backupNHGRequiresVrfWithDecap = flag.Bool("deviation_backup_nhg_requires_vrf_with_decap", false, "Set to true for devices that require IPOverIP Decapsulation for Backup NHG without interfaces.") + atePortLinkStateOperationsUnsupported = flag.Bool("deviation_ate_port_link_state_operations_unsupported", false, "Set to true for ATEs that do not support setting link state on their own ports.") + ateIPv6FlowLabelUnsupported = flag.Bool("deviation_ate_ipv6_flow_label_unsupported", false, "Set to true for ATEs that do not support IPv6 flow labels") ) func isFlagSet(name string) bool { @@ -104,3 +106,21 @@ func BackupNHGRequiresVrfWithDecap(dut *ondatra.DUTDevice) bool { } return lookupDUTDeviations(dut).GetBackupNhgRequiresVrfWithDecap() } + +// ATEPortLinkStateOperationsUnsupported returns true for traffic generators that do not support +// port link state control operations (such as port shutdown.) +func ATEPortLinkStateOperationsUnsupported(ate *ondatra.ATEDevice) bool { + if isFlagSet("deviation_ate_port_link_state_operations_unsupported") { + return *atePortLinkStateOperationsUnsupported + } + return lookupATEDeviations(ate).GetAtePortLinkStateOperationsUnsupported() +} + +// ATEIPv6FlowLabelUnsupported returns true for traffic generators that do not support +// IPv6 flow labels +func ATEIPv6FlowLabelUnsupported(ate *ondatra.ATEDevice) bool { + if isFlagSet("deviation_ate_ipv6_flow_label_unsupported") { + return *ateIPv6FlowLabelUnsupported + } + return lookupATEDeviations(ate).GetAteIpv6FlowLabelUnsupported() +} diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 468c2fd2c62..6e24e724882 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -534,12 +534,6 @@ func P4RTGdpRequiresDot1QSubinterface(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetP4RtGdpRequiresDot1QSubinterface() } -// ATEPortLinkStateOperationsUnsupported returns true for traffic generators that do not support -// port link state control operations (such as port shutdown.) -func ATEPortLinkStateOperationsUnsupported(ate *ondatra.ATEDevice) bool { - return lookupATEDeviations(ate).GetAtePortLinkStateOperationsUnsupported() -} - // ISISLspLifetimeIntervalRequiresLspRefreshInterval returns true for devices that require // configuring lspRefreshInterval ISIS timer when lspLifetimeInterval is configured. func ISISLspLifetimeIntervalRequiresLspRefreshInterval(dut *ondatra.DUTDevice) bool { diff --git a/proto/metadata.proto b/proto/metadata.proto index 65009878e67..0bea337d0fa 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -316,6 +316,8 @@ message Metadata { // Device does not support telemetry path // /qos/interfaces/interface/input/virtual-output-queues/voq-interface/queues/queue/state/dropped-pkts. bool qos_voq_drop_counter_unsupported = 103; + // ATE IPv6 flow label unsupported in KNE/virtualized environments. + bool ate_ipv6_flow_label_unsupported = 104; // Reserved field numbers and identifiers. reserved 84, 9, 28; diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index f34dd5455c6..3b967df202f 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 -// protoc v3.6.1 +// protoc-gen-go v1.28.1 +// protoc v3.21.12 // source: metadata.proto package metadata_go_proto @@ -581,6 +581,8 @@ type Metadata_Deviations struct { // Device does not support telemetry path // /qos/interfaces/interface/input/virtual-output-queues/voq-interface/queues/queue/state/dropped-pkts. QosVoqDropCounterUnsupported bool `protobuf:"varint,103,opt,name=qos_voq_drop_counter_unsupported,json=qosVoqDropCounterUnsupported,proto3" json:"qos_voq_drop_counter_unsupported,omitempty"` + // ATE IPv6 flow label unsupported in KNE/virtualized environments. + AteIpv6FlowLabelUnsupported bool `protobuf:"varint,104,opt,name=ate_ipv6_flow_label_unsupported,json=ateIpv6FlowLabelUnsupported,proto3" json:"ate_ipv6_flow_label_unsupported,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1266,6 +1268,13 @@ func (x *Metadata_Deviations) GetQosVoqDropCounterUnsupported() bool { return false } +func (x *Metadata_Deviations) GetAteIpv6FlowLabelUnsupported() bool { + if x != nil { + return x.AteIpv6FlowLabelUnsupported + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1329,7 +1338,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbc, 0x3a, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x82, 0x3b, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1360,7 +1369,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0x90, 0x33, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xd6, 0x33, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -1768,36 +1777,41 @@ var file_metadata_proto_rawDesc = []byte{ 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x67, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x71, 0x6f, 0x73, 0x56, 0x6f, 0x71, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x55, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, - 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa7, 0x01, - 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, - 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, - 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, - 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, - 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, - 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, - 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, - 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, - 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, - 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, - 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, - 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, - 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, - 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, - 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, - 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, - 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x1f, 0x61, 0x74, 0x65, 0x5f, + 0x69, 0x70, 0x76, 0x36, 0x5f, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, + 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x68, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x1b, 0x61, 0x74, 0x65, 0x49, 0x70, 0x76, 0x36, 0x46, 0x6c, 0x6f, 0x77, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, + 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, + 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, + 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, + 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, + 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, + 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, + 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, + 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, + 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, + 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, + 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, + 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, + 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, + 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, + 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x22, 0x6d, 0x0a, + 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, + 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, + 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, + 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, + 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, + 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( From 2c737f2239d4bb3d3d827662fbe40e674e00ed0f Mon Sep 17 00:00:00 2001 From: ANISH-GOTTAPU <48308607+ANISH-GOTTAPU@users.noreply.github.com> Date: Fri, 8 Sep 2023 21:03:00 +0530 Subject: [PATCH 10/43] Align OTG test RT5.1 with ATE test (#2065) * Align OTG test with ATE test * Address review comment --------- Co-authored-by: Octavian Petre <96260185+octpetre@users.noreply.github.com> --- .../singleton_test/singleton_test.go | 64 +++++++++++++++---- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/feature/interface/singleton/otg_tests/singleton_test/singleton_test.go b/feature/interface/singleton/otg_tests/singleton_test/singleton_test.go index 449a4c3b915..eb1e587d9fb 100644 --- a/feature/interface/singleton/otg_tests/singleton_test/singleton_test.go +++ b/feature/interface/singleton/otg_tests/singleton_test/singleton_test.go @@ -20,6 +20,7 @@ import ( "testing" "time" + "github.com/google/go-cmp/cmp" "github.com/open-traffic-generator/snappi/gosnappi" "github.com/openconfig/featureprofiles/internal/attrs" "github.com/openconfig/featureprofiles/internal/confirm" @@ -29,7 +30,6 @@ import ( "github.com/openconfig/ondatra" "github.com/openconfig/ondatra/gnmi" "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygnmi/ygnmi" "github.com/openconfig/ygot/ygot" otgtelemetry "github.com/openconfig/ondatra/gnmi/otg" @@ -101,10 +101,10 @@ var ( type testCase struct { mtu uint16 // This is the L3 MTU, i.e. the payload portion of an Ethernet frame. - dut *ondatra.DUTDevice - ate *ondatra.ATEDevice - top gosnappi.Config - + dut *ondatra.DUTDevice + ate *ondatra.ATEDevice + top gosnappi.Config + breakoutPorts map[string][]string // Initialized by configureDUT. duti1, duti2 *oc.Interface } @@ -129,6 +129,33 @@ func (tc *testCase) configInterfaceDUT(i *oc.Interface, dp *ondatra.Port, a *att s6.Mtu = ygot.Uint32(uint32(tc.mtu)) } +func (tc *testCase) configureDUTBreakout(t *testing.T) *oc.Component_Port_BreakoutMode_Group { + t.Helper() + d := gnmi.OC() + tc.breakoutPorts = make(map[string][]string) + + for _, dp := range tc.dut.Ports() { + // TODO(liulk): figure out a better way to detect breakout port. + if dp.PMD() != ondatra.PMD100GBASEFR { + continue + } + parent := gnmi.Get(t, tc.dut, gnmi.OC().Interface(dp.Name()).HardwarePort().State()) + tc.breakoutPorts[parent] = append(tc.breakoutPorts[parent], dp.Name()) + } + var group *oc.Component_Port_BreakoutMode_Group + for physical := range tc.breakoutPorts { + bmode := &oc.Component_Port_BreakoutMode{} + bmp := d.Component(physical).Port().BreakoutMode() + group = bmode.GetOrCreateGroup(0) + // TODO(liulk): use one of the logical port.Speed(). + group.BreakoutSpeed = oc.IfEthernet_ETHERNET_SPEED_SPEED_100GB + group.NumBreakouts = ygot.Uint8(4) + gnmi.Replace(t, tc.dut, bmp.Config(), bmode) + } + return group + +} + func (tc *testCase) configureDUT(t *testing.T) { d := gnmi.OC() @@ -260,13 +287,25 @@ func (tc *testCase) verifyInterfaceDUT( // verifyDUT checks the telemetry against the parameters set by // configureDUT(). -func (tc *testCase) verifyDUT(t *testing.T) { +func (tc *testCase) verifyDUT(t *testing.T, breakoutGroup *oc.Component_Port_BreakoutMode_Group) { t.Run("Port1", func(t *testing.T) { tc.verifyInterfaceDUT(t, tc.dut.Port(t, "port1"), tc.duti1, &ateSrc) }) t.Run("Port2", func(t *testing.T) { tc.verifyInterfaceDUT(t, tc.dut.Port(t, "port2"), tc.duti2, &ateDst) }) + t.Run("Breakout", func(t *testing.T) { + for physical := range tc.breakoutPorts { + if physical == "" { + continue // Not a breakout. + } + const want = 4 + got := breakoutGroup.GetNumBreakouts() + if !cmp.Equal(got, want) { + t.Errorf("number of brekaoutports = %v, want = %v", got, want) + } + } + }) } func (tc *testCase) verifyInterfaceATE(t *testing.T, ap *ondatra.Port) { @@ -320,15 +359,11 @@ func (tc *testCase) configureIPv6FlowHeader(t *testing.T, packetSize uint16) { } func (tc *testCase) waitOTGIPv4NeighborEntry(t *testing.T) { - gnmi.WatchAll(t, tc.ate.OTG(), gnmi.OTG().Interface(ateSrc.Name+".Eth").Ipv4NeighborAny().LinkLayerAddress().State(), time.Minute, func(val *ygnmi.Value[string]) bool { - return val.IsPresent() - }).Await(t) + otgutils.WaitForARP(t, tc.ate.OTG(), tc.top, "IPv4") } func (tc *testCase) waitOTGIPv6NeighborEntry(t *testing.T) { - gnmi.WatchAll(t, tc.ate.OTG(), gnmi.OTG().Interface(ateSrc.Name+".Eth").Ipv6NeighborAny().LinkLayerAddress().State(), time.Minute, func(val *ygnmi.Value[string]) bool { - return val.IsPresent() - }).Await(t) + otgutils.WaitForARP(t, tc.ate.OTG(), tc.top, "IPv6") } type counters struct { @@ -454,8 +489,9 @@ func (tc *testCase) testFlow(t *testing.T, packetSize uint16, configIPHeader otg func (tc *testCase) testMTU(t *testing.T) { tc.configureDUT(t) tc.configureATE(t) + breakoutGroup := tc.configureDUTBreakout(t) - t.Run("VerifyDUT", func(t *testing.T) { tc.verifyDUT(t) }) + t.Run("VerifyDUT", func(t *testing.T) { tc.verifyDUT(t, breakoutGroup) }) t.Run("VerifyATE", func(t *testing.T) { tc.verifyATE(t) }) for _, c := range []struct { @@ -491,7 +527,7 @@ func (tc *testCase) testMTU(t *testing.T) { } } -func TestSingleton(t *testing.T) { +func TestMTUs(t *testing.T) { dut := ondatra.DUT(t, "dut") ate := ondatra.ATE(t, "ate") From 93e449b63349e6f049f5f92ae0a8310618b46a39 Mon Sep 17 00:00:00 2001 From: anksaiki Date: Fri, 8 Sep 2023 13:35:59 -0400 Subject: [PATCH 11/43] fix test expectation for isis_interface_passive_test (#2074) * fix test expectation * fix isis interface passive test to use session library --- .../isis_interface_passive_test.go | 269 +++++++----------- .../metadata.textproto | 3 + internal/deviations/deviations.go | 18 ++ proto/metadata.proto | 10 + proto/metadata_go_proto/metadata.pb.go | 116 +++++--- 5 files changed, 212 insertions(+), 204 deletions(-) diff --git a/feature/experimental/isis/otg_tests/isis_interface_passive_test/isis_interface_passive_test.go b/feature/experimental/isis/otg_tests/isis_interface_passive_test/isis_interface_passive_test.go index 706cf74fbc6..c576f6b239a 100644 --- a/feature/experimental/isis/otg_tests/isis_interface_passive_test/isis_interface_passive_test.go +++ b/feature/experimental/isis/otg_tests/isis_interface_passive_test/isis_interface_passive_test.go @@ -15,22 +15,17 @@ package isis_interface_passive_test import ( - "fmt" "net" - "strings" "testing" "time" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/open-traffic-generator/snappi/gosnappi" - "github.com/openconfig/featureprofiles/internal/attrs" + "github.com/openconfig/featureprofiles/feature/experimental/isis/otg_tests/internal/session" "github.com/openconfig/featureprofiles/internal/deviations" "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/ondatra" "github.com/openconfig/ondatra/gnmi" "github.com/openconfig/ondatra/gnmi/oc" - otg "github.com/openconfig/ondatra/otg" "github.com/openconfig/ygnmi/ygnmi" "github.com/openconfig/ygot/ygot" ) @@ -40,75 +35,33 @@ func TestMain(m *testing.M) { } const ( - plenIPv4 = 30 - plenIPv6 = 126 - ISISInstance = "DEFAULT" - dutAreaAddress = "49.0001" - ateAreaAddress = "49.0002" - dutSysID = "1920.0000.2001" - ateSystemID = "640000000001" - v4Metric = 100 - v6Metric = 100 - password = "google" + plenIPv4 = 30 + plenIPv6 = 126 + v4Metric = 100 + v6Metric = 100 + password = "google" ) -var ( - dutPort1Attr = attrs.Attributes{ - Desc: "DUT to ATE link1 ", - IPv4: "192.0.2.1", - IPv6: "2001:db8::192:0:2:1", - IPv4Len: plenIPv4, - IPv6Len: plenIPv6, - } - atePort1attr = attrs.Attributes{ - Name: "ATE to DUT port1 ", - IPv4: "192.0.2.2", - IPv6: "2001:db8::192:0:2:2", - MAC: "02:00:01:01:01:01", - IPv4Len: plenIPv4, - IPv6Len: plenIPv6, - } -) - -// configureDUT configures all the interfaces on the DUT. -func configureDUT(t *testing.T) { +// configureISIS configures isis configs on ts.DUT. +func configureISIS(t *testing.T, ts *session.TestSession) { t.Helper() - dc := gnmi.OC() - dut := ondatra.DUT(t, "dut") - i1 := dutPort1Attr.NewOCInterface(dut.Port(t, "port1").Name(), dut) - - t.Log("Pushing interface config on DUT") - gnmi.Replace(t, dut, dc.Interface(i1.GetName()).Config(), i1) - - if deviations.ExplicitPortSpeed(dut) { - fptest.SetPortSpeed(t, dut.Port(t, "port1")) - } -} - -// configureISIS configures isis configs on DUT. -func configureISIS(t *testing.T, dut *ondatra.DUTDevice, intfName string, dutAreaAddress, dutSysID string) { - t.Helper() - d := &oc.Root{} - configPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, ISISInstance) - netInstance := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - prot := netInstance.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, ISISInstance) + d := ts.DUTConf + netInstance := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(ts.DUT)) + prot := netInstance.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, session.ISISName) prot.Enabled = ygot.Bool(true) isis := prot.GetOrCreateIsis() globalIsis := isis.GetOrCreateGlobal() // Global configs. - globalIsis.Net = []string{fmt.Sprintf("%v.%v.00", dutAreaAddress, dutSysID)} globalIsis.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) globalIsis.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) globalIsis.LevelCapability = oc.Isis_LevelType_LEVEL_2 globalIsis.AuthenticationCheck = ygot.Bool(true) - globalIsis.HelloPadding = oc.Isis_HelloPaddingType_LOOSE + globalIsis.HelloPadding = oc.Isis_HelloPaddingType_ADAPTIVE // Level configs. level := isis.GetOrCreateLevel(2) - level.Enabled = ygot.Bool(true) - level.LevelNumber = ygot.Uint8(2) // Authentication configs. auth := level.GetOrCreateAuthentication() @@ -118,19 +71,22 @@ func configureISIS(t *testing.T, dut *ondatra.DUTDevice, intfName string, dutAre auth.AuthPassword = ygot.String(password) // Interface configs. + intfName := ts.DUTPort1.Name() + if deviations.ExplicitInterfaceInDefaultVRF(ts.DUT) { + intfName += ".0" + } intf := isis.GetOrCreateInterface(intfName) - intf.Enabled = ygot.Bool(true) - intf.CircuitType = oc.Isis_CircuitType_POINT_TO_POINT - intf.InterfaceId = &intfName // Interface timers. isisIntfTimers := intf.GetOrCreateTimers() isisIntfTimers.CsnpInterval = ygot.Uint16(5) + if deviations.ISISTimersCsnpIntervalUnsupported(ts.DUT) { + isisIntfTimers.CsnpInterval = nil + } isisIntfTimers.LspPacingInterval = ygot.Uint64(150) // Interface level configs. isisIntfLevel := intf.GetOrCreateLevel(2) - isisIntfLevel.LevelNumber = ygot.Uint8(2) isisIntfLevel.GetOrCreateHelloAuthentication().Enabled = ygot.Bool(true) isisIntfLevel.GetHelloAuthentication().AuthPassword = ygot.String(password) isisIntfLevel.GetHelloAuthentication().AuthType = oc.KeychainTypes_AUTH_TYPE_SIMPLE_KEY @@ -140,83 +96,49 @@ func configureISIS(t *testing.T, dut *ondatra.DUTDevice, intfName string, dutAre isisIntfLevelTimers.HelloInterval = ygot.Uint32(5) isisIntfLevelTimers.HelloMultiplier = ygot.Uint8(3) - isisIntfLevel.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) isisIntfLevel.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Metric = ygot.Uint32(v4Metric) - isisIntfLevel.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) isisIntfLevel.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Metric = ygot.Uint32(v6Metric) - - // Interface afi-safi configs. - intf.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) - intf.GetOrCreateAf(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Enabled = ygot.Bool(true) - - t.Log("Pushing isis config on DUT") - gnmi.Replace(t, dut, configPath.Config(), prot) } // configureOTG configures the interfaces and isis protocol on ATE. -func configureOTG(t *testing.T, otg *otg.OTG) { +func configureOTG(t *testing.T, ts *session.TestSession) { t.Helper() - config := otg.NewConfig(t) - port1 := config.Ports().Add().SetName("port1") - - iDut1Dev := config.Devices().Add().SetName(atePort1attr.Name) - iDut1Eth := iDut1Dev.Ethernets().Add().SetName(atePort1attr.Name + ".Eth").SetMac(atePort1attr.MAC) - iDut1Eth.Connection().SetChoice(gosnappi.EthernetConnectionChoice.PORT_NAME).SetPortName(port1.Name()) - iDut1Ipv4 := iDut1Eth.Ipv4Addresses().Add().SetName(atePort1attr.Name + ".IPv4") - iDut1Ipv4.SetAddress(atePort1attr.IPv4).SetGateway(dutPort1Attr.IPv4).SetPrefix(uint32(atePort1attr.IPv4Len)) - iDut1Ipv6 := iDut1Eth.Ipv6Addresses().Add().SetName(atePort1attr.Name + ".IPv6") - iDut1Ipv6.SetAddress(atePort1attr.IPv6).SetGateway(dutPort1Attr.IPv6).SetPrefix(uint32(atePort1attr.IPv6Len)) - - iDut1Dev.Isis().SetSystemId(ateSystemID).SetName("devIsis").RouterAuth().AreaAuth().SetAuthType("md5").SetMd5(password) - iDut1Dev.Isis().RouterAuth().DomainAuth().SetAuthType("md5").SetMd5(password) - iDut1Dev.Isis().Basic().SetIpv4TeRouterId(atePort1attr.IPv4).SetEnableWideMetric(false) - iDut1Dev.Isis().Advanced().SetAreaAddresses([]string{strings.Replace(ateAreaAddress, ".", "", -1)}).SetEnableHelloPadding(true) + ts.ATEIntf1.Isis().RouterAuth().AreaAuth().SetAuthType("md5").SetMd5(password) + ts.ATEIntf1.Isis().RouterAuth().DomainAuth().SetAuthType("md5").SetMd5(password) + ts.ATEIntf1.Isis().Basic().SetEnableWideMetric(true).SetLearnedLspFilter(false) + ts.ATEIntf1.Isis().Advanced().SetEnableHelloPadding(true) - iDut1Dev.Isis().Interfaces(). - Add(). - SetEthName(iDut1Dev.Ethernets().Items()[0].Name()). - SetName("devIsisInt"). - SetNetworkType(gosnappi.IsisInterfaceNetworkType.POINT_TO_POINT). - SetLevelType(gosnappi.IsisInterfaceLevelType.LEVEL_2). - SetMetric(10).Authentication().SetAuthType("md5").SetMd5(password) - - t.Logf("Pushing config to OTG and starting protocols...") - otg.PushConfig(t, config) - time.Sleep(30 * time.Second) - otg.StartProtocols(t) + ts.ATEIntf1.Isis().Interfaces().Items()[0].Authentication().SetAuthType("md5").SetMd5(password) } // TestIsisInterfacePassive verifies passive isis interface. func TestIsisInterfacePassive(t *testing.T) { - dut := ondatra.DUT(t, "dut") - ate := ondatra.ATE(t, "ate") - intfName := dut.Port(t, "port1").Name() - - // Configure interface on the DUT. - configureDUT(t) + ts := session.MustNew(t).WithISIS() - // Configure network Instance type on DUT. - dutConfNIPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)) - t.Log("Pushing network Instance type config on DUT") - gnmi.Replace(t, dut, dutConfNIPath.Type().Config(), oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE) + // Configure isis on dut. + configureISIS(t, ts) - // Configure isis on DUT. - configureISIS(t, dut, intfName, dutAreaAddress, dutSysID) + configureOTG(t, ts) + pcl := ts.DUTConf.GetNetworkInstance(deviations.DefaultNetworkInstance(ts.DUT)).GetProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, session.ISISName) + fptest.LogQuery(t, "Protocol ISIS", session.ProtocolPath(ts.DUT).Config(), pcl) - // Configure interface,isis and traffic on ATE. - otg := ate.OTG() - configureOTG(t, otg) + ts.PushAndStart(t) - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - intfName = intfName + ".0" + _, err := ts.AwaitAdjacency() + if err != nil { + t.Fatalf("Adjacency state invalid: %v", err) } - statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_ISIS, ISISInstance).Isis() + statePath := session.ISISPath(ts.DUT) + intfName := ts.DUTPort1.Name() + if deviations.ExplicitInterfaceInDefaultVRF(ts.DUT) { + intfName += ".0" + } t.Run("Isis telemetry", func(t *testing.T) { adjacencyPath := statePath.Interface(intfName).Level(2).AdjacencyAny().AdjacencyState().State() - _, ok := gnmi.WatchAll(t, dut, adjacencyPath, time.Minute, func(val *ygnmi.Value[oc.E_Isis_IsisInterfaceAdjState]) bool { + _, ok := gnmi.WatchAll(t, ts.DUT, adjacencyPath, time.Minute, func(val *ygnmi.Value[oc.E_Isis_IsisInterfaceAdjState]) bool { state, present := val.Val() return present && state == oc.Isis_IsisInterfaceAdjState_UP }).Await(t) @@ -224,32 +146,32 @@ func TestIsisInterfacePassive(t *testing.T) { t.Fatalf("No isis adjacency reported on interface %v", intfName) } // Getting neighbors sysid. - sysid := gnmi.GetAll(t, dut, statePath.Interface(intfName).Level(2).AdjacencyAny().SystemId().State()) + sysid := gnmi.GetAll(t, ts.DUT, statePath.Interface(intfName).Level(2).AdjacencyAny().SystemId().State()) ateSysID := sysid[0] t.Run("Afi-Safi checks", func(t *testing.T) { // Checking v4 afi name. - if got := gnmi.Get(t, dut, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).AfiName().State()); got != oc.IsisTypes_AFI_TYPE_IPV4 { + if got := gnmi.Get(t, ts.DUT, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).AfiName().State()); got != oc.IsisTypes_AFI_TYPE_IPV4 { t.Errorf("FAIL- Expected afi name not found, got %d, want %d", got, oc.IsisTypes_AFI_TYPE_IPV4) } // Checking v4 safi name. - if got := gnmi.Get(t, dut, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).SafiName().State()); got != oc.IsisTypes_SAFI_TYPE_UNICAST { + if got := gnmi.Get(t, ts.DUT, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).SafiName().State()); got != oc.IsisTypes_SAFI_TYPE_UNICAST { t.Errorf("FAIL- Expected safi name not found, got %d, want %d", got, oc.IsisTypes_SAFI_TYPE_UNICAST) } // Checking v6 afi name. - if got := gnmi.Get(t, dut, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).AfiName().State()); got != oc.IsisTypes_AFI_TYPE_IPV6 { + if got := gnmi.Get(t, ts.DUT, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).AfiName().State()); got != oc.IsisTypes_AFI_TYPE_IPV6 { t.Errorf("FAIL- Expected afi name not found, got %d, want %d", got, oc.IsisTypes_AFI_TYPE_IPV6) } // Checking v6 safi name. - if got := gnmi.Get(t, dut, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).SafiName().State()); got != oc.IsisTypes_SAFI_TYPE_UNICAST { + if got := gnmi.Get(t, ts.DUT, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).SafiName().State()); got != oc.IsisTypes_SAFI_TYPE_UNICAST { t.Errorf("FAIL- Expected safi name not found, got %d, want %d", got, oc.IsisTypes_SAFI_TYPE_UNICAST) } // Checking v4 unicast metric. - if got := gnmi.Get(t, dut, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Metric().State()); got != v4Metric { + if got := gnmi.Get(t, ts.DUT, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV4, oc.IsisTypes_SAFI_TYPE_UNICAST).Metric().State()); got != v4Metric { t.Errorf("FAIL- Expected v4 unicast metric value not found, got %d, want %d", got, v4Metric) } // Checking v6 unicast metric. - if got := gnmi.Get(t, dut, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Metric().State()); got != v6Metric { + if got := gnmi.Get(t, ts.DUT, statePath.Interface(intfName).Level(2).Af(oc.IsisTypes_AFI_TYPE_IPV6, oc.IsisTypes_SAFI_TYPE_UNICAST).Metric().State()); got != v6Metric { t.Errorf("FAIL- Expected v6 unicast metric value not found, got %d, want %d", got, v6Metric) } }) @@ -257,143 +179,150 @@ func TestIsisInterfacePassive(t *testing.T) { adjPath := statePath.Interface(intfName).Level(2).Adjacency(ateSysID) // Checking neighbor sysid. - if got := gnmi.Get(t, dut, adjPath.SystemId().State()); got != ateSysID { + if got := gnmi.Get(t, ts.DUT, adjPath.SystemId().State()); got != ateSysID { t.Errorf("FAIL- Expected neighbor system id not found, got %s, want %s", got, ateSysID) } // Checking isis area address. - want := []string{ateAreaAddress, dutAreaAddress} - if got := gnmi.Get(t, dut, adjPath.AreaAddress().State()); !cmp.Equal(got, want, cmpopts.SortSlices(func(a, b string) bool { return a < b })) { + want := []string{session.ATEAreaAddress, session.DUTAreaAddress} + if got := gnmi.Get(t, ts.DUT, adjPath.AreaAddress().State()); !cmp.Equal(got, want, cmpopts.SortSlices(func(a, b string) bool { return a < b })) { t.Errorf("FAIL- Expected area address not found, got %s, want %s", got, want) } // Checking dis system id. - if got := gnmi.Get(t, dut, adjPath.DisSystemId().State()); got != "0000.0000.0000" { + if got := gnmi.Get(t, ts.DUT, adjPath.DisSystemId().State()); got != "0000.0000.0000" { t.Errorf("FAIL- Expected dis system id not found, got %s, want %s", got, "0000.0000.0000") } // Checking isis local extended circuit id. - if got := gnmi.Get(t, dut, adjPath.LocalExtendedCircuitId().State()); got == 0 { + if got := gnmi.Get(t, ts.DUT, adjPath.LocalExtendedCircuitId().State()); got == 0 { t.Errorf("FAIL- Expected local extended circuit id not found,expected non-zero value, got %d", got) } // Checking multitopology. - if got := gnmi.Get(t, dut, adjPath.MultiTopology().State()); got != false { + if got := gnmi.Get(t, ts.DUT, adjPath.MultiTopology().State()); got != false { t.Errorf("FAIL- Expected value for multi topology not found, got %t, want %t", got, false) } // Checking neighbor circuit type. - if got := gnmi.Get(t, dut, adjPath.NeighborCircuitType().State()); got != oc.Isis_LevelType_LEVEL_2 { + if got := gnmi.Get(t, ts.DUT, adjPath.NeighborCircuitType().State()); got != oc.Isis_LevelType_LEVEL_2 { t.Errorf("FAIL- Expected value for circuit type not found, got %s, want %s", got, oc.Isis_LevelType_LEVEL_2) } // Checking neighbor ipv4 address. - if got := gnmi.Get(t, dut, adjPath.NeighborIpv4Address().State()); got != atePort1attr.IPv4 { - t.Errorf("FAIL- Expected value for ipv4 address not found, got %s, want %s", got, atePort1attr.IPv4) + if got := gnmi.Get(t, ts.DUT, adjPath.NeighborIpv4Address().State()); got != session.ATEISISAttrs.IPv4 { + t.Errorf("FAIL- Expected value for ipv4 address not found, got %s, want %s", got, session.ATEISISAttrs.IPv4) } // Checking isis neighbor extended circuit id. - if got := gnmi.Get(t, dut, adjPath.NeighborExtendedCircuitId().State()); got == 0 { + if got := gnmi.Get(t, ts.DUT, adjPath.NeighborExtendedCircuitId().State()); got == 0 { t.Errorf("FAIL- Expected neighbor extended circuit id not found,expected non-zero value, got %d", got) } // Checking neighbor snpa. - snpaAddress := gnmi.Get(t, dut, adjPath.NeighborSnpa().State()) + snpaAddress := gnmi.Get(t, ts.DUT, adjPath.NeighborSnpa().State()) mac, err := net.ParseMAC(snpaAddress) if !(mac != nil && err == nil) { t.Errorf("FAIL- Expected value for snpa address not found, got %s", snpaAddress) } // Checking isis adjacency address families. - if got := gnmi.Get(t, dut, adjPath.Nlpid().State()); !cmp.Equal(got, []oc.E_Adjacency_Nlpid{oc.Adjacency_Nlpid_IPV4, oc.Adjacency_Nlpid_IPV6}) { + if got := gnmi.Get(t, ts.DUT, adjPath.Nlpid().State()); !cmp.Equal(got, []oc.E_Adjacency_Nlpid{oc.Adjacency_Nlpid_IPV4, oc.Adjacency_Nlpid_IPV6}) { t.Errorf("FAIL- Expected address families not found, got %s, want %s", got, []oc.E_Adjacency_Nlpid{oc.Adjacency_Nlpid_IPV4, oc.Adjacency_Nlpid_IPV6}) } // Checking neighbor ipv6 address. - ipv6Address := gnmi.Get(t, dut, adjPath.NeighborIpv6Address().State()) + ipv6Address := gnmi.Get(t, ts.DUT, adjPath.NeighborIpv6Address().State()) ip := net.ParseIP(ipv6Address) if !(ip != nil && ip.To16() != nil) { t.Errorf("FAIL- Expected ipv6 address not found, got %s", ipv6Address) } // Checking isis priority. - if _, ok := gnmi.Lookup(t, dut, adjPath.Priority().State()).Val(); !ok { + if _, ok := gnmi.Lookup(t, ts.DUT, adjPath.Priority().State()).Val(); !ok { t.Errorf("FAIL- Priority is not present") } // Checking isis restart status. - if _, ok := gnmi.Lookup(t, dut, adjPath.RestartStatus().State()).Val(); !ok { + if _, ok := gnmi.Lookup(t, ts.DUT, adjPath.RestartStatus().State()).Val(); !ok { t.Errorf("FAIL- Restart status not present") } // Checking isis restart support. - if _, ok := gnmi.Lookup(t, dut, adjPath.RestartSupport().State()).Val(); !ok { + if _, ok := gnmi.Lookup(t, ts.DUT, adjPath.RestartSupport().State()).Val(); !ok { t.Errorf("FAIL- Restart support not present") } // Checking isis restart suppress. - if _, ok := gnmi.Lookup(t, dut, adjPath.RestartStatus().State()).Val(); !ok { + if _, ok := gnmi.Lookup(t, ts.DUT, adjPath.RestartStatus().State()).Val(); !ok { t.Errorf("FAIL- Restart suppress not present") } }) t.Run("System level counter checks", func(t *testing.T) { // Checking authFail counters. - if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().AuthFails().State()); got != 0 { + if got := gnmi.Get(t, ts.DUT, statePath.Level(2).SystemLevelCounters().AuthFails().State()); got != 0 { t.Errorf("FAIL- Not expecting any authentication key failure, got %d, want %d", got, 0) } // Checking authTypeFail counters. - if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().AuthTypeFails().State()); got != 0 { + if got := gnmi.Get(t, ts.DUT, statePath.Level(2).SystemLevelCounters().AuthTypeFails().State()); got != 0 { t.Errorf("FAIL- Not expecting any authentication type mismatches, got %d, want %d", got, 0) } // Checking corrupted lsps counters. - if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().CorruptedLsps().State()); got != 0 { + if got := gnmi.Get(t, ts.DUT, statePath.Level(2).SystemLevelCounters().CorruptedLsps().State()); got != 0 { t.Errorf("FAIL- Not expecting any corrupted lsps, got %d, want %d", got, 0) } // Checking database_overloads counters. - if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().DatabaseOverloads().State()); got != 0 { + if got := gnmi.Get(t, ts.DUT, statePath.Level(2).SystemLevelCounters().DatabaseOverloads().State()); got != 0 { t.Errorf("FAIL- Not expecting non zero database_overloads, got %d, want %d", got, 0) } // Checking execeeded maximum seq number counters"). - if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().ExceedMaxSeqNums().State()); got != 0 { + if got := gnmi.Get(t, ts.DUT, statePath.Level(2).SystemLevelCounters().ExceedMaxSeqNums().State()); got != 0 { t.Errorf("FAIL- Not expecting non zero max_seqnum counter, got %d, want %d", got, 0) } // Checking IdLenMismatch counters. - if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().IdLenMismatch().State()); got != 0 { + if got := gnmi.Get(t, ts.DUT, statePath.Level(2).SystemLevelCounters().IdLenMismatch().State()); got != 0 { t.Errorf("FAIL- Not expecting non zero IdLen_Mismatch counter, got %d, want %d", got, 0) } // Checking LspErrors counters. - if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().LspErrors().State()); got != 0 { + if got := gnmi.Get(t, ts.DUT, statePath.Level(2).SystemLevelCounters().LspErrors().State()); got != 0 { t.Errorf("FAIL- Not expecting any lsp errors, got %d, want %d", got, 0) } // Checking MaxAreaAddressMismatches counters. - if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().MaxAreaAddressMismatches().State()); got != 0 { + if got := gnmi.Get(t, ts.DUT, statePath.Level(2).SystemLevelCounters().MaxAreaAddressMismatches().State()); got != 0 { t.Errorf("FAIL- Not expecting non zero MaxAreaAddressMismatches counter, got %d, want %d", got, 0) } // Checking OwnLspPurges counters. - if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().OwnLspPurges().State()); got != 0 { + if got := gnmi.Get(t, ts.DUT, statePath.Level(2).SystemLevelCounters().OwnLspPurges().State()); got != 0 { t.Errorf("FAIL- Not expecting non zero OwnLspPurges counter, got %d, want %d", got, 0) } // Checking SeqNumSkips counters. - if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().SeqNumSkips().State()); got != 0 { + if got := gnmi.Get(t, ts.DUT, statePath.Level(2).SystemLevelCounters().SeqNumSkips().State()); got != 0 { t.Errorf("FAIL- Not expecting non zero SeqNumber skips, got %d, want %d", got, 0) } // Checking ManualAddressDropFromAreas counters. - if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().ManualAddressDropFromAreas().State()); got != 0 { - t.Errorf("FAIL- Not expecting non zero ManualAddressDropFromAreas counter, got %d, want %d", got, 0) + if !deviations.ISISCounterManualAddressDropFromAreasUnsupported(ts.DUT) { + if got := gnmi.Get(t, ts.DUT, statePath.Level(2).SystemLevelCounters().ManualAddressDropFromAreas().State()); got != 0 { + t.Errorf("FAIL- Not expecting non zero ManualAddressDropFromAreas counter, got %d, want %d", got, 0) + } } // Checking PartChanges counters. - if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().PartChanges().State()); got != 0 { - t.Errorf("FAIL- Not expecting partition changes, got %d, want %d", got, 0) + if !deviations.ISISCounterPartChangesUnsupported(ts.DUT) { + if got := gnmi.Get(t, ts.DUT, statePath.Level(2).SystemLevelCounters().PartChanges().State()); got != 0 { + t.Errorf("FAIL- Not expecting partition changes, got %d, want %d", got, 0) + } } // Checking SpfRuns counters. - if got := gnmi.Get(t, dut, statePath.Level(2).SystemLevelCounters().SpfRuns().State()); got == 0 { + if got := gnmi.Get(t, ts.DUT, statePath.Level(2).SystemLevelCounters().SpfRuns().State()); got == 0 { t.Errorf("FAIL- Not expecting spf runs counter to be 0, got %d, want non zero", got) } }) t.Run("Passive interface checks", func(t *testing.T) { - // Pushing passive config to DUT. - gnmi.Update(t, dut, statePath.Interface(intfName).Passive().Config(), true) - gnmi.Update(t, dut, statePath.Interface(intfName).Level(2).Passive().Config(), false) + // Pushing passive config to ts.DUT. + gnmi.Update(t, ts.DUT, statePath.Interface(intfName).Passive().Config(), true) // Checking passive telemetry. - if got := gnmi.Get(t, dut, statePath.Interface(intfName).Passive().State()); got != true { + if got := gnmi.Get(t, ts.DUT, statePath.Interface(intfName).Passive().State()); got != true { t.Errorf("FAIL- Expected value for passive not found on isis interface, got %t, want %t", got, true) } - if got := gnmi.Get(t, dut, statePath.Interface(intfName).Level(2).Passive().State()); got != true { - t.Errorf("FAIL- Expected value for passive not found on isis interface level, got %t, want %t", got, true) - } - // Checking adjacency after configuring interface as passive. - adjacencyPath := statePath.Interface(intfName).Level(2).AdjacencyAny().AdjacencyState().State() - - _, ok := gnmi.WatchAll(t, dut, adjacencyPath, time.Minute, func(val *ygnmi.Value[oc.E_Isis_IsisInterfaceAdjState]) bool { + l2 := statePath.Interface(intfName).Level(2).State() + _, ok := gnmi.Watch(t, ts.DUT, l2, time.Minute, func(val *ygnmi.Value[*oc.NetworkInstance_Protocol_Isis_Interface_Level]) bool { state, present := val.Val() - return present && state == oc.Isis_IsisInterfaceAdjState_DOWN + if !present { + return false + } + + for _, adj := range state.Adjacency { + if adj.GetAdjacencyState() != oc.Isis_IsisInterfaceAdjState_DOWN { + return false + } + } + return true }).Await(t) if !ok { t.Errorf("FAIL-isis adjacency on %s with level 2 is not down", intfName) diff --git a/feature/experimental/isis/otg_tests/isis_interface_passive_test/metadata.textproto b/feature/experimental/isis/otg_tests/isis_interface_passive_test/metadata.textproto index 1366f3a1a77..e2d3183891a 100644 --- a/feature/experimental/isis/otg_tests/isis_interface_passive_test/metadata.textproto +++ b/feature/experimental/isis/otg_tests/isis_interface_passive_test/metadata.textproto @@ -39,5 +39,8 @@ platform_exceptions: { default_network_instance: "default" isis_instance_enabled_required: true isis_lsp_lifetime_interval_requires_lsp_refresh_interval: true + isis_timers_csnp_interval_unsupported: true + isis_counter_manual_address_drop_from_areas_unsupported: true + isis_counter_part_changes_unsupported: true } } diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 6e24e724882..40e47c5f16f 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -584,3 +584,21 @@ func LinecardMemoryUtilizationUnsupported(dut *ondatra.DUTDevice) bool { func QOSVoqDropCounterUnsupported(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetQosVoqDropCounterUnsupported() } + +// ISISTimersCsnpIntervalUnsupported returns true for devices that do not support +// configuring csnp-interval timer for ISIS. +func ISISTimersCsnpIntervalUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetIsisTimersCsnpIntervalUnsupported() +} + +// ISISCounterManualAddressDropFromAreasUnsupported returns true for devices that do not +// support telemetry for isis system-level-counter manual-address-drop-from-areas. +func ISISCounterManualAddressDropFromAreasUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetIsisCounterManualAddressDropFromAreasUnsupported() +} + +// ISISCounterPartChangesUnsupported returns true for devices that do not +// support telemetry for isis system-level-counter part-changes. +func ISISCounterPartChangesUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetIsisCounterPartChangesUnsupported() +} diff --git a/proto/metadata.proto b/proto/metadata.proto index 0bea337d0fa..fbbf5b0b4a0 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -318,6 +318,16 @@ message Metadata { bool qos_voq_drop_counter_unsupported = 103; // ATE IPv6 flow label unsupported in KNE/virtualized environments. bool ate_ipv6_flow_label_unsupported = 104; + // Devices do not support configuring isis csnp-interval timer. + // Arista: partnerissuetracker.corp.google.com/299283216 + bool isis_timers_csnp_interval_unsupported = 105; + // Devices do not support telemetry for isis counter: + // manual-address-drop-from-areas. + // Arista: partnerissuetracker.corp.google.com/299285115 + bool isis_counter_manual_address_drop_from_areas_unsupported = 106; + // Devices do not support telemetry for isis counter: part-changes. + // Arista: partnerissuetracker.corp.google.com/299285991 + bool isis_counter_part_changes_unsupported = 107; // Reserved field numbers and identifiers. reserved 84, 9, 28; diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 3b967df202f..6169fecfd73 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,7 +14,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 +// protoc-gen-go v1.28.0 // protoc v3.21.12 // source: metadata.proto @@ -583,6 +583,16 @@ type Metadata_Deviations struct { QosVoqDropCounterUnsupported bool `protobuf:"varint,103,opt,name=qos_voq_drop_counter_unsupported,json=qosVoqDropCounterUnsupported,proto3" json:"qos_voq_drop_counter_unsupported,omitempty"` // ATE IPv6 flow label unsupported in KNE/virtualized environments. AteIpv6FlowLabelUnsupported bool `protobuf:"varint,104,opt,name=ate_ipv6_flow_label_unsupported,json=ateIpv6FlowLabelUnsupported,proto3" json:"ate_ipv6_flow_label_unsupported,omitempty"` + // Devices do not support configuring isis csnp-interval timer. + // Arista: partnerissuetracker.corp.google.com/299283216 + IsisTimersCsnpIntervalUnsupported bool `protobuf:"varint,105,opt,name=isis_timers_csnp_interval_unsupported,json=isisTimersCsnpIntervalUnsupported,proto3" json:"isis_timers_csnp_interval_unsupported,omitempty"` + // Devices do not support telemetry for isis counter: + // manual-address-drop-from-areas. + // Arista: partnerissuetracker.corp.google.com/299285115 + IsisCounterManualAddressDropFromAreasUnsupported bool `protobuf:"varint,106,opt,name=isis_counter_manual_address_drop_from_areas_unsupported,json=isisCounterManualAddressDropFromAreasUnsupported,proto3" json:"isis_counter_manual_address_drop_from_areas_unsupported,omitempty"` + // Devices do not support telemetry for isis counter: part-changes. + // Arista: partnerissuetracker.corp.google.com/299285991 + IsisCounterPartChangesUnsupported bool `protobuf:"varint,107,opt,name=isis_counter_part_changes_unsupported,json=isisCounterPartChangesUnsupported,proto3" json:"isis_counter_part_changes_unsupported,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1275,6 +1285,27 @@ func (x *Metadata_Deviations) GetAteIpv6FlowLabelUnsupported() bool { return false } +func (x *Metadata_Deviations) GetIsisTimersCsnpIntervalUnsupported() bool { + if x != nil { + return x.IsisTimersCsnpIntervalUnsupported + } + return false +} + +func (x *Metadata_Deviations) GetIsisCounterManualAddressDropFromAreasUnsupported() bool { + if x != nil { + return x.IsisCounterManualAddressDropFromAreasUnsupported + } + return false +} + +func (x *Metadata_Deviations) GetIsisCounterPartChangesUnsupported() bool { + if x != nil { + return x.IsisCounterPartChangesUnsupported + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1338,7 +1369,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x82, 0x3b, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x99, 0x3d, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1369,7 +1400,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xd6, 0x33, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xed, 0x35, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -1781,37 +1812,54 @@ var file_metadata_proto_rawDesc = []byte{ 0x69, 0x70, 0x76, 0x36, 0x5f, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x68, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x61, 0x74, 0x65, 0x49, 0x70, 0x76, 0x36, 0x46, 0x6c, 0x6f, 0x77, 0x4c, 0x61, - 0x62, 0x65, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, - 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, - 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, - 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, - 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, - 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, - 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, - 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, - 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, - 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, - 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, - 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, - 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, - 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, - 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, - 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, - 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x22, 0x6d, 0x0a, - 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, - 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, - 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, - 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, - 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, - 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x62, 0x65, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x50, + 0x0a, 0x25, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x5f, 0x63, 0x73, + 0x6e, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x69, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x69, + 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x43, 0x73, 0x6e, 0x70, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x76, 0x61, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x12, 0x71, 0x0a, 0x37, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, + 0x5f, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, + 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x72, 0x65, 0x61, 0x73, 0x5f, + 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6a, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x30, 0x69, 0x73, 0x69, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x4d, 0x61, + 0x6e, 0x75, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x44, 0x72, 0x6f, 0x70, 0x46, + 0x72, 0x6f, 0x6d, 0x41, 0x72, 0x65, 0x61, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x25, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, + 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6b, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x21, 0x69, 0x73, 0x69, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x50, + 0x61, 0x72, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, + 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, + 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, + 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, + 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x07, 0x54, + 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, + 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, + 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, + 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, + 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, + 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, + 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, + 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, + 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, + 0x41, 0x47, 0x10, 0x05, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, + 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, + 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, + 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, + 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, + 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, + 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( From 82c635ce86383f00cb383791d479a6853a50c38d Mon Sep 17 00:00:00 2001 From: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> Date: Fri, 8 Sep 2023 13:40:03 -0400 Subject: [PATCH 12/43] Upgrade to latest version of Ondatra (#2102) * Upgrade to latest version of Ondatra * Fix cli_test * Simplied cli implementation --- go.mod | 50 +++--- go.sum | 294 ++++++++++++++++++++++++++++----- topologies/binding/binding.go | 2 +- topologies/binding/cli.go | 65 +------- topologies/binding/cli_test.go | 58 +------ topologies/binding/gnsi.go | 9 +- topologies/binding/reset.go | 2 +- 7 files changed, 292 insertions(+), 188 deletions(-) diff --git a/go.mod b/go.mod index 2a19810f258..7ffd5345c57 100644 --- a/go.mod +++ b/go.mod @@ -3,37 +3,37 @@ module github.com/openconfig/featureprofiles go 1.19 require ( - cloud.google.com/go/pubsub v1.32.0 + cloud.google.com/go/pubsub v1.33.0 cloud.google.com/go/storage v1.30.1 github.com/cisco-open/go-p4 v0.1.1 github.com/go-git/go-billy/v5 v5.4.1 github.com/go-git/go-git/v5 v5.7.0 - github.com/golang/glog v1.1.1 + github.com/golang/glog v1.1.2 github.com/google/go-cmp v0.5.9 github.com/google/go-github/v50 v50.1.0 github.com/google/gopacket v1.1.19 github.com/google/uuid v1.3.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 - github.com/open-traffic-generator/snappi/gosnappi v0.12.1 + github.com/open-traffic-generator/snappi/gosnappi v0.12.3 github.com/openconfig/gnmi v0.10.0 github.com/openconfig/gnoi v0.1.0 - github.com/openconfig/gnsi v1.2.1 + github.com/openconfig/gnsi v1.2.3 github.com/openconfig/gocloser v0.0.0-20220310182203-c6c950ed3b0b - github.com/openconfig/goyang v1.4.0 + github.com/openconfig/goyang v1.4.1 github.com/openconfig/gribi v1.0.0 github.com/openconfig/gribigo v0.0.0-20230207233343-ef59db57c4fc github.com/openconfig/kne v0.1.14 - github.com/openconfig/ondatra v0.2.7 + github.com/openconfig/ondatra v0.2.8 github.com/openconfig/testt v0.0.0-20220311054427-efbb1a32ec07 - github.com/openconfig/ygnmi v0.8.8 - github.com/openconfig/ygot v0.29.9 + github.com/openconfig/ygnmi v0.8.9 + github.com/openconfig/ygot v0.29.10 github.com/p4lang/p4runtime v1.4.0-rc.5 github.com/protocolbuffers/txtpbfmt v0.0.0-20220608084003-fc78c767cd6a - golang.org/x/crypto v0.11.0 - golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691 - golang.org/x/text v0.11.0 + golang.org/x/crypto v0.13.0 + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 + golang.org/x/text v0.13.0 google.golang.org/api v0.126.0 - google.golang.org/grpc v1.58.0-dev + google.golang.org/grpc v1.58.0 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -41,12 +41,12 @@ require ( require ( github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect - golang.org/x/oauth2 v0.8.0 + golang.org/x/oauth2 v0.10.0 ) require ( - cloud.google.com/go v0.110.4 // indirect - cloud.google.com/go/compute v1.20.1 // indirect + cloud.google.com/go v0.110.6 // indirect + cloud.google.com/go/compute v1.23.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.1 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 // indirect @@ -97,12 +97,12 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/networkop/meshnet-cni v0.3.1-0.20230525201116-d7c306c635cf // indirect github.com/open-traffic-generator/ixia-c-operator v0.3.4 // indirect - github.com/openconfig/entity-naming v0.0.0-20230812015236-03f6f9489f24 // indirect + github.com/openconfig/entity-naming v0.0.0-20230829162409-b28ee246e213 // indirect github.com/openconfig/grpctunnel v0.0.0-20220819142823-6f5422b8ca70 // indirect github.com/openconfig/lemming/operator v0.2.0 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/pborman/uuid v1.2.1 // indirect - github.com/pelletier/go-toml/v2 v2.0.9 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect @@ -119,20 +119,20 @@ require ( github.com/spf13/viper v1.16.0 // indirect github.com/srl-labs/srl-controller v0.6.0 // indirect github.com/srl-labs/srlinux-scrapli v0.6.0 // indirect - github.com/subosito/gotenv v1.4.2 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.10.0 // indirect - golang.org/x/net v0.12.0 // indirect - golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.10.0 // indirect - golang.org/x/term v0.10.0 // indirect + golang.org/x/net v0.15.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.12.0 // indirect + golang.org/x/term v0.12.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230731193218-e0aa005b6bdf // indirect + google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/go.sum b/go.sum index bea62cbece4..c4caa9e0f29 100644 --- a/go.sum +++ b/go.sum @@ -36,35 +36,45 @@ cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRY cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= -cloud.google.com/go v0.110.4 h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk= +cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw= cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= +cloud.google.com/go v0.110.6 h1:8uYAkj3YHTP/1iwReuHPxLSbdcyc+dSBbzFMrVwDR6Q= +cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4= cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw= cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= +cloud.google.com/go/accessapproval v1.7.1/go.mod h1:JYczztsHRMK7NTXb6Xw+dwbs/WnOJxbo/2mTI+Kgg68= cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o= cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE= cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM= cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= +cloud.google.com/go/accesscontextmanager v1.8.0/go.mod h1:uI+AI/r1oyWK99NN8cQ3UK76AMelMzgZCvJfsi2c+ps= +cloud.google.com/go/accesscontextmanager v1.8.1/go.mod h1:JFJHfvuaTC+++1iL1coPiG1eu5D24db2wXCDWDjIrxo= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg= cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ= cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k= cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= +cloud.google.com/go/aiplatform v1.45.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M= cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE= cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= +cloud.google.com/go/analytics v0.21.2/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo= cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk= cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc= cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= +cloud.google.com/go/apigateway v1.6.1/go.mod h1:ufAS3wpbRjqfZrzpvLC2oh0MFlpRJm2E/ts25yyqmXA= cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc= cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04= cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= +cloud.google.com/go/apigeeconnect v1.6.1/go.mod h1:C4awq7x0JpLtrlQCr8AzVIzAaYgngRqWf9S5Uhg+wWs= cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY= cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM= cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= +cloud.google.com/go/apigeeregistry v0.7.1/go.mod h1:1XgyjZye4Mqtw7T9TsY4NW10U7BojBvG4RMD+vRDrIw= cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU= cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI= cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= @@ -73,10 +83,12 @@ cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodC cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84= cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A= cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= +cloud.google.com/go/appengine v1.8.1/go.mod h1:6NJXGLVhZCN9aQ/AEDvmfzKEfoYBlfB80/BHiKVputY= cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY= cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= +cloud.google.com/go/area120 v0.8.1/go.mod h1:BVfZpGpB7KFVNxPiQBuHkX6Ed0rS51xIgmGyjrAfzsg= cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0= @@ -85,6 +97,7 @@ cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1 cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ= cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI= cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= +cloud.google.com/go/artifactregistry v1.14.1/go.mod h1:nxVdG19jTaSTu7yA7+VbWL346r3rIdkZ142BSQqhn5E= cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= @@ -93,17 +106,20 @@ cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAt cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo= cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg= cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= +cloud.google.com/go/asset v1.14.1/go.mod h1:4bEJ3dnHCqWCDbWJ/6Vn7GVI9LerSi7Rfdi03hd+WTQ= cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo= cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0= cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= +cloud.google.com/go/assuredworkloads v1.11.1/go.mod h1:+F04I52Pgn5nmPG36CWFtxmav6+7Q+c5QyJoL18Lry0= cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8= cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM= cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= +cloud.google.com/go/automl v1.13.1/go.mod h1:1aowgAHWYZU27MybSCFiukPO7xnyawv7pt3zK4bheQE= cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc= cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI= cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= @@ -114,6 +130,7 @@ cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckm cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8= cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM= cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= +cloud.google.com/go/beyondcorp v0.6.1/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -127,38 +144,46 @@ cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/Zur cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac= cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q= cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= +cloud.google.com/go/bigquery v1.52.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4= cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI= cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y= cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss= cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= +cloud.google.com/go/billing v1.16.0/go.mod h1:y8vx09JSSJG02k5QxbycNRrN7FGZB6F3CAcgum7jvGA= cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0= cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk= cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= +cloud.google.com/go/binaryauthorization v1.6.1/go.mod h1:TKt4pa8xhowwffiBmbrbcxijJRZED4zrqnwZ1lKH51U= cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg= cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590= cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= +cloud.google.com/go/certificatemanager v1.7.1/go.mod h1:iW8J3nG6SaRYImIa+wXQ0g8IgoofDFRp5UMzaNk1UqI= cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk= cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk= cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE= cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= +cloud.google.com/go/channel v1.16.0/go.mod h1:eN/q1PFSl5gyu0dYdmxNXscY/4Fi7ABmeHCJNf/oHmc= cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U= cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA= cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M= cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg= cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= +cloud.google.com/go/cloudbuild v1.10.1/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM= cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk= cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= +cloud.google.com/go/clouddms v1.6.1/go.mod h1:Ygo1vL52Ov4TBZQquhz5fiw2CQ58gvu+PlS6PVXCpZI= cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4= cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI= cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y= cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= +cloud.google.com/go/cloudtasks v1.11.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= @@ -174,8 +199,11 @@ cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63 cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= -cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg= +cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= +cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= @@ -184,15 +212,18 @@ cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2Aawl cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= +cloud.google.com/go/contactcenterinsights v1.9.1/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo= cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4= cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM= cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= +cloud.google.com/go/container v1.22.1/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI= cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= +cloud.google.com/go/containeranalysis v0.10.1/go.mod h1:Ya2jiILITMY68ZLPaogjmOMNkwsDrWBSTyBubGXO7j0= cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= @@ -201,44 +232,56 @@ cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOX cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M= cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0= cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= +cloud.google.com/go/datacatalog v1.14.0/go.mod h1:h0PrGtlihoutNMp/uvwhawLQ9+c63Kz65UFqh49Yo+E= +cloud.google.com/go/datacatalog v1.14.1/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4= cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= +cloud.google.com/go/dataflow v0.9.1/go.mod h1:Wp7s32QjYuQDWqJPFFlnBKhkAtiFpMTdg00qGbnIHVw= cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0= cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA= cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= +cloud.google.com/go/dataform v0.8.1/go.mod h1:3BhPSiw8xmppbgzeBbmDvmSWlwouuJkXsXsb8UBih9M= cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38= cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w= cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= +cloud.google.com/go/datafusion v1.7.1/go.mod h1:KpoTBbFmoToDExJUso/fcCiguGDk7MEzOWXUsJo0wsI= cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= +cloud.google.com/go/datalabeling v0.8.1/go.mod h1:XS62LBSVPbYR54GfYQsPXZjTW8UxCK2fkDciSrpRFdY= cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA= cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A= cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ= cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= +cloud.google.com/go/dataplex v1.8.1/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s= cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI= cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= +cloud.google.com/go/dataqna v0.8.1/go.mod h1:zxZM0Bl6liMePWsHA8RMGAfmTG34vJMapbHAxQ5+WA8= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM= cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= +cloud.google.com/go/datastore v1.12.0/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= +cloud.google.com/go/datastore v1.12.1/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g= cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4= cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs= cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= +cloud.google.com/go/datastream v1.9.1/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q= cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c= cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s= cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI= cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= +cloud.google.com/go/deploy v1.11.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g= cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= @@ -247,35 +290,44 @@ cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFM cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM= cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4= cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= +cloud.google.com/go/dialogflow v1.38.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4= cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM= cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q= cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= +cloud.google.com/go/dlp v1.10.1/go.mod h1:IM8BWz1iJd8njcNcG0+Kyd9OPnqnRNkDV8j42VT5KOI= cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k= cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4= cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM= cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= +cloud.google.com/go/documentai v1.20.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E= cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= +cloud.google.com/go/domains v0.9.1/go.mod h1:aOp1c0MbejQQ2Pjf1iJvnVyT+z6R6s8pX66KaCSDYfE= cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc= cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= +cloud.google.com/go/edgecontainer v1.1.1/go.mod h1:O5bYcS//7MELQZs3+7mabRqoWQhXCzenBu0R8bz2rwk= cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI= cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8= cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= +cloud.google.com/go/essentialcontacts v1.6.2/go.mod h1:T2tB6tX+TRak7i88Fb2N9Ok3PvY3UNbUsMag9/BARh4= cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc= cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw= cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw= cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= +cloud.google.com/go/eventarc v1.12.1/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI= cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w= cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= +cloud.google.com/go/filestore v1.7.1/go.mod h1:y10jsorq40JJnjR/lQ8AfFbbcGlw3g+Dp8oN7i7FjV4= cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/firestore v1.11.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4= cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY= @@ -283,28 +335,35 @@ cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5Uwt cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw= cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA= cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= +cloud.google.com/go/functions v1.15.1/go.mod h1:P5yNWUTkyU+LvW/S9O6V+V423VZooALQlqoXdoPz5AE= cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w= cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM= cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= +cloud.google.com/go/gaming v1.10.1/go.mod h1:XQQvtfP8Rb9Rxnxm5wFVpAp9zCQkJi2bLIb7iHGwB3s= cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60= cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo= cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= +cloud.google.com/go/gkeconnect v0.8.1/go.mod h1:KWiK1g9sDLZqhxB2xEuPV8V9NYzrqTUmQR9shJHpOZw= cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E= cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= +cloud.google.com/go/gkehub v0.14.1/go.mod h1:VEXKIJZ2avzrbd7u+zeMtW00Y8ddk/4V9511C9CQGTY= cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA= cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI= cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= +cloud.google.com/go/gkemulticloud v0.6.1/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw= cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/grafeas v0.3.0/go.mod h1:P7hgN24EyONOTMyeJH6DxG4zD7fwiYa5Q6GUgyFSOU8= cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM= cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o= cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= +cloud.google.com/go/gsuiteaddons v1.6.1/go.mod h1:CodrdOqRZcLp5WOwejHWYBjZvfY0kOphkAKpF/3qdZY= cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= @@ -314,6 +373,8 @@ cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGE cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY= cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY= cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= +cloud.google.com/go/iam v1.0.1/go.mod h1:yR3tmSL8BcZB4bxByRv2jkSIahVmCtfKZwLYGBalRE8= +cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5gVyk= cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y= cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc= @@ -321,13 +382,16 @@ cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/ cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk= cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo= cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= +cloud.google.com/go/iap v1.8.1/go.mod h1:sJCbeqg3mvWLqjZNsI6dfAtbbV1DL2Rl7e1mTyXYREQ= cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM= cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY= cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= +cloud.google.com/go/ids v1.4.1/go.mod h1:np41ed8YMU8zOgv53MMMoCntLTn2lF+SUzlM+O3u/jw= cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs= cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g= cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o= cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= +cloud.google.com/go/iot v1.7.1/go.mod h1:46Mgw7ev1k9KqK1ao0ayW9h0lI+3hxeanz+L1zmbbbk= cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= @@ -335,92 +399,118 @@ cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4 cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w= cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24= cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= -cloud.google.com/go/kms v1.12.1 h1:xZmZuwy2cwzsocmKDOPu4BL7umg8QXagQx6fKVmf45U= +cloud.google.com/go/kms v1.11.0/go.mod h1:hwdiYC0xjnWsKQQCQQmIQnS9asjYVSK6jtXm+zFqXLM= +cloud.google.com/go/kms v1.12.1/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM= +cloud.google.com/go/kms v1.15.0 h1:xYl5WEaSekKYN5gGRyhjvZKM22GVBBCzegGNVPy+aIs= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE= cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8= cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= +cloud.google.com/go/language v1.10.1/go.mod h1:CPp94nsdVNiQEt1CNjF5WkTcisLiHPyIbMhvR8H2AW0= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= +cloud.google.com/go/lifesciences v0.9.1/go.mod h1:hACAOd1fFbCGLr/+weUKRAJas82Y4vrL3O5326N//Wc= cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw= cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= +cloud.google.com/go/longrunning v0.4.2/go.mod h1:OHrnaYyLUV6oqwh0xiS7e5sLQhP1m0QU9R+WhGDMgIQ= +cloud.google.com/go/longrunning v0.5.0/go.mod h1:0JNuqRShmscVAhIACGtskSAWtqtOoPkwP0YF1oVEchc= +cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc= cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE= cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM= cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= +cloud.google.com/go/managedidentities v1.6.1/go.mod h1:h/irGhTN2SkZ64F43tfGPMbHnypMbu4RB3yl8YcuEak= cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI= cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw= cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= +cloud.google.com/go/mediatranslation v0.8.1/go.mod h1:L/7hBdEYbYHQJhX2sldtTO5SZZ1C1vkapubj0T2aGig= cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA= cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY= cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= +cloud.google.com/go/memcache v1.10.1/go.mod h1:47YRQIarv4I3QS5+hoETgKO40InqzLP6kpNLvyXuyaA= cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8= cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI= cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= +cloud.google.com/go/metastore v1.11.1/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA= cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk= cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4= cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w= cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= +cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM= cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM= cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8= cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E= cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= +cloud.google.com/go/networkconnectivity v1.12.1/go.mod h1:PelxSWYM7Sh9/guf8CFhi6vIqf19Ir/sbfZRUwXh92E= cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8= cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4= cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= +cloud.google.com/go/networkmanagement v1.8.0/go.mod h1:Ho/BUGmtyEqrttTgWEe7m+8vDdK74ibQc+Be0q7Fof0= cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k= cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= +cloud.google.com/go/networksecurity v0.9.1/go.mod h1:MCMdxOKQ30wsBI1eI659f9kEp4wuuAueoC9AJKSPWZQ= cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA= cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0= cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE= cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= +cloud.google.com/go/notebooks v1.9.1/go.mod h1:zqG9/gk05JrzgBt4ghLzEepPHNwE5jgPcHZRKhlC1A8= cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4= cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs= cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= +cloud.google.com/go/optimization v1.4.1/go.mod h1:j64vZQP7h9bO49m2rVaTVoNM0vEBEN5eKPUPbZyXOrk= cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA= cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk= cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= +cloud.google.com/go/orchestration v1.8.1/go.mod h1:4sluRF3wgbYVRqz7zJ1/EUNc90TTprliq9477fGobD8= cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE= cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc= cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= +cloud.google.com/go/orgpolicy v1.11.0/go.mod h1:2RK748+FtVvnfuynxBzdnyu7sygtoZa1za/0ZfpOs1M= +cloud.google.com/go/orgpolicy v1.11.1/go.mod h1:8+E3jQcpZJQliP+zaFfayC2Pg5bmhuLK755wKhIIUCE= cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo= cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw= cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= +cloud.google.com/go/osconfig v1.12.0/go.mod h1:8f/PaYzoS3JMVfdfTubkowZYGmAhUCjjwnjqWI7NVBc= +cloud.google.com/go/osconfig v1.12.1/go.mod h1:4CjBxND0gswz2gfYRCUoUzCm9zCABp91EeTtWXyz0tE= cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70= cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo= cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= +cloud.google.com/go/oslogin v1.10.1/go.mod h1:x692z7yAue5nE7CsSnoG0aaMbNoRJRXO4sn73R+ZqAs= cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= +cloud.google.com/go/phishingprotection v0.8.1/go.mod h1:AxonW7GovcA8qdEk13NfHq9hNx5KPtfxXNeUxTDxB6I= cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg= cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE= cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw= cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= +cloud.google.com/go/policytroubleshooter v1.7.1/go.mod h1:0NaT5v3Ag1M7U5r0GfDCpUFkWd9YqpubBWsQlhanRv0= cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg= cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= +cloud.google.com/go/privatecatalog v0.9.1/go.mod h1:0XlDXW2unJXdf9zFz968Hp35gl/bhF4twwpXZAW50JA= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -429,11 +519,13 @@ cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcd cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0= cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8= cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= -cloud.google.com/go/pubsub v1.32.0 h1:JOEkgEYBuUTHSyHS4TcqOFuWr+vD6qO/imsFqShUCp4= cloud.google.com/go/pubsub v1.32.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= +cloud.google.com/go/pubsub v1.33.0 h1:6SPCPvWav64tj0sVX/+npCBKhUi/UjJehy9op/V3p2g= +cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg= cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k= cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= +cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0= cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= @@ -442,32 +534,39 @@ cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U= cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA= cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= +cloud.google.com/go/recaptchaenterprise/v2 v2.7.2/go.mod h1:kR0KjsJS7Jt1YSyWFkseQ756D45kaYNTlDPPaRAvDBU= cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= +cloud.google.com/go/recommendationengine v0.8.1/go.mod h1:MrZihWwtFYWDzE6Hz5nKcNz3gLizXVIDI/o3G1DLcrE= cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs= cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70= cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= +cloud.google.com/go/recommender v1.10.1/go.mod h1:XFvrE4Suqn5Cq0Lf+mCP6oBHD/yRMA8XxP5sb7Q7gpA= cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA= cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM= cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= +cloud.google.com/go/redis v1.13.1/go.mod h1:VP7DGLpE91M6bcsDdMuyCm2hIpB6Vp2hI090Mfd1tcg= cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA= cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0= cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots= cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo= cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= +cloud.google.com/go/resourcemanager v1.9.1/go.mod h1:dVCuosgrh1tINZ/RwBufr8lULmWGOkPS8gL5gqyjdT8= cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU= cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg= cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= +cloud.google.com/go/resourcesettings v1.6.1/go.mod h1:M7mk9PIZrC5Fgsu1kZJci6mpgN8o0IUzVx3eJU3y4Jw= cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc= cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y= cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= +cloud.google.com/go/retail v1.14.1/go.mod h1:y3Wv3Vr2k54dLNIrCzenyKG8g8dhvhncT2NcNjb/6gE= cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do= cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo= cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM= @@ -478,10 +577,12 @@ cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRr cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44= cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc= cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= +cloud.google.com/go/scheduler v1.10.1/go.mod h1:R63Ldltd47Bs4gnhQkmNDse5w8gBRrhObZ54PxgR2Oo= cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4= cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4= cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= +cloud.google.com/go/secretmanager v1.11.1/go.mod h1:znq9JlXgTNdBeQk9TBW/FnR/W4uChEKGeqQWAJ8SXFw= cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= @@ -489,12 +590,14 @@ cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA= cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8= cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= +cloud.google.com/go/security v1.15.1/go.mod h1:MvTnnbsWnehoizHi09zoiZob0iCHVcL4AUBj76h9fXA= cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk= cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk= cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0= cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= +cloud.google.com/go/securitycenter v1.23.0/go.mod h1:8pwQ4n+Y9WCWM278R8W3nF65QtY172h4S8aXyI9/hsQ= cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU= cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s= cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA= @@ -506,6 +609,7 @@ cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPj cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U= cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY= cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= +cloud.google.com/go/servicedirectory v1.10.1/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ= cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco= cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo= cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc= @@ -517,15 +621,18 @@ cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DR cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4= cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw= cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= +cloud.google.com/go/shell v1.7.1/go.mod h1:u1RaM+huXFaTojTbW4g9P5emOrrmLE69KrxqQahKn4g= cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos= cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk= cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= +cloud.google.com/go/spanner v1.47.0/go.mod h1:IXsJwVW2j4UKs0eYDqodab6HgGuA1bViSqW4uH9lfUI= cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0= cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco= cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0= cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= +cloud.google.com/go/speech v1.17.1/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= @@ -543,37 +650,45 @@ cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POF cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I= cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4= cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= +cloud.google.com/go/storagetransfer v1.10.0/go.mod h1:DM4sTlSmGiNczmV6iZyceIh2dbs+7z2Ayg6YAiQlYfA= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM= cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA= cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= +cloud.google.com/go/talent v1.6.2/go.mod h1:CbGvmKCG61mkdjcqTcLOkb2ZN1SrQI8MDyma2l7VD24= cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8= cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4= cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= +cloud.google.com/go/texttospeech v1.7.1/go.mod h1:m7QfG5IXxeneGqTapXNxv2ItxP/FS0hCZBwXYqucgSk= cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ= cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg= cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= +cloud.google.com/go/tpu v1.6.1/go.mod h1:sOdcHVIgDEEOKuqUoi6Fq53MKHJAtOwtz0GuKsWSH3E= cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28= cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y= cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA= cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= +cloud.google.com/go/trace v1.10.1/go.mod h1:gbtL94KE5AJLH3y+WVpfWILmqgc6dXcqgNXdOPAQTYk= cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs= cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg= cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0= cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/translate v1.8.1/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk= cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw= cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg= cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk= cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/video v1.17.1/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU= cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M= cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU= cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= +cloud.google.com/go/videointelligence v1.11.1/go.mod h1:76xn/8InyQHarjTWsBR058SmlPCwQjgcvoW0aZykOvo= cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= @@ -581,29 +696,36 @@ cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E= cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY= cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= +cloud.google.com/go/vision/v2 v2.7.2/go.mod h1:jKa8oSYBWhYiXarHPvP4USxYANYUEdEsQrloLjrSwJU= cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE= cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g= cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc= cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= +cloud.google.com/go/vmmigration v1.7.1/go.mod h1:WD+5z7a/IpZ5bKK//YmT9E047AD+rjycCAvyMxGJbro= cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208= cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8= cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= +cloud.google.com/go/vmwareengine v0.4.1/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0= cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w= cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8= cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= +cloud.google.com/go/vpcaccess v1.7.1/go.mod h1:FogoD46/ZU+JUBX9D606X21EnxiszYi2tArQwLY4SXs= cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc= cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A= cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= +cloud.google.com/go/webrisk v1.9.1/go.mod h1:4GCmXKcOa2BZcZPn6DCEvE7HypmEJcJkr4mtM+sqYPc= cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo= cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ= cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= +cloud.google.com/go/websecurityscanner v1.6.1/go.mod h1:Njgaw3rttgRHXzwCB8kgCYqv5/rGpFCsBOvPbYgszpg= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= +cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= @@ -628,6 +750,7 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= +github.com/apache/arrow/go/v12 v12.0.0/go.mod h1:d+tV/eHZZ7Dz7RPrFKtPK02tpr+c9/PEd/zm8mDS9Vg= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/aristanetworks/arista-ceoslab-operator/v2 v2.0.1 h1:lOGhvrrxc/bzUMJI4kYmZh/N1a87Vnsk/TENZt5kCoc= github.com/aristanetworks/arista-ceoslab-operator/v2 v2.0.1/go.mod h1:/mvSt2fEmlVEU7dppip3UNz/MUt380f50dFsZRGn83o= @@ -672,6 +795,8 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230428030218-4003588d1b74/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -682,6 +807,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0= github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= @@ -697,11 +823,16 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= +github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= +github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= +github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= @@ -754,8 +885,8 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= -github.com/golang/glog v1.1.1 h1:jxpi2eWoU84wbX9iIEyAeeoac3FLuifZpY9tcNUD9kw= -github.com/golang/glog v1.1.1/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -845,6 +976,8 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/protobuf v3.11.4+incompatible/go.mod h1:lUQ9D1ePzbH2PrIS7ob/bjm9HXyH5WHB0Akwh7URreM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= +github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -868,6 +1001,8 @@ github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqE github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw= github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4= github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= @@ -933,6 +1068,7 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+ github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= +github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= @@ -941,7 +1077,9 @@ github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= @@ -966,10 +1104,10 @@ github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc= github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= github.com/open-traffic-generator/ixia-c-operator v0.3.4 h1:xH0hLVWf2wuVUT9ovFdh/WwwBf1oGkBu5YEWD61igck= github.com/open-traffic-generator/ixia-c-operator v0.3.4/go.mod h1:Q+ZXCinXxUKcnrJf5PJC1Q7JxUQc5ZPZA85jwVAqIRQ= -github.com/open-traffic-generator/snappi/gosnappi v0.12.1 h1:wT8Zu74wjv7OtquJ1WzcIwz6H8EHyrqEaCIpS9UiQfo= -github.com/open-traffic-generator/snappi/gosnappi v0.12.1/go.mod h1:WZgX4CdajxEN4T6cf/oiGfTYUbFClcJFD+Zar1QVeCs= -github.com/openconfig/entity-naming v0.0.0-20230812015236-03f6f9489f24 h1:o0lPkFXwh9kJzXJo/VExxZZ+6Sda1/QpARywGh+fY5M= -github.com/openconfig/entity-naming v0.0.0-20230812015236-03f6f9489f24/go.mod h1:ZRUrfwYYY+pLaOoWPad3p/8J4LLQcSqtXhBCkD2pXJc= +github.com/open-traffic-generator/snappi/gosnappi v0.12.3 h1:Qu9rAPvD98wgDzr1W7srtf7pkQsI8FXv3w6p76RHjcY= +github.com/open-traffic-generator/snappi/gosnappi v0.12.3/go.mod h1:C1W8UKEsCCRX9j/bRmAWVd6prlZPqp5/jHzoCp3MMJI= +github.com/openconfig/entity-naming v0.0.0-20230829162409-b28ee246e213 h1:HwztR9b5qfdWASbKtdx7BGojKSORTBb7IM/Q66ns85s= +github.com/openconfig/entity-naming v0.0.0-20230829162409-b28ee246e213/go.mod h1:ZRUrfwYYY+pLaOoWPad3p/8J4LLQcSqtXhBCkD2pXJc= github.com/openconfig/gnmi v0.0.0-20200414194230-1597cc0f2600/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A= github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A= github.com/openconfig/gnmi v0.0.0-20220920173703-480bf53a74d2/go.mod h1:Y9os75GmSkhHw2wX8sMsxfI7qRGAEcDh8NTa5a8vj6E= @@ -977,16 +1115,16 @@ github.com/openconfig/gnmi v0.10.0 h1:kQEZ/9ek3Vp2Y5IVuV2L/ba8/77TgjdXg505QXvYmg github.com/openconfig/gnmi v0.10.0/go.mod h1:Y9os75GmSkhHw2wX8sMsxfI7qRGAEcDh8NTa5a8vj6E= github.com/openconfig/gnoi v0.1.0 h1:7Odq6UyieHuXW3PYfDBj/dUWgFrL9KVMm0iooQoFLdw= github.com/openconfig/gnoi v0.1.0/go.mod h1:ZMRwQ7maVNSOjie3Jn67fW5WY7UDrFSiYSlV/GxthQs= -github.com/openconfig/gnsi v1.2.1 h1:JIC6+uVg39jLx3K39g/n6+J7b+c8FKU8TgwFAxmON+A= -github.com/openconfig/gnsi v1.2.1/go.mod h1:QikTHkm468uc2rq/kVhETfyZ6FPeM+zitubrHBbB0HE= +github.com/openconfig/gnsi v1.2.3 h1:Y/fBMQOn5xqdo9xuT7AK2YHSRejx/ws4sDOMBCHQG6w= +github.com/openconfig/gnsi v1.2.3/go.mod h1:QikTHkm468uc2rq/kVhETfyZ6FPeM+zitubrHBbB0HE= github.com/openconfig/gocloser v0.0.0-20220310182203-c6c950ed3b0b h1:NSYuxdlOWLldNpid1dThR6Dci96juXioUguMho6aliI= github.com/openconfig/gocloser v0.0.0-20220310182203-c6c950ed3b0b/go.mod h1:uhC/ybmPapgeyAL2b9ZrUQ+DZE+DB+J+/7377PX+lek= github.com/openconfig/goyang v0.0.0-20200115183954-d0a48929f0ea/go.mod h1:dhXaV0JgHJzdrHi2l+w0fZrwArtXL7jEFoiqLEdmkvU= github.com/openconfig/goyang v0.2.2/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= github.com/openconfig/goyang v0.2.9/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= github.com/openconfig/goyang v1.2.0/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= -github.com/openconfig/goyang v1.4.0 h1:/7T1Wk0r/8Bxcdh1LhWsnAKl+QuUV6Pfl4AyH63r9bA= -github.com/openconfig/goyang v1.4.0/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= +github.com/openconfig/goyang v1.4.1 h1:OmkovLj01iOskzviwnoXkWWY0fwfhPVGTAKKCMSbgeE= +github.com/openconfig/goyang v1.4.1/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= github.com/openconfig/gribi v0.1.1-0.20210423184541-ce37eb4ba92f/go.mod h1:OoH46A2kV42cIXGyviYmAlGmn6cHjGduyC2+I9d/iVs= github.com/openconfig/gribi v0.1.1-0.20221218044856-ec9f4fc18013/go.mod h1:VFqGH2ZPFIfnKTimP4/AQB4OK0eySW5muJNFxXAwP6k= github.com/openconfig/gribi v0.1.1-0.20230111180713-7ea0c4e1ee20/go.mod h1:VFqGH2ZPFIfnKTimP4/AQB4OK0eySW5muJNFxXAwP6k= @@ -1000,20 +1138,18 @@ github.com/openconfig/kne v0.1.14 h1:3xHy2bP+rr+2/2uFqliWXGjMPR7umO6mvFXh/TA2aJE github.com/openconfig/kne v0.1.14/go.mod h1:gMhrUKk6aveDaLSo2yi/25tDm9pSlmgRkG8IP45CGqs= github.com/openconfig/lemming/operator v0.2.0 h1:dovZnR6lQkOHXcODli1NDOr/GVYrBY05KS5X11jxVbw= github.com/openconfig/lemming/operator v0.2.0/go.mod h1:LKgEXSR5VK2CAeh2uKijKAXFj42uQuwakrCHVPF0iII= -github.com/openconfig/ondatra v0.2.7 h1:abEI0qO4Q/BrXV/qi2unXn8dpkZFp9DF8rw6kZod5/E= -github.com/openconfig/ondatra v0.2.7/go.mod h1:Vfwg/PvsupSJOxTxpQvF078MyHxJGvff3jIr4H0vgzs= +github.com/openconfig/ondatra v0.2.8 h1:Ivh5p4kFnXgZVIqGmfgICwH19CJSgafWE8LD9qy0lrE= +github.com/openconfig/ondatra v0.2.8/go.mod h1:Wgp0ZqfuCr4ooUHNqMvO1gCV4jVzg2/JTZJkc6E1W8g= github.com/openconfig/testt v0.0.0-20220311054427-efbb1a32ec07 h1:X631iD/B0ximGFb5P9LY5wHju4SiedxUhc5UZEo7VSw= github.com/openconfig/testt v0.0.0-20220311054427-efbb1a32ec07/go.mod h1:bmpU0kIsCiXuncozViVuQx1HqolC3C94H7lD9KKmoTo= -github.com/openconfig/ygnmi v0.8.7 h1:8K87+VztXhHqsU6/OYRnY/l/bGqFk+qU61mhhdxMCYo= -github.com/openconfig/ygnmi v0.8.7/go.mod h1:7up6qc9l9G4+Cfo37gzO0D7+2g4yqyW+xzh4vYsYTEE= -github.com/openconfig/ygnmi v0.8.8 h1:zadlR/bonL5hSzPLgFneKurUYf0ANcBoc52StEFJgHs= -github.com/openconfig/ygnmi v0.8.8/go.mod h1:7up6qc9l9G4+Cfo37gzO0D7+2g4yqyW+xzh4vYsYTEE= +github.com/openconfig/ygnmi v0.8.9 h1:QkGuqQm3CloQeVmCaN9aD9OSZ+/xLMIhAGqKkp3tL+8= +github.com/openconfig/ygnmi v0.8.9/go.mod h1:7up6qc9l9G4+Cfo37gzO0D7+2g4yqyW+xzh4vYsYTEE= github.com/openconfig/ygot v0.6.0/go.mod h1:o30svNf7O0xK+R35tlx95odkDmZWS9JyWWQSmIhqwAs= github.com/openconfig/ygot v0.10.4/go.mod h1:oCQNdXnv7dWc8scTDgoFkauv1wwplJn5HspHcjlxSAQ= github.com/openconfig/ygot v0.13.2/go.mod h1:kJN0yCXIH07dOXvNBEFm3XxXdnDD5NI6K99tnD5x49c= github.com/openconfig/ygot v0.25.6/go.mod h1:+IVqHe5iTfGcDRi3szuq1Mgvy5q3S4x8DG69K5kw62o= -github.com/openconfig/ygot v0.29.9 h1:SCDD3Vs0qeYgBu+tqynxgSXsgHMomAnB57Yzhe5221M= -github.com/openconfig/ygot v0.29.9/go.mod h1:dmcOYUbSoFRiIj8Wv8ZDXApdnSEbmCdQVNANnXogjD0= +github.com/openconfig/ygot v0.29.10 h1:FRZXxyeCdiJXz6uat5uOm3Hlg+PUu2N0mY+eiva12MI= +github.com/openconfig/ygot v0.29.10/go.mod h1:RNnn1ytQ8GZV5LPts36l0cyoRjsYYpruiruJEvmU2sg= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/p4lang/p4runtime v1.4.0-rc.5 h1:zztZGEkRM09Hf25SIX0p0ML07dmRCgsy0oC8uafmjtg= github.com/p4lang/p4runtime v1.4.0-rc.5/go.mod h1:m9laObIMXM9N1ElGXijc66/MSM5eheZJLRLxg/TG+fU= @@ -1022,8 +1158,8 @@ github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTK github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= -github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= @@ -1041,13 +1177,15 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/protocolbuffers/txtpbfmt v0.0.0-20220608084003-fc78c767cd6a h1:AKJY61V2SQtJ2a2PdeswKk0NM1qF77X+julRNYRxPOk= github.com/protocolbuffers/txtpbfmt v0.0.0-20220608084003-fc78c767cd6a/go.mod h1:KjY0wibdYKc4DYkerHSbguaf3JeIPGhNJBp2BNiFH78= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= @@ -1103,11 +1241,12 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -1156,10 +1295,14 @@ golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1175,8 +1318,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691 h1:/yRP+0AN7mf5DkD3BAI6TOFnd51gEoDEb8o35jIFtgw= -golang.org/x/exp v0.0.0-20230728194245-b0cb94b80691/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1219,6 +1362,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1272,6 +1417,7 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= @@ -1279,8 +1425,11 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1310,8 +1459,9 @@ golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= -golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8= +golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1328,8 +1478,9 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1408,24 +1559,32 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1442,8 +1601,10 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1514,6 +1675,9 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1589,6 +1753,10 @@ google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/ google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= +google.golang.org/api v0.118.0/go.mod h1:76TtD3vkgmZ66zZzp72bUUklpmQmKlhh6sYtIjYK+5E= +google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= +google.golang.org/api v0.124.0/go.mod h1:xu2HQurE5gi/3t1aFCvhPD781p0a3p11sdunTJ2BlP4= +google.golang.org/api v0.125.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o= google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -1734,18 +1902,35 @@ google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVix google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= -google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= -google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e h1:xIXmWJ303kJCuogpj0bHq+dcjcZHU+XFyc1I0Yl9cRg= -google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:0ggbjUrZYpy1q+ANUS30SEoGZ53cdfwtbuG7Ptgy108= +google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= +google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= +google.golang.org/genproto v0.0.0-20230629202037-9506855d4529/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= +google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y= +google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0= +google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= +google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 h1:XVeBY8d/FaK4848myy41HBqnDwvxeV3zMZhwN1TvAMU= +google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e h1:z3vDksarJxsAKM5dmEGv0GHwE2hKJ096wZra71Vs4sw= +google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230731193218-e0aa005b6bdf h1:guOdSPaeFgN+jEJwTo1dQ71hdBm+yKSCCKuTRkJzcVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230731193218-e0aa005b6bdf/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:8mL13HKkDa+IuJ8yruA3ci0q+0vsUz4m//+ottjwS5o= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1784,12 +1969,14 @@ google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= -google.golang.org/grpc v1.58.0-dev h1:BggFp6joqwbgXlqFIogQr6r35o+BnzYw54An5wzoSLA= -google.golang.org/grpc v1.58.0-dev/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.58.0 h1:32JY8YpPMSR45K+c3o6b8VL73V+rR8k+DeMIr4vRH8o= +google.golang.org/grpc v1.58.0/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1860,12 +2047,17 @@ lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= +modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20= +modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0= modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc= modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw= +modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI= modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ= modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= +modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g= +modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY= modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= @@ -1875,19 +2067,31 @@ modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= +modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA= +modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0= +modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0= +modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI= +modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw= modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= +modernc.org/sqlite v1.18.2/go.mod h1:kvrTLEWgxUcHa2GfHBQtanR1H9ht3hTJNtKpzH9k1u0= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= +modernc.org/tcl v1.13.2/go.mod h1:7CLiGIPo1M8Rv1Mitpv5akc2+8fxUd2y2UzC/MfMzy0= modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/topologies/binding/binding.go b/topologies/binding/binding.go index a00485e5297..085d314ce5e 100644 --- a/topologies/binding/binding.go +++ b/topologies/binding/binding.go @@ -185,7 +185,7 @@ func (d *staticDUT) DialP4RT(ctx context.Context, opts ...grpc.DialOption) (p4pb return p4pb.NewP4RuntimeClient(conn), nil } -func (d *staticDUT) DialCLI(_ context.Context) (binding.StreamClient, error) { +func (d *staticDUT) DialCLI(_ context.Context) (binding.CLIClient, error) { dialer, err := d.r.ssh(d.Name()) if err != nil { return nil, err diff --git a/topologies/binding/cli.go b/topologies/binding/cli.go index 7851f8c3069..51b95e6622b 100644 --- a/topologies/binding/cli.go +++ b/topologies/binding/cli.go @@ -17,60 +17,19 @@ package binding import ( "context" "fmt" - "io" "github.com/openconfig/ondatra/binding" "golang.org/x/crypto/ssh" ) -// cli implements the binding.StreamClient interface using an SSH -// client (see also the ondatra.StreamClient returned by -// dut.RawAPIS().CLI()). It creates a default session with pty and -// shell to service stdin, stdout, and stderr; each SendCommand will -// run in its own session but without shell or pty. +// cli implements the binding.ClientClient interface using an SSH client. type cli struct { - *binding.AbstractStreamClient - - ssh *ssh.Client - sess *ssh.Session - stdin io.WriteCloser - stdout io.Reader - stderr io.Reader + *binding.AbstractCLIClient + ssh *ssh.Client } -var _ = binding.StreamClient(&cli{}) - func newCLI(sc *ssh.Client) (*cli, error) { - sess, err := sc.NewSession() - if err != nil { - return nil, fmt.Errorf("could not create session: %w", err) - } - if err := sess.RequestPty("ansi", 24, 80, nil); err != nil { - return nil, fmt.Errorf("could not request pty: %w", err) - } - stdin, err := sess.StdinPipe() - if err != nil { - return nil, fmt.Errorf("could not get stdin: %w", err) - } - stdout, err := sess.StdoutPipe() - if err != nil { - return nil, fmt.Errorf("could not get stdout: %w", err) - } - stderr, err := sess.StderrPipe() - if err != nil { - return nil, fmt.Errorf("could not get stderr: %w", err) - } - if err := sess.Shell(); err != nil { - return nil, fmt.Errorf("could not start shell: %w", err) - } - c := &cli{ - ssh: sc, - sess: sess, - stdin: stdin, - stdout: stdout, - stderr: stderr, - } - return c, nil + return &cli{ssh: sc}, nil } func (c *cli) SendCommand(_ context.Context, cmd string) (string, error) { @@ -85,19 +44,3 @@ func (c *cli) SendCommand(_ context.Context, cmd string) (string, error) { } return string(buf), nil } - -func (c *cli) Stdin() io.WriteCloser { - return c.stdin -} - -func (c *cli) Stdout() io.ReadCloser { - return io.NopCloser(c.stdout) -} - -func (c *cli) Stderr() io.ReadCloser { - return io.NopCloser(c.stderr) -} - -func (c *cli) Close() error { - return c.ssh.Close() -} diff --git a/topologies/binding/cli_test.go b/topologies/binding/cli_test.go index 03f3172cc32..d7fc333a598 100644 --- a/topologies/binding/cli_test.go +++ b/topologies/binding/cli_test.go @@ -41,16 +41,6 @@ type cliFixture struct { cli *cli } -func (f *cliFixture) close(t testing.TB) { - if f.cli == nil { - return - } - if err := f.cli.Close(); err != nil { - t.Errorf("Could not close cli: %v", err) - } - f.cli = nil -} - // serverPrivateKey and serverPublicKey are ed25519 key pairs // specifically generated for testing. This is initialized as // serverSigner. @@ -281,48 +271,18 @@ var cmpSortStrings = cmpopts.SortSlices(func(a, b string) bool { func TestCLI(t *testing.T) { f := &cliFixture{} - defer f.close(t) if err := f.start(t); err != nil { t.Fatalf("Could not start cliFixture: %v", err) } t.Log("Test is ready.") - stdout := bufio.NewReader(f.cli.Stdout()) - stderr := bufio.NewReader(f.cli.Stderr()) - - t.Run("StdinStdout", func(t *testing.T) { - f.cli.Stdin().Write([]byte("hello\n")) - got, err := stdout.ReadString('\n') - if err != nil { - t.Fatalf("Could not read from stdout: %v", err) - } - want := "pty shell hello\n" - if got != want { - t.Errorf("Stdout got %q, want %q", got, want) - } - }) - - t.Run("StdinStderr", func(t *testing.T) { - f.cli.Stdin().Write([]byte("stderr hello again\n")) - got, err := stderr.ReadString('\n') - if err != nil { - t.Fatalf("Could not read from stderr: %v", err) - } - want := "pty shell stderr hello again\n" - if got != want { - t.Errorf("Stderr got %q, want %q", got, want) - } - }) - - t.Run("SendCommand", func(t *testing.T) { - output, err := f.cli.SendCommand(context.Background(), "xyzzy") - if err != nil { - t.Fatalf("Could not execute command: %v", err) - } - got := strings.Split(output, "\n") - want := []string{"exec command: xyzzy", "exec stderr", ""} - if diff := cmp.Diff(want, got, cmpSortStrings); diff != "" { - t.Errorf("Command output -want, +got:\n%s", diff) - } - }) + output, err := f.cli.SendCommand(context.Background(), "xyzzy") + if err != nil { + t.Fatalf("Could not execute command: %v", err) + } + got := strings.Split(output, "\n") + want := []string{"exec command: xyzzy", "exec stderr", ""} + if diff := cmp.Diff(want, got, cmpSortStrings); diff != "" { + t.Errorf("Command output -want, +got:\n%s", diff) + } } diff --git a/topologies/binding/gnsi.go b/topologies/binding/gnsi.go index 0a21bc016e0..7469edf20b3 100644 --- a/topologies/binding/gnsi.go +++ b/topologies/binding/gnsi.go @@ -18,7 +18,7 @@ import ( "github.com/openconfig/ondatra/binding" "google.golang.org/grpc" - accpb "github.com/openconfig/gnsi/accounting" + accpb "github.com/openconfig/gnsi/acctz" authzpb "github.com/openconfig/gnsi/authz" certzpb "github.com/openconfig/gnsi/certz" credpb "github.com/openconfig/gnsi/credentialz" @@ -40,11 +40,8 @@ func (g gnsiConn) Certz() certzpb.CertzClient { return certzpb.NewCertzClient(g. func (g gnsiConn) Credentialz() credpb.CredentialzClient { return credpb.NewCredentialzClient(g.conn) } -func (g gnsiConn) AccountingPull() accpb.AccountingPullClient { - return accpb.NewAccountingPullClient(g.conn) -} -func (g gnsiConn) AccountingPush() accpb.AccountingPushClient { - return accpb.NewAccountingPushClient(g.conn) +func (g gnsiConn) Acctz() accpb.AcctzClient { + return accpb.NewAcctzClient(g.conn) } var _ = binding.GNSIClients(gnsiConn{}) diff --git a/topologies/binding/reset.go b/topologies/binding/reset.go index 532bfd1b59b..712a7d0bfaf 100644 --- a/topologies/binding/reset.go +++ b/topologies/binding/reset.go @@ -59,11 +59,11 @@ func resetCLI(ctx context.Context, bdut *bindpb.Device, r resolver) error { if err != nil { return err } + defer sc.Close() cli, err := newCLI(sc) if err != nil { return err } - defer cli.Close() if _, err := cli.SendCommand(ctx, conf); err != nil { return err From d6f1ba2c0d7925b79b56fd2b7a0b326c87be1271 Mon Sep 17 00:00:00 2001 From: ahsaanyousaf <46231245+ahsaanyousaf@users.noreply.github.com> Date: Fri, 8 Sep 2023 13:10:58 -0700 Subject: [PATCH 13/43] 400ZR test for monitoring pre FEC BER. (#2078) * 400ZR transceiver test for monitoring pre-FEC BER. --------- Co-authored-by: Darren Loher --- .../transceiver/ZR_pre-fec_ber_test/README.md | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 feature/platform/transceiver/ZR_pre-fec_ber_test/README.md diff --git a/feature/platform/transceiver/ZR_pre-fec_ber_test/README.md b/feature/platform/transceiver/ZR_pre-fec_ber_test/README.md new file mode 100644 index 00000000000..3a55b191fe0 --- /dev/null +++ b/feature/platform/transceiver/ZR_pre-fec_ber_test/README.md @@ -0,0 +1,48 @@ +# gNMI-1.20: Telemetry: 400ZR Optics Pre-FEC(Forward Error Correction) BER(Bit Error Rate) + +## Summary + +Validate 400ZR optics module reports pre-FEC bit error rate performance data. + +## Procedure + +* Connect two ZR interfaces using a duplex LC fiber jumper such that TX + output power of one is the RX input power of the other module. +* To establish a point to point ZR link ensure the following: + * Both transceivers state is enabled + * Both transceivers are set to a valid target TX output power + example -10 dBm + * Both transceivers are tuned to a valid centre frequency + example 193.1 THz +* With the link ZR link established as explained above, verify that the + following ZR transceiver telemetry paths exist and are streamed for both + the ZR optics + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/instant + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/avg + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/min + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/max + +**Note:** For min, max, and avg values, 10 second sampling is preferred. If + 10 seconds is not supported, the sampling interval used must be + communicated. + + +* Verify that the optics pre-FEC BER is updated after the interface flaps. + + * Enable a pair of ZR interfaces on the DUT as explained above. + * Verify the ZR optics pre FEC BER PMs are in the normal range. + * Disable or shut down the interface on the DUT. + * Re-enable the interfaces on the DUT. + * Verify the ZR optics pre FEC PM is updated to the value in the normal + range again. Typical expected value should be less than 1.2E-2 + +## Config Parameter coverage + +* /components/component/oc-transceiver:transceiver/oc-transceiver/config/enabled + +## Telemetry Parameter coverage + + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/instant + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/avg + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/min + * /terminal-device/logical-channels/channel/otn/state/pre-fec-ber/max \ No newline at end of file From 3277670458dd78b1f2bf5d2d5bb05bb8cbfb25da Mon Sep 17 00:00:00 2001 From: Tushar Rathod <111466464+trathod1@users.noreply.github.com> Date: Fri, 8 Sep 2023 18:45:22 -0400 Subject: [PATCH 14/43] DP-1.14: Adding test support for Nokia (#2026) * DP-1.14: Adding test support for Nokia Following changes are made in this PR - 1. Updating deviations in metadata file 2. Updating test script to support Nokia 3. Adding function (SetForwardingGroupWithFabricPriority) to configure ForwardingGroup with Fabric-priority in qoscfg.go "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." Co-authored-by: Krishna Bovilla * Replacing fabric-priority configuration with queue-id as discussed in b/297188157 "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." --------- Co-authored-by: Krishna Bovilla Co-authored-by: Sergey Fomin --- .../qos_basic_test/metadata.textproto | 4 ++- .../qos_basic_test/qos_basic_test.go | 26 +++++++++++++++++ .../qos_basic_test/metadata.textproto | 4 ++- .../qos_basic_test/qos_basic_test.go | 29 ++++++++++++++++--- 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/feature/qos/ate_tests/qos_basic_test/metadata.textproto b/feature/qos/ate_tests/qos_basic_test/metadata.textproto index 50aa355399f..1df28d671a7 100644 --- a/feature/qos/ate_tests/qos_basic_test/metadata.textproto +++ b/feature/qos/ate_tests/qos_basic_test/metadata.textproto @@ -28,8 +28,10 @@ platform_exceptions: { vendor: NOKIA } deviations: { - explicit_interface_ref_definition: true interface_enabled: true + explicit_port_speed: true + explicit_interface_in_default_vrf: true + qos_octets: true } } platform_exceptions: { diff --git a/feature/qos/ate_tests/qos_basic_test/qos_basic_test.go b/feature/qos/ate_tests/qos_basic_test/qos_basic_test.go index f2d3b3fd48e..97f552f46b8 100644 --- a/feature/qos/ate_tests/qos_basic_test/qos_basic_test.go +++ b/feature/qos/ate_tests/qos_basic_test/qos_basic_test.go @@ -513,6 +513,14 @@ func ConfigureDUTIntf(t *testing.T, dut *ondatra.DUTDevice) { a := s.GetOrCreateAddress(intf.ipAddr) a.PrefixLength = ygot.Uint8(intf.prefixLen) gnmi.Replace(t, dut, gnmi.OC().Interface(intf.intfName).Config(), i) + if deviations.ExplicitInterfaceInDefaultVRF(dut) { + fptest.AssignToNetworkInstance(t, dut, intf.intfName, deviations.DefaultNetworkInstance(dut), 0) + } + } + if deviations.ExplicitPortSpeed(dut) { + fptest.SetPortSpeed(t, dp1) + fptest.SetPortSpeed(t, dp2) + fptest.SetPortSpeed(t, dp3) } } @@ -525,6 +533,15 @@ func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { q := d.GetOrCreateQos() queues := netutil.CommonTrafficQueues(t, dut) + if dut.Vendor() == ondatra.NOKIA { + queueNames := []string{queues.NC1, queues.AF4, queues.AF3, queues.AF2, queues.AF1, queues.BE0, queues.BE1} + for i, queue := range queueNames { + q1 := q.GetOrCreateQueue(queue) + q1.Name = ygot.String(queue) + queueid := len(queueNames) - i + q1.QueueId = ygot.Uint8(uint8(queueid)) + } + } t.Logf("Create qos forwarding groups and queue name config") forwardingGroups := []struct { desc string @@ -893,19 +910,28 @@ func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { ecnProfile: "ECNProfile", }} + maxBurstSize := uint32(268435456) t.Logf("qos output interface config: %v", schedulerIntfs) for _, tc := range schedulerIntfs { i := q.GetOrCreateInterface(dp3.Name()) i.SetInterfaceId(dp3.Name()) + i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) output := i.GetOrCreateOutput() schedulerPolicy := output.GetOrCreateSchedulerPolicy() schedulerPolicy.SetName(tc.scheduler) queue := output.GetOrCreateQueue(tc.queueName) queue.SetName(tc.queueName) queue.SetQueueManagementProfile(tc.ecnProfile) + if dut.Vendor() == ondatra.NOKIA { + bufferAllocation := q.GetOrCreateBufferAllocationProfile("ballocprofile") + bq := bufferAllocation.GetOrCreateQueue(tc.queueName) + bq.SetStaticSharedBufferLimit(maxBurstSize) + output.SetBufferAllocationProfile("ballocprofile") + } gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) } } + func ConfigureCiscoQos(t *testing.T, dut *ondatra.DUTDevice) { t.Helper() dp1 := dut.Port(t, "port1") diff --git a/feature/qos/otg_tests/qos_basic_test/metadata.textproto b/feature/qos/otg_tests/qos_basic_test/metadata.textproto index 50aa355399f..1df28d671a7 100644 --- a/feature/qos/otg_tests/qos_basic_test/metadata.textproto +++ b/feature/qos/otg_tests/qos_basic_test/metadata.textproto @@ -28,8 +28,10 @@ platform_exceptions: { vendor: NOKIA } deviations: { - explicit_interface_ref_definition: true interface_enabled: true + explicit_port_speed: true + explicit_interface_in_default_vrf: true + qos_octets: true } } platform_exceptions: { diff --git a/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go b/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go index e9714508c1a..42a281b2fec 100644 --- a/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go +++ b/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go @@ -575,6 +575,14 @@ func ConfigureDUTIntf(t *testing.T, dut *ondatra.DUTDevice) { a := s.GetOrCreateAddress(intf.ipAddr) a.PrefixLength = ygot.Uint8(intf.prefixLen) gnmi.Replace(t, dut, gnmi.OC().Interface(intf.intfName).Config(), i) + if deviations.ExplicitInterfaceInDefaultVRF(dut) { + fptest.AssignToNetworkInstance(t, dut, intf.intfName, deviations.DefaultNetworkInstance(dut), 0) + } + } + if deviations.ExplicitPortSpeed(dut) { + fptest.SetPortSpeed(t, dp1) + fptest.SetPortSpeed(t, dp2) + fptest.SetPortSpeed(t, dp3) } } @@ -587,6 +595,15 @@ func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { q := d.GetOrCreateQos() queues := netutil.CommonTrafficQueues(t, dut) + if dut.Vendor() == ondatra.NOKIA { + queueNames := []string{queues.NC1, queues.AF4, queues.AF3, queues.AF2, queues.AF1, queues.BE0, queues.BE1} + for i, queue := range queueNames { + q1 := q.GetOrCreateQueue(queue) + q1.Name = ygot.String(queue) + queueid := len(queueNames) - i + q1.QueueId = ygot.Uint8(uint8(queueid)) + } + } t.Logf("Create qos forwarding groups and queue name config") forwardingGroups := []struct { desc string @@ -596,10 +613,6 @@ func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { desc: "forwarding-group-BE1", queueName: queues.BE1, targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: queues.BE0, - targetGroup: "target-group-BE0", }, { desc: "forwarding-group-AF1", queueName: queues.AF1, @@ -955,16 +968,24 @@ func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { ecnProfile: "ECNProfile", }} + maxBurstSize := uint32(268435456) t.Logf("qos output interface config: %v", schedulerIntfs) for _, tc := range schedulerIntfs { i := q.GetOrCreateInterface(dp3.Name()) i.SetInterfaceId(dp3.Name()) + i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) output := i.GetOrCreateOutput() schedulerPolicy := output.GetOrCreateSchedulerPolicy() schedulerPolicy.SetName(tc.scheduler) queue := output.GetOrCreateQueue(tc.queueName) queue.SetName(tc.queueName) queue.SetQueueManagementProfile(tc.ecnProfile) + if dut.Vendor() == ondatra.NOKIA { + bufferAllocation := q.GetOrCreateBufferAllocationProfile("ballocprofile") + bq := bufferAllocation.GetOrCreateQueue(tc.queueName) + bq.SetStaticSharedBufferLimit(maxBurstSize) + output.SetBufferAllocationProfile("ballocprofile") + } gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) } } From 55444707910d0803221859803be5b4afb79c1c3d Mon Sep 17 00:00:00 2001 From: Darren Loher Date: Fri, 8 Sep 2023 23:06:15 -0700 Subject: [PATCH 15/43] Add template for creating test requirement README files (#2106) --- .../ISSUE_TEMPLATE/new_test_requirement.md | 16 +++++ doc/test-requirements-template.md | 71 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 doc/test-requirements-template.md diff --git a/.github/ISSUE_TEMPLATE/new_test_requirement.md b/.github/ISSUE_TEMPLATE/new_test_requirement.md index f3b950bdcc7..b2072b92ae5 100644 --- a/.github/ISSUE_TEMPLATE/new_test_requirement.md +++ b/.github/ISSUE_TEMPLATE/new_test_requirement.md @@ -1,5 +1,6 @@ --- name: New featureprofiles test requirement +<<<<<<< Updated upstream about: Use this template to document the requirements for a new test to be implemented. title: '' labels: enhancement @@ -49,3 +50,18 @@ For example: * Get * Check * Artifact +======= +about: Use this template to create an issue to assign and track implemenation of the code for a test. +title: '' +labels: enhancement +assignees: '' +--- + +# Request for New Test Code Implementation Instructions + +* The label 'enhancement' is automatically set by this template. +* Add a label for the test priority according to the test requirements. (p0, p1, p2) +* Add a link in this issue description to the README.md for the test requirements. For example: + +Implement code for [Test name here]() +>>>>>>> Stashed changes diff --git a/doc/test-requirements-template.md b/doc/test-requirements-template.md new file mode 100644 index 00000000000..61b2f0df0cf --- /dev/null +++ b/doc/test-requirements-template.md @@ -0,0 +1,71 @@ +--- +name: New featureprofiles test requirement +about: Use this template to document the requirements for a new test to be implemented. +title: '' +labels: enhancement +assignees: '' + +--- + +# Instructions for this template + +Below is the required template for writing test requirements. Good examples of test +requirements include: + +* [TE-3.7: Base Hierarchical NHG Update](/feature/gribi/otg_tests/base_hierarchical_nhg_update/README.md) +* [gNMI-1.13: Telemetry: Optics Power and Bias Current](https://github.com/openconfig/featureprofiles/blob/main/feature/platform/tests/optics_power_and_bias_current_test/README.md) +* [RT-5.1: Singleton Interface](https://github.com/openconfig/featureprofiles/blob/main/feature/interface/singleton/otg_tests/singleton_test/README.md) + +# TestID-x.y: Short name of test here + +## Summary + +Write a few sentences or paragraphs describing the purpose and scope of the test. + +## Testbed type + +* Specify the .testbed topology file from the [topologies](https://github.com/openconfig/featureprofiles/tree/main/topologies) folder to be used with this test + +## Procedure + +* Sub Test #1 - Name of test + * Step 1 + * Step 2 + * Validation and pass fail criteria + +* Sub Test #2 - New of test + * Step 1 + * Step 2 + * Validation and pass fail criteria + +## Config Parameter Coverage + +Add list of OpenConfig 'config' paths used in this test, if any. + +## Telemetry Parameter Coverage + +Add list of OpenConfig 'state' paths used in this test, if any. + +## Protocol/RPC Parameter Coverage + +Add list of OpenConfig RPC's (gNMI, gNOI, gNSI, gRIBI) used in the list, if any. + +For example: + +* gNMI + * Set + * Subscribe +* gNOI + * System + * KillProcess + * Healthz + * Get + * Check + * Artifact + +## Required DUT platform + +* Specify the minimum DUT-type: + * MFF - A modular form factor device containing LINECARDs, FABRIC and redundant CONTROLLER_CARD components + * FFF - fixed form factor + * vRX - virtual router device From ce47e05f97fc2266f8697db845d857295de3155b Mon Sep 17 00:00:00 2001 From: cprabha Date: Sun, 10 Sep 2023 08:41:06 -0700 Subject: [PATCH 16/43] dutdutate testbed (#2105) * Initial commit for adding dutdutate testbed * commit after Make * Add trailing new line --------- Co-authored-by: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> --- cloudbuild/virtual.sh | 1 + internal/fptest/runtests.go | 1 + proto/metadata.proto | 1 + proto/metadata_go_proto/metadata.pb.go | 11 ++- topologies/dutdutate.testbed | 39 ++++++++++ .../kne/arista/ceos/dutdutate.textproto | 56 ++++++++++++++ .../kne/cisco/8000e/dutdutate.textproto | 56 ++++++++++++++ topologies/kne/cisco/xrd/dutdutate.textproto | 56 ++++++++++++++ .../kne/juniper/cptx/dutdutate.textproto | 75 +++++++++++++++++++ .../kne/nokia/srlinux/dutdutate.textproto | 68 +++++++++++++++++ .../openconfig/lemming/dutdutate.textproto | 28 +++++++ 11 files changed, 389 insertions(+), 3 deletions(-) create mode 100644 topologies/dutdutate.testbed create mode 100644 topologies/kne/arista/ceos/dutdutate.textproto create mode 100644 topologies/kne/cisco/8000e/dutdutate.textproto create mode 100644 topologies/kne/cisco/xrd/dutdutate.textproto create mode 100644 topologies/kne/juniper/cptx/dutdutate.textproto create mode 100644 topologies/kne/nokia/srlinux/dutdutate.textproto create mode 100644 topologies/kne/openconfig/lemming/dutdutate.textproto diff --git a/cloudbuild/virtual.sh b/cloudbuild/virtual.sh index 25399c7ec57..88a2805d39d 100755 --- a/cloudbuild/virtual.sh +++ b/cloudbuild/virtual.sh @@ -82,6 +82,7 @@ function metadata_kne_topology() { kne_topology_file["TESTBED_DUT_ATE_2LINKS"]="${topo_prefix}/dutate.textproto" kne_topology_file["TESTBED_DUT_ATE_4LINKS"]="${topo_prefix}/dutate.textproto" kne_topology_file["TESTBED_DUT_ATE_9LINKS_LAG"]="${topo_prefix}/dutate_lag.textproto" + kne_topology_file["TESTBED_DUT_DUT_ATE_2LINKS"]="${topo_prefix}/dutdutate.textproto" for p in "${!kne_topology_file[@]}"; do if grep -q "testbed.*${p}$" "${metadata_test_path}"/metadata.textproto; then echo "${kne_topology_file[${p}]}" diff --git a/internal/fptest/runtests.go b/internal/fptest/runtests.go index fcc0d3a395a..d6aa487f6c8 100644 --- a/internal/fptest/runtests.go +++ b/internal/fptest/runtests.go @@ -73,6 +73,7 @@ func testbedPathFromMetadata() (string, error) { mpb.Metadata_TESTBED_DUT_ATE_2LINKS: "atedut_2.testbed", mpb.Metadata_TESTBED_DUT_ATE_4LINKS: "atedut_4.testbed", mpb.Metadata_TESTBED_DUT_ATE_9LINKS_LAG: "atedut_9_lag.testbed", + mpb.Metadata_TESTBED_DUT_DUT_ATE_2LINKS: "dutdutate.testbed", } testbedFile, ok := testbedToFile[testbed] if !ok { diff --git a/proto/metadata.proto b/proto/metadata.proto index fbbf5b0b4a0..66920f7d097 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -35,6 +35,7 @@ message Metadata { TESTBED_DUT_ATE_2LINKS = 3; TESTBED_DUT_ATE_4LINKS = 4; TESTBED_DUT_ATE_9LINKS_LAG = 5; + TESTBED_DUT_DUT_ATE_2LINKS = 6; } // Testbed on which the test is intended to run. Testbed testbed = 4; diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 6169fecfd73..e0f9386124e 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -46,6 +46,7 @@ const ( Metadata_TESTBED_DUT_ATE_2LINKS Metadata_Testbed = 3 Metadata_TESTBED_DUT_ATE_4LINKS Metadata_Testbed = 4 Metadata_TESTBED_DUT_ATE_9LINKS_LAG Metadata_Testbed = 5 + Metadata_TESTBED_DUT_DUT_ATE_2LINKS Metadata_Testbed = 6 ) // Enum value maps for Metadata_Testbed. @@ -57,6 +58,7 @@ var ( 3: "TESTBED_DUT_ATE_2LINKS", 4: "TESTBED_DUT_ATE_4LINKS", 5: "TESTBED_DUT_ATE_9LINKS_LAG", + 6: "TESTBED_DUT_DUT_ATE_2LINKS", } Metadata_Testbed_value = map[string]int32{ "TESTBED_UNSPECIFIED": 0, @@ -65,6 +67,7 @@ var ( "TESTBED_DUT_ATE_2LINKS": 3, "TESTBED_DUT_ATE_4LINKS": 4, "TESTBED_DUT_ATE_9LINKS_LAG": 5, + "TESTBED_DUT_DUT_ATE_2LINKS": 6, } ) @@ -1369,7 +1372,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x99, 0x3d, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb9, 0x3d, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1841,7 +1844,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, - 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x07, 0x54, + 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xc7, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, @@ -1852,7 +1855,9 @@ var file_metadata_proto_rawDesc = []byte{ 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, - 0x41, 0x47, 0x10, 0x05, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, + 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, + 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, + 0x4b, 0x53, 0x10, 0x06, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, diff --git a/topologies/dutdutate.testbed b/topologies/dutdutate.testbed new file mode 100644 index 00000000000..f440a5180fe --- /dev/null +++ b/topologies/dutdutate.testbed @@ -0,0 +1,39 @@ +# proto-file: github.com/openconfig/ondatra/blob/main/proto/testbed.proto +# proto-message: ondatra.Testbed + +# This testbed provides 2 DUTs and ATE connected serially. +# This is used for control plane testing, not traffic testing. + +duts { + id: "dut1" + ports { + id: "port1" + } + ports { + id: "port2" + } +} + +duts { + id: "dut2" + ports { + id: "port1" + } +} + +ates { + id: "ate" + ports { + id: "port1" + } +} + +links { + a: "dut1:port1" + b: "ate:port1" +} + +links { + a: "dut1:port2" + b: "dut2:port1" +} diff --git a/topologies/kne/arista/ceos/dutdutate.textproto b/topologies/kne/arista/ceos/dutdutate.textproto new file mode 100644 index 00000000000..ca353a0a6b9 --- /dev/null +++ b/topologies/kne/arista/ceos/dutdutate.textproto @@ -0,0 +1,56 @@ +name: "arista-ceos-dutdut" +nodes: { + name: "dut1" + vendor: ARISTA + model: "ceos" + os: "eos" + config: { + image: "ceos:latest" + file: "config.cfg" + config_path: "/mnt/flash" + config_file: "startup-config" + cert: { + self_signed: { + cert_name: "gnmiCert.pem" + key_name: "gnmiCertKey.pem" + key_size: 4096 + } + } + } +} +nodes: { + name: "dut2" + vendor: ARISTA + model: "ceos" + os: "eos" + config: { + image: "ceos:latest" + file: "config.cfg" + config_path: "/mnt/flash" + config_file: "startup-config" + cert: { + self_signed: { + cert_name: "gnmiCert.pem" + key_name: "gnmiCertKey.pem" + key_size: 4096 + } + } + } +} +nodes: { + name: "otg" + vendor: KEYSIGHT + version: "0.0.1-9999" # Please update this with the local version from ixiatg-configmap.yaml +} +links: { + a_node: "otg" + a_int: "eth1" + z_node: "dut1" + z_int: "eth1" +} +links: { + a_node: "dut1" + a_int: "eth2" + z_node: "dut2" + z_int: "eth1" +} diff --git a/topologies/kne/cisco/8000e/dutdutate.textproto b/topologies/kne/cisco/8000e/dutdutate.textproto new file mode 100644 index 00000000000..35b040c836f --- /dev/null +++ b/topologies/kne/cisco/8000e/dutdutate.textproto @@ -0,0 +1,56 @@ +name: "cisco-8000e-dutdut" +nodes: { + name: "dut1" + vendor: CISCO + model: "8201" + os: "ios-xr" + config: { + image: "8000e:latest" + file: "config.cfg" + } + interfaces: { + key: "eth1" + value: { + name: "FourHundredGigE0/0/0/0" + } + } + interfaces: { + key: "eth2" + value: { + name: "FourHundredGigE0/0/0/1" + } + } +} +nodes: { + name: "dut2" + vendor: CISCO + model: "8201" + os: "ios-xr" + config: { + image: "8000e:latest" + file: "config.cfg" + } + interfaces: { + key: "eth1" + value: { + name: "FourHundredGigE0/0/0/0" + } + } +} +nodes: { + name: "otg" + vendor: KEYSIGHT + version: "0.0.1-9999" # Please update this with the local version from ixiatg-configmap.yaml +} +links: { + a_node: "otg" + a_int: "eth1" + z_node: "dut1" + z_int: "eth1" +} +links: { + a_node: "dut1" + a_int: "eth2" + z_node: "dut2" + z_int: "eth1" +} diff --git a/topologies/kne/cisco/xrd/dutdutate.textproto b/topologies/kne/cisco/xrd/dutdutate.textproto new file mode 100644 index 00000000000..b1a3593bfc8 --- /dev/null +++ b/topologies/kne/cisco/xrd/dutdutate.textproto @@ -0,0 +1,56 @@ +name: "cisco-xrd-dutdut" +nodes: { + name: "dut1" + vendor: CISCO + model: "xrd" + os: "ios-xr" + config: { + image: "xrd:latest" + file: "config.cfg" + } + interfaces: { + key: "eth1" + value: { + name: "GigabitEthernet0/0/0/0" + } + } + interfaces: { + key: "eth2" + value: { + name: "GigabitEthernet0/0/0/1" + } + } +} +nodes: { + name: "dut2" + vendor: CISCO + model: "xrd" + os: "ios-xr" + config: { + image: "xrd:latest" + file: "config.cfg" + } + interfaces: { + key: "eth1" + value: { + name: "GigabitEthernet0/0/0/0" + } + } +} +nodes: { + name: "otg" + vendor: KEYSIGHT + version: "0.0.1-9999" # Please update this with the local version from ixiatg-configmap.yaml +} +links: { + a_node: "otg" + a_int: "eth1" + z_node: "dut" + z_int: "eth1" +} +links: { + a_node: "dut1" + a_int: "eth2" + z_node: "dut2" + z_int: "eth1" +} diff --git a/topologies/kne/juniper/cptx/dutdutate.textproto b/topologies/kne/juniper/cptx/dutdutate.textproto new file mode 100644 index 00000000000..a1a97e39204 --- /dev/null +++ b/topologies/kne/juniper/cptx/dutdutate.textproto @@ -0,0 +1,75 @@ +name: "juniper-cptx-dutdutate" +nodes: { + name: "dut1" + vendor: JUNIPER + model: "cptx" + os: "evo" + config: { + image: "cptx:latest" + config_path: "/home/evo/configdisk" + config_file: "juniper.conf" + file: "config.cfg" + cert: { + self_signed: { + cert_name: "grpc-server-cert" + key_name: "N/A" + key_size: 4096 + } + } + } + interfaces: { + key: "eth4" + value: { + name: "et-0/0/0:0" + } + } + interfaces: { + key: "eth12" + value: { + name: "et-0/0/1:0" + } + } +} +nodes: { + name: "dut2" + vendor: JUNIPER + model: "cptx" + os: "evo" + config: { + image: "cptx:latest" + config_path: "/home/evo/configdisk" + config_file: "juniper.conf" + file: "config.cfg" + cert: { + self_signed: { + cert_name: "grpc-server-cert" + key_name: "N/A" + key_size: 4096 + } + } + } + interfaces: { + key: "eth12" + value: { + name: "et-0/0/1:0" + } + } +} +nodes: { + name: "otg" + vendor: KEYSIGHT + version: "0.0.1-9999" # Please update this with the local version from ixiatg-configmap.yaml +} +links: { + a_node: "otg" + a_int: "eth1" + z_node: "dut1" + z_int: "eth4" +} +links: { + a_node: "dut1" + a_int: "eth12" + z_node: "dut2" + z_int: "eth12" +} + diff --git a/topologies/kne/nokia/srlinux/dutdutate.textproto b/topologies/kne/nokia/srlinux/dutdutate.textproto new file mode 100644 index 00000000000..4e9a6b4cba5 --- /dev/null +++ b/topologies/kne/nokia/srlinux/dutdutate.textproto @@ -0,0 +1,68 @@ +name: "nokia-srlinux-dutdut" +nodes: { + name: "dut1" + vendor: NOKIA + model: "ixr10" + config: { + image: "srlinux:latest" + file: "config.cfg" + cert: { + self_signed: { + cert_name: "kne-profile" + key_name: "N/A" + key_size: 4096 + } + } + } + interfaces: { + key: "e1-1" + value: { + name: "ethernet-1/1" + } + } + interfaces: { + key: "e1-2" + value: { + name: "ethernet-1/2" + } + } +} +nodes: { + name: "dut2" + vendor: NOKIA + model: "ixr10" + config: { + image: "srlinux:latest" + file: "config.cfg" + cert: { + self_signed: { + cert_name: "kne-profile" + key_name: "N/A" + key_size: 4096 + } + } + } + interfaces: { + key: "e1-1" + value: { + name: "ethernet-1/1" + } + } +} +nodes: { + name: "otg" + vendor: KEYSIGHT + version: "0.0.1-9999" # Please update this with the local version from ixiatg-configmap.yaml +} +links: { + a_node: "otg" + a_int: "eth1" + z_node: "dut1" + z_int: "e1-1" +} +links: { + a_node: "dut1" + a_int: "e1-2" + z_node: "dut2" + z_int: "e1-1" +} diff --git a/topologies/kne/openconfig/lemming/dutdutate.textproto b/topologies/kne/openconfig/lemming/dutdutate.textproto new file mode 100644 index 00000000000..c0b8c9423c5 --- /dev/null +++ b/topologies/kne/openconfig/lemming/dutdutate.textproto @@ -0,0 +1,28 @@ +name: "openconfig-lemming-dutdut" +nodes: { + name: "dut1" + vendor: OPENCONFIG + model: "LEMMING" +} +nodes: { + name: "dut2" + vendor: OPENCONFIG + model: "LEMMING" +} +nodes: { + name: "otg" + vendor: KEYSIGHT + version: "0.0.1-9999" # Please update this with the local version from ixiatg-configmap.yaml +} +links: { + a_node: "otg" + a_int: "eth1" + z_node: "dut" + z_int: "eth1" +} +links: { + a_node: "dut1" + a_int: "eth2" + z_node: "dut2" + z_int: "eth1" +} From 981ca565cd863d2fa3c842b388c5c018e5707997 Mon Sep 17 00:00:00 2001 From: Darren Loher Date: Mon, 11 Sep 2023 10:58:00 -0700 Subject: [PATCH 17/43] Clean test requirement issue template (#2113) * add new test req tmpl * refine min DUT platform description * clean test req issue template * make a better example link --- .../ISSUE_TEMPLATE/new_test_requirement.md | 54 +------------------ 1 file changed, 1 insertion(+), 53 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_test_requirement.md b/.github/ISSUE_TEMPLATE/new_test_requirement.md index b2072b92ae5..a384d423733 100644 --- a/.github/ISSUE_TEMPLATE/new_test_requirement.md +++ b/.github/ISSUE_TEMPLATE/new_test_requirement.md @@ -1,56 +1,5 @@ --- name: New featureprofiles test requirement -<<<<<<< Updated upstream -about: Use this template to document the requirements for a new test to be implemented. -title: '' -labels: enhancement -assignees: '' - ---- - -# TestID-x.y: Short name of test here - -## Summary - -Write a few sentences or paragraphs describing the purpose and scope of the test. - -## Procedure - -* Test #1 - Name of test - * Step 1 - * Step 2 - * Step 3 - -* Test #2 - New of test - * Step 1 - * Step 2 - * Step 3 - - -## Config Parameter Coverage - -Add list of OpenConfig 'config' paths used in this test, if any. - -## Telemetry Parameter Coverage - -Add list of OpenConfig 'state' paths used in this test, if any. - -## Protocol/RPC Parameter Coverage - -Add list of OpenConfig RPC's (gNMI, gNOI, gNSI, gRIBI) used in the list - -For example: -* gNMI - * Set - * Subscribe -* gNOI - * System - * KillProcess - * Healthz - * Get - * Check - * Artifact -======= about: Use this template to create an issue to assign and track implemenation of the code for a test. title: '' labels: enhancement @@ -63,5 +12,4 @@ assignees: '' * Add a label for the test priority according to the test requirements. (p0, p1, p2) * Add a link in this issue description to the README.md for the test requirements. For example: -Implement code for [Test name here]() ->>>>>>> Stashed changes +Implement code for [Test name here](https://github.com/openconfig/featureprofiles/blob/main/feature/example/tests/topology_test/README.md) From 5902d56306d104e93d3919bd6f90a06a15d44043 Mon Sep 17 00:00:00 2001 From: mananpat-cisco Date: Mon, 11 Sep 2023 15:16:05 -0400 Subject: [PATCH 18/43] FP-1.1 deviation removed (#2071) * FP-1.1 deviation removed * removed typo --- .../metadata.textproto | 1 - .../power_admin_down_up_test.go | 18 +++++------------- internal/deviations/deviations.go | 6 ------ proto/metadata.proto | 4 +--- proto/metadata_go_proto/metadata.pb.go | 13 ++----------- 5 files changed, 8 insertions(+), 34 deletions(-) diff --git a/feature/platform/tests/power_admin_down_up_test/metadata.textproto b/feature/platform/tests/power_admin_down_up_test/metadata.textproto index 1f3d179befd..7f89a50f234 100644 --- a/feature/platform/tests/power_admin_down_up_test/metadata.textproto +++ b/feature/platform/tests/power_admin_down_up_test/metadata.textproto @@ -35,7 +35,6 @@ platform_exceptions: { vendor: CISCO } deviations: { - component_power_down_returns_inactive_state: true skip_fabric_card_power_admin: true skip_controller_card_power_admin: true } diff --git a/feature/platform/tests/power_admin_down_up_test/power_admin_down_up_test.go b/feature/platform/tests/power_admin_down_up_test/power_admin_down_up_test.go index 986e4c6cbbb..733aef03bf3 100644 --- a/feature/platform/tests/power_admin_down_up_test/power_admin_down_up_test.go +++ b/feature/platform/tests/power_admin_down_up_test/power_admin_down_up_test.go @@ -146,19 +146,11 @@ func powerDownUp(t *testing.T, dut *ondatra.DUTDevice, name string, cType oc.E_P } t.Logf("Component %s, power-admin-state after %f minutes: %v", name, time.Since(start).Minutes(), power) - if deviations.ComponentPowerDownReturnsInactiveState(dut) { - oper, ok := gnmi.Await(t, dut, c.OperStatus().State(), timeout, oc.PlatformTypes_COMPONENT_OPER_STATUS_INACTIVE).Val() - if !ok { - t.Errorf("Component %s oper-status, got: %v, want: %v", name, oper, oc.PlatformTypes_COMPONENT_OPER_STATUS_INACTIVE) - } - t.Logf("Component %s, oper-status after %f minutes: %v", name, time.Since(start).Minutes(), oper) - } else { - oper, ok := gnmi.Await(t, dut, c.OperStatus().State(), timeout, oc.PlatformTypes_COMPONENT_OPER_STATUS_DISABLED).Val() - if !ok { - t.Errorf("Component %s oper-status, got: %v, want: %v", name, oper, oc.PlatformTypes_COMPONENT_OPER_STATUS_DISABLED) - } - t.Logf("Component %s, oper-status after %f minutes: %v", name, time.Since(start).Minutes(), oper) + oper, ok := gnmi.Await(t, dut, c.OperStatus().State(), timeout, oc.PlatformTypes_COMPONENT_OPER_STATUS_DISABLED).Val() + if !ok { + t.Errorf("Component %s oper-status, got: %v, want: %v", name, oper, oc.PlatformTypes_COMPONENT_OPER_STATUS_DISABLED) } + t.Logf("Component %s, oper-status after %f minutes: %v", name, time.Since(start).Minutes(), oper) start = time.Now() t.Logf("Starting %s POWER_ENABLE", name) gnmi.Replace(t, dut, config, oc.Platform_ComponentPowerType_POWER_ENABLED) @@ -171,7 +163,7 @@ func powerDownUp(t *testing.T, dut *ondatra.DUTDevice, name string, cType oc.E_P t.Logf("Component %s, power-admin-state after %f minutes: %v", name, time.Since(start).Minutes(), power) } - oper, ok := gnmi.Await(t, dut, c.OperStatus().State(), timeout, oc.PlatformTypes_COMPONENT_OPER_STATUS_ACTIVE).Val() + oper, ok = gnmi.Await(t, dut, c.OperStatus().State(), timeout, oc.PlatformTypes_COMPONENT_OPER_STATUS_ACTIVE).Val() if !ok { t.Errorf("Component %s oper-status after POWER_ENABLED, got: %v, want: %v", name, oper, oc.PlatformTypes_COMPONENT_OPER_STATUS_ACTIVE) } diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 40e47c5f16f..ed7f7267f8c 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -505,12 +505,6 @@ func SkipFabricCardPowerAdmin(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetSkipFabricCardPowerAdmin() } -// ComponentPowerDownReturnsInactiveState returns whether the device should allow the component power Down state inactive. -// Default value is false and expected component power down state is shutdown. -func ComponentPowerDownReturnsInactiveState(dut *ondatra.DUTDevice) bool { - return lookupDUTDeviations(dut).GetComponentPowerDownReturnsInactiveState() -} - // ISISRequireSameL1MetricWithL2Metric returns true for devices that require configuring // the same ISIS Metrics for Level 1 when configuring Level 2 Metrics. func ISISRequireSameL1MetricWithL2Metric(dut *ondatra.DUTDevice) bool { diff --git a/proto/metadata.proto b/proto/metadata.proto index 66920f7d097..a614b68f6a9 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -278,8 +278,6 @@ message Metadata { bool os_component_parent_is_chassis = 88; // Device does not support fabric power-admin-state leaf. bool skip_fabric_card_power_admin = 89; - // Device returns component state inactive during power down. - bool component_power_down_returns_inactive_state = 90; // Devices require configuring the same ISIS Metrics for Level 1 when // configuring Level 2 Metrics. bool isis_require_same_l1_metric_with_l2_metric = 91; @@ -331,7 +329,7 @@ message Metadata { bool isis_counter_part_changes_unsupported = 107; // Reserved field numbers and identifiers. - reserved 84, 9, 28; + reserved 84, 9, 28, 90; } message PlatformExceptions { diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index e0f9386124e..5415cb33625 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 -// protoc v3.21.12 +// protoc-gen-go v1.30.0 +// protoc v3.19.3 // source: metadata.proto package metadata_go_proto @@ -545,8 +545,6 @@ type Metadata_Deviations struct { OsComponentParentIsChassis bool `protobuf:"varint,88,opt,name=os_component_parent_is_chassis,json=osComponentParentIsChassis,proto3" json:"os_component_parent_is_chassis,omitempty"` // Device does not support fabric power-admin-state leaf. SkipFabricCardPowerAdmin bool `protobuf:"varint,89,opt,name=skip_fabric_card_power_admin,json=skipFabricCardPowerAdmin,proto3" json:"skip_fabric_card_power_admin,omitempty"` - // Device returns component state inactive during power down. - ComponentPowerDownReturnsInactiveState bool `protobuf:"varint,90,opt,name=component_power_down_returns_inactive_state,json=componentPowerDownReturnsInactiveState,proto3" json:"component_power_down_returns_inactive_state,omitempty"` // Devices require configuring the same ISIS Metrics for Level 1 when // configuring Level 2 Metrics. IsisRequireSameL1MetricWithL2Metric bool `protobuf:"varint,91,opt,name=isis_require_same_l1_metric_with_l2_metric,json=isisRequireSameL1MetricWithL2Metric,proto3" json:"isis_require_same_l1_metric_with_l2_metric,omitempty"` @@ -1183,13 +1181,6 @@ func (x *Metadata_Deviations) GetSkipFabricCardPowerAdmin() bool { return false } -func (x *Metadata_Deviations) GetComponentPowerDownReturnsInactiveState() bool { - if x != nil { - return x.ComponentPowerDownReturnsInactiveState - } - return false -} - func (x *Metadata_Deviations) GetIsisRequireSameL1MetricWithL2Metric() bool { if x != nil { return x.IsisRequireSameL1MetricWithL2Metric From 88b828f8b750d8f94aa86e8335a9b25e09392d41 Mon Sep 17 00:00:00 2001 From: Darren Loher Date: Mon, 11 Sep 2023 12:34:55 -0700 Subject: [PATCH 19/43] Update telemetry_inventory_test.go (#1694) Component type chassis is expected to return mfg-name Co-authored-by: sachendras <44847441+sachendras@users.noreply.github.com> --- .../tests/telemetry_inventory_test/telemetry_inventory_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/platform/tests/telemetry_inventory_test/telemetry_inventory_test.go b/feature/platform/tests/telemetry_inventory_test/telemetry_inventory_test.go index 9a8136eba04..22c55846f79 100644 --- a/feature/platform/tests/telemetry_inventory_test/telemetry_inventory_test.go +++ b/feature/platform/tests/telemetry_inventory_test/telemetry_inventory_test.go @@ -129,7 +129,7 @@ func TestHardwareCards(t *testing.T) { nameValidation: true, partNoValidation: true, serialNoValidation: true, - mfgNameValidation: false, + mfgNameValidation: true, mfgDateValidation: false, hwVerValidation: true, fwVerValidation: false, From c40bd73e961a3ee3036a1e7cfd61820acb936ca8 Mon Sep 17 00:00:00 2001 From: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> Date: Mon, 11 Sep 2023 16:35:29 -0400 Subject: [PATCH 20/43] Use simplified RawAPIs calls to fetch default clients (#2104) * Use simplified RawAPIs calls to fetch default/existing clients * Fix route_removal_during_failover_tests --- .../bgp_graceful_restart_test.go | 6 +++--- .../bgp_2byte_4byte_asn_policy_test.go | 2 +- .../bgp_long_lived_graceful_restart_test.go | 10 +++++----- .../dut_daemon_failure/dut_daemon_failure_test.go | 2 +- .../route_addition_during_failover_test.go | 4 ++-- .../route_removal_during_failover_test.go | 5 +++-- .../dut_daemon_failure/dut_daemon_failure_test.go | 2 +- .../route_addition_during_failover_test.go | 4 ++-- .../route_removal_during_failover_test.go | 5 +++-- .../isis/ate_tests/internal/session/session.go | 2 +- .../isis/otg_tests/internal/session/session.go | 2 +- feature/experimental/p4rt/README.md | 2 +- .../p4rt/ate_tests/base_p4rt/base_p4rt_test.go | 4 ++-- .../google_discovery_protocol_packetin_test.go | 4 ++-- .../google_discovery_protocol_packetout_test.go | 4 ++-- .../ate_tests/lldp_packetin_test/lldp_packetin_test.go | 4 ++-- .../lldp_packetout_test/lldp_packetout_test.go | 4 ++-- .../p4rt_daemon_failure_test.go | 2 +- .../ate_tests/performance_test/performance_test.go | 2 +- .../traceroute_packetin_test.go | 4 ++-- .../traceroute_packetout_test.go | 2 +- .../p4rt/otg_tests/base_p4rt/base_p4rt_test.go | 4 ++-- .../google_discovery_protocol_packetin_test.go | 4 ++-- .../google_discovery_protocol_packetout_test.go | 4 ++-- .../otg_tests/lldp_packetin_test/lldp_packetin_test.go | 4 ++-- .../lldp_packetout_test/lldp_packetout_test.go | 4 ++-- .../p4rt_daemon_failure_test.go | 2 +- .../otg_tests/performance_test/performance_test.go | 2 +- .../traceroute_packetin_test.go | 4 ++-- .../traceroute_packetout_test.go | 2 +- .../metadata_validation_test.go | 2 +- .../p4rt/tests/p4rt_election/p4rt_election_test.go | 2 +- .../tls_authentication_over_grpc_test.go | 2 +- .../system_generic_health_check_test.go | 2 +- .../tunnel_acl_based_test/tun_acl_dscp_test.go | 2 +- feature/gnoi/os/tests/osinstall/osinstall_test.go | 4 ++-- .../packet_link_qualification_test.go | 10 +++++----- .../chassis_reboot_status_and_cancel_test.go | 4 ++-- .../per_component_reboot_test.go | 6 +++--- feature/gnoi/system/tests/ping_test/ping_test.go | 2 +- .../system/tests/traceroute_test/traceroute_test.go | 2 +- feature/gribi/ate_tests/get_rpc_test/get_rpc_test.go | 2 +- .../ate_tests/gribi_scaling/gribi_scaling_test.go | 2 +- .../gribigo_compliance_test/gribigo_compliance_test.go | 2 +- .../hierarchical_weight_resolution_test.go | 2 +- .../gribi/ate_tests/ipv4_entry_test/ipv4_entry_test.go | 2 +- .../ate_tests/ordering_ack_test/ordering_ack_test.go | 2 +- .../route_removal_via_flush_test.go | 2 +- .../supervisor_failure_test/supervisor_failure_test.go | 2 +- .../port_flap_rebalanced_test.go | 2 +- .../weighted_balancing_test/weighted_balancing_test.go | 2 +- feature/gribi/otg_tests/get_rpc_test/get_rpc_test.go | 2 +- .../otg_tests/gribi_scaling/gribi_scaling_test.go | 2 +- .../gribigo_compliance_test/gribigo_compliance_test.go | 2 +- .../gribi/otg_tests/ipv4_entry_test/ipv4_entry_test.go | 2 +- .../otg_tests/ordering_ack_test/ordering_ack_test.go | 2 +- .../route_removal_via_flush_test.go | 2 +- .../supervisor_failure_test/supervisor_failure_test.go | 2 +- .../port_flap_rebalanced_test.go | 2 +- .../weighted_balancing_test/weighted_balancing_test.go | 2 +- .../core_lldp_tlv_population_test.go | 2 +- .../core_lldp_tlv_population_test.go | 2 +- .../ate_tests/cli_origin_test/cli_origin_test.go | 2 +- .../metadata/tests/annotation_test/annotation_test.go | 2 +- internal/components/components.go | 2 +- internal/fptest/networkinstance.go | 2 +- internal/gribi/gribi.go | 2 +- 67 files changed, 99 insertions(+), 97 deletions(-) diff --git a/feature/bgp/gracefulrestart/ate_tests/bgp_graceful_restart_test/bgp_graceful_restart_test.go b/feature/bgp/gracefulrestart/ate_tests/bgp_graceful_restart_test/bgp_graceful_restart_test.go index c50e12c5931..443b9ee4a83 100644 --- a/feature/bgp/gracefulrestart/ate_tests/bgp_graceful_restart_test/bgp_graceful_restart_test.go +++ b/feature/bgp/gracefulrestart/ate_tests/bgp_graceful_restart_test/bgp_graceful_restart_test.go @@ -582,7 +582,7 @@ func configACLNative(t testing.TB, d *ondatra.DUTDevice, name string) { }, }, } - gnmiClient := d.RawAPIs().GNMI().Default(t) + gnmiClient := d.RawAPIs().GNMI(t) if _, err := gnmiClient.Set(context.Background(), gpbSetRequest); err != nil { t.Fatalf("Unexpected error configuring SRL ACL: %v", err) } @@ -618,7 +618,7 @@ func configAdmitAllACLNative(t testing.TB, d *ondatra.DUTDevice, name string) { }, }, } - gnmiClient := d.RawAPIs().GNMI().Default(t) + gnmiClient := d.RawAPIs().GNMI(t) if _, err := gnmiClient.Set(context.Background(), gpbDelRequest); err != nil { t.Fatalf("Unexpected error removing SRL ACL: %v", err) } @@ -667,7 +667,7 @@ func configACLInterfaceNative(t *testing.T, d *ondatra.DUTDevice, ifName string) }, }, } - gnmiClient := d.RawAPIs().GNMI().Default(t) + gnmiClient := d.RawAPIs().GNMI(t) if _, err := gnmiClient.Set(context.Background(), gpbSetRequest); err != nil { t.Fatalf("Unexpected error configuring interface ACL: %v", err) } diff --git a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/bgp_2byte_4byte_asn_policy_test.go b/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/bgp_2byte_4byte_asn_policy_test.go index 0f5f7945fa4..7565490b256 100644 --- a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/bgp_2byte_4byte_asn_policy_test.go +++ b/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/bgp_2byte_4byte_asn_policy_test.go @@ -220,7 +220,7 @@ func juniperCLI() string { func configureRegexPolicy(t *testing.T, dut *ondatra.DUTDevice) { t.Helper() var config string - gnmiClient := dut.RawAPIs().GNMI().Default(t) + gnmiClient := dut.RawAPIs().GNMI(t) switch dut.Vendor() { case ondatra.JUNIPER: diff --git a/feature/experimental/bgp/ate_tests/bgp_long_lived_graceful_restart/bgp_long_lived_graceful_restart_test.go b/feature/experimental/bgp/ate_tests/bgp_long_lived_graceful_restart/bgp_long_lived_graceful_restart_test.go index af303cfb796..788f59da58e 100644 --- a/feature/experimental/bgp/ate_tests/bgp_long_lived_graceful_restart/bgp_long_lived_graceful_restart_test.go +++ b/feature/experimental/bgp/ate_tests/bgp_long_lived_graceful_restart/bgp_long_lived_graceful_restart_test.go @@ -725,7 +725,7 @@ func configACLNative(t testing.TB, d *ondatra.DUTDevice, name string) { }, }, } - gnmiClient := d.RawAPIs().GNMI().Default(t) + gnmiClient := d.RawAPIs().GNMI(t) if _, err := gnmiClient.Set(context.Background(), gpbSetRequest); err != nil { t.Fatalf("Unexpected error configuring SRL ACL: %v", err) } @@ -761,7 +761,7 @@ func configAdmitAllACLNative(t testing.TB, d *ondatra.DUTDevice, name string) { }, }, } - gnmiClient := d.RawAPIs().GNMI().Default(t) + gnmiClient := d.RawAPIs().GNMI(t) if _, err := gnmiClient.Set(context.Background(), gpbDelRequest); err != nil { t.Fatalf("Unexpected error removing SRL ACL: %v", err) } @@ -810,7 +810,7 @@ func configACLInterfaceNative(t *testing.T, d *ondatra.DUTDevice, ifName string) }, }, } - gnmiClient := d.RawAPIs().GNMI().Default(t) + gnmiClient := d.RawAPIs().GNMI(t) if _, err := gnmiClient.Set(context.Background(), gpbSetRequest); err != nil { t.Fatalf("Unexpected error configuring interface ACL: %v", err) } @@ -906,7 +906,7 @@ func findProcessByName(t *testing.T, dut *ondatra.DUTDevice, pName string) uint6 // gNOIKillProcess kills a daemon on the DUT, given its name and pid. func gNOIKillProcess(t *testing.T, dut *ondatra.DUTDevice, pName string, pID uint32) { t.Helper() - gnoiClient := dut.RawAPIs().GNOI().Default(t) + gnoiClient := dut.RawAPIs().GNOI(t) killRequest := &gnps.KillProcessRequest{Name: pName, Pid: pID, Signal: gnps.KillProcessRequest_SIGNAL_TERM, Restart: true} killResponse, err := gnoiClient.System().KillProcess(context.Background(), killRequest) t.Logf("Got kill process response: %v\n\n", killResponse) @@ -1275,7 +1275,7 @@ func TestTrafficWithGracefulRestart(t *testing.T) { }) t.Run("Disable LLGR on dut.", func(t *testing.T) { - gnmiClient := dut.RawAPIs().GNMI().Default(t) + gnmiClient := dut.RawAPIs().GNMI(t) config := disableLLGRConf(dut, dutAS) t.Logf("Push the CLI config:%s", dut.Vendor()) gpbSetRequest := buildCliConfigRequest(config) diff --git a/feature/experimental/gribi/ate_tests/dut_daemon_failure/dut_daemon_failure_test.go b/feature/experimental/gribi/ate_tests/dut_daemon_failure/dut_daemon_failure_test.go index d9daa2d65cf..466384a9c26 100644 --- a/feature/experimental/gribi/ate_tests/dut_daemon_failure/dut_daemon_failure_test.go +++ b/feature/experimental/gribi/ate_tests/dut_daemon_failure/dut_daemon_failure_test.go @@ -254,7 +254,7 @@ func verifyGRIBIGet(ctx context.Context, t *testing.T, clientA *gribi.Client, du // gNOIKillProcess kills a daemon on the DUT, given its name and pid. func gNOIKillProcess(ctx context.Context, t *testing.T, args *testArgs, pName string, pID uint32) { - gnoiClient := args.dut.RawAPIs().GNOI().Default(t) + gnoiClient := args.dut.RawAPIs().GNOI(t) killRequest := &gnps.KillProcessRequest{Name: pName, Pid: pID, Signal: gnps.KillProcessRequest_SIGNAL_TERM, Restart: true} killResponse, err := gnoiClient.System().KillProcess(context.Background(), killRequest) t.Logf("Got kill process response: %v\n\n", killResponse) diff --git a/feature/experimental/gribi/ate_tests/route_addition_during_failover_test/route_addition_during_failover_test.go b/feature/experimental/gribi/ate_tests/route_addition_during_failover_test/route_addition_during_failover_test.go index a8f0efda170..43d3557f15d 100644 --- a/feature/experimental/gribi/ate_tests/route_addition_during_failover_test/route_addition_during_failover_test.go +++ b/feature/experimental/gribi/ate_tests/route_addition_during_failover_test/route_addition_during_failover_test.go @@ -497,7 +497,7 @@ func TestRouteAdditionDuringFailover(t *testing.T) { ate := ondatra.ATE(t, "ate") ctx := context.Background() - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) dp1 := dut.Port(t, "port1") ap1 := ate.Port(t, "port1") top := ate.Topology().New() @@ -597,7 +597,7 @@ func TestRouteAdditionDuringFailover(t *testing.T) { awaitSwitchoverReady(t, dut, primaryBeforeSwitch) t.Logf("Controller %q is ready for switchover before test.", primaryBeforeSwitch) - gnoiClient := dut.RawAPIs().GNOI().Default(t) + gnoiClient := dut.RawAPIs().GNOI(t) useNameOnly := deviations.GNOISubcomponentPath(dut) switchoverRequest := &spb.SwitchControlProcessorRequest{ ControlProcessor: cmp.GetSubcomponentPath(secondaryBeforeSwitch, useNameOnly), diff --git a/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go b/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go index 7ef08309d2b..f4502988093 100644 --- a/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go +++ b/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go @@ -34,6 +34,7 @@ import ( "github.com/openconfig/gribigo/constants" "github.com/openconfig/gribigo/fluent" "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/binding" "github.com/openconfig/ondatra/gnmi" "github.com/openconfig/ondatra/gnmi/oc" "github.com/openconfig/ondatra/raw" @@ -455,7 +456,7 @@ func TestRouteRemovalDuringFailover(t *testing.T) { ate := ondatra.ATE(t, "ate") ctx := context.Background() - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) dp1 := dut.Port(t, "port1") ap1 := ate.Port(t, "port1") top := ate.Topology().New() @@ -557,7 +558,7 @@ func TestRouteRemovalDuringFailover(t *testing.T) { switchoverReady(t, dut, primaryBeforeSwitch) t.Logf("Controller %q is ready for switchover before test.", primaryBeforeSwitch) - gnoiClient := dut.RawAPIs().GNOI().Default(t) + var gnoiClient binding.GNOIClients = dut.RawAPIs().GNOI(t) useNameOnly := deviations.GNOISubcomponentPath(dut) switchoverRequest := &spb.SwitchControlProcessorRequest{ ControlProcessor: cmp.GetSubcomponentPath(secondaryBeforeSwitch, useNameOnly), diff --git a/feature/experimental/gribi/otg_tests/dut_daemon_failure/dut_daemon_failure_test.go b/feature/experimental/gribi/otg_tests/dut_daemon_failure/dut_daemon_failure_test.go index 38f69ab1563..487594133b7 100644 --- a/feature/experimental/gribi/otg_tests/dut_daemon_failure/dut_daemon_failure_test.go +++ b/feature/experimental/gribi/otg_tests/dut_daemon_failure/dut_daemon_failure_test.go @@ -250,7 +250,7 @@ func verifyGRIBIGet(ctx context.Context, t *testing.T, clientA *gribi.Client, du // gNOIKillProcess kills a daemon on the DUT, given its name and pid. func gNOIKillProcess(ctx context.Context, t *testing.T, args *testArgs, pName string, pID uint32) { - gnoiClient := args.dut.RawAPIs().GNOI().Default(t) + gnoiClient := args.dut.RawAPIs().GNOI(t) killRequest := &gnps.KillProcessRequest{Name: pName, Pid: pID, Signal: gnps.KillProcessRequest_SIGNAL_TERM, Restart: true} killResponse, err := gnoiClient.System().KillProcess(context.Background(), killRequest) t.Logf("Got kill process response: %v\n\n", killResponse) diff --git a/feature/experimental/gribi/otg_tests/route_addition_during_failover_test/route_addition_during_failover_test.go b/feature/experimental/gribi/otg_tests/route_addition_during_failover_test/route_addition_during_failover_test.go index 60093394e79..2bdd4ce46bc 100644 --- a/feature/experimental/gribi/otg_tests/route_addition_during_failover_test/route_addition_during_failover_test.go +++ b/feature/experimental/gribi/otg_tests/route_addition_during_failover_test/route_addition_during_failover_test.go @@ -524,7 +524,7 @@ func TestRouteAdditionDuringFailover(t *testing.T) { ate := ondatra.ATE(t, "ate") ctx := context.Background() - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) dp1 := dut.Port(t, "port1") ap1 := ate.Port(t, "port1") top := ate.OTG().NewConfig(t) @@ -628,7 +628,7 @@ func TestRouteAdditionDuringFailover(t *testing.T) { awaitSwitchoverReady(t, dut, primaryBeforeSwitch) t.Logf("Controller %q is ready for switchover before test.", primaryBeforeSwitch) - gnoiClient := dut.RawAPIs().GNOI().Default(t) + gnoiClient := dut.RawAPIs().GNOI(t) useNameOnly := deviations.GNOISubcomponentPath(dut) switchoverRequest := &spb.SwitchControlProcessorRequest{ ControlProcessor: cmp.GetSubcomponentPath(secondaryBeforeSwitch, useNameOnly), diff --git a/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go b/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go index f0d4371a399..7245992929f 100644 --- a/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go +++ b/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go @@ -37,6 +37,7 @@ import ( "github.com/openconfig/gribigo/constants" "github.com/openconfig/gribigo/fluent" "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/binding" "github.com/openconfig/ondatra/gnmi" "github.com/openconfig/ondatra/gnmi/oc" "github.com/openconfig/ondatra/raw" @@ -478,7 +479,7 @@ func TestRouteRemovalDuringFailover(t *testing.T) { ate := ondatra.ATE(t, "ate") ctx := context.Background() - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) dp1 := dut.Port(t, "port1") ap1 := ate.Port(t, "port1") top := ate.OTG().NewConfig(t) @@ -588,7 +589,7 @@ func TestRouteRemovalDuringFailover(t *testing.T) { switchoverReady(t, dut, primaryBeforeSwitch) t.Logf("Controller %q is ready for switchover before test.", primaryBeforeSwitch) - gnoiClient := dut.RawAPIs().GNOI().Default(t) + var gnoiClient binding.GNOIClients = dut.RawAPIs().GNOI(t) useNameOnly := deviations.GNOISubcomponentPath(dut) switchoverRequest := &spb.SwitchControlProcessorRequest{ ControlProcessor: cmp.GetSubcomponentPath(secondaryBeforeSwitch, useNameOnly), diff --git a/feature/experimental/isis/ate_tests/internal/session/session.go b/feature/experimental/isis/ate_tests/internal/session/session.go index b36c1d4e747..ef94d56e1cf 100644 --- a/feature/experimental/isis/ate_tests/internal/session/session.go +++ b/feature/experimental/isis/ate_tests/internal/session/session.go @@ -169,7 +169,7 @@ func New(t testing.TB) (*TestSession, error) { s := &TestSession{} s.DUT = ondatra.DUT(t, "dut") var err error - s.DUTClient, err = ygnmi.NewClient(s.DUT.RawAPIs().GNMI().Default(t), ygnmi.WithTarget(s.DUT.ID())) + s.DUTClient, err = ygnmi.NewClient(s.DUT.RawAPIs().GNMI(t), ygnmi.WithTarget(s.DUT.ID())) if err != nil { return nil, fmt.Errorf("unable to connect to gNMI on %v: %w", s.DUT, err) } diff --git a/feature/experimental/isis/otg_tests/internal/session/session.go b/feature/experimental/isis/otg_tests/internal/session/session.go index de05b0f5631..fa1accdf2ef 100644 --- a/feature/experimental/isis/otg_tests/internal/session/session.go +++ b/feature/experimental/isis/otg_tests/internal/session/session.go @@ -188,7 +188,7 @@ func New(t testing.TB) (*TestSession, error) { s := &TestSession{} s.DUT = ondatra.DUT(t, "dut") var err error - s.DUTClient, err = ygnmi.NewClient(s.DUT.RawAPIs().GNMI().Default(t), ygnmi.WithTarget(s.DUT.ID())) + s.DUTClient, err = ygnmi.NewClient(s.DUT.RawAPIs().GNMI(t), ygnmi.WithTarget(s.DUT.ID())) if err != nil { return nil, fmt.Errorf("unable to connect to gNMI on %v: %w", s.DUT, err) } diff --git a/feature/experimental/p4rt/README.md b/feature/experimental/p4rt/README.md index dd0dcbf2e26..f673b15bac5 100644 --- a/feature/experimental/p4rt/README.md +++ b/feature/experimental/p4rt/README.md @@ -14,7 +14,7 @@ This document specifies the requirements for p4rt test implementation. function, which sets up the `StreamTermErr` channel required to check errors when the p4rt stream terminates. -4. Tests should make use of Ondatra Raw API `dut.RawAPIs().P4RT().Default(t)` +4. Tests should make use of Ondatra Raw API `dut.RawAPIs().P4RT(t)` during client instantiation. 5. Tests should log Stream Termination errors populated in the diff --git a/feature/experimental/p4rt/ate_tests/base_p4rt/base_p4rt_test.go b/feature/experimental/p4rt/ate_tests/base_p4rt/base_p4rt_test.go index f8bb019b351..3fa0d375b61 100644 --- a/feature/experimental/p4rt/ate_tests/base_p4rt/base_p4rt_test.go +++ b/feature/experimental/p4rt/ate_tests/base_p4rt/base_p4rt_test.go @@ -311,12 +311,12 @@ func TestP4rtConnect(t *testing.T) { // Setup two different clients for different FAPs client1 := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := client1.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := client1.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } client2 := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := client2.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := client2.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go b/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go index f549e625466..30b8f2d5753 100644 --- a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go +++ b/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go @@ -411,12 +411,12 @@ func TestPacketIn(t *testing.T) { configureDeviceID(ctx, t, dut) leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go b/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go index e4812973740..6df9267e4e9 100644 --- a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go +++ b/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go @@ -367,12 +367,12 @@ func TestPacketOut(t *testing.T) { configureDeviceID(ctx, t, dut) leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/ate_tests/lldp_packetin_test/lldp_packetin_test.go b/feature/experimental/p4rt/ate_tests/lldp_packetin_test/lldp_packetin_test.go index 9508483e38f..ec9b8545922 100644 --- a/feature/experimental/p4rt/ate_tests/lldp_packetin_test/lldp_packetin_test.go +++ b/feature/experimental/p4rt/ate_tests/lldp_packetin_test/lldp_packetin_test.go @@ -389,12 +389,12 @@ func TestPacketIn(t *testing.T) { configureDeviceID(ctx, t, dut) leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/ate_tests/lldp_packetout_test/lldp_packetout_test.go b/feature/experimental/p4rt/ate_tests/lldp_packetout_test/lldp_packetout_test.go index 1ea543b77b3..e89353a0ab4 100644 --- a/feature/experimental/p4rt/ate_tests/lldp_packetout_test/lldp_packetout_test.go +++ b/feature/experimental/p4rt/ate_tests/lldp_packetout_test/lldp_packetout_test.go @@ -361,12 +361,12 @@ func TestPacketOut(t *testing.T) { gnmi.Replace(t, dut, gnmi.OC().Lldp().Enabled().Config(), false) leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go b/feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go index b6722e0f136..089654803df 100644 --- a/feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go +++ b/feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go @@ -287,7 +287,7 @@ func TestP4RTDaemonFailure(t *testing.T) { t.Fatal(err) } - c := dut.RawAPIs().GNOI().Default(t) + c := dut.RawAPIs().GNOI(t) req := &syspb.KillProcessRequest{ Name: p4rtD, Pid: uint32(pID), diff --git a/feature/experimental/p4rt/ate_tests/performance_test/performance_test.go b/feature/experimental/p4rt/ate_tests/performance_test/performance_test.go index f2be1d9ccb7..703d1863e7a 100644 --- a/feature/experimental/p4rt/ate_tests/performance_test/performance_test.go +++ b/feature/experimental/p4rt/ate_tests/performance_test/performance_test.go @@ -632,7 +632,7 @@ func TestP4rtPerformance(t *testing.T) { configureDeviceID(t, dut) leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/traceroute_packetin_test.go b/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/traceroute_packetin_test.go index 67b56c2eda9..4312320a864 100644 --- a/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/traceroute_packetin_test.go +++ b/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/traceroute_packetin_test.go @@ -269,12 +269,12 @@ func TestPacketIn(t *testing.T) { top.Push(t).StartProtocols(t) leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/traceroute_packetout_test.go b/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/traceroute_packetout_test.go index 37c97568032..798b792f1f5 100644 --- a/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/traceroute_packetout_test.go +++ b/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/traceroute_packetout_test.go @@ -243,7 +243,7 @@ func TestPacketOut(t *testing.T) { configureDeviceID(ctx, t, dut) leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/otg_tests/base_p4rt/base_p4rt_test.go b/feature/experimental/p4rt/otg_tests/base_p4rt/base_p4rt_test.go index 400af57bcf6..8d411987577 100644 --- a/feature/experimental/p4rt/otg_tests/base_p4rt/base_p4rt_test.go +++ b/feature/experimental/p4rt/otg_tests/base_p4rt/base_p4rt_test.go @@ -313,12 +313,12 @@ func TestP4rtConnect(t *testing.T) { // Setup two different clients for different FAPs client1 := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := client1.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := client1.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } client2 := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := client2.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := client2.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go b/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go index c860aa4644c..f6faf84a0c4 100644 --- a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go +++ b/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go @@ -478,12 +478,12 @@ func TestPacketIn(t *testing.T) { configureDeviceID(ctx, t, dut) leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go b/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go index 2bf70ba3eea..cf236a684d8 100644 --- a/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go +++ b/feature/experimental/p4rt/otg_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go @@ -378,12 +378,12 @@ func TestPacketOut(t *testing.T) { configureDeviceID(ctx, t, dut) leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/otg_tests/lldp_packetin_test/lldp_packetin_test.go b/feature/experimental/p4rt/otg_tests/lldp_packetin_test/lldp_packetin_test.go index fb2fd9acd37..d01f7cf1bba 100644 --- a/feature/experimental/p4rt/otg_tests/lldp_packetin_test/lldp_packetin_test.go +++ b/feature/experimental/p4rt/otg_tests/lldp_packetin_test/lldp_packetin_test.go @@ -394,12 +394,12 @@ func TestPacketIn(t *testing.T) { configureDeviceID(ctx, t, dut) leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/otg_tests/lldp_packetout_test/lldp_packetout_test.go b/feature/experimental/p4rt/otg_tests/lldp_packetout_test/lldp_packetout_test.go index 4d74fba8703..5c8e6ab6d4a 100644 --- a/feature/experimental/p4rt/otg_tests/lldp_packetout_test/lldp_packetout_test.go +++ b/feature/experimental/p4rt/otg_tests/lldp_packetout_test/lldp_packetout_test.go @@ -360,12 +360,12 @@ func TestPacketOut(t *testing.T) { gnmi.Replace(t, dut, gnmi.OC().Lldp().Enabled().Config(), false) leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/otg_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go b/feature/experimental/p4rt/otg_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go index f38ddbbd5e6..edbdbfdd46c 100644 --- a/feature/experimental/p4rt/otg_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go +++ b/feature/experimental/p4rt/otg_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go @@ -282,7 +282,7 @@ func TestP4RTDaemonFailure(t *testing.T) { t.Fatal(err) } - c := dut.RawAPIs().GNOI().Default(t) + c := dut.RawAPIs().GNOI(t) req := &syspb.KillProcessRequest{ Name: p4rtD, Pid: uint32(pID), diff --git a/feature/experimental/p4rt/otg_tests/performance_test/performance_test.go b/feature/experimental/p4rt/otg_tests/performance_test/performance_test.go index 1fa83a304d3..aa8ed8c19ce 100644 --- a/feature/experimental/p4rt/otg_tests/performance_test/performance_test.go +++ b/feature/experimental/p4rt/otg_tests/performance_test/performance_test.go @@ -638,7 +638,7 @@ func TestP4rtPerformance(t *testing.T) { configureDeviceID(t, dut) leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetin_test/traceroute_packetin_test.go b/feature/experimental/p4rt/otg_tests/traceroute_packetin_test/traceroute_packetin_test.go index c54ae2ccb68..c9838ed294a 100644 --- a/feature/experimental/p4rt/otg_tests/traceroute_packetin_test/traceroute_packetin_test.go +++ b/feature/experimental/p4rt/otg_tests/traceroute_packetin_test/traceroute_packetin_test.go @@ -262,12 +262,12 @@ func TestPacketIn(t *testing.T) { ate.OTG().StartProtocols(t) leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/otg_tests/traceroute_packetout_test/traceroute_packetout_test.go b/feature/experimental/p4rt/otg_tests/traceroute_packetout_test/traceroute_packetout_test.go index 8443069b6a8..6c3d1a8f7b6 100644 --- a/feature/experimental/p4rt/otg_tests/traceroute_packetout_test/traceroute_packetout_test.go +++ b/feature/experimental/p4rt/otg_tests/traceroute_packetout_test/traceroute_packetout_test.go @@ -249,7 +249,7 @@ func TestPacketOut(t *testing.T) { configureDeviceID(ctx, t, dut) leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/tests/metadata_validation_test/metadata_validation_test.go b/feature/experimental/p4rt/tests/metadata_validation_test/metadata_validation_test.go index f67a6aaefff..5c9c3e1ff92 100644 --- a/feature/experimental/p4rt/tests/metadata_validation_test/metadata_validation_test.go +++ b/feature/experimental/p4rt/tests/metadata_validation_test/metadata_validation_test.go @@ -39,7 +39,7 @@ func TestP4RTMetadata(t *testing.T) { configurePortID(t, dut) c := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := c.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := c.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } diff --git a/feature/experimental/p4rt/tests/p4rt_election/p4rt_election_test.go b/feature/experimental/p4rt/tests/p4rt_election/p4rt_election_test.go index 2de3b602d4c..5fb2c81ab05 100644 --- a/feature/experimental/p4rt/tests/p4rt_election/p4rt_election_test.go +++ b/feature/experimental/p4rt/tests/p4rt_election/p4rt_election_test.go @@ -101,7 +101,7 @@ func configurePortID(t *testing.T, dut *ondatra.DUTDevice) { // Create client connection func clientConnection(t *testing.T, dut *ondatra.DUTDevice) *p4rt_client.P4RTClient { clientHandle := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := clientHandle.P4rtClientSet(dut.RawAPIs().P4RT().Default(t)); err != nil { + if err := clientHandle.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { t.Fatalf("Could not initialize p4rt client: %v", err) } return clientHandle diff --git a/feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/tls_authentication_over_grpc_test.go b/feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/tls_authentication_over_grpc_test.go index 9f1484ed7b8..869abffbda2 100644 --- a/feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/tls_authentication_over_grpc_test.go +++ b/feature/experimental/security/aaa/kne_tests/tls_authentication_over_grpc_test/tls_authentication_over_grpc_test.go @@ -168,7 +168,7 @@ func createNativeUser(t testing.TB, dut *ondatra.DUTDevice, user string, pass st }, }, } - gnmiClient := dut.RawAPIs().GNMI().Default(t) + gnmiClient := dut.RawAPIs().GNMI(t) if _, err := gnmiClient.Set(context.Background(), SetRequest); err != nil { t.Fatalf("Unexpected error configuring User: %v", err) } diff --git a/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go b/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go index 46ec8f358cd..6dc01fc1f6d 100644 --- a/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go +++ b/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go @@ -136,7 +136,7 @@ func removeElement(list []string, element string) []string { func TestCheckForCoreFiles(t *testing.T) { dut := ondatra.DUT(t, "dut") timestamp := uint64(time.Now().UTC().Unix()) - gnoiClient := dut.RawAPIs().GNOI().Default(t) + gnoiClient := dut.RawAPIs().GNOI(t) coreFileCheck(t, dut, gnoiClient, timestamp, true) } diff --git a/feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/tun_acl_dscp_test.go b/feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/tun_acl_dscp_test.go index 8761e7e0a5a..cff964de4c2 100644 --- a/feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/tun_acl_dscp_test.go +++ b/feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/tun_acl_dscp_test.go @@ -138,7 +138,7 @@ func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { configureNetworkInstance(t) t.Logf("Configure the DUT with static route ...") configStaticRoute(t, dut, prefix, nexthop) - gnmiClient := dut.RawAPIs().GNMI().Default(t) + gnmiClient := dut.RawAPIs().GNMI(t) var config string t.Logf("Push the CLI config:\n%s", dut.Vendor()) switch dut.Vendor() { diff --git a/feature/gnoi/os/tests/osinstall/osinstall_test.go b/feature/gnoi/os/tests/osinstall/osinstall_test.go index 2c8b22ad73c..cd38346da74 100644 --- a/feature/gnoi/os/tests/osinstall/osinstall_test.go +++ b/feature/gnoi/os/tests/osinstall/osinstall_test.go @@ -84,8 +84,8 @@ func TestOSInstall(t *testing.T) { tc := testCase{ reader: reader, dut: dut, - osc: dut.RawAPIs().GNOI().Default(t).OS(), - sc: dut.RawAPIs().GNOI().Default(t).System(), + osc: dut.RawAPIs().GNOI(t).OS(), + sc: dut.RawAPIs().GNOI(t).System(), } noReboot := deviations.OSActivateNoReboot(dut) tc.fetchStandbySupervisorStatus(ctx, t) diff --git a/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go b/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go index 6147d42f08b..e9d57f8d4a6 100644 --- a/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go +++ b/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go @@ -125,7 +125,7 @@ func TestCapabilitiesResponse(t *testing.T) { func TestNonexistingID(t *testing.T) { dut1 := ondatra.DUT(t, "dut1") id := "non-extsing-ID" - gnoiClient1 := dut1.RawAPIs().GNOI().Default(t) + gnoiClient1 := dut1.RawAPIs().GNOI(t) getResp, err := gnoiClient1.LinkQualification().Get(context.Background(), &plqpb.GetRequest{Ids: []string{id}}) t.Logf("LinkQualification().Get(): %v, err: %v", getResp, err) @@ -156,8 +156,8 @@ func TestNonexistingID(t *testing.T) { func TestListDelete(t *testing.T) { dut1 := ondatra.DUT(t, "dut1") dut2 := ondatra.DUT(t, "dut2") - gnoiClient1 := dut1.RawAPIs().GNOI().Default(t) - gnoiClient2 := dut2.RawAPIs().GNOI().Default(t) + gnoiClient1 := dut1.RawAPIs().GNOI(t) + gnoiClient2 := dut2.RawAPIs().GNOI(t) clients := []raw.GNOI{gnoiClient1, gnoiClient2} for i, client := range clients { @@ -306,8 +306,8 @@ func TestLinkQualification(t *testing.T) { } t.Logf("ReflectorCreateRequest: %v", reflectorCreateRequest) - gnoiClient1 := dut1.RawAPIs().GNOI().Default(t) - gnoiClient2 := dut2.RawAPIs().GNOI().Default(t) + gnoiClient1 := dut1.RawAPIs().GNOI(t) + gnoiClient2 := dut2.RawAPIs().GNOI(t) generatorCreateResp, err := gnoiClient1.LinkQualification().Create(context.Background(), generatorCreateRequest) t.Logf("LinkQualification().Create() generatorCreateResp: %v, err: %v", generatorCreateResp, err) diff --git a/feature/gnoi/system/tests/chassis_reboot_status_and_cancel_test/chassis_reboot_status_and_cancel_test.go b/feature/gnoi/system/tests/chassis_reboot_status_and_cancel_test/chassis_reboot_status_and_cancel_test.go index a9673e27197..30d20401fc6 100644 --- a/feature/gnoi/system/tests/chassis_reboot_status_and_cancel_test/chassis_reboot_status_and_cancel_test.go +++ b/feature/gnoi/system/tests/chassis_reboot_status_and_cancel_test/chassis_reboot_status_and_cancel_test.go @@ -62,7 +62,7 @@ func TestMain(m *testing.M) { func TestRebootStatus(t *testing.T) { dut := ondatra.DUT(t, "dut") - gnoiClient := dut.RawAPIs().GNOI().Default(t) + gnoiClient := dut.RawAPIs().GNOI(t) cases := []struct { desc string @@ -136,7 +136,7 @@ func TestRebootStatus(t *testing.T) { func TestCancelReboot(t *testing.T) { dut := ondatra.DUT(t, "dut") - gnoiClient := dut.RawAPIs().GNOI().Default(t) + gnoiClient := dut.RawAPIs().GNOI(t) rebootRequest := &spb.RebootRequest{ Method: spb.RebootMethod_COLD, diff --git a/feature/gnoi/system/tests/per_component_reboot_test/per_component_reboot_test.go b/feature/gnoi/system/tests/per_component_reboot_test/per_component_reboot_test.go index f9c6c0fd65e..16994cb693b 100644 --- a/feature/gnoi/system/tests/per_component_reboot_test/per_component_reboot_test.go +++ b/feature/gnoi/system/tests/per_component_reboot_test/per_component_reboot_test.go @@ -98,7 +98,7 @@ func TestStandbyControllerCardReboot(t *testing.T) { rpStandby, rpActive := components.FindStandbyRP(t, dut, controllerCards) t.Logf("Detected rpStandby: %v, rpActive: %v", rpStandby, rpActive) - gnoiClient := dut.RawAPIs().GNOI().Default(t) + gnoiClient := dut.RawAPIs().GNOI(t) useNameOnly := deviations.GNOISubcomponentPath(dut) rebootSubComponentRequest := &spb.RebootRequest{ Method: spb.RebootMethod_COLD, @@ -173,7 +173,7 @@ func TestLinecardReboot(t *testing.T) { t.Fatalf("Component(lc).Removable().Get(t): got none, want non-empty") } - gnoiClient := dut.RawAPIs().GNOI().Default(t) + gnoiClient := dut.RawAPIs().GNOI(t) useNameOnly := deviations.GNOISubcomponentPath(dut) rebootSubComponentRequest := &spb.RebootRequest{ Method: spb.RebootMethod_COLD, @@ -249,7 +249,7 @@ func TestFabricReboot(t *testing.T) { t.Logf("OperStatusUP interfaces before reboot: %v", intfsOperStatusUPBeforeReboot) // Fetch a new gnoi client. - gnoiClient := dut.RawAPIs().GNOI().Default(t) + gnoiClient := dut.RawAPIs().GNOI(t) useNameOnly := deviations.GNOISubcomponentPath(dut) rebootSubComponentRequest := &spb.RebootRequest{ Method: spb.RebootMethod_COLD, diff --git a/feature/gnoi/system/tests/ping_test/ping_test.go b/feature/gnoi/system/tests/ping_test/ping_test.go index 56f6dd1cf18..8feddae2b22 100644 --- a/feature/gnoi/system/tests/ping_test/ping_test.go +++ b/feature/gnoi/system/tests/ping_test/ping_test.go @@ -402,7 +402,7 @@ func TestGNOIPing(t *testing.T) { expectedStats: commonExpectedReplyStats, }} - gnoiClient := dut.RawAPIs().GNOI().Default(t) + gnoiClient := dut.RawAPIs().GNOI(t) for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { t.Logf("Sent ping request: %v\n\n", tc.pingRequest) diff --git a/feature/gnoi/system/tests/traceroute_test/traceroute_test.go b/feature/gnoi/system/tests/traceroute_test/traceroute_test.go index 2e1bc9abf74..d2f33fec932 100644 --- a/feature/gnoi/system/tests/traceroute_test/traceroute_test.go +++ b/feature/gnoi/system/tests/traceroute_test/traceroute_test.go @@ -230,7 +230,7 @@ func TestGNOITraceroute(t *testing.T) { }}, } - gnoiClient := dut.RawAPIs().GNOI().Default(t) + gnoiClient := dut.RawAPIs().GNOI(t) for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { time.Sleep(1 * time.Second) // some devices do not allow back to back traceroute to prevent flooding diff --git a/feature/gribi/ate_tests/get_rpc_test/get_rpc_test.go b/feature/gribi/ate_tests/get_rpc_test/get_rpc_test.go index e2b0c0ef324..29b31294a3c 100644 --- a/feature/gribi/ate_tests/get_rpc_test/get_rpc_test.go +++ b/feature/gribi/ate_tests/get_rpc_test/get_rpc_test.go @@ -374,7 +374,7 @@ func TestElectionID(t *testing.T) { // Dial gRIBI ctx := context.Background() - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) // Configure the DUT configureDUT(t, dut) diff --git a/feature/gribi/ate_tests/gribi_scaling/gribi_scaling_test.go b/feature/gribi/ate_tests/gribi_scaling/gribi_scaling_test.go index 9e7d12a8e60..97a41604f33 100644 --- a/feature/gribi/ate_tests/gribi_scaling/gribi_scaling_test.go +++ b/feature/gribi/ate_tests/gribi_scaling/gribi_scaling_test.go @@ -469,7 +469,7 @@ func TestScaling(t *testing.T) { dut := ondatra.DUT(t, "dut") ate := ondatra.ATE(t, "ate") ctx := context.Background() - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) ap1 := ate.Port(t, "port1") ap2 := ate.Port(t, "port2") top := ate.Topology().New() diff --git a/feature/gribi/ate_tests/gribigo_compliance_test/gribigo_compliance_test.go b/feature/gribi/ate_tests/gribigo_compliance_test/gribigo_compliance_test.go index fc48da2d519..afe7c38ca26 100644 --- a/feature/gribi/ate_tests/gribigo_compliance_test/gribigo_compliance_test.go +++ b/feature/gribi/ate_tests/gribigo_compliance_test/gribigo_compliance_test.go @@ -127,7 +127,7 @@ func TestCompliance(t *testing.T) { ate := ondatra.ATE(t, "ate") configureATE(t, ate) - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) for _, tt := range compliance.TestSuite { t.Run(tt.In.ShortName, func(t *testing.T) { diff --git a/feature/gribi/ate_tests/hierarchical_weight_resolution_test/hierarchical_weight_resolution_test.go b/feature/gribi/ate_tests/hierarchical_weight_resolution_test/hierarchical_weight_resolution_test.go index 22a5d24b550..b74f8ebaad7 100644 --- a/feature/gribi/ate_tests/hierarchical_weight_resolution_test/hierarchical_weight_resolution_test.go +++ b/feature/gribi/ate_tests/hierarchical_weight_resolution_test/hierarchical_weight_resolution_test.go @@ -175,7 +175,7 @@ func filterPacketReceived(t *testing.T, flow string, ate *ondatra.ATEDevice) map // configureGRIBIClient configures a new GRIBI client with PRESERVE and FIB_ACK. func configureGRIBIClient(t *testing.T, dut *ondatra.DUTDevice) *fluent.GRIBIClient { t.Helper() - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) // Configure the gRIBI client. c := fluent.NewClient() diff --git a/feature/gribi/ate_tests/ipv4_entry_test/ipv4_entry_test.go b/feature/gribi/ate_tests/ipv4_entry_test/ipv4_entry_test.go index 97d0f8677c4..b6fa1e35a63 100644 --- a/feature/gribi/ate_tests/ipv4_entry_test/ipv4_entry_test.go +++ b/feature/gribi/ate_tests/ipv4_entry_test/ipv4_entry_test.go @@ -149,7 +149,7 @@ func TestIPv4Entry(t *testing.T) { dut := ondatra.DUT(t, "dut") configureDUT(t, dut) - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) ate := ondatra.ATE(t, "ate") ateTop := configureATE(t, ate) diff --git a/feature/gribi/ate_tests/ordering_ack_test/ordering_ack_test.go b/feature/gribi/ate_tests/ordering_ack_test/ordering_ack_test.go index d8e4c546a0b..a85e00a47e2 100644 --- a/feature/gribi/ate_tests/ordering_ack_test/ordering_ack_test.go +++ b/feature/gribi/ate_tests/ordering_ack_test/ordering_ack_test.go @@ -473,7 +473,7 @@ func TestOrderingACK(t *testing.T) { // Dial gRIBI ctx := context.Background() - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) // Configure the DUT configureDUT(t, dut) diff --git a/feature/gribi/ate_tests/route_removal_via_flush_test/route_removal_via_flush_test.go b/feature/gribi/ate_tests/route_removal_via_flush_test/route_removal_via_flush_test.go index 1bc3b90e588..7f6f2718243 100644 --- a/feature/gribi/ate_tests/route_removal_via_flush_test/route_removal_via_flush_test.go +++ b/feature/gribi/ate_tests/route_removal_via_flush_test/route_removal_via_flush_test.go @@ -99,7 +99,7 @@ func TestRouteRemovelViaFlush(t *testing.T) { ateTop := configureATE(t, ate) ateTop.Push(t).StartProtocols(t) - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) // Configure the gRIBI client clientA with election ID of 10. clientA := fluent.NewClient() diff --git a/feature/gribi/ate_tests/supervisor_failure_test/supervisor_failure_test.go b/feature/gribi/ate_tests/supervisor_failure_test/supervisor_failure_test.go index 3806f154503..f28ca6a7411 100644 --- a/feature/gribi/ate_tests/supervisor_failure_test/supervisor_failure_test.go +++ b/feature/gribi/ate_tests/supervisor_failure_test/supervisor_failure_test.go @@ -340,7 +340,7 @@ func TestSupFailure(t *testing.T) { t.Fatalf("Controller %q did not become switchover-ready before test.", primaryBeforeSwitch) } - gnoiClient := dut.RawAPIs().GNOI().Default(t) + gnoiClient := dut.RawAPIs().GNOI(t) useNameOnly := deviations.GNOISubcomponentPath(dut) switchoverRequest := &spb.SwitchControlProcessorRequest{ ControlProcessor: cmp.GetSubcomponentPath(secondaryBeforeSwitch, useNameOnly), diff --git a/feature/gribi/ate_tests/weighted_balancing_test/port_flap_rebalanced_test.go b/feature/gribi/ate_tests/weighted_balancing_test/port_flap_rebalanced_test.go index 6f3b429d8c2..3c5568e28f3 100644 --- a/feature/gribi/ate_tests/weighted_balancing_test/port_flap_rebalanced_test.go +++ b/feature/gribi/ate_tests/weighted_balancing_test/port_flap_rebalanced_test.go @@ -92,7 +92,7 @@ func TestPortFlap(t *testing.T) { // Dial gRIBI ctx := context.Background() dut := ondatra.DUT(t, "dut") - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) // Configure the DUT configureDUT(t, dut) diff --git a/feature/gribi/ate_tests/weighted_balancing_test/weighted_balancing_test.go b/feature/gribi/ate_tests/weighted_balancing_test/weighted_balancing_test.go index 2b3b58f2152..b4ca9214e1b 100644 --- a/feature/gribi/ate_tests/weighted_balancing_test/weighted_balancing_test.go +++ b/feature/gribi/ate_tests/weighted_balancing_test/weighted_balancing_test.go @@ -195,7 +195,7 @@ func TestWeightedBalancing(t *testing.T) { // Dial gRIBI ctx := context.Background() - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) // Configure the DUT configureDUT(t, dut) diff --git a/feature/gribi/otg_tests/get_rpc_test/get_rpc_test.go b/feature/gribi/otg_tests/get_rpc_test/get_rpc_test.go index b347a8e2b0d..98bab515c85 100644 --- a/feature/gribi/otg_tests/get_rpc_test/get_rpc_test.go +++ b/feature/gribi/otg_tests/get_rpc_test/get_rpc_test.go @@ -381,7 +381,7 @@ func TestElectionID(t *testing.T) { // Dial gRIBI ctx := context.Background() - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) // Configure the DUT configureDUT(t, dut) diff --git a/feature/gribi/otg_tests/gribi_scaling/gribi_scaling_test.go b/feature/gribi/otg_tests/gribi_scaling/gribi_scaling_test.go index 53fdecf786d..5958053ea22 100644 --- a/feature/gribi/otg_tests/gribi_scaling/gribi_scaling_test.go +++ b/feature/gribi/otg_tests/gribi_scaling/gribi_scaling_test.go @@ -492,7 +492,7 @@ func TestScaling(t *testing.T) { ate := ondatra.ATE(t, "ate") ctx := context.Background() - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) ap1 := ate.Port(t, "port1") ap2 := ate.Port(t, "port2") diff --git a/feature/gribi/otg_tests/gribigo_compliance_test/gribigo_compliance_test.go b/feature/gribi/otg_tests/gribigo_compliance_test/gribigo_compliance_test.go index db7f42daca0..125150a532b 100644 --- a/feature/gribi/otg_tests/gribigo_compliance_test/gribigo_compliance_test.go +++ b/feature/gribi/otg_tests/gribigo_compliance_test/gribigo_compliance_test.go @@ -132,7 +132,7 @@ func TestCompliance(t *testing.T) { ate := ondatra.ATE(t, "ate") configureATE(t, ate) - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) for _, tt := range compliance.TestSuite { t.Run(tt.In.ShortName, func(t *testing.T) { diff --git a/feature/gribi/otg_tests/ipv4_entry_test/ipv4_entry_test.go b/feature/gribi/otg_tests/ipv4_entry_test/ipv4_entry_test.go index e27d5f92ba7..eff48632db3 100644 --- a/feature/gribi/otg_tests/ipv4_entry_test/ipv4_entry_test.go +++ b/feature/gribi/otg_tests/ipv4_entry_test/ipv4_entry_test.go @@ -158,7 +158,7 @@ func TestIPv4Entry(t *testing.T) { dut := ondatra.DUT(t, "dut") configureDUT(t, dut) - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) cases := []struct { desc string diff --git a/feature/gribi/otg_tests/ordering_ack_test/ordering_ack_test.go b/feature/gribi/otg_tests/ordering_ack_test/ordering_ack_test.go index 9c18fb02a3e..bed3dacaec4 100644 --- a/feature/gribi/otg_tests/ordering_ack_test/ordering_ack_test.go +++ b/feature/gribi/otg_tests/ordering_ack_test/ordering_ack_test.go @@ -500,7 +500,7 @@ func TestOrderingACK(t *testing.T) { // Dial gRIBI ctx := context.Background() - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) // Configure the ATE ate := ondatra.ATE(t, "ate") diff --git a/feature/gribi/otg_tests/route_removal_via_flush_test/route_removal_via_flush_test.go b/feature/gribi/otg_tests/route_removal_via_flush_test/route_removal_via_flush_test.go index 6aa0a13cc9b..81e0a8b1b3b 100644 --- a/feature/gribi/otg_tests/route_removal_via_flush_test/route_removal_via_flush_test.go +++ b/feature/gribi/otg_tests/route_removal_via_flush_test/route_removal_via_flush_test.go @@ -103,7 +103,7 @@ func TestRouteRemovelViaFlush(t *testing.T) { ate.OTG().PushConfig(t, ateTop) ate.OTG().StartProtocols(t) - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) // Configure the gRIBI client clientA with election ID of 10. clientA := fluent.NewClient() diff --git a/feature/gribi/otg_tests/supervisor_failure_test/supervisor_failure_test.go b/feature/gribi/otg_tests/supervisor_failure_test/supervisor_failure_test.go index 0d10645d1cc..46c4fa7f22c 100644 --- a/feature/gribi/otg_tests/supervisor_failure_test/supervisor_failure_test.go +++ b/feature/gribi/otg_tests/supervisor_failure_test/supervisor_failure_test.go @@ -327,7 +327,7 @@ func TestSupFailure(t *testing.T) { t.Fatalf("Controller %q did not become switchover-ready before test.", primaryBeforeSwitch) } - gnoiClient := dut.RawAPIs().GNOI().Default(t) + gnoiClient := dut.RawAPIs().GNOI(t) useNameOnly := deviations.GNOISubcomponentPath(dut) switchoverRequest := &spb.SwitchControlProcessorRequest{ ControlProcessor: cmp.GetSubcomponentPath(secondaryBeforeSwitch, useNameOnly), diff --git a/feature/gribi/otg_tests/weighted_balancing_test/port_flap_rebalanced_test.go b/feature/gribi/otg_tests/weighted_balancing_test/port_flap_rebalanced_test.go index 0b5e1035b5e..f228fcd0da3 100644 --- a/feature/gribi/otg_tests/weighted_balancing_test/port_flap_rebalanced_test.go +++ b/feature/gribi/otg_tests/weighted_balancing_test/port_flap_rebalanced_test.go @@ -96,7 +96,7 @@ func TestPortFlap(t *testing.T) { // Dial gRIBI ctx := context.Background() dut := ondatra.DUT(t, "dut") - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) // Configure the ATE ate := ondatra.ATE(t, "ate") diff --git a/feature/gribi/otg_tests/weighted_balancing_test/weighted_balancing_test.go b/feature/gribi/otg_tests/weighted_balancing_test/weighted_balancing_test.go index 29fa7f9f4de..a9e90ac07f2 100644 --- a/feature/gribi/otg_tests/weighted_balancing_test/weighted_balancing_test.go +++ b/feature/gribi/otg_tests/weighted_balancing_test/weighted_balancing_test.go @@ -197,7 +197,7 @@ func TestWeightedBalancing(t *testing.T) { // Dial gRIBI ctx := context.Background() - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) // Configure the ATE ate := ondatra.ATE(t, "ate") diff --git a/feature/lldp/ate_tests/core_lldp_tlv_population_test/core_lldp_tlv_population_test.go b/feature/lldp/ate_tests/core_lldp_tlv_population_test/core_lldp_tlv_population_test.go index dbc0d67ad6e..d5408bbd803 100644 --- a/feature/lldp/ate_tests/core_lldp_tlv_population_test/core_lldp_tlv_population_test.go +++ b/feature/lldp/ate_tests/core_lldp_tlv_population_test/core_lldp_tlv_population_test.go @@ -213,7 +213,7 @@ func disableP4RTLLDP(t *testing.T, dut *ondatra.DUTDevice) { case ondatra.ARISTA: cli := `p4-runtime shutdown` - if _, err := dut.RawAPIs().GNMI().Default(t). + if _, err := dut.RawAPIs().GNMI(t). Set(context.Background(), cliSetRequest(cli)); err != nil { t.Fatalf("Failed to disable P4RTLLDP: %v", err) } diff --git a/feature/lldp/otg_tests/core_lldp_tlv_population_test/core_lldp_tlv_population_test.go b/feature/lldp/otg_tests/core_lldp_tlv_population_test/core_lldp_tlv_population_test.go index f4535eb9ab6..d239b5ea67c 100644 --- a/feature/lldp/otg_tests/core_lldp_tlv_population_test/core_lldp_tlv_population_test.go +++ b/feature/lldp/otg_tests/core_lldp_tlv_population_test/core_lldp_tlv_population_test.go @@ -307,7 +307,7 @@ func disableP4RTLLDP(t *testing.T, dut *ondatra.DUTDevice) { case ondatra.ARISTA: cli := `p4-runtime shutdown` - if _, err := dut.RawAPIs().GNMI().Default(t). + if _, err := dut.RawAPIs().GNMI(t). Set(context.Background(), cliSetRequest(cli)); err != nil { t.Fatalf("Failed to disable P4RTLLDP: %v", err) } diff --git a/feature/system/gnmi/cliorigin/ate_tests/cli_origin_test/cli_origin_test.go b/feature/system/gnmi/cliorigin/ate_tests/cli_origin_test/cli_origin_test.go index c704d075a25..d9e25ce4755 100644 --- a/feature/system/gnmi/cliorigin/ate_tests/cli_origin_test/cli_origin_test.go +++ b/feature/system/gnmi/cliorigin/ate_tests/cli_origin_test/cli_origin_test.go @@ -89,7 +89,7 @@ func TestOriginCliConfig(t *testing.T) { }, } - gnmiClient := dut.RawAPIs().GNMI().Default(t) + gnmiClient := dut.RawAPIs().GNMI(t) for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { var config string diff --git a/feature/system/gnmi/metadata/tests/annotation_test/annotation_test.go b/feature/system/gnmi/metadata/tests/annotation_test/annotation_test.go index 9458a89b60c..d50dec0cea1 100644 --- a/feature/system/gnmi/metadata/tests/annotation_test/annotation_test.go +++ b/feature/system/gnmi/metadata/tests/annotation_test/annotation_test.go @@ -96,7 +96,7 @@ func TestGNMIMetadataAnnotation(t *testing.T) { for _, tc := range cases { t.Log(tc.desc) - gnmiClient := dut.RawAPIs().GNMI().Default(t) + gnmiClient := dut.RawAPIs().GNMI(t) //Not assuming that hostname is already configured hostnameConfigPath := gnmi.OC().System().Hostname() gnmi.Replace(t, dut, hostnameConfigPath.Config(), string("ondatraHost")) diff --git a/internal/components/components.go b/internal/components/components.go index 9044949f014..3e666357082 100644 --- a/internal/components/components.go +++ b/internal/components/components.go @@ -114,7 +114,7 @@ type Y struct { // New creates a new ygnmi based helper from a *ondatra.DUTDevice. func New(t testing.TB, dut *ondatra.DUTDevice) Y { - gnmic := dut.RawAPIs().GNMI().Default(t) + gnmic := dut.RawAPIs().GNMI(t) yc, err := ygnmi.NewClient(gnmic) if err != nil { t.Fatalf("Could not create ygnmi.Client: %v", err) diff --git a/internal/fptest/networkinstance.go b/internal/fptest/networkinstance.go index 2f74d3c95cb..4adac88d50f 100644 --- a/internal/fptest/networkinstance.go +++ b/internal/fptest/networkinstance.go @@ -84,7 +84,7 @@ func EnableGRIBIUnderNetworkInstance(t testing.TB, d *ondatra.DUTDevice, ni stri }, }}, } - gnmiClient := d.RawAPIs().GNMI().Default(t) + gnmiClient := d.RawAPIs().GNMI(t) if _, err := gnmiClient.Set(context.Background(), gpbSetRequest); err != nil { t.Fatalf("Enabling Gribi on network-instance %s failed with unexpected error: %v", ni, err) } diff --git a/internal/gribi/gribi.go b/internal/gribi/gribi.go index 1637ce0bc5c..699ef907617 100644 --- a/internal/gribi/gribi.go +++ b/internal/gribi/gribi.go @@ -115,7 +115,7 @@ type NHOptions struct { func (c *Client) Start(t testing.TB) error { t.Helper() t.Logf("Starting GRIBI connection for dut: %s", c.DUT.Name()) - gribiC := c.DUT.RawAPIs().GRIBI().Default(t) + gribiC := c.DUT.RawAPIs().GRIBI(t) c.fluentC = fluent.NewClient() c.electionID = Uint128{Low: 1, High: 0} From a58db3e57d0e1cef5589b42a7a39bcf198e0f879 Mon Sep 17 00:00:00 2001 From: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> Date: Tue, 12 Sep 2023 12:03:45 -0400 Subject: [PATCH 21/43] Add a few documentation pointers back to Ondatra. (#2112) --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 809398653d6..12b6f99663f 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,10 @@ protocols such as BGP, IS-IS. Feature profiles also includes a suite of [Ondatra](https://github.com/openconfig/ondatra) tests for validating the -network device behavior for each defined feature. +network device behavior for each defined feature. If you are new to Ondatra, +please start by reading the Ondata +[README](https://github.com/openconfig/ondatra#readme) and taking the [Ondatra +tour](https://docs.google.com/viewer?url=https://raw.githubusercontent.com/openconfig/ondatra/main/internal/tour/tour.pdf). # Contributing From 28ad80cf6d4541b9094117d581dda09f65faa77f Mon Sep 17 00:00:00 2001 From: jasdeep-hundal Date: Tue, 12 Sep 2023 09:08:26 -0700 Subject: [PATCH 22/43] Delete P4RT/QoS ATE tests (#2114) * Delete deprecated ATE version of the P4RT tests * Delete deprecated ATE version of the QoS tests --- .../p4rt/ate_tests/base_p4rt/README.md | 42 - .../ate_tests/base_p4rt/base_p4rt_test.go | 446 ---- .../ate_tests/base_p4rt/metadata.textproto | 26 - .../README.md | 27 - ...google_discovery_protocol_packetin_test.go | 483 ----- .../metadata.textproto | 34 - .../README.md | 30 - ...oogle_discovery_protocol_packetout_test.go | 460 ---- .../metadata.textproto | 34 - .../ate_tests/lldp_packetin_test/README.md | 28 - .../lldp_packetin_test/lldp_packetin_test.go | 461 ---- .../lldp_packetin_test/metadata.textproto | 26 - .../ate_tests/lldp_packetout_test/README.md | 29 - .../lldp_packetout_test.go | 460 ---- .../lldp_packetout_test/metadata.textproto | 26 - .../p4rt_daemon_failure_test/README.md | 41 - .../metadata.textproto | 34 - .../p4rt_daemon_failure_test.go | 311 --- .../p4rt/ate_tests/performance_test/README.md | 35 - .../performance_test/metadata.textproto | 27 - .../performance_test/performance_test.go | 933 -------- .../traceroute_packetin_test/README.md | 34 - .../metadata.textproto | 26 - .../traceroute_packetin_test/packetin_test.go | 238 --- .../traceroute_packetin_test.go | 374 ---- .../traceroute_packetout_test/README.md | 45 - .../metadata.textproto | 36 - .../packetout_test.go | 129 -- .../traceroute_packetout_test.go | 377 ---- .../ate_tests/bursty_traffic_test/README.md | 131 -- .../bursty_traffic_test.go | 1203 ----------- .../bursty_traffic_test/metadata.textproto | 42 - .../mixed_sp_wrr_traffic_test/README.md | 152 -- .../metadata.textproto | 44 - .../mixed_sp_wrr_traffic_test.go | 1385 ------------ .../one_sp_queue_traffic_test/README.md | 138 -- .../metadata.textproto | 40 - .../one_sp_queue_traffic_test.go | 1452 ------------- .../qos/ate_tests/qos_basic_test/README.md | 140 -- .../qos_basic_test/metadata.textproto | 45 - .../qos_basic_test/qos_basic_test.go | 1663 --------------- .../qos_output_queue_counters_test/README.md | 28 - .../metadata.textproto | 43 - .../qos_output_queue_counters_test.go | 986 --------- .../two_sp_queue_traffic_test/README.md | 162 -- .../metadata.textproto | 41 - .../two_sp_queue_traffic_test.go | 1872 ----------------- .../qos/ate_tests/wrr_traffic_test/README.md | 147 -- .../wrr_traffic_test/metadata.textproto | 41 - .../wrr_traffic_test/wrr_traffic_test.go | 1642 --------------- 50 files changed, 16649 deletions(-) delete mode 100644 feature/experimental/p4rt/ate_tests/base_p4rt/README.md delete mode 100644 feature/experimental/p4rt/ate_tests/base_p4rt/base_p4rt_test.go delete mode 100644 feature/experimental/p4rt/ate_tests/base_p4rt/metadata.textproto delete mode 100644 feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/README.md delete mode 100644 feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go delete mode 100644 feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/metadata.textproto delete mode 100644 feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/README.md delete mode 100644 feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go delete mode 100644 feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/metadata.textproto delete mode 100644 feature/experimental/p4rt/ate_tests/lldp_packetin_test/README.md delete mode 100644 feature/experimental/p4rt/ate_tests/lldp_packetin_test/lldp_packetin_test.go delete mode 100644 feature/experimental/p4rt/ate_tests/lldp_packetin_test/metadata.textproto delete mode 100644 feature/experimental/p4rt/ate_tests/lldp_packetout_test/README.md delete mode 100644 feature/experimental/p4rt/ate_tests/lldp_packetout_test/lldp_packetout_test.go delete mode 100644 feature/experimental/p4rt/ate_tests/lldp_packetout_test/metadata.textproto delete mode 100644 feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/README.md delete mode 100644 feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/metadata.textproto delete mode 100644 feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go delete mode 100644 feature/experimental/p4rt/ate_tests/performance_test/README.md delete mode 100644 feature/experimental/p4rt/ate_tests/performance_test/metadata.textproto delete mode 100644 feature/experimental/p4rt/ate_tests/performance_test/performance_test.go delete mode 100644 feature/experimental/p4rt/ate_tests/traceroute_packetin_test/README.md delete mode 100644 feature/experimental/p4rt/ate_tests/traceroute_packetin_test/metadata.textproto delete mode 100644 feature/experimental/p4rt/ate_tests/traceroute_packetin_test/packetin_test.go delete mode 100644 feature/experimental/p4rt/ate_tests/traceroute_packetin_test/traceroute_packetin_test.go delete mode 100644 feature/experimental/p4rt/ate_tests/traceroute_packetout_test/README.md delete mode 100644 feature/experimental/p4rt/ate_tests/traceroute_packetout_test/metadata.textproto delete mode 100644 feature/experimental/p4rt/ate_tests/traceroute_packetout_test/packetout_test.go delete mode 100644 feature/experimental/p4rt/ate_tests/traceroute_packetout_test/traceroute_packetout_test.go delete mode 100644 feature/qos/ate_tests/bursty_traffic_test/README.md delete mode 100644 feature/qos/ate_tests/bursty_traffic_test/bursty_traffic_test.go delete mode 100644 feature/qos/ate_tests/bursty_traffic_test/metadata.textproto delete mode 100644 feature/qos/ate_tests/mixed_sp_wrr_traffic_test/README.md delete mode 100644 feature/qos/ate_tests/mixed_sp_wrr_traffic_test/metadata.textproto delete mode 100644 feature/qos/ate_tests/mixed_sp_wrr_traffic_test/mixed_sp_wrr_traffic_test.go delete mode 100644 feature/qos/ate_tests/one_sp_queue_traffic_test/README.md delete mode 100644 feature/qos/ate_tests/one_sp_queue_traffic_test/metadata.textproto delete mode 100644 feature/qos/ate_tests/one_sp_queue_traffic_test/one_sp_queue_traffic_test.go delete mode 100644 feature/qos/ate_tests/qos_basic_test/README.md delete mode 100644 feature/qos/ate_tests/qos_basic_test/metadata.textproto delete mode 100644 feature/qos/ate_tests/qos_basic_test/qos_basic_test.go delete mode 100644 feature/qos/ate_tests/qos_output_queue_counters_test/README.md delete mode 100644 feature/qos/ate_tests/qos_output_queue_counters_test/metadata.textproto delete mode 100644 feature/qos/ate_tests/qos_output_queue_counters_test/qos_output_queue_counters_test.go delete mode 100644 feature/qos/ate_tests/two_sp_queue_traffic_test/README.md delete mode 100644 feature/qos/ate_tests/two_sp_queue_traffic_test/metadata.textproto delete mode 100644 feature/qos/ate_tests/two_sp_queue_traffic_test/two_sp_queue_traffic_test.go delete mode 100644 feature/qos/ate_tests/wrr_traffic_test/README.md delete mode 100644 feature/qos/ate_tests/wrr_traffic_test/metadata.textproto delete mode 100644 feature/qos/ate_tests/wrr_traffic_test/wrr_traffic_test.go diff --git a/feature/experimental/p4rt/ate_tests/base_p4rt/README.md b/feature/experimental/p4rt/ate_tests/base_p4rt/README.md deleted file mode 100644 index e4ca8068fb1..00000000000 --- a/feature/experimental/p4rt/ate_tests/base_p4rt/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# P4RT-1.1: Base P4RT Functionality - - -## Summary - -Validate that the P4RT server can accept basic configuration and Read/Write RPCs. - - -## Procedure - -* Connect ATE port-1 to DUT port-1, and ATE port-2 to DUT port-2. - -* Configure P4RT id and node-id with two different interfaces on different FAPs. - -* Send the WBB P4Info via the SetForwardingConfigPipeline. - -* Send RPC Write to install the WBBIngressaclTable for GDP, LLDP and traceroute with meters attached. - -* Verify if the RPC write is success. - -* Send RPC Read to read back the installed table entries. - -* Validate the read Response for each of table entries GDP, LLDP and traceroute. - -* Repeat the same steps for another FAP and verify the Table entries. - - -## Config Parameter Coverage - -* /components/component/integrated-circuit/config/node-id -* /interfaces/interface/config/id - - -## Telemetry Parameter coverage - -No new telemetry covered. - - -## Protocol/RPC Parameter coverage - -No new Protocol/RPC covered. - diff --git a/feature/experimental/p4rt/ate_tests/base_p4rt/base_p4rt_test.go b/feature/experimental/p4rt/ate_tests/base_p4rt/base_p4rt_test.go deleted file mode 100644 index 3fa0d375b61..00000000000 --- a/feature/experimental/p4rt/ate_tests/base_p4rt/base_p4rt_test.go +++ /dev/null @@ -1,446 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package base_p4rt_test - -import ( - "context" - "errors" - "fmt" - "testing" - - "flag" - - "github.com/cisco-open/go-p4/p4rt_client" - "github.com/cisco-open/go-p4/utils" - "github.com/google/go-cmp/cmp" - "github.com/openconfig/featureprofiles/feature/experimental/p4rt/internal/p4rtutils" - "github.com/openconfig/featureprofiles/internal/attrs" - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygot/ygot" - p4_v1 "github.com/p4lang/p4runtime/go/p4/v1" - "google.golang.org/protobuf/testing/protocmp" -) - -type testArgs struct { - ctx context.Context - client1 *p4rt_client.P4RTClient - client2 *p4rt_client.P4RTClient - dut *ondatra.DUTDevice - ate *ondatra.ATEDevice - top *ondatra.ATETopology -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -const ( - ipv4PrefixLen = 30 -) - -var ( - // Path to the p4Info file for sending it with SetFwdPipelineConfig - p4InfoFile = flag.String("p4info_file_location", "../../wbb.p4info.pb.txt", "Path to the p4info file.") - streamName1 = "p4rt1" - streamName2 = "p4rt2" - - electionId = uint64(100) - //Enter the P4RT openconfig node-id and P4RT port-id to be configured in DUT and for client connection - deviceId1 = uint64(100) - deviceId2 = uint64(200) - - portId = uint32(20) - - dutPort1 = attrs.Attributes{ - Desc: "dutPort1", - IPv4: "192.0.2.1", - IPv4Len: ipv4PrefixLen, - } - - atePort1 = attrs.Attributes{ - Name: "atePort1", - IPv4: "192.0.2.2", - IPv4Len: ipv4PrefixLen, - } - - dutPort2 = attrs.Attributes{ - Desc: "dutPort2", - IPv4: "192.0.2.5", - IPv4Len: ipv4PrefixLen, - } - - atePort2 = attrs.Attributes{ - Name: "atePort2", - IPv4: "192.0.2.6", - IPv4Len: ipv4PrefixLen, - } -) - -// configInterfaceDUT configures the interface with the Addrs. -func configInterfaceDUT(i *oc.Interface, a *attrs.Attributes, dut *ondatra.DUTDevice) *oc.Interface { - i.Description = ygot.String(a.Desc) - i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd - if deviations.InterfaceEnabled(dut) { - i.Enabled = ygot.Bool(true) - } - - s := i.GetOrCreateSubinterface(0) - s4 := s.GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) { - s4.Enabled = ygot.Bool(true) - } - s4a := s4.GetOrCreateAddress(a.IPv4) - s4a.PrefixLength = ygot.Uint8(ipv4PrefixLen) - - return i -} - -// configureDeviceIDs configures p4rt device-id on the DUT. -func configureDeviceIDs(t *testing.T, dut *ondatra.DUTDevice, nodes map[string]string) { - deviceIDs := []uint64{deviceId1, deviceId2} - i := 0 - for node := range nodes { - t.Logf("Configuring P4RT Node: %s", node) - c := oc.Component{} - c.Name = ygot.String(node) - c.IntegratedCircuit = &oc.Component_IntegratedCircuit{} - c.IntegratedCircuit.NodeId = ygot.Uint64(deviceIDs[i]) - gnmi.Replace(t, dut, gnmi.OC().Component(node).Config(), &c) - i++ - } -} - -// configureDUT configures two ports on the DUT. -func configureDUT(t *testing.T, dut *ondatra.DUTDevice, ports []string) { - d := gnmi.OC() - - p1 := dut.Port(t, ports[0]) - i1 := &oc.Interface{Name: ygot.String(p1.Name()), Id: ygot.Uint32(portId)} - gnmi.Replace(t, dut, d.Interface(p1.Name()).Config(), configInterfaceDUT(i1, &dutPort1, dut)) - - p2 := dut.Port(t, ports[1]) - i2 := &oc.Interface{Name: ygot.String(p2.Name()), Id: ygot.Uint32(portId + 1)} - gnmi.Replace(t, dut, d.Interface(p2.Name()).Config(), configInterfaceDUT(i2, &dutPort2, dut)) - - if deviations.ExplicitPortSpeed(dut) { - fptest.SetPortSpeed(t, p1) - fptest.SetPortSpeed(t, p2) - } - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - fptest.AssignToNetworkInstance(t, dut, p1.Name(), deviations.DefaultNetworkInstance(dut), 0) - fptest.AssignToNetworkInstance(t, dut, p2.Name(), deviations.DefaultNetworkInstance(dut), 0) - } -} - -// findP4RTNodes returns a map[string]string where keys are unique P4RT Device IDs -// and values represent ONDATRA DUT port IDs from the devices -func findP4RTNodes(t *testing.T, dut *ondatra.DUTDevice) map[string]string { - nodes := make(map[string]string) - p4NodeMap := p4rtutils.P4RTNodesByPort(t, dut) - for k, v := range p4NodeMap { - // skip empty device IDs - if v == "" { - continue - } - nodes[v] = k - // quit when found two unique devices with available ports - if len(nodes) == 2 { - t.Logf("Found P4RT devices and corresponding ports: %+v", nodes) - return nodes - } - } - t.Fatalf("The test requires two DUT ports located on different P4RT Nodes (found %v), cannot proceed.", len(nodes)) - return nodes -} - -// ATE configuration with IP address -func configureATE(t *testing.T, ate *ondatra.ATEDevice, ports []string) *ondatra.ATETopology { - top := ate.Topology().New() - - p1 := ate.Port(t, ports[0]) - i1 := top.AddInterface(atePort1.Name).WithPort(p1) - i1.IPv4(). - WithAddress(atePort1.IPv4CIDR()). - WithDefaultGateway(dutPort1.IPv4) - - p2 := ate.Port(t, ports[1]) - i2 := top.AddInterface(atePort2.Name).WithPort(p2) - i2.IPv4(). - WithAddress(atePort2.IPv4CIDR()). - WithDefaultGateway(dutPort2.IPv4) - - return top -} - -// setupP4RTClient sends client arbitration message for both clients. -// then sends setforwordingpipelineconfig for both clients, compare the P4Info -func setupP4RTClient(ctx context.Context, args *testArgs) error { - // Setup p4rt-client stream parameters for both clients - streamParameter1 := p4rt_client.P4RTStreamParameters{ - Name: streamName1, - DeviceId: deviceId1, - ElectionIdH: uint64(0), - ElectionIdL: electionId, - } - streamParameter2 := p4rt_client.P4RTStreamParameters{ - Name: streamName2, - DeviceId: deviceId2, - ElectionIdH: uint64(0), - ElectionIdL: electionId, - } - streamlist := []p4rt_client.P4RTStreamParameters{streamParameter1, streamParameter2} - - // Send ClientArbitration message on both clients. - clients := []*p4rt_client.P4RTClient{args.client1, args.client2} - for index, client := range clients { - if client != nil { - client.StreamChannelCreate(&streamlist[index]) - if err := client.StreamChannelSendMsg(&streamlist[index].Name, &p4_v1.StreamMessageRequest{ - Update: &p4_v1.StreamMessageRequest_Arbitration{ - Arbitration: &p4_v1.MasterArbitrationUpdate{ - DeviceId: streamlist[index].DeviceId, - ElectionId: &p4_v1.Uint128{ - High: streamlist[index].ElectionIdH, - Low: streamlist[index].ElectionIdL, - }, - }, - }, - }); err != nil { - return fmt.Errorf("errors seen when sending ClientArbitration message: %v", err) - } - if _, _, arbErr := client.StreamChannelGetArbitrationResp(&streamlist[index].Name, 1); arbErr != nil { - if err := p4rtutils.StreamTermErr(client.StreamTermErr); err != nil { - return err - } - return fmt.Errorf("errors seen in ClientArbitration response: %v", arbErr) - } - } - } - - // Load p4info file. - p4Info, err := utils.P4InfoLoad(p4InfoFile) - if err != nil { - return errors.New("Errors seen when loading p4info file.") - } - - // Send SetForwardingPipelineConfig for p4rt leader client. - fmt.Println("Sending SetForwardingPipelineConfig for both clients") - deviceid_list := []uint64{deviceId1, deviceId2} - for index, client := range clients { - if err := client.SetForwardingPipelineConfig(&p4_v1.SetForwardingPipelineConfigRequest{ - DeviceId: deviceid_list[index], - ElectionId: &p4_v1.Uint128{High: uint64(0), Low: electionId}, - Action: p4_v1.SetForwardingPipelineConfigRequest_VERIFY_AND_COMMIT, - Config: &p4_v1.ForwardingPipelineConfig{ - P4Info: p4Info, - Cookie: &p4_v1.ForwardingPipelineConfig_Cookie{ - Cookie: 159, - }, - }, - }); err != nil { - return errors.New("Errors seen when sending SetForwardingPipelineConfig.") - } - } - - // Receive GetForwardingPipelineConfig - for index, client := range clients { - resp, err := client.GetForwardingPipelineConfig(&p4_v1.GetForwardingPipelineConfigRequest{ - DeviceId: deviceid_list[index], - ResponseType: p4_v1.GetForwardingPipelineConfigRequest_P4INFO_AND_COOKIE, - }) - if err != nil { - return errors.New("Errors seen when sending SetForwardingPipelineConfig.") - } - // Compare P4Info from GetForwardingPipelineConfig and SetForwardingPipelineConfig - if diff := cmp.Diff(p4Info, resp.Config.P4Info, protocmp.Transform()); diff != "" { - return fmt.Errorf("P4info diff (-want +got): \n%s", diff) - } - } - return nil -} - -// Function to compare and check if the expected table is present in RPC ReadResponse. -func verifyReadReceiveMatch(t *testing.T, expected_table *p4_v1.Update, received_entry *p4_v1.ReadResponse) error { - matches := 0 - for _, table := range received_entry.Entities { - if cmp.Equal(table, expected_table.Entity, protocmp.Transform(), protocmp.IgnoreFields(&p4_v1.TableEntry{}, "meter_config", "counter_data")) { - t.Logf("Table match succesful") - matches += 1 - } - } - if matches == 0 { - return errors.New("no matches found") - } - return nil -} - -// TestP4rtConnect connects to the P4Runtime server over grpc -// It then calls setupP4RTClient which sets the arbitration request and sends SetForwardingPipelineConfig with P4Info -func TestP4rtConnect(t *testing.T) { - - dut := ondatra.DUT(t, "dut") - ctx := context.Background() - ate := ondatra.ATE(t, "ate") - - // configure DUT with P4RT node-id and ids on different FAPs - nodes := findP4RTNodes(t, dut) - configureDeviceIDs(t, dut, nodes) - - var ports []string - for _, v := range nodes { - ports = append(ports, v) - } - configureDUT(t, dut, ports) - top := configureATE(t, ate, ports) - - // Setup two different clients for different FAPs - client1 := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := client1.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { - t.Fatalf("Could not initialize p4rt client: %v", err) - } - - client2 := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := client2.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { - t.Fatalf("Could not initialize p4rt client: %v", err) - } - - args := &testArgs{ - ctx: ctx, - client1: client1, - client2: client2, - dut: dut, - ate: ate, - top: top, - } - - if err := setupP4RTClient(ctx, args); err != nil { - t.Fatalf("Could not setup p4rt client: %v", err) - } - - // RPC Write to write the table entries to the P4RT Server - deviceid_list := []uint64{deviceId1, deviceId2} - clients := []*p4rt_client.P4RTClient{args.client1, args.client2} - for index, client := range clients { - err := client.Write(&p4_v1.WriteRequest{ - DeviceId: deviceid_list[index], - ElectionId: &p4_v1.Uint128{High: uint64(0), Low: electionId}, - Updates: p4rtutils.ACLWbbIngressTableEntryGet([]*p4rtutils.ACLWbbIngressTableEntryInfo{ - { - Type: p4_v1.Update_INSERT, - EtherType: 0x6007, - EtherTypeMask: 0xFFFF, - Priority: 1, - }, - { - Type: p4_v1.Update_INSERT, - EtherType: 0x88cc, - EtherTypeMask: 0xFFFF, - Priority: 1, - }, - { - Type: p4_v1.Update_INSERT, - IsIpv4: 0x1, - TTL: 0x1, - TTLMask: 0xFF, - Priority: 1, - }, - }), - Atomicity: p4_v1.WriteRequest_CONTINUE_ON_ERROR, - }) - if err != nil { - countOK, countNotOK, errDetails := p4rt_client.P4RTWriteErrParse(err) - t.Errorf("Write Partial Errors %d/%d: %s", countOK, countNotOK, errDetails) - } else { - t.Logf("RPC Write Success for client %d", index) - } - } - - nomatch := 0 // To count no matches for Table entries - // Receive read response - for index, client := range clients { - rStream, rErr := client.Read(&p4_v1.ReadRequest{ - DeviceId: deviceid_list[index], - Entities: []*p4_v1.Entity{ - { - Entity: &p4_v1.Entity_TableEntry{}, - }, - }, - }) - if rErr != nil { - t.Fatalf("Received error") - } - - readResp, respErr := rStream.Recv() - if respErr != nil { - t.Fatalf("Read Response Err: %s", respErr) - } else { - t.Logf("Read Response success") - } - t.Logf("Verify Read response for client%d", index) - - // Construct expected table for GDP to match with received table entry - expected_update := p4rtutils.ACLWbbIngressTableEntryGet([]*p4rtutils.ACLWbbIngressTableEntryInfo{ - { - Type: p4_v1.Update_INSERT, - EtherType: 0x6007, - EtherTypeMask: 0xFFFF, - Priority: 1, - }, - }) - expected_entity := expected_update[0] - if err := verifyReadReceiveMatch(t, expected_entity, readResp); err != nil { - t.Errorf("Table entry for GDP %s", err) - nomatch += 1 - } - - // Construct expected table for LLDP to match with received table entry - expected_update = p4rtutils.ACLWbbIngressTableEntryGet([]*p4rtutils.ACLWbbIngressTableEntryInfo{ - { - Type: p4_v1.Update_INSERT, - EtherType: 0x88cc, - EtherTypeMask: 0xFFFF, - Priority: 1, - }, - }) - expected_entity = expected_update[0] - if err := verifyReadReceiveMatch(t, expected_entity, readResp); err != nil { - t.Errorf("Table entry for LLDP %s", err) - nomatch += 1 - } - - // Construct expected table for traceroute to match with received table entry - expected_update = p4rtutils.ACLWbbIngressTableEntryGet([]*p4rtutils.ACLWbbIngressTableEntryInfo{ - { - Type: p4_v1.Update_INSERT, - IsIpv4: 0x1, - TTL: 0x1, - TTLMask: 0xFF, - Priority: 1, - }, - }) - expected_entity = expected_update[0] - if err := verifyReadReceiveMatch(t, expected_entity, readResp); err != nil { - t.Errorf("Table entry for traceroute %s", err) - nomatch += 1 - } - } - if nomatch > 0 { - t.Fatalf("Table entry matches failed") - } -} diff --git a/feature/experimental/p4rt/ate_tests/base_p4rt/metadata.textproto b/feature/experimental/p4rt/ate_tests/base_p4rt/metadata.textproto deleted file mode 100644 index 45078cb02a6..00000000000 --- a/feature/experimental/p4rt/ate_tests/base_p4rt/metadata.textproto +++ /dev/null @@ -1,26 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "ac980b1f-2139-48c1-8146-37a25d3eb980" -plan_id: "P4RT-1.1" -description: "Base P4RT Functionality" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_port_speed: true - explicit_interface_in_default_vrf: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - interface_enabled: true - default_network_instance: "default" - } -} diff --git a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/README.md b/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/README.md deleted file mode 100644 index a5bffb0cdd9..00000000000 --- a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# P4RT-3.1: Google Discovery Protocol: PacketIn - -## Summary - -Verify that GDP packets are punted with correct metadata. - -## Procedure - -* Connect ATE port-1 to DUT port-1, and ATE port-2 to DUT port-2. -* Enable the P4RT server on the device. -* Connect two P4RT clients in a master/secondary configuration. -* Configure the forwarding pipeline and install the P4RT table entry required for GDP. -* Send a GDP packet from the ATE and verify that it is received on the master and not the secondary client. -* Verify that the packet has the ingress_singleton_port metadata set and it corresponds to the interface ID of the port that the packet was received on. - - -## Config Parameter coverage - -No new configuration covered. - -## Telemetry Parameter coverage - -No new telemetry covered. - -## Minimum DUT platform requirement - -vRX if the vendor implementation supports FIB-ACK simulation, otherwise FFF. \ No newline at end of file diff --git a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go b/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go deleted file mode 100644 index 30b8f2d5753..00000000000 --- a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/google_discovery_protocol_packetin_test.go +++ /dev/null @@ -1,483 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package google_discovery_protocol_packetin_test - -import ( - "context" - "errors" - "fmt" - "strings" - "testing" - "time" - - "flag" - - "github.com/cisco-open/go-p4/p4rt_client" - "github.com/cisco-open/go-p4/utils" - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "github.com/openconfig/featureprofiles/feature/experimental/p4rt/internal/p4rtutils" - "github.com/openconfig/featureprofiles/internal/attrs" - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygot/ygot" - p4_v1 "github.com/p4lang/p4runtime/go/p4/v1" -) - -const ( - ipv4PrefixLen = 30 -) - -var ( - p4InfoFile = flag.String("p4info_file_location", "../../wbb.p4info.pb.txt", "Path to the p4info file.") - gdpSrcMAC = flag.String("gdp_src_MAC", "00:01:00:02:00:03", "source MAC address for PacketIn") - streamName = "p4rt" - gdpMAC = "00:0a:da:f0:f0:f0" - gdpEtherType = uint32(0x6007) - deviceID = uint64(1) - portID = uint32(10) - electionID = uint64(100) - metadataIngressPort = uint32(1) - metadataEgressPort = uint32(2) -) - -var ( - dutPort1 = attrs.Attributes{ - Desc: "dutPort1", - IPv4: "192.0.2.1", - IPv4Len: ipv4PrefixLen, - } - - atePort1 = attrs.Attributes{ - Name: "atePort1", - IPv4: "192.0.2.2", - IPv4Len: ipv4PrefixLen, - } - - dutPort2 = attrs.Attributes{ - Desc: "dutPort2", - IPv4: "192.0.2.5", - IPv4Len: ipv4PrefixLen, - } - - atePort2 = attrs.Attributes{ - Name: "atePort2", - IPv4: "192.0.2.6", - IPv4Len: ipv4PrefixLen, - } -) - -type PacketIO interface { - GetTableEntry(delete bool) []*p4rtutils.ACLWbbIngressTableEntryInfo - GetPacketTemplate() *PacketIOPacket - GetTrafficFlow(ate *ondatra.ATEDevice, frameSize uint32, frameRate uint64) []*ondatra.Flow - GetEgressPort() []string - GetIngressPort() string -} - -type PacketIOPacket struct { - SrcMAC, DstMAC *string - EthernetType *uint32 -} - -type testArgs struct { - ctx context.Context - leader *p4rt_client.P4RTClient - follower *p4rt_client.P4RTClient - dut *ondatra.DUTDevice - ate *ondatra.ATEDevice - top *ondatra.ATETopology - packetIO PacketIO -} - -// programmTableEntry programs or deletes p4rt table entry based on delete flag. -func programmTableEntry(ctx context.Context, t *testing.T, client *p4rt_client.P4RTClient, packetIO PacketIO, delete bool) error { - t.Helper() - err := client.Write(&p4_v1.WriteRequest{ - DeviceId: deviceID, - ElectionId: &p4_v1.Uint128{High: uint64(0), Low: electionID}, - Updates: p4rtutils.ACLWbbIngressTableEntryGet( - packetIO.GetTableEntry(delete), - ), - Atomicity: p4_v1.WriteRequest_CONTINUE_ON_ERROR, - }) - if err != nil { - return err - } - return nil -} - -// decodePacket decodes L2 header in the packet and returns source and destination MAC and ethernet type. -func decodePacket(t *testing.T, packetData []byte) (string, string, layers.EthernetType) { - t.Helper() - packet := gopacket.NewPacket(packetData, layers.LayerTypeEthernet, gopacket.Default) - etherHeader := packet.Layer(layers.LayerTypeEthernet) - if etherHeader != nil { - header, decoded := etherHeader.(*layers.Ethernet) - if decoded { - return header.SrcMAC.String(), header.DstMAC.String(), header.EthernetType - } - } - return "", "", layers.EthernetType(0) -} - -// testTraffic sends traffic flow for duration seconds and returns the -// number of packets sent out. -func testTraffic(t *testing.T, ate *ondatra.ATEDevice, flows []*ondatra.Flow, srcEndPoint *ondatra.Interface, duration int) int { - t.Helper() - for _, flow := range flows { - flow.WithSrcEndpoints(srcEndPoint).WithDstEndpoints(srcEndPoint) - } - ate.Traffic().Start(t, flows...) - time.Sleep(time.Duration(duration) * time.Second) - ate.Traffic().Stop(t) - - outPkts := gnmi.GetAll(t, ate, gnmi.OC().FlowAny().Counters().OutPkts().State()) - total := 0 - for _, count := range outPkts { - total += int(count) - } - return total -} - -// testPacketIn programs p4rt table entry and sends traffic related to GDP, -// then validates packetin message metadata and payload. -func testPacketIn(ctx context.Context, t *testing.T, args *testArgs) { - leader := args.leader - follower := args.follower - - // Insert wbb acl entry on the DUT - if err := programmTableEntry(ctx, t, leader, args.packetIO, false); err != nil { - t.Fatalf("There is error when programming entry") - } - // Delete wbb acl entry on the device - defer programmTableEntry(ctx, t, leader, args.packetIO, true) - - // Send GDP traffic from ATE - srcEndPoint := args.top.Interfaces()[atePort1.Name] - pktOut := testTraffic(t, args.ate, args.packetIO.GetTrafficFlow(args.ate, 300, 2), srcEndPoint, 20) - - packetInTests := []struct { - desc string - client *p4rt_client.P4RTClient - wantPkts int - }{{ - desc: "PacketIn to Primary Controller", - client: leader, - wantPkts: pktOut, - }, { - desc: "PacketIn to Secondary Controller", - client: follower, - wantPkts: 0, - }} - - for _, test := range packetInTests { - t.Run(test.desc, func(t *testing.T) { - // Extract packets from PacketIn message sent to p4rt client - _, packets, err := test.client.StreamChannelGetPackets(&streamName, uint64(test.wantPkts), 30*time.Second) - if err != nil { - t.Errorf("Unexpected error on StreamChannelGetPackets: %v", err) - } - - if test.wantPkts == 0 { - return - } - t.Logf("Start to decode packet and compare with expected packets.") - wantPacket := args.packetIO.GetPacketTemplate() - gotPkts := 0 - for _, packet := range packets { - if packet != nil { - if wantPacket.DstMAC != nil && wantPacket.EthernetType != nil { - srcMAC, dstMac, etherType := decodePacket(t, packet.Pkt.GetPayload()) - if dstMac != *wantPacket.DstMAC || etherType != layers.EthernetType(*wantPacket.EthernetType) { - continue - } - if !strings.EqualFold(srcMAC, *gdpSrcMAC) { - continue - } - } - - metaData := packet.Pkt.GetMetadata() - for _, data := range metaData { - switch data.GetMetadataId() { - case metadataIngressPort: - if string(data.GetValue()) != args.packetIO.GetIngressPort() { - t.Fatalf("Ingress Port Id is not matching expectation.") - } - case metadataEgressPort: - found := false - for _, portData := range args.packetIO.GetEgressPort() { - if string(data.GetValue()) == portData { - found = true - } - } - if !found { - t.Fatalf("Egress Port Id is not matching expectation.") - } - } - } - gotPkts++ - } - } - - if got, want := gotPkts, test.wantPkts; got != want { - t.Errorf("Number of PacketIn, got: %d, want: %d", got, want) - } - }) - } -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// configInterfaceDUT configures the interface with the Addrs. -func configInterfaceDUT(i *oc.Interface, a *attrs.Attributes, dut *ondatra.DUTDevice) *oc.Interface { - i.Description = ygot.String(a.Desc) - i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd - if deviations.InterfaceEnabled(dut) { - i.Enabled = ygot.Bool(true) - } - - s := i.GetOrCreateSubinterface(0) - s4 := s.GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) && !deviations.IPv4MissingEnabled(dut) { - s4.Enabled = ygot.Bool(true) - } - s4a := s4.GetOrCreateAddress(a.IPv4) - s4a.PrefixLength = ygot.Uint8(ipv4PrefixLen) - - return i -} - -// configureDUT configures port1 and port2 on the DUT. -func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { - d := gnmi.OC() - - p1 := dut.Port(t, "port1") - i1 := &oc.Interface{Name: ygot.String(p1.Name()), Id: ygot.Uint32(portID)} - gnmi.Replace(t, dut, d.Interface(p1.Name()).Config(), configInterfaceDUT(i1, &dutPort1, dut)) - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - fptest.AssignToNetworkInstance(t, dut, p1.Name(), deviations.DefaultNetworkInstance(dut), 0) - } - - p2 := dut.Port(t, "port2") - i2 := &oc.Interface{Name: ygot.String(p2.Name()), Id: ygot.Uint32(portID + 1)} - gnmi.Replace(t, dut, d.Interface(p2.Name()).Config(), configInterfaceDUT(i2, &dutPort2, dut)) - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - fptest.AssignToNetworkInstance(t, dut, p2.Name(), deviations.DefaultNetworkInstance(dut), 0) - } - if deviations.ExplicitPortSpeed(dut) { - fptest.SetPortSpeed(t, p1) - fptest.SetPortSpeed(t, p2) - } - gnmi.Replace(t, dut, gnmi.OC().Lldp().Enabled().Config(), false) -} - -// configureATE configures port1 and port2 on the ATE. -func configureATE(t *testing.T, ate *ondatra.ATEDevice) *ondatra.ATETopology { - top := ate.Topology().New() - - p1 := ate.Port(t, "port1") - i1 := top.AddInterface(atePort1.Name).WithPort(p1) - i1.IPv4(). - WithAddress(atePort1.IPv4CIDR()). - WithDefaultGateway(dutPort1.IPv4) - - p2 := ate.Port(t, "port2") - i2 := top.AddInterface(atePort2.Name).WithPort(p2) - i2.IPv4(). - WithAddress(atePort2.IPv4CIDR()). - WithDefaultGateway(dutPort2.IPv4) - - return top -} - -// configureDeviceIDs configures p4rt device-id on the DUT. -func configureDeviceID(ctx context.Context, t *testing.T, dut *ondatra.DUTDevice) { - nodes := p4rtutils.P4RTNodesByPort(t, dut) - p4rtNode, ok := nodes["port1"] - if !ok { - t.Fatal("Couldn't find P4RT Node for port: port1") - } - t.Logf("Configuring P4RT Node: %s", p4rtNode) - c := oc.Component{} - c.Name = ygot.String(p4rtNode) - c.IntegratedCircuit = &oc.Component_IntegratedCircuit{} - c.IntegratedCircuit.NodeId = ygot.Uint64(deviceID) - gnmi.Replace(t, dut, gnmi.OC().Component(p4rtNode).Config(), &c) -} - -// setupP4RTClient sends client arbitration message for both leader and follower clients, -// then sends setforwordingpipelineconfig with leader client. -func setupP4RTClient(ctx context.Context, args *testArgs) error { - // Setup p4rt-client stream parameters - streamParameter := p4rt_client.P4RTStreamParameters{ - Name: streamName, - DeviceId: deviceID, - ElectionIdH: uint64(0), - ElectionIdL: electionID, - } - - // Send ClientArbitration message on both p4rt leader and follower clients. - clients := []*p4rt_client.P4RTClient{args.leader, args.follower} - for index, client := range clients { - if client != nil { - client.StreamChannelCreate(&streamParameter) - if err := client.StreamChannelSendMsg(&streamName, &p4_v1.StreamMessageRequest{ - Update: &p4_v1.StreamMessageRequest_Arbitration{ - Arbitration: &p4_v1.MasterArbitrationUpdate{ - DeviceId: streamParameter.DeviceId, - ElectionId: &p4_v1.Uint128{ - High: streamParameter.ElectionIdH, - Low: streamParameter.ElectionIdL - uint64(index), - }, - }, - }, - }); err != nil { - return fmt.Errorf("errors seen when sending ClientArbitration message: %v", err) - } - if _, _, arbErr := client.StreamChannelGetArbitrationResp(&streamName, 1); arbErr != nil { - if err := p4rtutils.StreamTermErr(client.StreamTermErr); err != nil { - return err - } - return fmt.Errorf("errors seen in ClientArbitration response: %v", arbErr) - } - } - } - - // Load p4info file. - p4Info, err := utils.P4InfoLoad(p4InfoFile) - if err != nil { - return errors.New("Errors seen when loading p4info file.") - } - - // Send SetForwardingPipelineConfig for p4rt leader client. - if err := args.leader.SetForwardingPipelineConfig(&p4_v1.SetForwardingPipelineConfigRequest{ - DeviceId: deviceID, - ElectionId: &p4_v1.Uint128{High: uint64(0), Low: electionID}, - Action: p4_v1.SetForwardingPipelineConfigRequest_VERIFY_AND_COMMIT, - Config: &p4_v1.ForwardingPipelineConfig{ - P4Info: p4Info, - Cookie: &p4_v1.ForwardingPipelineConfig_Cookie{ - Cookie: 159, - }, - }, - }); err != nil { - return errors.New("Errors seen when sending SetForwardingPipelineConfig.") - } - return nil -} - -// getGDPParameter returns GDP related parameters for testPacketIn testcase. -func getGDPParameter(t *testing.T) PacketIO { - return &GDPPacketIO{ - PacketIOPacket: PacketIOPacket{ - SrcMAC: gdpSrcMAC, - DstMAC: &gdpMAC, - EthernetType: &gdpEtherType, - }, - IngressPort: fmt.Sprint(portID), - } -} - -func TestPacketIn(t *testing.T) { - dut := ondatra.DUT(t, "dut") - ctx := context.Background() - - configureDUT(t, dut) - - // Configure the ATE - ate := ondatra.ATE(t, "ate") - top := configureATE(t, ate) - top.Push(t).StartProtocols(t) - - // Configure P4RT device-id - configureDeviceID(ctx, t, dut) - - leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { - t.Fatalf("Could not initialize p4rt client: %v", err) - } - - follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { - t.Fatalf("Could not initialize p4rt client: %v", err) - } - - args := &testArgs{ - ctx: ctx, - leader: leader, - follower: follower, - dut: dut, - ate: ate, - top: top, - } - - if err := setupP4RTClient(ctx, args); err != nil { - t.Fatalf("Could not setup p4rt client: %v", err) - } - - args.packetIO = getGDPParameter(t) - testPacketIn(ctx, t, args) -} - -type GDPPacketIO struct { - PacketIOPacket - IngressPort string -} - -// GetTableEntry creates wbb acl entry related to GDP. -func (gdp *GDPPacketIO) GetTableEntry(delete bool) []*p4rtutils.ACLWbbIngressTableEntryInfo { - actionType := p4_v1.Update_INSERT - if delete { - actionType = p4_v1.Update_DELETE - } - return []*p4rtutils.ACLWbbIngressTableEntryInfo{{ - Type: actionType, - EtherType: 0x6007, - EtherTypeMask: 0xFFFF, - Priority: 1, - }} -} - -// GetPacketTemplate returns expected packets in PacketIn. -func (gdp *GDPPacketIO) GetPacketTemplate() *PacketIOPacket { - return &gdp.PacketIOPacket -} - -// GetTrafficFlow generates ATE traffic flows for GDP. -func (gdp *GDPPacketIO) GetTrafficFlow(ate *ondatra.ATEDevice, frameSize uint32, frameRate uint64) []*ondatra.Flow { - ethHeader := ondatra.NewEthernetHeader() - ethHeader.WithSrcAddress(*gdp.SrcMAC) - ethHeader.WithDstAddress(*gdp.DstMAC) - ethHeader.WithEtherType(*gdp.EthernetType) - - flow := ate.Traffic().NewFlow("GDP").WithFrameSize(frameSize).WithFrameRateFPS(frameRate).WithHeaders(ethHeader) - return []*ondatra.Flow{flow} -} - -// GetEgressPort returns expected egress port info in PacketIn. -func (gdp *GDPPacketIO) GetEgressPort() []string { - return []string{"0"} -} - -// GetIngressPort return expected ingress port info in PacketIn. -func (gdp *GDPPacketIO) GetIngressPort() string { - return gdp.IngressPort -} diff --git a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/metadata.textproto b/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/metadata.textproto deleted file mode 100644 index 14e92e70411..00000000000 --- a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetin_test/metadata.textproto +++ /dev/null @@ -1,34 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "d944e6e8-268c-4e37-87a2-df779d19dbde" -plan_id: "P4RT-3.1" -description: "Google Discovery Protocol: PacketIn" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - ipv4_missing_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_port_speed: true - explicit_interface_in_default_vrf: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - interface_enabled: true - default_network_instance: "default" - } -} diff --git a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/README.md b/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/README.md deleted file mode 100644 index 8d6fd5b5870..00000000000 --- a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# P4RT-3.2: Google Discovery Protocol: PacketOut - -## Summary - -Verify that GDP packets can be sent by the controller. - -## Procedure - -* Connect ATE port-1 to DUT port-1, and ATE port-2 to DUT port-2. -* Enable the P4RT server on the device. -* Connect two P4RT clients in a master/secondary configuration. -* Configure the forwarding pipeline and install the P4RT table entry required for GDP. -* Send a GDP packet from the master with egress_singleton_port set to one of the connected interfaces. -* Verify that the GDP packet is received on the ATE port connected to the indicated interface. -* Repeat sending the packet in the same way but from the secondary connection. -* Verify that the packet is not received on the ATE. - - - -## Config Parameter coverage - -No new configuration covered. - -## Telemetry Parameter coverage - -No new telemetry covered. - -## Minimum DUT platform requirement - -vRX if the vendor implementation supports FIB-ACK simulation, otherwise FFF. \ No newline at end of file diff --git a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go b/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go deleted file mode 100644 index 6df9267e4e9..00000000000 --- a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/google_discovery_protocol_packetout_test.go +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package google_discovery_protocol_packetout_test - -import ( - "context" - "errors" - "fmt" - "net" - "sort" - "testing" - "time" - - "flag" - - "github.com/cisco-open/go-p4/p4rt_client" - "github.com/cisco-open/go-p4/utils" - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "github.com/openconfig/featureprofiles/feature/experimental/p4rt/internal/p4rtutils" - "github.com/openconfig/featureprofiles/internal/attrs" - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygot/ygot" - p4_v1 "github.com/p4lang/p4runtime/go/p4/v1" -) - -const ( - ipv4PrefixLen = 30 - packetCount = 100 -) - -var ( - p4InfoFile = flag.String("p4info_file_location", "../../wbb.p4info.pb.txt", "Path to the p4info file.") - streamName = "p4rt" - gdpInLayers layers.EthernetType = 0x6007 - deviceID = *ygot.Uint64(1) - portID = *ygot.Uint32(10) - electionID = *ygot.Uint64(100) - METADATA_INGRESS_PORT = *ygot.Uint32(1) - METADATA_EGRESS_PORT = *ygot.Uint32(2) - SUBMIT_TO_INGRESS = *ygot.Uint32(1) - SUBMIT_TO_EGRESS = *ygot.Uint32(0) -) - -var ( - dutPort1 = attrs.Attributes{ - Desc: "dutPort1", - IPv4: "192.0.2.1", - IPv4Len: ipv4PrefixLen, - } - - atePort1 = attrs.Attributes{ - Name: "atePort1", - IPv4: "192.0.2.2", - IPv4Len: ipv4PrefixLen, - } - - dutPort2 = attrs.Attributes{ - Desc: "dutPort2", - IPv4: "192.0.2.5", - IPv4Len: ipv4PrefixLen, - } - - atePort2 = attrs.Attributes{ - Name: "atePort2", - IPv4: "192.0.2.6", - IPv4Len: ipv4PrefixLen, - } -) - -type PacketIO interface { - GetTableEntry(delete bool) []*p4rtutils.ACLWbbIngressTableEntryInfo - GetPacketOut(portID uint32, submitIngress bool) []*p4_v1.PacketOut -} - -type testArgs struct { - ctx context.Context - leader *p4rt_client.P4RTClient - follower *p4rt_client.P4RTClient - dut *ondatra.DUTDevice - ate *ondatra.ATEDevice - top *ondatra.ATETopology - packetIO PacketIO -} - -// programmTableEntry programs or deletes p4rt table entry based on delete flag. -func programmTableEntry(ctx context.Context, t *testing.T, client *p4rt_client.P4RTClient, packetIO PacketIO, delete bool) error { - t.Helper() - err := client.Write(&p4_v1.WriteRequest{ - DeviceId: deviceID, - ElectionId: &p4_v1.Uint128{High: uint64(0), Low: electionID}, - Updates: p4rtutils.ACLWbbIngressTableEntryGet( - packetIO.GetTableEntry(delete), - ), - Atomicity: p4_v1.WriteRequest_CONTINUE_ON_ERROR, - }) - if err != nil { - return err - } - return nil -} - -// sendPackets sends out packets via PacketOut message in StreamChannel. -func sendPackets(t *testing.T, client *p4rt_client.P4RTClient, packets []*p4_v1.PacketOut, packetCount int) { - count := packetCount / len(packets) - for _, packet := range packets { - for i := 0; i < count; i++ { - if err := client.StreamChannelSendMsg( - &streamName, &p4_v1.StreamMessageRequest{ - Update: &p4_v1.StreamMessageRequest_Packet{ - Packet: packet, - }, - }); err != nil { - t.Errorf("There is error seen in Packet Out. %v, %s", err, err) - } - } - } -} - -// testPacketOut sends out PacketOut with GDP payload on p4rt leader or -// follower client, then verify DUT interface statistics -func testPacketOut(ctx context.Context, t *testing.T, args *testArgs) { - leader := args.leader - follower := args.follower - - // Insert wbb acl entry on the DUT - if err := programmTableEntry(ctx, t, leader, args.packetIO, false); err != nil { - t.Fatalf("There is error when programming entry") - } - // Delete wbb acl entry on the device - defer programmTableEntry(ctx, t, leader, args.packetIO, true) - - packetOutTests := []struct { - desc string - client *p4rt_client.P4RTClient - expectPass bool - }{{ - desc: "PacketOut from Primary Controller", - client: leader, - expectPass: true, - }, { - desc: "PacketOut from Secondary Controller", - client: follower, - expectPass: false, - }} - - for _, test := range packetOutTests { - t.Run(test.desc, func(t *testing.T) { - // Check initial packet counters - port := sortPorts(args.ate.Ports())[0].Name() - counter0 := gnmi.Get(t, args.ate, gnmi.OC().Interface(port).Counters().InPkts().State()) - - packets := args.packetIO.GetPacketOut(portID, false) - sendPackets(t, test.client, packets, packetCount) - - // Wait for ate stats to be populated - time.Sleep(60 * time.Second) - - // Check packet counters after packet out - counter1 := gnmi.Get(t, args.ate, gnmi.OC().Interface(port).Counters().InPkts().State()) - - // Verify InPkts stats to check P4RT stream - t.Logf("Received %v packets on ATE port %s", counter1-counter0, port) - - if test.expectPass { - if counter1-counter0 < uint64(float64(packetCount)*0.95) { - t.Fatalf("Not all the packets are received.") - } - } else { - if counter1-counter0 > uint64(float64(packetCount)*0.10) { - t.Fatalf("Unexpected packets are received.") - } - } - }) - } -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// sortPorts sorts the ports by the testbed port ID. -func sortPorts(ports []*ondatra.Port) []*ondatra.Port { - sort.Slice(ports, func(i, j int) bool { - idi, idj := ports[i].ID(), ports[j].ID() - li, lj := len(idi), len(idj) - if li == lj { - return idi < idj - } - return li < lj // "port2" < "port10" - }) - return ports -} - -// configInterfaceDUT configures the interface with the Addrs. -func configInterfaceDUT(i *oc.Interface, a *attrs.Attributes, dut *ondatra.DUTDevice) *oc.Interface { - i.Description = ygot.String(a.Desc) - i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd - if deviations.InterfaceEnabled(dut) { - i.Enabled = ygot.Bool(true) - } - - s := i.GetOrCreateSubinterface(0) - s4 := s.GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) && !deviations.IPv4MissingEnabled(dut) { - s4.Enabled = ygot.Bool(true) - } - s4a := s4.GetOrCreateAddress(a.IPv4) - s4a.PrefixLength = ygot.Uint8(ipv4PrefixLen) - - return i -} - -// configureDUT configures port1 and port2 on the DUT. -func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { - d := gnmi.OC() - - p1 := dut.Port(t, "port1") - i1 := &oc.Interface{Name: ygot.String(p1.Name()), Id: ygot.Uint32(portID)} - gnmi.Replace(t, dut, d.Interface(p1.Name()).Config(), configInterfaceDUT(i1, &dutPort1, dut)) - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - fptest.AssignToNetworkInstance(t, dut, p1.Name(), deviations.DefaultNetworkInstance(dut), 0) - } - - p2 := dut.Port(t, "port2") - i2 := &oc.Interface{Name: ygot.String(p2.Name()), Id: ygot.Uint32(portID + 1)} - gnmi.Replace(t, dut, d.Interface(p2.Name()).Config(), configInterfaceDUT(i2, &dutPort2, dut)) - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - fptest.AssignToNetworkInstance(t, dut, p2.Name(), deviations.DefaultNetworkInstance(dut), 0) - } - if deviations.ExplicitPortSpeed(dut) { - fptest.SetPortSpeed(t, p1) - fptest.SetPortSpeed(t, p2) - } -} - -// configureATE configures port1 and port2 on the ATE. -func configureATE(t *testing.T, ate *ondatra.ATEDevice) *ondatra.ATETopology { - top := ate.Topology().New() - - p1 := ate.Port(t, "port1") - i1 := top.AddInterface(atePort1.Name).WithPort(p1) - i1.IPv4(). - WithAddress(atePort1.IPv4CIDR()). - WithDefaultGateway(dutPort1.IPv4) - - p2 := ate.Port(t, "port2") - i2 := top.AddInterface(atePort2.Name).WithPort(p2) - i2.IPv4(). - WithAddress(atePort2.IPv4CIDR()). - WithDefaultGateway(dutPort2.IPv4) - - return top -} - -// configureDeviceIDs configures p4rt device-id on the DUT. -func configureDeviceID(ctx context.Context, t *testing.T, dut *ondatra.DUTDevice) { - nodes := p4rtutils.P4RTNodesByPort(t, dut) - p4rtNode, ok := nodes["port1"] - if !ok { - t.Fatal("Couldn't find P4RT Node for port: port1") - } - t.Logf("Configuring P4RT Node: %s", p4rtNode) - c := oc.Component{} - c.Name = ygot.String(p4rtNode) - c.IntegratedCircuit = &oc.Component_IntegratedCircuit{} - c.IntegratedCircuit.NodeId = ygot.Uint64(deviceID) - gnmi.Replace(t, dut, gnmi.OC().Component(p4rtNode).Config(), &c) -} - -// setupP4RTClient sends client arbitration message for both leader and follower clients, -// then sends setforwordingpipelineconfig with leader client. -func setupP4RTClient(ctx context.Context, args *testArgs) error { - // Setup p4rt-client stream parameters - streamParameter := p4rt_client.P4RTStreamParameters{ - Name: streamName, - DeviceId: deviceID, - ElectionIdH: uint64(0), - ElectionIdL: electionID, - } - - // Send ClientArbitration message on both p4rt leader and follower clients. - clients := []*p4rt_client.P4RTClient{args.leader, args.follower} - for index, client := range clients { - if client != nil { - client.StreamChannelCreate(&streamParameter) - if err := client.StreamChannelSendMsg(&streamName, &p4_v1.StreamMessageRequest{ - Update: &p4_v1.StreamMessageRequest_Arbitration{ - Arbitration: &p4_v1.MasterArbitrationUpdate{ - DeviceId: streamParameter.DeviceId, - ElectionId: &p4_v1.Uint128{ - High: streamParameter.ElectionIdH, - Low: streamParameter.ElectionIdL - uint64(index), - }, - }, - }, - }); err != nil { - return fmt.Errorf("errors seen when sending ClientArbitration message: %v", err) - } - if _, _, arbErr := client.StreamChannelGetArbitrationResp(&streamName, 1); arbErr != nil { - if err := p4rtutils.StreamTermErr(client.StreamTermErr); err != nil { - return err - } - return fmt.Errorf("errors seen in ClientArbitration response: %v", arbErr) - } - } - } - - // Load p4info file. - p4Info, err := utils.P4InfoLoad(p4InfoFile) - if err != nil { - return errors.New("Errors seen when loading p4info file.") - } - - // Send SetForwardingPipelineConfig for p4rt leader client. - if err := args.leader.SetForwardingPipelineConfig(&p4_v1.SetForwardingPipelineConfigRequest{ - DeviceId: deviceID, - ElectionId: &p4_v1.Uint128{High: uint64(0), Low: electionID}, - Action: p4_v1.SetForwardingPipelineConfigRequest_VERIFY_AND_COMMIT, - Config: &p4_v1.ForwardingPipelineConfig{ - P4Info: p4Info, - Cookie: &p4_v1.ForwardingPipelineConfig_Cookie{ - Cookie: 159, - }, - }, - }); err != nil { - return errors.New("Errors seen when sending SetForwardingPipelineConfig.") - } - return nil -} - -// getGDPParameter returns GDP related parameters for testPacketOut testcase. -func getGDPParameter(t *testing.T) PacketIO { - return &GDPPacketIO{ - IngressPort: fmt.Sprint(portID), - } -} - -func TestPacketOut(t *testing.T) { - dut := ondatra.DUT(t, "dut") - ctx := context.Background() - - configureDUT(t, dut) - - // Configure the ATE - ate := ondatra.ATE(t, "ate") - top := configureATE(t, ate) - top.Push(t).StartProtocols(t) - - // Configure P4RT device-id - configureDeviceID(ctx, t, dut) - - leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { - t.Fatalf("Could not initialize p4rt client: %v", err) - } - - follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { - t.Fatalf("Could not initialize p4rt client: %v", err) - } - - args := &testArgs{ - ctx: ctx, - leader: leader, - follower: follower, - dut: dut, - ate: ate, - top: top, - } - - if err := setupP4RTClient(ctx, args); err != nil { - t.Fatalf("Could not setup p4rt client: %v", err) - } - - args.packetIO = getGDPParameter(t) - testPacketOut(ctx, t, args) -} - -type GDPPacketIO struct { - PacketIO - IngressPort string -} - -// packetGDPRequestGet generates PacketOut payload for GDP packets. -func packetGDPRequestGet() []byte { - buf := gopacket.NewSerializeBuffer() - opts := gopacket.SerializeOptions{ - FixLengths: true, - ComputeChecksums: true, - } - pktEth := &layers.Ethernet{ - SrcMAC: net.HardwareAddr{0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA}, - // GDP MAC is 00:0A:DA:F0:F0:F0 - DstMAC: net.HardwareAddr{0x00, 0x0A, 0xDA, 0xF0, 0xF0, 0xF0}, - EthernetType: gdpInLayers, - } - payload := []byte{} - payLoadLen := 64 - for i := 0; i < payLoadLen; i++ { - payload = append(payload, byte(i)) - } - gopacket.SerializeLayers(buf, opts, - pktEth, gopacket.Payload(payload), - ) - return buf.Bytes() -} - -// GetTableEntry creates wbb acl entry related to GDP. -func (gdp *GDPPacketIO) GetTableEntry(delete bool) []*p4rtutils.ACLWbbIngressTableEntryInfo { - actionType := p4_v1.Update_INSERT - if delete { - actionType = p4_v1.Update_DELETE - } - return []*p4rtutils.ACLWbbIngressTableEntryInfo{{ - Type: actionType, - EtherType: 0x6007, - EtherTypeMask: 0xFFFF, - Priority: 1, - }} -} - -// GetPacketOut generates PacketOut message with payload as GDP. -func (gdp *GDPPacketIO) GetPacketOut(portID uint32, submitIngress bool) []*p4_v1.PacketOut { - packets := []*p4_v1.PacketOut{} - packet := &p4_v1.PacketOut{ - Payload: packetGDPRequestGet(), - Metadata: []*p4_v1.PacketMetadata{ - { - MetadataId: uint32(1), // "egress_port" - Value: []byte(fmt.Sprint(portID)), - }, - }, - } - if submitIngress { - packet.Metadata = append(packet.Metadata, - &p4_v1.PacketMetadata{ - MetadataId: uint32(2), // "submit_to_ingress" - Value: []byte{1}, - }) - } - packets = append(packets, packet) - return packets -} diff --git a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/metadata.textproto b/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/metadata.textproto deleted file mode 100644 index 15f9dac55a9..00000000000 --- a/feature/experimental/p4rt/ate_tests/google_discovery_protocol_packetout_test/metadata.textproto +++ /dev/null @@ -1,34 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "35e47706-04ec-44b2-a184-d1f274fb3182" -plan_id: "P4RT-3.2" -description: "Google Discovery Protocol: PacketOut" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - ipv4_missing_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_port_speed: true - explicit_interface_in_default_vrf: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - interface_enabled: true - default_network_instance: "default" - } -} diff --git a/feature/experimental/p4rt/ate_tests/lldp_packetin_test/README.md b/feature/experimental/p4rt/ate_tests/lldp_packetin_test/README.md deleted file mode 100644 index 4af42c8c091..00000000000 --- a/feature/experimental/p4rt/ate_tests/lldp_packetin_test/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# P4RT-7.1: LLDP: PacketIn - -## Summary - -Verify that LLDP packets are punted with correct metadata. - -## Procedure - -* Connect ATE port-1 to DUT port-1, and ATE port-2 to DUT port-2. -* Disable on-box processing of LLDP. -* Enable the P4RT server on the device. -* Connect a P4RT client and configure the forwarding pipeline. Install the P4RT table entry required for LLDP. -* Send an LLDP packet from the ATE and verify that it is received by the client. -* Verify that the packet has the ingress_singleton_port metadata set and it corresponds to the interface ID of the port that the packet was received on. - - - -## Config Parameter coverage - -No new configuration covered. - -## Telemetry Parameter coverage - -No new telemetry covered. - -## Minimum DUT platform requirement - -vRX if the vendor implementation supports FIB-ACK simulation, otherwise FFF. \ No newline at end of file diff --git a/feature/experimental/p4rt/ate_tests/lldp_packetin_test/lldp_packetin_test.go b/feature/experimental/p4rt/ate_tests/lldp_packetin_test/lldp_packetin_test.go deleted file mode 100644 index ec9b8545922..00000000000 --- a/feature/experimental/p4rt/ate_tests/lldp_packetin_test/lldp_packetin_test.go +++ /dev/null @@ -1,461 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package lldp_packetin_test - -import ( - "context" - "errors" - "fmt" - "strings" - "testing" - "time" - - "flag" - - "github.com/cisco-open/go-p4/p4rt_client" - "github.com/cisco-open/go-p4/utils" - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "github.com/openconfig/featureprofiles/feature/experimental/p4rt/internal/p4rtutils" - "github.com/openconfig/featureprofiles/internal/attrs" - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygot/ygot" - p4pb "github.com/p4lang/p4runtime/go/p4/v1" -) - -const ( - ipv4PrefixLen = 30 -) - -var ( - p4InfoFile = flag.String("p4info_file_location", "../../wbb.p4info.pb.txt", "Path to the p4info file.") - lldpSrcMAC = flag.String("lldp_src_MAC", "00:01:00:02:00:03", "source MAC address for PacketIn") - streamName = "p4rt" - lldpMAC = "01:80:c2:00:00:0e" - lldpEtherType = uint32(0x88cc) - deviceID = uint64(1) - portID = uint32(10) - electionID = uint64(100) - metadataIngressPort = uint32(1) - metadataEgressPort = uint32(2) -) - -var ( - dutPort1 = attrs.Attributes{ - Desc: "dutPort1", - IPv4: "192.0.2.1", - IPv4Len: ipv4PrefixLen, - } - - atePort1 = attrs.Attributes{ - Name: "atePort1", - IPv4: "192.0.2.2", - IPv4Len: ipv4PrefixLen, - } - - dutPort2 = attrs.Attributes{ - Desc: "dutPort2", - IPv4: "192.0.2.5", - IPv4Len: ipv4PrefixLen, - } - - atePort2 = attrs.Attributes{ - Name: "atePort2", - IPv4: "192.0.2.6", - IPv4Len: ipv4PrefixLen, - } -) - -type PacketIO interface { - GetTableEntry(delete bool) []*p4rtutils.ACLWbbIngressTableEntryInfo - GetPacketTemplate() *PacketIOPacket - GetTrafficFlow(ate *ondatra.ATEDevice, frameSize uint32, frameRate uint64) []*ondatra.Flow - GetEgressPort() []string - GetIngressPort() string -} - -type PacketIOPacket struct { - SrcMAC, DstMAC *string - EthernetType *uint32 -} - -type testArgs struct { - ctx context.Context - leader *p4rt_client.P4RTClient - follower *p4rt_client.P4RTClient - dut *ondatra.DUTDevice - ate *ondatra.ATEDevice - top *ondatra.ATETopology - packetIO PacketIO -} - -// programmTableEntry programs or deletes p4rt table entry based on delete flag. -func programmTableEntry(ctx context.Context, t *testing.T, client *p4rt_client.P4RTClient, packetIO PacketIO, delete bool) error { - t.Helper() - err := client.Write(&p4pb.WriteRequest{ - DeviceId: deviceID, - ElectionId: &p4pb.Uint128{High: uint64(0), Low: electionID}, - Updates: p4rtutils.ACLWbbIngressTableEntryGet( - packetIO.GetTableEntry(delete), - ), - Atomicity: p4pb.WriteRequest_CONTINUE_ON_ERROR, - }) - if err != nil { - return err - } - return nil -} - -// decodePacket decodes L2 header in the packet and returns source and destination MAC and ethernet type. -func decodePacket(t *testing.T, packetData []byte) (string, string, layers.EthernetType) { - t.Helper() - packet := gopacket.NewPacket(packetData, layers.LayerTypeEthernet, gopacket.Default) - etherHeader := packet.Layer(layers.LayerTypeEthernet) - if etherHeader != nil { - header, decoded := etherHeader.(*layers.Ethernet) - if decoded { - return header.SrcMAC.String(), header.DstMAC.String(), header.EthernetType - } - } - return "", "", layers.EthernetType(0) -} - -// testTraffic sends traffic flow for duration seconds and returns the -// number of packets sent out. -func testTraffic(t *testing.T, ate *ondatra.ATEDevice, flows []*ondatra.Flow, srcEndPoint *ondatra.Interface, duration int) int { - t.Helper() - for _, flow := range flows { - flow.WithSrcEndpoints(srcEndPoint).WithDstEndpoints(srcEndPoint) - } - ate.Traffic().Start(t, flows...) - time.Sleep(time.Duration(duration) * time.Second) - ate.Traffic().Stop(t) - - outPkts := gnmi.GetAll(t, ate, gnmi.OC().FlowAny().Counters().OutPkts().State()) - total := 0 - for _, count := range outPkts { - total += int(count) - } - return total -} - -// testPacketIn programs p4rt table entry and sends traffic related to LLDP, -// then validates packetin message metadata and payload. -func testPacketIn(ctx context.Context, t *testing.T, args *testArgs) { - leader := args.leader - - // Insert wbb acl entry on the DUT - if err := programmTableEntry(ctx, t, leader, args.packetIO, false); err != nil { - t.Fatalf("There is error when programming entry") - } - // Delete wbb acl entry on the device - defer programmTableEntry(ctx, t, leader, args.packetIO, true) - - // Send LLDP traffic from ATE - srcEndPoint := args.top.Interfaces()[atePort1.Name] - pktOut := testTraffic(t, args.ate, args.packetIO.GetTrafficFlow(args.ate, 300, 2), srcEndPoint, 10) - - // Extract packets from PacketIn message sent to p4rt client - _, packets, err := leader.StreamChannelGetPackets(&streamName, uint64(pktOut), 30*time.Second) - if err != nil { - t.Errorf("Unexpected error on StreamChannelGetPackets: %v", err) - } - - gotPkts := 0 - t.Logf("Start to decode packet and compare with expected packets.") - wantPacket := args.packetIO.GetPacketTemplate() - for _, packet := range packets { - if packet != nil { - if wantPacket.DstMAC != nil && wantPacket.EthernetType != nil { - srcMAC, dstMac, etherType := decodePacket(t, packet.Pkt.GetPayload()) - if dstMac != *wantPacket.DstMAC || etherType != layers.EthernetType(*wantPacket.EthernetType) { - continue - } - if !strings.EqualFold(srcMAC, *lldpSrcMAC) { - continue - } - } - - metaData := packet.Pkt.GetMetadata() - for _, data := range metaData { - switch data.GetMetadataId() { - case metadataIngressPort: - if string(data.GetValue()) != args.packetIO.GetIngressPort() { - t.Fatalf("Ingress Port Id is not matching expectation.") - } - case metadataEgressPort: - found := false - for _, portData := range args.packetIO.GetEgressPort() { - if string(data.GetValue()) == portData { - found = true - } - } - if !found { - t.Fatalf("Egress Port Id is not matching expectation.") - } - } - } - gotPkts++ - } - } - if got, want := gotPkts, pktOut; got != want { - t.Errorf("Number of PacketIn, got: %d, want: %d", got, want) - } -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// configInterfaceDUT configures the interface with the Addrs. -func configInterfaceDUT(i *oc.Interface, a *attrs.Attributes, dut *ondatra.DUTDevice) *oc.Interface { - i.Description = ygot.String(a.Desc) - i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd - if deviations.InterfaceEnabled(dut) { - i.Enabled = ygot.Bool(true) - } - - s := i.GetOrCreateSubinterface(0) - s4 := s.GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) { - s4.Enabled = ygot.Bool(true) - } - s4a := s4.GetOrCreateAddress(a.IPv4) - s4a.PrefixLength = ygot.Uint8(ipv4PrefixLen) - - return i -} - -// configureDUT configures port1 and port2 on the DUT. -func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { - d := gnmi.OC() - - p1 := dut.Port(t, "port1") - i1 := &oc.Interface{Name: ygot.String(p1.Name()), Id: ygot.Uint32(portID)} - gnmi.Replace(t, dut, d.Interface(p1.Name()).Config(), configInterfaceDUT(i1, &dutPort1, dut)) - - p2 := dut.Port(t, "port2") - i2 := &oc.Interface{Name: ygot.String(p2.Name()), Id: ygot.Uint32(portID + 1)} - gnmi.Replace(t, dut, d.Interface(p2.Name()).Config(), configInterfaceDUT(i2, &dutPort2, dut)) - - if deviations.ExplicitPortSpeed(dut) { - fptest.SetPortSpeed(t, p1) - fptest.SetPortSpeed(t, p2) - } - - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - fptest.AssignToNetworkInstance(t, dut, p1.Name(), deviations.DefaultNetworkInstance(dut), 0) - fptest.AssignToNetworkInstance(t, dut, p2.Name(), deviations.DefaultNetworkInstance(dut), 0) - } - gnmi.Replace(t, dut, gnmi.OC().Lldp().Enabled().Config(), false) -} - -// configureATE configures port1 and port2 on the ATE. -func configureATE(t *testing.T, ate *ondatra.ATEDevice) *ondatra.ATETopology { - top := ate.Topology().New() - - p1 := ate.Port(t, "port1") - i1 := top.AddInterface(atePort1.Name).WithPort(p1) - i1.IPv4(). - WithAddress(atePort1.IPv4CIDR()). - WithDefaultGateway(dutPort1.IPv4) - - p2 := ate.Port(t, "port2") - i2 := top.AddInterface(atePort2.Name).WithPort(p2) - i2.IPv4(). - WithAddress(atePort2.IPv4CIDR()). - WithDefaultGateway(dutPort2.IPv4) - - return top -} - -// configureDeviceID configures p4rt device-id on the DUT. -func configureDeviceID(ctx context.Context, t *testing.T, dut *ondatra.DUTDevice) { - nodes := p4rtutils.P4RTNodesByPort(t, dut) - p4rtNode, ok := nodes["port1"] - if !ok { - t.Fatal("Couldn't find P4RT Node for port: port1") - } - t.Logf("Configuring P4RT Node: %s", p4rtNode) - - c := oc.Component{} - c.Name = ygot.String(p4rtNode) - c.IntegratedCircuit = &oc.Component_IntegratedCircuit{} - c.IntegratedCircuit.NodeId = ygot.Uint64(deviceID) - gnmi.Replace(t, dut, gnmi.OC().Component(p4rtNode).Config(), &c) -} - -// setupP4RTClient sends client arbitration message for both leader and follower clients, -// then sends setforwordingpipelineconfig with leader client. -func setupP4RTClient(ctx context.Context, args *testArgs) error { - // Setup p4rt-client stream parameters - streamParameter := p4rt_client.P4RTStreamParameters{ - Name: streamName, - DeviceId: deviceID, - ElectionIdH: uint64(0), - ElectionIdL: electionID, - } - - // Send ClientArbitration message on both p4rt leader and follower clients. - clients := []*p4rt_client.P4RTClient{args.leader, args.follower} - for index, client := range clients { - if client != nil { - client.StreamChannelCreate(&streamParameter) - if err := client.StreamChannelSendMsg(&streamName, &p4pb.StreamMessageRequest{ - Update: &p4pb.StreamMessageRequest_Arbitration{ - Arbitration: &p4pb.MasterArbitrationUpdate{ - DeviceId: streamParameter.DeviceId, - ElectionId: &p4pb.Uint128{ - High: streamParameter.ElectionIdH, - Low: streamParameter.ElectionIdL - uint64(index), - }, - }, - }, - }); err != nil { - return errors.New("errors seen when sending ClientArbitration message") - } - if _, _, arbErr := client.StreamChannelGetArbitrationResp(&streamName, 1); arbErr != nil { - if err := p4rtutils.StreamTermErr(client.StreamTermErr); err != nil { - return err - } - return errors.New("errors seen in ClientArbitration response") - } - } - } - - // Load p4info file. - p4Info, err := utils.P4InfoLoad(p4InfoFile) - if err != nil { - return errors.New("errors seen when loading p4info file") - } - - // Send SetForwardingPipelineConfig for p4rt leader client. - if err := args.leader.SetForwardingPipelineConfig(&p4pb.SetForwardingPipelineConfigRequest{ - DeviceId: deviceID, - ElectionId: &p4pb.Uint128{High: uint64(0), Low: electionID}, - Action: p4pb.SetForwardingPipelineConfigRequest_VERIFY_AND_COMMIT, - Config: &p4pb.ForwardingPipelineConfig{ - P4Info: p4Info, - Cookie: &p4pb.ForwardingPipelineConfig_Cookie{ - Cookie: 159, - }, - }, - }); err != nil { - return errors.New("errors seen when sending SetForwardingPipelineConfig") - } - return nil -} - -// getLLDPParameter returns LLDP related parameters for testPacketIn testcase. -func getLLDPParameter(t *testing.T) PacketIO { - return &LLDPPacketIO{ - PacketIOPacket: PacketIOPacket{ - SrcMAC: lldpSrcMAC, - DstMAC: &lldpMAC, - EthernetType: &lldpEtherType, - }, - IngressPort: fmt.Sprint(portID), - } -} - -func TestPacketIn(t *testing.T) { - dut := ondatra.DUT(t, "dut") - ctx := context.Background() - - configureDUT(t, dut) - - // Configure the ATE - ate := ondatra.ATE(t, "ate") - top := configureATE(t, ate) - top.Push(t).StartProtocols(t) - - // Configure P4RT device-id - configureDeviceID(ctx, t, dut) - - leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { - t.Fatalf("Could not initialize p4rt client: %v", err) - } - - follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { - t.Fatalf("Could not initialize p4rt client: %v", err) - } - - args := &testArgs{ - ctx: ctx, - leader: leader, - follower: follower, - dut: dut, - ate: ate, - top: top, - } - - if err := setupP4RTClient(ctx, args); err != nil { - t.Fatalf("Could not setup p4rt client: %v", err) - } - - args.packetIO = getLLDPParameter(t) - testPacketIn(ctx, t, args) -} - -type LLDPPacketIO struct { - PacketIOPacket - IngressPort string -} - -// GetTableEntry creates wbb acl entry related to LLDP. -func (lldp *LLDPPacketIO) GetTableEntry(delete bool) []*p4rtutils.ACLWbbIngressTableEntryInfo { - actionType := p4pb.Update_INSERT - if delete { - actionType = p4pb.Update_DELETE - } - return []*p4rtutils.ACLWbbIngressTableEntryInfo{{ - Type: actionType, - EtherType: 0x88cc, - EtherTypeMask: 0xFFFF, - Priority: 1, - }} -} - -// GetPacketTemplate returns expected packets in PacketIn. -func (lldp *LLDPPacketIO) GetPacketTemplate() *PacketIOPacket { - return &lldp.PacketIOPacket -} - -// GetTrafficFlow generates ATE traffic flows for LLDP. -func (lldp *LLDPPacketIO) GetTrafficFlow(ate *ondatra.ATEDevice, frameSize uint32, frameRate uint64) []*ondatra.Flow { - ethHeader := ondatra.NewEthernetHeader() - ethHeader.WithSrcAddress(*lldp.SrcMAC) - ethHeader.WithDstAddress(*lldp.DstMAC) - ethHeader.WithEtherType(*lldp.EthernetType) - - flow := ate.Traffic().NewFlow("LLDP").WithFrameSize(frameSize).WithFrameRateFPS(frameRate).WithHeaders(ethHeader) - return []*ondatra.Flow{flow} -} - -// GetEgressPort returns expected egress port info in PacketIn. -func (lldp *LLDPPacketIO) GetEgressPort() []string { - return []string{"0"} -} - -// GetIngressPort return expected ingress port info in PacketIn. -func (lldp *LLDPPacketIO) GetIngressPort() string { - return lldp.IngressPort -} diff --git a/feature/experimental/p4rt/ate_tests/lldp_packetin_test/metadata.textproto b/feature/experimental/p4rt/ate_tests/lldp_packetin_test/metadata.textproto deleted file mode 100644 index dd54cc68e40..00000000000 --- a/feature/experimental/p4rt/ate_tests/lldp_packetin_test/metadata.textproto +++ /dev/null @@ -1,26 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "f9782c58-1b28-41d0-b9c8-9bbbd7bb1b1c" -plan_id: "P4RT-7.1" -description: "LLDP: PacketIn" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_port_speed: true - explicit_interface_in_default_vrf: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - interface_enabled: true - default_network_instance: "default" - } -} diff --git a/feature/experimental/p4rt/ate_tests/lldp_packetout_test/README.md b/feature/experimental/p4rt/ate_tests/lldp_packetout_test/README.md deleted file mode 100644 index ec9b4d9d73a..00000000000 --- a/feature/experimental/p4rt/ate_tests/lldp_packetout_test/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# P4RT-7.2: LLDP: PacketOut - -## Summary - -Verify that LLDP packets can be sent by the controller. - -## Procedure - -* Connect ATE port-1 to DUT port-1, and ATE port-2 to DUT port-2. -* Disable on-box processing of LLDP. -* Enable the P4RT server on the device. -* Connect a P4RT client and configure the forwarding pipeline. Install the P4RT table entry required for LLDP. -* Send an LLDP packet from the client with egress_singleton_port set to one of the connected interfaces. -* Verify that the LLDP packet is received on the ATE port connected to the indicated interface. - - - - -## Config Parameter coverage - -No new configuration covered. - -## Telemetry Parameter coverage - -No new telemetry covered. - -## Minimum DUT platform requirement - -vRX if the vendor implementation supports FIB-ACK simulation, otherwise FFF. \ No newline at end of file diff --git a/feature/experimental/p4rt/ate_tests/lldp_packetout_test/lldp_packetout_test.go b/feature/experimental/p4rt/ate_tests/lldp_packetout_test/lldp_packetout_test.go deleted file mode 100644 index e89353a0ab4..00000000000 --- a/feature/experimental/p4rt/ate_tests/lldp_packetout_test/lldp_packetout_test.go +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package lldp_packetout_test - -import ( - "context" - "errors" - "fmt" - "net" - "sort" - "testing" - "time" - - "flag" - - "github.com/cisco-open/go-p4/p4rt_client" - "github.com/cisco-open/go-p4/utils" - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "github.com/openconfig/featureprofiles/feature/experimental/p4rt/internal/p4rtutils" - "github.com/openconfig/featureprofiles/internal/attrs" - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygot/ygot" - p4pb "github.com/p4lang/p4runtime/go/p4/v1" -) - -const ( - ipv4PrefixLen = 30 - packetCount = 100 -) - -var ( - p4InfoFile = flag.String("p4info_file_location", "../../wbb.p4info.pb.txt", "Path to the p4info file.") - streamName = "p4rt" - lldpInLayers layers.EthernetType = 0x88cc - deviceID = *ygot.Uint64(1) - portID = *ygot.Uint32(10) - electionID = *ygot.Uint64(100) -) - -var ( - dutPort1 = attrs.Attributes{ - Desc: "dutPort1", - IPv4: "192.0.2.1", - IPv4Len: ipv4PrefixLen, - } - - atePort1 = attrs.Attributes{ - Name: "atePort1", - IPv4: "192.0.2.2", - IPv4Len: ipv4PrefixLen, - } - - dutPort2 = attrs.Attributes{ - Desc: "dutPort2", - IPv4: "192.0.2.5", - IPv4Len: ipv4PrefixLen, - } - - atePort2 = attrs.Attributes{ - Name: "atePort2", - IPv4: "192.0.2.6", - IPv4Len: ipv4PrefixLen, - } -) - -type PacketIO interface { - GetTableEntry(delete bool) []*p4rtutils.ACLWbbIngressTableEntryInfo - GetPacketOut(portID uint32, submitIngress bool) []*p4pb.PacketOut -} - -type testArgs struct { - ctx context.Context - leader *p4rt_client.P4RTClient - follower *p4rt_client.P4RTClient - dut *ondatra.DUTDevice - ate *ondatra.ATEDevice - top *ondatra.ATETopology - packetIO PacketIO -} - -// programmTableEntry programs or deletes p4rt table entry based on delete flag. -func programmTableEntry(ctx context.Context, t *testing.T, client *p4rt_client.P4RTClient, packetIO PacketIO, delete bool) error { - t.Helper() - err := client.Write(&p4pb.WriteRequest{ - DeviceId: deviceID, - ElectionId: &p4pb.Uint128{High: uint64(0), Low: electionID}, - Updates: p4rtutils.ACLWbbIngressTableEntryGet( - packetIO.GetTableEntry(delete), - ), - Atomicity: p4pb.WriteRequest_CONTINUE_ON_ERROR, - }) - if err != nil { - return err - } - return nil -} - -// sendPackets sends out packets via PacketOut message in StreamChannel. -func sendPackets(t *testing.T, client *p4rt_client.P4RTClient, packets []*p4pb.PacketOut, packetCount int) { - count := packetCount / len(packets) - for _, packet := range packets { - for i := 0; i < count; i++ { - if err := client.StreamChannelSendMsg( - &streamName, &p4pb.StreamMessageRequest{ - Update: &p4pb.StreamMessageRequest_Packet{ - Packet: packet, - }, - }); err != nil { - t.Errorf("There is error seen in Packet Out. %v, %s", err, err) - } - } - } -} - -// testPacketOut sends out PacketOut with GDP payload on p4rt leader or -// follower client, then verify DUT interface statistics -func testPacketOut(ctx context.Context, t *testing.T, args *testArgs) { - leader := args.leader - - // Insert wbb acl entry on the DUT - if err := programmTableEntry(ctx, t, leader, args.packetIO, false); err != nil { - t.Fatalf("There is error when programming entry") - } - // Delete wbb acl entry on the device - defer programmTableEntry(ctx, t, leader, args.packetIO, true) - - packetOutTests := []struct { - desc string - client *p4rt_client.P4RTClient - expectPass bool - }{{ - desc: "PacketOut from Primary Controller", - client: leader, - expectPass: true, - }} - - for _, test := range packetOutTests { - t.Run(test.desc, func(t *testing.T) { - // Check initial packet counters - port := sortPorts(args.ate.Ports())[0].Name() - counter0 := gnmi.Get(t, args.ate, gnmi.OC().Interface(port).Counters().InPkts().State()) - - packets := args.packetIO.GetPacketOut(portID, false) - sendPackets(t, test.client, packets, packetCount) - - // Wait for ate stats to be populated - time.Sleep(60 * time.Second) - - // Check packet counters after packet out - counter1 := gnmi.Get(t, args.ate, gnmi.OC().Interface(port).Counters().InPkts().State()) - - // Verify InPkts stats to check P4RT stream - t.Logf("Received %v packets on ATE port %s", counter1-counter0, port) - - if test.expectPass { - if counter1-counter0 < uint64(float64(packetCount)*0.95) { - t.Fatalf("Not all the packets are received.") - } - } else { - if counter1-counter0 > uint64(float64(packetCount)*0.10) { - t.Fatalf("Unexpected packets are received.") - } - } - }) - } -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// sortPorts sorts the ports by the testbed port ID. -func sortPorts(ports []*ondatra.Port) []*ondatra.Port { - sort.Slice(ports, func(i, j int) bool { - idi, idj := ports[i].ID(), ports[j].ID() - li, lj := len(idi), len(idj) - if li == lj { - return idi < idj - } - return li < lj // "port2" < "port10" - }) - return ports -} - -// configInterfaceDUT configures the interface with the Addrs. -func configInterfaceDUT(i *oc.Interface, a *attrs.Attributes, dut *ondatra.DUTDevice) *oc.Interface { - i.Description = ygot.String(a.Desc) - i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd - if deviations.InterfaceEnabled(dut) { - i.Enabled = ygot.Bool(true) - } - - s := i.GetOrCreateSubinterface(0) - s4 := s.GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) { - s4.Enabled = ygot.Bool(true) - } - s4a := s4.GetOrCreateAddress(a.IPv4) - s4a.PrefixLength = ygot.Uint8(ipv4PrefixLen) - - return i -} - -// configureDUT configures port1 and port2 on the DUT. -func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { - d := gnmi.OC() - - p1 := dut.Port(t, "port1") - i1 := &oc.Interface{Name: ygot.String(p1.Name()), Id: ygot.Uint32(portID)} - gnmi.Replace(t, dut, d.Interface(p1.Name()).Config(), configInterfaceDUT(i1, &dutPort1, dut)) - - p2 := dut.Port(t, "port2") - i2 := &oc.Interface{Name: ygot.String(p2.Name()), Id: ygot.Uint32(portID + 1)} - gnmi.Replace(t, dut, d.Interface(p2.Name()).Config(), configInterfaceDUT(i2, &dutPort2, dut)) - - if deviations.ExplicitPortSpeed(dut) { - fptest.SetPortSpeed(t, p1) - fptest.SetPortSpeed(t, p2) - } - - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - fptest.AssignToNetworkInstance(t, dut, p1.Name(), deviations.DefaultNetworkInstance(dut), 0) - fptest.AssignToNetworkInstance(t, dut, p2.Name(), deviations.DefaultNetworkInstance(dut), 0) - } -} - -// configureATE configures port1 and port2 on the ATE. -func configureATE(t *testing.T, ate *ondatra.ATEDevice) *ondatra.ATETopology { - top := ate.Topology().New() - - p1 := ate.Port(t, "port1") - i1 := top.AddInterface(atePort1.Name).WithPort(p1) - i1.IPv4(). - WithAddress(atePort1.IPv4CIDR()). - WithDefaultGateway(dutPort1.IPv4) - - p2 := ate.Port(t, "port2") - i2 := top.AddInterface(atePort2.Name).WithPort(p2) - i2.IPv4(). - WithAddress(atePort2.IPv4CIDR()). - WithDefaultGateway(dutPort2.IPv4) - - return top -} - -// configureDeviceID configures p4rt device-id on the DUT. -func configureDeviceID(ctx context.Context, t *testing.T, dut *ondatra.DUTDevice) { - nodes := p4rtutils.P4RTNodesByPort(t, dut) - p4rtNode, ok := nodes["port1"] - if !ok { - t.Fatal("Couldn't find P4RT Node for port: port1") - } - t.Logf("Configuring P4RT Node: %s", p4rtNode) - component := oc.Component{} - component.IntegratedCircuit = &oc.Component_IntegratedCircuit{} - component.Name = ygot.String(p4rtNode) - component.IntegratedCircuit.NodeId = ygot.Uint64(deviceID) - gnmi.Replace(t, dut, gnmi.OC().Component(p4rtNode).Config(), &component) -} - -// setupP4RTClient sends client arbitration message for both leader and follower clients, -// then sends setforwordingpipelineconfig with leader client. -func setupP4RTClient(ctx context.Context, args *testArgs) error { - // Setup p4rt-client stream parameters - streamParameter := p4rt_client.P4RTStreamParameters{ - Name: streamName, - DeviceId: deviceID, - ElectionIdH: uint64(0), - ElectionIdL: electionID, - } - - // Send ClientArbitration message on both p4rt leader and follower clients. - clients := []*p4rt_client.P4RTClient{args.leader, args.follower} - for index, client := range clients { - if client != nil { - client.StreamChannelCreate(&streamParameter) - if err := client.StreamChannelSendMsg(&streamName, &p4pb.StreamMessageRequest{ - Update: &p4pb.StreamMessageRequest_Arbitration{ - Arbitration: &p4pb.MasterArbitrationUpdate{ - DeviceId: streamParameter.DeviceId, - ElectionId: &p4pb.Uint128{ - High: streamParameter.ElectionIdH, - Low: streamParameter.ElectionIdL - uint64(index), - }, - }, - }, - }); err != nil { - return errors.New("errors seen when sending ClientArbitration message") - } - if _, _, arbErr := client.StreamChannelGetArbitrationResp(&streamName, 1); arbErr != nil { - if err := p4rtutils.StreamTermErr(client.StreamTermErr); err != nil { - return err - } - return errors.New("errors seen in ClientArbitration response") - } - } - } - - // Load p4info file. - p4Info, err := utils.P4InfoLoad(p4InfoFile) - if err != nil { - return errors.New("errors seen when loading p4info file") - } - - // Send SetForwardingPipelineConfig for p4rt leader client. - if err := args.leader.SetForwardingPipelineConfig(&p4pb.SetForwardingPipelineConfigRequest{ - DeviceId: deviceID, - ElectionId: &p4pb.Uint128{High: uint64(0), Low: electionID}, - Action: p4pb.SetForwardingPipelineConfigRequest_VERIFY_AND_COMMIT, - Config: &p4pb.ForwardingPipelineConfig{ - P4Info: p4Info, - Cookie: &p4pb.ForwardingPipelineConfig_Cookie{ - Cookie: 159, - }, - }, - }); err != nil { - return errors.New("errors seen when sending SetForwardingPipelineConfig") - } - return nil -} - -// getLLDPParameter returns LLDP related parameters for testPacketOut testcase. -func getLLDPParameter(t *testing.T) PacketIO { - return &LLDPPacketIO{ - IngressPort: fmt.Sprint(portID), - } -} - -func TestPacketOut(t *testing.T) { - dut := ondatra.DUT(t, "dut") - ctx := context.Background() - - configureDUT(t, dut) - - // Configure the ATE - ate := ondatra.ATE(t, "ate") - top := configureATE(t, ate) - top.Push(t).StartProtocols(t) - - // Configure P4RT device-id - configureDeviceID(ctx, t, dut) - - t.Logf("Disable LLDP config") - gnmi.Replace(t, dut, gnmi.OC().Lldp().Enabled().Config(), false) - - leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { - t.Fatalf("Could not initialize p4rt client: %v", err) - } - - follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { - t.Fatalf("Could not initialize p4rt client: %v", err) - } - - args := &testArgs{ - ctx: ctx, - leader: leader, - follower: follower, - dut: dut, - ate: ate, - top: top, - } - - if err := setupP4RTClient(ctx, args); err != nil { - t.Fatalf("Could not setup p4rt client: %v", err) - } - - args.packetIO = getLLDPParameter(t) - testPacketOut(ctx, t, args) -} - -type LLDPPacketIO struct { - PacketIO - IngressPort string -} - -// packetLLDPRequestGet generates PacketOut payload for LLDP packets. -func packetLLDPRequestGet() []byte { - buf := gopacket.NewSerializeBuffer() - opts := gopacket.SerializeOptions{ - FixLengths: true, - ComputeChecksums: true, - } - pktEth := &layers.Ethernet{ - SrcMAC: net.HardwareAddr{0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA}, - // LLDP MAC is 01:80:C2:00:00:0E - DstMAC: net.HardwareAddr{0x01, 0x80, 0xC2, 0x00, 0x00, 0x0E}, - EthernetType: lldpInLayers, - } - - pktLLDP := &layers.LinkLayerDiscovery{ - ChassisID: layers.LLDPChassisID{ - Subtype: layers.LLDPChassisIDSubTypeMACAddr, - ID: []byte{0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, - }, - PortID: layers.LLDPPortID{ - Subtype: layers.LLDPPortIDSubtypeIfaceName, - ID: []byte("port1"), - }, - TTL: 100, - } - - gopacket.SerializeLayers(buf, opts, pktEth, pktLLDP) - return buf.Bytes() -} - -// GetTableEntry creates wbb acl entry related to LLDP. -func (lldp *LLDPPacketIO) GetTableEntry(delete bool) []*p4rtutils.ACLWbbIngressTableEntryInfo { - actionType := p4pb.Update_INSERT - if delete { - actionType = p4pb.Update_DELETE - } - return []*p4rtutils.ACLWbbIngressTableEntryInfo{{ - Type: actionType, - EtherType: 0x88cc, - EtherTypeMask: 0xFFFF, - Priority: 1, - }} -} - -// GetPacketOut generates PacketOut message with payload as LLDP. -func (lldp *LLDPPacketIO) GetPacketOut(portID uint32, submitIngress bool) []*p4pb.PacketOut { - packets := []*p4pb.PacketOut{} - packet := &p4pb.PacketOut{ - Payload: packetLLDPRequestGet(), - Metadata: []*p4pb.PacketMetadata{ - { - MetadataId: uint32(1), // "egress_port" - Value: []byte(fmt.Sprint(portID)), - }, - }, - } - if submitIngress { - packet.Metadata = append(packet.Metadata, - &p4pb.PacketMetadata{ - MetadataId: uint32(2), // "submit_to_ingress" - Value: []byte{1}, - }) - } - packets = append(packets, packet) - return packets -} diff --git a/feature/experimental/p4rt/ate_tests/lldp_packetout_test/metadata.textproto b/feature/experimental/p4rt/ate_tests/lldp_packetout_test/metadata.textproto deleted file mode 100644 index 93f176037a0..00000000000 --- a/feature/experimental/p4rt/ate_tests/lldp_packetout_test/metadata.textproto +++ /dev/null @@ -1,26 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "65aab5ff-2e76-4437-a77b-7ed10f663c5e" -plan_id: "P4RT-7.2" -description: "LLDP: PacketOut" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_port_speed: true - explicit_interface_in_default_vrf: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - interface_enabled: true - default_network_instance: "default" - } -} diff --git a/feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/README.md b/feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/README.md deleted file mode 100644 index 4a8a2140675..00000000000 --- a/feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# P4RT-1.2: P4RT Daemon Failure - -## Summary - -Ensure that data plane traffic is not interrupted by P4RT daemon failure. - -## Procedure - -* Connect ATE port-1 to DUT port-1, and ATE port-2 to DUT port-2. - -* Establish a gRIBI client connection to the DUT (SINGLE_PRIMARY and PRESERVE - mode) and make it become leader. - - * Inject an IPv4 Entry for 203.0.113.0/24 pointed to a NHG containing a NH - of ATE port-2. Ensure that traffic with a destination in 203.0.113.0/24 - can be forwarded between ATE port-1 and port-2. Verify through AFT - telemetry that the route is installed. - -* Kill P4RT daemon on DUT using gNOI test command (gNOI.KillProcess). - -* Validate: - - * Traffic can continue to be forwarded between ATE port-1 and port-2. - -## Note - -* P4RT is not being used to configure the data plane in this test because our - test tables only configure the control plane traffic. Instead, this test - configures the data plane using gRIBI. It can also be achieved by - configuring static routes. - -## Protocol/RPC Parameter Coverage - -* gRIBI - * ModifyRequest - * GetRequest - -## Telemetry Parameter Coverage - -* AFT - * /network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/prefix/ diff --git a/feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/metadata.textproto b/feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/metadata.textproto deleted file mode 100644 index d9063936e7a..00000000000 --- a/feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/metadata.textproto +++ /dev/null @@ -1,34 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "78f99d29-c7db-4e6d-8284-614154efc0d1" -plan_id: "P4RT-1.2" -description: "P4RT Daemon Failure" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - ipv4_missing_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_port_speed: true - explicit_interface_in_default_vrf: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - interface_enabled: true - default_network_instance: "default" - } -} diff --git a/feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go b/feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go deleted file mode 100644 index 089654803df..00000000000 --- a/feature/experimental/p4rt/ate_tests/p4rt_daemon_failure_test/p4rt_daemon_failure_test.go +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package p4rt_daemon_failure_test - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/openconfig/featureprofiles/feature/experimental/p4rt/internal/p4rtutils" - "github.com/openconfig/featureprofiles/internal/attrs" - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/featureprofiles/internal/gribi" - "github.com/openconfig/gribigo/fluent" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygnmi/ygnmi" - "github.com/openconfig/ygot/ygot" - - syspb "github.com/openconfig/gnoi/system" -) - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -const ( - ipv4PrefixLen = 30 - ateDstNetCIDR = "203.0.113.0/24" - ipv4TrafficStart = "203.0.113.1" - ipv4TrafficEnd = "203.0.113.250" - nhIndex = 1 - nhgIndex = 42 - deviceID1 = uint64(1) - deviceID2 = uint64(2) - lossTolerance = float32(0.02) -) - -var ( - dutPort1 = attrs.Attributes{ - Desc: "dutPort1", - IPv4: "192.0.2.1", - IPv4Len: ipv4PrefixLen, - } - - atePort1 = attrs.Attributes{ - Name: "atePort1", - IPv4: "192.0.2.2", - IPv4Len: ipv4PrefixLen, - } - - dutPort2 = attrs.Attributes{ - Desc: "dutPort2", - IPv4: "192.0.2.5", - IPv4Len: ipv4PrefixLen, - } - - atePort2 = attrs.Attributes{ - Name: "atePort2", - IPv4: "192.0.2.6", - IPv4Len: ipv4PrefixLen, - } - - p4rtDaemons = map[ondatra.Vendor]string{ - ondatra.ARISTA: "P4Runtime", - ondatra.CISCO: "emsd", - ondatra.JUNIPER: "p4-switch", - ondatra.NOKIA: "sr_p4rt_server", - } -) - -// configInterfaceDUT returns the OC Interface config for a given port. -func configInterfaceDUT(i *oc.Interface, a *attrs.Attributes, dut *ondatra.DUTDevice) *oc.Interface { - i.Description = ygot.String(a.Desc) - i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd - if deviations.InterfaceEnabled(dut) { - i.Enabled = ygot.Bool(true) - } - - s := i.GetOrCreateSubinterface(0) - s4 := s.GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) && !deviations.IPv4MissingEnabled(dut) { - s4.Enabled = ygot.Bool(true) - } - s4a := s4.GetOrCreateAddress(a.IPv4) - s4a.PrefixLength = ygot.Uint8(ipv4PrefixLen) - - return i -} - -// configP4RTNode returns the OC P4RT Node Component for a given port. -func configP4RTNode(nodeID string, deviceID uint64) *oc.Component { - c := &oc.Component{} - c.Name = ygot.String(nodeID) - c.IntegratedCircuit = &oc.Component_IntegratedCircuit{} - c.IntegratedCircuit.NodeId = ygot.Uint64(deviceID) - return c -} - -// configureDUT uses gNMI to configure port1 and port2 on the DUT. -func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - d := gnmi.OC() - nodes := p4rtutils.P4RTNodesByPort(t, dut) - - p1 := dut.Port(t, "port1") - i1 := &oc.Interface{Name: ygot.String(p1.Name())} - gnmi.Replace(t, dut, d.Interface(p1.Name()).Config(), configInterfaceDUT(i1, &dutPort1, dut)) - - n1, ok := nodes[p1.ID()] - if !ok { - t.Fatal("P4RT node name for port1 not found.") - } - gnmi.Replace(t, dut, gnmi.OC().Component(n1).Config(), configP4RTNode(n1, deviceID1)) - - p2 := dut.Port(t, "port2") - i2 := &oc.Interface{Name: ygot.String(p2.Name())} - gnmi.Replace(t, dut, d.Interface(p2.Name()).Config(), configInterfaceDUT(i2, &dutPort2, dut)) - n2, ok := nodes[p2.ID()] - if !ok { - t.Fatal("P4RT node name for port2 not found.") - } - gnmi.Replace(t, dut, gnmi.OC().Component(n2).Config(), configP4RTNode(n2, deviceID2)) - - if deviations.ExplicitPortSpeed(dut) { - fptest.SetPortSpeed(t, p1) - fptest.SetPortSpeed(t, p2) - } - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - fptest.AssignToNetworkInstance(t, dut, p1.Name(), deviations.DefaultNetworkInstance(dut), 0) - fptest.AssignToNetworkInstance(t, dut, p2.Name(), deviations.DefaultNetworkInstance(dut), 0) - } -} - -// configureATE configures port1 and port2 on the ATE. -func configureATE(t *testing.T, ate *ondatra.ATEDevice) *ondatra.ATETopology { - t.Helper() - top := ate.Topology().New() - - p1 := ate.Port(t, "port1") - i1 := top.AddInterface(atePort1.Name).WithPort(p1) - i1.IPv4(). - WithAddress(atePort1.IPv4CIDR()). - WithDefaultGateway(dutPort1.IPv4) - - p2 := ate.Port(t, "port2") - i2 := top.AddInterface(atePort2.Name).WithPort(p2) - i2.IPv4(). - WithAddress(atePort2.IPv4CIDR()). - WithDefaultGateway(dutPort2.IPv4) - - return top -} - -// startTraffic generates traffic flow from source network to -// destination network via atePort1 to atePort2. -// Returns the flow object that it creates. -func startTraffic(t *testing.T, ate *ondatra.ATEDevice, top *ondatra.ATETopology) *ondatra.Flow { - t.Helper() - srcEndPoint := top.Interfaces()[atePort1.Name] - dstEndPoint := top.Interfaces()[atePort2.Name] - - ethHeader := ondatra.NewEthernetHeader() - ipv4Header := ondatra.NewIPv4Header() - ipv4Header.DstAddressRange(). - WithMin(ipv4TrafficStart). - WithMax(ipv4TrafficEnd). - WithCount(250) - - flow := ate.Traffic().NewFlow("Flow"). - WithSrcEndpoints(srcEndPoint). - WithDstEndpoints(dstEndPoint). - WithHeaders(ethHeader, ipv4Header) - - ate.Traffic().Start(t, flow) - - return flow -} - -// pidByName uses telemetry to find out the PID of a process -func pidByName(t *testing.T, dut *ondatra.DUTDevice, process string) (uint64, error) { - t.Helper() - ps := gnmi.GetAll(t, dut, gnmi.OC().System().ProcessAny().State()) - for _, p := range ps { - if p.GetName() == process { - return p.GetPid(), nil - } - } - return 0, fmt.Errorf("could not find PID for process: %s", process) -} - -func installRoutes(t *testing.T, dut *ondatra.DUTDevice) error { - t.Helper() - - c := &gribi.Client{ - DUT: dut, - FIBACK: false, - Persistence: true, - } - - t.Log("Establish gRIBI client connection") - if err := c.Start(t); err != nil { - return err - } - c.BecomeLeader(t) - defer c.Close(t) - - t.Logf("Add an IPv4Entry for %s pointing to ATE port-2 via clientA", ateDstNetCIDR) - c.AddNH(t, nhIndex, atePort2.IPv4, deviations.DefaultNetworkInstance(dut), fluent.InstalledInRIB) - c.AddNHG(t, nhgIndex, map[uint64]uint64{nhIndex: 1}, deviations.DefaultNetworkInstance(dut), fluent.InstalledInRIB) - c.AddIPv4(t, ateDstNetCIDR, nhgIndex, deviations.DefaultNetworkInstance(dut), "", fluent.InstalledInRIB) - - t.Logf("Verify through AFT Telemetry that %s is active", ateDstNetCIDR) - ipv4Path := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Afts().Ipv4Entry(ateDstNetCIDR) - if got, ok := gnmi.Watch(t, dut, ipv4Path.State(), time.Minute, func(val *ygnmi.Value[*oc.NetworkInstance_Afts_Ipv4Entry]) bool { - ipv4Entry, present := val.Val() - return present && ipv4Entry.GetPrefix() == ateDstNetCIDR - }).Await(t); !ok { - return fmt.Errorf("ipv4-entry/state/prefix got %v, want %s", got, ateDstNetCIDR) - } - return nil -} - -func flushRoutes(t *testing.T, dut *ondatra.DUTDevice) error { - t.Helper() - - c := &gribi.Client{ - DUT: dut, - FIBACK: false, - Persistence: true, - } - - t.Log("Establish gRIBI client connection") - if err := c.Start(t); err != nil { - return err - } - defer c.Close(t) - - c.FlushAll(t) - return nil -} - -func TestP4RTDaemonFailure(t *testing.T) { - dut := ondatra.DUT(t, "dut") - - p4rtD, ok := p4rtDaemons[dut.Vendor()] - if !ok { - t.Fatalf("Please add support for vendor %v in var p4rtDaemons", dut.Vendor()) - } - - t.Logf("Configure DUT") - configureDUT(t, dut) - - t.Logf("Configure ATE") - ate := ondatra.ATE(t, "ate") - top := configureATE(t, ate) - top.Push(t).StartProtocols(t) - - if err := installRoutes(t, dut); err != nil { - t.Fatalf("Could not install routes to DUT: %v", err) - } - defer func() { - if err := flushRoutes(t, dut); err != nil { - t.Errorf("Could not flush routes to DUT: %v", err) - } - }() - - flow := startTraffic(t, ate, top) - - pID, err := pidByName(t, dut, p4rtD) - if err != nil { - t.Fatal(err) - } - - c := dut.RawAPIs().GNOI(t) - req := &syspb.KillProcessRequest{ - Name: p4rtD, - Pid: uint32(pID), - Signal: syspb.KillProcessRequest_SIGNAL_TERM, - Restart: true, - } - resp, err := c.System().KillProcess(context.Background(), req) - t.Logf("Got kill process response: %v", resp) - if err != nil { - t.Fatalf("Failed to execute gNOI.KillProcess, error received: %v", err) - } - - // let traffic keep running for another 10 seconds. - time.Sleep(10 * time.Second) - - ate.Traffic().Stop(t) - - if got := gnmi.Get(t, ate, gnmi.OC().Flow(flow.Name()).LossPct().State()); got > lossTolerance { - t.Errorf("FAIL: LossPct for %s got: %f, want: 0", flow.Name(), got) - } -} diff --git a/feature/experimental/p4rt/ate_tests/performance_test/README.md b/feature/experimental/p4rt/ate_tests/performance_test/README.md deleted file mode 100644 index 470f6c467be..00000000000 --- a/feature/experimental/p4rt/ate_tests/performance_test/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# P4RT-6.1: Required Packet I/O rate: Performance - - -## Summary - -Verify that both Packetin and Packetout traffic is handled by the P4RT server at the required rate. - - -## Procedure - -* Connect ATE port-1 to DUT port-1, ATE port-2 to DUT port-2. -* Enable the P4RT server on the device. -* Connect a P4RT client and configure the forwarding pipeline. InstallP4RT table entries required for traceroute, GDP and LLDP. -* Setup packetin GDP, LLDP and traceroute traffic from the ATE at the rate 200kbps, 100kbps and 324 pps respectively. -* Setup packetout packets for GDP, LLDP and traceroute from the P4RT client. -* Start both packetin and packetout traffic at the same rate simultaneously. -* Verify no packetloss for both directions of traffic. -* Verify the metadata ID and the value for all three traffic types on the P4RT client for packetin. - - -## Config Parameter coverage - -* /components/component/integrated-circuit/config/node-id -* /interfaces/interface/config/id - - -## Telemetry Parameter coverage - -No new telemetry covered. - - -## Protocol/RPC Parameter coverage - -No new Protocol/RPC covered. - diff --git a/feature/experimental/p4rt/ate_tests/performance_test/metadata.textproto b/feature/experimental/p4rt/ate_tests/performance_test/metadata.textproto deleted file mode 100644 index f7df4805b49..00000000000 --- a/feature/experimental/p4rt/ate_tests/performance_test/metadata.textproto +++ /dev/null @@ -1,27 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "44fb709e-fc15-4285-94cf-cb6b9dc19d1a" -plan_id: "P4RT-6.1" -description: "Required Packet I/O rate: Performance" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_port_speed: true - explicit_interface_in_default_vrf: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - gribi_mac_override_static_arp_static_route: true - interface_enabled: true - default_network_instance: "default" - } -} diff --git a/feature/experimental/p4rt/ate_tests/performance_test/performance_test.go b/feature/experimental/p4rt/ate_tests/performance_test/performance_test.go deleted file mode 100644 index 703d1863e7a..00000000000 --- a/feature/experimental/p4rt/ate_tests/performance_test/performance_test.go +++ /dev/null @@ -1,933 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package performance_test - -import ( - "errors" - "fmt" - "net" - "sort" - "strings" - "sync" - "testing" - "time" - - "flag" - - "github.com/cisco-open/go-p4/p4rt_client" - "github.com/cisco-open/go-p4/utils" - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "github.com/openconfig/featureprofiles/feature/experimental/p4rt/internal/p4rtutils" - "github.com/openconfig/featureprofiles/internal/attrs" - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygot/ygot" - p4v1pb "github.com/p4lang/p4runtime/go/p4/v1" -) - -const ( - deviceID = uint64(1) - portID = uint32(10) - electionID = uint64(100) - metadataIngressPort = uint32(1) - metadataEgressPort = uint32(2) - duration = uint32(20) // Sleep duration after starting ATE traffic. - gdpBitRate = uint64(200000) - lldpBitRate = uint64(100000) - trPacketRate = uint64(324) - packetInPktsize = uint32(300) - ipv4PrefixLen = uint8(30) - ipv6PrefixLen = uint8(126) - packetOutWait = time.Duration(77 * time.Second) // Wait for the ATE traffic start, so both packetin and packetout hits DUT simultaneously. - packetCount = int(2000) -) - -var ( - p4InfoFile = flag.String("p4info_file_location", "../../wbb.p4info.pb.txt", "Path to the p4info file.") - streamName = "p4rt" - pktInSrcMAC = "00:02:00:03:00:04" - pktOutSrcMAC = "00:01:00:02:00:03" - lldpInDstMAC = "01:80:c2:00:00:0e" - lldpOutDstMAC = "01:80:c3:00:00:0e" - gdpInDstMAC = "00:0a:da:f0:f0:f0" - gdpOutDstMAC = "00:0a:db:f0:f0:f0" - tracerouteOutDstMAC = "02:F6:65:64:00:08" - ttl1 = uint8(1) - hopLimit1 = uint8(1) - gdpEthType layers.EthernetType = 0x6007 - lldpEthType layers.EthernetType = layers.EthernetTypeLinkLayerDiscovery - tracerouteEthType layers.EthernetType = layers.EthernetTypeIPv4 - - dutPort1 = attrs.Attributes{ - Desc: "dutPort1", - IPv4: "192.0.2.1", - IPv6: "2001:db8::1", - IPv4Len: ipv4PrefixLen, - IPv6Len: ipv6PrefixLen, - } - - atePort1 = attrs.Attributes{ - Name: "atePort1", - IPv4: "192.0.2.2", - IPv6: "2001:db8::2", - IPv4Len: ipv4PrefixLen, - IPv6Len: ipv6PrefixLen, - } - - dutPort2 = attrs.Attributes{ - Desc: "dutPort2", - IPv4: "192.0.2.5", - IPv6: "2001:db8::5", - IPv4Len: ipv4PrefixLen, - IPv6Len: ipv6PrefixLen, - } - - atePort2 = attrs.Attributes{ - Name: "atePort2", - IPv4: "192.0.2.6", - IPv6: "2001:db8::6", - IPv4Len: ipv4PrefixLen, - IPv6Len: ipv6PrefixLen, - } -) - -type testArgs struct { - leader *p4rt_client.P4RTClient - dut *ondatra.DUTDevice - ate *ondatra.ATEDevice - top *ondatra.ATETopology - gdpPacketIO PacketIO - lldpPacketIO PacketIO - trPacketIO PacketIO -} - -type PacketIOPacket struct { - TTL *uint8 - SrcMAC, DstMAC *string - EthernetType *uint32 - HopLimit *uint8 -} - -type PacketIO interface { - GetPacketTemplate() *PacketIOPacket - GetEgressPort() string - GetIngressPort() string -} - -type LLDPPacketIO struct { - PacketIOPacket - IngressPort string -} - -type GDPPacketIO struct { - PacketIOPacket - IngressPort string -} - -type TraceroutePacketIO struct { - PacketIOPacket - IngressPort string - EgressPort string -} - -// programTableEntry programs or deletes p4rt table entry based on delete flag. -func programTableEntry(client *p4rt_client.P4RTClient, delete bool) error { - updateType := p4v1pb.Update_INSERT - if delete { - updateType = p4v1pb.Update_DELETE - } - return client.Write(&p4v1pb.WriteRequest{ - DeviceId: deviceID, - ElectionId: &p4v1pb.Uint128{High: uint64(0), Low: electionID}, - Updates: p4rtutils.ACLWbbIngressTableEntryGet( - newTableEntry(updateType), - ), - Atomicity: p4v1pb.WriteRequest_CONTINUE_ON_ERROR, - }) -} - -// testTraffic sends ATE traffic, stop and collect total packet tx from ATE source port. -func testTraffic(t *testing.T, ate *ondatra.ATEDevice, flows []*ondatra.Flow, srcEndPoint *ondatra.Interface, duration time.Duration) int { - t.Helper() - for _, flow := range flows { - flow.WithSrcEndpoints(srcEndPoint).WithDstEndpoints(srcEndPoint) - } - ate.Traffic().Start(t, flows...) - time.Sleep(duration) - ate.Traffic().Stop(t) - - outPkts := gnmi.GetAll(t, ate, gnmi.OC().FlowAny().Counters().OutPkts().State()) - total := 0 - for _, count := range outPkts { - total += int(count) - } - return total -} - -// sendPackets GDP/LLDP/Traceroute sends out packets via PacketOut message in StreamChannel. -func sendPackets(t *testing.T, client *p4rt_client.P4RTClient, packet *p4v1pb.PacketOut, packetCount int, delay time.Duration) { - for i := 0; i < packetCount; i++ { - if err := client.StreamChannelSendMsg( - &streamName, &p4v1pb.StreamMessageRequest{ - Update: &p4v1pb.StreamMessageRequest_Packet{ - Packet: packet, - }, - }); err != nil { - t.Errorf("There is error seen in Packet Out. %v, %s", err, err) - } - time.Sleep(delay) - } -} - -// decodeIPPacketTTL decodes L2 header in the packet and returns TTL, packetData[14:0] to remove first 14 bytes of Ethernet header. -func decodeIPPacketTTL(packetData []byte) (uint8, error) { - packet := gopacket.NewPacket(packetData, layers.LayerTypeEthernet, gopacket.Default) - etherHeader := packet.Layer(layers.LayerTypeEthernet) - if etherHeader == nil { - return 0, errors.New("not an Ethernet packet") - } - header, ok := etherHeader.(*layers.Ethernet) - if !ok || header.EthernetType != tracerouteEthType { - return 0, errors.New("not a Traceroute packet") - } - packet1 := gopacket.NewPacket(packetData[14:], layers.LayerTypeIPv4, gopacket.Default) - if ipv4 := packet1.Layer(layers.LayerTypeIPv4); ipv4 != nil { - return ipv4.(*layers.IPv4).TTL, nil - } - return 0, errors.New("not an Traceroute IPv4 packet") -} - -// decodeL2Packet decodes L2 header in the packet and returns source MAC, destination MAC and ethernet type. -func decodeL2Packet(packetData []byte) (string, string, layers.EthernetType) { - packet := gopacket.NewPacket(packetData, layers.LayerTypeEthernet, gopacket.Default) - etherHeader := packet.Layer(layers.LayerTypeEthernet) - if etherHeader != nil { - header, ok := etherHeader.(*layers.Ethernet) - if header.EthernetType == lldpEthType || header.EthernetType == gdpEthType || header.EthernetType == tracerouteEthType { - if ok { - return header.SrcMAC.String(), header.DstMAC.String(), header.EthernetType - } - } - } - return "", "", layers.EthernetType(0) -} - -// testPktinPktout sends out packetout and packetin traffic together simultaneously. -func testPktInPktOut(t *testing.T, args *testArgs) { - - // Insert wbb acl entry on the DUT - if err := programTableEntry(args.leader, false); err != nil { - t.Fatalf("There is error when programming entry") - } - // Delete wbb acl entry on the device - defer programTableEntry(args.leader, true) - - t.Run("PacketOut and Packetin traffic tests", func(t *testing.T) { - // Check initial packet counters - port := sortPorts(args.ate.Ports())[0].Name() - counter0 := gnmi.Get(t, args.ate, gnmi.OC().Interface(port).Counters().InPkts().State()) - - packets, err := newPacketOut(portID) - if err != nil { - t.Fatalf("Unexpected error creating packet out packets: %v", err) - } - srcEndPoint := args.top.Interfaces()[atePort1.Name] - streamChan := args.leader.StreamChannelGet(&streamName) - - qSize := 12000 - streamChan.SetArbQSize(qSize) - qSizeRead := streamChan.GetArbQSize() - if qSize != qSizeRead { - t.Errorf("Stream '%s' expecting Arbitration qSize(%d) Got (%d)", - streamName, qSize, qSizeRead) - } - - streamChan.SetPacketQSize(qSize) - qSizeRead = streamChan.GetPacketQSize() - if qSize != qSizeRead { - t.Errorf("Stream '%s' expecting Packet qSize(%d) Got (%d)", - streamName, qSize, qSizeRead) - } - // Create the flows for Packetin. - flows := newTrafficFlow(args.ate) - pktIn := 0 - // Run Packetin and packetout traffic in parallel. - var wg sync.WaitGroup - wg.Add(4) - - go func() { - defer wg.Done() - pktIn = testTraffic(t, args.ate, flows, srcEndPoint, 20*time.Second) - t.Logf("Total Packetin packets sent from ATE %v", pktIn) - }() - - go func() { - defer wg.Done() - time.Sleep(packetOutWait) - // GDP packetout with 2.6ms timer. - sendPackets(t, args.leader, packets[0], packetCount, 2600*time.Microsecond) - }() - - go func() { - defer wg.Done() - time.Sleep(packetOutWait) - // Traceroute packetout with 3.1ms timer. - sendPackets(t, args.leader, packets[1], packetCount, 3100*time.Microsecond) - }() - - go func() { - defer wg.Done() - time.Sleep(packetOutWait) - // LLDP packetout with 5.1ms timer. - sendPackets(t, args.leader, packets[2], packetCount, 5100*time.Microsecond) - }() - - wg.Wait() // Wait for all four goroutines to finish before exiting. - - // Wait for the packetOut requests to be completed on the server side - time.Sleep(1 * time.Minute) - - // Check packet counters after packet out - time.Sleep(3 * time.Second) - counter1 := gnmi.Get(t, args.ate, gnmi.OC().Interface(port).Counters().InPkts().State()) - - // Verify Packetout stats to check P4RT stream - t.Logf("Received %v packetout on ATE port %s", counter1-counter0, port) - - if (counter1 - counter0) < uint64(float32(3*packetCount)*0.95) { - t.Errorf("Number of Packetout packets, got: %d, want: %d", counter1-counter0, (3 * packetCount)) - } - _, packetinPackets, err := args.leader.StreamChannelGetPackets(&streamName, uint64(pktIn), 30*time.Second) - if err != nil { - t.Errorf("Unexpected error on StreamChannelGetPackets: %v", err) - } - - t.Logf("Start to decode packetin and compare with expected packets.") - wantgdpPacket := args.gdpPacketIO.GetPacketTemplate() - wantlldpPacket := args.lldpPacketIO.GetPacketTemplate() - wanttrPacket := args.trPacketIO.GetPacketTemplate() - - gdpIncount := 0 - lldpIncount := 0 - trIncount := 0 - - for _, packet := range packetinPackets { - if packet != nil { - srcMAC, dstMac, etherType := decodeL2Packet(packet.Pkt.GetPayload()) - if !strings.EqualFold(srcMAC, pktInSrcMAC) { - continue - } - ttl, _ := decodeIPPacketTTL(packet.Pkt.GetPayload()) - - metaData := packet.Pkt.GetMetadata() - if wantgdpPacket.EthernetType != nil { - if etherType == layers.EthernetType(*wantgdpPacket.EthernetType) { - if dstMac == *wantgdpPacket.DstMAC { - for _, data := range metaData { - switch data.GetMetadataId() { - case metadataIngressPort: - if string(data.GetValue()) != args.gdpPacketIO.GetIngressPort() { - t.Fatalf("Ingress Port Id is not matching expectation for GDP.") - } - case metadataEgressPort: - portData := args.gdpPacketIO.GetEgressPort() - if string(data.GetValue()) != portData { - t.Fatalf("Egress Port Id is not matching expectation for GDP.") - } - default: - t.Fatalf("Missing packet metadata for GDP PacketIn") - } - } - gdpIncount++ - } - } - } - if wantlldpPacket.EthernetType != nil { - if etherType == layers.EthernetType(*wantlldpPacket.EthernetType) { - if dstMac == *wantlldpPacket.DstMAC { - for _, data := range metaData { - switch data.GetMetadataId() { - case metadataIngressPort: - if string(data.GetValue()) != args.lldpPacketIO.GetIngressPort() { - t.Fatalf("Ingress Port Id is not matching expectation for LLDP.") - } - case metadataEgressPort: - portData := args.lldpPacketIO.GetEgressPort() - if string(data.GetValue()) != portData { - t.Fatalf("Egress Port Id is not matching expectation for LLDP.") - } - default: - t.Fatalf("Missing packet metadata for LLDP PacketIn") - } - } - lldpIncount++ - } - } - } - if wanttrPacket.TTL != nil { - if ttl == 1 { - //Metadata comparision - if metaData := packet.Pkt.GetMetadata(); metaData != nil { - if got := metaData[0].GetMetadataId(); got == metadataIngressPort { - if gotPortID := string(metaData[0].GetValue()); gotPortID != args.trPacketIO.GetIngressPort() { - t.Fatalf("Ingress Port Id mismatch: want %s, got %s", args.trPacketIO.GetIngressPort(), gotPortID) - } - } else { - t.Fatalf("Metadata ingress port mismatch: want %d, got %d", metadataIngressPort, got) - } - if got := metaData[1].GetMetadataId(); got == metadataEgressPort { - if gotPortID := string(metaData[1].GetValue()); gotPortID != args.trPacketIO.GetEgressPort() { - t.Fatalf("Egress Port Id mismatch: want %s, got %s", args.trPacketIO.GetEgressPort(), gotPortID) - } - } else { - t.Fatalf("Metadata egress port mismatch: want %d, got %d", metadataEgressPort, got) - } - } else { - t.Fatalf("Packet missing metadata information for traceroute") - } - trIncount++ - } - } - } - } - if got, want := (gdpIncount + lldpIncount + trIncount), pktIn; float32(got) < (0.95 * float32(want)) { - t.Errorf("Number of PacketIn, got: %d, want: %d", got, want) - } - }) -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// sortPorts sorts the ports by the testbed port ID. -func sortPorts(ports []*ondatra.Port) []*ondatra.Port { - sort.Slice(ports, func(i, j int) bool { - idi, idj := ports[i].ID(), ports[j].ID() - li, lj := len(idi), len(idj) - if li == lj { - return idi < idj - } - return li < lj // "port2" < "port10" - }) - return ports -} - -// configInterfaceDUT configures the interface with the IP Addresses. -func configInterfaceDUT(i *oc.Interface, a *attrs.Attributes, dut *ondatra.DUTDevice) *oc.Interface { - i.Description = ygot.String(a.Desc) - i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd - if deviations.InterfaceEnabled(dut) { - i.Enabled = ygot.Bool(true) - } - s := i.GetOrCreateSubinterface(0) - s4 := s.GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) { - s4.Enabled = ygot.Bool(true) - } - s4a := s4.GetOrCreateAddress(a.IPv4) - s4a.PrefixLength = ygot.Uint8(ipv4PrefixLen) - - s6 := s.GetOrCreateIpv6() - if deviations.InterfaceEnabled(dut) { - s6.Enabled = ygot.Bool(true) - } - s6.GetOrCreateAddress(a.IPv6).PrefixLength = ygot.Uint8(ipv6PrefixLen) - - return i -} - -// configureDUT configures port1 and port2 on the DUT. -func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { - d := gnmi.OC() - - p1 := dut.Port(t, "port1") - i1 := &oc.Interface{Name: ygot.String(p1.Name()), Id: ygot.Uint32(portID)} - gnmi.Replace(t, dut, d.Interface(p1.Name()).Config(), configInterfaceDUT(i1, &dutPort1, dut)) - - p2 := dut.Port(t, "port2") - i2 := &oc.Interface{Name: ygot.String(p2.Name()), Id: ygot.Uint32(portID + 1)} - gnmi.Replace(t, dut, d.Interface(p2.Name()).Config(), configInterfaceDUT(i2, &dutPort2, dut)) - - if deviations.ExplicitPortSpeed(dut) { - fptest.SetPortSpeed(t, p1) - fptest.SetPortSpeed(t, p2) - } - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - fptest.AssignToNetworkInstance(t, dut, p1.Name(), deviations.DefaultNetworkInstance(dut), 0) - fptest.AssignToNetworkInstance(t, dut, p2.Name(), deviations.DefaultNetworkInstance(dut), 0) - } - gnmi.Replace(t, dut, gnmi.OC().Lldp().Enabled().Config(), false) - - if deviations.GRIBIMACOverrideStaticARPStaticRoute(dut) { - gnmi.Replace(t, dut, gnmi.OC().System().MacAddress().RoutingMac().Config(), tracerouteOutDstMAC) - } -} - -// configureATE configures port1 and port2 on the ATE. -func configureATE(t *testing.T, ate *ondatra.ATEDevice) *ondatra.ATETopology { - top := ate.Topology().New() - - p1 := ate.Port(t, "port1") - i1 := top.AddInterface(atePort1.Name).WithPort(p1) - i1.IPv4(). - WithAddress(atePort1.IPv4CIDR()). - WithDefaultGateway(dutPort1.IPv4) - i1.IPv6(). - WithAddress(atePort1.IPv6CIDR()). - WithDefaultGateway(dutPort1.IPv6) - - p2 := ate.Port(t, "port2") - i2 := top.AddInterface(atePort2.Name).WithPort(p2) - i2.IPv4(). - WithAddress(atePort2.IPv4CIDR()). - WithDefaultGateway(dutPort2.IPv4) - i2.IPv6(). - WithAddress(atePort2.IPv6CIDR()). - WithDefaultGateway(dutPort2.IPv6) - - return top -} - -// configureDeviceIDs configures p4rt device-id on the DUT. -func configureDeviceID(t *testing.T, dut *ondatra.DUTDevice) { - nodes := p4rtutils.P4RTNodesByPort(t, dut) - p4rtNode, ok := nodes["port1"] - if !ok { - t.Fatal("Couldn't find P4RT Node for port: port1") - } - t.Logf("Configuring P4RT Node: %s", p4rtNode) - c := oc.Component{} - c.Name = ygot.String(p4rtNode) - c.IntegratedCircuit = &oc.Component_IntegratedCircuit{} - c.IntegratedCircuit.NodeId = ygot.Uint64(deviceID) - gnmi.Replace(t, dut, gnmi.OC().Component(p4rtNode).Config(), &c) -} - -// setupP4RTClient sends client arbitration message for the leader client, -// then sends setforwordingpipelineconfig config. -func setupP4RTClient(args *testArgs) error { - // Setup p4rt-client stream parameters. - streamParameter := p4rt_client.P4RTStreamParameters{ - Name: streamName, - DeviceId: deviceID, - ElectionIdH: uint64(0), - ElectionIdL: electionID, - } - - // Send ClientArbitration message from the leader client. - clients := []*p4rt_client.P4RTClient{args.leader} - for index, client := range clients { - if client != nil { - client.StreamChannelCreate(&streamParameter) - if err := client.StreamChannelSendMsg(&streamName, &p4v1pb.StreamMessageRequest{ - Update: &p4v1pb.StreamMessageRequest_Arbitration{ - Arbitration: &p4v1pb.MasterArbitrationUpdate{ - DeviceId: streamParameter.DeviceId, - ElectionId: &p4v1pb.Uint128{ - High: streamParameter.ElectionIdH, - Low: streamParameter.ElectionIdL - uint64(index), - }, - }, - }, - }); err != nil { - return fmt.Errorf("errors seen when sending ClientArbitration message: %v", err) - } - if _, _, arbErr := client.StreamChannelGetArbitrationResp(&streamName, 1); arbErr != nil { - if err := p4rtutils.StreamTermErr(client.StreamTermErr); err != nil { - return err - } - return fmt.Errorf("errors seen in ClientArbitration response: %v", arbErr) - } - } - } - - // Load p4info file. - p4Info, err := utils.P4InfoLoad(p4InfoFile) - if err != nil { - return errors.New("errors seen when loading p4info file") - } - - // Send SetForwardingPipelineConfig for p4rt leader client. - if err := args.leader.SetForwardingPipelineConfig(&p4v1pb.SetForwardingPipelineConfigRequest{ - DeviceId: deviceID, - ElectionId: &p4v1pb.Uint128{High: uint64(0), Low: electionID}, - Action: p4v1pb.SetForwardingPipelineConfigRequest_VERIFY_AND_COMMIT, - Config: &p4v1pb.ForwardingPipelineConfig{ - P4Info: p4Info, - Cookie: &p4v1pb.ForwardingPipelineConfig_Cookie{ - Cookie: 159, - }, - }, - }); err != nil { - return errors.New("errors seen when sending SetForwardingPipelineConfig") - } - return nil -} - -// gdpParameter returns GDP related parameters for testPacketOut testcase. -func gdpParameter() PacketIO { - ethType := uint32(gdpEthType) - return &GDPPacketIO{ - PacketIOPacket: PacketIOPacket{ - SrcMAC: &pktInSrcMAC, - DstMAC: &gdpInDstMAC, - EthernetType: ðType, - }, - IngressPort: fmt.Sprint(portID), - } -} - -// tracerouteParameter returns Traceroute related parameters for testPacketIn testcase. -func tracerouteParameter() PacketIO { - return &TraceroutePacketIO{ - PacketIOPacket: PacketIOPacket{ - TTL: &ttl1, - HopLimit: &hopLimit1, - }, - IngressPort: fmt.Sprint(portID), - EgressPort: fmt.Sprint(portID + 1), - } -} - -// lldpParameter returns LLDP related parameters for testPacketIn testcase. -func lldpParameter() PacketIO { - ethType := uint32(lldpEthType) - return &LLDPPacketIO{ - PacketIOPacket: PacketIOPacket{ - SrcMAC: &pktInSrcMAC, - DstMAC: &lldpInDstMAC, - EthernetType: ðType, - }, - IngressPort: fmt.Sprint(portID), - } -} - -func TestP4rtPerformance(t *testing.T) { - dut := ondatra.DUT(t, "dut") - configureDUT(t, dut) - - // Configure the ATE - ate := ondatra.ATE(t, "ate") - top := configureATE(t, ate) - top.Push(t).StartProtocols(t) - - // Configure P4RT device-id - configureDeviceID(t, dut) - - leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { - t.Fatalf("Could not initialize p4rt client: %v", err) - } - - args := &testArgs{ - leader: leader, - dut: dut, - ate: ate, - top: top, - } - - if err := setupP4RTClient(args); err != nil { - t.Fatalf("Could not setup p4rt client: %v", err) - } - args.gdpPacketIO = gdpParameter() - args.lldpPacketIO = lldpParameter() - args.trPacketIO = tracerouteParameter() - testPktInPktOut(t, args) -} - -// packetGDPRequestGet generates PacketOut payload for GDP packets. -func packetGDPRequestGet() ([]byte, error) { - buf := gopacket.NewSerializeBuffer() - opts := gopacket.SerializeOptions{ - FixLengths: true, - ComputeChecksums: true, - } - srcMAC, err := net.ParseMAC(pktOutSrcMAC) - if err != nil { - return nil, err - } - dstMAC, err := net.ParseMAC(gdpOutDstMAC) - if err != nil { - return nil, err - } - pktEth := &layers.Ethernet{ - SrcMAC: srcMAC, - DstMAC: dstMAC, - EthernetType: gdpEthType, - } - var payload []byte - payLoadLen := 64 - for i := 0; i < payLoadLen; i++ { - payload = append(payload, byte(i)) - } - gopacket.SerializeLayers(buf, opts, - pktEth, gopacket.Payload(payload), - ) - return buf.Bytes(), nil -} - -// packetTracerouteRequestGet generates PacketOut payload for Traceroute packets. -func packetTracerouteRequestGet(ttl uint8, seq int) ([]byte, error) { - buf := gopacket.NewSerializeBuffer() - opts := gopacket.SerializeOptions{ - FixLengths: true, - ComputeChecksums: true, - } - var payload []byte - payLoadLen := 32 - - ethType := layers.EthernetTypeIPv4 - - srcMAC, err := net.ParseMAC(pktOutSrcMAC) - if err != nil { - return nil, err - } - dstMAC, err := net.ParseMAC(tracerouteOutDstMAC) - if err != nil { - return nil, err - } - pktEth := &layers.Ethernet{ - SrcMAC: srcMAC, - DstMAC: dstMAC, - EthernetType: ethType, - } - - pktIpv4 := &layers.IPv4{ - Version: 4, - TTL: ttl, - SrcIP: net.ParseIP(dutPort1.IPv4).To4(), - DstIP: net.ParseIP(atePort1.IPv4).To4(), - Protocol: layers.IPProtocolICMPv4, - Flags: layers.IPv4DontFragment, - } - pktICMP4 := &layers.ICMPv4{ - TypeCode: layers.CreateICMPv4TypeCode(layers.ICMPv4TypeEchoRequest, 0), - Seq: uint16(seq), - } - - for i := 0; i < payLoadLen; i++ { - payload = append(payload, byte(i)) - } - if err := gopacket.SerializeLayers(buf, opts, - pktEth, pktIpv4, pktICMP4, gopacket.Payload(payload), - ); err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -// packetLLDPRequestGet generates PacketOut payload for LLDP packets. -func packetLLDPRequestGet() ([]byte, error) { - buf := gopacket.NewSerializeBuffer() - opts := gopacket.SerializeOptions{ - FixLengths: true, - ComputeChecksums: true, - } - srcMAC, err := net.ParseMAC(pktOutSrcMAC) - if err != nil { - return nil, err - } - dstMAC, err := net.ParseMAC(lldpOutDstMAC) - if err != nil { - return nil, err - } - pktEth := &layers.Ethernet{ - SrcMAC: srcMAC, - DstMAC: dstMAC, - EthernetType: lldpEthType, - } - - pktLLDP := &layers.LinkLayerDiscovery{ - ChassisID: layers.LLDPChassisID{ - Subtype: layers.LLDPChassisIDSubTypeMACAddr, - ID: []byte{0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, - }, - PortID: layers.LLDPPortID{ - Subtype: layers.LLDPPortIDSubtypeIfaceName, - ID: []byte("port1"), - }, - TTL: 100, - } - - gopacket.SerializeLayers(buf, opts, pktEth, pktLLDP) - return buf.Bytes(), nil -} - -// newTableEntry creates wbb acl entry related to GDP,LLDP and traceroute. -func newTableEntry(actionType p4v1pb.Update_Type) []*p4rtutils.ACLWbbIngressTableEntryInfo { - return []*p4rtutils.ACLWbbIngressTableEntryInfo{ - { - Type: actionType, - EtherType: uint16(gdpEthType), - EtherTypeMask: 0xFFFF, - Priority: 1, - }, - { - Type: actionType, - EtherType: uint16(lldpEthType), - EtherTypeMask: 0xFFFF, - Priority: 1, - }, - { - Type: actionType, - IsIpv4: 0x1, - TTL: 0x1, - TTLMask: 0xFF, - Priority: 1, - }, - { - Type: actionType, - IsIpv6: 0x1, - TTL: 0x1, - TTLMask: 0xFF, - Priority: 1, - }, - } -} - -// newPacketOut generates 3 PacketOut messages with payload as GDP, LLDP and, traceroute. -func newPacketOut(portID uint32) ([]*p4v1pb.PacketOut, error) { - p, err := packetGDPRequestGet() - if err != nil { - return nil, err - } - packet1 := &p4v1pb.PacketOut{ - Payload: p, - Metadata: []*p4v1pb.PacketMetadata{ - { - MetadataId: uint32(1), // "egress_port" - Value: []byte(fmt.Sprint(portID)), - }, - }, - } - - p, err = packetTracerouteRequestGet(2, 1) - if err != nil { - return nil, err - } - - packet2 := &p4v1pb.PacketOut{ - Payload: p, - Metadata: []*p4v1pb.PacketMetadata{ - { - MetadataId: uint32(1), // "egress_port" - Value: []byte("0"), - }, - { - MetadataId: uint32(2), // "submit_to_ingress" - Value: []byte{1}, - }, - { - MetadataId: uint32(3), // "unused_pad" - Value: []byte{0}, - }, - }, - } - - p, err = packetLLDPRequestGet() - if err != nil { - return nil, err - } - packet3 := &p4v1pb.PacketOut{ - Payload: p, - Metadata: []*p4v1pb.PacketMetadata{ - { - MetadataId: uint32(1), // "egress_port" - Value: []byte(fmt.Sprint(portID)), - }, - }, - } - return []*p4v1pb.PacketOut{packet1, packet2, packet3}, nil -} - -// newTrafficFlow generates ATE traffic flows for LLDP. -func newTrafficFlow(ate *ondatra.ATEDevice) []*ondatra.Flow { - ethHeader1 := ondatra.NewEthernetHeader() - ethHeader1.WithSrcAddress(pktInSrcMAC) - ethHeader1.WithDstAddress(lldpInDstMAC) - ethHeader1.WithEtherType(uint32(lldpEthType)) - - // flow1 for LLDP traffic. - flow1 := ate.Traffic().NewFlow("LLDP").WithFrameSize(packetInPktsize).WithFrameRateBPS(lldpBitRate).WithHeaders(ethHeader1) - flow1.Transmission().WithPatternFixedDuration(duration) - - ethHeader2 := ondatra.NewEthernetHeader() - ethHeader2.WithSrcAddress(pktInSrcMAC) - ethHeader2.WithDstAddress(gdpInDstMAC) - ethHeader2.WithEtherType(uint32(gdpEthType)) - - // flow2 for GDP traffic. - flow2 := ate.Traffic().NewFlow("GDP").WithFrameSize(packetInPktsize).WithFrameRateBPS(gdpBitRate).WithHeaders(ethHeader2) - flow2.Transmission().WithPatternFixedDuration(duration) - - ethHeader := ondatra.NewEthernetHeader().WithSrcAddress(pktInSrcMAC) - ipv4Header := ondatra.NewIPv4Header().WithSrcAddress(atePort1.IPv4).WithDstAddress(atePort2.IPv4).WithTTL(ttl1) //ttl=1 is traceroute traffic - - // flow3 for Traceroute traffic. - flow3 := ate.Traffic().NewFlow("IPv4").WithFrameSize(packetInPktsize).WithFrameRateFPS(trPacketRate).WithHeaders(ethHeader, ipv4Header) - flow3.Transmission().WithPatternFixedDuration(duration) - - return []*ondatra.Flow{flow1, flow2, flow3} -} - -// GetEgressPort returns expected egress port info in PacketIn. -func (lldp *LLDPPacketIO) GetEgressPort() string { - return string("0") -} - -// GetIngressPort return expected ingress port info in PacketIn. -func (lldp *LLDPPacketIO) GetIngressPort() string { - return lldp.IngressPort -} - -// GetEgressPort returns expected egress port info in PacketIn. -func (gdp *GDPPacketIO) GetEgressPort() string { - return string("0") -} - -// GetIngressPort return expected ingress port info in PacketIn. -func (gdp *GDPPacketIO) GetIngressPort() string { - return gdp.IngressPort -} - -// GetEgressPort returns expected egress port info in Packetin. -func (traceroute *TraceroutePacketIO) GetEgressPort() string { - return traceroute.EgressPort -} - -// GetIngressPort return expected ingress port info in Packetin. -func (traceroute *TraceroutePacketIO) GetIngressPort() string { - return traceroute.IngressPort -} - -// GetPacketTemplate returns the expected PacketIOPacket for LLDP traffic type. -func (lldp *LLDPPacketIO) GetPacketTemplate() *PacketIOPacket { - return &lldp.PacketIOPacket -} - -// GetPacketTemplate returns the expected PacketIOPacket for GDP traffic type. -func (gdp *GDPPacketIO) GetPacketTemplate() *PacketIOPacket { - return &gdp.PacketIOPacket -} - -// GetPacketTemplate returns the expected PacketIOPacket for traceroute type. -func (traceroute *TraceroutePacketIO) GetPacketTemplate() *PacketIOPacket { - return &traceroute.PacketIOPacket -} diff --git a/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/README.md b/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/README.md deleted file mode 100644 index 8a69af7d868..00000000000 --- a/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# P4RT-5.1: Traceroute: PacketIn - - -## Summary - -Verify that Traceroute packets are punted with correct metadata. - - -## Procedure - -* Connect ATE port-1 to DUT port-1, ATE port-2 to DUT port-2. -* TODO: Install the set of routes on the device. -* Enable the P4RT server on the device. -* Connect a P4RT client and configure the forwarding pipeline. InstallP4RT table entries required for traceroute. -* Send IPv4 packets from the ATE with TTL=1 and verify that packets with TTL=1 are received by the client. -* Send IPv6 packets from the ATE with HopLimit=1 and verify that packets with HopLimit=1 are received by the client. -* Verify that the packets have both ingress_singleton_port and egress_singleton_port metadata set. - - -## Config Parameter coverage - -* /components/component/integrated-circuit/config/node-id -* /interfaces/interface/config/id - - -## Telemetry Parameter coverage - -No new telemetry covered. - - -## Protocol/RPC Parameter coverage - -No new Protocol/RPC covered. - diff --git a/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/metadata.textproto b/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/metadata.textproto deleted file mode 100644 index 740afcff301..00000000000 --- a/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/metadata.textproto +++ /dev/null @@ -1,26 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "5a5491b5-9900-4a05-b289-43feb1ceb814" -plan_id: "P4RT-5.1" -description: "Traceroute: PacketIn" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_port_speed: true - explicit_interface_in_default_vrf: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - interface_enabled: true - default_network_instance: "default" - } -} diff --git a/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/packetin_test.go b/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/packetin_test.go deleted file mode 100644 index 4c93c908c82..00000000000 --- a/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/packetin_test.go +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// package to test P4RT with traceroute traffic of IPV4 and IPV6 with TTL/HopLimit as 0&1. -// go test -v . -testbed /root/ondatra/featureprofiles/topologies/atedut_2.testbed -binding /root/ondatra/featureprofiles/topologies/atedut_2.binding -outputs_dir logs - -package traceroute_packetin_test - -import ( - "context" - "strings" - "testing" - "time" - - "github.com/cisco-open/go-p4/p4rt_client" - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "github.com/openconfig/featureprofiles/feature/experimental/p4rt/internal/p4rtutils" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - p4_v1 "github.com/p4lang/p4runtime/go/p4/v1" -) - -type PacketIO interface { - GetTableEntry(delete bool, isIPv4 bool) []*p4rtutils.ACLWbbIngressTableEntryInfo - GetPacketTemplate() *PacketIOPacket - GetTrafficFlow(ate *ondatra.ATEDevice, isIPv4 bool, TTL uint8, frameSize uint32, frameRate uint64) []*ondatra.Flow - GetEgressPort() string - GetIngressPort() string -} - -type PacketIOPacket struct { - TTL *uint8 - SrcMAC, DstMAC *string - EthernetType *uint32 - HopLimit *uint8 -} - -type testArgs struct { - ctx context.Context - leader *p4rt_client.P4RTClient - follower *p4rt_client.P4RTClient - dut *ondatra.DUTDevice - ate *ondatra.ATEDevice - top *ondatra.ATETopology - packetIO PacketIO -} - -// programmTableEntry programs or deletes p4rt table entry based on delete flag. -func programmTableEntry(client *p4rt_client.P4RTClient, packetIO PacketIO, delete bool, isIPv4 bool) error { - err := client.Write(&p4_v1.WriteRequest{ - DeviceId: deviceID, - ElectionId: &p4_v1.Uint128{High: uint64(0), Low: electionId}, - Updates: p4rtutils.ACLWbbIngressTableEntryGet( - packetIO.GetTableEntry(delete, isIPv4), - ), - Atomicity: p4_v1.WriteRequest_CONTINUE_ON_ERROR, - }) - return err -} - -// decodePacket decodes L2 header in the packet and returns source and destination MAC and ethernet type. -func decodePacket(t *testing.T, packetData []byte) (string, string, layers.EthernetType) { - t.Helper() - packet := gopacket.NewPacket(packetData, layers.LayerTypeEthernet, gopacket.Default) - etherHeader := packet.Layer(layers.LayerTypeEthernet) - if etherHeader != nil { - header, decoded := etherHeader.(*layers.Ethernet) - if decoded { - return header.SrcMAC.String(), header.DstMAC.String(), header.EthernetType - } - } - return "", "", layers.EthernetType(0) -} - -// decodePacket decodes L2 header in the packet and returns TTL. packetData[14:0] to remove first 14 bytes of Ethernet header. -func decodePacket4(t *testing.T, packetData []byte) uint8 { - t.Helper() - packet := gopacket.NewPacket(packetData[14:], layers.LayerTypeIPv4, gopacket.Default) - if IPv4 := packet.Layer(layers.LayerTypeIPv4); IPv4 != nil { - ipv4, _ := IPv4.(*layers.IPv4) - IPv4 := ipv4.TTL - return IPv4 - } - return 7 -} - -// decodePacket decodes IPV6 L2 header in the packet and returns HopLimit. packetData[14:] to remove first 14 bytes of Ethernet header. -func decodePacket6(t *testing.T, packetData []byte) uint8 { - t.Helper() - packet := gopacket.NewPacket(packetData[14:], layers.LayerTypeIPv6, gopacket.Default) - if IPv6 := packet.Layer(layers.LayerTypeIPv6); IPv6 != nil { - ipv6, _ := IPv6.(*layers.IPv6) - IPv6 := ipv6.HopLimit - return IPv6 - } - return 7 -} - -// testTraffic sends traffic flow for duration seconds and returns the -// number of packets sent out. -func testTraffic(t *testing.T, ate *ondatra.ATEDevice, flows []*ondatra.Flow, srcEndPoint *ondatra.Interface, duration int) int { - t.Helper() - for _, flow := range flows { - flow.WithSrcEndpoints(srcEndPoint).WithDstEndpoints(srcEndPoint) - } - ate.Traffic().Start(t, flows...) - time.Sleep(time.Duration(duration) * time.Second) - ate.Traffic().Stop(t) - - outPkts := gnmi.GetAll(t, ate, gnmi.OC().FlowAny().Counters().OutPkts().State()) - total := 0 - for _, count := range outPkts { - total += int(count) - } - return total -} - -// testPacketIn programs p4rt table entry and sends traffic related to Traceroute, -// then validates packetin message metadata and payload. -func testPacketIn(ctx context.Context, t *testing.T, args *testArgs, isIPv4 bool) { - leader := args.leader - follower := args.follower - - if isIPv4 { - // Insert p4rtutils acl entry on the DUT - if err := programmTableEntry(leader, args.packetIO, false, isIPv4); err != nil { - t.Fatalf("There is error when programming entry") - } - // Delete p4rtutils acl entry on the device - defer programmTableEntry(leader, args.packetIO, true, isIPv4) - } else { - // Insert p4rtutils acl entry on the DUT - if err := programmTableEntry(leader, args.packetIO, false, false); err != nil { - t.Fatalf("There is error when programming entry") - } - // Delete p4rtutils acl entry on the device - defer programmTableEntry(leader, args.packetIO, true, false) - } - - // Send Traceroute traffic from ATE - srcEndPoint := args.top.Interfaces()[atePort1.Name] - pktOut := testTraffic(t, args.ate, args.packetIO.GetTrafficFlow(args.ate, isIPv4, 1, 300, 2), srcEndPoint, 10) - packetInTests := []struct { - desc string - client *p4rt_client.P4RTClient - wantPkts int - }{{ - desc: "PacketIn to Primary Controller", - client: leader, - wantPkts: pktOut, - }, { - desc: "PacketIn to Secondary Controller", - client: follower, - wantPkts: 0, - }} - - t.Log("TTL/HopLimit 1") - for _, test := range packetInTests { - t.Run(test.desc, func(t *testing.T) { - // Extract packets from PacketIn message sent to p4rt client - _, packets, err := test.client.StreamChannelGetPackets(&streamName, uint64(test.wantPkts), 30*time.Second) - if err != nil { - t.Errorf("Unexpected error on fetchPackets: %v", err) - } - - if test.wantPkts == 0 { - return - } - - gotPkts := 0 - t.Logf("Start to decode packet and compare with expected packets.") - wantPacket := args.packetIO.GetPacketTemplate() - for _, packet := range packets { - if packet != nil { - - srcMAC, _, etherType := decodePacket(t, packet.Pkt.GetPayload()) - if etherType != layers.EthernetTypeIPv4 && etherType != layers.EthernetTypeIPv6 { - continue - } - if !strings.EqualFold(srcMAC, tracerouteSrcMAC) { - continue - } - if wantPacket.TTL != nil { - //TTL/HopLimit comparison for IPV4 & IPV6 - if isIPv4 { - captureTTL := decodePacket4(t, packet.Pkt.GetPayload()) - if captureTTL != TTL1 { - t.Fatalf("Packet in PacketIn message is not matching wanted packet=IPV4 TTL1") - } - - } else { - captureHopLimit := decodePacket6(t, packet.Pkt.GetPayload()) - if captureHopLimit != HopLimit1 { - t.Fatalf("Packet in PacketIn message is not matching wanted packet=IPV6 HopLimit1") - } - } - } - - //Metadata comparision - if metaData := packet.Pkt.GetMetadata(); metaData != nil { - if got := metaData[0].GetMetadataId(); got == METADATA_INGRESS_PORT { - if gotPortID := string(metaData[0].GetValue()); gotPortID != args.packetIO.GetIngressPort() { - t.Fatalf("Ingress Port Id mismatch: want %s, got %s", args.packetIO.GetIngressPort(), gotPortID) - } - } else { - t.Fatalf("Metadata ingress port mismatch: want %d, got %d", METADATA_INGRESS_PORT, got) - } - - if got := metaData[1].GetMetadataId(); got == METADATA_EGRESS_PORT { - if gotPortID := string(metaData[1].GetValue()); gotPortID != args.packetIO.GetEgressPort() { - t.Fatalf("Egress Port Id mismatch: want %s, got %s", args.packetIO.GetEgressPort(), gotPortID) - } - } else { - t.Fatalf("Metadata egress port mismatch: want %d, got %d", METADATA_EGRESS_PORT, got) - } - } else { - t.Fatalf("Packet missing metadata information.") - } - gotPkts++ - } - } - if got, want := gotPkts, test.wantPkts; got != want { - t.Errorf("Number of PacketIn, got: %d, want: %d", got, want) - } - }) - } -} diff --git a/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/traceroute_packetin_test.go b/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/traceroute_packetin_test.go deleted file mode 100644 index 4312320a864..00000000000 --- a/feature/experimental/p4rt/ate_tests/traceroute_packetin_test/traceroute_packetin_test.go +++ /dev/null @@ -1,374 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// package to test P4RT with traceroute traffic of IPV4 and IPV6 with TTL/HopLimit as 0&1. -// go test -v . -testbed /root/ondatra/featureprofiles/topologies/atedut_2.testbed -binding /root/ondatra/featureprofiles/topologies/atedut_2.binding -outputs_dir logs - -package traceroute_packetin_test - -import ( - "context" - "errors" - "fmt" - "testing" - - "flag" - - "github.com/cisco-open/go-p4/p4rt_client" - "github.com/cisco-open/go-p4/utils" - "github.com/openconfig/featureprofiles/feature/experimental/p4rt/internal/p4rtutils" - "github.com/openconfig/featureprofiles/internal/attrs" - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygot/ygot" - p4_v1 "github.com/p4lang/p4runtime/go/p4/v1" -) - -var ( - p4InfoFile = flag.String("p4info_file_location", "../../wbb.p4info.pb.txt", "Path to the p4info file.") - streamName = "p4rt" - tracerouteSrcMAC = "00:01:00:02:00:03" - deviceID = uint64(1) - portId = uint32(10) - electionId = uint64(100) - METADATA_INGRESS_PORT = uint32(1) - METADATA_EGRESS_PORT = uint32(2) - TTL1 = uint8(1) - HopLimit1 = uint8(1) - TTL0 = uint8(0) - HopLimit0 = uint8(0) - ipv4PrefixLen = uint8(30) - ipv6PrefixLen = uint8(126) -) - -var ( - dutPort1 = attrs.Attributes{ - Desc: "dutPort1", - IPv4: "192.0.2.1", - IPv6: "2001:db8::1", - IPv4Len: ipv4PrefixLen, - IPv6Len: ipv6PrefixLen, - } - - atePort1 = attrs.Attributes{ - Name: "atePort1", - IPv4: "192.0.2.2", - IPv6: "2001:db8::2", - IPv4Len: ipv4PrefixLen, - IPv6Len: ipv6PrefixLen, - } - - dutPort2 = attrs.Attributes{ - Desc: "dutPort2", - IPv4: "192.0.2.5", - IPv6: "2001:db8::5", - IPv4Len: ipv4PrefixLen, - IPv6Len: ipv6PrefixLen, - } - - atePort2 = attrs.Attributes{ - Name: "atePort2", - IPv4: "192.0.2.6", - IPv6: "2001:db8::6", - IPv4Len: ipv4PrefixLen, - IPv6Len: ipv6PrefixLen, - } -) - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// configInterfaceDUT configures the interface with the Addrs. -func configInterfaceDUT(i *oc.Interface, a *attrs.Attributes, dut *ondatra.DUTDevice) *oc.Interface { - i.Description = ygot.String(a.Desc) - i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd - if deviations.InterfaceEnabled(dut) { - i.Enabled = ygot.Bool(true) - } - - s := i.GetOrCreateSubinterface(0) - s4 := s.GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) { - s4.Enabled = ygot.Bool(true) - } - s4a := s4.GetOrCreateAddress(a.IPv4) - s4a.PrefixLength = ygot.Uint8(ipv4PrefixLen) - - s6 := s.GetOrCreateIpv6() - if deviations.InterfaceEnabled(dut) { - s6.Enabled = ygot.Bool(true) - } - s6.GetOrCreateAddress(a.IPv6).PrefixLength = ygot.Uint8(ipv6PrefixLen) - - return i -} - -// configureDUT configures port1 and port2 on the DUT. -func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { - d := gnmi.OC() - - p1 := dut.Port(t, "port1") - i1 := &oc.Interface{Name: ygot.String(p1.Name()), Id: ygot.Uint32(portId)} - gnmi.Replace(t, dut, d.Interface(p1.Name()).Config(), configInterfaceDUT(i1, &dutPort1, dut)) - - p2 := dut.Port(t, "port2") - i2 := &oc.Interface{Name: ygot.String(p2.Name()), Id: ygot.Uint32(portId + 1)} - gnmi.Replace(t, dut, d.Interface(p2.Name()).Config(), configInterfaceDUT(i2, &dutPort2, dut)) - - if deviations.ExplicitPortSpeed(dut) { - fptest.SetPortSpeed(t, p1) - fptest.SetPortSpeed(t, p2) - } - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - fptest.AssignToNetworkInstance(t, dut, p1.Name(), deviations.DefaultNetworkInstance(dut), 0) - fptest.AssignToNetworkInstance(t, dut, p2.Name(), deviations.DefaultNetworkInstance(dut), 0) - } - gnmi.Replace(t, dut, gnmi.OC().Lldp().Enabled().Config(), false) -} - -// configureATE configures port1 and port2 on the ATE. -func configureATE(t *testing.T, ate *ondatra.ATEDevice) *ondatra.ATETopology { - top := ate.Topology().New() - - p1 := ate.Port(t, "port1") - i1 := top.AddInterface(atePort1.Name).WithPort(p1) - i1.IPv4(). - WithAddress(atePort1.IPv4CIDR()). - WithDefaultGateway(dutPort1.IPv4) - i1.IPv6(). - WithAddress(atePort1.IPv6CIDR()). - WithDefaultGateway(dutPort1.IPv6) - - p2 := ate.Port(t, "port2") - i2 := top.AddInterface(atePort2.Name).WithPort(p2) - i2.IPv4(). - WithAddress(atePort2.IPv4CIDR()). - WithDefaultGateway(dutPort2.IPv4) - i2.IPv6(). - WithAddress(atePort2.IPv6CIDR()). - WithDefaultGateway(dutPort2.IPv6) - - return top -} - -// configureDeviceIDs configures p4rt device-id on the DUT. -func configureDeviceID(ctx context.Context, t *testing.T, dut *ondatra.DUTDevice) { - nodes := p4rtutils.P4RTNodesByPort(t, dut) - p4rtNode, ok := nodes["port1"] - if !ok { - t.Fatal("Couldn't find P4RT Node for port: port1") - } - t.Logf("Configuring P4RT Node: %s", p4rtNode) - c := oc.Component{} - c.Name = ygot.String(p4rtNode) - c.IntegratedCircuit = &oc.Component_IntegratedCircuit{} - c.IntegratedCircuit.NodeId = ygot.Uint64(deviceID) - gnmi.Replace(t, dut, gnmi.OC().Component(p4rtNode).Config(), &c) -} - -// setupP4RTClient sends client arbitration message for both leader and follower clients, -// then sends setforwordingpipelineconfig with leader client. -func setupP4RTClient(ctx context.Context, args *testArgs) error { - // Setup p4rt-client stream parameters - streamParameter := p4rt_client.P4RTStreamParameters{ - Name: streamName, - DeviceId: deviceID, - ElectionIdH: uint64(0), - ElectionIdL: electionId, - } - - // Send ClientArbitration message on both p4rt leader and follower clients. - clients := []*p4rt_client.P4RTClient{args.leader, args.follower} - for index, client := range clients { - if client != nil { - client.StreamChannelCreate(&streamParameter) - if err := client.StreamChannelSendMsg(&streamName, &p4_v1.StreamMessageRequest{ - Update: &p4_v1.StreamMessageRequest_Arbitration{ - Arbitration: &p4_v1.MasterArbitrationUpdate{ - DeviceId: streamParameter.DeviceId, - ElectionId: &p4_v1.Uint128{ - High: streamParameter.ElectionIdH, - Low: streamParameter.ElectionIdL - uint64(index), - }, - }, - }, - }); err != nil { - return fmt.Errorf("errors seen when sending ClientArbitration message: %v", err) - } - if _, _, arbErr := client.StreamChannelGetArbitrationResp(&streamName, 1); arbErr != nil { - if err := p4rtutils.StreamTermErr(client.StreamTermErr); err != nil { - return err - } - return fmt.Errorf("errors seen in ClientArbitration response: %v", arbErr) - } - } - } - - // Load p4info file. - p4Info, err := utils.P4InfoLoad(p4InfoFile) - if err != nil { - return errors.New("Errors seen when loading p4info file.") - } - - // Send SetForwardingPipelineConfig for p4rt leader client. - if err := args.leader.SetForwardingPipelineConfig(&p4_v1.SetForwardingPipelineConfigRequest{ - DeviceId: deviceID, - ElectionId: &p4_v1.Uint128{High: uint64(0), Low: electionId}, - Action: p4_v1.SetForwardingPipelineConfigRequest_VERIFY_AND_COMMIT, - Config: &p4_v1.ForwardingPipelineConfig{ - P4Info: p4Info, - Cookie: &p4_v1.ForwardingPipelineConfig_Cookie{ - Cookie: 159, - }, - }, - }); err != nil { - return errors.New("Errors seen when sending SetForwardingPipelineConfig.") - } - return nil -} - -// getTracerouteParameter returns Traceroute related parameters for testPacketIn testcase. -func getTracerouteParameter(t *testing.T) PacketIO { - return &TraceroutePacketIO{ - PacketIOPacket: PacketIOPacket{ - TTL: &TTL1, - HopLimit: &HopLimit1, - }, - IngressPort: fmt.Sprint(portId), - EgressPort: fmt.Sprint(portId + 1), - } -} - -func TestPacketIn(t *testing.T) { - dut := ondatra.DUT(t, "dut") - ctx := context.Background() - - // Configure the DUT - configureDUT(t, dut) - - // Configure P4RT device-id - configureDeviceID(ctx, t, dut) - - // Configure the ATE - ate := ondatra.ATE(t, "ate") - top := configureATE(t, ate) - top.Push(t).StartProtocols(t) - - leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { - t.Fatalf("Could not initialize p4rt client: %v", err) - } - - follower := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := follower.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { - t.Fatalf("Could not initialize p4rt client: %v", err) - } - - args := &testArgs{ - ctx: ctx, - leader: leader, - follower: follower, - dut: dut, - ate: ate, - top: top, - } - - if err := setupP4RTClient(ctx, args); err != nil { - t.Fatalf("Could not setup p4rt client: %v", err) - } - - args.packetIO = getTracerouteParameter(t) - testPacketIn(ctx, t, args, true) // testPacketin for Ipv4 - testPacketIn(ctx, t, args, false) // testPacketin for Ipv6 -} - -type TraceroutePacketIO struct { - PacketIOPacket - IngressPort string - EgressPort string -} - -// GetTableEntry creates p4rtutils acl entry related to Traceroute protocol. -func (traceroute *TraceroutePacketIO) GetTableEntry(delete bool, IsIpv4 bool) []*p4rtutils.ACLWbbIngressTableEntryInfo { - if IsIpv4 { - actionType := p4_v1.Update_INSERT - if delete { - actionType = p4_v1.Update_DELETE - } - return []*p4rtutils.ACLWbbIngressTableEntryInfo{{ - Type: actionType, - IsIpv4: 0x1, - TTL: 0x1, - TTLMask: 0xFF, - Priority: 1, - }, - { - Type: actionType, - IsIpv4: 0x1, - TTL: 0x0, - TTLMask: 0xFF, - Priority: 1, - }} - } else { - actionType := p4_v1.Update_INSERT - if delete { - actionType = p4_v1.Update_DELETE - } - return []*p4rtutils.ACLWbbIngressTableEntryInfo{{ - Type: actionType, - IsIpv6: 0x1, - TTL: 0x1, - TTLMask: 0xFF, - Priority: 1, - }, - { - Type: actionType, - IsIpv6: 0x1, - TTL: 0x0, - TTLMask: 0xFF, - Priority: 1, - }} - } -} - -// GetPacketTemplate returns expected packets in PacketIn. -func (traceroute *TraceroutePacketIO) GetPacketTemplate() *PacketIOPacket { - return &traceroute.PacketIOPacket -} - -func (traceroute *TraceroutePacketIO) GetTrafficFlow(ate *ondatra.ATEDevice, isIpv4 bool, TTL uint8, frameSize uint32, frameRate uint64) []*ondatra.Flow { - ethHeader := ondatra.NewEthernetHeader().WithSrcAddress(tracerouteSrcMAC) - ipv4Header := ondatra.NewIPv4Header().WithSrcAddress(atePort1.IPv4).WithDstAddress(atePort2.IPv4).WithTTL(uint8(TTL)) //ttl=1 is traceroute traffic - ipv6Header := ondatra.NewIPv6Header().WithSrcAddress(atePort1.IPv6).WithDstAddress(atePort2.IPv6).WithHopLimit(uint8(TTL)) - if isIpv4 { - flow := ate.Traffic().NewFlow("IP4").WithFrameSize(frameSize).WithFrameRateFPS(frameRate).WithHeaders(ethHeader, ipv4Header) - return []*ondatra.Flow{flow} - } else { - flow := ate.Traffic().NewFlow("IP6").WithFrameSize(frameSize).WithFrameRateFPS(frameRate).WithHeaders(ethHeader, ipv6Header) - return []*ondatra.Flow{flow} - } -} - -// GetEgressPort returns expected egress port info in Packetin. -func (traceroute *TraceroutePacketIO) GetEgressPort() string { - return traceroute.EgressPort -} - -// GetIngressPort return expected ingress port info in Packetin. -func (traceroute *TraceroutePacketIO) GetIngressPort() string { - return traceroute.IngressPort -} diff --git a/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/README.md b/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/README.md deleted file mode 100644 index fe8bca5b1a0..00000000000 --- a/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# P4RT-5.2: Traceroute Packetout - - -## Summary - -Verify that traceroute packets can be sent by the controller. - - -## Procedure - -* Connect ATE port-1 to DUT port-1, ATE port-2 to DUT port-2, and ATE port-3 to - DUT port-3. - -* Install a set of routes on the device in both the default and TE VRFs. - -* Enable the P4RT server on the device.. - -* Connect a P4RT client and configure the forwarding pipeline. - -* Send an IPv4 traceroute reply from the client with submit_to_ingress_pipeline metadata set to true. - -* Verify that the packet is received on the ATE on the port corresponding to the routing table in the default VRF. - -* Repeat with an IPv6 traceroute reply and verify that it is received correctly by the ATE. - - -* Validate: - - * Traffic can continue to be forwarded between ATE port-1 and port-2. - - * Through AFT telemetry that the route entries remain present. - - * Following daemon restart, the gRIBI client connection can be re-established. - - * Issuing a gRIBI Get RPC results in 203.0.113.0/24 being returned. - - -## Protocol/RPC Parameter Coverage - -* No new configuration covered. - - -## Telemetry Parameter Coverage - -* No new telemetry covered. diff --git a/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/metadata.textproto b/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/metadata.textproto deleted file mode 100644 index 9370df541bd..00000000000 --- a/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/metadata.textproto +++ /dev/null @@ -1,36 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "6c2613a5-7579-4d2b-940b-d93a128d4fd5" -plan_id: "P4RT-5.2" -description: "Traceroute Packetout" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - ipv4_missing_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_port_speed: true - explicit_interface_in_default_vrf: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - omit_l2_mtu: true - gribi_mac_override_static_arp_static_route: true - interface_enabled: true - default_network_instance: "default" - } -} diff --git a/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/packetout_test.go b/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/packetout_test.go deleted file mode 100644 index 4d5175253ca..00000000000 --- a/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/packetout_test.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package traceroute_packetout_test - -import ( - "context" - "net" - "testing" - "time" - - "github.com/cisco-open/go-p4/p4rt_client" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - p4v1 "github.com/p4lang/p4runtime/go/p4/v1" -) - -type PacketIO interface { - GetPacketOut(srcMAC, dstMAC net.HardwareAddr, portID uint32, isIPv4 bool, ttl uint8, numPkts int) ([]*p4v1.PacketOut, error) -} - -type testArgs struct { - ctx context.Context - leader *p4rt_client.P4RTClient - dut *ondatra.DUTDevice - ate *ondatra.ATEDevice - top *ondatra.ATETopology - srcMAC net.HardwareAddr - dstMAC net.HardwareAddr - packetIO PacketIO -} - -// sendPackets sends out packets via PacketOut message in StreamChannel. -func sendPackets(t *testing.T, client *p4rt_client.P4RTClient, packets []*p4v1.PacketOut) { - for _, packet := range packets { - if err := client.StreamChannelSendMsg( - &streamName, &p4v1.StreamMessageRequest{ - Update: &p4v1.StreamMessageRequest_Packet{ - Packet: packet, - }, - }, - ); err != nil { - t.Errorf("There is error seen in Packet Out. %v", err) - } - } -} - -// testPacketOut sends out PacketOut with payload on p4rt leader or -// follower client, then verify DUT interface statistics -func testPacketOut(ctx context.Context, t *testing.T, args *testArgs) { - leader := args.leader - desc := "PacketOut from Primary Controller" - ttl := 2 - //for ipv4 - t.Run(desc+" ipv4 ", func(t *testing.T) { - // Check initial packet counters - port := sortPorts(args.ate.Ports())[0].Name() - t.Logf("Sending ipv4 pakcets with ttl %d", ttl) - counter0 := gnmi.Get(t, args.ate, gnmi.OC().Interface(port).Counters().InPkts().State()) - t.Logf("Initial number of packets: %d", counter0) - - packetCounter := 100 - packets, err := args.packetIO.GetPacketOut(args.srcMAC, args.dstMAC, portId, true, uint8(ttl), packetCounter) - if err != nil { - t.Fatalf("GetPacketOut returned unexpected error: %v", err) - } - t.Logf("Sending packets now") - - sendPackets(t, leader, packets) - - // Wait for ate stats to be populated - time.Sleep(60 * time.Second) - - // Check packet counters after packet out - counter1 := gnmi.Get(t, args.ate, gnmi.OC().Interface(port).Counters().InPkts().State()) - t.Logf("Final number of packets: %d", counter1) - - // Verify InPkts stats to check P4RT stream - t.Logf("Received %v packets on ATE port %s", counter1-counter0, port) - - if counter1-counter0 < uint64(float64(packetCounter)*0.95) { - t.Fatalf("Not all the packets are received.") - } - }, - ) - //for ipv6 - t.Run(desc+" ipv6", func(t *testing.T) { - // Check initial packet counters - port := sortPorts(args.ate.Ports())[0].Name() - - t.Logf("Sending ipv6 packets with ttl = %d", ttl) - counter0 := gnmi.Get(t, args.ate, gnmi.OC().Interface(port).Counters().InPkts().State()) - t.Logf("Initial number of packets: %d", counter0) - - packetCounter := 100 - packets, err := args.packetIO.GetPacketOut(args.srcMAC, args.dstMAC, portId, false, uint8(ttl), packetCounter) - if err != nil { - t.Fatalf("GetPacketOut returned unexpected error: %v", err) - } - t.Logf("Sending packets now") - - sendPackets(t, leader, packets) - - // Wait for ate stats to be populated - time.Sleep(60 * time.Second) - - // Check packet counters after packet out - counter1 := gnmi.Get(t, args.ate, gnmi.OC().Interface(port).Counters().InPkts().State()) - t.Logf("Final number of packets: %d", counter1) - - // Verify InPkts stats to check P4RT stream - t.Logf("Received %v packets on ATE port %s", counter1-counter0, port) - if counter1-counter0 < uint64(float64(packetCounter)*0.95) { - t.Fatalf("Not all the packets are received.") - } - }, - ) -} diff --git a/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/traceroute_packetout_test.go b/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/traceroute_packetout_test.go deleted file mode 100644 index 798b792f1f5..00000000000 --- a/feature/experimental/p4rt/ate_tests/traceroute_packetout_test/traceroute_packetout_test.go +++ /dev/null @@ -1,377 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -//go test -v -testbed /root/ondatra/featureprofiles/topologies/atedut_2.testbed -binding /root/ondatra/featureprofiles/topologies/atedut_2.binding -outputs_dir logs - -package traceroute_packetout_test - -import ( - "context" - "errors" - "fmt" - "net" - "sort" - "testing" - - "flag" - - "github.com/cisco-open/go-p4/p4rt_client" - "github.com/cisco-open/go-p4/utils" - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "github.com/openconfig/featureprofiles/feature/experimental/p4rt/internal/p4rtutils" - "github.com/openconfig/featureprofiles/internal/attrs" - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ygot/ygot" - p4v1 "github.com/p4lang/p4runtime/go/p4/v1" -) - -const ( - ipv4PrefixLen = 30 - ipv6PrefixLen = 126 - deviceID = uint64(100) - portId = uint32(2100) - electionId = uint64(100) - dstMAC = "00:1A:11:00:00:01" -) - -var ( - p4InfoFile = flag.String("p4info_file_location", "../../wbb.p4info.pb.txt", "Path to the p4info file.") - streamName = "p4rt" -) - -var ( - dutPort1 = attrs.Attributes{ - Desc: "dutPort1", - IPv4: "192.0.2.1", - IPv6: "2001:db8::192:0:2:1", - IPv4Len: ipv4PrefixLen, - IPv6Len: ipv6PrefixLen, - } - - atePort1 = attrs.Attributes{ - Name: "atePort1", - IPv4: "192.0.2.2", - IPv6: "2001:db8::192:0:2:2", - IPv4Len: ipv4PrefixLen, - IPv6Len: ipv6PrefixLen, - } - - dutPort2 = attrs.Attributes{ - Desc: "dutPort2", - IPv4: "192.0.2.5", - IPv6: "2001:db8::192:0:2:5", - IPv4Len: ipv4PrefixLen, - IPv6Len: ipv6PrefixLen, - } - - atePort2 = attrs.Attributes{ - Name: "atePort2", - IPv4: "192.0.2.6", - IPv6: "2001:db8::192:0:2:6", - IPv4Len: ipv4PrefixLen, - IPv6Len: ipv6PrefixLen, - } -) - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// sortPorts sorts the ports by the testbed port ID. -func sortPorts(ports []*ondatra.Port) []*ondatra.Port { - sort.Slice(ports, func(i, j int) bool { - idi, idj := ports[i].ID(), ports[j].ID() - li, lj := len(idi), len(idj) - if li == lj { - return idi < idj - } - return li < lj // "port2" < "port10" - }) - return ports -} - -// configureDUT configures port1 and port2 on the DUT. -func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { - d := gnmi.OC() - - p1 := dut.Port(t, "port1").Name() - i1 := dutPort1.NewOCInterface(p1, dut) - i1.Id = ygot.Uint32(portId) - gnmi.Replace(t, dut, d.Interface(p1).Config(), i1) - - p2 := dut.Port(t, "port2").Name() - i2 := dutPort2.NewOCInterface(p2, dut) - i2.Id = ygot.Uint32(portId + 1) - gnmi.Replace(t, dut, d.Interface(p2).Config(), i2) - - if deviations.ExplicitPortSpeed(dut) { - fptest.SetPortSpeed(t, dut.Port(t, "port1")) - fptest.SetPortSpeed(t, dut.Port(t, "port2")) - } - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - fptest.AssignToNetworkInstance(t, dut, p1, deviations.DefaultNetworkInstance(dut), 0) - fptest.AssignToNetworkInstance(t, dut, p2, deviations.DefaultNetworkInstance(dut), 0) - } -} - -// configureATE configures port1 and port2 on the ATE. -func configureATE(t *testing.T, ate *ondatra.ATEDevice) *ondatra.ATETopology { - top := ate.Topology().New() - - p1 := ate.Port(t, "port1") - atePort1.AddToATE(top, p1, &dutPort1) - - p2 := ate.Port(t, "port2") - atePort2.AddToATE(top, p2, &dutPort2) - return top -} - -// configureDeviceIDs configures p4rt device-id on the DUT. -func configureDeviceID(ctx context.Context, t *testing.T, dut *ondatra.DUTDevice) { - nodes := p4rtutils.P4RTNodesByPort(t, dut) - p4rtNode, ok := nodes["port1"] - if !ok { - t.Fatal("Couldn't find P4RT Node for port: port1") - } - t.Logf("Configuring P4RT Node: %s", p4rtNode) - c := oc.Component{} - c.Name = ygot.String(p4rtNode) - c.IntegratedCircuit = &oc.Component_IntegratedCircuit{} - c.IntegratedCircuit.NodeId = ygot.Uint64(deviceID) - gnmi.Replace(t, dut, gnmi.OC().Component(p4rtNode).Config(), &c) -} - -// setupP4RTClient sends client arbitration message for both leader and follower clients, -// then sends setforwordingpipelineconfig with leader client. -func setupP4RTClient(ctx context.Context, args *testArgs) error { - // Setup p4rt-client stream parameters - streamParameter := p4rt_client.P4RTStreamParameters{ - Name: streamName, - DeviceId: deviceID, - ElectionIdH: uint64(0), - ElectionIdL: electionId, - } - - // Send ClientArbitration message on both p4rt leader and backup clients. - client := args.leader - - if client != nil { - client.StreamChannelCreate(&streamParameter) - if err := client.StreamChannelSendMsg(&streamName, &p4v1.StreamMessageRequest{ - Update: &p4v1.StreamMessageRequest_Arbitration{ - Arbitration: &p4v1.MasterArbitrationUpdate{ - DeviceId: streamParameter.DeviceId, - ElectionId: &p4v1.Uint128{ - High: streamParameter.ElectionIdH, - Low: streamParameter.ElectionIdL - uint64(0), - }, - }, - }, - }); err != nil { - return fmt.Errorf("errors seen when sending ClientArbitration message: %v", err) - } - if _, _, arbErr := client.StreamChannelGetArbitrationResp(&streamName, 1); arbErr != nil { - if err := p4rtutils.StreamTermErr(client.StreamTermErr); err != nil { - return err - } - return fmt.Errorf("errors seen in ClientArbitration response: %v", arbErr) - } - } - // Load p4info file. - p4Info, err := utils.P4InfoLoad(p4InfoFile) - if err != nil { - return errors.New("Errors seen when loading p4info file.") - } - // Send SetForwardingPipelineConfig for p4rt leader client. - if err := args.leader.SetForwardingPipelineConfig(&p4v1.SetForwardingPipelineConfigRequest{ - DeviceId: deviceID, - ElectionId: &p4v1.Uint128{High: uint64(0), Low: electionId}, - Action: p4v1.SetForwardingPipelineConfigRequest_VERIFY_AND_COMMIT, - Config: &p4v1.ForwardingPipelineConfig{ - P4Info: p4Info, - Cookie: &p4v1.ForwardingPipelineConfig_Cookie{ - Cookie: 159, - }, - }, - }); err != nil { - return errors.New("errors seen when sending SetForwardingPipelineConfig.") - } - return nil -} - -// getTracerouteParameter returns Traceroute related parameters for testPacketOut testcase. -func getTracerouteParameter(t *testing.T) PacketIO { - return &TraceroutePacketIO{ - IngressPort: fmt.Sprint(portId), - } -} - -func dMAC(t *testing.T, dut *ondatra.DUTDevice) string { - if !deviations.GRIBIMACOverrideStaticARPStaticRoute(dut) { - return dstMAC - } - gnmi.Replace(t, dut, gnmi.OC().System().MacAddress().RoutingMac().Config(), dstMAC) - return dstMAC -} - -func TestPacketOut(t *testing.T) { - dut := ondatra.DUT(t, "dut") - ctx := context.Background() - // Configure the DUT - configureDUT(t, dut) - // Configure the ATE - ate := ondatra.ATE(t, "ate") - top := configureATE(t, ate) - top.Push(t).StartProtocols(t) - - // Configure P4RT device-id - configureDeviceID(ctx, t, dut) - - leader := p4rt_client.NewP4RTClient(&p4rt_client.P4RTClientParameters{}) - if err := leader.P4rtClientSet(dut.RawAPIs().P4RT(t)); err != nil { - t.Fatalf("Could not initialize p4rt client: %v", err) - } - - sm := gnmi.Get(t, dut, gnmi.OC().Interface(dut.Port(t, "port1").Name()).Ethernet().MacAddress().State()) - srcMAC, err := net.ParseMAC(sm) - if err != nil { - t.Fatalf("Couldn't parse Source MAC: %v", err) - } - - dstMAC, err := net.ParseMAC(dMAC(t, dut)) - if err != nil { - t.Fatalf("Couldn't parse router MAC: %v", err) - } - - args := &testArgs{ - ctx: ctx, - leader: leader, - dut: dut, - ate: ate, - top: top, - srcMAC: srcMAC, - dstMAC: dstMAC, - } - - if err := setupP4RTClient(ctx, args); err != nil { - t.Fatalf("Could not setup p4rt client: %v", err) - } - - args.packetIO = getTracerouteParameter(t) - testPacketOut(ctx, t, args) -} - -type TraceroutePacketIO struct { - PacketIO - IngressPort string -} - -// packetTracerouteRequestGet generates PacketOut payload for Traceroute packets. -func packetTracerouteRequestGet(srcMAC, dstMAC net.HardwareAddr, isIPv4 bool, ttl uint8, seq int) ([]byte, error) { - buf := gopacket.NewSerializeBuffer() - opts := gopacket.SerializeOptions{ - FixLengths: true, - ComputeChecksums: true, - } - payload := []byte{} - payLoadLen := 32 - - ethType := layers.EthernetTypeIPv4 - if !isIPv4 { - ethType = layers.EthernetTypeIPv6 - } - pktEth := &layers.Ethernet{ - SrcMAC: srcMAC, - DstMAC: dstMAC, - EthernetType: ethType, - } - - pktIpv4 := &layers.IPv4{ - Version: 4, - TTL: ttl, - SrcIP: net.ParseIP(dutPort1.IPv4).To4(), - DstIP: net.ParseIP(atePort1.IPv4).To4(), - Protocol: layers.IPProtocolICMPv4, - Flags: layers.IPv4DontFragment, - } - pktICMP4 := &layers.ICMPv4{ - TypeCode: layers.CreateICMPv4TypeCode(layers.ICMPv4TypeEchoRequest, 0), - Seq: uint16(seq), - } - - pktIpv6 := &layers.IPv6{ - Version: 6, - HopLimit: ttl, - NextHeader: layers.IPProtocolICMPv6, - SrcIP: net.ParseIP(dutPort1.IPv6).To16(), - DstIP: net.ParseIP(atePort1.IPv6).To16(), - } - pktICMP6 := &layers.ICMPv6{ - TypeCode: layers.CreateICMPv6TypeCode(layers.ICMPv6TypeEchoRequest, 0), - } - pktICMP6.SetNetworkLayerForChecksum(pktIpv6) - - for i := 0; i < payLoadLen; i++ { - payload = append(payload, byte(i)) - } - if isIPv4 { - if err := gopacket.SerializeLayers(buf, opts, - pktEth, pktIpv4, pktICMP4, gopacket.Payload(payload), - ); err != nil { - return nil, err - } - return buf.Bytes(), nil - } - if err := gopacket.SerializeLayers(buf, opts, - pktEth, pktIpv6, pktICMP6, gopacket.Payload(payload), - ); err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -// GetPacketOut generates PacketOut message with payload as Traceroute IPv6 and IPv6 packets. -// isIPv4==true refers to the ipv4 packets and if false we are sending ipv6 packet -func (traceroute *TraceroutePacketIO) GetPacketOut(srcMAC, dstMAC net.HardwareAddr, portID uint32, isIPv4 bool, ttl uint8, numPkts int) ([]*p4v1.PacketOut, error) { - packets := []*p4v1.PacketOut{} - for i := 1; i <= numPkts; i++ { - pkt, err := packetTracerouteRequestGet(srcMAC, dstMAC, isIPv4, ttl, i) - if err != nil { - return nil, err - } - packet := &p4v1.PacketOut{ - Payload: pkt, - Metadata: []*p4v1.PacketMetadata{ - { - MetadataId: uint32(1), // "egress_port" - Value: []byte("submit_to_ingress"), - }, - { - MetadataId: uint32(2), // "submit_to_ingress" - Value: []byte{1}, - }, - { - MetadataId: uint32(3), // "unused_pad" - Value: []byte{0}, - }, - }, - } - packets = append(packets, packet) - } - return packets, nil -} diff --git a/feature/qos/ate_tests/bursty_traffic_test/README.md b/feature/qos/ate_tests/bursty_traffic_test/README.md deleted file mode 100644 index c3d16c87cc0..00000000000 --- a/feature/qos/ate_tests/bursty_traffic_test/README.md +++ /dev/null @@ -1,131 +0,0 @@ -# DP-1.11: Bursty traffic test - -## Summary - -Verify that DUT does not drop bursty traffic. - -## QoS traffic test setup: - -* Topology: - - * 2 input interfaces and 1 output interface with the same port speed. The - interface can be a physical interface or LACP bundle interface with the - same aggregated speed. - - ``` - ATE port 1 - | - DUT--------ATE port 3 - | - ATE port 2 - ``` - -* Traffic classes: - - * We will use 7 traffic classes NC1, AF4, AF3, AF2, AF1, BE0 and BE1. - -* Traffic types: - - * All the traffic tests apply to both IPv4 and IPv6 traffic. - -* Queue types: - - * NC1 will have strict priority queues - * AF4/AF3/AF2/AF1/BE1/BE0 will use WRR queues. - * NC1 will have strict priority queue. - * AF4, AF3, AF2, AF1, BE1 and BE0 will use WRR queues. - -* Test results should be independent of the location of interfaces. For - example, 2 input interfaces and output interface could be located on - - * Same ASIC-based forwarding engine - * Different ASIC-based forwarding engine on same line card - * Different ASIC-based forwarding engine on different line cards - -* Test results should be the same for port speeds 100G and 400G. - -* Counters should be also verified for each test case: - - * /qos/interfaces/interface/output/queues/queue/state/transmit-pkts - * /qos/interfaces/interface/output/queues/queue/state/dropped-pkts - * transmit-pkts should be equal to the number of Rx pkts on Ixia port - * dropped-pkts should be equal to diff between the number of Tx and the - number Rx pkts on Ixia ports - -* Latency: - - * Should be < 100000ns - -## Procedure - -* Connect DUT port-1 to ATE port-1, DUT port-2 to ATE port-2 and DUT port-3 to - ATE port-3. - -* Configuration: - - * Configure strict priority queues for NC1 and AF4 with NC1 having higher - priority. - * Configure WRR for AF4, AF3, AF2, AF1, BE0 and BE1 with weight 48, 12, 8, - 4, 1 and 1 respectively. - -* Verify that there is no traffic loss with bursty traffic - - * NC1 traffic from Input interface 1 and 2: - - Interface# | Rate(%) | Frame size | Packet count | Inter-pkt gap(bytes) | inter burst gap(bytes) | Output(%) - ---------- | ------- | ---------- | ------------ | -------------------- | ---------------------- | --------- - 1 | 45 | 512 | 1200 | 12 | 48000 | 100 - 2 | 50 | 512 | 1200 | 12 | 96000 | 100 - - * Repeat the above test case for other traffic classes:: - * AF4 - * AF3 - * AF2 - * AF1 - * BE1 - * BE0 - -## Config parameter coverage - -* Classifiers - - * /qos/classifiers/classifier/config/name - * /qos/classifiers/classifier/config/type - * /qos/classifiers/classifier/terms/term/actions/config/target-group - * /qos/classifiers/classifier/terms/term/conditions/ipv4/config/dscp-set - * qos/classifiers/classifier/terms/term/conditions/ipv6/config/dscp-set - * /qos/classifiers/classifier/terms/term/config/id - -* Forwarding Groups - - * /qos/forwarding-groups/forwarding-group/config/name - * /qos/forwarding-groups/forwarding-group/config/output-queue - -* Queue - - * /qos/queues/queue/config/name - -* Interfaces - - * /qos/interfaces/interface/input/classifiers/classifier/config/name - * /qos/interfaces/interface/output/queues/queue/config/name - * /qos/interfaces/interface/output/scheduler-policy/config/name - -* Scheduler policy - - * /qos/scheduler-policies/scheduler-policy/config/name - * /qos/scheduler-policies/scheduler - -policy/schedulers/scheduler/config/priority - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/sequence - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/id - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight - -## Telemetry parameter coverage - -* /qos/interfaces/interface/output/queues/queue/state/transmit-pkts -* /qos/interfaces/interface/output/queues/queue/state/transmit-octets -* /qos/interfaces/interface/output/queues/queue/state/dropped-pkts -* /qos/interfaces/interface/output/queues/queue/state/dropped-octets diff --git a/feature/qos/ate_tests/bursty_traffic_test/bursty_traffic_test.go b/feature/qos/ate_tests/bursty_traffic_test/bursty_traffic_test.go deleted file mode 100644 index 9206cc15f04..00000000000 --- a/feature/qos/ate_tests/bursty_traffic_test/bursty_traffic_test.go +++ /dev/null @@ -1,1203 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package bursty_traffic_test - -import ( - "testing" - "time" - - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/featureprofiles/internal/qoscfg" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ondatra/netutil" - "github.com/openconfig/ygot/ygot" -) - -type trafficData struct { - trafficRate float64 - expectedThroughputPct float32 - frameSize uint32 - dscp uint8 - queue string - inputIntf *ondatra.Interface - burstPackets uint32 - burstMinGap uint32 - burstGap uint32 -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// Test cases: -// - Verify that there is no traffic loss with bursty traffic cases: -// 1) Bursty NC1 traffic. -// 2) Bursty AF4 traffic. -// 3) Bursty AF3 traffic. -// 4) Bursty AF2 traffic. -// 5) Bursty AF1 traffic. -// 6) Bursty BE0 traffic. -// 7) Bursty BE1 traffic. -// -// Topology: -// ATE port 1 -// | -// DUT--------ATE port 3 -// | -// ATE port 2 -// -// Sample CLI command to get telemetry using gmic: -// - gnmic -a ipaddr:10162 -u username -p password --skip-verify get \ -// --path /components/component --format flat -// - gnmic tool info: -// - https://github.com/karimra/gnmic/blob/main/README.md -// - -func TestBurstyTraffic(t *testing.T) { - dut := ondatra.DUT(t, "dut") - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - - // Configure DUT interfaces and QoS. - ConfigureDUTIntf(t, dut) - switch dut.Vendor() { - case ondatra.CISCO: - ConfigureCiscoQos(t, dut) - default: - ConfigureQoS(t, dut) - } - - // Configure ATE interfaces. - ate := ondatra.ATE(t, "ate") - ap1 := ate.Port(t, "port1") - ap2 := ate.Port(t, "port2") - ap3 := ate.Port(t, "port3") - top := ate.Topology().New() - intf1 := top.AddInterface("intf1").WithPort(ap1) - intf1.IPv4(). - WithAddress("198.51.100.1/31"). - WithDefaultGateway("198.51.100.0") - intf2 := top.AddInterface("intf2").WithPort(ap2) - intf2.IPv4(). - WithAddress("198.51.100.3/31"). - WithDefaultGateway("198.51.100.2") - intf3 := top.AddInterface("intf3").WithPort(ap3) - intf3.IPv4(). - WithAddress("198.51.100.5/31"). - WithDefaultGateway("198.51.100.4") - top.Push(t).StartProtocols(t) - - queues := netutil.CommonTrafficQueues(t, dut) - - // Test case 1: Bursty NC1 traffic. - nc1TrafficFlows := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 512, - trafficRate: 45, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - burstPackets: 1200, - burstMinGap: 12, - burstGap: 48000, - }, - "intf2-nc1": { - frameSize: 512, - trafficRate: 50, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - burstPackets: 1200, - burstMinGap: 12, - burstGap: 96000, - }, - } - - // Test case 2: Bursty AF4 traffic. - af4TrafficFlows := map[string]*trafficData{ - "intf1-af4": { - frameSize: 512, - trafficRate: 45, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - burstPackets: 1200, - burstMinGap: 12, - burstGap: 48000, - }, - "intf2-af4": { - frameSize: 512, - trafficRate: 50, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - burstPackets: 1200, - burstMinGap: 12, - burstGap: 96000, - }, - } - - // Test case 3: Bursty AF3 traffic. - af3TrafficFlows := map[string]*trafficData{ - "intf1-af3": { - frameSize: 512, - trafficRate: 45, - expectedThroughputPct: 100.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - burstPackets: 1200, - burstMinGap: 12, - burstGap: 48000, - }, - "intf2-af3": { - frameSize: 512, - trafficRate: 50, - dscp: 24, - expectedThroughputPct: 100.0, - queue: queues.AF3, - inputIntf: intf2, - burstPackets: 1200, - burstMinGap: 12, - burstGap: 96000, - }, - } - - // Test case 4: Bursty AF2 traffic. - af2TrafficFlows := map[string]*trafficData{ - "intf1-af2": { - frameSize: 512, - trafficRate: 45, - expectedThroughputPct: 100.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - burstPackets: 1200, - burstMinGap: 12, - burstGap: 48000, - }, - "intf2-af2": { - frameSize: 512, - trafficRate: 50, - dscp: 16, - expectedThroughputPct: 100.0, - queue: queues.AF2, - inputIntf: intf2, - burstPackets: 1200, - burstMinGap: 12, - burstGap: 96000, - }, - } - - // Test case 5: Bursty AF1 traffic. - af1TrafficFlows := map[string]*trafficData{ - "intf1-af1": { - frameSize: 512, - trafficRate: 45, - expectedThroughputPct: 100.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - burstPackets: 1200, - burstMinGap: 12, - burstGap: 48000, - }, - "intf2-af1": { - frameSize: 512, - trafficRate: 50, - dscp: 8, - expectedThroughputPct: 100.0, - queue: queues.AF1, - inputIntf: intf2, - burstPackets: 1200, - burstMinGap: 12, - burstGap: 96000, - }, - } - - // Test case 6: Bursty BE0 traffic. - be0TrafficFlows := map[string]*trafficData{ - "intf1-be0": { - frameSize: 512, - trafficRate: 45, - expectedThroughputPct: 100.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - burstPackets: 1200, - burstMinGap: 12, - burstGap: 48000, - }, - "intf2-be0": { - frameSize: 512, - trafficRate: 50, - dscp: 4, - expectedThroughputPct: 100.0, - queue: queues.BE0, - inputIntf: intf2, - burstPackets: 1200, - burstMinGap: 12, - burstGap: 96000, - }, - } - - // Test case 7: Bursty BE1 traffic. - be1TrafficFlows := map[string]*trafficData{ - "intf1-be1": { - frameSize: 512, - trafficRate: 45, - expectedThroughputPct: 100.0, - dscp: 0, - queue: queues.BE1, - inputIntf: intf1, - burstPackets: 1200, - burstMinGap: 12, - burstGap: 48000, - }, - "intf2-be1": { - frameSize: 512, - trafficRate: 50, - dscp: 0, - expectedThroughputPct: 100.0, - queue: queues.BE1, - inputIntf: intf2, - burstPackets: 1200, - burstMinGap: 12, - burstGap: 96000, - }, - } - - cases := []struct { - desc string - trafficFlows map[string]*trafficData - }{{ - desc: "Bursty NC1 traffic", - trafficFlows: nc1TrafficFlows, - }, { - desc: "Bursty AF4 traffic", - trafficFlows: af4TrafficFlows, - }, { - desc: "Bursty AF3 traffic", - trafficFlows: af3TrafficFlows, - }, { - desc: "Bursty AF2 traffic", - trafficFlows: af2TrafficFlows, - }, { - desc: "Bursty AF1 traffic", - trafficFlows: af1TrafficFlows, - }, { - desc: "Bursty BE0 traffic", - trafficFlows: be0TrafficFlows, - }, { - desc: "Bursty BE1 traffic", - trafficFlows: be1TrafficFlows, - }} - - for _, tc := range cases { - t.Run(tc.desc, func(t *testing.T) { - trafficFlows := tc.trafficFlows - - var flows []*ondatra.Flow - for trafficID, data := range trafficFlows { - t.Logf("Configuring flow %s", trafficID) - flow := ate.Traffic().NewFlow(trafficID). - WithSrcEndpoints(data.inputIntf). - WithDstEndpoints(intf3). - WithHeaders(ondatra.NewEthernetHeader(), ondatra.NewIPv4Header().WithDSCP(data.dscp)). - WithFrameRatePct(data.trafficRate). - WithFrameSize(data.frameSize) - flow.Transmission().WithPatternBurst(). - WithPacketsPerBurst(data.burstPackets).WithMinGapBytes(data.burstMinGap). - WithInterburstGapBytes(data.burstGap) - flows = append(flows, flow) - } - var counterNames []string - counters := make(map[string]map[string]uint64) - if !deviations.QOSDroppedOctets(dut) { - counterNames = []string{ - - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedOctetsBeforeTraffic", "dutQosDroppedPktsAfterTraffic", - "dutQosDroppedOctetsAfterTraffic", - } - } else { - counterNames = []string{ - - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedPktsAfterTraffic", - } - - } - - for _, name := range counterNames { - counters[name] = make(map[string]uint64) - - // Set the initial counters to 0. - for _, data := range trafficFlows { - counters[name][data.queue] = 0 - } - } - - // Get QoS egress packet counters before the traffic. - for _, data := range trafficFlows { - counters["dutQosPktsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) - counters["dutQosOctetsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitOctets().State()) - counters["dutQosDroppedPktsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - //counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State()) - - if !deviations.QOSDroppedOctets(dut) { - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State()) - } - } - - t.Logf("Running traffic 1 on DUT interfaces: %s => %s ", dp1.Name(), dp3.Name()) - t.Logf("Running traffic 2 on DUT interfaces: %s => %s ", dp2.Name(), dp3.Name()) - t.Logf("Sending traffic flows: \n%v\n\n", trafficFlows) - ate.Traffic().Start(t, flows...) - time.Sleep(30 * time.Second) - ate.Traffic().Stop(t) - time.Sleep(60 * time.Second) - - for trafficID, data := range trafficFlows { - counters["ateOutPkts"][data.queue] += gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).Counters().OutPkts().State()) - counters["ateInPkts"][data.queue] += gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).Counters().InPkts().State()) - - counters["dutQosPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) - counters["dutQosOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitOctets().State()) - counters["dutQosDroppedPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - //counters["dutQosDroppedOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State()) - - if !deviations.QOSDroppedOctets(dut) { - counters["dutQosDroppedOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State()) - } - t.Logf("ateInPkts: %v, txPkts %v, Queue: %v", counters["ateInPkts"][data.queue], counters["dutQosPktsAfterTraffic"][data.queue], data.queue) - - lossPct := gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).LossPct().State()) - t.Logf("Get flow %q: lossPct: %.2f%% or rxPct: %.2f%%, want: %.2f%%\n\n", data.queue, lossPct, 100.0-lossPct, data.expectedThroughputPct) - if got, want := 100.0-lossPct, data.expectedThroughputPct; got != want { - t.Errorf("Get(throughput for queue %q): got %.2f%%, want %.2f%%", data.queue, got, want) - } - } - - // Check QoS egress packet counters are updated correctly. - for _, name := range counterNames { - t.Logf("QoS %s: %v", name, counters[name]) - } - - for _, data := range trafficFlows { - dutPktCounterDiff := counters["dutQosPktsAfterTraffic"][data.queue] - counters["dutQosPktsBeforeTraffic"][data.queue] - atePktCounterDiff := counters["ateInPkts"][data.queue] - t.Logf("Queue %q: atePktCounterDiff: %v dutPktCounterDiff: %v", data.queue, atePktCounterDiff, dutPktCounterDiff) - if dutPktCounterDiff < atePktCounterDiff { - t.Errorf("Get dutPktCounterDiff for queue %q: got %v, want >= %v", data.queue, dutPktCounterDiff, atePktCounterDiff) - } - - dutDropPktCounterDiff := counters["dutQosDroppedPktsAfterTraffic"][data.queue] - counters["dutQosDroppedPktsBeforeTraffic"][data.queue] - t.Logf("Queue %q: dutDropPktCounterDiff: %v", data.queue, dutDropPktCounterDiff) - if dutDropPktCounterDiff != 0 { - t.Errorf("Get dutDropPktCounterDiff for queue %q: got %v, want 0", data.queue, dutDropPktCounterDiff) - } - - dutOctetCounterDiff := counters["dutQosOctetsAfterTraffic"][data.queue] - counters["dutQosOctetsBeforeTraffic"][data.queue] - ateOctetCounterDiff := counters["ateInPkts"][data.queue] * uint64(data.frameSize) - t.Logf("Queue %q: ateOctetCounterDiff: %v dutOctetCounterDiff: %v", data.queue, ateOctetCounterDiff, dutOctetCounterDiff) - if !deviations.QOSOctets(dut) { - if dutOctetCounterDiff < ateOctetCounterDiff { - t.Errorf("Get dutOctetCounterDiff for queue %q: got %v, want >= %v", data.queue, dutOctetCounterDiff, ateOctetCounterDiff) - } - } - - if !deviations.QOSDroppedOctets(dut) { - ateDropOctetCounterDiff := (counters["ateOutPkts"][data.queue] - counters["ateInPkts"][data.queue]) * uint64(data.frameSize) - dutDropOctetCounterDiff := counters["dutQosDroppedOctetsAfterTraffic"][data.queue] - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] - t.Logf("Queue %q: ateDropOctetCounterDiff: %v dutDropOctetCounterDiff: %v", data.queue, ateDropOctetCounterDiff, dutDropOctetCounterDiff) - if dutDropOctetCounterDiff < ateDropOctetCounterDiff { - t.Errorf("Get dutDropOctetCounterDiff for queue %q: got %v, want >= %v", data.queue, dutDropOctetCounterDiff, ateDropOctetCounterDiff) - } - } - - } - }) - } -} - -func ConfigureDUTIntf(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - - dutIntfs := []struct { - desc string - intfName string - ipAddr string - prefixLen uint8 - }{{ - desc: "Input interface port1", - intfName: dp1.Name(), - ipAddr: "198.51.100.0", - prefixLen: 31, - }, { - desc: "Input interface port2", - intfName: dp2.Name(), - ipAddr: "198.51.100.2", - prefixLen: 31, - }, { - desc: "Output interface port3", - intfName: dp3.Name(), - ipAddr: "198.51.100.4", - prefixLen: 31, - }} - - // Configure the interfaces. - for _, intf := range dutIntfs { - t.Logf("Configure DUT interface %s with attributes %v", intf.intfName, intf) - i := &oc.Interface{ - Name: ygot.String(intf.intfName), - Description: ygot.String(intf.desc), - Type: oc.IETFInterfaces_InterfaceType_ethernetCsmacd, - Enabled: ygot.Bool(true), - } - i.GetOrCreateEthernet() - s := i.GetOrCreateSubinterface(0).GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) && !deviations.IPv4MissingEnabled(dut) { - s.Enabled = ygot.Bool(true) - } - a := s.GetOrCreateAddress(intf.ipAddr) - a.PrefixLength = ygot.Uint8(intf.prefixLen) - gnmi.Replace(t, dut, gnmi.OC().Interface(intf.intfName).Config(), i) - } -} - -func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - d := &oc.Root{} - q := d.GetOrCreateQos() - queues := netutil.CommonTrafficQueues(t, dut) - - t.Logf("Create qos forwarding groups config") - forwardingGroups := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - t.Logf("qos forwarding groups config: %v", forwardingGroups) - for _, tc := range forwardingGroups { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - } - - t.Logf("Create qos Classifiers config") - classifiers := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - t.Logf("qos Classifiers config: %v", classifiers) - for _, tc := range classifiers { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.name == "dscp_based_classifier_ipv4" { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.name == "dscp_based_classifier_ipv6" { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos input classifier config") - classifierIntfs := []struct { - desc string - intf string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }, { - desc: "Input Classifier Type IPV4", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - t.Logf("qos input classifier config: %v", classifierIntfs) - for _, tc := range classifierIntfs { - qoscfg.SetInputClassifier(t, dut, q, tc.intf, tc.inputClassifierType, tc.classifier) - } - - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - priority oc.E_Scheduler_Priority - inputID string - inputType oc.E_Input_InputType - weight uint64 - queueName string - targetGroup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE0", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(4), - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF2", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(8), - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF3", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(12), - queueName: queues.AF2, - targetGroup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF4", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(48), - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(7), - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - s.SetPriority(tc.priority) - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - input.SetInputType(tc.inputType) - input.SetQueue(tc.queueName) - input.SetWeight(tc.weight) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - scheduler string - }{{ - desc: "output-interface-BE1", - queueName: queues.BE1, - scheduler: "scheduler", - }, { - desc: "output-interface-BE0", - queueName: queues.BE0, - scheduler: "scheduler", - }, { - desc: "output-interface-AF1", - queueName: queues.AF1, - scheduler: "scheduler", - }, { - desc: "output-interface-AF2", - queueName: queues.AF2, - scheduler: "scheduler", - }, { - desc: "output-interface-AF3", - queueName: queues.AF3, - scheduler: "scheduler", - }, { - desc: "output-interface-AF4", - queueName: queues.AF4, - scheduler: "scheduler", - }, { - desc: "output-interface-NC1", - queueName: queues.NC1, - scheduler: "scheduler", - }} - - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp3.Name()) - i.SetInterfaceId(dp3.Name()) - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) - if deviations.InterfaceRefConfigUnsupported(dut) { - i.InterfaceRef = nil - } - output := i.GetOrCreateOutput() - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName(tc.scheduler) - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } -} -func ConfigureCiscoQos(t *testing.T, dut *ondatra.DUTDevice) { - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - d := &oc.Root{} - q := d.GetOrCreateQos() - t.Logf("Create qos Classifiers config") - classifiers := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - queueName := []string{"NC1", "AF4", "AF3", "AF2", "AF1", "BE0", "BE1"} - - for i, queue := range queueName { - q1 := q.GetOrCreateQueue(queue) - q1.Name = ygot.String(queue) - queueid := len(queueName) - i - q1.QueueId = ygot.Uint8(uint8(queueid)) - - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - casesfwdgrp := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: "BE1", - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: "BE0", - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: "AF1", - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: "AF2", - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: "AF3", - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: "AF4", - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: "NC1", - targetGroup: "target-group-NC1", - }} - t.Logf("qos forwarding groups config cases: %v", casesfwdgrp) - for _, tc := range casesfwdgrp { - t.Run(tc.desc, func(t *testing.T) { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - }) - } - for _, tc := range classifiers { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.classType == oc.Qos_Classifier_Type_IPV4 { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.classType == oc.Qos_Classifier_Type_IPV6 { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos input classifier config") - classifierIntfs := []struct { - desc string - intf string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }, { - desc: "Input Classifier Type IPV4", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - t.Logf("qos input classifier config: %v", classifierIntfs) - for _, tc := range classifierIntfs { - qoscfg.SetInputClassifier(t, dut, q, tc.intf, tc.inputClassifierType, tc.classifier) - } - - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - priority oc.E_Scheduler_Priority - inputID string - inputType oc.E_Input_InputType - weight uint64 - queueName string - targetGrpoup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: "BE1", - targetGrpoup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE0", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: "BE0", - targetGrpoup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(4), - queueName: "AF1", - targetGrpoup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF2", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(8), - queueName: "AF2", - targetGrpoup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF3", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(12), - queueName: "AF3", - targetGrpoup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF4", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(48), - queueName: "AF4", - targetGrpoup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(7), - queueName: "NC1", - targetGrpoup: "target-group-NC1", - }} - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - s.SetPriority(tc.priority) - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - input.SetInputType(tc.inputType) - input.SetQueue(tc.queueName) - input.SetWeight(tc.weight) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - scheduler string - }{{ - desc: "output-interface-NC1", - queueName: "NC1", - scheduler: "scheduler", - }, { - desc: "output-interface-AF4", - queueName: "AF4", - scheduler: "scheduler", - }, { - desc: "output-interface-AF3", - queueName: "AF3", - scheduler: "scheduler", - }, { - desc: "output-interface-AF2", - queueName: "AF2", - scheduler: "scheduler", - }, { - desc: "output-interface-AF1", - queueName: "AF1", - scheduler: "scheduler", - }, { - desc: "output-interface-BE0", - queueName: "BE0", - scheduler: "scheduler", - }, { - desc: "output-interface-BE1", - queueName: "BE1", - scheduler: "scheduler", - }} - - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp3.Name()) - i.SetInterfaceId(dp3.Name()) - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) - output := i.GetOrCreateOutput() - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName(tc.scheduler) - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - -} diff --git a/feature/qos/ate_tests/bursty_traffic_test/metadata.textproto b/feature/qos/ate_tests/bursty_traffic_test/metadata.textproto deleted file mode 100644 index decad5823f4..00000000000 --- a/feature/qos/ate_tests/bursty_traffic_test/metadata.textproto +++ /dev/null @@ -1,42 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "8e6a4bdd-7e4e-4c2a-90d8-55f3543f9e99" -plan_id: "DP-1.11" -description: "Bursty traffic test" -testbed: TESTBED_DUT_ATE_4LINKS -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - ipv4_missing_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: JUNIPER - } - deviations: { - explicit_interface_ref_definition: true - qos_dropped_octets: true - } -} -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_interface_ref_definition: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - interface_enabled: true - qos_octets: true - } -} diff --git a/feature/qos/ate_tests/mixed_sp_wrr_traffic_test/README.md b/feature/qos/ate_tests/mixed_sp_wrr_traffic_test/README.md deleted file mode 100644 index 09c58f2d08b..00000000000 --- a/feature/qos/ate_tests/mixed_sp_wrr_traffic_test/README.md +++ /dev/null @@ -1,152 +0,0 @@ -# DP-1.10: Mixed strict priority and WRR traffic test - -## Summary - -Verify that DUT drops AF3, AF2, AF1, BE1 and BE0 before AF4 before NC1 and -forwards AF3, AF2, AF1, BE1 and BE0 based on weight. - -## QoS traffic test setup: - -* Topology: - - * 2 input interfaces and 1 output interface with the same port speed. The - interface can be a physical interface or LACP bundle interface with the - same aggregated speed. - - ``` - ATE port 1 - | - DUT--------ATE port 3 - | - ATE port 2 - ``` - -* Traffic classes: - - * We will use 7 traffic classes NC1, AF4, AF3, AF2, AF1, BE1 and BE0. - -* Traffic types: - - * All the traffic tests apply to both IPv4 and IPv6 traffic. - -* Queue types: - - * NC1 will have strict priority queues - * AF4/AF3/AF2/AF1/BE1/BE0 will use WRR queues. - * NC1 and AF4 will have strict priority queues with NC1 having higher - priority. - * AF3, AF2, AF1, BE1 and BE0 will use WRR queues. - -* Test results should be independent of the location of interfaces. For - example, 2 input interfaces and output interface could be located on - - * Same ASIC-based forwarding engine - * Different ASIC-based forwarding engine on same line card - * Different ASIC-based forwarding engine on different line cards - -* Test results should be the same for port speeds 100G and 400G. - -* Counters should be also verified for each test case: - - * /qos/interfaces/interface/output/queues/queue/state/transmit-pkts - * /qos/interfaces/interface/output/queues/queue/state/dropped-pkts - * transmit-pkts should be equal to the number of Rx pkts on Ixia port - * dropped-pkts should be equal to diff between the number of Tx and the - number Rx pkts on Ixia ports - -* Latency: - - * Should be < 100000ns - -## Procedure - -* Connect DUT port-1 to ATE port-1, DUT port-2 to ATE port-2 and DUT port-3 to - ATE port-3. - -* Configuration: - - * Configure strict priority queues for NC1 and AF4 with NC1 having higher - priority. - * Configure WRR for AF3, AF2, AF1, BE1 and BE0 with weight 32, 16, 8, 4 - and 1 respectively. - -* Non-oversubscription traffic test case - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Rx from interface1(%) | Rx from interface2(%) - ------------- | ----------------------- | ----------------------- | --------------------- | --------------------- - NC1 | 0.1 | 0.9 | 100 | 100 - Af4 | 18 | 20 | 100 | 100 - AF3 | 16 | 16 | 100 | 100 - AF2 | 8 | 8 | 100 | 100 - AF1 | 4 | 4 | 100 | 100 - BE0 | 2 | 2 | 100 | 100 - BE1 | 0.5 | 0.5 | 100 | 100 - -* Oversubscription traffic test case 1 - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Rx from interface1(%) | Rx from interface2(%) - ------------- | ----------------------- | ----------------------- | --------------------- | --------------------- - NC1 | 0.1 | 0.9 | 100 | 100 - Af4 | 50 | 49 | 100 | 100 - AF3 | 20 | 14 | 0 | 0 - AF2 | 14 | 24 | 0 | 0 - AF1 | 12 | 4 | 0 | 0 - BE0 | 1 | 7 | 0 | 0 - BE1 | 1 | 1 | 0 | 0 - -* Oversubscription traffic test case 2 - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Aggregate throughput(%) - ------------- | ----------------------- | ----------------------- | ----------------------- - NC1 | 0.1 | 0.9 | 100 - Af4 | 18 | 20 | 100 - AF3 | 40 | 24 | 50 - AF2 | 8 | 24 | 50 - AF1 | 12 | 4 | 50 - BE0 | 1 | 7 | 50 - BE1 | 1 | 1 | 50 - -## Config parameter coverage - -* Classifiers - - * /qos/classifiers/classifier/config/name - * /qos/classifiers/classifier/config/type - * /qos/classifiers/classifier/terms/term/actions/config/target-group - * /qos/classifiers/classifier/terms/term/conditions/ipv4/config/dscp-set - * qos/classifiers/classifier/terms/term/conditions/ipv6/config/dscp-set - * /qos/classifiers/classifier/terms/term/config/id - -* Forwarding Groups - - * /qos/forwarding-groups/forwarding-group/config/name - * /qos/forwarding-groups/forwarding-group/config/output-queue - -* Queue - - * /qos/queues/queue/config/name - -* Interfaces - - * /qos/interfaces/interface/input/classifiers/classifier/config/name - * /qos/interfaces/interface/output/queues/queue/config/name - * /qos/interfaces/interface/output/scheduler-policy/config/name - -* Scheduler policy - - * /qos/scheduler-policies/scheduler-policy/config/name - * /qos/scheduler-policies/scheduler - -policy/schedulers/scheduler/config/priority - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/sequence - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/id - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight - -## Telemetry parameter coverage - -* /qos/interfaces/interface/output/queues/queue/state/transmit-pkts -* /qos/interfaces/interface/output/queues/queue/state/transmit-octets -* /qos/interfaces/interface/output/queues/queue/state/dropped-pkts -* /qos/interfaces/interface/output/queues/queue/state/dropped-octets diff --git a/feature/qos/ate_tests/mixed_sp_wrr_traffic_test/metadata.textproto b/feature/qos/ate_tests/mixed_sp_wrr_traffic_test/metadata.textproto deleted file mode 100644 index 8cb261e51c8..00000000000 --- a/feature/qos/ate_tests/mixed_sp_wrr_traffic_test/metadata.textproto +++ /dev/null @@ -1,44 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "8e6a4bdd-7e4e-4c2a-90d8-55f3543f9e67" -plan_id: "DP-1.10" -description: "Mixed strict priority and WRR traffic test" -testbed: TESTBED_DUT_ATE_4LINKS -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - ipv4_missing_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: JUNIPER - } - deviations: { - explicit_interface_ref_definition: true - qos_dropped_octets: true - scheduler_input_weight_limit: true - } -} -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_interface_ref_definition: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - dequeue_delete_not_counted_as_drops: true - interface_enabled: true - qos_octets: true - } -} diff --git a/feature/qos/ate_tests/mixed_sp_wrr_traffic_test/mixed_sp_wrr_traffic_test.go b/feature/qos/ate_tests/mixed_sp_wrr_traffic_test/mixed_sp_wrr_traffic_test.go deleted file mode 100644 index 07230789e8d..00000000000 --- a/feature/qos/ate_tests/mixed_sp_wrr_traffic_test/mixed_sp_wrr_traffic_test.go +++ /dev/null @@ -1,1385 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package mixed_sp_wrr_traffic_test - -import ( - "testing" - "time" - - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/featureprofiles/internal/qoscfg" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ondatra/netutil" - "github.com/openconfig/ygot/ygot" -) - -type trafficData struct { - trafficRate float64 - expectedThroughputPct float32 - frameSize uint32 - dscp uint8 - queue string - inputIntf *ondatra.Interface -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// Test cases: -// 1) Non-oversubscription traffic. -// - There should be no packet drop for all traffic classes. -// 2) Oversubscription traffic case 1. -// - There should be no packet drop for strict priority traffic classes. -// - All WRR traffic should be dropped. -// 3) Oversubscription traffic case 2. -// - There should be no packet drop for strict priority traffic classes. -// - 50% of WRR traffic should be dropped. -// Details: https://github.com/openconfig/featureprofiles/blob/main/feature/qos/ate_tests/mixed_sp_wrr_traffic_test/README.md -// -// Topology: -// ATE port 1 -// | -// DUT--------ATE port 3 -// | -// ATE port 2 -// -// Sample CLI command to get telemetry using gmic: -// - gnmic -a ipaddr:10162 -u username -p password --skip-verify get \ -// --path /components/component --format flat -// - gnmic tool info: -// - https://github.com/karimra/gnmic/blob/main/README.md -// - -func TestMixedSPWrrTraffic(t *testing.T) { - dut := ondatra.DUT(t, "dut") - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - - // Configure DUT interfaces and QoS. - ConfigureDUTIntf(t, dut) - if dut.Vendor() == ondatra.CISCO { - ConfigureCiscoQos(t, dut) - } else { - ConfigureQoS(t, dut) - } - - // Configure ATE interfaces. - ate := ondatra.ATE(t, "ate") - ap1 := ate.Port(t, "port1") - ap2 := ate.Port(t, "port2") - ap3 := ate.Port(t, "port3") - top := ate.Topology().New() - intf1 := top.AddInterface("intf1").WithPort(ap1) - intf1.IPv4(). - WithAddress("198.51.100.1/31"). - WithDefaultGateway("198.51.100.0") - intf2 := top.AddInterface("intf2").WithPort(ap2) - intf2.IPv4(). - WithAddress("198.51.100.3/31"). - WithDefaultGateway("198.51.100.2") - intf3 := top.AddInterface("intf3").WithPort(ap3) - intf3.IPv4(). - WithAddress("198.51.100.5/31"). - WithDefaultGateway("198.51.100.4") - top.Push(t).StartProtocols(t) - - var tolerance float32 = 3.0 - queues := netutil.CommonTrafficQueues(t, dut) - - // Test case 1: Non-oversubscription traffic. - // - There should be no packet drop for all traffic classes. - NonoversubscribedTrafficFlows := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af4": { - frameSize: 1000, - trafficRate: 18, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-af3": { - frameSize: 1000, - trafficRate: 16, - expectedThroughputPct: 100.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 8, - expectedThroughputPct: 100.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 4, - expectedThroughputPct: 100.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 2, - expectedThroughputPct: 100.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 0.5, - dscp: 0, - expectedThroughputPct: 100.0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.9, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 20, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 16, - expectedThroughputPct: 100.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 8, - expectedThroughputPct: 100.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 4, - expectedThroughputPct: 100.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 2, - dscp: 4, - expectedThroughputPct: 100.0, - queue: queues.BE0, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 0.5, - expectedThroughputPct: 100.0, - dscp: 0, - queue: queues.BE1, - inputIntf: intf2, - }, - } - - // Test case 2: Oversubscription traffic case - // - There should be no packet drop for strict priority traffic classes. - // - All WRR traffic should be dropped. - oversubscribedTrafficFlows1 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af4": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-af3": { - frameSize: 1000, - trafficRate: 20, - expectedThroughputPct: 0.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 14, - expectedThroughputPct: 0.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 12, - expectedThroughputPct: 0.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 1, - expectedThroughputPct: 0.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 1, - dscp: 0, - expectedThroughputPct: 0.0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.9, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 49, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 14, - expectedThroughputPct: 0.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 24, - expectedThroughputPct: 0.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 4, - expectedThroughputPct: 0.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 7, - dscp: 4, - expectedThroughputPct: 0.0, - queue: queues.BE0, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 1, - expectedThroughputPct: 0.0, - dscp: 0, - queue: queues.BE1, - inputIntf: intf2, - }, - } - - // Test case 3: Oversubscription traffic case - // - There should be no packet drop for strict priority traffic classes. - // - 50% of WRR traffic should be dropped. - oversubscribedTrafficFlows2 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af4": { - frameSize: 1000, - trafficRate: 18, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-af3": { - frameSize: 1000, - trafficRate: 32, - expectedThroughputPct: 50.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 16, - expectedThroughputPct: 50.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 8, - expectedThroughputPct: 50.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 4, - expectedThroughputPct: 50.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 1, - dscp: 0, - expectedThroughputPct: 50.0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.9, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 20, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 32, - expectedThroughputPct: 50.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 16, - expectedThroughputPct: 50.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 8, - expectedThroughputPct: 50.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 4, - dscp: 4, - expectedThroughputPct: 50.0, - queue: queues.BE0, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 1, - expectedThroughputPct: 50.0, - dscp: 0, - queue: queues.BE1, - inputIntf: intf2, - }, - } - - cases := []struct { - desc string - trafficFlows map[string]*trafficData - }{{ - desc: "Non-oversubscription traffic", - trafficFlows: NonoversubscribedTrafficFlows, - }, { - desc: "Oversubscription traffic with all BE0-AF3 dropped", - trafficFlows: oversubscribedTrafficFlows1, - }, { - desc: "Oversubscription traffic with half BE0-AF3 dropped", - trafficFlows: oversubscribedTrafficFlows2, - }} - - for _, tc := range cases { - t.Run(tc.desc, func(t *testing.T) { - trafficFlows := tc.trafficFlows - - var flows []*ondatra.Flow - for trafficID, data := range trafficFlows { - t.Logf("Configuring flow %s", trafficID) - flow := ate.Traffic().NewFlow(trafficID). - WithSrcEndpoints(data.inputIntf). - WithDstEndpoints(intf3). - WithHeaders(ondatra.NewEthernetHeader(), ondatra.NewIPv4Header().WithDSCP(data.dscp)). - WithFrameRatePct(data.trafficRate). - WithFrameSize(data.frameSize) - flows = append(flows, flow) - } - - trafficInputRate := make(map[string]float64) - trafficOutputRate := make(map[string]float64) - var counterNames []string - counters := make(map[string]map[string]uint64) - - if !deviations.QOSDroppedOctets(dut) { - counterNames = []string{ - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedOctetsBeforeTraffic", "dutQosDroppedPktsAfterTraffic", - "dutQosDroppedOctetsAfterTraffic", - } - } else { - counterNames = []string{ - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedPktsAfterTraffic", - } - } - - for _, name := range counterNames { - counters[name] = make(map[string]uint64) - - // Set the initial counters to 0. - for _, data := range trafficFlows { - counters[name][data.queue] = 0 - } - } - - // Get QoS egress packet counters before the traffic. - for _, data := range trafficFlows { - counters["dutQosPktsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) - counters["dutQosOctetsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitOctets().State()) - counters["dutQosDroppedPktsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - if !deviations.QOSDroppedOctets(dut) { - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State()) - } - } - - t.Logf("Running traffic 1 on DUT interfaces: %s => %s ", dp1.Name(), dp3.Name()) - t.Logf("Running traffic 2 on DUT interfaces: %s => %s ", dp2.Name(), dp3.Name()) - t.Logf("Sending traffic flows: \n%v\n\n", trafficFlows) - ate.Traffic().Start(t, flows...) - time.Sleep(120 * time.Second) - ate.Traffic().Stop(t) - time.Sleep(30 * time.Second) - - for trafficID, data := range trafficFlows { - counters["ateOutPkts"][data.queue] += gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).Counters().OutPkts().State()) - counters["ateInPkts"][data.queue] += gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).Counters().InPkts().State()) - - counters["dutQosPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) - counters["dutQosOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitOctets().State()) - counters["dutQosDroppedPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - if !deviations.QOSDroppedOctets(dut) { - counters["dutQosDroppedOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State()) - } - t.Logf("ateInPkts: %v, txPkts %v, Queue: %v", counters["ateInPkts"][data.queue], counters["dutQosPktsAfterTraffic"][data.queue], data.queue) - - // Calculate aggregated throughput: - // (InputRate1*rxPct+InputRate2*rxPct)/(InputRate1+InputRate2) - _, ok := trafficInputRate[data.queue] - if !ok { - trafficInputRate[data.queue] = data.trafficRate - } else { - trafficInputRate[data.queue] += data.trafficRate - } - - lossPct := gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).LossPct().State()) - t.Logf("Get flow %q: lossPct: %.2f%% or rxPct: %.2f%%, want: %.2f%%\n\n", data.queue, lossPct, 100.0-lossPct, data.expectedThroughputPct) - _, ok = trafficOutputRate[data.queue] - if !ok { - trafficOutputRate[data.queue] = data.trafficRate * float64(100.0-lossPct) - } else { - trafficOutputRate[data.queue] += data.trafficRate * float64(100.0-lossPct) - got := trafficOutputRate[data.queue] / trafficInputRate[data.queue] - want := float64(data.expectedThroughputPct) - if got < want-float64(tolerance) || got > want+float64(tolerance) { - t.Errorf("Get(throughput for queue %q): got %.2f%%, want within [%.2f%%, %.2f%%]", data.queue, got, want-float64(tolerance), want+float64(tolerance)) - } - } - } - - // Check QoS egress packet counters are updated correctly. - for _, name := range counterNames { - t.Logf("QoS %s: %v", name, counters[name]) - } - - for _, data := range trafficFlows { - dutPktCounterDiff := counters["dutQosPktsAfterTraffic"][data.queue] - counters["dutQosPktsBeforeTraffic"][data.queue] - atePktCounterDiff := counters["ateInPkts"][data.queue] - t.Logf("Queue %q: atePktCounterDiff: %v dutPktCounterDiff: %v", data.queue, atePktCounterDiff, dutPktCounterDiff) - if dutPktCounterDiff < atePktCounterDiff { - t.Errorf("Get dutPktCounterDiff for queue %q: got %v, want >= %v", data.queue, dutPktCounterDiff, atePktCounterDiff) - } - - ateDropPktCounterDiff := counters["ateOutPkts"][data.queue] - counters["ateInPkts"][data.queue] - dutDropPktCounterDiff := counters["dutQosDroppedPktsAfterTraffic"][data.queue] - counters["dutQosDroppedPktsBeforeTraffic"][data.queue] - t.Logf("Queue %q: ateDropPktCounterDiff: %v dutDropPktCounterDiff: %v", data.queue, ateDropPktCounterDiff, dutDropPktCounterDiff) - if dutDropPktCounterDiff < ateDropPktCounterDiff { - if !deviations.DequeueDeleteNotCountedAsDrops(dut) { - t.Errorf("Get dutDropPktCounterDiff for queue %q: got %v, want >= %v", data.queue, dutDropPktCounterDiff, ateDropPktCounterDiff) - } - } - - dutOctetCounterDiff := counters["dutQosOctetsAfterTraffic"][data.queue] - counters["dutQosOctetsBeforeTraffic"][data.queue] - ateOctetCounterDiff := counters["ateInPkts"][data.queue] * uint64(data.frameSize) - t.Logf("Queue %q: ateOctetCounterDiff: %v dutOctetCounterDiff: %v", data.queue, ateOctetCounterDiff, dutOctetCounterDiff) - if !deviations.QOSOctets(dut) { - if dutOctetCounterDiff < ateOctetCounterDiff { - t.Errorf("Get dutOctetCounterDiff for queue %q: got %v, want >= %v", data.queue, dutOctetCounterDiff, ateOctetCounterDiff) - } - } - - if !deviations.QOSDroppedOctets(dut) { - ateDropOctetCounterDiff := (counters["ateOutPkts"][data.queue] - counters["ateInPkts"][data.queue]) * uint64(data.frameSize) - dutDropOctetCounterDiff := counters["dutQosDroppedOctetsAfterTraffic"][data.queue] - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] - t.Logf("Queue %q: ateDropOctetCounterDiff: %v dutDropOctetCounterDiff: %v", data.queue, ateDropOctetCounterDiff, dutDropOctetCounterDiff) - if dutDropOctetCounterDiff < ateDropOctetCounterDiff { - if !deviations.DequeueDeleteNotCountedAsDrops(dut) { - t.Errorf("Get dutDropOctetCounterDiff for queue %q: got %v, want >= %v", data.queue, dutDropOctetCounterDiff, ateDropOctetCounterDiff) - } - } - } - - } - }) - } -} - -func ConfigureDUTIntf(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - - dutIntfs := []struct { - desc string - intfName string - ipAddr string - prefixLen uint8 - }{{ - desc: "Input interface port1", - intfName: dp1.Name(), - ipAddr: "198.51.100.0", - prefixLen: 31, - }, { - desc: "Input interface port2", - intfName: dp2.Name(), - ipAddr: "198.51.100.2", - prefixLen: 31, - }, { - desc: "Output interface port3", - intfName: dp3.Name(), - ipAddr: "198.51.100.4", - prefixLen: 31, - }} - - // Configure the interfaces. - for _, intf := range dutIntfs { - t.Logf("Configure DUT interface %s with attributes %v", intf.intfName, intf) - i := &oc.Interface{ - Name: ygot.String(intf.intfName), - Description: ygot.String(intf.desc), - Type: oc.IETFInterfaces_InterfaceType_ethernetCsmacd, - Enabled: ygot.Bool(true), - } - i.GetOrCreateEthernet() - s := i.GetOrCreateSubinterface(0).GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) && !deviations.IPv4MissingEnabled(dut) { - s.Enabled = ygot.Bool(true) - } - a := s.GetOrCreateAddress(intf.ipAddr) - a.PrefixLength = ygot.Uint8(intf.prefixLen) - gnmi.Replace(t, dut, gnmi.OC().Interface(intf.intfName).Config(), i) - } -} - -func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - d := &oc.Root{} - q := d.GetOrCreateQos() - queues := netutil.CommonTrafficQueues(t, dut) - - t.Logf("Create qos forwarding groups config") - forwardingGroups := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - t.Logf("qos forwarding groups config: %v", forwardingGroups) - for _, tc := range forwardingGroups { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - } - - t.Logf("Create qos Classifiers config") - classifiers := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - t.Logf("qos Classifiers config: %v", classifiers) - for _, tc := range classifiers { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.name == "dscp_based_classifier_ipv4" { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.name == "dscp_based_classifier_ipv6" { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos input classifier config") - classifierIntfs := []struct { - desc string - intf string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }, { - desc: "Input Classifier Type IPV4", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - t.Logf("qos input classifier config: %v", classifierIntfs) - for _, tc := range classifierIntfs { - qoscfg.SetInputClassifier(t, dut, q, tc.intf, tc.inputClassifierType, tc.classifier) - } - - nc1InputWeight := uint64(200) - af4InputWeight := uint64(100) - if deviations.SchedulerInputWeightLimit(dut) { - nc1InputWeight = uint64(100) - af4InputWeight = uint64(99) - } - - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - priority oc.E_Scheduler_Priority - inputID string - inputType oc.E_Input_InputType - weight uint64 - queueName string - targetGroup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE0", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(4), - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(8), - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF2", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(16), - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF3", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(32), - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "AF4", - inputType: oc.Input_InputType_QUEUE, - weight: af4InputWeight, - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - inputType: oc.Input_InputType_QUEUE, - weight: nc1InputWeight, - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - s.SetPriority(tc.priority) - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - input.SetInputType(tc.inputType) - input.SetQueue(tc.queueName) - input.SetWeight(tc.weight) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - scheduler string - }{{ - desc: "output-interface-BE1", - queueName: queues.BE1, - scheduler: "scheduler", - }, { - desc: "output-interface-BE0", - queueName: queues.BE0, - scheduler: "scheduler", - }, { - desc: "output-interface-AF1", - queueName: queues.AF1, - scheduler: "scheduler", - }, { - desc: "output-interface-AF2", - queueName: queues.AF2, - scheduler: "scheduler", - }, { - desc: "output-interface-AF3", - queueName: queues.AF3, - scheduler: "scheduler", - }, { - desc: "output-interface-AF4", - queueName: queues.AF4, - scheduler: "scheduler", - }, { - desc: "output-interface-NC1", - queueName: queues.NC1, - scheduler: "scheduler", - }} - - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp3.Name()) - i.SetInterfaceId(dp3.Name()) - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) - if deviations.InterfaceRefConfigUnsupported(dut) { - i.InterfaceRef = nil - } - output := i.GetOrCreateOutput() - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName(tc.scheduler) - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } -} - -func ConfigureCiscoQos(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - d := &oc.Root{} - q := d.GetOrCreateQos() - t.Logf("Create qos Classifiers config") - classifiers := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - t.Logf("qos Classifiers config: %v", classifiers) - queueName := []string{"NC1", "AF4", "AF3", "AF2", "AF1", "BE0", "BE1"} - - for i, queue := range queueName { - q1 := q.GetOrCreateQueue(queue) - q1.Name = ygot.String(queue) - queueid := len(queueName) - i - q1.QueueId = ygot.Uint8(uint8(queueid)) - - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - casesfwdgrp := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: "BE1", - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: "BE0", - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: "AF1", - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: "AF2", - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: "AF3", - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: "AF4", - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: "NC1", - targetGroup: "target-group-NC1", - }} - t.Logf("qos forwarding groups config cases: %v", casesfwdgrp) - for _, tc := range casesfwdgrp { - t.Run(tc.desc, func(t *testing.T) { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - }) - } - for _, tc := range classifiers { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.classType == oc.Qos_Classifier_Type_IPV4 { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.classType == oc.Qos_Classifier_Type_IPV6 { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos input classifier config") - classifierIntfs := []struct { - desc string - intf string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }, { - desc: "Input Classifier Type IPV4", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - t.Logf("qos input classifier config: %v", classifierIntfs) - for _, tc := range classifierIntfs { - qoscfg.SetInputClassifier(t, dut, q, tc.intf, tc.inputClassifierType, tc.classifier) - } - - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - priority oc.E_Scheduler_Priority - inputID string - inputType oc.E_Input_InputType - weight uint64 - queueName string - targetGroup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: "BE1", - targetGroup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE0", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(4), - queueName: "BE0", - targetGroup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(8), - queueName: "AF1", - targetGroup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF2", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(16), - queueName: "AF2", - targetGroup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF3", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(32), - queueName: "AF3", - targetGroup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "AF4", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(6), - queueName: "AF4", - targetGroup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(7), - queueName: "NC1", - targetGroup: "target-group-NC1", - }} - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - s.SetPriority(tc.priority) - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - input.SetInputType(tc.inputType) - input.SetQueue(tc.queueName) - input.SetWeight(tc.weight) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - scheduler string - }{{ - desc: "output-interface-NC1", - queueName: "NC1", - scheduler: "scheduler", - }, { - desc: "output-interface-AF4", - queueName: "AF4", - scheduler: "scheduler", - }, { - desc: "output-interface-AF3", - queueName: "AF3", - scheduler: "scheduler", - }, { - desc: "output-interface-AF2", - queueName: "AF2", - scheduler: "scheduler", - }, { - desc: "output-interface-AF1", - queueName: "AF1", - scheduler: "scheduler", - }, { - desc: "output-interface-BE0", - queueName: "BE0", - scheduler: "scheduler", - }, { - desc: "output-interface-BE1", - queueName: "BE1", - scheduler: "scheduler", - }} - - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp3.Name()) - i.SetInterfaceId(dp3.Name()) - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) - output := i.GetOrCreateOutput() - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName(tc.scheduler) - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - -} diff --git a/feature/qos/ate_tests/one_sp_queue_traffic_test/README.md b/feature/qos/ate_tests/one_sp_queue_traffic_test/README.md deleted file mode 100644 index d2cd200b781..00000000000 --- a/feature/qos/ate_tests/one_sp_queue_traffic_test/README.md +++ /dev/null @@ -1,138 +0,0 @@ -# DP-1.7: One strict priority queue traffic test - -## Summary - -Verify that DUT drops AF4, AF3, AF2, AF1, BE1 and BE0 before NC1. - -## QoS traffic test setup: - -* Topology: - - * 2 input interfaces and 1 output interface with the same port speed. The - interface can be a physical interface or LACP bundle interface with the - same aggregated speed. - - ``` - ATE port 1 - | - DUT--------ATE port 3 - | - ATE port 2 - ``` - -* Traffic classes: - - * We will use 7 traffic classes NC1, AF4, AF3, AF2, AF1, BE0 and BE1. - -* Traffic types: - - * All the traffic tests apply to both IPv4 and IPv6 traffic. - -* Queue types: - - * NC1 will have strict priority queues - * AF4/AF3/AF2/AF1/BE1/BE0 will use WRR queues. - * NC1 and AF4 will have strict priority queues with NC1 having higher - priority. - * AF3, AF2, AF1, BE1 and BE0 will use WRR queues. - -* Test results should be independent of the location of interfaces. For - example, 2 input interfaces and output interface could be located on - - * Same ASIC-based forwarding engine - * Different ASIC-based forwarding engine on same line card - * Different ASIC-based forwarding engine on different line cards - -* Test results should be the same for port speeds 100G and 400G. - -* Counters should be also verified for each test case: - - * /qos/interfaces/interface/output/queues/queue/state/transmit-pkts - * /qos/interfaces/interface/output/queues/queue/state/dropped-pkts - * transmit-pkts should be equal to the number of Rx pkts on Ixia port - * dropped-pkts should be equal to diff between the number of Tx and the - number Rx pkts on Ixia ports - -* Latency: - - * Should be < 100000ns - -## Procedure - -* Connect DUT port-1 to ATE port-1, DUT port-2 to ATE port-2 and DUT port-3 to - ATE port-3. - -* Configuration - - * Configure strict priority queue for NC1. - * Configure WRR for AF4, AF3, AF2, AF1, BE1 and BE0 with weight 48, 12, 8, - 4, 2 and 1 respectively. - -* NC1 vs AF4 traffic test - - * Non-oversubscription traffic test case - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Rx from interface1(%) | Rx from interface2(%) - ------------- | ----------------------- | ----------------------- | --------------------- | --------------------- - NC1 | 0.1 | 0.7 | 100 | 100 - AF4 | 45.1 | 54.1 | 100 | 100 - - * Oversubscription traffic test case - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Rx from interface1(%) | Rx from interface2(%) - ------------- | ----------------------- | ----------------------- | --------------------- | --------------------- - NC1 | 0.1 | 0.7 | 100 | 100 - AF4 | 99.9 | 99.3 | 49.8 | 49.8 - -* Repeat the above 2 test cases between traffic classes: - - * NC1 vs AF3 - * NC1 vs AF2 - * NC1 vs AF1 - * NC1 vs BE1 - * NC1 vs BE0 - -## Config parameter coverage - -* Classifiers - - * /qos/classifiers/classifier/config/name - * /qos/classifiers/classifier/config/type - * /qos/classifiers/classifier/terms/term/actions/config/target-group - * /qos/classifiers/classifier/terms/term/conditions/ipv4/config/dscp-set - * qos/classifiers/classifier/terms/term/conditions/ipv6/config/dscp-set - * /qos/classifiers/classifier/terms/term/config/id - -* Forwarding Groups - - * /qos/forwarding-groups/forwarding-group/config/name - * /qos/forwarding-groups/forwarding-group/config/output-queue - -* Queue - - * /qos/queues/queue/config/name - -* Interfaces - - * /qos/interfaces/interface/input/classifiers/classifier/config/name - * /qos/interfaces/interface/output/queues/queue/config/name - * /qos/interfaces/interface/output/scheduler-policy/config/name - -* Scheduler policy - - * /qos/scheduler-policies/scheduler-policy/config/name - * /qos/scheduler-policies/scheduler - -policy/schedulers/scheduler/config/priority - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/sequence - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/id - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight - -## Telemetry parameter coverage - -* /qos/interfaces/interface/output/queues/queue/state/transmit-pkts -* /qos/interfaces/interface/output/queues/queue/state/transmit-octets -* /qos/interfaces/interface/output/queues/queue/state/dropped-pkts -* /qos/interfaces/interface/output/queues/queue/state/dropped-octets diff --git a/feature/qos/ate_tests/one_sp_queue_traffic_test/metadata.textproto b/feature/qos/ate_tests/one_sp_queue_traffic_test/metadata.textproto deleted file mode 100644 index 4c8748ec05e..00000000000 --- a/feature/qos/ate_tests/one_sp_queue_traffic_test/metadata.textproto +++ /dev/null @@ -1,40 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "50dd5501-d9c8-4888-9d9d-00f3c51e606f" -plan_id: "DP-1.7" -description: "One strict priority queue traffic test" -testbed: TESTBED_DUT_ATE_4LINKS -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - ipv4_missing_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: JUNIPER - } - deviations: { - explicit_interface_ref_definition: true - } -} -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_interface_ref_definition: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - interface_enabled: true - } -} diff --git a/feature/qos/ate_tests/one_sp_queue_traffic_test/one_sp_queue_traffic_test.go b/feature/qos/ate_tests/one_sp_queue_traffic_test/one_sp_queue_traffic_test.go deleted file mode 100644 index 5b516e26e85..00000000000 --- a/feature/qos/ate_tests/one_sp_queue_traffic_test/one_sp_queue_traffic_test.go +++ /dev/null @@ -1,1452 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package one_sp_queue_traffic_test - -import ( - "testing" - "time" - - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/featureprofiles/internal/qoscfg" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ondatra/netutil" - "github.com/openconfig/ygot/ygot" -) - -type trafficData struct { - trafficRate float64 - expectedThroughputPct float32 - frameSize uint32 - dscp uint8 - queue string - inputIntf *ondatra.Interface -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// Test cases: -// 1) Non-oversubscription NC1 and AF4 traffic. -// - There should be no packet drop for all traffic classes. -// 2) Non-oversubscription NC1 and AF3 traffic. -// - There should be no packet drop for all traffic classes. -// 3) Non-oversubscription NC1 and AF2 traffic. -// - There should be no packet drop for all traffic classes. -// 4) Non-oversubscription NC1 and AF1 traffic. -// - There should be no packet drop for all traffic classes. -// 5) Non-oversubscription NC1 and BE0 traffic. -// - There should be no packet drop for all traffic classes. -// 6) Non-oversubscription NC1 and BE1 traffic. -// - There should be no packet drop for all traffic classes. -// 7) Oversubscription NC1 and AF4 traffic. -// - There should be no packet drop for strict priority traffic class. -// 8) Oversubscription NC1 and AF3 traffic. -// - There should be no packet drop for strict priority traffic class. -// 9) Oversubscription NC1 and AF2 traffic. -// - There should be no packet drop for strict priority traffic class. -// 10) Oversubscription NC1 and AF1 traffic. -// - There should be no packet drop for strict priority traffic class. -// 11) Oversubscription NC1 and BE0 traffic. -// - There should be no packet drop for strict priority traffic class. -// 12) Oversubscription NC1 and BE1 traffic. -// - There should be no packet drop for strict priority traffic class. -// -// Topology: -// ATE port 1 -// | -// DUT--------ATE port 3 -// | -// ATE port 2 -// -// Sample CLI command to get telemetry using gmic: -// - gnmic -a ipaddr:10162 -u username -p password --skip-verify get \ -// --path /components/component --format flat -// - gnmic tool info: -// - https://github.com/karimra/gnmic/blob/main/README.md -// - -func TestOneSPQueueTraffic(t *testing.T) { - dut := ondatra.DUT(t, "dut") - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - - // Configure DUT interfaces and QoS. - ConfigureDUTIntf(t, dut) - if dut.Vendor() == ondatra.CISCO { - ConfigureCiscoQos(t, dut) - } else { - ConfigureQoS(t, dut) - } - - // Configure ATE interfaces. - ate := ondatra.ATE(t, "ate") - ap1 := ate.Port(t, "port1") - ap2 := ate.Port(t, "port2") - ap3 := ate.Port(t, "port3") - top := ate.Topology().New() - intf1 := top.AddInterface("intf1").WithPort(ap1) - intf1.IPv4(). - WithAddress("198.51.100.1/31"). - WithDefaultGateway("198.51.100.0") - intf2 := top.AddInterface("intf2").WithPort(ap2) - intf2.IPv4(). - WithAddress("198.51.100.3/31"). - WithDefaultGateway("198.51.100.2") - intf3 := top.AddInterface("intf3").WithPort(ap3) - intf3.IPv4(). - WithAddress("198.51.100.5/31"). - WithDefaultGateway("198.51.100.4") - top.Push(t).StartProtocols(t) - - var tolerance float32 = 2.0 - queues := netutil.CommonTrafficQueues(t, dut) - if dut.Vendor() == ondatra.JUNIPER { - queues.AF4 = "5" - } - // Test case 1: Non-oversubscription NC1 and AF4 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows1 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af4": { - frameSize: 1000, - trafficRate: 45.1, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 54.1, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - } - - // Test case 2: Non-oversubscription NC1 and AF3 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows2 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af3": { - frameSize: 1000, - trafficRate: 45.1, - expectedThroughputPct: 100.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 54.1, - dscp: 24, - expectedThroughputPct: 100.0, - queue: queues.AF3, - inputIntf: intf2, - }, - } - - // Test case 3: Non-oversubscription NC1 and AF2 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows3 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 45.1, - expectedThroughputPct: 100.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 54.1, - dscp: 19, - expectedThroughputPct: 100.0, - queue: queues.AF2, - inputIntf: intf2, - }, - } - - // Test case 4: Non-oversubscription NC1 and AF1 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows4 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 45.1, - expectedThroughputPct: 100.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 54.1, - dscp: 8, - expectedThroughputPct: 100.0, - queue: queues.AF1, - inputIntf: intf2, - }, - } - - // Test case 5: Non-oversubscription NC1 and BE0 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows5 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 45.1, - expectedThroughputPct: 100.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 54.1, - dscp: 4, - expectedThroughputPct: 100.0, - queue: queues.BE0, - inputIntf: intf2, - }, - } - - // Test case 6: Non-oversubscription NC1 and BE1 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows6 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 45.1, - expectedThroughputPct: 100.0, - dscp: 0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 54.1, - dscp: 0, - expectedThroughputPct: 100.0, - queue: queues.BE1, - inputIntf: intf2, - }, - } - - // Test case 7: Oversubscription NC1 and AF4 traffic. - // - There should be no packet drop for strict priority traffic class. - oversubscribedTrafficFlows1 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af4": { - frameSize: 1000, - trafficRate: 99.9, - expectedThroughputPct: 49.8, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 99.3, - dscp: 32, - expectedThroughputPct: 49.8, - queue: queues.AF4, - inputIntf: intf2, - }, - } - - // Test case 8: Oversubscription NC1 and AF3 traffic. - // - There should be no packet drop for strict priority traffic class. - oversubscribedTrafficFlows2 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af3": { - frameSize: 1000, - trafficRate: 99.9, - expectedThroughputPct: 49.8, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 99.3, - dscp: 24, - expectedThroughputPct: 49.8, - queue: queues.AF3, - inputIntf: intf2, - }, - } - - // Test case 9: Oversubscription NC1 and AF2 traffic. - // - There should be no packet drop for strict priority traffic class. - oversubscribedTrafficFlows3 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 99.9, - expectedThroughputPct: 49.8, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 99.3, - dscp: 16, - expectedThroughputPct: 49.8, - queue: queues.AF2, - inputIntf: intf2, - }, - } - - // Test case 10: Oversubscription NC1 and AF1 traffic. - // - There should be no packet drop for strict priority traffic class. - oversubscribedTrafficFlows4 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 99.9, - expectedThroughputPct: 49.8, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 99.3, - dscp: 8, - expectedThroughputPct: 49.8, - queue: queues.AF1, - inputIntf: intf2, - }, - } - - // Test case 11: Oversubscription NC1 and BE0 traffic. - // - There should be no packet drop for strict priority traffic class. - oversubscribedTrafficFlows5 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 99.9, - expectedThroughputPct: 49.8, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 99.3, - dscp: 4, - expectedThroughputPct: 49.8, - queue: queues.BE0, - inputIntf: intf2, - }, - } - - // Test case 12: Oversubscription NC1 and BE1 traffic. - // - There should be no packet drop for strict priority traffic class. - oversubscribedTrafficFlows6 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 99.9, - expectedThroughputPct: 49.8, - dscp: 0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.BE1, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 99.3, - dscp: 0, - expectedThroughputPct: 49.8, - queue: queues.BE1, - inputIntf: intf2, - }, - } - - cases := []struct { - desc string - trafficFlows map[string]*trafficData - }{{ - desc: "Non-oversubscription NC1 and AF4 traffic", - trafficFlows: nonOversubscribedTrafficFlows1, - }, { - desc: "Non-oversubscription NC1 and AF3 traffic", - trafficFlows: nonOversubscribedTrafficFlows2, - }, { - desc: "Non-oversubscription NC1 and AF2 traffic", - trafficFlows: nonOversubscribedTrafficFlows3, - }, { - desc: "Non-oversubscription NC1 and AF1 traffic", - trafficFlows: nonOversubscribedTrafficFlows4, - }, { - desc: "Non-oversubscription NC1 and BE0 traffic", - trafficFlows: nonOversubscribedTrafficFlows5, - }, { - desc: "Non-oversubscription NC1 and BE1 traffic", - trafficFlows: nonOversubscribedTrafficFlows6, - }, { - desc: "Oversubscription NC1 and AF4 traffic with half AF4 dropped", - trafficFlows: oversubscribedTrafficFlows1, - }, { - desc: "Oversubscription NC1 and AF3 traffic with half AF3 dropped", - trafficFlows: oversubscribedTrafficFlows2, - }, { - desc: "Oversubscription NC1 and AF2 traffic with half AF2 dropped", - trafficFlows: oversubscribedTrafficFlows3, - }, { - desc: "Oversubscription NC1 and AF1 traffic with half AF1 dropped", - trafficFlows: oversubscribedTrafficFlows4, - }, { - desc: "Oversubscription NC1 and BE0 traffic with half BE0 dropped", - trafficFlows: oversubscribedTrafficFlows5, - }, { - desc: "Oversubscription NC1 and BE1 traffic with half BE1 dropped", - trafficFlows: oversubscribedTrafficFlows6, - }} - - for _, tc := range cases { - t.Run(tc.desc, func(t *testing.T) { - trafficFlows := tc.trafficFlows - - var flows []*ondatra.Flow - for trafficID, data := range trafficFlows { - t.Logf("Configuring flow %s", trafficID) - flow := ate.Traffic().NewFlow(trafficID). - WithSrcEndpoints(data.inputIntf). - WithDstEndpoints(intf3). - WithHeaders(ondatra.NewEthernetHeader(), ondatra.NewIPv4Header().WithDSCP(data.dscp)). - WithFrameRatePct(data.trafficRate). - WithFrameSize(data.frameSize) - flows = append(flows, flow) - } - - ateOutPkts := make(map[string]uint64) - ateInPkts := make(map[string]uint64) - dutQosPktsBeforeTraffic := make(map[string]uint64) - dutQosPktsAfterTraffic := make(map[string]uint64) - dutQosDroppedPktsBeforeTraffic := make(map[string]uint64) - dutQosDroppedPktsAfterTraffic := make(map[string]uint64) - - // Set the initial counters to 0. - for _, data := range trafficFlows { - ateOutPkts[data.queue] = 0 - ateInPkts[data.queue] = 0 - dutQosPktsBeforeTraffic[data.queue] = 0 - dutQosPktsAfterTraffic[data.queue] = 0 - dutQosDroppedPktsBeforeTraffic[data.queue] = 0 - dutQosDroppedPktsAfterTraffic[data.queue] = 0 - } - - // Get QoS egress packet counters before the traffic. - for _, data := range trafficFlows { - dutQosPktsBeforeTraffic[data.queue] += gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) - dutQosDroppedPktsBeforeTraffic[data.queue] += gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - } - - t.Logf("Running traffic 1 on DUT interfaces: %s => %s ", dp1.Name(), dp3.Name()) - t.Logf("Running traffic 2 on DUT interfaces: %s => %s ", dp2.Name(), dp3.Name()) - t.Logf("Sending traffic flows: \n%v\n\n", trafficFlows) - ate.Traffic().Start(t, flows...) - time.Sleep(30 * time.Second) - ate.Traffic().Stop(t) - time.Sleep(30 * time.Second) - - for trafficID, data := range trafficFlows { - ateOutPkts[data.queue] += gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).Counters().OutPkts().State()) - ateInPkts[data.queue] += gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).Counters().InPkts().State()) - dutQosPktsAfterTraffic[data.queue] += gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) - dutQosDroppedPktsAfterTraffic[data.queue] += gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - t.Logf("ateInPkts: %v, txPkts %v, Queue: %v", ateInPkts[data.queue], dutQosPktsAfterTraffic[data.queue], data.queue) - - lossPct := gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).LossPct().State()) - t.Logf("Get flow %q: lossPct: %.2f%% or rxPct: %.2f%%, want: %.2f%%\n\n", data.queue, lossPct, 100.0-lossPct, data.expectedThroughputPct) - if got, want := 100.0-lossPct, data.expectedThroughputPct; got < want-tolerance || got > want+tolerance { - t.Errorf("Get(throughput for queue %q): got %.2f%%, want within [%.2f%%, %.2f%%]", data.queue, got, want-tolerance, want+tolerance) - } - } - - // Check QoS egress packet counters are updated correctly. - t.Logf("QoS dutQosPktsBeforeTraffic: %v", dutQosPktsBeforeTraffic) - t.Logf("QoS dutQosPktsAfterTraffic: %v", dutQosPktsAfterTraffic) - t.Logf("QoS dutQosDroppedPktsBeforeTraffic: %v", dutQosDroppedPktsBeforeTraffic) - t.Logf("QoS dutQosDroppedPktsAfterTraffic: %v", dutQosDroppedPktsAfterTraffic) - t.Logf("QoS ateOutPkts: %v", ateOutPkts) - t.Logf("QoS ateInPkts: %v", ateInPkts) - for _, data := range trafficFlows { - qosCounterDiff := dutQosPktsAfterTraffic[data.queue] - dutQosPktsBeforeTraffic[data.queue] - ateCounterDiff := ateInPkts[data.queue] - ateDropCounterDiff := ateOutPkts[data.queue] - ateInPkts[data.queue] - dutDropCounterDiff := dutQosDroppedPktsAfterTraffic[data.queue] - dutQosDroppedPktsBeforeTraffic[data.queue] - t.Logf("QoS queue %q: ateDropCounterDiff: %v dutDropCounterDiff: %v", data.queue, ateDropCounterDiff, dutDropCounterDiff) - if qosCounterDiff < ateCounterDiff { - t.Errorf("Get telemetry packet update for queue %q: got %v, want >= %v", data.queue, qosCounterDiff, ateCounterDiff) - } - } - }) - } -} - -func ConfigureDUTIntf(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - - dutIntfs := []struct { - desc string - intfName string - ipAddr string - prefixLen uint8 - }{{ - desc: "Input interface port1", - intfName: dp1.Name(), - ipAddr: "198.51.100.0", - prefixLen: 31, - }, { - desc: "Input interface port2", - intfName: dp2.Name(), - ipAddr: "198.51.100.2", - prefixLen: 31, - }, { - desc: "Output interface port3", - intfName: dp3.Name(), - ipAddr: "198.51.100.4", - prefixLen: 31, - }} - - // Configure the interfaces. - for _, intf := range dutIntfs { - t.Logf("Configure DUT interface %s with attributes %v", intf.intfName, intf) - i := &oc.Interface{ - Name: ygot.String(intf.intfName), - Description: ygot.String(intf.desc), - Type: oc.IETFInterfaces_InterfaceType_ethernetCsmacd, - Enabled: ygot.Bool(true), - } - i.GetOrCreateEthernet() - s := i.GetOrCreateSubinterface(0).GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) && !deviations.IPv4MissingEnabled(dut) { - s.Enabled = ygot.Bool(true) - } - a := s.GetOrCreateAddress(intf.ipAddr) - a.PrefixLength = ygot.Uint8(intf.prefixLen) - gnmi.Replace(t, dut, gnmi.OC().Interface(intf.intfName).Config(), i) - } -} - -func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - d := &oc.Root{} - q := d.GetOrCreateQos() - queues := netutil.CommonTrafficQueues(t, dut) - if dut.Vendor() == ondatra.JUNIPER { - queues.AF4 = "5" - } - - t.Logf("Create qos forwarding groups config") - forwardingGroups := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - t.Logf("qos forwarding groups config: %v", forwardingGroups) - for _, tc := range forwardingGroups { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - } - - t.Logf("Create qos Classifiers config") - classifiers := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - t.Logf("qos Classifiers config: %v", classifiers) - for _, tc := range classifiers { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.name == "dscp_based_classifier_ipv4" { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.name == "dscp_based_classifier_ipv6" { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos input classifier config") - classifierIntfs := []struct { - desc string - intf string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }, { - desc: "Input Classifier Type IPV4", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - t.Logf("qos input classifier config: %v", classifierIntfs) - for _, tc := range classifierIntfs { - qoscfg.SetInputClassifier(t, dut, q, tc.intf, tc.inputClassifierType, tc.classifier) - } - - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - priority oc.E_Scheduler_Priority - inputID string - inputType oc.E_Input_InputType - weight uint64 - queueName string - targetGroup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE0", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(2), - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(4), - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF2", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(8), - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF3", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(12), - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF4", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(48), - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(100), - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - s.SetPriority(tc.priority) - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - input.SetInputType(tc.inputType) - input.SetQueue(tc.queueName) - input.SetWeight(tc.weight) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - scheduler string - }{{ - desc: "output-interface-BE1", - queueName: queues.BE1, - scheduler: "scheduler", - }, { - desc: "output-interface-BE0", - queueName: queues.BE0, - scheduler: "scheduler", - }, { - desc: "output-interface-AF1", - queueName: queues.AF1, - scheduler: "scheduler", - }, { - desc: "output-interface-AF2", - queueName: queues.AF2, - scheduler: "scheduler", - }, { - desc: "output-interface-AF3", - queueName: queues.AF3, - scheduler: "scheduler", - }, { - desc: "output-interface-AF4", - queueName: queues.AF4, - scheduler: "scheduler", - }, { - desc: "output-interface-NC1", - queueName: queues.NC1, - scheduler: "scheduler", - }} - - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp3.Name()) - i.SetInterfaceId(dp3.Name()) - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) - if deviations.InterfaceRefConfigUnsupported(dut) { - i.InterfaceRef = nil - } - output := i.GetOrCreateOutput() - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName(tc.scheduler) - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } -} -func ConfigureCiscoQos(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - d := &oc.Root{} - q := d.GetOrCreateQos() - - t.Logf("Create qos Classifiers config") - classifiers := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - t.Logf("qos Classifiers config: %v", classifiers) - queueName := []string{"NC1", "AF4", "AF3", "AF2", "AF1", "BE0", "BE1"} - - for i, queue := range queueName { - q1 := q.GetOrCreateQueue(queue) - q1.Name = ygot.String(queue) - queueid := len(queueName) - i - q1.QueueId = ygot.Uint8(uint8(queueid)) - - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - casesfwdgrp := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: "BE1", - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: "BE0", - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: "AF1", - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: "AF2", - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: "AF3", - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: "AF4", - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: "NC1", - targetGroup: "target-group-NC1", - }} - t.Logf("qos forwarding groups config cases: %v", casesfwdgrp) - for _, tc := range casesfwdgrp { - t.Run(tc.desc, func(t *testing.T) { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - }) - } - for _, tc := range classifiers { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.classType == oc.Qos_Classifier_Type_IPV4 { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.classType == oc.Qos_Classifier_Type_IPV6 { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos input classifier config") - classifierIntfs := []struct { - desc string - intf string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }, { - desc: "Input Classifier Type IPV4", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - t.Logf("qos input classifier config: %v", classifierIntfs) - for _, tc := range classifierIntfs { - qoscfg.SetInputClassifier(t, dut, q, tc.intf, tc.inputClassifierType, tc.classifier) - } - - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - priority oc.E_Scheduler_Priority - inputID string - inputType oc.E_Input_InputType - weight uint64 - queueName string - targetGroup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: "BE1", - targetGroup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE0", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(2), - queueName: "BE0", - targetGroup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(4), - queueName: "AF1", - targetGroup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF2", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(8), - queueName: "AF2", - targetGroup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF3", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(12), - queueName: "AF3", - targetGroup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF4", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(48), - queueName: "AF4", - targetGroup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(7), - queueName: "NC1", - targetGroup: "target-group-NC1", - }} - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - s.SetPriority(tc.priority) - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - //input.SetInputType(tc.inputType) - input.SetQueue(tc.queueName) - input.SetWeight(tc.weight) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - scheduler string - }{{ - desc: "output-interface-NC1", - queueName: "NC1", - scheduler: "scheduler", - }, { - desc: "output-interface-AF4", - queueName: "AF4", - scheduler: "scheduler", - }, { - desc: "output-interface-AF3", - queueName: "AF3", - scheduler: "scheduler", - }, { - desc: "output-interface-AF2", - queueName: "AF2", - scheduler: "scheduler", - }, { - desc: "output-interface-AF1", - queueName: "AF1", - scheduler: "scheduler", - }, { - desc: "output-interface-BE0", - queueName: "BE0", - scheduler: "scheduler", - }, { - desc: "output-interface-BE1", - queueName: "BE1", - scheduler: "scheduler", - }} - - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp3.Name()) - i.SetInterfaceId(dp3.Name()) - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) - output := i.GetOrCreateOutput() - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName(tc.scheduler) - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) -} diff --git a/feature/qos/ate_tests/qos_basic_test/README.md b/feature/qos/ate_tests/qos_basic_test/README.md deleted file mode 100644 index e107301c2ee..00000000000 --- a/feature/qos/ate_tests/qos_basic_test/README.md +++ /dev/null @@ -1,140 +0,0 @@ -# DP-1.14: QoS basic test - -## Summary - -Verify that DUT supports QoS config and forward QoS traffic correctly. - -## QoS traffic test setup: - -* Topology: - - * 2 input interfaces and 1 output interface with the same port speed. The - interface can be a physical interface or LACP bundle interface with the - same aggregated speed. - - ``` - ATE port 1 - | - DUT--------ATE port 3 - | - ATE port 2 - ``` - -* Traffic classes: - - * We will use 7 traffic classes NC1, AF4, AF3, AF2, AF1, BE0 and BE1. - -* Traffic types: - - * All the traffic tests apply to both IPv4 and IPv6 traffic. - -* Queue types: - - * NC1 will have strict priority queues - * AF4/AF3/AF2/AF1/BE1/BE0 will use WRR queues. - * NC1 and AF4 will have strict priority queues with NC1 having higher - priority. - * AF3, AF2, AF1, BE1 and BE0 will use WRR queues. - -* Test results should be independent of the location of interfaces. For - example, 2 input interfaces and output interface could be located on - - * Same ASIC-based forwarding engine - * Different ASIC-based forwarding engine on same line card - * Different ASIC-based forwarding engine on different line cards - -* Test results should be the same for port speeds 100G and 400G. - -* Counters should be also verified for each test case: - - * /qos/interfaces/interface/output/queues/queue/state/transmit-pkts - * /qos/interfaces/interface/output/queues/queue/state/dropped-pkts - * transmit-pkts should be equal to the number of Rx pkts on Ixia port - * dropped-pkts should be equal to diff between the number of Tx and the - number Rx pkts on Ixia ports - -* Latency: - - * Should be < 100000ns - -## Procedure - -* Connect DUT port-1 to ATE port-1, DUT port-2 to ATE port-2 and DUT port-3 to - ATE port-3. - -* Configuration: - - * Configure strict priority queues for NC1. - * Configure WRR for AF4, AF3, AF2, AF1, BE0 and BE1 with weight 48, 12, 8, 4, 1 - and 1 respectively. - -* Non-oversubscription traffic test case 1 with 80% of aggregated linerate - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Rx from interface1(%) | Rx from interface2(%) - ------------- | ----------------------- | ----------------------- | --------------------- | --------------------- - NC1 | 3 | 3 | 100 | 100 - Af4 | 24 | 24 | 100 | 100 - AF3 | 6 | 6 | 100 | 100 - AF2 | 4 | 4 | 100 | 100 - AF1 | 2 | 2 | 100 | 100 - BE0 | 0.5 | 0.5 | 100 | 100 - BE1 | 0.5 | 0.5 | 100 | 100 - -* Non-oversubscription traffic test case 2 with 98% of aggregated linerate - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Rx from interface1(%) | Rx from interface2(%) - ------------- | ----------------------- | ----------------------- | --------------------- | --------------------- - NC1 | 5 | 4 | 100 | 100 - Af4 | 30 | 30 | 100 | 100 - AF3 | 7.5 | 7.5 | 100 | 100 - AF2 | 4 | 4 | 100 | 100 - AF1 | 2 | 2 | 100 | 100 - BE0 | 0.5 | 0.5 | 100 | 100 - BE1 | 0.5 | 0.5 | 100 | 100 - -* Verify that there is no traffic loss - -## Config parameter coverage - -* Classifiers - - * /qos/classifiers/classifier/config/name - * /qos/classifiers/classifier/config/type - * /qos/classifiers/classifier/terms/term/actions/config/target-group - * /qos/classifiers/classifier/terms/term/conditions/ipv4/config/dscp-set - * qos/classifiers/classifier/terms/term/conditions/ipv6/config/dscp-set - * /qos/classifiers/classifier/terms/term/config/id - -* Forwarding Groups - - * /qos/forwarding-groups/forwarding-group/config/name - * /qos/forwarding-groups/forwarding-group/config/output-queue - -* Queue - - * /qos/queues/queue/config/name - -* Interfaces - - * /qos/interfaces/interface/input/classifiers/classifier/config/name - * /qos/interfaces/interface/output/queues/queue/config/name - * /qos/interfaces/interface/output/scheduler-policy/config/name - -* Scheduler policy - - * /qos/scheduler-policies/scheduler-policy/config/name - * /qos/scheduler-policies/scheduler - -policy/schedulers/scheduler/config/priority - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/sequence - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/id - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight - -## Telemetry parameter coverage - -* /qos/interfaces/interface/output/queues/queue/state/transmit-pkts -* /qos/interfaces/interface/output/queues/queue/state/transmit-octets -* /qos/interfaces/interface/output/queues/queue/state/dropped-pkts -* /qos/interfaces/interface/output/queues/queue/state/dropped-octets diff --git a/feature/qos/ate_tests/qos_basic_test/metadata.textproto b/feature/qos/ate_tests/qos_basic_test/metadata.textproto deleted file mode 100644 index 1df28d671a7..00000000000 --- a/feature/qos/ate_tests/qos_basic_test/metadata.textproto +++ /dev/null @@ -1,45 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "8e6a4bdd-7e4e-4c2a-90d8-55f3543f9e18" -plan_id: "DP-1.14" -description: "QoS basic test" -testbed: TESTBED_DUT_ATE_4LINKS -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - ipv4_missing_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: JUNIPER - } - deviations: { - ecn_profile_required_definition: true - explicit_interface_ref_definition: true - qos_dropped_octets: true - } -} -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - interface_enabled: true - explicit_port_speed: true - explicit_interface_in_default_vrf: true - qos_octets: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - interface_enabled: true - qos_octets: true - } -} diff --git a/feature/qos/ate_tests/qos_basic_test/qos_basic_test.go b/feature/qos/ate_tests/qos_basic_test/qos_basic_test.go deleted file mode 100644 index 97f552f46b8..00000000000 --- a/feature/qos/ate_tests/qos_basic_test/qos_basic_test.go +++ /dev/null @@ -1,1663 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package qos_basic_test - -import ( - "testing" - "time" - - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/featureprofiles/internal/qoscfg" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ondatra/netutil" - "github.com/openconfig/ygot/ygot" -) - -type trafficData struct { - trafficRate float64 - expectedThroughputPct float32 - frameSize uint32 - dscp uint8 - queue string - inputIntf *ondatra.Interface -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// Test cases: -// - Verify that there is no traffic loss: -// 1) Non-oversubscription traffic with 80% of linerate. -// 2) Non-oversubscription traffic with 98% of linerate. -// -// Topology: -// ATE port 1 -// | -// DUT--------ATE port 3 -// | -// ATE port 2 -// -// Sample CLI command to get telemetry using gmic: -// - gnmic -a ipaddr:10162 -u username -p password --skip-verify get \ -// --path /components/component --format flat -// - gnmic tool info: -// - https://github.com/karimra/gnmic/blob/main/README.md -// - -func TestBasicConfigWithTraffic(t *testing.T) { - dut := ondatra.DUT(t, "dut") - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - - // Configure DUT interfaces and QoS. - ConfigureDUTIntf(t, dut) - switch dut.Vendor() { - case ondatra.CISCO: - ConfigureCiscoQos(t, dut) - case ondatra.JUNIPER: - ConfigureJuniperQos(t, dut) - default: - ConfigureQoS(t, dut) - } - - // Configure ATE interfaces. - ate := ondatra.ATE(t, "ate") - ap1 := ate.Port(t, "port1") - ap2 := ate.Port(t, "port2") - ap3 := ate.Port(t, "port3") - top := ate.Topology().New() - intf1 := top.AddInterface("intf1").WithPort(ap1) - intf1.IPv4(). - WithAddress("198.51.100.1/31"). - WithDefaultGateway("198.51.100.0") - intf2 := top.AddInterface("intf2").WithPort(ap2) - intf2.IPv4(). - WithAddress("198.51.100.3/31"). - WithDefaultGateway("198.51.100.2") - intf3 := top.AddInterface("intf3").WithPort(ap3) - intf3.IPv4(). - WithAddress("198.51.100.5/31"). - WithDefaultGateway("198.51.100.4") - top.Push(t).StartProtocols(t) - - queues := netutil.CommonTrafficQueues(t, dut) - - // Test case 1: Non-oversubscription traffic with 80% of linerate. - // - There should be no packet drop for all traffic classes. - NonoversubscribedTrafficFlows1 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 3, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af4": { - frameSize: 1000, - trafficRate: 24, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-af3": { - frameSize: 1000, - trafficRate: 6, - expectedThroughputPct: 100.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 4, - expectedThroughputPct: 100.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 2, - expectedThroughputPct: 100.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 0.5, - expectedThroughputPct: 100.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 0.5, - dscp: 0, - expectedThroughputPct: 100.0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 3, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 24, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 6, - expectedThroughputPct: 100.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 4, - expectedThroughputPct: 100.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 2, - expectedThroughputPct: 100.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 0.5, - dscp: 4, - expectedThroughputPct: 100.0, - queue: queues.BE0, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 0.5, - expectedThroughputPct: 100.0, - dscp: 0, - queue: queues.BE1, - inputIntf: intf2, - }, - } - - // Test case 2: Non-oversubscription traffic with 98% of linerate. - // - There should be no packet drop for all traffic classes. - NonoversubscribedTrafficFlows2 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 5, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af4": { - frameSize: 1000, - trafficRate: 30, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-af3": { - frameSize: 1000, - trafficRate: 7.5, - expectedThroughputPct: 100.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 4, - expectedThroughputPct: 100.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 2, - expectedThroughputPct: 100.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 0.5, - expectedThroughputPct: 100.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 0.5, - dscp: 0, - expectedThroughputPct: 100.0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 4, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 30, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 7.5, - expectedThroughputPct: 100.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 4, - expectedThroughputPct: 100.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 2, - expectedThroughputPct: 100.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 0.5, - dscp: 4, - expectedThroughputPct: 100.0, - queue: queues.BE0, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 0.5, - expectedThroughputPct: 100.0, - dscp: 0, - queue: queues.BE1, - inputIntf: intf2, - }, - } - - cases := []struct { - desc string - trafficFlows map[string]*trafficData - }{{ - desc: "Non-oversubscription 80 percent of linerate traffic", - trafficFlows: NonoversubscribedTrafficFlows1, - }, { - desc: "Non-oversubscription 98 percent of linerate traffic", - trafficFlows: NonoversubscribedTrafficFlows2, - }} - - for _, tc := range cases { - t.Run(tc.desc, func(t *testing.T) { - trafficFlows := tc.trafficFlows - - var flows []*ondatra.Flow - for trafficID, data := range trafficFlows { - t.Logf("Configuring flow %s", trafficID) - flow := ate.Traffic().NewFlow(trafficID). - WithSrcEndpoints(data.inputIntf). - WithDstEndpoints(intf3). - WithHeaders(ondatra.NewEthernetHeader(), ondatra.NewIPv4Header().WithDSCP(data.dscp)). - WithFrameRatePct(data.trafficRate). - WithFrameSize(data.frameSize) - flows = append(flows, flow) - } - - counters := make(map[string]map[string]uint64) - var counterNames []string - - if !deviations.QOSDroppedOctets(dut) { - counterNames = []string{ - - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedOctetsBeforeTraffic", "dutQosDroppedPktsAfterTraffic", - "dutQosDroppedOctetsAfterTraffic", - } - } else { - counterNames = []string{ - - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedPktsAfterTraffic", - } - - } - - for _, name := range counterNames { - counters[name] = make(map[string]uint64) - - // Set the initial counters to 0. - for _, data := range trafficFlows { - counters[name][data.queue] = 0 - } - } - - // Get QoS egress packet counters before the traffic. - for _, data := range trafficFlows { - counters["dutQosPktsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) - counters["dutQosOctetsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitOctets().State()) - counters["dutQosDroppedPktsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - if !deviations.QOSDroppedOctets(dut) { - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State()) - } - } - - t.Logf("Running traffic 1 on DUT interfaces: %s => %s ", dp1.Name(), dp3.Name()) - t.Logf("Running traffic 2 on DUT interfaces: %s => %s ", dp2.Name(), dp3.Name()) - t.Logf("Sending traffic flows: \n%v\n\n", trafficFlows) - ate.Traffic().Start(t, flows...) - time.Sleep(30 * time.Second) - ate.Traffic().Stop(t) - time.Sleep(30 * time.Second) - - for trafficID, data := range trafficFlows { - counters["ateOutPkts"][data.queue] += gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).Counters().OutPkts().State()) - counters["ateInPkts"][data.queue] += gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).Counters().InPkts().State()) - - counters["dutQosPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) - counters["dutQosOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitOctets().State()) - counters["dutQosDroppedPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - if !deviations.QOSDroppedOctets(dut) { - counters["dutQosDroppedOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedOctets().State()) - } - t.Logf("ateInPkts: %v, txPkts %v, Queue: %v", counters["ateInPkts"][data.queue], counters["dutQosPktsAfterTraffic"][data.queue], data.queue) - - lossPct := gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).LossPct().State()) - t.Logf("Get flow %q: lossPct: %.2f%% or rxPct: %.2f%%, want: %.2f%%\n\n", data.queue, lossPct, 100.0-lossPct, data.expectedThroughputPct) - if got, want := 100.0-lossPct, data.expectedThroughputPct; got != want { - t.Errorf("Get(throughput for queue %q): got %.2f%%, want %.2f%%", data.queue, got, want) - } - } - - // Check QoS egress packet counters are updated correctly. - for _, name := range counterNames { - t.Logf("QoS %s: %v", name, counters[name]) - } - - for _, data := range trafficFlows { - dutPktCounterDiff := counters["dutQosPktsAfterTraffic"][data.queue] - counters["dutQosPktsBeforeTraffic"][data.queue] - atePktCounterDiff := counters["ateInPkts"][data.queue] - t.Logf("Queue %q: atePktCounterDiff: %v dutPktCounterDiff: %v", data.queue, atePktCounterDiff, dutPktCounterDiff) - if dutPktCounterDiff < atePktCounterDiff { - t.Errorf("Get dutPktCounterDiff for queue %q: got %v, want >= %v", data.queue, dutPktCounterDiff, atePktCounterDiff) - } - - dutDropPktCounterDiff := counters["dutQosDroppedPktsAfterTraffic"][data.queue] - counters["dutQosDroppedPktsBeforeTraffic"][data.queue] - t.Logf("Queue %q: dutDropPktCounterDiff: %v", data.queue, dutDropPktCounterDiff) - if dutDropPktCounterDiff != 0 { - t.Errorf("Get dutDropPktCounterDiff for queue %q: got %v, want 0", data.queue, dutDropPktCounterDiff) - } - - dutOctetCounterDiff := counters["dutQosOctetsAfterTraffic"][data.queue] - counters["dutQosOctetsBeforeTraffic"][data.queue] - ateOctetCounterDiff := counters["ateInPkts"][data.queue] * uint64(data.frameSize) - t.Logf("Queue %q: ateOctetCounterDiff: %v dutOctetCounterDiff: %v", data.queue, ateOctetCounterDiff, dutOctetCounterDiff) - if !deviations.QOSOctets(dut) { - if dutOctetCounterDiff < ateOctetCounterDiff { - t.Errorf("Get dutOctetCounterDiff for queue %q: got %v, want >= %v", data.queue, dutOctetCounterDiff, ateOctetCounterDiff) - } - } - - if !deviations.QOSDroppedOctets(dut) { - dutDropOctetCounterDiff := counters["dutQosDroppedOctetsAfterTraffic"][data.queue] - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] - t.Logf("Queue %q: dutDropOctetCounterDiff: %v", data.queue, dutDropOctetCounterDiff) - if dutDropOctetCounterDiff != 0 { - t.Errorf("Get dutDropOctetCounterDiff for queue %q: got %v, want 0", data.queue, dutDropOctetCounterDiff) - } - } - - } - }) - } -} - -func ConfigureDUTIntf(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - - dutIntfs := []struct { - desc string - intfName string - ipAddr string - prefixLen uint8 - }{{ - desc: "Input interface port1", - intfName: dp1.Name(), - ipAddr: "198.51.100.0", - prefixLen: 31, - }, { - desc: "Input interface port2", - intfName: dp2.Name(), - ipAddr: "198.51.100.2", - prefixLen: 31, - }, { - desc: "Output interface port3", - intfName: dp3.Name(), - ipAddr: "198.51.100.4", - prefixLen: 31, - }} - - // Configure the interfaces. - for _, intf := range dutIntfs { - t.Logf("Configure DUT interface %s with attributes %v", intf.intfName, intf) - i := &oc.Interface{ - Name: ygot.String(intf.intfName), - Description: ygot.String(intf.desc), - Type: oc.IETFInterfaces_InterfaceType_ethernetCsmacd, - Enabled: ygot.Bool(true), - } - i.GetOrCreateEthernet() - s := i.GetOrCreateSubinterface(0).GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) && !deviations.IPv4MissingEnabled(dut) { - s.Enabled = ygot.Bool(true) - } - a := s.GetOrCreateAddress(intf.ipAddr) - a.PrefixLength = ygot.Uint8(intf.prefixLen) - gnmi.Replace(t, dut, gnmi.OC().Interface(intf.intfName).Config(), i) - if deviations.ExplicitInterfaceInDefaultVRF(dut) { - fptest.AssignToNetworkInstance(t, dut, intf.intfName, deviations.DefaultNetworkInstance(dut), 0) - } - } - if deviations.ExplicitPortSpeed(dut) { - fptest.SetPortSpeed(t, dp1) - fptest.SetPortSpeed(t, dp2) - fptest.SetPortSpeed(t, dp3) - } -} - -func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - d := &oc.Root{} - q := d.GetOrCreateQos() - queues := netutil.CommonTrafficQueues(t, dut) - - if dut.Vendor() == ondatra.NOKIA { - queueNames := []string{queues.NC1, queues.AF4, queues.AF3, queues.AF2, queues.AF1, queues.BE0, queues.BE1} - for i, queue := range queueNames { - q1 := q.GetOrCreateQueue(queue) - q1.Name = ygot.String(queue) - queueid := len(queueNames) - i - q1.QueueId = ygot.Uint8(uint8(queueid)) - } - } - t.Logf("Create qos forwarding groups and queue name config") - forwardingGroups := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - t.Logf("qos forwarding groups config: %v", forwardingGroups) - for _, tc := range forwardingGroups { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - } - - t.Logf("Create qos queue management profile config") - ecnConfig := struct { - profileName string - ecnEnabled bool - minThreshold uint64 - }{ - profileName: "ECNProfile", - ecnEnabled: true, - minThreshold: uint64(80000), - } - t.Logf("qos queue management profile config: %v", ecnConfig) - queueMgmtProfile := q.GetOrCreateQueueManagementProfile(ecnConfig.profileName) - queueMgmtProfile.SetName("ECNProfile") - wred := queueMgmtProfile.GetOrCreateWred() - uniform := wred.GetOrCreateUniform() - uniform.SetEnableEcn(ecnConfig.ecnEnabled) - uniform.SetMinThreshold(ecnConfig.minThreshold) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - - t.Logf("Create qos Classifiers config") - classifiers := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - t.Logf("qos Classifiers config: %v", classifiers) - for _, tc := range classifiers { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.name == "dscp_based_classifier_ipv4" { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.name == "dscp_based_classifier_ipv6" { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos input classifier config") - classifierIntfs := []struct { - desc string - intf string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }, { - desc: "Input Classifier Type IPV4", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - t.Logf("qos input classifier config: %v", classifierIntfs) - for _, tc := range classifierIntfs { - qoscfg.SetInputClassifier(t, dut, q, tc.intf, tc.inputClassifierType, tc.classifier) - } - - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - setPriority bool - priority oc.E_Scheduler_Priority - inputID string - inputType oc.E_Input_InputType - setWeight bool - weight uint64 - queueName string - targetGroup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(1), - setPriority: false, - setWeight: true, - inputID: "BE1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(1), - setPriority: false, - setWeight: true, - inputID: "BE0", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(1), - setPriority: false, - setWeight: true, - inputID: "AF1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(4), - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(1), - setPriority: false, - setWeight: true, - inputID: "AF2", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(8), - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(1), - setPriority: false, - setWeight: true, - inputID: "AF3", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(12), - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(1), - setPriority: false, - setWeight: true, - inputID: "AF4", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(48), - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - setPriority: true, - setWeight: false, - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - inputType: oc.Input_InputType_QUEUE, - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - if tc.setPriority { - s.SetPriority(tc.priority) - } - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - input.SetInputType(tc.inputType) - input.SetQueue(tc.queueName) - if tc.setWeight { - input.SetWeight(tc.weight) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - scheduler string - ecnProfile string - }{{ - desc: "output-interface-BE1", - queueName: queues.BE1, - scheduler: "scheduler", - ecnProfile: "ECNProfile", - }, { - desc: "output-interface-BE0", - queueName: queues.BE0, - scheduler: "scheduler", - ecnProfile: "ECNProfile", - }, { - desc: "output-interface-AF1", - queueName: queues.AF1, - scheduler: "scheduler", - ecnProfile: "ECNProfile", - }, { - desc: "output-interface-AF2", - queueName: queues.AF2, - scheduler: "scheduler", - ecnProfile: "ECNProfile", - }, { - desc: "output-interface-AF3", - queueName: queues.AF3, - scheduler: "scheduler", - ecnProfile: "ECNProfile", - }, { - desc: "output-interface-AF4", - queueName: queues.AF4, - scheduler: "scheduler", - ecnProfile: "ECNProfile", - }, { - desc: "output-interface-NC1", - queueName: queues.NC1, - scheduler: "scheduler", - ecnProfile: "ECNProfile", - }} - - maxBurstSize := uint32(268435456) - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp3.Name()) - i.SetInterfaceId(dp3.Name()) - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) - output := i.GetOrCreateOutput() - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName(tc.scheduler) - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - queue.SetQueueManagementProfile(tc.ecnProfile) - if dut.Vendor() == ondatra.NOKIA { - bufferAllocation := q.GetOrCreateBufferAllocationProfile("ballocprofile") - bq := bufferAllocation.GetOrCreateQueue(tc.queueName) - bq.SetStaticSharedBufferLimit(maxBurstSize) - output.SetBufferAllocationProfile("ballocprofile") - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } -} - -func ConfigureCiscoQos(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - d := &oc.Root{} - q := d.GetOrCreateQos() - - queueName := []string{"NC1", "AF4", "AF3", "AF2", "AF1", "BE0", "BE1"} - - for i, queue := range queueName { - q1 := q.GetOrCreateQueue(queue) - q1.Name = ygot.String(queue) - queueid := len(queueName) - i - q1.QueueId = ygot.Uint8(uint8(queueid)) - - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - casesfwdgrp := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: "BE1", - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: "BE0", - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: "AF1", - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: "AF2", - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: "AF3", - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: "AF4", - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: "NC1", - targetGroup: "target-group-NC1", - }} - t.Logf("qos forwarding groups config cases: %v", casesfwdgrp) - for _, tc := range casesfwdgrp { - t.Run(tc.desc, func(t *testing.T) { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - }) - } - - t.Logf("Create qos Classifiers config") - cases := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - t.Logf("qos Classifiers config cases: %v", cases) - for _, tc := range cases { - t.Run(tc.desc, func(t *testing.T) { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.classType == oc.Qos_Classifier_Type_IPV4 { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.classType == oc.Qos_Classifier_Type_IPV6 { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - }) - } - - t.Logf("Create qos input classifier config") - t.Logf("Create qos input classifier config") - classifierIntfs := []struct { - desc string - intf string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }, { - desc: "Input Classifier Type IPV4", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - t.Logf("qos input classifier config: %v", classifierIntfs) - for _, tc := range classifierIntfs { - qoscfg.SetInputClassifier(t, dut, q, tc.intf, tc.inputClassifierType, tc.classifier) - } - - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - priority oc.E_Scheduler_Priority - inputID string - inputType oc.E_Input_InputType - weight uint64 - queueName string - targetGroup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(6), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: "BE1", - targetGroup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(5), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE0", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(2), - queueName: "BE0", - targetGroup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(4), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(4), - queueName: "AF1", - targetGroup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(3), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF2", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(8), - queueName: "AF2", - targetGroup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(2), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF3", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(12), - queueName: "AF3", - targetGroup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF4", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(48), - queueName: "AF4", - targetGroup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(7), - queueName: "NC1", - targetGroup: "target-group-NC1", - }} - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - s.SetPriority(tc.priority) - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - input.SetInputType(tc.inputType) - input.SetQueue(tc.queueName) - input.SetWeight(tc.weight) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - scheduler string - }{{ - desc: "output-interface-NC1", - queueName: "NC1", - scheduler: "scheduler", - }, { - desc: "output-interface-AF4", - queueName: "AF4", - scheduler: "scheduler", - }, { - desc: "output-interface-AF3", - queueName: "AF3", - scheduler: "scheduler", - }, { - desc: "output-interface-AF2", - queueName: "AF2", - scheduler: "scheduler", - }, { - desc: "output-interface-AF1", - queueName: "AF1", - scheduler: "scheduler", - }, { - desc: "output-interface-BE0", - queueName: "BE0", - scheduler: "scheduler", - }, { - desc: "output-interface-BE1", - queueName: "BE1", - scheduler: "scheduler", - }} - - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp3.Name()) - i.SetInterfaceId(dp3.Name()) - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) - output := i.GetOrCreateOutput() - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName(tc.scheduler) - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) -} -func ConfigureJuniperQos(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - d := &oc.Root{} - q := d.GetOrCreateQos() - queues := netutil.CommonTrafficQueues(t, dut) - - forwardingGroups := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - t.Logf("qos forwarding groups config: %v", forwardingGroups) - for _, tc := range forwardingGroups { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - } - - if deviations.ECNProfileRequiredDefinition(dut) { - t.Logf("Create qos queue management profile config") - - profileName := string("ECNProfile") - ecnEnabled := bool(true) - minThreshold := uint64(0) - maxThreshold := uint64(55) - maxDropProbabilityPercent := uint8(25) - - queueMgmtProfile := q.GetOrCreateQueueManagementProfile(profileName) - queueMgmtProfile.SetName(profileName) - wred := queueMgmtProfile.GetOrCreateWred() - uniform := wred.GetOrCreateUniform() - uniform.SetEnableEcn(ecnEnabled) - uniform.SetMinThreshold(minThreshold) - uniform.SetMaxThreshold(maxThreshold) - uniform.SetMaxDropProbabilityPercent(maxDropProbabilityPercent) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - t.Logf("Create qos Classifiers config") - classifiers := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - t.Logf("qos Classifiers config: %v", classifiers) - for _, tc := range classifiers { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.name == "dscp_based_classifier_ipv4" { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.name == "dscp_based_classifier_ipv6" { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos input classifier config") - classifierIntfs := []struct { - desc string - intf string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4 for interface 1", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6 for interface 1", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }, { - desc: "Input Classifier Type IPV4 for interface 2", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6 for interface 2", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - t.Logf("qos input classifier config: %v", classifierIntfs) - for _, tc := range classifierIntfs { - qoscfg.SetInputClassifier(t, dut, q, tc.intf, tc.inputClassifierType, tc.classifier) - } - - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - setPriority bool - priority oc.E_Scheduler_Priority - inputID string - setWeight bool - weight uint64 - queueName string - targetGroup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(1), - setPriority: false, - setWeight: true, - inputID: "BE1", - weight: uint64(1), - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(1), - setPriority: false, - setWeight: true, - inputID: "BE0", - weight: uint64(1), - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(1), - setPriority: false, - setWeight: true, - inputID: "AF1", - weight: uint64(4), - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(1), - setPriority: false, - setWeight: true, - inputID: "AF2", - weight: uint64(8), - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(1), - setPriority: false, - setWeight: true, - inputID: "AF3", - weight: uint64(12), - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(1), - setPriority: false, - setWeight: true, - inputID: "AF4", - weight: uint64(48), - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - setPriority: true, - setWeight: false, - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - if tc.setPriority { - s.SetPriority(tc.priority) - } - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - input.SetInputType(oc.Input_InputType_QUEUE) - input.SetQueue(tc.queueName) - if tc.setWeight { - input.SetWeight(tc.weight) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - }{{ - desc: "output-interface-BE1", - queueName: queues.BE1, - }, { - desc: "output-interface-BE0", - queueName: queues.BE0, - }, { - desc: "output-interface-AF1", - queueName: queues.AF1, - }, { - desc: "output-interface-AF2", - queueName: queues.AF2, - }, { - desc: "output-interface-AF3", - queueName: queues.AF3, - }, { - desc: "output-interface-AF4", - queueName: queues.AF4, - }, { - desc: "output-interface-NC1", - queueName: queues.NC1, - }} - - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp3.Name()) - i.SetInterfaceId(dp3.Name()) - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) - output := i.GetOrCreateOutput() - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName("scheduler") - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - queue.SetQueueManagementProfile("ECNProfile") - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } -} diff --git a/feature/qos/ate_tests/qos_output_queue_counters_test/README.md b/feature/qos/ate_tests/qos_output_queue_counters_test/README.md deleted file mode 100644 index eb8bb04af09..00000000000 --- a/feature/qos/ate_tests/qos_output_queue_counters_test/README.md +++ /dev/null @@ -1,28 +0,0 @@ -# DP-1.4: QoS Interface Output Queue Counters - -## Summary - -Validate QoS interface output queue counters. - -## Procedure - -* Configure ATE port-1 connected to DUT port-1, and ATE port-2 connected to DUT port-2, with the relevant IPv4 addresses. -* Send the traffic with forwarding class NC1, AF4, AF3, AF2, AF1 and BE1 over the DUT. -* Verify that the following telemetry paths exist on the QoS output interface of the DUT. - * /qos/interfaces/interface/output/queues/queue/state/transmit-pkts - * /qos/interfaces/interface/output/queues/queue/state/transmit-octets - * /qos/interfaces/interface/output/queues/queue/state/dropped-pkts - * /qos/interfaces/interface/output/queues/queue/state/dropped-octets - -## Config Parameter coverage - -* /interfaces/interface/config/enabled -* /interfaces/interface/config/name -* /interfaces/interface/config/description - -## Telemetry Parameter coverage - -* /qos/interfaces/interface/output/queues/queue/state/transmit-pkts -* /qos/interfaces/interface/output/queues/queue/state/transmit-octets -* /qos/interfaces/interface/output/queues/queue/state/dropped-pkts -* /qos/interfaces/interface/output/queues/queue/state/dropped-octets diff --git a/feature/qos/ate_tests/qos_output_queue_counters_test/metadata.textproto b/feature/qos/ate_tests/qos_output_queue_counters_test/metadata.textproto deleted file mode 100644 index dceb9fac219..00000000000 --- a/feature/qos/ate_tests/qos_output_queue_counters_test/metadata.textproto +++ /dev/null @@ -1,43 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "279bd41d-dbe7-4b6c-8ec1-08fb12b7f7b0" -plan_id: "DP-1.4" -description: "QoS Interface Output Queue Counters" -testbed: TESTBED_DUT_ATE_2LINKS -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - ipv4_missing_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: JUNIPER - } - deviations: { - scheduler_input_weight_limit: true - explicit_interface_ref_definition: true - qos_dropped_octets: true - } -} -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_interface_ref_definition: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - interface_enabled: true - qos_octets: true - } -} diff --git a/feature/qos/ate_tests/qos_output_queue_counters_test/qos_output_queue_counters_test.go b/feature/qos/ate_tests/qos_output_queue_counters_test/qos_output_queue_counters_test.go deleted file mode 100644 index 8c21c03f431..00000000000 --- a/feature/qos/ate_tests/qos_output_queue_counters_test/qos_output_queue_counters_test.go +++ /dev/null @@ -1,986 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package qos_output_queue_counters_test - -import ( - "testing" - "time" - - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/featureprofiles/internal/qoscfg" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ondatra/netutil" - "github.com/openconfig/ygot/ygot" -) - -type trafficData struct { - trafficRate float64 - frameSize uint32 - dscp uint8 - queue string -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// Test cases: -// -// Verify the presence of the telemetry paths of the following features: -// - Configure the interfaces connectd to ATE ports. -// - Send the traffic with all forwarding class NC1, AF4, AF3, AF2, AF1 and BE1 over the DUT. -// - Check the QoS queue counters exist and are updated correctly -// - /qos/interfaces/interface/output/queues/queue/state/transmit-pkts -// - /qos/interfaces/interface/output/queues/queue/state/transmit-octets -// - /qos/interfaces/interface/output/queues/queue/state/dropped-pkts -// -// Topology: -// ate:port1 <--> port1:dut:port2 <--> ate:port2 -// -// Test notes: -// - We may need to update the queue mapping after QoS feature implementation is finalized. -// -// Sample CLI command to get telemetry using gmic: -// - gnmic -a ipaddr:10162 -u username -p password --skip-verify get \ -// --path /components/component --format flat -// - gnmic tool info: -// - https://github.com/karimra/gnmic/blob/main/README.md -// - -func TestQoSCounters(t *testing.T) { - dut := ondatra.DUT(t, "dut") - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - - // Configure DUT interfaces and QoS. - ConfigureDUTIntf(t, dut) - if dut.Vendor() == ondatra.CISCO { - ConfigureCiscoQos(t, dut) - } else { - ConfigureQoS(t, dut) - } - - // Configure ATE interfaces. - ate := ondatra.ATE(t, "ate") - ap1 := ate.Port(t, "port1") - ap2 := ate.Port(t, "port2") - top := ate.Topology().New() - intf1 := top.AddInterface("intf1").WithPort(ap1) - intf1.IPv4(). - WithAddress("198.51.100.1/31"). - WithDefaultGateway("198.51.100.0") - intf2 := top.AddInterface("intf2").WithPort(ap2) - intf2.IPv4(). - WithAddress("198.51.100.3/31"). - WithDefaultGateway("198.51.100.2") - top.Push(t).StartProtocols(t) - - var trafficFlows map[string]*trafficData - queues := netutil.CommonTrafficQueues(t, dut) - - switch dut.Vendor() { - case ondatra.JUNIPER: - trafficFlows = map[string]*trafficData{ - "flow-nc1": {frameSize: 1000, trafficRate: 1, dscp: 56, queue: queues.NC1}, - "flow-af4": {frameSize: 400, trafficRate: 4, dscp: 32, queue: queues.AF4}, - "flow-af3": {frameSize: 300, trafficRate: 3, dscp: 24, queue: queues.AF3}, - "flow-af2": {frameSize: 200, trafficRate: 2, dscp: 16, queue: queues.AF2}, - "flow-af1": {frameSize: 1100, trafficRate: 1, dscp: 8, queue: queues.AF1}, - "flow-be1": {frameSize: 1200, trafficRate: 1, dscp: 0, queue: queues.BE1}, - } - case ondatra.ARISTA: - trafficFlows = map[string]*trafficData{ - "flow-nc1": {frameSize: 700, trafficRate: 7, dscp: 56, queue: queues.NC1}, - "flow-af4": {frameSize: 400, trafficRate: 4, dscp: 32, queue: queues.AF4}, - "flow-af3": {frameSize: 1300, trafficRate: 3, dscp: 24, queue: queues.AF3}, - "flow-af2": {frameSize: 1200, trafficRate: 2, dscp: 16, queue: queues.AF2}, - "flow-af1": {frameSize: 1000, trafficRate: 10, dscp: 8, queue: queues.AF1}, - "flow-be0": {frameSize: 1110, trafficRate: 1, dscp: 4, queue: queues.BE0}, - "flow-be1": {frameSize: 1111, trafficRate: 1, dscp: 0, queue: queues.BE1}, - } - case ondatra.CISCO: - trafficFlows = map[string]*trafficData{ - "flow-nc1": {frameSize: 700, trafficRate: 7, dscp: 56, queue: queues.NC1}, - "flow-af4": {frameSize: 400, trafficRate: 4, dscp: 32, queue: queues.AF4}, - "flow-af3": {frameSize: 1300, trafficRate: 3, dscp: 24, queue: queues.AF3}, - "flow-af2": {frameSize: 1200, trafficRate: 2, dscp: 16, queue: queues.AF2}, - "flow-af1": {frameSize: 1000, trafficRate: 10, dscp: 8, queue: queues.AF1}, - "flow-be0": {frameSize: 1110, trafficRate: 1, dscp: 4, queue: queues.BE0}, - "flow-be1": {frameSize: 1111, trafficRate: 1, dscp: 0, queue: queues.BE1}, - } - default: - t.Fatalf("Output queue mapping is missing for %v", dut.Vendor().String()) - } - - var flows []*ondatra.Flow - for trafficID, data := range trafficFlows { - t.Logf("Configuring flow %s", trafficID) - flow := ate.Traffic().NewFlow(trafficID). - WithSrcEndpoints(intf1). - WithDstEndpoints(intf2). - WithHeaders(ondatra.NewEthernetHeader(), ondatra.NewIPv4Header().WithDSCP(data.dscp)). - WithFrameRatePct(data.trafficRate). - WithFrameSize(data.frameSize) - flows = append(flows, flow) - } - - var counterNames []string - counters := make(map[string]map[string]uint64) - - if !deviations.QOSDroppedOctets(dut) { - counterNames = []string{ - - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedOctetsBeforeTraffic", "dutQosDroppedPktsAfterTraffic", - "dutQosDroppedOctetsAfterTraffic", - } - } else { - counterNames = []string{ - - "ateOutPkts", "ateInPkts", "dutQosPktsBeforeTraffic", "dutQosOctetsBeforeTraffic", - "dutQosPktsAfterTraffic", "dutQosOctetsAfterTraffic", "dutQosDroppedPktsBeforeTraffic", - "dutQosDroppedPktsAfterTraffic", - } - - } - - for _, name := range counterNames { - counters[name] = make(map[string]uint64) - - // Set the initial counters to 0. - for _, data := range trafficFlows { - counters[name][data.queue] = 0 - } - } - - // Get QoS egress packet counters before the traffic. - for _, data := range trafficFlows { - counters["dutQosPktsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).TransmitPkts().State()) - counters["dutQosOctetsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).TransmitOctets().State()) - counters["dutQosDroppedPktsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).DroppedPkts().State()) - if !deviations.QOSDroppedOctets(dut) { - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).DroppedOctets().State()) - } - } - - t.Logf("Running traffic 1 on DUT interfaces: %s => %s ", dp1.Name(), dp2.Name()) - t.Logf("Sending traffic flows: \n%v\n\n", trafficFlows) - ate.Traffic().Start(t, flows...) - time.Sleep(120 * time.Second) - ate.Traffic().Stop(t) - time.Sleep(30 * time.Second) - - for trafficID, data := range trafficFlows { - counters["ateOutPkts"][data.queue] += gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).Counters().OutPkts().State()) - counters["ateInPkts"][data.queue] += gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).Counters().InPkts().State()) - - counters["dutQosPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).TransmitPkts().State()) - counters["dutQosOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).TransmitOctets().State()) - counters["dutQosDroppedPktsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).DroppedPkts().State()) - if !deviations.QOSDroppedOctets(dut) { - counters["dutQosDroppedOctetsAfterTraffic"][data.queue] = gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp2.Name()).Output().Queue(data.queue).DroppedOctets().State()) - } - t.Logf("ateInPkts: %v, txPkts %v, Queue: %v", counters["ateInPkts"][data.queue], counters["dutQosPktsAfterTraffic"][data.queue], data.queue) - - lossPct := gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).LossPct().State()) - t.Logf("Get flow %q: lossPct: %.2f%% or rxPct: %.2f%%, want: %.2f%%\n\n", data.queue, lossPct, 100.0-lossPct, 100.0) - if got, want := 100.0-lossPct, float32(100.0); got != want { - t.Errorf("Get(throughput for queue %q): got %.2f%%, want %.2f%%", data.queue, got, want) - } - } - - // Check QoS egress packet counters are updated correctly. - for _, name := range counterNames { - t.Logf("QoS %s: %v", name, counters[name]) - } - - for _, data := range trafficFlows { - dutPktCounterDiff := counters["dutQosPktsAfterTraffic"][data.queue] - counters["dutQosPktsBeforeTraffic"][data.queue] - atePktCounterDiff := counters["ateInPkts"][data.queue] - t.Logf("Queue %q: atePktCounterDiff: %v dutPktCounterDiff: %v", data.queue, atePktCounterDiff, dutPktCounterDiff) - if dutPktCounterDiff < atePktCounterDiff { - t.Errorf("Get dutPktCounterDiff for queue %q: got %v, want >= %v", data.queue, dutPktCounterDiff, atePktCounterDiff) - } - - dutDropPktCounterDiff := counters["dutQosDroppedPktsAfterTraffic"][data.queue] - counters["dutQosDroppedPktsBeforeTraffic"][data.queue] - t.Logf("Queue %q: dutDropPktCounterDiff: %v", data.queue, dutDropPktCounterDiff) - if dutDropPktCounterDiff != 0 { - t.Errorf("Get dutDropPktCounterDiff for queue %q: got %v, want 0", data.queue, dutDropPktCounterDiff) - } - - dutOctetCounterDiff := counters["dutQosOctetsAfterTraffic"][data.queue] - counters["dutQosOctetsBeforeTraffic"][data.queue] - ateOctetCounterDiff := counters["ateInPkts"][data.queue] * uint64(data.frameSize) - t.Logf("Queue %q: ateOctetCounterDiff: %v dutOctetCounterDiff: %v", data.queue, ateOctetCounterDiff, dutOctetCounterDiff) - if !deviations.QOSOctets(dut) { - if dutOctetCounterDiff < ateOctetCounterDiff { - t.Errorf("Get dutOctetCounterDiff for queue %q: got %v, want >= %v", data.queue, dutOctetCounterDiff, ateOctetCounterDiff) - } - } - - if !deviations.QOSDroppedOctets(dut) { - dutDropOctetCounterDiff := counters["dutQosDroppedOctetsAfterTraffic"][data.queue] - counters["dutQosDroppedOctetsBeforeTraffic"][data.queue] - t.Logf("Queue %q: dutDropOctetCounterDiff: %v", data.queue, dutDropOctetCounterDiff) - if dutDropOctetCounterDiff != 0 { - t.Errorf("Get dutDropOctetCounterDiff for queue %q: got %v, want 0", data.queue, dutDropOctetCounterDiff) - } - } - - } -} - -func ConfigureDUTIntf(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - - dutIntfs := []struct { - desc string - intfName string - ipAddr string - prefixLen uint8 - }{{ - desc: "Input interface port1", - intfName: dp1.Name(), - ipAddr: "198.51.100.0", - prefixLen: 31, - }, { - desc: "Output interface port2", - intfName: dp2.Name(), - ipAddr: "198.51.100.2", - prefixLen: 31, - }} - - // Configure the interfaces. - for _, intf := range dutIntfs { - t.Logf("Configure DUT interface %s with attributes %v", intf.intfName, intf) - i := &oc.Interface{ - Name: ygot.String(intf.intfName), - Description: ygot.String(intf.desc), - Type: oc.IETFInterfaces_InterfaceType_ethernetCsmacd, - Enabled: ygot.Bool(true), - } - i.GetOrCreateEthernet() - s := i.GetOrCreateSubinterface(0).GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) && !deviations.IPv4MissingEnabled(dut) { - s.Enabled = ygot.Bool(true) - } - a := s.GetOrCreateAddress(intf.ipAddr) - a.PrefixLength = ygot.Uint8(intf.prefixLen) - gnmi.Replace(t, dut, gnmi.OC().Interface(intf.intfName).Config(), i) - } -} - -func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - d := &oc.Root{} - q := d.GetOrCreateQos() - queues := netutil.CommonTrafficQueues(t, dut) - - nc1InputWeight := uint64(200) - af4InputWeight := uint64(100) - if deviations.SchedulerInputWeightLimit(dut) { - nc1InputWeight = uint64(100) - af4InputWeight = uint64(99) - } - - t.Logf("Create qos forwarding groups config") - forwardingGroups := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - t.Logf("qos forwarding groups config: %v", forwardingGroups) - for _, tc := range forwardingGroups { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - } - - t.Logf("Create qos Classifiers config") - classifiers := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - t.Logf("qos Classifiers config: %v", classifiers) - for _, tc := range classifiers { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.name == "dscp_based_classifier_ipv4" { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.name == "dscp_based_classifier_ipv6" { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos input classifier config") - classifierIntfs := []struct { - desc string - intf string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - t.Logf("qos input classifier config: %v", classifierIntfs) - for _, tc := range classifierIntfs { - qoscfg.SetInputClassifier(t, dut, q, tc.intf, tc.inputClassifierType, tc.classifier) - } - - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - priority oc.E_Scheduler_Priority - inputID string - inputType oc.E_Input_InputType - weight uint64 - queueName string - targetGroup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE0", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(4), - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(8), - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF2", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(16), - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF3", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(32), - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "AF4", - inputType: oc.Input_InputType_QUEUE, - weight: af4InputWeight, - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - inputType: oc.Input_InputType_QUEUE, - weight: nc1InputWeight, - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - s.SetPriority(tc.priority) - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - input.SetInputType(tc.inputType) - input.SetQueue(tc.queueName) - input.SetWeight(tc.weight) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - scheduler string - }{{ - desc: "output-interface-BE1", - queueName: queues.BE1, - scheduler: "scheduler", - }, { - desc: "output-interface-BE0", - queueName: queues.BE0, - scheduler: "scheduler", - }, { - desc: "output-interface-AF1", - queueName: queues.AF1, - scheduler: "scheduler", - }, { - desc: "output-interface-AF2", - queueName: queues.AF2, - scheduler: "scheduler", - }, { - desc: "output-interface-AF3", - queueName: queues.AF3, - scheduler: "scheduler", - }, { - desc: "output-interface-AF4", - queueName: queues.AF4, - scheduler: "scheduler", - }, { - desc: "output-interface-NC1", - queueName: queues.NC1, - scheduler: "scheduler", - }} - - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp2.Name()) - i.SetInterfaceId(dp2.Name()) - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp2.Name()) - if deviations.InterfaceRefConfigUnsupported(dut) { - i.InterfaceRef = nil - } - output := i.GetOrCreateOutput() - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName(tc.scheduler) - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } -} - -func ConfigureCiscoQos(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - d := &oc.Root{} - q := d.GetOrCreateQos() - queueName := []string{"NC1", "AF4", "AF3", "AF2", "AF1", "BE0", "BE1"} - - for i, queue := range queueName { - q1 := q.GetOrCreateQueue(queue) - q1.Name = ygot.String(queue) - queueid := len(queueName) - i - q1.QueueId = ygot.Uint8(uint8(queueid)) - - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - casesfwdgrp := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: "BE1", - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: "BE0", - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: "AF1", - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: "AF2", - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: "AF3", - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: "AF4", - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: "NC1", - targetGroup: "target-group-NC1", - }} - t.Logf("qos forwarding groups config cases: %v", casesfwdgrp) - for _, tc := range casesfwdgrp { - t.Run(tc.desc, func(t *testing.T) { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - }) - } - - t.Logf("Create qos Classifiers config") - t.Logf("Create qos Classifiers config") - cases := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - t.Logf("qos Classifiers config cases: %v", cases) - for _, tc := range cases { - t.Run(tc.desc, func(t *testing.T) { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.classType == oc.Qos_Classifier_Type_IPV4 { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.classType == oc.Qos_Classifier_Type_IPV6 { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - }) - } - intcases := []struct { - desc string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4", - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - for _, tc := range intcases { - t.Run(tc.desc, func(t *testing.T) { - qoscfg.SetInputClassifier(t, dut, q, dp1.Name(), tc.inputClassifierType, tc.classifier) - }) - } - - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - priority oc.E_Scheduler_Priority - inputID string - inputType oc.E_Input_InputType - weight uint64 - queueName string - targetGroup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: "BE1", - targetGroup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE0", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(4), - queueName: "BE0", - targetGroup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(8), - queueName: "AF1", - targetGroup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF2", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(16), - queueName: "AF2", - targetGroup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF3", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(32), - queueName: "AF3", - targetGroup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "AF4", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(6), - queueName: "AF4", - targetGroup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(7), - queueName: "NC1", - targetGroup: "target-group-NC1", - }} - - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - s.SetPriority(tc.priority) - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - input.SetInputType(tc.inputType) - input.SetQueue(tc.queueName) - input.SetWeight(tc.weight) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - scheduler string - }{{ - desc: "output-interface-NC1", - queueName: "NC1", - scheduler: "scheduler", - }, { - desc: "output-interface-AF4", - queueName: "AF4", - scheduler: "scheduler", - }, { - desc: "output-interface-AF3", - queueName: "AF3", - scheduler: "scheduler", - }, { - desc: "output-interface-AF2", - queueName: "AF2", - scheduler: "scheduler", - }, { - desc: "output-interface-AF1", - queueName: "AF1", - scheduler: "scheduler", - }, { - desc: "output-interface-BE0", - queueName: "BE0", - scheduler: "scheduler", - }, { - desc: "output-interface-BE1", - queueName: "BE1", - scheduler: "scheduler", - }} - - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp2.Name()) - i.SetInterfaceId(dp2.Name()) - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp2.Name()) - output := i.GetOrCreateOutput() - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName(tc.scheduler) - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) -} diff --git a/feature/qos/ate_tests/two_sp_queue_traffic_test/README.md b/feature/qos/ate_tests/two_sp_queue_traffic_test/README.md deleted file mode 100644 index 69c06f27d9b..00000000000 --- a/feature/qos/ate_tests/two_sp_queue_traffic_test/README.md +++ /dev/null @@ -1,162 +0,0 @@ -# DP-1.8: Two strict priority queue traffic test - -## Summary - -Verify that DUT drops AF3, AF2, AF1, BE1 and BE0 before AF4 before NC1. - -## QoS traffic test setup: - -* Topology: - - * 2 input interfaces and 1 output interface with the same port speed. The - interface can be a physical interface or LACP bundle interface with the - same aggregated speed. - - ``` - ATE port 1 - | - DUT--------ATE port 3 - | - ATE port 2 - ``` - -* Traffic classes: - - * We will use 7 traffic classes NC1, AF4, AF3, AF2, AF1, BE1 and BE0. - -* Traffic types: - - * All the traffic tests apply to both IPv4 and IPv6 traffic. - -* Queue types: - - * NC1 will have strict priority queues - * AF4/AF3/AF2/AF1/BE1/BE0 will use WRR queues. - * NC1 and AF4 will have strict priority queues with NC1 having higher - priority. - * AF3, AF2, AF1, BE1 and BE0 will use WRR queues. - -* Test results should be independent of the location of interfaces. For - example, 2 input interfaces and output interface could be located on - - * Same ASIC-based forwarding engine - * Different ASIC-based forwarding engine on same line card - * Different ASIC-based forwarding engine on different line cards - -* Test results should be the same for port speeds 100G and 400G. - -* Counters should be also verified for each test case: - - * /qos/interfaces/interface/output/queues/queue/state/transmit-pkts - * /qos/interfaces/interface/output/queues/queue/state/dropped-pkts - * transmit-pkts should be equal to the number of Rx pkts on Ixia port - * dropped-pkts should be equal to diff between the number of Tx and the - number Rx pkts on Ixia ports - -* Latency: - - * Should be < 100000ns - -## Procedure - -* Connect DUT port-1 to ATE port-1, DUT port-2 to ATE port-2 and DUT port-3 to - ATE port-3. - -* Configuration - - * Configure strict priority queues for NC1 and AF4 with NC1 having higher - priority. - * Configure WRR for AF3, AF2, AF1, BE1 and BE0 with weight 12, 8, 4, 2 and - 1 respectively. - -* NC1 vs AF4 Strict priority traffic test - - * Non-oversubscription traffic test case - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Rx from interface1(%) | Rx from interface2(%) - ------------- | ----------------------- | ----------------------- | --------------------- | --------------------- - NC1 | 0.1 | 0.7 | 100 | 100 - AF4 | 45.1 | 54.1 | 100 | 100 - - * Oversubscription traffic test case - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Rx from interface1(%) | Rx from interface2(%) - ------------- | ----------------------- | ----------------------- | --------------------- | --------------------- - NC1 | 0.1 | 0.7 | 100 | 100 - AF4 | 99.9 | 99.3 | 49.8 | 49.8 - -* Repeat the above 2 test cases between traffic classes: - - * NC1 vs AF3 - * NC1 vs AF2 - * NC1 vs AF1 - * NC1 vs BE1 - * NC1 vs BE0 - -* Strict priority vs WRR traffic test - - * Starvation traffic test case - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Rx from interface1(%) | Rx from interface2(%) - ------------- | ----------------------- | ----------------------- | --------------------- | --------------------- - AF4 | 50 | 50 | 100 | 100 - AF3 | 50 | 50 | 0 | 0 - - * Oversubscription traffic test case - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Rx from interface1(%) | Rx from interface2(%) - ------------- | ----------------------- | ----------------------- | --------------------- | --------------------- - AF4 | 20 | 30 | 100 | 100 - AF3 | 60 | 40 | 50 | 50 - -* Repeat the above 2 test cases between traffic classes: - - * AF4 vs AF2 - * AF4 vs AF1 - * AF4 vs BE1 - * AF4 vs BE0 - -## Config parameter coverage - -* Classifiers - - * /qos/classifiers/classifier/config/name - * /qos/classifiers/classifier/config/type - * /qos/classifiers/classifier/terms/term/actions/config/target-group - * /qos/classifiers/classifier/terms/term/conditions/ipv4/config/dscp-set - * qos/classifiers/classifier/terms/term/conditions/ipv6/config/dscp-set - * /qos/classifiers/classifier/terms/term/config/id - -* Forwarding Groups - - * /qos/forwarding-groups/forwarding-group/config/name - * /qos/forwarding-groups/forwarding-group/config/output-queue - -* Queue - - * /qos/queues/queue/config/name - -* Interfaces - - * /qos/interfaces/interface/input/classifiers/classifier/config/name - * /qos/interfaces/interface/output/queues/queue/config/name - * /qos/interfaces/interface/output/scheduler-policy/config/name - -* Scheduler policy - - * /qos/scheduler-policies/scheduler-policy/config/name - * /qos/scheduler-policies/scheduler - -policy/schedulers/scheduler/config/priority - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/sequence - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/id - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight - -## Telemetry parameter coverage - -* /qos/interfaces/interface/output/queues/queue/state/transmit-pkts -* /qos/interfaces/interface/output/queues/queue/state/transmit-octets -* /qos/interfaces/interface/output/queues/queue/state/dropped-pkts -* /qos/interfaces/interface/output/queues/queue/state/dropped-octets diff --git a/feature/qos/ate_tests/two_sp_queue_traffic_test/metadata.textproto b/feature/qos/ate_tests/two_sp_queue_traffic_test/metadata.textproto deleted file mode 100644 index 0e2e765dd2b..00000000000 --- a/feature/qos/ate_tests/two_sp_queue_traffic_test/metadata.textproto +++ /dev/null @@ -1,41 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "50dd5501-d9c8-4888-9d9d-00f3c51e6068" -plan_id: "DP-1.8" -description: "Two strict priority queue traffic test" -testbed: TESTBED_DUT_ATE_4LINKS -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - ipv4_missing_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: JUNIPER - } - deviations: { - explicit_interface_ref_definition: true - scheduler_input_weight_limit: true - } -} -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_interface_ref_definition: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - interface_enabled: true - } -} diff --git a/feature/qos/ate_tests/two_sp_queue_traffic_test/two_sp_queue_traffic_test.go b/feature/qos/ate_tests/two_sp_queue_traffic_test/two_sp_queue_traffic_test.go deleted file mode 100644 index e78c328fbec..00000000000 --- a/feature/qos/ate_tests/two_sp_queue_traffic_test/two_sp_queue_traffic_test.go +++ /dev/null @@ -1,1872 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package two_sp_queue_traffic_test - -import ( - "testing" - "time" - - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/featureprofiles/internal/qoscfg" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ondatra/netutil" - "github.com/openconfig/ygot/ygot" -) - -type trafficData struct { - trafficRate float64 - expectedThroughputPct float32 - frameSize uint32 - dscp uint8 - queue string - inputIntf *ondatra.Interface -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// Test cases: -// 1) Non-oversubscription NC1 and AF4 traffic. -// - There should be no packet drop for all traffic classes. -// 2) Non-oversubscription NC1 and AF3 traffic. -// - There should be no packet drop for all traffic classes. -// 3) Non-oversubscription NC1 and AF2 traffic. -// - There should be no packet drop for all traffic classes. -// 4) Non-oversubscription NC1 and AF1 traffic. -// - There should be no packet drop for all traffic classes. -// 5) Non-oversubscription NC1 and BE0 traffic. -// - There should be no packet drop for all traffic classes. -// 6) Non-oversubscription NC1 and BE1 traffic. -// - There should be no packet drop for all traffic classes. -// 7) Non-oversubscription AF4 and AF3 traffic. -// - There should be no packet drop for all traffic classes. -// 8) Non-oversubscription AF4 and AF2 traffic. -// - There should be no packet drop for all traffic classes. -// 9) Non-oversubscription AF4 and AF1 traffic. -// - There should be no packet drop for all traffic classes. -// 10) Non-oversubscription AF4 and BE0 traffic. -// - There should be no packet drop for all traffic classes. -// 11) Non-oversubscription AF4 and BE1 traffic. -// - There should be no packet drop for all traffic classes. -// 12) Oversubscription NC1 and AF4 traffic. -// - There should be no packet drop for strict priority traffic class. -// 12) Oversubscription NC1 and AF3 traffic. -// - There should be no packet drop for strict priority traffic class. -// 13) Oversubscription NC1 and AF2 traffic. -// - There should be no packet drop for strict priority traffic class. -// 14) Oversubscription NC1 and AF1 traffic. -// - There should be no packet drop for strict priority traffic class. -// 15) Oversubscription NC1 and BE0 traffic. -// - There should be no packet drop for strict priority traffic class. -// 16) Oversubscription NC1 and BE1 traffic. -// - There should be no packet drop for strict priority traffic class. -// 17) Oversubscription AF4 and AF3 traffic. -// - There should be no packet drop for strict priority traffic class. -// 19) Oversubscription AF4 and AF3 traffic. -// - There should be no packet drop for strict priority traffic class. -// 20) Oversubscription AF4 and AF3 traffic. -// - There should be no packet drop for strict priority traffic class. -// 21) Oversubscription AF4 and AF3 traffic. -// - There should be no packet drop for strict priority traffic class. -// 22) Oversubscription AF4 and AF3 traffic. -// - There should be no packet drop for strict priority traffic class. -// -// Topology: -// ATE port 1 -// | -// DUT--------ATE port 3 -// | -// ATE port 2 -// -// Sample CLI command to get telemetry using gmic: -// - gnmic -a ipaddr:10162 -u username -p password --skip-verify get \ -// --path /components/component --format flat -// - gnmic tool info: -// - https://github.com/karimra/gnmic/blob/main/README.md -// - -func TestTwoSPQueueTraffic(t *testing.T) { - dut := ondatra.DUT(t, "dut") - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - - // Configure DUT interfaces and QoS. - ConfigureDUTIntf(t, dut) - ConfigureDUTIntf(t, dut) - if dut.Vendor() == ondatra.CISCO { - ConfigureCiscoQos(t, dut) - } else { - ConfigureQoS(t, dut) - } - - // Configure ATE interfaces. - ate := ondatra.ATE(t, "ate") - ap1 := ate.Port(t, "port1") - ap2 := ate.Port(t, "port2") - ap3 := ate.Port(t, "port3") - top := ate.Topology().New() - intf1 := top.AddInterface("intf1").WithPort(ap1) - intf1.IPv4(). - WithAddress("198.51.100.1/31"). - WithDefaultGateway("198.51.100.0") - intf2 := top.AddInterface("intf2").WithPort(ap2) - intf2.IPv4(). - WithAddress("198.51.100.3/31"). - WithDefaultGateway("198.51.100.2") - intf3 := top.AddInterface("intf3").WithPort(ap3) - intf3.IPv4(). - WithAddress("198.51.100.5/31"). - WithDefaultGateway("198.51.100.4") - top.Push(t).StartProtocols(t) - - var tolerance float32 = 2.0 - queues := netutil.CommonTrafficQueues(t, dut) - - // Test case 1: Non-oversubscription NC1 and AF4 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows1 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af4": { - frameSize: 1000, - trafficRate: 45.1, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 54.1, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - } - - // Test case 2: Non-oversubscription NC1 and AF3 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows2 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af3": { - frameSize: 1000, - trafficRate: 45.1, - expectedThroughputPct: 100.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 54.1, - dscp: 24, - expectedThroughputPct: 100.0, - queue: queues.AF3, - inputIntf: intf2, - }, - } - - // Test case 3: Non-oversubscription NC1 and AF2 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows3 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 45.1, - expectedThroughputPct: 100.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 54.1, - dscp: 16, - expectedThroughputPct: 100.0, - queue: queues.AF2, - inputIntf: intf2, - }, - } - - // Test case 4: Non-oversubscription NC1 and AF1 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows4 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 45.1, - expectedThroughputPct: 100.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 54.1, - dscp: 8, - expectedThroughputPct: 100.0, - queue: queues.AF1, - inputIntf: intf2, - }, - } - - // Test case 5: Non-oversubscription NC1 and BE0 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows5 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 45.1, - expectedThroughputPct: 100.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 54.1, - dscp: 4, - expectedThroughputPct: 100.0, - queue: queues.BE0, - inputIntf: intf2, - }, - } - - // Test case 6: Non-oversubscription NC1 and BE1 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows6 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 45.1, - expectedThroughputPct: 100.0, - dscp: 0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 54.1, - dscp: 0, - expectedThroughputPct: 100.0, - queue: queues.BE1, - inputIntf: intf2, - }, - } - - // Test case 7: Non-oversubscription AF4 and AF3 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows7 := map[string]*trafficData{ - "intf1-af4": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-af3": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 0.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 50, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 50, - dscp: 24, - expectedThroughputPct: 0.0, - queue: queues.AF3, - inputIntf: intf2, - }, - } - - // Test case 8: Non-oversubscription AF4 and AF2 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows8 := map[string]*trafficData{ - "intf1-af4": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 0.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 50, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 50, - dscp: 16, - expectedThroughputPct: 0.0, - queue: queues.AF2, - inputIntf: intf2, - }, - } - - // Test case 9: Non-oversubscription AF4 and AF1 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows9 := map[string]*trafficData{ - "intf1-af4": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 0.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 50, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 50, - dscp: 8, - expectedThroughputPct: 0.0, - queue: queues.AF1, - inputIntf: intf2, - }, - } - - // Test case 10: Non-oversubscription AF4 and BE0 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows10 := map[string]*trafficData{ - "intf1-af4": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 0.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 50, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 50, - dscp: 4, - expectedThroughputPct: 0.0, - queue: queues.BE0, - inputIntf: intf2, - }, - } - - // Test case 11: Non-oversubscription AF4 and BE1 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows11 := map[string]*trafficData{ - "intf1-af4": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 0.0, - dscp: 0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 50, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 50, - dscp: 0, - expectedThroughputPct: 0.0, - queue: queues.BE1, - inputIntf: intf2, - }, - } - - // Test case 12: Oversubscription NC1 and AF4 traffic. - // - There should be no packet drop for strict priority traffic class. - oversubscribedTrafficFlows1 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af4": { - frameSize: 1000, - trafficRate: 99.9, - expectedThroughputPct: 49.8, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 99.3, - dscp: 32, - expectedThroughputPct: 49.8, - queue: queues.AF4, - inputIntf: intf2, - }, - } - - // Test case 13: Oversubscription NC1 and AF3 traffic. - // - There should be no packet drop for strict priority traffic class. - oversubscribedTrafficFlows2 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af3": { - frameSize: 1000, - trafficRate: 99.9, - expectedThroughputPct: 49.8, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 99.3, - dscp: 24, - expectedThroughputPct: 49.8, - queue: queues.AF3, - inputIntf: intf2, - }, - } - - // Test case 14: Oversubscription NC1 and AF2 traffic. - // - There should be no packet drop for strict priority traffic class. - oversubscribedTrafficFlows3 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 99.9, - expectedThroughputPct: 49.8, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 99.3, - dscp: 16, - expectedThroughputPct: 49.8, - queue: queues.AF2, - inputIntf: intf2, - }, - } - - // Test case 15: Oversubscription NC1 and AF1 traffic. - // - There should be no packet drop for strict priority traffic class. - oversubscribedTrafficFlows4 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 99.9, - expectedThroughputPct: 49.8, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 99.3, - dscp: 8, - expectedThroughputPct: 49.8, - queue: queues.AF1, - inputIntf: intf2, - }, - } - - // Test case 16: Oversubscription NC1 and BE0 traffic. - // - There should be no packet drop for strict priority traffic class. - oversubscribedTrafficFlows5 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 99.9, - expectedThroughputPct: 49.8, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.NC1, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 99.3, - dscp: 4, - expectedThroughputPct: 49.8, - queue: queues.BE0, - inputIntf: intf2, - }, - } - - // Test case 17: Oversubscription NC1 and BE1 traffic. - // - There should be no packet drop for strict priority traffic class. - oversubscribedTrafficFlows6 := map[string]*trafficData{ - "intf1-nc1": { - frameSize: 1000, - trafficRate: 0.1, - expectedThroughputPct: 100.0, - dscp: 56, - queue: queues.NC1, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 99.9, - expectedThroughputPct: 49.8, - dscp: 0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-nc1": { - frameSize: 1000, - trafficRate: 0.7, - dscp: 56, - expectedThroughputPct: 100.0, - queue: queues.BE1, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 99.3, - dscp: 0, - expectedThroughputPct: 49.8, - queue: queues.BE1, - inputIntf: intf2, - }, - } - - // Test case 18: Oversubscription AF4 and AF3 traffic. - // - There should be no packet drop for strict priority traffic class. - oversubscribedTrafficFlows7 := map[string]*trafficData{ - "intf1-af4": { - frameSize: 1000, - trafficRate: 20, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-af3": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 50.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 30, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 50, - dscp: 24, - expectedThroughputPct: 50.0, - queue: queues.AF3, - inputIntf: intf2, - }, - } - - // Test case 19: Non-oversubscription AF4 and AF2 traffic. - // - There should be no packet drop for all traffic classes. - oversubscribedTrafficFlows8 := map[string]*trafficData{ - "intf1-af4": { - frameSize: 1000, - trafficRate: 20, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 50.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 30, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 50, - dscp: 16, - expectedThroughputPct: 50.0, - queue: queues.AF2, - inputIntf: intf2, - }, - } - - // Test case 20: Non-oversubscription AF4 and AF1 traffic. - // - There should be no packet drop for all traffic classes. - oversubscribedTrafficFlows9 := map[string]*trafficData{ - "intf1-af4": { - frameSize: 1000, - trafficRate: 20, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 50.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 30, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 50, - dscp: 8, - expectedThroughputPct: 50.0, - queue: queues.AF1, - inputIntf: intf2, - }, - } - - // Test case 21: Non-oversubscription AF4 and BE0 traffic. - // - There should be no packet drop for all traffic classes. - oversubscribedTrafficFlows10 := map[string]*trafficData{ - "intf1-af4": { - frameSize: 1000, - trafficRate: 20, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 50.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 30, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 50, - dscp: 4, - expectedThroughputPct: 50.0, - queue: queues.BE0, - inputIntf: intf2, - }, - } - - // Test case 22: Non-oversubscription AF4 and BE1 traffic. - // - There should be no packet drop for all traffic classes. - oversubscribedTrafficFlows11 := map[string]*trafficData{ - "intf1-af4": { - frameSize: 1000, - trafficRate: 20, - expectedThroughputPct: 100.0, - dscp: 32, - queue: queues.AF4, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 50.0, - dscp: 0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-af4": { - frameSize: 1000, - trafficRate: 30, - dscp: 32, - expectedThroughputPct: 100.0, - queue: queues.AF4, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 50, - dscp: 0, - expectedThroughputPct: 50.0, - queue: queues.BE1, - inputIntf: intf2, - }, - } - - cases := []struct { - desc string - trafficFlows map[string]*trafficData - }{{ - desc: "Non-oversubscription NC1 and AF4 traffic", - trafficFlows: nonOversubscribedTrafficFlows1, - }, { - desc: "Non-oversubscription NC1 and AF3 traffic", - trafficFlows: nonOversubscribedTrafficFlows2, - }, { - desc: "Non-oversubscription NC1 and AF2 traffic", - trafficFlows: nonOversubscribedTrafficFlows3, - }, { - desc: "Non-oversubscription NC1 and AF1 traffic", - trafficFlows: nonOversubscribedTrafficFlows4, - }, { - desc: "Non-oversubscription NC1 and BE0 traffic", - trafficFlows: nonOversubscribedTrafficFlows5, - }, { - desc: "Non-oversubscription NC1 and BE1 traffic", - trafficFlows: nonOversubscribedTrafficFlows6, - }, { - desc: "Non-oversubscription AF4 and AF3 traffic", - trafficFlows: nonOversubscribedTrafficFlows7, - }, { - desc: "Non-oversubscription AF4 and AF2 traffic", - trafficFlows: nonOversubscribedTrafficFlows8, - }, { - desc: "Non-oversubscription AF4 and AF1 traffic", - trafficFlows: nonOversubscribedTrafficFlows9, - }, { - desc: "Non-oversubscription AF4 and BE0 traffic", - trafficFlows: nonOversubscribedTrafficFlows10, - }, { - desc: "Non-oversubscription AF4 and BE1 traffic", - trafficFlows: nonOversubscribedTrafficFlows11, - }, { - desc: "Oversubscription NC1 and AF4 traffic with half AF4 dropped", - trafficFlows: oversubscribedTrafficFlows1, - }, { - desc: "Oversubscription NC1 and AF3 traffic with half AF3 dropped", - trafficFlows: oversubscribedTrafficFlows2, - }, { - desc: "Oversubscription NC1 and AF2 traffic with half AF2 dropped", - trafficFlows: oversubscribedTrafficFlows3, - }, { - desc: "Oversubscription NC1 and AF1 traffic with half AF1 dropped", - trafficFlows: oversubscribedTrafficFlows4, - }, { - desc: "Oversubscription NC1 and BE0 traffic with half BE0 dropped", - trafficFlows: oversubscribedTrafficFlows5, - }, { - desc: "Oversubscription NC1 and BE1 traffic with half BE1 dropped", - trafficFlows: oversubscribedTrafficFlows6, - }, { - desc: "Oversubscription AF4 and AF3 traffic with half AF3 dropped", - trafficFlows: oversubscribedTrafficFlows7, - }, { - desc: "Oversubscription AF4 and AF2 traffic with half AF2 dropped", - trafficFlows: oversubscribedTrafficFlows8, - }, { - desc: "Oversubscription AF4 and AF1 traffic with half AF1 dropped", - trafficFlows: oversubscribedTrafficFlows9, - }, { - desc: "Oversubscription AF4 and BE0 traffic with half BE0 dropped", - trafficFlows: oversubscribedTrafficFlows10, - }, { - desc: "Oversubscription AF4 and BE1 traffic with half BE1 dropped", - trafficFlows: oversubscribedTrafficFlows11, - }} - - for _, tc := range cases { - t.Run(tc.desc, func(t *testing.T) { - trafficFlows := tc.trafficFlows - - var flows []*ondatra.Flow - for trafficID, data := range trafficFlows { - t.Logf("Configuring flow %s", trafficID) - flow := ate.Traffic().NewFlow(trafficID). - WithSrcEndpoints(data.inputIntf). - WithDstEndpoints(intf3). - WithHeaders(ondatra.NewEthernetHeader(), ondatra.NewIPv4Header().WithDSCP(data.dscp)). - WithFrameRatePct(data.trafficRate). - WithFrameSize(data.frameSize) - flows = append(flows, flow) - } - - ateOutPkts := make(map[string]uint64) - ateInPkts := make(map[string]uint64) - dutQosPktsBeforeTraffic := make(map[string]uint64) - dutQosPktsAfterTraffic := make(map[string]uint64) - dutQosDroppedPktsBeforeTraffic := make(map[string]uint64) - dutQosDroppedPktsAfterTraffic := make(map[string]uint64) - - // Set the initial counters to 0. - for _, data := range trafficFlows { - ateOutPkts[data.queue] = 0 - ateInPkts[data.queue] = 0 - dutQosPktsBeforeTraffic[data.queue] = 0 - dutQosPktsAfterTraffic[data.queue] = 0 - dutQosDroppedPktsBeforeTraffic[data.queue] = 0 - dutQosDroppedPktsAfterTraffic[data.queue] = 0 - } - - // Get QoS egress packet counters before the traffic. - for _, data := range trafficFlows { - dutQosPktsBeforeTraffic[data.queue] += gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) - dutQosDroppedPktsBeforeTraffic[data.queue] += gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - } - - t.Logf("Running traffic 1 on DUT interfaces: %s => %s ", dp1.Name(), dp3.Name()) - t.Logf("Running traffic 2 on DUT interfaces: %s => %s ", dp2.Name(), dp3.Name()) - t.Logf("Sending traffic flows: \n%v\n\n", trafficFlows) - ate.Traffic().Start(t, flows...) - time.Sleep(30 * time.Second) - ate.Traffic().Stop(t) - time.Sleep(30 * time.Second) - - for trafficID, data := range trafficFlows { - ateOutPkts[data.queue] += gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).Counters().OutPkts().State()) - ateInPkts[data.queue] += gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).Counters().InPkts().State()) - dutQosPktsAfterTraffic[data.queue] += gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) - dutQosDroppedPktsAfterTraffic[data.queue] += gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - t.Logf("ateInPkts: %v, txPkts %v, Queue: %v", ateInPkts[data.queue], dutQosPktsAfterTraffic[data.queue], data.queue) - - lossPct := gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).LossPct().State()) - t.Logf("Get flow %q: lossPct: %.2f%% or rxPct: %.2f%%, want: %.2f%%\n\n", data.queue, lossPct, 100.0-lossPct, data.expectedThroughputPct) - if got, want := 100.0-lossPct, data.expectedThroughputPct; got < want-tolerance || got > want+tolerance { - t.Errorf("Get(throughput for queue %q): got %.2f%%, want within [%.2f%%, %.2f%%]", data.queue, got, want-tolerance, want+tolerance) - } - } - - // Check QoS egress packet counters are updated correctly. - t.Logf("QoS dutQosPktsBeforeTraffic: %v", dutQosPktsBeforeTraffic) - t.Logf("QoS dutQosPktsAfterTraffic: %v", dutQosPktsAfterTraffic) - t.Logf("QoS dutQosDroppedPktsBeforeTraffic: %v", dutQosDroppedPktsBeforeTraffic) - t.Logf("QoS dutQosDroppedPktsAfterTraffic: %v", dutQosDroppedPktsAfterTraffic) - t.Logf("QoS ateOutPkts: %v", ateOutPkts) - t.Logf("QoS ateInPkts: %v", ateInPkts) - for _, data := range trafficFlows { - qosCounterDiff := dutQosPktsAfterTraffic[data.queue] - dutQosPktsBeforeTraffic[data.queue] - ateCounterDiff := ateInPkts[data.queue] - ateDropCounterDiff := ateOutPkts[data.queue] - ateInPkts[data.queue] - dutDropCounterDiff := dutQosDroppedPktsAfterTraffic[data.queue] - dutQosDroppedPktsBeforeTraffic[data.queue] - t.Logf("QoS queue %q: ateDropCounterDiff: %v dutDropCounterDiff: %v", data.queue, ateDropCounterDiff, dutDropCounterDiff) - if qosCounterDiff < ateCounterDiff { - t.Errorf("Get telemetry packet update for queue %q: got %v, want >= %v", data.queue, qosCounterDiff, ateCounterDiff) - } - } - }) - } -} - -func ConfigureDUTIntf(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - - dutIntfs := []struct { - desc string - intfName string - ipAddr string - prefixLen uint8 - }{{ - desc: "Input interface port1", - intfName: dp1.Name(), - ipAddr: "198.51.100.0", - prefixLen: 31, - }, { - desc: "Input interface port2", - intfName: dp2.Name(), - ipAddr: "198.51.100.2", - prefixLen: 31, - }, { - desc: "Output interface port3", - intfName: dp3.Name(), - ipAddr: "198.51.100.4", - prefixLen: 31, - }} - - // Configure the interfaces. - for _, intf := range dutIntfs { - t.Logf("Configure DUT interface %s with attributes %v", intf.intfName, intf) - i := &oc.Interface{ - Name: ygot.String(intf.intfName), - Description: ygot.String(intf.desc), - Type: oc.IETFInterfaces_InterfaceType_ethernetCsmacd, - Enabled: ygot.Bool(true), - } - i.GetOrCreateEthernet() - s := i.GetOrCreateSubinterface(0).GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) && !deviations.IPv4MissingEnabled(dut) { - s.Enabled = ygot.Bool(true) - } - a := s.GetOrCreateAddress(intf.ipAddr) - a.PrefixLength = ygot.Uint8(intf.prefixLen) - gnmi.Replace(t, dut, gnmi.OC().Interface(intf.intfName).Config(), i) - } -} - -func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - d := &oc.Root{} - q := d.GetOrCreateQos() - queues := netutil.CommonTrafficQueues(t, dut) - - t.Logf("Create qos forwarding groups config") - forwardingGroups := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - t.Logf("qos forwarding groups config: %v", forwardingGroups) - for _, tc := range forwardingGroups { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - } - - t.Logf("Create qos Classifiers config") - classifiers := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - t.Logf("qos Classifiers config: %v", classifiers) - for _, tc := range classifiers { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.name == "dscp_based_classifier_ipv4" { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.name == "dscp_based_classifier_ipv6" { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos input classifier config") - classifierIntfs := []struct { - desc string - intf string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }, { - desc: "Input Classifier Type IPV4", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - t.Logf("qos input classifier config: %v", classifierIntfs) - for _, tc := range classifierIntfs { - qoscfg.SetInputClassifier(t, dut, q, tc.intf, tc.inputClassifierType, tc.classifier) - } - - nc1InputWeight := uint64(200) - af4InputWeight := uint64(100) - if deviations.SchedulerInputWeightLimit(dut) { - nc1InputWeight = uint64(100) - af4InputWeight = uint64(99) - } - - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - priority oc.E_Scheduler_Priority - inputID string - inputType oc.E_Input_InputType - weight uint64 - queueName string - targetGroup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE0", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(4), - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(8), - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF2", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(16), - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF3", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(32), - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "AF4", - inputType: oc.Input_InputType_QUEUE, - weight: af4InputWeight, - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - inputType: oc.Input_InputType_QUEUE, - weight: nc1InputWeight, - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - s.SetPriority(tc.priority) - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - input.SetInputType(tc.inputType) - input.SetQueue(tc.queueName) - input.SetWeight(tc.weight) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - scheduler string - }{{ - desc: "output-interface-BE1", - queueName: queues.BE1, - scheduler: "scheduler", - }, { - desc: "output-interface-BE0", - queueName: queues.BE0, - scheduler: "scheduler", - }, { - desc: "output-interface-AF1", - queueName: queues.AF1, - scheduler: "scheduler", - }, { - desc: "output-interface-AF2", - queueName: queues.AF2, - scheduler: "scheduler", - }, { - desc: "output-interface-AF3", - queueName: queues.AF3, - scheduler: "scheduler", - }, { - desc: "output-interface-AF4", - queueName: queues.AF4, - scheduler: "scheduler", - }, { - desc: "output-interface-NC1", - queueName: queues.NC1, - scheduler: "scheduler", - }} - - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp3.Name()) - i.SetInterfaceId(dp3.Name()) - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) - if deviations.InterfaceRefConfigUnsupported(dut) { - i.InterfaceRef = nil - } - output := i.GetOrCreateOutput() - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName(tc.scheduler) - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } -} -func ConfigureCiscoQos(t *testing.T, dut *ondatra.DUTDevice) { - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - d := &oc.Root{} - q := d.GetOrCreateQos() - t.Logf("Create qos Classifiers config") - classifiers := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - t.Logf("qos Classifiers config: %v", classifiers) - queueName := []string{"NC1", "AF4", "AF3", "AF2", "AF1", "BE0", "BE1"} - for i, queue := range queueName { - q1 := q.GetOrCreateQueue(queue) - q1.Name = ygot.String(queue) - queueid := len(queueName) - i - q1.QueueId = ygot.Uint8(uint8(queueid)) - - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - casesfwdgrp := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: "BE1", - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: "BE0", - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: "AF1", - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: "AF2", - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: "AF3", - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: "AF4", - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: "NC1", - targetGroup: "target-group-NC1", - }} - t.Logf("qos forwarding groups config cases: %v", casesfwdgrp) - for _, tc := range casesfwdgrp { - t.Run(tc.desc, func(t *testing.T) { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - }) - } - for _, tc := range classifiers { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.classType == oc.Qos_Classifier_Type_IPV4 { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.classType == oc.Qos_Classifier_Type_IPV6 { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos input classifier config") - classifierIntfs := []struct { - desc string - intf string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }, { - desc: "Input Classifier Type IPV4", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - t.Logf("qos input classifier config: %v", classifierIntfs) - for _, tc := range classifierIntfs { - qoscfg.SetInputClassifier(t, dut, q, tc.intf, tc.inputClassifierType, tc.classifier) - } - - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - priority oc.E_Scheduler_Priority - inputID string - inputType oc.E_Input_InputType - weight uint64 - queueName string - targetGrpoup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: "BE1", - targetGrpoup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE0", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(4), - queueName: "BE0", - targetGrpoup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(8), - queueName: "AF1", - targetGrpoup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF2", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(16), - queueName: "AF2", - targetGrpoup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF3", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(32), - queueName: "AF3", - targetGrpoup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "AF4", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(6), - queueName: "AF4", - targetGrpoup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(7), - queueName: "NC1", - targetGrpoup: "target-group-NC1", - }} - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - s.SetPriority(tc.priority) - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - input.SetInputType(tc.inputType) - input.SetQueue(tc.queueName) - input.SetWeight(tc.weight) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - scheduler string - }{{ - desc: "output-interface-NC1", - queueName: "NC1", - scheduler: "scheduler", - }, { - desc: "output-interface-AF4", - queueName: "AF4", - scheduler: "scheduler", - }, { - desc: "output-interface-AF3", - queueName: "AF3", - scheduler: "scheduler", - }, { - desc: "output-interface-AF2", - queueName: "AF2", - scheduler: "scheduler", - }, { - desc: "output-interface-AF1", - queueName: "AF1", - scheduler: "scheduler", - }, { - desc: "output-interface-BE0", - queueName: "BE0", - scheduler: "scheduler", - }, { - desc: "output-interface-BE1", - queueName: "BE1", - scheduler: "scheduler", - }} - - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp3.Name()) - i.SetInterfaceId(dp3.Name()) - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) - output := i.GetOrCreateOutput() - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName(tc.scheduler) - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - -} diff --git a/feature/qos/ate_tests/wrr_traffic_test/README.md b/feature/qos/ate_tests/wrr_traffic_test/README.md deleted file mode 100644 index 1a981ac4d5e..00000000000 --- a/feature/qos/ate_tests/wrr_traffic_test/README.md +++ /dev/null @@ -1,147 +0,0 @@ -# DP-1.9: WRR traffic test - -## Summary - -Verify that DUT forwards AF3, AF2, AF1, BE0 and BE1 traffic based on WRR weight. - -## QoS traffic test setup: - -* Topology: - - * 2 input interfaces and 1 output interface with the same port speed. The - interface can be a physical interface or LACP bundle interface with the - same aggregated speed. - - ``` - ATE port 1 - | - DUT--------ATE port 3 - | - ATE port 2 - ``` - -* Traffic classes: - - * We will use 7 traffic classes NC1, AF4, AF3, AF2, AF1, BE0 and BE1. - -* Traffic types: - - * All the traffic tests apply to both IPv4 and IPv6 traffic. - -* Queue types: - - * NC1 will have strict priority queues - * AF4/AF3/AF2/AF1/BE1/BE0 will use WRR queues. - * NC1 and AF4 will have strict priority queues with NC1 having higher - priority. - * AF3, AF2, AF1, BE1 and BE0 will use WRR queues. - -* Test results should be independent of the location of interfaces. For - example, 2 input interfaces and output interface could be located on - - * Same ASIC-based forwarding engine - * Different ASIC-based forwarding engine on same line card - * Different ASIC-based forwarding engine on different line cards - -* Test results should be the same for port speeds 100G and 400G. - -* Counters should be also verified for each test case: - - * /qos/interfaces/interface/output/queues/queue/state/transmit-pkts - * /qos/interfaces/interface/output/queues/queue/state/dropped-pkts - * transmit-pkts should be equal to the number of Rx pkts on Ixia port - * dropped-pkts should be equal to diff between the number of Tx and the - number Rx pkts on Ixia ports - -* Latency: - - * Should be < 100000ns - -## Procedure - -* Connect DUT port-1 to ATE port-1, DUT port-2 to ATE port-2 and DUT port-3 to - ATE port-3. - -* Configure WRR for AF3, AF2, AF1, BE0 and BE1 with weight 64, 16, 4, 1 and - 1 respectively. - -* AF3 vs AF2 traffic test - - * Non-oversubscription traffic test case - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Rx from interface1(%) | Rx from interface2(%) - ------------- | ----------------------- | ----------------------- | --------------------- | --------------------- - AF3 | 40 | 40 | 100 | 100 - AF2 | 10 | 10 | 100 | 100 - - * Oversubscription traffic test case 1 - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Rx from interface1(%) | Rx from interface2(%) - ------------- | ----------------------- | ----------------------- | --------------------- | --------------------- - AF3 | 80 | 80 | 50 | 50 - AF2 | 10 | 10 | 100 | 100 - - * Oversubscription traffic test case 2 - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Rx from interface1(%) | Rx from interface2(%) - ------------- | ----------------------- | ----------------------- | --------------------- | --------------------- - AF3 | 40 | 40 | 100 | 100 - AF2 | 20 | 20 | 50 | 50 - - * Oversubscription traffic test case 3 - - Traffic class | Interface1(line rate %) | Interface2(line rate %) | Rx from interface1(%) | Rx from interface2(%) - ------------- | ----------------------- | ----------------------- | --------------------- | --------------------- - AF3 | 50 | 50 | 80 | 80 - AF2 | 50 | 50 | 20 | 20 - -* Repeat the above 3 oversubscription test cases between traffic classes - - * AF2 vs AF1 - * AF1 vs BE1 - * BE1 vs BE0 - -## Config parameter coverage - -* Classifiers - - * /qos/classifiers/classifier/config/name - * /qos/classifiers/classifier/config/type - * /qos/classifiers/classifier/terms/term/actions/config/target-group - * /qos/classifiers/classifier/terms/term/conditions/ipv4/config/dscp-set - * qos/classifiers/classifier/terms/term/conditions/ipv6/config/dscp-set - * /qos/classifiers/classifier/terms/term/config/id - -* Forwarding Groups - - * /qos/forwarding-groups/forwarding-group/config/name - * /qos/forwarding-groups/forwarding-group/config/output-queue - -* Queue - - * /qos/queues/queue/config/name - -* Interfaces - - * /qos/interfaces/interface/input/classifiers/classifier/config/name - * /qos/interfaces/interface/output/queues/queue/config/name - * /qos/interfaces/interface/output/scheduler-policy/config/name - -* Scheduler policy - - * /qos/scheduler-policies/scheduler-policy/config/name - * /qos/scheduler-policies/scheduler - -policy/schedulers/scheduler/config/priority - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/sequence - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/config/type - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/id - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/input-type - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/queue - * /qos/scheduler-policies/scheduler-policy/schedulers/scheduler/inputs/input/config/weight - -## Telemetry parameter coverage - -* /qos/interfaces/interface/output/queues/queue/state/transmit-pkts -* /qos/interfaces/interface/output/queues/queue/state/transmit-octets -* /qos/interfaces/interface/output/queues/queue/state/dropped-pkts -* /qos/interfaces/interface/output/queues/queue/state/dropped-octets diff --git a/feature/qos/ate_tests/wrr_traffic_test/metadata.textproto b/feature/qos/ate_tests/wrr_traffic_test/metadata.textproto deleted file mode 100644 index 83e7de3d525..00000000000 --- a/feature/qos/ate_tests/wrr_traffic_test/metadata.textproto +++ /dev/null @@ -1,41 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "50dd5501-d9c8-4888-9d9d-00f3c51e6088" -plan_id: "DP-1.9" -description: "WRR traffic test" -testbed: TESTBED_DUT_ATE_4LINKS -platform_exceptions: { - platform: { - vendor: CISCO - } - deviations: { - ipv4_missing_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: JUNIPER - } - deviations: { - explicit_interface_ref_definition: true - scheduler_input_weight_limit: true - } -} -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_interface_ref_definition: true - interface_enabled: true - } -} -platform_exceptions: { - platform: { - vendor: ARISTA - } - deviations: { - interface_enabled: true - } -} diff --git a/feature/qos/ate_tests/wrr_traffic_test/wrr_traffic_test.go b/feature/qos/ate_tests/wrr_traffic_test/wrr_traffic_test.go deleted file mode 100644 index f7fea2dac8c..00000000000 --- a/feature/qos/ate_tests/wrr_traffic_test/wrr_traffic_test.go +++ /dev/null @@ -1,1642 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package wrr_traffic_test - -import ( - "testing" - "time" - - "github.com/openconfig/featureprofiles/internal/deviations" - "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/featureprofiles/internal/qoscfg" - "github.com/openconfig/ondatra" - "github.com/openconfig/ondatra/gnmi" - "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ondatra/netutil" - "github.com/openconfig/ygot/ygot" -) - -type trafficData struct { - trafficRate float64 - expectedThroughputPct float32 - frameSize uint32 - dscp uint8 - queue string - inputIntf *ondatra.Interface -} - -func TestMain(m *testing.M) { - fptest.RunTests(m) -} - -// Test cases: -// 1) Non-oversubscription AF3 and AF2 traffic. -// - There should be no packet drop for all traffic classes. -// 2) Non-oversubscription AF2 and AF1 traffic. -// - There should be no packet drop for all traffic classes. -// 3) Non-oversubscription AF1 and BE0 traffic. -// - There should be no packet drop for all traffic classes. -// 4) Non-oversubscription BE0 and BE1 traffic. -// - There should be no packet drop for all traffic classes. -// 5) Oversubscription AF3 and AF2 traffic 1. -// - There should be half of the AF3 drops. -// 6) Oversubscription AF3 and AF2 traffic 2. -// - There should be half of the AF2 drops. -// 7) Oversubscription AF3 and AF2 traffic 3. -// - There should be 20% of AF3 and 80% of AF2 drops. -// 8) Oversubscription AF2 and AF1 traffic 1. -// - There should be half of the AF2 drops. -// 9) Oversubscription AF2 and AF1 traffic 2. -// - There should be half of the AF1 drops. -// 10) Oversubscription AF2 and AF1 traffic 3. -// - There should be 20% of AF2 and 80% of AF1 drops. -// 11) Oversubscription AF1 and BE0 traffic 1. -// - There should be half of the AF1 drops. -// 12) Oversubscription AF1 and BE0 traffic 2. -// - There should be half of the BE0 drops. -// 13) Oversubscription AF1 and BE0 traffic 3. -// - There should be 20% of AF1 and 80% of BE0 drops. -// 14) Oversubscription BE0 and BE1 traffic 1. -// - There should be half of the BE0 drops. -// 15) Oversubscription BE0 and BE1 traffic 2. -// - There should be half of the BE1 drops. -// 16) Oversubscription BE0 and BE1 traffic 3. -// - There should be 20% of BE0 and 80% of BE1 drops. -// -// Topology: -// ATE port 1 -// | -// DUT--------ATE port 3 -// | -// ATE port 2 -// -// Sample CLI command to get telemetry using gmic: -// - gnmic -a ipaddr:10162 -u username -p password --skip-verify get \ -// --path /components/component --format flat -// - gnmic tool info: -// - https://github.com/karimra/gnmic/blob/main/README.md -// - -func TestWrrTraffic(t *testing.T) { - dut := ondatra.DUT(t, "dut") - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - - // Configure DUT interfaces and QoS. - ConfigureDUTIntf(t, dut) - if dut.Vendor() == ondatra.CISCO { - ConfigureCiscoQos(t, dut) - } else { - ConfigureQoS(t, dut) - } - - // Configure ATE interfaces. - ate := ondatra.ATE(t, "ate") - ap1 := ate.Port(t, "port1") - ap2 := ate.Port(t, "port2") - ap3 := ate.Port(t, "port3") - top := ate.Topology().New() - intf1 := top.AddInterface("intf1").WithPort(ap1) - intf1.IPv4(). - WithAddress("198.51.100.1/31"). - WithDefaultGateway("198.51.100.0") - intf2 := top.AddInterface("intf2").WithPort(ap2) - intf2.IPv4(). - WithAddress("198.51.100.3/31"). - WithDefaultGateway("198.51.100.2") - intf3 := top.AddInterface("intf3").WithPort(ap3) - intf3.IPv4(). - WithAddress("198.51.100.5/31"). - WithDefaultGateway("198.51.100.4") - top.Push(t).StartProtocols(t) - - var tolerance float32 = 3.0 - queues := netutil.CommonTrafficQueues(t, dut) - - // Test case 1: Non-oversubscription AF3 and AF2 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows1 := map[string]*trafficData{ - "intf1-af3": { - frameSize: 1000, - trafficRate: 40, - expectedThroughputPct: 100.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 10, - expectedThroughputPct: 100.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 40, - dscp: 24, - expectedThroughputPct: 100.0, - queue: queues.AF3, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 10, - dscp: 16, - expectedThroughputPct: 100.0, - queue: queues.AF2, - inputIntf: intf2, - }, - } - - // Test case 2: Non-oversubscription AF2 and AF1 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows2 := map[string]*trafficData{ - "intf1-af2": { - frameSize: 1000, - trafficRate: 40, - expectedThroughputPct: 100.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 10, - expectedThroughputPct: 100.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 40, - dscp: 16, - expectedThroughputPct: 100.0, - queue: queues.AF2, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 10, - dscp: 8, - expectedThroughputPct: 100.0, - queue: queues.AF1, - inputIntf: intf2, - }, - } - - // Test case 3: Non-oversubscription AF1 and BE0 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows3 := map[string]*trafficData{ - "intf1-af1": { - frameSize: 1000, - trafficRate: 40, - expectedThroughputPct: 100.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 10, - expectedThroughputPct: 100.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 40, - dscp: 8, - expectedThroughputPct: 100.0, - queue: queues.AF1, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 10, - dscp: 4, - expectedThroughputPct: 100.0, - queue: queues.BE0, - inputIntf: intf2, - }, - } - - // Test case 4: Non-oversubscription BE0 and BE1 traffic. - // - There should be no packet drop for all traffic classes. - nonOversubscribedTrafficFlows4 := map[string]*trafficData{ - "intf1-be0": { - frameSize: 1000, - trafficRate: 25, - expectedThroughputPct: 100.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 25, - expectedThroughputPct: 100.0, - dscp: 0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 25, - dscp: 4, - expectedThroughputPct: 100.0, - queue: queues.BE0, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 25, - dscp: 0, - expectedThroughputPct: 100.0, - queue: queues.BE1, - inputIntf: intf2, - }, - } - - // Test case 5: Oversubscription AF3 and AF2 traffic 1. - // - There should be half of the AF3 drops. - oversubscribedTrafficFlows1 := map[string]*trafficData{ - "intf1-af3": { - frameSize: 1000, - trafficRate: 80, - expectedThroughputPct: 50.0, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 10, - expectedThroughputPct: 100.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 80, - dscp: 24, - expectedThroughputPct: 50.0, - queue: queues.AF3, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 10, - dscp: 16, - expectedThroughputPct: 100.0, - queue: queues.AF2, - inputIntf: intf2, - }, - } - - // Test case 6: Oversubscription AF3 and AF2 traffic 2. - // - There should be half of the AF2 drops. - oversubscribedTrafficFlows2 := map[string]*trafficData{ - "intf1-af3": { - frameSize: 1000, - trafficRate: 40, - expectedThroughputPct: 100, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 20, - expectedThroughputPct: 50, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 40, - dscp: 24, - expectedThroughputPct: 100, - queue: queues.AF3, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 20, - dscp: 16, - expectedThroughputPct: 50, - queue: queues.AF2, - inputIntf: intf2, - }, - } - - // Test case 7: Oversubscription AF3 and AF2 traffic 3. - // - There should be 20% of AF3 and 80% of AF2 drops. - oversubscribedTrafficFlows3 := map[string]*trafficData{ - "intf1-af3": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 80, - dscp: 24, - queue: queues.AF3, - inputIntf: intf1, - }, - "intf1-af2": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 20, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf2-af3": { - frameSize: 1000, - trafficRate: 50, - dscp: 24, - expectedThroughputPct: 80, - queue: queues.AF3, - inputIntf: intf2, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 50, - dscp: 16, - expectedThroughputPct: 20, - queue: queues.AF2, - inputIntf: intf2, - }, - } - - // Test case 8: Oversubscription AF2 and AF1 traffic 1. - // - There should be half of the AF2 drops. - oversubscribedTrafficFlows4 := map[string]*trafficData{ - "intf1-af2": { - frameSize: 1000, - trafficRate: 80, - expectedThroughputPct: 50.0, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 10, - expectedThroughputPct: 100.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 80, - dscp: 16, - expectedThroughputPct: 50.0, - queue: queues.AF2, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 10, - dscp: 8, - expectedThroughputPct: 100.0, - queue: queues.AF1, - inputIntf: intf2, - }, - } - - // Test case 9: Oversubscription AF2 and AF1 traffic 2. - // - There should be half of the AF1 drops. - oversubscribedTrafficFlows5 := map[string]*trafficData{ - "intf1-af2": { - frameSize: 1000, - trafficRate: 40, - expectedThroughputPct: 100, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 20, - expectedThroughputPct: 50, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 40, - dscp: 16, - expectedThroughputPct: 100, - queue: queues.AF2, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 20, - dscp: 8, - expectedThroughputPct: 50, - queue: queues.AF1, - inputIntf: intf2, - }, - } - - // Test case 10: Oversubscription AF2 and AF1 traffic 3. - // - There should be 20% of AF2 and 80% of AF1 drops. - oversubscribedTrafficFlows6 := map[string]*trafficData{ - "intf1-af2": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 80, - dscp: 16, - queue: queues.AF2, - inputIntf: intf1, - }, - "intf1-af1": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 20, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf2-af2": { - frameSize: 1000, - trafficRate: 50, - dscp: 16, - expectedThroughputPct: 80, - queue: queues.AF2, - inputIntf: intf2, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 50, - dscp: 8, - expectedThroughputPct: 20, - queue: queues.AF1, - inputIntf: intf2, - }, - } - - // Test case 11: Oversubscription AF1 and BE0 traffic 1. - // - There should be half of the AF1 drops. - oversubscribedTrafficFlows7 := map[string]*trafficData{ - "intf1-af1": { - frameSize: 1000, - trafficRate: 80, - expectedThroughputPct: 50.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 10, - expectedThroughputPct: 100.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 80, - dscp: 8, - expectedThroughputPct: 50.0, - queue: queues.AF1, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 10, - dscp: 4, - expectedThroughputPct: 100.0, - queue: queues.BE0, - inputIntf: intf2, - }, - } - - // Test case 12: Oversubscription AF1 and BE0 traffic 2. - // - There should be half of the BE0 drops. - oversubscribedTrafficFlows8 := map[string]*trafficData{ - "intf1-af1": { - frameSize: 1000, - trafficRate: 40, - expectedThroughputPct: 100.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 20, - expectedThroughputPct: 50.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 40, - dscp: 8, - expectedThroughputPct: 100.0, - queue: queues.AF1, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 20, - dscp: 4, - expectedThroughputPct: 50.0, - queue: queues.BE0, - inputIntf: intf2, - }, - } - - // Test case 13: Oversubscription AF1 and BE0 traffic 3. - // - There should be 20% of AF1 and 80% of BE0 drops. - oversubscribedTrafficFlows9 := map[string]*trafficData{ - "intf1-af1": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 80.0, - dscp: 8, - queue: queues.AF1, - inputIntf: intf1, - }, - "intf1-be0": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 20.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf2-af1": { - frameSize: 1000, - trafficRate: 50, - dscp: 8, - expectedThroughputPct: 80.0, - queue: queues.AF1, - inputIntf: intf2, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 50, - dscp: 4, - expectedThroughputPct: 20.0, - queue: queues.BE0, - inputIntf: intf2, - }, - } - // Test case 14: Oversubscription BE0 and BE1 traffic 1. - // - There should be half of the BE0 drops. - oversubscribedTrafficFlows10 := map[string]*trafficData{ - "intf1-be0": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 50.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 25, - expectedThroughputPct: 100.0, - dscp: 0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 50, - dscp: 4, - expectedThroughputPct: 50.0, - queue: queues.BE0, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 25, - dscp: 0, - expectedThroughputPct: 100.0, - queue: queues.BE1, - inputIntf: intf2, - }, - } - - // Test case 15: Oversubscription BE0 and BE1 traffic 2. - // - There should be half of the BE1 drops. - oversubscribedTrafficFlows11 := map[string]*trafficData{ - "intf1-be0": { - frameSize: 1000, - trafficRate: 25, - expectedThroughputPct: 100.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 50.0, - dscp: 0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 25, - dscp: 4, - expectedThroughputPct: 100.0, - queue: queues.BE0, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 50, - dscp: 0, - expectedThroughputPct: 50.0, - queue: queues.BE1, - inputIntf: intf2, - }, - } - - // Test case 16: Oversubscription BE0 and BE1 traffic 3. - // - There should be 50% of BE0 and 50% of BE1 drops. - oversubscribedTrafficFlows12 := map[string]*trafficData{ - "intf1-be0": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 50.0, - dscp: 4, - queue: queues.BE0, - inputIntf: intf1, - }, - "intf1-be1": { - frameSize: 1000, - trafficRate: 50, - expectedThroughputPct: 50.0, - dscp: 0, - queue: queues.BE1, - inputIntf: intf1, - }, - "intf2-be0": { - frameSize: 1000, - trafficRate: 50, - dscp: 4, - expectedThroughputPct: 50.0, - queue: queues.BE0, - inputIntf: intf2, - }, - "intf2-be1": { - frameSize: 1000, - trafficRate: 50, - dscp: 0, - expectedThroughputPct: 50.0, - queue: queues.BE1, - inputIntf: intf2, - }, - } - type test struct { - desc string - trafficFlows map[string]*trafficData - trafficDuration time.Duration - } - - cases := []test{ - { - desc: "Non-oversubscription AF3 and AF2 traffic", - trafficFlows: nonOversubscribedTrafficFlows1, - trafficDuration: 60 * time.Second, - }, { - desc: "Non-oversubscription AF2 and AF1 traffic", - trafficFlows: nonOversubscribedTrafficFlows2, - trafficDuration: 60 * time.Second, - }, { - desc: "Non-oversubscription AF1 and BE0 traffic", - trafficFlows: nonOversubscribedTrafficFlows3, - trafficDuration: 60 * time.Second, - }, { - desc: "Non-oversubscription BE0 and BE1 traffic", - trafficFlows: nonOversubscribedTrafficFlows4, - trafficDuration: 60 * time.Second, - }, { - desc: "Oversubscription AF3 and AF2 traffic with half AF3 dropped", - trafficFlows: oversubscribedTrafficFlows1, - trafficDuration: 60 * time.Second, - }, { - desc: "Oversubscription AF3 and AF2 traffic with half AF2 dropped", - trafficFlows: oversubscribedTrafficFlows2, - trafficDuration: 60 * time.Second, - }, { - desc: "Oversubscription AF3 and AF2 traffic with AF3 and AF2 dropped", - trafficFlows: oversubscribedTrafficFlows3, - trafficDuration: 60 * time.Second, - }, { - desc: "Oversubscription AF2 and AF1 traffic with half AF2 dropped", - trafficFlows: oversubscribedTrafficFlows4, - trafficDuration: 60 * time.Second, - }, { - desc: "Oversubscription AF2 and AF1 traffic with half AF1 dropped", - trafficFlows: oversubscribedTrafficFlows5, - trafficDuration: 60 * time.Second, - }, { - desc: "Oversubscription AF2 and AF1 traffic with AF2 and AF1 dropped", - trafficFlows: oversubscribedTrafficFlows6, - trafficDuration: 60 * time.Second, - }, { - desc: "Oversubscription AF1 and BE0 traffic with half AF1 dropped", - trafficFlows: oversubscribedTrafficFlows7, - trafficDuration: 60 * time.Second, - }, { - desc: "Oversubscription AF1 and BE0 traffic with half BE0 dropped", - trafficFlows: oversubscribedTrafficFlows8, - trafficDuration: 60 * time.Second, - }, { - desc: "Oversubscription AF1 and BE0 traffic with AF1 and BE0 dropped", - trafficFlows: oversubscribedTrafficFlows9, - trafficDuration: 60 * time.Second, - }, { - desc: "Oversubscription BE0 and BE1 traffic with half BE0 dropped", - trafficFlows: oversubscribedTrafficFlows10, - trafficDuration: 60 * time.Second, - }, { - desc: "Oversubscription BE0 and BE1 traffic with half BE1 dropped", - trafficFlows: oversubscribedTrafficFlows11, - trafficDuration: 60 * time.Second, - }, { - desc: "Oversubscription BE0 and BE1 traffic with BE0 and BE1 dropped", - trafficFlows: oversubscribedTrafficFlows12, - trafficDuration: 60 * time.Second, - }, - } - - for _, tc := range cases { - t.Run(tc.desc, func(t *testing.T) { - trafficFlows := tc.trafficFlows - - var flows []*ondatra.Flow - for trafficID, data := range trafficFlows { - t.Logf("Configuring flow %s", trafficID) - flow := ate.Traffic().NewFlow(trafficID). - WithSrcEndpoints(data.inputIntf). - WithDstEndpoints(intf3). - WithHeaders(ondatra.NewEthernetHeader(), ondatra.NewIPv4Header().WithDSCP(data.dscp)). - WithFrameRatePct(data.trafficRate). - WithFrameSize(data.frameSize) - flows = append(flows, flow) - } - - ateOutPkts := make(map[string]uint64) - ateInPkts := make(map[string]uint64) - dutQosPktsBeforeTraffic := make(map[string]uint64) - dutQosPktsAfterTraffic := make(map[string]uint64) - dutQosDroppedPktsBeforeTraffic := make(map[string]uint64) - dutQosDroppedPktsAfterTraffic := make(map[string]uint64) - - // Set the initial counters to 0. - for _, data := range trafficFlows { - ateOutPkts[data.queue] = 0 - ateInPkts[data.queue] = 0 - dutQosPktsBeforeTraffic[data.queue] = 0 - dutQosPktsAfterTraffic[data.queue] = 0 - dutQosDroppedPktsBeforeTraffic[data.queue] = 0 - dutQosDroppedPktsAfterTraffic[data.queue] = 0 - } - - // Get QoS egress packet counters before the traffic. - for _, data := range trafficFlows { - dutQosPktsBeforeTraffic[data.queue] += gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) - dutQosDroppedPktsBeforeTraffic[data.queue] += gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - } - - t.Logf("Running traffic 1 on DUT interfaces: %s => %s ", dp1.Name(), dp3.Name()) - t.Logf("Running traffic 2 on DUT interfaces: %s => %s ", dp2.Name(), dp3.Name()) - t.Logf("Sending traffic flows: \n%v\n\n", trafficFlows) - ate.Traffic().Start(t, flows...) - time.Sleep(tc.trafficDuration) - ate.Traffic().Stop(t) - time.Sleep(10 * time.Second) - - for trafficID, data := range trafficFlows { - ateOutPkts[data.queue] += gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).Counters().OutPkts().State()) - ateInPkts[data.queue] += gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).Counters().InPkts().State()) - dutQosPktsAfterTraffic[data.queue] += gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).TransmitPkts().State()) - dutQosDroppedPktsAfterTraffic[data.queue] += gnmi.Get(t, dut, gnmi.OC().Qos().Interface(dp3.Name()).Output().Queue(data.queue).DroppedPkts().State()) - t.Logf("ateInPkts: %v, txPkts %v, Queue: %v", ateInPkts[data.queue], dutQosPktsAfterTraffic[data.queue], data.queue) - - lossPct := gnmi.Get(t, ate, gnmi.OC().Flow(trafficID).LossPct().State()) - t.Logf("Get flow %q: lossPct: %.2f%% or rxPct: %.2f%%, want: %.2f%%\n\n", data.queue, lossPct, 100.0-lossPct, data.expectedThroughputPct) - if got, want := 100.0-lossPct, data.expectedThroughputPct; got < want-tolerance || got > want+tolerance { - t.Errorf("Get(throughput for queue %q): got %.2f%%, want within [%.2f%%, %.2f%%]", data.queue, got, want-tolerance, want+tolerance) - } - } - - // Check QoS egress packet counters are updated correctly. - t.Logf("QoS dutQosPktsBeforeTraffic: %v", dutQosPktsBeforeTraffic) - t.Logf("QoS dutQosPktsAfterTraffic: %v", dutQosPktsAfterTraffic) - t.Logf("QoS dutQosDroppedPktsBeforeTraffic: %v", dutQosDroppedPktsBeforeTraffic) - t.Logf("QoS dutQosDroppedPktsAfterTraffic: %v", dutQosDroppedPktsAfterTraffic) - t.Logf("QoS ateOutPkts: %v", ateOutPkts) - t.Logf("QoS ateInPkts: %v", ateInPkts) - for _, data := range trafficFlows { - qosCounterDiff := dutQosPktsAfterTraffic[data.queue] - dutQosPktsBeforeTraffic[data.queue] - ateCounterDiff := ateInPkts[data.queue] - ateDropCounterDiff := ateOutPkts[data.queue] - ateInPkts[data.queue] - dutDropCounterDiff := dutQosDroppedPktsAfterTraffic[data.queue] - dutQosDroppedPktsBeforeTraffic[data.queue] - t.Logf("QoS queue %q: ateDropCounterDiff: %v dutDropCounterDiff: %v", data.queue, ateDropCounterDiff, dutDropCounterDiff) - if qosCounterDiff < ateCounterDiff { - t.Errorf("Get telemetry packet update for queue %q: got %v, want >= %v", data.queue, qosCounterDiff, ateCounterDiff) - } - } - }) - } -} - -func ConfigureDUTIntf(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - - dutIntfs := []struct { - desc string - intfName string - ipAddr string - prefixLen uint8 - }{{ - desc: "Input interface port1", - intfName: dp1.Name(), - ipAddr: "198.51.100.0", - prefixLen: 31, - }, { - desc: "Input interface port2", - intfName: dp2.Name(), - ipAddr: "198.51.100.2", - prefixLen: 31, - }, { - desc: "Output interface port3", - intfName: dp3.Name(), - ipAddr: "198.51.100.4", - prefixLen: 31, - }} - - // Configure the interfaces. - for _, intf := range dutIntfs { - t.Logf("Configure DUT interface %s with attributes %v", intf.intfName, intf) - i := &oc.Interface{ - Name: ygot.String(intf.intfName), - Description: ygot.String(intf.desc), - Type: oc.IETFInterfaces_InterfaceType_ethernetCsmacd, - Enabled: ygot.Bool(true), - } - i.GetOrCreateEthernet() - s := i.GetOrCreateSubinterface(0).GetOrCreateIpv4() - if deviations.InterfaceEnabled(dut) && !deviations.IPv4MissingEnabled(dut) { - s.Enabled = ygot.Bool(true) - } - a := s.GetOrCreateAddress(intf.ipAddr) - a.PrefixLength = ygot.Uint8(intf.prefixLen) - gnmi.Replace(t, dut, gnmi.OC().Interface(intf.intfName).Config(), i) - } -} - -func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - d := &oc.Root{} - q := d.GetOrCreateQos() - queues := netutil.CommonTrafficQueues(t, dut) - - t.Logf("Create qos forwarding groups config") - forwardingGroups := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - t.Logf("qos forwarding groups config: %v", forwardingGroups) - for _, tc := range forwardingGroups { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - } - - t.Logf("Create qos Classifiers config") - classifiers := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - t.Logf("qos Classifiers config: %v", classifiers) - for _, tc := range classifiers { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.name == "dscp_based_classifier_ipv4" { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.name == "dscp_based_classifier_ipv6" { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos input classifier config") - classifierIntfs := []struct { - desc string - intf string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }, { - desc: "Input Classifier Type IPV4", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - t.Logf("qos input classifier config: %v", classifierIntfs) - for _, tc := range classifierIntfs { - qoscfg.SetInputClassifier(t, dut, q, tc.intf, tc.inputClassifierType, tc.classifier) - } - - nc1InputWeight := uint64(200) - af4InputWeight := uint64(100) - if deviations.SchedulerInputWeightLimit(dut) { - nc1InputWeight = uint64(100) - af4InputWeight = uint64(99) - } - - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - priority oc.E_Scheduler_Priority - inputID string - inputType oc.E_Input_InputType - weight uint64 - queueName string - targetGroup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: queues.BE1, - targetGroup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE0", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: queues.BE0, - targetGroup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(4), - queueName: queues.AF1, - targetGroup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF2", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(16), - queueName: queues.AF2, - targetGroup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF3", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(64), - queueName: queues.AF3, - targetGroup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "AF4", - inputType: oc.Input_InputType_QUEUE, - weight: af4InputWeight, - queueName: queues.AF4, - targetGroup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - inputType: oc.Input_InputType_QUEUE, - weight: nc1InputWeight, - queueName: queues.NC1, - targetGroup: "target-group-NC1", - }} - - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - s.SetPriority(tc.priority) - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - input.SetInputType(tc.inputType) - input.SetQueue(tc.queueName) - input.SetWeight(tc.weight) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - scheduler string - }{{ - desc: "output-interface-BE1", - queueName: queues.BE1, - scheduler: "scheduler", - }, { - desc: "output-interface-BE0", - queueName: queues.BE0, - scheduler: "scheduler", - }, { - desc: "output-interface-AF1", - queueName: queues.AF1, - scheduler: "scheduler", - }, { - desc: "output-interface-AF2", - queueName: queues.AF2, - scheduler: "scheduler", - }, { - desc: "output-interface-AF3", - queueName: queues.AF3, - scheduler: "scheduler", - }, { - desc: "output-interface-AF4", - queueName: queues.AF4, - scheduler: "scheduler", - }, { - desc: "output-interface-NC1", - queueName: queues.NC1, - scheduler: "scheduler", - }} - - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp3.Name()) - i.SetInterfaceId(dp3.Name()) - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) - if deviations.InterfaceRefConfigUnsupported(dut) { - i.InterfaceRef = nil - } - output := i.GetOrCreateOutput() - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName(tc.scheduler) - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } -} - -func ConfigureCiscoQos(t *testing.T, dut *ondatra.DUTDevice) { - t.Helper() - dp1 := dut.Port(t, "port1") - dp2 := dut.Port(t, "port2") - dp3 := dut.Port(t, "port3") - d := &oc.Root{} - q := d.GetOrCreateQos() - - t.Logf("Create qos Classifiers config") - classifiers := []struct { - desc string - name string - classType oc.E_Qos_Classifier_Type - termID string - targetGroup string - dscpSet []uint8 - }{{ - desc: "classifier_ipv4_be1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv4_be0", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv4_af1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv4_af2", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv4_af3", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv4_af4", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv4_nc1", - name: "dscp_based_classifier_ipv4", - classType: oc.Qos_Classifier_Type_IPV4, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }, { - desc: "classifier_ipv6_be1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "0", - targetGroup: "target-group-BE1", - dscpSet: []uint8{0, 1, 2, 3}, - }, { - desc: "classifier_ipv6_be0", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "1", - targetGroup: "target-group-BE0", - dscpSet: []uint8{4, 5, 6, 7}, - }, { - desc: "classifier_ipv6_af1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "2", - targetGroup: "target-group-AF1", - dscpSet: []uint8{8, 9, 10, 11}, - }, { - desc: "classifier_ipv6_af2", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "3", - targetGroup: "target-group-AF2", - dscpSet: []uint8{16, 17, 18, 19}, - }, { - desc: "classifier_ipv6_af3", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "4", - targetGroup: "target-group-AF3", - dscpSet: []uint8{24, 25, 26, 27}, - }, { - desc: "classifier_ipv6_af4", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "5", - targetGroup: "target-group-AF4", - dscpSet: []uint8{32, 33, 34, 35}, - }, { - desc: "classifier_ipv6_nc1", - name: "dscp_based_classifier_ipv6", - classType: oc.Qos_Classifier_Type_IPV6, - termID: "6", - targetGroup: "target-group-NC1", - dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, - }} - - t.Logf("qos Classifiers config: %v", classifiers) - queueName := []string{"NC1", "AF4", "AF3", "AF2", "AF1", "BE0", "BE1"} - - for i, queue := range queueName { - q1 := q.GetOrCreateQueue(queue) - q1.Name = ygot.String(queue) - queueid := len(queueName) - i - q1.QueueId = ygot.Uint8(uint8(queueid)) - - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - casesfwdgrp := []struct { - desc string - queueName string - targetGroup string - }{{ - desc: "forwarding-group-BE1", - queueName: "BE1", - targetGroup: "target-group-BE1", - }, { - desc: "forwarding-group-BE0", - queueName: "BE0", - targetGroup: "target-group-BE0", - }, { - desc: "forwarding-group-AF1", - queueName: "AF1", - targetGroup: "target-group-AF1", - }, { - desc: "forwarding-group-AF2", - queueName: "AF2", - targetGroup: "target-group-AF2", - }, { - desc: "forwarding-group-AF3", - queueName: "AF3", - targetGroup: "target-group-AF3", - }, { - desc: "forwarding-group-AF4", - queueName: "AF4", - targetGroup: "target-group-AF4", - }, { - desc: "forwarding-group-NC1", - queueName: "NC1", - targetGroup: "target-group-NC1", - }} - t.Logf("qos forwarding groups config cases: %v", casesfwdgrp) - for _, tc := range casesfwdgrp { - t.Run(tc.desc, func(t *testing.T) { - qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) - }) - } - for _, tc := range classifiers { - classifier := q.GetOrCreateClassifier(tc.name) - classifier.SetName(tc.name) - classifier.SetType(tc.classType) - term, err := classifier.NewTerm(tc.termID) - if err != nil { - t.Fatalf("Failed to create classifier.NewTerm(): %v", err) - } - - term.SetId(tc.termID) - action := term.GetOrCreateActions() - action.SetTargetGroup(tc.targetGroup) - condition := term.GetOrCreateConditions() - if tc.classType == oc.Qos_Classifier_Type_IPV4 { - condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) - } else if tc.classType == oc.Qos_Classifier_Type_IPV6 { - condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - } - - t.Logf("Create qos input classifier config") - classifierIntfs := []struct { - desc string - intf string - inputClassifierType oc.E_Input_Classifier_Type - classifier string - }{{ - desc: "Input Classifier Type IPV4", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp1.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }, { - desc: "Input Classifier Type IPV4", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV4, - classifier: "dscp_based_classifier_ipv4", - }, { - desc: "Input Classifier Type IPV6", - intf: dp2.Name(), - inputClassifierType: oc.Input_Classifier_Type_IPV6, - classifier: "dscp_based_classifier_ipv6", - }} - - t.Logf("qos input classifier config: %v", classifierIntfs) - for _, tc := range classifierIntfs { - qoscfg.SetInputClassifier(t, dut, q, tc.intf, tc.inputClassifierType, tc.classifier) - } - - t.Logf("Create qos scheduler policies config") - schedulerPolicies := []struct { - desc string - sequence uint32 - priority oc.E_Scheduler_Priority - inputID string - inputType oc.E_Input_InputType - weight uint64 - queueName string - targetGrpoup string - }{{ - desc: "scheduler-policy-BE1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: "BE1", - targetGrpoup: "target-group-BE1", - }, { - desc: "scheduler-policy-BE0", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "BE0", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(1), - queueName: "BE0", - targetGrpoup: "target-group-BE0", - }, { - desc: "scheduler-policy-AF1", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(4), - queueName: "AF1", - targetGrpoup: "target-group-AF1", - }, { - desc: "scheduler-policy-AF2", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF2", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(16), - queueName: "AF2", - targetGrpoup: "target-group-AF2", - }, { - desc: "scheduler-policy-AF3", - sequence: uint32(1), - priority: oc.Scheduler_Priority_UNSET, - inputID: "AF3", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(63), - queueName: "AF3", - targetGrpoup: "target-group-AF3", - }, { - desc: "scheduler-policy-AF4", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "AF4", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(6), - queueName: "AF4", - targetGrpoup: "target-group-AF4", - }, { - desc: "scheduler-policy-NC1", - sequence: uint32(0), - priority: oc.Scheduler_Priority_STRICT, - inputID: "NC1", - inputType: oc.Input_InputType_QUEUE, - weight: uint64(7), - queueName: "NC1", - targetGrpoup: "target-group-NC1", - }} - schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") - schedulerPolicy.SetName("scheduler") - t.Logf("qos scheduler policies config: %v", schedulerPolicies) - for _, tc := range schedulerPolicies { - s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) - s.SetSequence(tc.sequence) - s.SetPriority(tc.priority) - input := s.GetOrCreateInput(tc.inputID) - input.SetId(tc.inputID) - //input.SetInputType(tc.inputType) - input.SetQueue(tc.queueName) - input.SetWeight(tc.weight) - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) - - } - - t.Logf("Create qos output interface config") - schedulerIntfs := []struct { - desc string - queueName string - scheduler string - }{{ - desc: "output-interface-NC1", - queueName: "NC1", - scheduler: "scheduler", - }, { - desc: "output-interface-AF4", - queueName: "AF4", - scheduler: "scheduler", - }, { - desc: "output-interface-AF3", - queueName: "AF3", - scheduler: "scheduler", - }, { - desc: "output-interface-AF2", - queueName: "AF2", - scheduler: "scheduler", - }, { - desc: "output-interface-AF1", - queueName: "AF1", - scheduler: "scheduler", - }, { - desc: "output-interface-BE0", - queueName: "BE0", - scheduler: "scheduler", - }, { - desc: "output-interface-BE1", - queueName: "BE1", - scheduler: "scheduler", - }} - - t.Logf("qos output interface config: %v", schedulerIntfs) - for _, tc := range schedulerIntfs { - i := q.GetOrCreateInterface(dp3.Name()) - i.SetInterfaceId(dp3.Name()) - output := i.GetOrCreateOutput() - i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) - schedulerPolicy := output.GetOrCreateSchedulerPolicy() - schedulerPolicy.SetName(tc.scheduler) - queue := output.GetOrCreateQueue(tc.queueName) - queue.SetName(tc.queueName) - - } - gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) -} From c7d741589f6061ed5eb26d47146eacdd8ef02104 Mon Sep 17 00:00:00 2001 From: Sameer Nandu Date: Wed, 13 Sep 2023 05:29:08 -0700 Subject: [PATCH 23/43] Update RT-1.20 to RT-1.24 (#2121) --- .../bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/README.md | 4 ++-- .../bgp_2byte_4byte_asn_policy_test/metadata.textproto | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/README.md b/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/README.md index ba142086ba4..51d125b5eb9 100644 --- a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/README.md +++ b/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/README.md @@ -1,4 +1,4 @@ -# RT-1.20: BGP 2-Byte and 4-Byte ASN support with policy +# RT-1.24: BGP 2-Byte and 4-Byte ASN support with policy ## Summary @@ -31,4 +31,4 @@ BGP 2-Byte and 4-Byte ASN support with policy * /global/config/as * /neighbors/neighbor/config/peer-as -* /neighbors/neighbor/config/local-as \ No newline at end of file +* /neighbors/neighbor/config/local-as diff --git a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/metadata.textproto b/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/metadata.textproto index 11a324ae2f2..da1720d7e4e 100644 --- a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/metadata.textproto +++ b/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn_policy_test/metadata.textproto @@ -2,7 +2,7 @@ # proto-message: Metadata uuid: "a993eb24-40f8-4b86-bc6b-02c19f6a0d53" -plan_id: "RT-1.20" +plan_id: "RT-1.24" description: "BGP 2-Byte and 4-Byte ASN support with policy" testbed: TESTBED_DUT_ATE_2LINKS platform_exceptions: { @@ -29,8 +29,7 @@ platform_exceptions: { platform: { vendor: JUNIPER } - deviations: { - } + deviations: {} } platform_exceptions: { platform: { @@ -43,4 +42,3 @@ platform_exceptions: { default_network_instance: "default" } } -tags: TAGS_EDGE From ea00cc1ce3cfd654c84242f814be2db8a8d85c19 Mon Sep 17 00:00:00 2001 From: sachendras <44847441+sachendras@users.noreply.github.com> Date: Wed, 13 Sep 2023 09:49:40 -0700 Subject: [PATCH 24/43] BGP route-reflector-at-scale-test (#1756) * Create route-reflector-test Proposed test addresses requirements in the internal bug b/287237486 Validates: - BGP RR capability where IBGP peering address is learnt over IS-IS - OC leaves that capture BGP transport session attributes like local-address, peer-type - Ensure supported-capabilites leaf functionality * Update route-reflector-test * Rename feature/bgp/route-reflector-test to feature/bgp/routereflector/route-reflector-test Moving the test in routereflector directory * Update route-reflector-test * Update route-reflector-test * Update route-reflector-test * Update route-reflector-test * Rename route-reflector-test to README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md --------- Co-authored-by: Benson Schliesser --- feature/bgp/routereflector/README.md | 47 ++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 feature/bgp/routereflector/README.md diff --git a/feature/bgp/routereflector/README.md b/feature/bgp/routereflector/README.md new file mode 100644 index 00000000000..9d3788c80d2 --- /dev/null +++ b/feature/bgp/routereflector/README.md @@ -0,0 +1,47 @@ +# RT-1.8: BGP Route Reflector Test at scale +## Summary +* BGP route reflector capabilities check +* Ensure functionality of different OC paths for "supported-capabilities", "BGP peer-type", "BGP Neighbor details" and "BGP transport session parameters" + +## Topology +ATE (Port1) <-EBGP-> (Port1) DUT (Port2) <-IS-IS/IBGP-> (Port2) ATE, DUT (Port3) <-IS-IS/IBGP-> (Port3) ATE +Connect ATE Port1 to DUT port1 (EBGP peering) +* Connect ATE Port2 to DUT port2 (For IS-IS adjacency and IBGP peer reachaility) +* Connect ATE Port3 to DUT port3 (For IS-IS adjacency and IBGP peer reachaility) + +## Test Procedure +* Establish IS-IS adjacency between ATE Port2 <-> DUT Port2, ATE Port3 <-> DUT Port3. +* Establish BGP sessions as follows between ATE and DUT. + * ATE port2 and ATE port3 are emulating RR clients peered with the DUT acting as the RR server. DUT's loopback address should be used for the IBGP peering and "transport/config/local-address" OC path should be used on DUT to configure BGP transport address for IBGP peering. ATE addresses used for the IBGP peering (different from ATE Port1 and ATE Port2 addreses) and DUT loopback addresses should be reachable via IS-IS. Each of the ATEs should advertise 5M IPv4 and 2M IPv6 prefixes to the RR over the IBGP peering, with different path attributes like protocol next-hops, local-preference, communitiy and MED. Among these, 2M v4 and 1M v6 prefixes are unique. Among the 2M IPv4 prefixes as well, 1.5M are non RFC1918 or RFC6598 addresses and represent Internet prefixes. Similarly, 600k IPv6 prefixes will represent internet prefixes. These prefixes should be common between the 2xDUTs with different path-attributes for protocol next-hop, AS-Path and community. Balance 500k IPv4 and 400k IPv6 prefixes represent internal subnets and should include some prefixes that are unique to each of the ATEs. Remaining prefixes in the mix need to be common between the 2xATEs and should have identical path attributes except for the protocol next-hops. + * The DUT Port1 has eBGP peering with ATE Port 1 and is receiving 10M IPv4 and 3M IPv6 Internet routes with different path attributes like protocol next-hops, AS-Path, Origin, MED and communities. Out of these, only 1.5M IPv4 and 600k IPv6 prefixes are unique and will be programmed to the FIB. + * The 1.5M IPv4 and 600k IPv6 unique prefixes representing internet addresses should be the same as the ones learnt by the DUT over the IBGP peering but with different path attributes like protocol Next-hops, communities etc. + * The DUT should automatically determine the BGP transport source address based on the nearest interface. Hence, the OC path "transport/config/local-address" shouldnt be used. + * The DUT should advertise these EBGP learnt prefixes over the 2xIBGP peering. [*] Expectations are that the DUT will prefer EBGP learnt internet routes over the IBGP learnt routes. For the IBGP learnt internal prefixes, the DUT should advertise the same over the EBGP peering. [**] Expectations are that the DUT would advertise all internal IPv4 and IPv6 prefixes to the EBGP peers. + * Validate session state on ATE ports and DUT using telemetry. + * The check should also include accurately receiving values for the path "transport/state/local-address" for RRCs as well as for the EBGP peering. + * Validate accuracy of the peer-type leaf (neighbor/config/peer-type) for EBGP and IBGP peering. + * Validate session state and capabilities received on DUT using telemetry. + * For capabilities, just make sure that the length of the list "neighbor/state/supported-capabilities" is non-zero + * Validate route receipt. + * Ensure that the DUT advertises all the IBGP learnt routes to the EBGP peer. Pass expectation covered in context in [**] above + * Ensure that the DUT advertises all the EBGP learnt routes to the IBGP peers. Pass expectation covered in context in [*] above + * Ensure that the DUT as RR server advertises routes learnt from each of the RRC to the other. + * Validate BGP route/path attributes below for each of the EBGP and IBGP learnt routes + * Next-Hop + * Local Pref + * Communities + * AS-Path + +## Config Parameter Coverage +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/route-reflector +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/route-reflector/config +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/route-reflector/config/route-reflector-cluster-id +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/route-reflector/config/route-reflector-client +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/peer-type +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/transport/config/local-address + +## Telemetry Parameter Coverage +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/route-reflector/state/route-reflector-cluster-id +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/route-reflector/state/route-reflector-client +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/peer-type +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/supported-capabilities From dc081fc38a5d9c514e971e7ac61cd4072fb0f0db Mon Sep 17 00:00:00 2001 From: anksaiki Date: Wed, 13 Sep 2023 14:32:52 -0400 Subject: [PATCH 25/43] QOS changes (#2111) * fix test expectation * fix isis interface passive test to use session library * Fix QOS tests for Arista --- feature/qos/otg_tests/qos_basic_test/qos_basic_test.go | 3 +++ .../tests/qos_policy_config_test/qos_policy_config_test.go | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go b/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go index 42a281b2fec..aeb85d1f6ae 100644 --- a/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go +++ b/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go @@ -974,6 +974,9 @@ func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { i := q.GetOrCreateInterface(dp3.Name()) i.SetInterfaceId(dp3.Name()) i.GetOrCreateInterfaceRef().Interface = ygot.String(dp3.Name()) + if deviations.InterfaceRefConfigUnsupported(dut) { + i.InterfaceRef = nil + } output := i.GetOrCreateOutput() schedulerPolicy := output.GetOrCreateSchedulerPolicy() schedulerPolicy.SetName(tc.scheduler) diff --git a/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go b/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go index 06e18a9a1b2..6a77eaf7505 100644 --- a/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go +++ b/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go @@ -584,7 +584,7 @@ func testECNConfig(t *testing.T) { ecnEnabled: true, dropEnabled: false, minThreshold: uint64(80000), - maxThreshold: math.MaxUint64, + maxThreshold: math.MaxUint32, maxDropProbabilityPercent: uint8(1), weight: uint32(0), } @@ -1653,7 +1653,7 @@ func testJuniperSchedulerPoliciesConfig(t *testing.T) { ecnEnabled: true, dropEnabled: false, minThreshold: uint64(80000), - maxThreshold: math.MaxUint64, + maxThreshold: math.MaxUint32, maxDropProbabilityPercent: uint8(1), weight: uint32(0), } From 6b1769fac5647ce5983315358c50340f47cf9016 Mon Sep 17 00:00:00 2001 From: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> Date: Wed, 13 Sep 2023 19:00:53 -0400 Subject: [PATCH 26/43] Migrate off remaining deprecated raw api uses (#2115) * Migrate off remaining deprecated raw api uses * feedback --- .../route_removal_during_failover_test.go | 6 +++++- .../route_removal_during_failover_test.go | 6 +++++- .../system_generic_health_check_test.go | 2 +- .../tests/factory_reset_test/factory_reset_test.go | 6 ++++-- .../packet_link_qualification_test.go | 2 +- .../complete_chassis_reboot/complete_chassis_reboot_test.go | 5 ++++- .../copying_debug_files_test/copying_debug_files_test.go | 5 ++--- .../supervisor_switchover_test.go | 2 +- .../get/tests/system_gnmi_get_test/system_gnmi_get_test.go | 2 +- topologies/binding/options.go | 2 +- 10 files changed, 25 insertions(+), 13 deletions(-) diff --git a/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go b/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go index f4502988093..b2f68925d41 100644 --- a/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go +++ b/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go @@ -652,7 +652,11 @@ func TestRouteRemovalDuringFailover(t *testing.T) { } // Check for coredumps in the DUT and validate that none are present post failover. - gnoiClient = dut.RawAPIs().GNOI().New(t) // reconnect gnoi connection after switchover + // Reconnect gnoi connection after switchover + gnoiClient, err = dut.RawAPIs().BindingDUT().DialGNOI(context.Background()) + if err != nil { + t.Fatalf("Error dialing gNOI: %v", err) + } coreFilecheck(t, dut, gnoiClient, sysConfigTime) t.Log("Re-inject routes from ipBlock1 in default VRF with NHGID: #1.") diff --git a/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go b/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go index 7245992929f..a3c59c5e485 100644 --- a/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go +++ b/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go @@ -683,7 +683,11 @@ func TestRouteRemovalDuringFailover(t *testing.T) { } // Check for coredumps in the DUT and validate that none are present post failover. - gnoiClient = dut.RawAPIs().GNOI().New(t) // reconnect gnoi connection after switchover + // Reconnect gnoi connection after switchover. + gnoiClient, err = dut.RawAPIs().BindingDUT().DialGNOI(context.Background()) + if err != nil { + t.Fatalf("Error dialing gNOI: %v", err) + } coreFilecheck(t, dut, gnoiClient, sysConfigTime) t.Log("Re-inject routes from ipBlock1 in default VRF with NHGID: #1.") diff --git a/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go b/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go index 6dc01fc1f6d..033694f5a2a 100644 --- a/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go +++ b/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go @@ -151,7 +151,7 @@ func TestComponentStatus(t *testing.T) { if len(checkComponents) == 0 { t.Errorf("ERROR: No component has been found.") } - gnoiClient := dut.RawAPIs().GNOI().New(t) + gnoiClient := dut.RawAPIs().GNOI(t) // check oper-status of the components is Active. for _, component := range checkComponents { t.Run(component, func(t *testing.T) { diff --git a/feature/gnoi/factory_reset/tests/factory_reset_test/factory_reset_test.go b/feature/gnoi/factory_reset/tests/factory_reset_test/factory_reset_test.go index ef817ad6c20..f1d1dbf9859 100644 --- a/feature/gnoi/factory_reset/tests/factory_reset_test/factory_reset_test.go +++ b/feature/gnoi/factory_reset/tests/factory_reset_test/factory_reset_test.go @@ -121,7 +121,10 @@ func deviceBootStatus(t *testing.T, dut *ondatra.DUTDevice) { // performs factory reset func factoryReset(t *testing.T, dut *ondatra.DUTDevice, devicePaths []string) { createFiles(t, dut, devicePaths) - gnoiClient := dut.RawAPIs().GNOI().New(t) + gnoiClient, err := dut.RawAPIs().BindingDUT().DialGNOI(context.Background()) + if err != nil { + t.Fatalf("Error dialing gNOI: %v", err) + } facRe, err := gnoiClient.FactoryReset().Start(context.Background(), &frpb.StartRequest{FactoryOs: false, ZeroFill: false}) if err != nil { t.Fatalf("Failed to initiate Factory Reset on the device, Error : %v ", err) @@ -202,5 +205,4 @@ func TestFactoryReset(t *testing.T) { time.Sleep(5 * time.Minute) factoryReset(t, dut, enCiscoCommands.DevicePaths) } - } diff --git a/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go b/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go index e9d57f8d4a6..9fc81b19a4d 100644 --- a/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go +++ b/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go @@ -52,7 +52,7 @@ func TestCapabilitiesResponse(t *testing.T) { t.Logf("dut1: %v, dut2: %v", dut1, dut2) t.Logf("dut1 dp1 name: %v, dut2 dp2 name : %v", dp1.Name(), dp2.Name()) - gnoiClient1 := dut1.RawAPIs().GNOI().New(t) + gnoiClient1 := dut1.RawAPIs().GNOI(t) plqResp, err := gnoiClient1.LinkQualification().Capabilities(context.Background(), &plqpb.CapabilitiesRequest{}) t.Logf("LinkQualification().Capabilities(): %v, err: %v", plqResp, err) diff --git a/feature/gnoi/system/tests/complete_chassis_reboot/complete_chassis_reboot_test.go b/feature/gnoi/system/tests/complete_chassis_reboot/complete_chassis_reboot_test.go index 3c1339cdd76..db8a3680628 100644 --- a/feature/gnoi/system/tests/complete_chassis_reboot/complete_chassis_reboot_test.go +++ b/feature/gnoi/system/tests/complete_chassis_reboot/complete_chassis_reboot_test.go @@ -111,7 +111,10 @@ func TestChassisReboot(t *testing.T) { for _, tc := range cases { t.Run(tc.desc, func(t *testing.T) { - gnoiClient := dut.RawAPIs().GNOI().New(t) + gnoiClient, err := dut.RawAPIs().BindingDUT().DialGNOI(context.Background()) + if err != nil { + t.Fatalf("Error dialing gNOI: %v", err) + } bootTimeBeforeReboot := gnmi.Get(t, dut, gnmi.OC().System().BootTime().State()) t.Logf("DUT boot time before reboot: %v", bootTimeBeforeReboot) prevTime, err := time.Parse(time.RFC3339, gnmi.Get(t, dut, gnmi.OC().System().CurrentDatetime().State())) diff --git a/feature/gnoi/system/tests/copying_debug_files_test/copying_debug_files_test.go b/feature/gnoi/system/tests/copying_debug_files_test/copying_debug_files_test.go index 996b410730d..d21e444e733 100644 --- a/feature/gnoi/system/tests/copying_debug_files_test/copying_debug_files_test.go +++ b/feature/gnoi/system/tests/copying_debug_files_test/copying_debug_files_test.go @@ -62,9 +62,8 @@ func TestMain(m *testing.M) { // func TestCopyingDebugFiles(t *testing.T) { - dut := ondatra.DUT(t, "dut") - gnoiClient := dut.RawAPIs().GNOI().New(t) + gnoiClient := dut.RawAPIs().GNOI(t) if _, ok := bgpProcName[dut.Vendor()]; !ok { t.Fatalf("Please add support for vendor %v in var bgpProcName", dut.Vendor()) } @@ -120,7 +119,7 @@ func findProcessByName(ctx context.Context, t *testing.T, dut *ondatra.DUTDevice func TestChassisComponentArtifacts(t *testing.T) { dut := ondatra.DUT(t, "dut") - gnoiClient := dut.RawAPIs().GNOI().New(t) + gnoiClient := dut.RawAPIs().GNOI(t) componentName := map[string]string{"name": components[dut.Vendor()]} // Execute Healthz Check RPC for the chassis component. chkReq := &hpb.CheckRequest{ diff --git a/feature/gnoi/system/tests/supervisor_switchover_test/supervisor_switchover_test.go b/feature/gnoi/system/tests/supervisor_switchover_test/supervisor_switchover_test.go index dd476b8489c..4ce309a06c4 100644 --- a/feature/gnoi/system/tests/supervisor_switchover_test/supervisor_switchover_test.go +++ b/feature/gnoi/system/tests/supervisor_switchover_test/supervisor_switchover_test.go @@ -101,7 +101,7 @@ func TestSupervisorSwitchover(t *testing.T) { t.Errorf("Get the number of intfsOperStatusUP interfaces for %q: got %v, want > %v", dut.Name(), got, want) } - gnoiClient := dut.RawAPIs().GNOI().New(t) + gnoiClient := dut.RawAPIs().GNOI(t) useNameOnly := deviations.GNOISubcomponentPath(dut) switchoverRequest := &spb.SwitchControlProcessorRequest{ ControlProcessor: components.GetSubcomponentPath(rpStandbyBeforeSwitch, useNameOnly), diff --git a/feature/system/gnmi/get/tests/system_gnmi_get_test/system_gnmi_get_test.go b/feature/system/gnmi/get/tests/system_gnmi_get_test/system_gnmi_get_test.go index 72b849e975e..e64969c69e5 100644 --- a/feature/system/gnmi/get/tests/system_gnmi_get_test/system_gnmi_get_test.go +++ b/feature/system/gnmi/get/tests/system_gnmi_get_test/system_gnmi_get_test.go @@ -122,7 +122,7 @@ func TestGNMIGet(t *testing.T) { // Not assuming that oc base config is loaded. // Config the hostname to prevent the test failure when oc base config is not loaded gnmi.Replace(t, dut, gnmi.OC().System().Hostname().Config(), "ondatraHost") - gnmiC := dut.RawAPIs().GNMI().New(t) + gnmiC := dut.RawAPIs().GNMI(t) t.Run(tt.desc, func(t *testing.T) { gotRes, err := gnmiC.Get(context.Background(), tt.inGetRequest) diff --git a/topologies/binding/options.go b/topologies/binding/options.go index 4cfcdcf441e..a681200ff0e 100644 --- a/topologies/binding/options.go +++ b/topologies/binding/options.go @@ -101,7 +101,7 @@ func (d *dialer) loadCertificates() (*x509.CertPool, tls.Certificate, error) { // //lint:ignore U1000 will be used by the binding. func (d *dialer) dialGRPC(ctx context.Context, overrideOpts ...grpc.DialOption) (*grpc.ClientConn, error) { - var opts []grpc.DialOption + opts := []grpc.DialOption{grpc.WithBlock()} switch { case d.Insecure: tc := insecure.NewCredentials() From cfda716d346f82c3490646c0ab3da7adaf597d3d Mon Sep 17 00:00:00 2001 From: Rob Shakir Date: Wed, 13 Sep 2023 16:33:35 -0700 Subject: [PATCH 27/43] Add gRIBI MPLS compliance test basics. (#2124) * Add gRIBI MPLS compliance test basics. * (A) feature/gribi/mplsutil/... - Add utilities for gRIBI MPLS compliance testing. * (A) feature/gribi/otg_tests/mpls_compliance/... - Add initial gRIBI MPLS compliance test. * Remove shadow `baseLabel` definition. --- feature/gribi/mplsutil/compliance.go | 125 +++++++++++++ feature/gribi/mplsutil/topo.go | 169 ++++++++++++++++++ .../gribi/otg_tests/mpls_compliance/README.md | 52 ++++++ .../gribi_mpls_compliance_test.go | 51 ++++++ .../mpls_compliance/metadata.textproto | 7 + 5 files changed, 404 insertions(+) create mode 100644 feature/gribi/mplsutil/compliance.go create mode 100644 feature/gribi/mplsutil/topo.go create mode 100644 feature/gribi/otg_tests/mpls_compliance/README.md create mode 100644 feature/gribi/otg_tests/mpls_compliance/gribi_mpls_compliance_test.go create mode 100644 feature/gribi/otg_tests/mpls_compliance/metadata.textproto diff --git a/feature/gribi/mplsutil/compliance.go b/feature/gribi/mplsutil/compliance.go new file mode 100644 index 00000000000..65856ae0d16 --- /dev/null +++ b/feature/gribi/mplsutil/compliance.go @@ -0,0 +1,125 @@ +// Package mplsutil defines helpers that are used to provide common functionality across gRIBI +// tests that handle MPLS programming. +package mplsutil + +import ( + "context" + "fmt" + "testing" + + "github.com/openconfig/gribigo/chk" + "github.com/openconfig/gribigo/client" + "github.com/openconfig/gribigo/compliance" + "github.com/openconfig/gribigo/constants" + "github.com/openconfig/gribigo/fluent" + "go.uber.org/atomic" +) + +var ( + // electionID is the global election ID used between test cases. + electionID = atomic.NewUint64(1) +) + +// flushServer removes all entries from the server and can be called between +// test cases in order to remove the server's RIB contents. +func flushServer(t *testing.T, c *fluent.GRIBIClient) { + ctx := context.Background() + c.Start(ctx, t) + defer c.Stop(t) + + if _, err := c.Flush(). + WithElectionOverride(). + WithAllNetworkInstances(). + Send(); err != nil { + t.Fatalf("Could not remove all entries from server, got: %v", err) + } +} + +// TrafficFunc defines a function that can be run following the compliance +// test. Functions are called with two arguments, a testing.T that is called +// with test results, and the packet's label stack. +type TrafficFunc func(t *testing.T, labelStack []uint32) + +// modify performs a set of operations (in ops) on the supplied gRIBI client, +// reporting errors via t. +func modify(t *testing.T, c *fluent.GRIBIClient, ops []func()) []*client.OpResult { + c.Connection(). + WithRedundancyMode(fluent.ElectedPrimaryClient). + WithInitialElectionID(electionID.Load(), 0) + + return compliance.DoModifyOps(c, t, ops, fluent.InstalledInRIB, false) +} + +// PushLabelStack defines a test that programs a DUT via gRIBI with a +// label forwarding entry within defaultNIName, with a label stack with +// numLabels in it, starting at baseLabel, if trafficFunc is non-nil it is run +// to validate the dataplane. +// +// The DUT is expected to have a next-hop of 192.0.2.2 that is resolvable. +func PushLabelStack(t *testing.T, c *fluent.GRIBIClient, defaultNIName string, baseLabel, numLabels int, trafficFunc TrafficFunc) { + defer electionID.Inc() + defer flushServer(t, c) + + var labels []uint32 + for n := 1; n <= numLabels; n++ { + labels = append(labels, uint32(baseLabel+n)) + } + + ops := []func(){ + func() { + c.Modify().AddEntry(t, + fluent.NextHopEntry(). + WithNetworkInstance(defaultNIName). + WithIndex(1). + WithIPAddress("192.0.2.2"). + WithPushedLabelStack(labels...)) + + c.Modify().AddEntry(t, + fluent.NextHopGroupEntry(). + WithNetworkInstance(defaultNIName). + WithID(1). + AddNextHop(1, 1)) + + c.Modify().AddEntry(t, + fluent.LabelEntry(). + WithLabel(100). + WithNetworkInstance(defaultNIName). + WithNextHopGroup(1)) + }, + } + + res := modify(t, c, ops) + + chk.HasResult(t, res, + fluent.OperationResult(). + WithMPLSOperation(100). + WithProgrammingResult(fluent.InstalledInRIB). + WithOperationType(constants.Add). + AsResult(), + chk.IgnoreOperationID(), + ) + + chk.HasResult(t, res, + fluent.OperationResult(). + WithNextHopGroupOperation(1). + WithProgrammingResult(fluent.InstalledInRIB). + WithOperationType(constants.Add). + AsResult(), + chk.IgnoreOperationID(), + ) + + chk.HasResult(t, res, + fluent.OperationResult(). + WithNextHopOperation(1). + WithProgrammingResult(fluent.InstalledInRIB). + WithOperationType(constants.Add). + AsResult(), + chk.IgnoreOperationID(), + ) + + if trafficFunc != nil { + t.Run(fmt.Sprintf("%d labels, traffic test", numLabels), func(t *testing.T) { + trafficFunc(t, labels) + }) + } +} diff --git a/feature/gribi/mplsutil/topo.go b/feature/gribi/mplsutil/topo.go new file mode 100644 index 00000000000..2a8c0d5cc26 --- /dev/null +++ b/feature/gribi/mplsutil/topo.go @@ -0,0 +1,169 @@ +package mplsutil + +import ( + "fmt" + "testing" + "time" + + "github.com/open-traffic-generator/snappi/gosnappi" + "github.com/openconfig/entity-naming/entname" + "github.com/openconfig/featureprofiles/internal/attrs" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ygot/ygot" +) + +var ( + // ATESrc describes the configuration parameters for the ATE port sourcing + // a flow. + ATESrc = &attrs.Attributes{ + Name: "port1", + Desc: "ATE_SRC_PORT", + IPv4: "192.0.2.0", + IPv4Len: 31, + MAC: "02:00:01:01:01:01", + IPv6: "2001:db8::0", + IPv6Len: 127, + } + // DUTSrc describes the configuration parameters for the DUT port connected + // to the ATE src port. + DUTSrc = &attrs.Attributes{ + Desc: "DUT_SRC_PORT", + IPv4: "192.0.2.1", + IPv4Len: 31, + IPv6: "2001:db8::1", + IPv6Len: 127, + } + // ATEDst describes the configuration parameters for the ATE port that acts + // as the traffic sink. + ATEDst = &attrs.Attributes{ + Name: "port2", + Desc: "ATE_DST_PORT", + IPv4: "192.0.2.2", + IPv4Len: 31, + MAC: "02:00:02:01:01:01", + IPv6: "2001:db8::2", + IPv6Len: 127, + } + // DUTDst describes the configuration parameters for the DUT port that is + // connected to the ate destination port. + DUTDst = &attrs.Attributes{ + Desc: "DUT_DST_PORT", + IPv4: "192.0.2.3", + IPv4Len: 31, + IPv6: "2001:db8::3", + IPv6Len: 127, + } +) + +var ( + // entmap provides a mapping between an ONDATRA vendor and a vendor + // within the entity naming library. + entmap = map[ondatra.Vendor]entname.Vendor{ + ondatra.ARISTA: entname.VendorArista, + } +) + +// dutIntf generates the configuration for an interface on the DUT in OpenConfig. +// It returns the generated configuration, or an error if the config could not be +// generated. +func dutIntf(dut *ondatra.DUTDevice, intf *attrs.Attributes, index int) ([]*oc.Interface, error) { + if intf == nil { + return nil, fmt.Errorf("invalid nil interface, %v", intf) + } + + i := &oc.Interface{ + Name: ygot.String(intf.Name), + Description: ygot.String(intf.Desc), + Type: oc.IETFInterfaces_InterfaceType_ethernetCsmacd, + Enabled: ygot.Bool(true), + } + + dev := &entname.DeviceParams{Vendor: entmap[dut.Vendor()]} + aggName, err := entname.AggregateInterface(dev, index) + if err != nil { + return nil, fmt.Errorf("cannot calculate aggregate interface name for vendor %s", dut.Vendor()) + } + i.GetOrCreateEthernet().AggregateId = ygot.String(aggName) + + pc := &oc.Interface{ + Name: ygot.String(aggName), + Description: ygot.String(fmt.Sprintf("LAG for %s", intf.Name)), + Type: oc.IETFInterfaces_InterfaceType_ieee8023adLag, + Enabled: ygot.Bool(true), + } + pc.GetOrCreateAggregation().LagType = oc.IfAggregate_AggregationType_STATIC + + v4 := pc.GetOrCreateSubinterface(0).GetOrCreateIpv4() + v4.Enabled = ygot.Bool(true) + v4Addr := v4.GetOrCreateAddress(intf.IPv4) + v4Addr.PrefixLength = ygot.Uint8(intf.IPv4Len) + + return []*oc.Interface{pc, i}, nil +} + +// ateIntfConfig returns the configuration required for the ATE interfaces. +func configureATEInterfaces(t *testing.T, ate *ondatra.ATEDevice, srcATE, srcDUT, dstATE, dstDUT *attrs.Attributes) (gosnappi.Config, error) { + topology := ate.OTG().NewConfig(t) + for _, p := range []struct { + ate, dut *attrs.Attributes + }{ + {ate: srcATE, dut: srcDUT}, + {ate: dstATE, dut: dstDUT}, + } { + topology.Ports().Add().SetName(p.ate.Name) + dev := topology.Devices().Add().SetName(p.ate.Name) + eth := dev.Ethernets().Add().SetName(fmt.Sprintf("%s_ETH", p.ate.Name)).SetMac(p.ate.MAC) + eth.Connection().SetPortName(dev.Name()) + ip := eth.Ipv4Addresses().Add().SetName(fmt.Sprintf("%s_IPV4", dev.Name())) + ip.SetAddress(p.ate.IPv4).SetGateway(p.dut.IPv4).SetPrefix(uint32(p.ate.IPv4Len)) + + ip6 := eth.Ipv6Addresses().Add().SetName(fmt.Sprintf("%s_IPV6", dev.Name())) + ip6.SetAddress(p.ate.IPv6).SetGateway(p.dut.IPv6).SetPrefix(uint32(p.ate.IPv6Len)) + } + + c, err := topology.ToJson() + if err != nil { + return topology, err + } + t.Logf("configuration for OTG is %s", c) + + return topology, nil +} + +// PushBaseConfigs pushes the base configuration to the ATE and DUT devices in +// the test topology. +func PushBaseConfigs(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice) gosnappi.Config { + DUTSrc.Name = dut.Port(t, "port1").Name() + DUTDst.Name = dut.Port(t, "port2").Name() + + otgCfg, err := configureATEInterfaces(t, ate, ATESrc, DUTSrc, ATEDst, DUTDst) + if err != nil { + t.Fatalf("cannot configure ATE interfaces via OTG, %v", err) + } + + ate.OTG().PushConfig(t, otgCfg) + + d := &oc.Root{} + // configure ports on the DUT. note that each port maps to two interfaces + // because we create a LAG. + for index, i := range []*attrs.Attributes{DUTSrc, DUTDst} { + cfgs, err := dutIntf(dut, i, index) + if err != nil { + t.Fatalf("cannot generate configuration for interface %s, err: %v", i.Name, err) + } + for _, intf := range cfgs { + d.AppendInterface(intf) + } + } + fptest.LogQuery(t, "", gnmi.OC().Config(), d) + gnmi.Update(t, dut, gnmi.OC().Config(), d) + + // Sleep for 1 second to ensure that OTG has absorbed configuration. + time.Sleep(1 * time.Second) + ate.OTG().StartProtocols(t) + + return otgCfg +} diff --git a/feature/gribi/otg_tests/mpls_compliance/README.md b/feature/gribi/otg_tests/mpls_compliance/README.md new file mode 100644 index 00000000000..b39e7d40c4b --- /dev/null +++ b/feature/gribi/otg_tests/mpls_compliance/README.md @@ -0,0 +1,52 @@ +# TE-9: gRIBI MPLS Compliance + +## Summary + +Ensure that the gRIBI server implements a base set of MPLS functionality without +traffic validation. + + +## Procedure + +### TE-9.1: Push MPLS Labels to MPLS payload + +* Configure ATE `port-1` connected to DUT `port-1`, and ATE `port-2` connected + to DUT `port-2`. +* ATE `port-2` is configured to have an assigned address of `192.0.2.2`, and the + interface to the DUT is enabled. +* For label stack depths beginning at `baseLabel`, with `numLabels` addition + labels: + - Program a `LabelEntry` matching outer label 100 pointing to a NHG + containing a single NH. + - Program a `NextHopEntry` which points to `192.0.2.2` pushing `[baseLabel, + ..., baseLabel+numLabels]` onto the MPLS label stack. + + +## Protocol/RPC Parameter coverage + +* gRIBI: + * `Modify()` + * `ModifyRequest` + * `AFTOperation`: + * `id` + * `network_instance` + * `op`: `ADD` + * `mpls`: + * `next_hop_group` + * `next_hop_group` + * `id` + * `next_hop` + * `next_hop` + * `id` + * `ip_address` + * `pushed_label_stack` + * `ModifyResponse`: + * `AFTResult`: + * `id` + * `status` + +## Config parameter coverage + +## Telemetry parameter coverage + + diff --git a/feature/gribi/otg_tests/mpls_compliance/gribi_mpls_compliance_test.go b/feature/gribi/otg_tests/mpls_compliance/gribi_mpls_compliance_test.go new file mode 100644 index 00000000000..da567fa77a2 --- /dev/null +++ b/feature/gribi/otg_tests/mpls_compliance/gribi_mpls_compliance_test.go @@ -0,0 +1,51 @@ +// Package gribi_mpls_compliance_test implements test that validate the gRIBI +// server behaviour for MPLS programming. No traffic validation is performed +// such that the validation is that the API for MPLS is complied with. +package gribi_mpls_compliance_test + +import ( + "flag" + "fmt" + "testing" + "time" + + "github.com/openconfig/featureprofiles/feature/gribi/mplsutil" + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/gribigo/fluent" + "github.com/openconfig/ondatra" +) + +const ( + // baseLabel specifies the lower bound label used within a stack. + baseLabel = 42 + // maxLabelDepth is the maximum number of labels that should be pushed on the stack. + maxLabelDepth = 20 +) + +var ( + sleep = flag.Int("sleep", 0, "seconds to sleep within test before exiting") +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +// TestMPLSLabelPushDepth validates the gRIBI actions that are used to push N labels onto +// a packet as part of routing towards a next-hop. Note that this test does not +// validate against the dataplane, but solely the gRIBI control-plane support. +func TestMPLSLabelPushDepth(t *testing.T) { + dut := ondatra.DUT(t, "dut") + gribic := dut.RawAPIs().GRIBI().Default(t) + c := fluent.NewClient() + c.Connection().WithStub(gribic) + + _ = mplsutil.PushBaseConfigs(t, ondatra.DUT(t, "dut"), ondatra.ATE(t, "ate")) + sleepFn := func(_ *testing.T, _ []uint32) { time.Sleep(time.Duration(*sleep) * time.Second) } + + for i := 1; i <= maxLabelDepth; i++ { + t.Run(fmt.Sprintf("push %d labels", i), func(t *testing.T) { + mplsutil.PushLabelStack(t, c, deviations.DefaultNetworkInstance(dut), baseLabel, i, sleepFn) + }) + } +} diff --git a/feature/gribi/otg_tests/mpls_compliance/metadata.textproto b/feature/gribi/otg_tests/mpls_compliance/metadata.textproto new file mode 100644 index 00000000000..175b68ecaa3 --- /dev/null +++ b/feature/gribi/otg_tests/mpls_compliance/metadata.textproto @@ -0,0 +1,7 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "835d2c66-3b57-4a62-99df-05120e282786" +plan_id: "TE-9" +description: "gRIBI MPLS Compliance" +testbed: TESTBED_DUT_ATE_2LINKS From 39534046fbf386db7d4e256e5b58386fe6cbaf19 Mon Sep 17 00:00:00 2001 From: Tushar Rathod <111466464+trathod1@users.noreply.github.com> Date: Wed, 13 Sep 2023 21:10:46 -0400 Subject: [PATCH 28/43] DP-1.2: Adding test support for Nokia (#2001) * DP-1.2: Adding test support for Nokia 1. Adding testNokiaClassifierConfig and testNokiaSchedulerPoliciesConfig to cover script scenario for Nokia 2. Adding function (SetForwardingGroupWithFabricPriority) to configure ForwardingGroup with Fabric-priority in qoscfg.go * Updating queue-name based on commonTrafficQueueNames based https://github.com/openconfig/entity-naming/pull/24 * Adding buffer-allocation configuration for maxBurstSize. * Consolidating buffer-allocation config. * Replacing fabric-priority configuration with Queue-id as discussed in b/297188157 * Validating priority state only when configured strict. --------- Co-authored-by: Sergey Fomin --- .../qos_policy_config_test/metadata.textproto | 8 - .../qos_policy_config_test.go | 557 ++++++++++++++++++ 2 files changed, 557 insertions(+), 8 deletions(-) diff --git a/feature/qos/tests/qos_policy_config_test/metadata.textproto b/feature/qos/tests/qos_policy_config_test/metadata.textproto index 9a649ffff17..2933884e6da 100644 --- a/feature/qos/tests/qos_policy_config_test/metadata.textproto +++ b/feature/qos/tests/qos_policy_config_test/metadata.textproto @@ -15,11 +15,3 @@ platform_exceptions: { explicit_interface_ref_definition: true } } -platform_exceptions: { - platform: { - vendor: NOKIA - } - deviations: { - explicit_interface_ref_definition: true - } -} diff --git a/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go b/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go index 6a77eaf7505..133c655eb05 100644 --- a/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go +++ b/feature/qos/tests/qos_policy_config_test/qos_policy_config_test.go @@ -84,6 +84,17 @@ var ( fn: testJuniperSchedulerPoliciesConfig, }, } + QosNokiaConfigTestcase = []Testcase{ + + { + name: "testNokiaClassifierConfig", + fn: testNokiaClassifierConfig, + }, + { + name: "testNokiaSchedulerPoliciesConfig", + fn: testNokiaSchedulerPoliciesConfig, + }, + } ) func TestMain(m *testing.M) { @@ -104,6 +115,12 @@ func TestQosConfigTests(t *testing.T) { tt.fn(t) }) } + case ondatra.NOKIA: + for _, tt := range QosNokiaConfigTestcase { + t.Run(tt.name, func(t *testing.T) { + tt.fn(t) + }) + } default: for _, tt := range QoSConfigTestcases { t.Run(tt.name, func(t *testing.T) { @@ -1754,3 +1771,543 @@ func testJuniperSchedulerPoliciesConfig(t *testing.T) { } } } + +func testNokiaClassifierConfig(t *testing.T) { + dut := ondatra.DUT(t, "dut") + d := &oc.Root{} + q := d.GetOrCreateQos() + queues := netutil.CommonTrafficQueues(t, dut) + queueNames := []string{queues.NC1, queues.AF4, queues.AF3, queues.AF2, queues.AF1, queues.BE0, queues.BE1} + for i, queue := range queueNames { + q1 := q.GetOrCreateQueue(queue) + q1.Name = ygot.String(queue) + queueid := len(queueNames) - i + q1.QueueId = ygot.Uint8(uint8(queueid)) + } + + t.Logf("Create qos forwarding groups config") + forwardingGroups := []struct { + desc string + queueName string + targetGroup string + }{{ + desc: "forwarding-group-BE1", + queueName: queues.BE1, + targetGroup: "target-group-BE1", + }, { + desc: "forwarding-group-BE0", + queueName: queues.BE0, + targetGroup: "target-group-BE0", + }, { + desc: "forwarding-group-AF1", + queueName: queues.AF1, + targetGroup: "target-group-AF1", + }, { + desc: "forwarding-group-AF2", + queueName: queues.AF2, + targetGroup: "target-group-AF2", + }, { + desc: "forwarding-group-AF3", + queueName: queues.AF3, + targetGroup: "target-group-AF3", + }, { + desc: "forwarding-group-AF4", + queueName: queues.AF4, + targetGroup: "target-group-AF4", + }, { + desc: "forwarding-group-NC1", + queueName: queues.NC1, + targetGroup: "target-group-NC1", + }} + + t.Logf("qos forwarding groups config cases: %v", forwardingGroups) + for _, tc := range forwardingGroups { + t.Run(tc.desc, func(t *testing.T) { + qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) + }) + + // Verify the ForwardingGroup is applied by checking the telemetry path state values. + forwardingGroup := gnmi.OC().Qos().ForwardingGroup(tc.targetGroup) + if got, want := gnmi.Get(t, dut, forwardingGroup.Name().State()), tc.targetGroup; got != want { + t.Errorf("forwardingGroup.Name().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, forwardingGroup.OutputQueue().State()), tc.queueName; got != want { + t.Errorf("forwardingGroup.OutputQueue().State(): got %v, want %v", got, want) + } + } + + classifiers := []struct { + desc string + name string + classType oc.E_Qos_Classifier_Type + termID string + targetGroup string + dscpSet []uint8 + }{{ + desc: "classifier_ipv4_be1", + name: "dscp_based_classifier_ipv4", + classType: oc.Qos_Classifier_Type_IPV4, + termID: "0", + targetGroup: "target-group-BE1", + dscpSet: []uint8{0, 1, 2, 3}, + }, { + desc: "classifier_ipv4_be0", + name: "dscp_based_classifier_ipv4", + classType: oc.Qos_Classifier_Type_IPV4, + termID: "1", + targetGroup: "target-group-BE0", + dscpSet: []uint8{4, 5, 6, 7}, + }, { + desc: "classifier_ipv4_af1", + name: "dscp_based_classifier_ipv4", + classType: oc.Qos_Classifier_Type_IPV4, + termID: "2", + targetGroup: "target-group-AF1", + dscpSet: []uint8{8, 9, 10, 11}, + }, { + desc: "classifier_ipv4_af2", + name: "dscp_based_classifier_ipv4", + classType: oc.Qos_Classifier_Type_IPV4, + termID: "3", + targetGroup: "target-group-AF2", + dscpSet: []uint8{16, 17, 18, 19}, + }, { + desc: "classifier_ipv4_af3", + name: "dscp_based_classifier_ipv4", + classType: oc.Qos_Classifier_Type_IPV4, + termID: "4", + targetGroup: "target-group-AF3", + dscpSet: []uint8{24, 25, 26, 27}, + }, { + desc: "classifier_ipv4_af4", + name: "dscp_based_classifier_ipv4", + classType: oc.Qos_Classifier_Type_IPV4, + termID: "5", + targetGroup: "target-group-AF4", + dscpSet: []uint8{32, 33, 34, 35}, + }, { + desc: "classifier_ipv4_nc1", + name: "dscp_based_classifier_ipv4", + classType: oc.Qos_Classifier_Type_IPV4, + termID: "6", + targetGroup: "target-group-NC1", + dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, + }, { + desc: "classifier_ipv6_be1", + name: "dscp_based_classifier_ipv6", + classType: oc.Qos_Classifier_Type_IPV6, + termID: "0", + targetGroup: "target-group-BE1", + dscpSet: []uint8{0, 1, 2, 3}, + }, { + desc: "classifier_ipv6_be0", + name: "dscp_based_classifier_ipv6", + classType: oc.Qos_Classifier_Type_IPV6, + termID: "1", + targetGroup: "target-group-BE0", + dscpSet: []uint8{4, 5, 6, 7}, + }, { + desc: "classifier_ipv6_af1", + name: "dscp_based_classifier_ipv6", + classType: oc.Qos_Classifier_Type_IPV6, + termID: "2", + targetGroup: "target-group-AF1", + dscpSet: []uint8{8, 9, 10, 11}, + }, { + desc: "classifier_ipv6_af2", + name: "dscp_based_classifier_ipv6", + classType: oc.Qos_Classifier_Type_IPV6, + termID: "3", + targetGroup: "target-group-AF2", + dscpSet: []uint8{16, 17, 18, 19}, + }, { + desc: "classifier_ipv6_af3", + name: "dscp_based_classifier_ipv6", + classType: oc.Qos_Classifier_Type_IPV6, + termID: "4", + targetGroup: "target-group-AF3", + dscpSet: []uint8{24, 25, 26, 27}, + }, { + desc: "classifier_ipv6_af4", + name: "dscp_based_classifier_ipv6", + classType: oc.Qos_Classifier_Type_IPV6, + termID: "5", + targetGroup: "target-group-AF4", + dscpSet: []uint8{32, 33, 34, 35}, + }, { + desc: "classifier_ipv6_nc1", + name: "dscp_based_classifier_ipv6", + classType: oc.Qos_Classifier_Type_IPV6, + termID: "6", + targetGroup: "target-group-NC1", + dscpSet: []uint8{48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59}, + }} + + t.Logf("qos Classifiers config cases: %v", classifiers) + for _, tc := range classifiers { + t.Run(tc.desc, func(t *testing.T) { + classifier := q.GetOrCreateClassifier(tc.name) + classifier.SetName(tc.name) + classifier.SetType(tc.classType) + term, err := classifier.NewTerm(tc.termID) + if err != nil { + t.Fatalf("Failed to create classifier.NewTerm(): %v", err) + } + + term.SetId(tc.termID) + action := term.GetOrCreateActions() + action.SetTargetGroup(tc.targetGroup) + condition := term.GetOrCreateConditions() + if tc.name == "dscp_based_classifier_ipv4" { + condition.GetOrCreateIpv4().SetDscpSet(tc.dscpSet) + } else if tc.name == "dscp_based_classifier_ipv6" { + condition.GetOrCreateIpv6().SetDscpSet(tc.dscpSet) + } + gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) + }) + + // Verify the Classifier is applied by checking the telemetry path state values. + classifier := gnmi.OC().Qos().Classifier(tc.name) + term := classifier.Term(tc.termID) + action := term.Actions() + condition := term.Conditions() + + cmp.Equal([]uint8{1, 2, 3}, []uint8{1, 2, 3}) + cmp.Equal([]uint8{1, 2, 3}, []uint8{1, 3, 2}) + + if got, want := gnmi.Get(t, dut, classifier.Name().State()), tc.name; got != want { + t.Errorf("classifier.Name().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, classifier.Type().State()), tc.classType; got != want { + t.Errorf("classifier.Type().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, term.Id().State()), tc.termID; got != want { + t.Errorf("term.Id().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, action.TargetGroup().State()), tc.targetGroup; got != want { + t.Errorf("action.TargetGroup().State(): got %v, want %v", got, want) + } + + // This Transformer sorts a []uint8. + trans := cmp.Transformer("Sort", func(in []uint8) []uint8 { + out := append([]uint8(nil), in...) + sort.Slice(out, func(i, j int) bool { return out[i] < out[j] }) + return out + }) + + if tc.name == "dscp_based_classifier_ipv4" { + if equal := cmp.Equal(gnmi.Get(t, dut, condition.Ipv4().DscpSet().State()), tc.dscpSet, trans); !equal { + t.Errorf("condition.Ipv4().DscpSet().State(): got %v, want %v", gnmi.Get(t, dut, condition.Ipv4().DscpSet().State()), tc.dscpSet) + } + } else if tc.name == "dscp_based_classifier_ipv6" { + if equal := cmp.Equal(gnmi.Get(t, dut, condition.Ipv6().DscpSet().State()), tc.dscpSet, trans); !equal { + t.Errorf("condition.Ipv6().DscpSet().State(): got %v, want %v", gnmi.Get(t, dut, condition.Ipv6().DscpSet().State()), tc.dscpSet) + } + } + } + + dp := dut.Port(t, "port1") + + cases := []struct { + desc string + inputClassifierType oc.E_Input_Classifier_Type + classifier string + }{{ + desc: "Input Classifier Type IPV4", + inputClassifierType: oc.Input_Classifier_Type_IPV4, + classifier: "dscp_based_classifier_ipv4", + }, { + desc: "Input Classifier Type IPV6", + inputClassifierType: oc.Input_Classifier_Type_IPV6, + classifier: "dscp_based_classifier_ipv6", + }} + + ip := &oc.Interface{Name: ygot.String(dp.Name())} + ip.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + s := ip.GetOrCreateSubinterface(0) + s.GetOrCreateIpv4().Enabled = ygot.Bool(true) + s.GetOrCreateIpv6().Enabled = ygot.Bool(true) + gnmi.Replace(t, dut, gnmi.OC().Interface(dp.Name()).Config(), ip) + t.Logf("qos input classifier config cases: %v", cases) + for _, tc := range cases { + t.Run(tc.desc, func(t *testing.T) { + qoscfg.SetInputClassifier(t, dut, q, dp.Name(), tc.inputClassifierType, tc.classifier) + }) + + // Verify the Classifier is applied on interface by checking the telemetry path state values. + classifier := gnmi.OC().Qos().Interface(dp.Name()).Input().Classifier(tc.inputClassifierType) + if got, want := gnmi.Get(t, dut, classifier.Name().State()), tc.classifier; got != want { + t.Errorf("classifier.Name().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, classifier.Type().State()), tc.inputClassifierType; got != want { + t.Errorf("classifier.Name().State(): got %v, want %v", got, want) + } + } +} + +func testNokiaSchedulerPoliciesConfig(t *testing.T) { + dut := ondatra.DUT(t, "dut") + d := &oc.Root{} + q := d.GetOrCreateQos() + dp := dut.Port(t, "port2") + i := q.GetOrCreateInterface(dp.Name()) + i.SetInterfaceId(dp.Name()) + i.GetOrCreateInterfaceRef().Interface = ygot.String(dp.Name()) + + ip := &oc.Interface{Name: ygot.String(dp.Name())} + ip.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + s := ip.GetOrCreateSubinterface(0) + s.GetOrCreateIpv4().Enabled = ygot.Bool(true) + s.GetOrCreateIpv6().Enabled = ygot.Bool(true) + gnmi.Replace(t, dut, gnmi.OC().Interface(dp.Name()).Config(), ip) + + queues := netutil.CommonTrafficQueues(t, dut) + queueNames := []string{queues.NC1, queues.AF4, queues.AF3, queues.AF2, queues.AF1, queues.BE0, queues.BE1} + for i, queue := range queueNames { + q1 := q.GetOrCreateQueue(queue) + q1.Name = ygot.String(queue) + queueid := len(queueNames) - i + q1.QueueId = ygot.Uint8(uint8(queueid)) + } + + schedulers := []struct { + desc string + sequence uint32 + priority oc.E_Scheduler_Priority + inputID string + weight uint64 + queueName string + targetGroup string + }{{ + desc: "scheduler-policy-BE1", + sequence: uint32(1), + priority: oc.Scheduler_Priority_UNSET, + inputID: "BE1", + weight: uint64(1), + queueName: queues.BE1, + targetGroup: "BE1", + }, { + desc: "scheduler-policy-BE0", + sequence: uint32(1), + priority: oc.Scheduler_Priority_UNSET, + inputID: "BE0", + weight: uint64(2), + queueName: queues.BE0, + targetGroup: "BE0", + }, { + desc: "scheduler-policy-AF1", + sequence: uint32(1), + priority: oc.Scheduler_Priority_UNSET, + inputID: "AF1", + weight: uint64(4), + queueName: queues.AF1, + targetGroup: "AF1", + }, { + desc: "scheduler-policy-AF2", + sequence: uint32(1), + priority: oc.Scheduler_Priority_UNSET, + inputID: "AF2", + weight: uint64(8), + queueName: queues.AF2, + targetGroup: "AF2", + }, { + desc: "scheduler-policy-AF3", + sequence: uint32(1), + priority: oc.Scheduler_Priority_UNSET, + inputID: "AF3", + weight: uint64(16), + queueName: queues.AF3, + targetGroup: "AF3", + }, { + desc: "scheduler-policy-AF4", + sequence: uint32(0), + priority: oc.Scheduler_Priority_STRICT, + inputID: queues.AF4, + weight: uint64(99), + queueName: queues.AF4, + targetGroup: "AF4", + }, { + desc: "scheduler-policy-NC1", + sequence: uint32(0), + priority: oc.Scheduler_Priority_STRICT, + inputID: "NC1", + weight: uint64(100), + queueName: queues.NC1, + targetGroup: "NC1", + }} + + schedulerPolicy := q.GetOrCreateSchedulerPolicy("scheduler") + schedulerPolicy.SetName("scheduler") + + t.Logf("qos scheduler policies config cases: %v", schedulers) + for _, tc := range schedulers { + t.Run(tc.desc, func(t *testing.T) { + qoscfg.SetForwardingGroup(t, dut, q, tc.targetGroup, tc.queueName) + s := schedulerPolicy.GetOrCreateScheduler(tc.sequence) + s.SetSequence(tc.sequence) + s.SetPriority(tc.priority) + input := s.GetOrCreateInput(tc.inputID) + input.SetId(tc.inputID) + input.SetInputType(oc.Input_InputType_QUEUE) + input.SetQueue(tc.queueName) + input.SetWeight(tc.weight) + gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) + }) + + // Verify the SchedulerPolicy is applied by checking the telemetry path state values. + + scheduler := gnmi.OC().Qos().SchedulerPolicy("scheduler").Scheduler(tc.sequence) + input := scheduler.Input(tc.inputID) + + if got, want := gnmi.Get(t, dut, scheduler.Sequence().State()), tc.sequence; got != want { + t.Errorf("scheduler.Sequence().State(): got %v, want %v", got, want) + } + if tc.priority == oc.Scheduler_Priority_STRICT { + if got, want := gnmi.Get(t, dut, scheduler.Priority().State()), tc.priority; got != want { + t.Errorf("scheduler.Priority().State(): got %v, want %v", got, want) + } + } + if got, want := gnmi.Get(t, dut, input.Id().State()), tc.inputID; got != want { + t.Errorf("input.Id().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, input.InputType().State()), oc.Input_InputType_QUEUE; got != want { + t.Errorf("input.InputType().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, input.Weight().State()), tc.weight; got != want { + t.Errorf("input.Weight().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, input.Queue().State()), tc.queueName; got != want { + t.Errorf("input.Queue().State(): got %v, want %v", got, want) + } + + } + + ecnConfig := struct { + ecnEnabled bool + dropEnabled bool + minThreshold uint64 + maxThreshold uint64 + maxDropProbabilityPercent uint8 + weight uint32 + }{ + ecnEnabled: true, + dropEnabled: false, + minThreshold: uint64(80000), + maxThreshold: math.MaxUint64, + maxDropProbabilityPercent: uint8(1), + weight: uint32(0), + } + + queueMgmtProfile := q.GetOrCreateQueueManagementProfile("DropProfile") + queueMgmtProfile.SetName("DropProfile") + wred := queueMgmtProfile.GetOrCreateWred() + uniform := wred.GetOrCreateUniform() + uniform.SetEnableEcn(ecnConfig.ecnEnabled) + uniform.SetMinThreshold(ecnConfig.minThreshold) + uniform.SetMaxThreshold(ecnConfig.maxThreshold) + uniform.SetMaxDropProbabilityPercent(ecnConfig.maxDropProbabilityPercent) + uniform.SetDrop(ecnConfig.dropEnabled) + uniform.SetWeight(ecnConfig.weight) + + t.Logf("qos ECN QueueManagementProfile config cases: %v", ecnConfig) + gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) + + // Verify the QueueManagementProfile is applied by checking the telemetry path state values. + + wredUniform := gnmi.OC().Qos().QueueManagementProfile("DropProfile").Wred().Uniform() + if got, want := gnmi.Get(t, dut, wredUniform.EnableEcn().State()), ecnConfig.ecnEnabled; got != want { + t.Errorf("wredUniform.EnableEcn().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, wredUniform.Drop().State()), ecnConfig.dropEnabled; got != want { + t.Errorf("wredUniform.Drop().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, wredUniform.MinThreshold().State()), ecnConfig.minThreshold; got != want { + t.Errorf("wredUniform.MinThreshold().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, wredUniform.MaxThreshold().State()), ecnConfig.maxThreshold; got != want { + t.Errorf("wredUniform.MaxThreshold().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, wredUniform.MaxDropProbabilityPercent().State()), ecnConfig.maxDropProbabilityPercent; got != want { + t.Errorf("wredUniform.MaxDropProbabilityPercent().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, wredUniform.Weight().State()), ecnConfig.weight; got != want { + t.Errorf("wredUniform.Weight().State(): got %v, want %v", got, want) + } + + cases := []struct { + desc string + queueName string + ecnProfile string + scheduler string + }{{ + desc: "output-interface-NC1", + queueName: "NC1", + ecnProfile: "DropProfile", + scheduler: "scheduler", + }, { + desc: "output-interface-AF4", + queueName: "AF4", + ecnProfile: "DropProfile", + scheduler: "scheduler", + }, { + desc: "output-interface-AF3", + queueName: "AF3", + ecnProfile: "DropProfile", + scheduler: "scheduler", + }, { + desc: "output-interface-AF2", + queueName: "AF2", + ecnProfile: "DropProfile", + scheduler: "scheduler", + }, { + desc: "output-interface-AF1", + queueName: "AF1", + ecnProfile: "DropProfile", + scheduler: "scheduler", + }, { + desc: "output-interface-BE0", + queueName: "BE0", + ecnProfile: "DropProfile", + scheduler: "scheduler", + }, { + desc: "output-interface-BE1", + queueName: "BE1", + ecnProfile: "DropProfile", + scheduler: "scheduler", + }} + + maxBurstSize := uint32(268435456) + bufferAllocation := q.GetOrCreateBufferAllocationProfile("ballocprofile") + t.Logf("qos output interface config cases: %v", cases) + for _, tc := range cases { + t.Run(tc.desc, func(t *testing.T) { + output := i.GetOrCreateOutput() + schedulerPolicy := output.GetOrCreateSchedulerPolicy() + schedulerPolicy.SetName(tc.scheduler) + queue := output.GetOrCreateQueue(tc.queueName) + queue.SetQueueManagementProfile(tc.ecnProfile) + queue.SetName(tc.queueName) + bq := bufferAllocation.GetOrCreateQueue(tc.queueName) + bq.SetStaticSharedBufferLimit(maxBurstSize) + output.SetBufferAllocationProfile("ballocprofile") + gnmi.Replace(t, dut, gnmi.OC().Qos().Config(), q) + }) + + // Verify the policy is applied by checking the telemetry path state values. + policy := gnmi.OC().Qos().Interface(dp.Name()).Output().SchedulerPolicy() + outQueue := gnmi.OC().Qos().Interface(dp.Name()).Output().Queue(tc.queueName) + + if got, want := gnmi.Get(t, dut, policy.Name().State()), "scheduler"; got != want { + t.Errorf("policy.Name().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, outQueue.Name().State()), tc.queueName; got != want { + t.Errorf("outQueue.Name().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, outQueue.QueueManagementProfile().State()), "DropProfile"; got != want { + t.Errorf("outQueue.QueueManagementProfile().State(): got %v, want %v", got, want) + } + if got, want := gnmi.Get(t, dut, wredUniform.EnableEcn().State()), ecnConfig.ecnEnabled; got != want { + t.Errorf("wredUniform.EnableEcn().State(): got %v, want %v", got, want) + } + } +} From e3dc053e7c0abe36b6899660c377b7f0bbe09632 Mon Sep 17 00:00:00 2001 From: Tushar Rathod <111466464+trathod1@users.noreply.github.com> Date: Thu, 14 Sep 2023 12:53:14 -0400 Subject: [PATCH 29/43] DP-1.4: Adding test support for Nokia (#2023) * DP-1.4: Adding test support for Nokia Following changes are made in this PR - 1. Updating deviations in metadata file 2. Updating test script to support Nokia 3. Adding function (SetForwardingGroupWithFabricPriority) to configure ForwardingGroup with Fabric-priority in qoscfg.go "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." Co-authored-by: Krishna Bovilla * Replacing fabric-priority configuration with queue-id as discussed in b/297188157 "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." --------- Co-authored-by: Krishna Bovilla Co-authored-by: Sergey Fomin --- .../metadata.textproto | 4 ++- .../qos_output_queue_counters_test.go | 26 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/feature/qos/otg_tests/qos_output_queue_counters_test/metadata.textproto b/feature/qos/otg_tests/qos_output_queue_counters_test/metadata.textproto index dceb9fac219..b8930208d3d 100644 --- a/feature/qos/otg_tests/qos_output_queue_counters_test/metadata.textproto +++ b/feature/qos/otg_tests/qos_output_queue_counters_test/metadata.textproto @@ -28,7 +28,9 @@ platform_exceptions: { vendor: NOKIA } deviations: { - explicit_interface_ref_definition: true + explicit_port_speed: true + explicit_interface_in_default_vrf: true + qos_octets: true interface_enabled: true } } diff --git a/feature/qos/otg_tests/qos_output_queue_counters_test/qos_output_queue_counters_test.go b/feature/qos/otg_tests/qos_output_queue_counters_test/qos_output_queue_counters_test.go index 3f4c0667442..4b2c0e801e8 100644 --- a/feature/qos/otg_tests/qos_output_queue_counters_test/qos_output_queue_counters_test.go +++ b/feature/qos/otg_tests/qos_output_queue_counters_test/qos_output_queue_counters_test.go @@ -142,6 +142,16 @@ func TestQoSCounters(t *testing.T) { "flow-be0": {frameSize: 1110, trafficRate: 1, dscp: 4, queue: queues.BE0}, "flow-be1": {frameSize: 1111, trafficRate: 1, dscp: 0, queue: queues.BE1}, } + case ondatra.NOKIA: + trafficFlows = map[string]*trafficData{ + "flow-nc1": {frameSize: 700, trafficRate: 7, dscp: 56, queue: queues.NC1}, + "flow-af4": {frameSize: 400, trafficRate: 4, dscp: 32, queue: queues.AF4}, + "flow-af3": {frameSize: 1300, trafficRate: 3, dscp: 24, queue: queues.AF3}, + "flow-af2": {frameSize: 1200, trafficRate: 2, dscp: 16, queue: queues.AF2}, + "flow-af1": {frameSize: 1000, trafficRate: 10, dscp: 8, queue: queues.AF1}, + "flow-be0": {frameSize: 1110, trafficRate: 1, dscp: 4, queue: queues.BE0}, + "flow-be1": {frameSize: 1111, trafficRate: 1, dscp: 0, queue: queues.BE1}, + } default: t.Fatalf("Output queue mapping is missing for %v", dut.Vendor().String()) } @@ -336,6 +346,13 @@ func ConfigureDUTIntf(t *testing.T, dut *ondatra.DUTDevice) { a := s.GetOrCreateAddress(intf.ipAddr) a.PrefixLength = ygot.Uint8(intf.prefixLen) gnmi.Replace(t, dut, gnmi.OC().Interface(intf.intfName).Config(), i) + if deviations.ExplicitInterfaceInDefaultVRF(dut) { + fptest.AssignToNetworkInstance(t, dut, intf.intfName, deviations.DefaultNetworkInstance(dut), 0) + } + } + if deviations.ExplicitPortSpeed(dut) { + fptest.SetPortSpeed(t, dp1) + fptest.SetPortSpeed(t, dp2) } } @@ -346,6 +363,15 @@ func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { d := &oc.Root{} q := d.GetOrCreateQos() queues := netutil.CommonTrafficQueues(t, dut) + if dut.Vendor() == ondatra.NOKIA { + queueNames := []string{queues.NC1, queues.AF4, queues.AF3, queues.AF2, queues.AF1, queues.BE0, queues.BE1} + for i, queue := range queueNames { + q1 := q.GetOrCreateQueue(queue) + q1.Name = ygot.String(queue) + queueid := len(queueNames) - i + q1.QueueId = ygot.Uint8(uint8(queueid)) + } + } nc1InputWeight := uint64(200) af4InputWeight := uint64(100) From 55d990daba591fd25b12e8623df04d3866c8da24 Mon Sep 17 00:00:00 2001 From: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> Date: Thu, 14 Sep 2023 15:50:00 -0400 Subject: [PATCH 30/43] Fix new use of deprecated raw API (#2130) --- .../otg_tests/mpls_compliance/gribi_mpls_compliance_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/gribi/otg_tests/mpls_compliance/gribi_mpls_compliance_test.go b/feature/gribi/otg_tests/mpls_compliance/gribi_mpls_compliance_test.go index da567fa77a2..b9bccac5a51 100644 --- a/feature/gribi/otg_tests/mpls_compliance/gribi_mpls_compliance_test.go +++ b/feature/gribi/otg_tests/mpls_compliance/gribi_mpls_compliance_test.go @@ -36,7 +36,7 @@ func TestMain(m *testing.M) { // validate against the dataplane, but solely the gRIBI control-plane support. func TestMPLSLabelPushDepth(t *testing.T) { dut := ondatra.DUT(t, "dut") - gribic := dut.RawAPIs().GRIBI().Default(t) + gribic := dut.RawAPIs().GRIBI(t) c := fluent.NewClient() c.Connection().WithStub(gribic) From 1b5bb5dd4c43e0a773271b814aa9a4f33fc93da9 Mon Sep 17 00:00:00 2001 From: bkreddy143 <127771656+bkreddy143@users.noreply.github.com> Date: Thu, 14 Sep 2023 17:09:52 -0400 Subject: [PATCH 31/43] DP-1.14: Fixing error in forwarding group config (#2123) As part of PR-2026 ,part of config was removed by mistake and corrected it. "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." --- feature/qos/otg_tests/qos_basic_test/qos_basic_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go b/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go index aeb85d1f6ae..c6ff494bbd4 100644 --- a/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go +++ b/feature/qos/otg_tests/qos_basic_test/qos_basic_test.go @@ -613,6 +613,10 @@ func ConfigureQoS(t *testing.T, dut *ondatra.DUTDevice) { desc: "forwarding-group-BE1", queueName: queues.BE1, targetGroup: "target-group-BE1", + }, { + desc: "forwarding-group-BE0", + queueName: queues.BE0, + targetGroup: "target-group-BE0", }, { desc: "forwarding-group-AF1", queueName: queues.AF1, From 536eb3edb684c8f197a421216c1ce65be14289e8 Mon Sep 17 00:00:00 2001 From: gforeal <120526274+gforeal@users.noreply.github.com> Date: Thu, 14 Sep 2023 15:13:17 -0700 Subject: [PATCH 32/43] Adding support for vendor ARISTA in Core file check test (#2125) --- .../system_generic_health_check_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go b/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go index 033694f5a2a..b53e4e8a8ba 100644 --- a/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go +++ b/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go @@ -45,11 +45,13 @@ var ( ondatra.JUNIPER: "/var/core/", ondatra.CISCO: "/misc/disk1/", ondatra.NOKIA: "/var/core/", + ondatra.ARISTA: "/var/core/", } vendorCoreFileNamePattern = map[ondatra.Vendor]*regexp.Regexp{ ondatra.JUNIPER: regexp.MustCompile(".*.tar.gz"), ondatra.CISCO: regexp.MustCompile("/misc/disk1/.*core.*"), ondatra.NOKIA: regexp.MustCompile("/var/core/coredump-.*"), + ondatra.ARISTA: regexp.MustCompile("/var/core/core.*"), } ) From e67790cd330c02d0d8624da2d9ae3fce282169a1 Mon Sep 17 00:00:00 2001 From: bkreddy143 <127771656+bkreddy143@users.noreply.github.com> Date: Thu, 14 Sep 2023 18:26:35 -0400 Subject: [PATCH 33/43] adding case insensitive check for mac (#1635) This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an as is basis without any warranties of any kind. Co-authored-by: Sergey Fomin --- .../staticarp/otg_tests/static_arp_test/static_arp_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/feature/interface/staticarp/otg_tests/static_arp_test/static_arp_test.go b/feature/interface/staticarp/otg_tests/static_arp_test/static_arp_test.go index ff00dac66ba..f52df8aa5d8 100644 --- a/feature/interface/staticarp/otg_tests/static_arp_test/static_arp_test.go +++ b/feature/interface/staticarp/otg_tests/static_arp_test/static_arp_test.go @@ -15,6 +15,7 @@ package te_1_1_static_arp_test import ( + "strings" "testing" "time" @@ -210,14 +211,14 @@ func checkDUTEntry(t *testing.T, ipType string, poisoned bool) { switch ipType { case "IPv4": macAddress := gnmi.Get(t, dut, gnmi.OC().Interface(dut.Port(t, "port2").Name()).Subinterface(0).Ipv4().Neighbor(ateDst.IPv4).State()).LinkLayerAddress - if *macAddress != expectedMac { + if !strings.EqualFold(*macAddress, expectedMac) { t.Errorf("ARP entry for %v is %v and expected was %v", ateDst.IPv4, *macAddress, expectedMac) } else { t.Logf("ARP entry for %v is %v", ateDst.IPv4, *macAddress) } case "IPv6": macAddress := gnmi.Get(t, dut, gnmi.OC().Interface(dut.Port(t, "port2").Name()).Subinterface(0).Ipv6().Neighbor(ateDst.IPv6).State()).LinkLayerAddress - if *macAddress != expectedMac { + if !strings.EqualFold(*macAddress, expectedMac) { t.Errorf("Neighbor entry for %v is %v and expected was %v", ateDst.IPv6, *macAddress, expectedMac) } else { t.Logf("Neighbor entry for %v is %v", ateDst.IPv6, *macAddress) From f1448a6d3589af8dd2ce411dd2b4190e7096ea0a Mon Sep 17 00:00:00 2001 From: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> Date: Thu, 14 Sep 2023 22:18:21 -0400 Subject: [PATCH 34/43] Fix nil dereference (#2128) --- .../route_removal_during_failover_test.go | 2 +- .../route_removal_during_failover_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go b/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go index b2f68925d41..bce6c166e4f 100644 --- a/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go +++ b/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go @@ -571,7 +571,7 @@ func TestRouteRemovalDuringFailover(t *testing.T) { var flushRes, wantFlushRes *gpb.FlushResponse t.Log("Execute gRIBi flush and master switchover concurrently.") go func(msg string) { - flushRes, err := gribi.Flush(client, eID, deviations.DefaultNetworkInstance(dut)) + flushRes, err = gribi.Flush(client, eID, deviations.DefaultNetworkInstance(dut)) if err != nil { t.Logf("Unexpected error from flush, got: %v, %v", err, flushRes) } diff --git a/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go b/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go index a3c59c5e485..830c35b4856 100644 --- a/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go +++ b/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go @@ -602,7 +602,7 @@ func TestRouteRemovalDuringFailover(t *testing.T) { var flushRes, wantFlushRes *gpb.FlushResponse t.Log("Execute gRIBi flush and master switchover concurrently.") go func(msg string) { - flushRes, err := gribi.Flush(client, eID, deviations.DefaultNetworkInstance(dut)) + flushRes, err = gribi.Flush(client, eID, deviations.DefaultNetworkInstance(dut)) if err != nil { t.Logf("Unexpected error from flush, got: %v, %v", err, flushRes) } From d0f7871653950ab668e4e9473fc2c411dd866d89 Mon Sep 17 00:00:00 2001 From: Girish Subramanian <103155016+sgirishj@users.noreply.github.com> Date: Thu, 14 Sep 2023 23:08:34 -0700 Subject: [PATCH 35/43] gNMI-1.13: New deviation for transceiver thresholds (#2122) * gNMI-1.13: New deviation for unsupported threshold container under transceiver component * Committing metadata.proto; had missed this in the earlier commit. --------- Co-authored-by: nicjiang2023 --- .../metadata.textproto | 9 + .../optics_power_and_bias_current_test.go | 34 ++- internal/deviations/deviations.go | 6 + proto/metadata.proto | 2 + proto/metadata_go_proto/metadata.pb.go | 275 +++++++++--------- 5 files changed, 180 insertions(+), 146 deletions(-) diff --git a/feature/platform/tests/optics_power_and_bias_current_test/metadata.textproto b/feature/platform/tests/optics_power_and_bias_current_test/metadata.textproto index 512971a9806..f25955ba3cb 100644 --- a/feature/platform/tests/optics_power_and_bias_current_test/metadata.textproto +++ b/feature/platform/tests/optics_power_and_bias_current_test/metadata.textproto @@ -13,3 +13,12 @@ platform_exceptions: { explicit_port_speed: true } } + +platform_exceptions: { + platform: { + vendor: JUNIPER + } + deviations: { + transceiver_thresholds_unsupported: true + } +} diff --git a/feature/platform/tests/optics_power_and_bias_current_test/optics_power_and_bias_current_test.go b/feature/platform/tests/optics_power_and_bias_current_test/optics_power_and_bias_current_test.go index ac1a8aa3982..9319abc3701 100644 --- a/feature/platform/tests/optics_power_and_bias_current_test/optics_power_and_bias_current_test.go +++ b/feature/platform/tests/optics_power_and_bias_current_test/optics_power_and_bias_current_test.go @@ -94,13 +94,17 @@ func TestOpticsPowerBiasCurrent(t *testing.T) { if len(biasCurrents) == 0 { t.Errorf("Get biasCurrents list for %q: got 0, want > 0", transceiver) } - // TODO(ankursaikia): Validate the values for each leaf. - ths := gnmi.GetAll(t, dut, component.Transceiver().ThresholdAny().State()) - for _, th := range ths { - t.Logf("Transceiver: %s, Threshold Severity: %s", transceiver, th.GetSeverity().String()) - t.Logf("Laser Temperature: lower %v, upper %v", th.GetLaserTemperatureLower(), th.GetLaserTemperatureUpper()) - t.Logf("Output Power: lower: %v, upper: %v", th.GetOutputPowerLower(), th.GetOutputPowerUpper()) - t.Logf("Input Power: lower: %v, upper: %v", th.GetInputPowerLower(), th.GetInputPowerUpper()) + if deviations.TransceiverThresholdsUnsupported(dut) { + t.Logf("Skipping verification of transceiver threshold leaves due to deviation") + } else { + // TODO(ankursaikia): Validate the values for each leaf. + ths := gnmi.GetAll(t, dut, component.Transceiver().ThresholdAny().State()) + for _, th := range ths { + t.Logf("Transceiver: %s, Threshold Severity: %s", transceiver, th.GetSeverity().String()) + t.Logf("Laser Temperature: lower %v, upper %v", th.GetLaserTemperatureLower(), th.GetLaserTemperatureUpper()) + t.Logf("Output Power: lower: %v, upper: %v", th.GetOutputPowerLower(), th.GetOutputPowerUpper()) + t.Logf("Input Power: lower: %v, upper: %v", th.GetInputPowerLower(), th.GetInputPowerUpper()) + } } }) } @@ -186,12 +190,16 @@ func TestOpticsPowerUpdate(t *testing.T) { t.Errorf("Get outPower for port %q): got %.2f, want > %f", dp.Name(), outPower, minOpticsPower) } } - ths := gnmi.GetAll(t, dut, component.Transceiver().ThresholdAny().State()) - for _, th := range ths { - t.Logf("Transceiver: %s, Threshold Severity: %s", transceiverName, th.GetSeverity().String()) - t.Logf("Laser Temperature: lower %v, upper %v", th.GetLaserTemperatureLower(), th.GetLaserTemperatureUpper()) - t.Logf("Output Power: lower: %v, upper: %v", th.GetOutputPowerLower(), th.GetOutputPowerUpper()) - t.Logf("Input Power: lower: %v, upper: %v", th.GetInputPowerLower(), th.GetInputPowerUpper()) + if deviations.TransceiverThresholdsUnsupported(dut) { + t.Logf("Skipping verification of transceiver threshold leaves due to deviation") + } else { + ths := gnmi.GetAll(t, dut, component.Transceiver().ThresholdAny().State()) + for _, th := range ths { + t.Logf("Transceiver: %s, Threshold Severity: %s", transceiverName, th.GetSeverity().String()) + t.Logf("Laser Temperature: lower %v, upper %v", th.GetLaserTemperatureLower(), th.GetLaserTemperatureUpper()) + t.Logf("Output Power: lower: %v, upper: %v", th.GetOutputPowerLower(), th.GetOutputPowerUpper()) + t.Logf("Input Power: lower: %v, upper: %v", th.GetInputPowerLower(), th.GetInputPowerUpper()) + } } }) } diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index ed7f7267f8c..7a6a0504554 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -596,3 +596,9 @@ func ISISCounterManualAddressDropFromAreasUnsupported(dut *ondatra.DUTDevice) bo func ISISCounterPartChangesUnsupported(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetIsisCounterPartChangesUnsupported() } + +// TransceiverThresholdsUnsupported returns true if the device does not support threshold container under /components/component/transceiver. +// Default value is false. +func TransceiverThresholdsUnsupported(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetTransceiverThresholdsUnsupported() +} diff --git a/proto/metadata.proto b/proto/metadata.proto index a614b68f6a9..09fe58a364e 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -327,6 +327,8 @@ message Metadata { // Devices do not support telemetry for isis counter: part-changes. // Arista: partnerissuetracker.corp.google.com/299285991 bool isis_counter_part_changes_unsupported = 107; + // Devices do not support threshold container under /components/component/transceiver. + bool transceiver_thresholds_unsupported = 108; // Reserved field numbers and identifiers. reserved 84, 9, 28, 90; diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 5415cb33625..a8c1faf97b1 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -14,8 +14,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.30.0 -// protoc v3.19.3 +// protoc-gen-go v1.31.0 +// protoc v3.6.1 // source: metadata.proto package metadata_go_proto @@ -594,6 +594,8 @@ type Metadata_Deviations struct { // Devices do not support telemetry for isis counter: part-changes. // Arista: partnerissuetracker.corp.google.com/299285991 IsisCounterPartChangesUnsupported bool `protobuf:"varint,107,opt,name=isis_counter_part_changes_unsupported,json=isisCounterPartChangesUnsupported,proto3" json:"isis_counter_part_changes_unsupported,omitempty"` + // Devices do not support threshold container under /components/component/transceiver. + TransceiverThresholdsUnsupported bool `protobuf:"varint,108,opt,name=transceiver_thresholds_unsupported,json=transceiverThresholdsUnsupported,proto3" json:"transceiver_thresholds_unsupported,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -1300,6 +1302,13 @@ func (x *Metadata_Deviations) GetIsisCounterPartChangesUnsupported() bool { return false } +func (x *Metadata_Deviations) GetTransceiverThresholdsUnsupported() bool { + if x != nil { + return x.TransceiverThresholdsUnsupported + } + return false +} + type Metadata_PlatformExceptions struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1363,7 +1372,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x74, 0x69, 0x6e, 0x67, 0x1a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x72, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x65, - 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb9, 0x3d, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb0, 0x3d, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49, @@ -1394,7 +1403,7 @@ var file_metadata_proto_rawDesc = []byte{ 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x0e, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xed, 0x35, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, + 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0xe4, 0x35, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x70, 0x76, 0x34, 0x5f, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x70, 0x76, 0x34, 0x4d, 0x69, 0x73, 0x73, 0x69, 0x6e, @@ -1726,136 +1735,136 @@ var file_metadata_proto_rawDesc = []byte{ 0x0a, 0x1c, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x59, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x73, 0x6b, 0x69, 0x70, 0x46, 0x61, 0x62, 0x72, 0x69, 0x63, - 0x43, 0x61, 0x72, 0x64, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x5b, - 0x0a, 0x2b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x6f, 0x77, 0x65, - 0x72, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x5f, 0x69, - 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x5a, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x26, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x50, 0x6f, - 0x77, 0x65, 0x72, 0x44, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x49, 0x6e, - 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x57, 0x0a, 0x2a, 0x69, - 0x73, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x65, - 0x5f, 0x6c, 0x31, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, - 0x6c, 0x32, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x5b, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x23, 0x69, 0x73, 0x69, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x65, - 0x4c, 0x31, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x57, 0x69, 0x74, 0x68, 0x4c, 0x32, 0x4d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x12, 0x57, 0x0a, 0x2a, 0x62, 0x67, 0x70, 0x5f, 0x73, 0x65, 0x74, 0x5f, - 0x6d, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x65, 0x71, 0x75, - 0x61, 0x6c, 0x5f, 0x6f, 0x73, 0x70, 0x66, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x18, 0x5c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x62, 0x67, 0x70, 0x53, 0x65, 0x74, - 0x4d, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x45, 0x71, 0x75, 0x61, 0x6c, - 0x4f, 0x73, 0x70, 0x66, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x4e, 0x0a, - 0x24, 0x70, 0x34, 0x72, 0x74, 0x5f, 0x67, 0x64, 0x70, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x73, 0x5f, 0x64, 0x6f, 0x74, 0x31, 0x71, 0x5f, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, 0x5d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x70, 0x34, 0x72, - 0x74, 0x47, 0x64, 0x70, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x44, 0x6f, 0x74, 0x31, - 0x71, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, 0x59, 0x0a, - 0x2a, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x5e, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x25, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x55, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x65, 0x74, 0x5f, - 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x5f, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0d, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x55, 0x73, 0x65, 0x72, - 0x12, 0x73, 0x0a, 0x38, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, 0x6c, 0x69, 0x66, - 0x65, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x72, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, 0x72, 0x65, 0x66, 0x72, - 0x65, 0x73, 0x68, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x60, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x31, 0x69, 0x73, 0x69, 0x73, 0x4c, 0x73, 0x70, 0x4c, 0x69, 0x66, 0x65, 0x74, - 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x73, 0x4c, 0x73, 0x70, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x77, 0x0a, 0x3a, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x65, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x6d, 0x6f, 0x64, 0x65, - 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, - 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x6d, - 0x6f, 0x64, 0x65, 0x18, 0x61, 0x20, 0x01, 0x28, 0x08, 0x52, 0x33, 0x61, 0x67, 0x67, 0x72, 0x65, - 0x67, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x50, 0x6f, - 0x72, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x4f, - 0x0a, 0x24, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x75, - 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, - 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x62, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x6c, 0x69, - 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x43, 0x70, 0x75, 0x55, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, - 0x53, 0x0a, 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, - 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5f, 0x75, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x63, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x23, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6f, - 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x12, 0x5c, 0x0a, 0x2b, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x75, 0x74, 0x69, 0x6c, - 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x18, 0x64, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x43, 0x70, 0x75, 0x55, 0x74, 0x69, 0x6c, + 0x43, 0x61, 0x72, 0x64, 0x50, 0x6f, 0x77, 0x65, 0x72, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x57, + 0x0a, 0x2a, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x73, + 0x61, 0x6d, 0x65, 0x5f, 0x6c, 0x31, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x77, 0x69, + 0x74, 0x68, 0x5f, 0x6c, 0x32, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x5b, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x23, 0x69, 0x73, 0x69, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x53, + 0x61, 0x6d, 0x65, 0x4c, 0x31, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x57, 0x69, 0x74, 0x68, 0x4c, + 0x32, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x57, 0x0a, 0x2a, 0x62, 0x67, 0x70, 0x5f, 0x73, + 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, + 0x65, 0x71, 0x75, 0x61, 0x6c, 0x5f, 0x6f, 0x73, 0x70, 0x66, 0x5f, 0x73, 0x65, 0x74, 0x5f, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x18, 0x5c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x23, 0x62, 0x67, 0x70, + 0x53, 0x65, 0x74, 0x4d, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x45, 0x71, + 0x75, 0x61, 0x6c, 0x4f, 0x73, 0x70, 0x66, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x12, 0x4e, 0x0a, 0x24, 0x70, 0x34, 0x72, 0x74, 0x5f, 0x67, 0x64, 0x70, 0x5f, 0x72, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x64, 0x6f, 0x74, 0x31, 0x71, 0x5f, 0x73, 0x75, 0x62, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, 0x5d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, + 0x70, 0x34, 0x72, 0x74, 0x47, 0x64, 0x70, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x44, + 0x6f, 0x74, 0x31, 0x71, 0x53, 0x75, 0x62, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, + 0x12, 0x59, 0x0a, 0x2a, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x69, 0x6e, + 0x6b, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x5e, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x25, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x69, 0x6e, + 0x6b, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x73, + 0x65, 0x74, 0x5f, 0x6e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x5f, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x65, 0x74, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x55, + 0x73, 0x65, 0x72, 0x12, 0x73, 0x0a, 0x38, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, + 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, + 0x6c, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x6c, 0x73, 0x70, 0x5f, 0x72, + 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, + 0x60, 0x20, 0x01, 0x28, 0x08, 0x52, 0x31, 0x69, 0x73, 0x69, 0x73, 0x4c, 0x73, 0x70, 0x4c, 0x69, + 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x4c, 0x73, 0x70, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x77, 0x0a, 0x3a, 0x61, 0x67, 0x67, 0x72, + 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x6d, + 0x6f, 0x64, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x6d, 0x65, 0x6d, + 0x62, 0x65, 0x72, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, + 0x6b, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x61, 0x20, 0x01, 0x28, 0x08, 0x52, 0x33, 0x61, 0x67, + 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x4d, + 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x73, 0x4d, 0x65, 0x6d, 0x62, 0x65, + 0x72, 0x50, 0x6f, 0x72, 0x74, 0x4c, 0x6f, 0x6f, 0x70, 0x62, 0x61, 0x63, 0x6b, 0x4d, 0x6f, 0x64, + 0x65, 0x12, 0x4f, 0x0a, 0x24, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x70, + 0x75, 0x5f, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, + 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x62, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x21, 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x43, 0x70, 0x75, 0x55, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x12, 0x45, 0x0a, 0x1f, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x5f, 0x64, 0x72, 0x6f, - 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x65, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x66, 0x61, 0x62, - 0x72, 0x69, 0x63, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x55, 0x6e, - 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x55, 0x0a, 0x27, 0x6c, 0x69, 0x6e, - 0x65, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x75, 0x74, 0x69, - 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x18, 0x66, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x6c, 0x69, 0x6e, 0x65, - 0x63, 0x61, 0x72, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x74, 0x69, 0x6c, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x12, 0x46, 0x0a, 0x20, 0x71, 0x6f, 0x73, 0x5f, 0x76, 0x6f, 0x71, 0x5f, 0x64, 0x72, 0x6f, 0x70, - 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x18, 0x67, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x71, 0x6f, 0x73, 0x56, - 0x6f, 0x71, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x55, 0x6e, 0x73, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x1f, 0x61, 0x74, 0x65, 0x5f, - 0x69, 0x70, 0x76, 0x36, 0x5f, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x68, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x1b, 0x61, 0x74, 0x65, 0x49, 0x70, 0x76, 0x36, 0x46, 0x6c, 0x6f, 0x77, 0x4c, 0x61, - 0x62, 0x65, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x50, - 0x0a, 0x25, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x5f, 0x63, 0x73, - 0x6e, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x75, 0x6e, 0x73, 0x75, - 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x69, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x69, - 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x43, 0x73, 0x6e, 0x70, 0x49, 0x6e, 0x74, - 0x65, 0x72, 0x76, 0x61, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x12, 0x71, 0x0a, 0x37, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, - 0x5f, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, - 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x72, 0x65, 0x61, 0x73, 0x5f, - 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6a, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x30, 0x69, 0x73, 0x69, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x4d, 0x61, - 0x6e, 0x75, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x44, 0x72, 0x6f, 0x70, 0x46, - 0x72, 0x6f, 0x6d, 0x41, 0x72, 0x65, 0x61, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x25, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, - 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6b, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x21, 0x69, 0x73, 0x69, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x50, - 0x61, 0x72, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, - 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, - 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x1a, 0xa0, 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, - 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, - 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, - 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xc7, 0x01, 0x0a, 0x07, 0x54, - 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, - 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, - 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, - 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, - 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, - 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, - 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, - 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, - 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, - 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, - 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, - 0x4b, 0x53, 0x10, 0x06, 0x22, 0x6d, 0x0a, 0x04, 0x54, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, - 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, - 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, - 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, - 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, - 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, - 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x64, 0x12, 0x53, 0x0a, 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, + 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x63, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x23, 0x63, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x43, 0x6f, + 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x55, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x5c, 0x0a, 0x2b, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x75, + 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x64, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x43, 0x61, 0x72, 0x64, 0x43, 0x70, 0x75, 0x55, + 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, + 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x45, 0x0a, 0x1f, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x5f, + 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x65, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, + 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, + 0x72, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x55, 0x0a, 0x27, + 0x6c, 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, + 0x75, 0x74, 0x69, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x66, 0x20, 0x01, 0x28, 0x08, 0x52, 0x24, 0x6c, + 0x69, 0x6e, 0x65, 0x63, 0x61, 0x72, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x74, 0x69, + 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x20, 0x71, 0x6f, 0x73, 0x5f, 0x76, 0x6f, 0x71, 0x5f, 0x64, + 0x72, 0x6f, 0x70, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x75, 0x6e, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x67, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1c, 0x71, + 0x6f, 0x73, 0x56, 0x6f, 0x71, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, + 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x1f, 0x61, + 0x74, 0x65, 0x5f, 0x69, 0x70, 0x76, 0x36, 0x5f, 0x66, 0x6c, 0x6f, 0x77, 0x5f, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x68, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x61, 0x74, 0x65, 0x49, 0x70, 0x76, 0x36, 0x46, 0x6c, 0x6f, + 0x77, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x12, 0x50, 0x0a, 0x25, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x73, + 0x5f, 0x63, 0x73, 0x6e, 0x70, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x75, + 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x69, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x21, 0x69, 0x73, 0x69, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x73, 0x43, 0x73, 0x6e, 0x70, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x55, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x12, 0x71, 0x0a, 0x37, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x65, 0x72, 0x5f, 0x6d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x5f, 0x64, 0x72, 0x6f, 0x70, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x61, 0x72, 0x65, + 0x61, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6a, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x30, 0x69, 0x73, 0x69, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, + 0x72, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x44, 0x72, + 0x6f, 0x70, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x72, 0x65, 0x61, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x50, 0x0a, 0x25, 0x69, 0x73, 0x69, 0x73, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, + 0x6b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x21, 0x69, 0x73, 0x69, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x65, 0x72, 0x50, 0x61, 0x72, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x55, 0x6e, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x12, 0x4c, 0x0a, 0x22, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, + 0x64, 0x73, 0x5f, 0x75, 0x6e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x18, 0x6c, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x72, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x73, 0x55, 0x6e, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, + 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x1a, 0xa0, + 0x01, 0x0a, 0x12, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x45, 0x78, 0x63, 0x65, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, + 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, + 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x47, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, + 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, + 0x67, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0xc7, 0x01, 0x0a, 0x07, 0x54, 0x65, 0x73, 0x74, 0x62, 0x65, 0x64, 0x12, 0x17, 0x0a, + 0x13, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, + 0x44, 0x5f, 0x44, 0x55, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, + 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, + 0x53, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, + 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x03, 0x12, + 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, + 0x54, 0x45, 0x5f, 0x34, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, + 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x39, + 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x5f, 0x4c, 0x41, 0x47, 0x10, 0x05, 0x12, 0x1e, 0x0a, 0x1a, 0x54, + 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, + 0x54, 0x45, 0x5f, 0x32, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x06, 0x22, 0x6d, 0x0a, 0x04, 0x54, + 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x41, 0x47, + 0x53, 0x5f, 0x41, 0x47, 0x47, 0x52, 0x45, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, + 0x18, 0x0a, 0x14, 0x54, 0x41, 0x47, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x43, 0x45, 0x4e, 0x54, + 0x45, 0x52, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x41, 0x47, + 0x53, 0x5f, 0x45, 0x44, 0x47, 0x45, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x41, 0x47, 0x53, + 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x10, 0x04, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( From bb9ce4aa585f5cfcefc17cd103332536310241af Mon Sep 17 00:00:00 2001 From: cprabha Date: Thu, 14 Sep 2023 23:39:34 -0700 Subject: [PATCH 36/43] RT-1.23 BGP AFI-SAFI OC Defaults (#2082) * Initial commit for RT-1.23 * updated metadata * Update bgp_afi_safi_defaults_test.go * Update metadata.textproto --------- Co-authored-by: Arul Kumar Sekar <128646204+arulkumarsekar@users.noreply.github.com> Co-authored-by: sachendras <44847441+sachendras@users.noreply.github.com> --- .../otg_tests/bgp_afi_safi_defaults/README.md | 110 +++++ .../bgp_afi_safi_defaults_test.go | 406 ++++++++++++++++++ .../bgp_afi_safi_defaults/metadata.textproto | 35 ++ 3 files changed, 551 insertions(+) create mode 100644 feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/README.md create mode 100644 feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go create mode 100644 feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/metadata.textproto diff --git a/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/README.md b/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/README.md new file mode 100644 index 00000000000..b82f7c4bc20 --- /dev/null +++ b/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/README.md @@ -0,0 +1,110 @@ +# RT-1.23: BGP AFI SAFI OC DEFAULTS + +## Summary + +BGP AFI SAFI OC DEFAULTS TEST + +## Procedure + +* When operating in "openconfig mode", NOS (network operating system) defaults should match what OC + defines as the defaults i.e, +* For BGP, there are no defaults for AFI-SAFI at the neighbor and peer-group levels. However at the + global level the default is "false" +* This test currently only verifies the defaults for ipv4-unicast and ipv6-unicast families. + However, this test can be extended further to cover for other AFI-SAFIs as well in future. +* The test will check for default implementations under the neighbor and peer-group hierarchies and + also test for inheritance rules as was specified in [pull/774](https://github.com/openconfig/public/pull/774) and [pull/815](https://github.com/openconfig/public/pull/815). + + +* Topology: + * ATE (Port1) <-EBGP-> (Port1) DUT (Port2) <-IBGP-> (Port2) ATE + * Connect ATE Port1 to DUT port1 (EBGP peering) + * Connect ATE Port2 to DUT port2 (IBGP peering) + +* [Test case-1] AFI-SAFI configurations at "neighbor level": + + * Push EBGP and IBGP OC configuration to the DUT + * Configuration should include corresponding IPv4 and IPv6 neighbor configurations. + * Ensure that only IPv4-Unicast enabled boolean is made "true" for IPv4 neighbor. + "IPv6-unicast enabled" boolean is left to OC default for the IPv4 peer". + * Ensure that only IPv6-Unicast enabled boolean is made "true" for IPv6 neighbor. + "IPv4-unicast enabled" boolean is left to OC default for the IPv6 peer". + * Ensure that there are no AFI-SAFI configurations at the global and peer-group levels. + * On the ATE side ensure that IPv4-unicast and IPv6-unicast AFI-SAFI are enabled==true for + IPv4 and IPv6 neighbors. + + * Verification: + * For IPv4 neighbor, ensure that the IPv4 neighborship is up and IPv6-unicast capability is + not negotiated. + * For IPv6 neighbor ensure that the IPv6 neighborship is up and IPv4-unicast capability is + not negotiated. + +* [Test case-2] IPv4-unicast and IPv6-Unicast AFI-SAFIs enabled at peer-group level: + + * Configuration at the neighbor level is same as in [Test case-1] except for IPv4-unicast and + IPv6-unicast being enabled at the peer-group level + * No configuration should be made at the global AFI-SAFI level + + * Verification: + * For IPv4 neighbor, ensure that the IPv4 neighborship is up and both IPv4-unicast and + IPv6-unicast capabilities are negotiated. + * For IPv6 neighbor ensure that the IPv6 neighborship is up and both IPv4-unicast and + IPv6-unicast capabilities are negotiated. + + +* [Test case-3] IPv4-unicast and IPv6-Unicast AFI-SAFIs enabled at Global level: + + * Configuration at the neighbor level is same as in [Test case-1] except for IPv4-unicast and + IPv6-unicast being enabled at the global level + * No configuration should be made at the peer-group AFI-SAFI level + + * Verification: + * For IPv4 neighbor, ensure that the IPv4 neighborship is up and both IPv4-unicast and + IPv6-unicast capabilities are negotiated. + * For IPv6 neighbor ensure that the IPv6 neighborship is up and both IPv4-unicast and + IPv6-unicast capabilities are negotiated. + +## Config Parameter coverage + +* /network-instances/network-instance/protocols/protocol/bgp/global/config/as +* /network-instances/network-instance/protocols/protocol/bgp/global/config/router-id +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/auth-password +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/ + neighbor-address +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/peer-as +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/neighbor-address +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/ + config/enabled +* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config/ + auth-password +* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config/ + neighbor-address +* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config/peer-as +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/config/peer-group/ + peer-group-name +* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/afi-safis/ + afi-safi/config/enabled +* /network-instances/network-instance/protocols/protocol/bgp/global/afi-safis/afi-safi/config/enabled + + +## Telemetry Parameter coverage + +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/session-state +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/ + supported-capabilities +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/peer-type +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/peer-as +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/ + supported-capabilities +* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/state/peer-type +* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/state/peer-as +* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/state/local-as +* /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/state/peer-group + +## Protocol/RPC Parameter coverage + +N/A + +## Minimum DUT platform requirement + +N/A diff --git a/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go b/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go new file mode 100644 index 00000000000..572343caf54 --- /dev/null +++ b/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go @@ -0,0 +1,406 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bgp_afi_safi_defaults_test + +import ( + "testing" + "time" + + "github.com/open-traffic-generator/snappi/gosnappi" + "github.com/openconfig/featureprofiles/internal/attrs" + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ondatra/gnmi/oc/netinstbgp" + otgtelemetry "github.com/openconfig/ondatra/gnmi/otg" + otg "github.com/openconfig/ondatra/otg" + "github.com/openconfig/ygnmi/ygnmi" + "github.com/openconfig/ygot/ygot" +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +const ( + trafficDuration = 1 * time.Minute + ipv4SrcTraffic = "192.0.2.2" + advertisedRoutesv4CIDR = "203.0.113.1/32" + advertisedRoutesv4Net = "203.0.113.1" + advertisedRoutesv4Prefix = 32 + ipv4DstTrafficStart = "203.0.113.1" + ipv4DstTrafficEnd = "203.0.113.254" + peerGrpName1 = "BGP-PEER-GROUP1" + peerGrpName2 = "BGP-PEER-GROUP2" + tolerancePct = 2 + tolerance = 50 + routeCount = 254 + dutAS = 65501 + ateAS = 65502 + plenIPv4 = 30 + plenIPv6 = 126 + nbrLevel = "NEIGHBOR" + peerGrpLevel = "PEER-GROUP" + globalLevel = "GLOBAL" +) + +var ( + dutPort1 = attrs.Attributes{ + Desc: "DUT to ATE Port1", + IPv4: "192.0.2.1", + IPv6: "2001:db8::192:0:2:1", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + atePort1 = attrs.Attributes{ + Name: "atePort1", + IPv4: "192.0.2.2", + IPv6: "2001:db8::192:0:2:2", + MAC: "02:00:01:01:01:01", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + dutPort2 = attrs.Attributes{ + Desc: "DUT to ATE Port2", + IPv4: "192.0.2.5", + IPv6: "2001:db8::192:0:2:5", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + atePort2 = attrs.Attributes{ + Name: "atePort2", + IPv4: "192.0.2.6", + IPv6: "2001:db8::192:0:2:6", + MAC: "02:00:02:01:01:01", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + + nbr1 = &bgpNeighbor{as: ateAS, neighborip: atePort1.IPv4, isV4: true, peerGrp: peerGrpName1} + nbr2 = &bgpNeighbor{as: ateAS, neighborip: atePort1.IPv6, isV4: false, peerGrp: peerGrpName2} + nbr3 = &bgpNeighbor{as: dutAS, neighborip: atePort2.IPv4, isV4: true, peerGrp: peerGrpName1} + nbr4 = &bgpNeighbor{as: dutAS, neighborip: atePort2.IPv6, isV4: false, peerGrp: peerGrpName2} +) + +// configureDUT configures all the interfaces on the DUT. +func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + dc := gnmi.OC() + i1 := dutPort1.NewOCInterface(dut.Port(t, "port1").Name(), dut) + gnmi.Replace(t, dut, dc.Interface(i1.GetName()).Config(), i1) + + i2 := dutPort2.NewOCInterface(dut.Port(t, "port2").Name(), dut) + gnmi.Replace(t, dut, dc.Interface(i2.GetName()).Config(), i2) +} + +// verifyPortsUp asserts that each port on the device is operating. +func verifyPortsUp(t *testing.T, dev *ondatra.Device) { + t.Helper() + for _, p := range dev.Ports() { + status := gnmi.Get(t, dev, gnmi.OC().Interface(p.Name()).OperStatus().State()) + if want := oc.Interface_OperStatus_UP; status != want { + t.Errorf("%s Status: got %v, want %v", p, status, want) + } + } +} + +// bgpCreateNbr creates a BGP object with neighbors pointing to ateSrc and ateDst. +func bgpCreateNbr(t *testing.T, localAs, peerAs uint32, dut *ondatra.DUTDevice, afiSafiLevel string) *oc.NetworkInstance_Protocol { + t.Helper() + nbrs := []*bgpNeighbor{nbr1, nbr2, nbr3, nbr4} + dutOcRoot := &oc.Root{} + ni1 := dutOcRoot.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := ni_proto.GetOrCreateBgp() + global := bgp.GetOrCreateGlobal() + global.RouterId = ygot.String(dutPort2.IPv4) + global.As = ygot.Uint32(localAs) + + // Note: we have to define the peer group even if we aren't setting any policy because it's + // invalid OC for the neighbor to be part of a peer group that doesn't exist. + pg1 := bgp.GetOrCreatePeerGroup(peerGrpName1) // V4 peer group + pg1.PeerAs = ygot.Uint32(ateAS) + pg1.PeerGroupName = ygot.String(peerGrpName1) + + pg2 := bgp.GetOrCreatePeerGroup(peerGrpName2) // V6 peer group + pg2.PeerAs = ygot.Uint32(dutAS) + pg2.PeerGroupName = ygot.String(peerGrpName2) + + for _, nbr := range nbrs { + nv4 := bgp.GetOrCreateNeighbor(nbr.neighborip) + nv4.PeerGroup = ygot.String(nbr.peerGrp) + nv4.PeerAs = ygot.Uint32(nbr.as) + nv4.Enabled = ygot.Bool(true) + + switch afiSafiLevel { + case globalLevel: + global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + extNh := global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).GetOrCreateIpv4Unicast() + extNh.ExtendedNextHopEncoding = ygot.Bool(true) + case nbrLevel: + if nbr.isV4 == true { + af4 := nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + af4.Enabled = ygot.Bool(true) + } else { + af6 := nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + af6.Enabled = ygot.Bool(true) + } + case peerGrpLevel: + pg1af4 := pg1.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + pg1af4.Enabled = ygot.Bool(true) + ext1Nh := pg1af4.GetOrCreateIpv4Unicast() + ext1Nh.ExtendedNextHopEncoding = ygot.Bool(true) + pg1af6 := pg1.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + pg1af6.Enabled = ygot.Bool(true) + + pg2af4 := pg2.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + pg2af4.Enabled = ygot.Bool(true) + ext2Nh := pg2af4.GetOrCreateIpv4Unicast() + ext2Nh.ExtendedNextHopEncoding = ygot.Bool(true) + pg2af6 := pg2.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + pg2af6.Enabled = ygot.Bool(true) + } + } + return ni_proto +} + +func verifyOtgBgpTelemetry(t *testing.T, otg *otg.OTG, c gosnappi.Config, state string) { + t.Helper() + for _, d := range c.Devices().Items() { + for _, ip := range d.Bgp().Ipv4Interfaces().Items() { + for _, configPeer := range ip.Peers().Items() { + nbrPath := gnmi.OTG().BgpPeer(configPeer.Name()) + _, ok := gnmi.Watch(t, otg, nbrPath.SessionState().State(), time.Minute, func(val *ygnmi.Value[otgtelemetry.E_BgpPeer_SessionState]) bool { + currState, ok := val.Val() + return ok && currState.String() == state + }).Await(t) + if !ok { + t.Errorf("No BGP neighbor formed for peer %s", configPeer.Name()) + } + } + } + for _, ip := range d.Bgp().Ipv6Interfaces().Items() { + for _, configPeer := range ip.Peers().Items() { + nbrPath := gnmi.OTG().BgpPeer(configPeer.Name()) + _, ok := gnmi.Watch(t, otg, nbrPath.SessionState().State(), time.Minute, func(val *ygnmi.Value[otgtelemetry.E_BgpPeer_SessionState]) bool { + currState, ok := val.Val() + return ok && currState.String() == state + }).Await(t) + if !ok { + t.Errorf("No BGP neighbor formed for peer %s", configPeer.Name()) + } + } + } + } +} + +// verifyBgpTelemetry checks that the dut has an established BGP session with reasonable settings. +func verifyBgpTelemetry(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + var nbrIP = []string{atePort1.IPv4, atePort2.IPv4, atePort1.IPv6, atePort2.IPv6} + t.Logf("Verifying BGP state.") + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + + for _, nbr := range nbrIP { + nbrPath := bgpPath.Neighbor(nbr) + // Get BGP adjacency state. + t.Logf("Waiting for BGP neighbor to establish...") + status, ok := gnmi.Watch(t, dut, nbrPath.SessionState().State(), time.Minute, func(val *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState]) bool { + state, ok := val.Val() + return ok && state == oc.Bgp_Neighbor_SessionState_ESTABLISHED + }).Await(t) + if !ok { + t.Fatal("No BGP neighbor formed") + } + state, _ := status.Val() + t.Logf("BGP adjacency for %s: %v", nbr, state) + if want := oc.Bgp_Neighbor_SessionState_ESTABLISHED; state != want { + t.Errorf("BGP peer %s status got %d, want %d", nbr, state, want) + } + } +} + +// configureOTG configures the interfaces and BGP protocols on an ATE, including +// advertising some(faked) networks over BGP. +func configureOTG(t *testing.T, otg *otg.OTG) gosnappi.Config { + t.Helper() + config := otg.NewConfig(t) + port1 := config.Ports().Add().SetName("port1") + port2 := config.Ports().Add().SetName("port2") + + iDut1Dev := config.Devices().Add().SetName(atePort1.Name) + iDut1Eth := iDut1Dev.Ethernets().Add().SetName(atePort1.Name + ".Eth").SetMac(atePort1.MAC) + iDut1Eth.Connection().SetChoice(gosnappi.EthernetConnectionChoice.PORT_NAME).SetPortName(port1.Name()) + iDut1Ipv4 := iDut1Eth.Ipv4Addresses().Add().SetName(atePort1.Name + ".IPv4") + iDut1Ipv4.SetAddress(atePort1.IPv4).SetGateway(dutPort1.IPv4).SetPrefix(uint32(atePort1.IPv4Len)) + iDut1Ipv6 := iDut1Eth.Ipv6Addresses().Add().SetName(atePort1.Name + ".IPv6") + iDut1Ipv6.SetAddress(atePort1.IPv6).SetGateway(dutPort1.IPv6).SetPrefix(uint32(atePort1.IPv6Len)) + + iDut2Dev := config.Devices().Add().SetName(atePort2.Name) + iDut2Eth := iDut2Dev.Ethernets().Add().SetName(atePort2.Name + ".Eth").SetMac(atePort2.MAC) + iDut2Eth.Connection().SetChoice(gosnappi.EthernetConnectionChoice.PORT_NAME).SetPortName(port2.Name()) + iDut2Ipv4 := iDut2Eth.Ipv4Addresses().Add().SetName(atePort2.Name + ".IPv4") + iDut2Ipv4.SetAddress(atePort2.IPv4).SetGateway(dutPort2.IPv4).SetPrefix(uint32(atePort2.IPv4Len)) + iDut2Ipv6 := iDut2Eth.Ipv6Addresses().Add().SetName(atePort2.Name + ".IPv6") + iDut2Ipv6.SetAddress(atePort2.IPv6).SetGateway(dutPort2.IPv6).SetPrefix(uint32(atePort2.IPv6Len)) + + // BGP seesion + iDut1Bgp := iDut1Dev.Bgp().SetRouterId(iDut1Ipv4.Address()) + iDut1Bgp4Peer := iDut1Bgp.Ipv4Interfaces().Add().SetIpv4Name(iDut1Ipv4.Name()).Peers().Add().SetName(atePort1.Name + ".BGP4.peer") + iDut1Bgp4Peer.SetPeerAddress(iDut1Ipv4.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + iDut1Bgp4Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) + iDut1Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + + iDut1Bgp6Peer := iDut1Bgp.Ipv6Interfaces().Add().SetIpv6Name(iDut1Ipv6.Name()).Peers().Add().SetName(atePort1.Name + ".BGP6.peer") + iDut1Bgp6Peer.SetPeerAddress(iDut1Ipv6.Gateway()).SetAsNumber(ateAS).SetAsType(gosnappi.BgpV6PeerAsType.EBGP) + iDut1Bgp6Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) + iDut1Bgp6Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + + iDut2Bgp := iDut2Dev.Bgp().SetRouterId(iDut2Ipv4.Address()) + iDut2Bgp4Peer := iDut2Bgp.Ipv4Interfaces().Add().SetIpv4Name(iDut2Ipv4.Name()).Peers().Add().SetName(atePort2.Name + ".BGP4.peer") + iDut2Bgp4Peer.SetPeerAddress(iDut2Ipv4.Gateway()).SetAsNumber(dutAS).SetAsType(gosnappi.BgpV4PeerAsType.IBGP) + iDut2Bgp4Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) + iDut2Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + + iDut2Bgp6Peer := iDut2Bgp.Ipv6Interfaces().Add().SetIpv6Name(iDut2Ipv6.Name()).Peers().Add().SetName(atePort2.Name + ".BGP6.peer") + iDut2Bgp6Peer.SetPeerAddress(iDut2Ipv6.Gateway()).SetAsNumber(dutAS).SetAsType(gosnappi.BgpV6PeerAsType.IBGP) + iDut2Bgp6Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) + iDut2Bgp6Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + + t.Logf("Pushing config to OTG and starting protocols...") + otg.PushConfig(t, config) + time.Sleep(30 * time.Second) + otg.StartProtocols(t) + time.Sleep(30 * time.Second) + + return config +} + +// verifyBGPCapabilities is used to Verify BGP capabilities like route refresh as32 and mpbgp. +func verifyBgpCapabilities(t *testing.T, dut *ondatra.DUTDevice, afiSafiLevel string) { + t.Helper() + t.Log("Verifying BGP AFI-SAFI capabilities.") + nbrs := []*bgpNeighbor{nbr1, nbr2, nbr3, nbr4} + + statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + var nbrPath *netinstbgp.NetworkInstance_Protocol_Bgp_Neighbor_AfiSafi_AfiSafiNamePathAny + + for _, nbr := range nbrs { + nbrPath = statePath.Neighbor(nbr.neighborip).AfiSafiAny().AfiSafiName() + + capabilities := map[oc.E_BgpTypes_AFI_SAFI_TYPE]bool{ + oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST: false, + oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST: false, + } + + for _, cap := range gnmi.GetAll(t, dut, nbrPath.State()) { + capabilities[cap] = true + } + + switch afiSafiLevel { + case nbrLevel: + if nbr.isV4 && capabilities[oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST] { + t.Errorf("AFI_SAFI_TYPE_IPV6_UNICAST should not be enabled for v4 Peer: %v, %v", capabilities, nbr.neighborip) + } + if !nbr.isV4 && capabilities[oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST] { + t.Errorf("AFI_SAFI_TYPE_IPV4_UNICAST should not be for v6 Peer: %v, %v", capabilities, nbr.neighborip) + } + t.Logf("Capabilities for peer %v are %v", nbr.neighborip, capabilities) + case peerGrpLevel: + if capabilities[oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST] == true && + capabilities[oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST] == true { + t.Logf("Both V4 and V6 AFI-SAFI are inherited from peer-group level for peer: %v, %v", nbr.neighborip, capabilities) + } else { + t.Errorf("Both V4 and V6 AFI-SAFI are not inherited from peer-group level for peer: %v, %v", nbr.neighborip, capabilities) + } + case globalLevel: + if capabilities[oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST] == true && + capabilities[oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST] == true { + t.Logf("Both V4 and V6 AFI-SAFI are inherited from global level for peer: %v, %v", nbr.neighborip, capabilities) + } else { + t.Errorf("Both V4 and V6 AFI-SAFI are not inherited from gloval level for peer: %v, %v", nbr.neighborip, capabilities) + } + } + } +} + +type bgpNeighbor struct { + as uint32 + neighborip string + isV4 bool + peerGrp string +} + +// TestAfiSafiOcDefaults validates AFI-SAFI configuration enabled at neighbor, +// peer group and global levels. +func TestAfiSafiOcDefaults(t *testing.T) { + t.Logf("Start DUT config load.") + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + + t.Run("Configure DUT interfaces", func(t *testing.T) { + configureDUT(t, dut) + }) + + t.Run("Configure DEFAULT network instance", func(t *testing.T) { + dutConfNIPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)) + gnmi.Replace(t, dut, dutConfNIPath.Type().Config(), oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE) + }) + + dutConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + + cases := []struct { + desc string + afiSafiLevel string + }{{ + desc: "Validate AFI-SAFI OC defaults at neighbor level.", + afiSafiLevel: nbrLevel, + }, { + desc: "Validate AFI-SAFI OC defaults at peer group level.", + afiSafiLevel: peerGrpLevel, + }, { + desc: "Validate AFI-SAFI OC defaults at global level", + afiSafiLevel: globalLevel, + }} + for _, tc := range cases { + t.Run(tc.desc, func(t *testing.T) { + t.Run("Configure BGP Neighbors", func(t *testing.T) { + gnmi.Delete(t, dut, dutConfPath.Config()) + dutConf := bgpCreateNbr(t, dutAS, ateAS, dut, tc.afiSafiLevel) + gnmi.Replace(t, dut, dutConfPath.Config(), dutConf) + fptest.LogQuery(t, "DUT BGP Config", dutConfPath.Config(), gnmi.GetConfig(t, dut, dutConfPath.Config())) + }) + + otg := ate.OTG() + var otgConfig gosnappi.Config + t.Run("Configure OTG", func(t *testing.T) { + otgConfig = configureOTG(t, otg) + }) + + t.Run("Verify port status on DUT", func(t *testing.T) { + verifyPortsUp(t, dut.Device) + }) + + t.Run("Verify BGP telemetry", func(t *testing.T) { + verifyBgpTelemetry(t, dut) + verifyOtgBgpTelemetry(t, otg, otgConfig, "ESTABLISHED") + verifyBgpCapabilities(t, dut, tc.afiSafiLevel) + }) + }) + } +} diff --git a/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/metadata.textproto b/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/metadata.textproto new file mode 100644 index 00000000000..08ab58b61ed --- /dev/null +++ b/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/metadata.textproto @@ -0,0 +1,35 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "22bdc706-3dd1-47d7-80d9-58eeb0c14b47" +plan_id: "RT-1.23" +description: "BGP AFI SAFI OC DEFAULTS" +testbed: TESTBED_DUT_ATE_4LINKS +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + ipv4_missing_enabled: true + } +} +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + route_policy_under_afi_unsupported: true + interface_enabled: true + } +} +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + route_policy_under_afi_unsupported: true + omit_l2_mtu: true + interface_enabled: true + default_network_instance: "default" + } +} From 97cd5bbc417ced00bc10827e59ef70113a3ca978 Mon Sep 17 00:00:00 2001 From: KandukuriSudheer <134359848+KandukuriSudheer@users.noreply.github.com> Date: Fri, 15 Sep 2023 12:37:12 +0530 Subject: [PATCH 37/43] fixed the tun1.9 subnet issue (#2088) * fixed the tun1.9 subnet issue * fixing the ip address assignment guidelines --------- Co-authored-by: Arul Kumar Sekar <128646204+arulkumarsekar@users.noreply.github.com> Co-authored-by: sachendras <44847441+sachendras@users.noreply.github.com> --- .../otg_tests/tunnel_acl_based_test/tun_acl_dscp_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/tun_acl_dscp_test.go b/feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/tun_acl_dscp_test.go index cff964de4c2..78af86c65af 100644 --- a/feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/tun_acl_dscp_test.go +++ b/feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/tun_acl_dscp_test.go @@ -62,7 +62,7 @@ func TestMain(m *testing.M) { // which is equivalet to 32 in decimal. const ( - ipv4PrefixLen = 24 + ipv4PrefixLen = 30 pps = 100 FrameSize = 512 aclName = "f1" @@ -229,6 +229,7 @@ func configureOTG(t *testing.T, ate *ondatra.ATEDevice) gosnappi.Config { v4.Priority().Dscp().Phb().SetValue(uint32(dscp)) t.Logf("Pushing config to ATE and starting protocols...") otg.PushConfig(t, topo) + t.Logf("starting protocols...") otg.StartProtocols(t) time.Sleep(30 * time.Second) // otgutils.WaitForARP(t, otg, topo, "IPv4") From e4897c7be5cdf4d735f30f5e95a86a9c14ccfc64 Mon Sep 17 00:00:00 2001 From: cprabha Date: Fri, 15 Sep 2023 00:37:33 -0700 Subject: [PATCH 38/43] =?UTF-8?q?RT-1.11=20-=20BGP=20remove=20private=20AS?= =?UTF-8?q?=C2=A0=20-=20OTG=20test=20(#1853)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * added OTG test for RT-1.11 * added metadata * updated * updated * added deviations to metadata * Update bgp_remove_private_as_otg_test.go updated int32 to uint32 * Addressing review comments * Updated README * Updated README * Update metadata.textproto * Adressing review comments --------- Co-authored-by: Arul Kumar Sekar <128646204+arulkumarsekar@users.noreply.github.com> --- .../otg_tests/bgp_remove_private_as/README.md | 35 ++ .../bgp_remove_private_as_test.go | 454 ++++++++++++++++++ .../bgp_remove_private_as/metadata.textproto | 26 + 3 files changed, 515 insertions(+) create mode 100644 feature/experimental/bgp/otg_tests/bgp_remove_private_as/README.md create mode 100644 feature/experimental/bgp/otg_tests/bgp_remove_private_as/bgp_remove_private_as_test.go create mode 100644 feature/experimental/bgp/otg_tests/bgp_remove_private_as/metadata.textproto diff --git a/feature/experimental/bgp/otg_tests/bgp_remove_private_as/README.md b/feature/experimental/bgp/otg_tests/bgp_remove_private_as/README.md new file mode 100644 index 00000000000..6a5ce3e8a52 --- /dev/null +++ b/feature/experimental/bgp/otg_tests/bgp_remove_private_as/README.md @@ -0,0 +1,35 @@ +# RT-1.11: BGP remove private ASĀ  + +## Summary + +BGP remove private AS + +## Procedure + +* Establish BGP sessions as follows between ATE and DUT. +* ATE port 1 emulates two eBGP neighbors peering the DUT. +* eBGP neighbor # 1 is injecting routes with AS_PATH modified to have private AS numbers. +* Validate that private AS numbers are stripped before advertisement to the eBGP neighbor on ATE + port 2. +* Tested AS-Path Patterns: + * PRIV_AS1 + * PRIV_AS1 PRIV_AS2 + * AS1 PRIV_AS1 PRIV_AS2 + * PRIV_AS1 AS1 + * AS1 PRIV_AS1 AS2 + +## Config Parameter coverage + +* /network-instances/network-instance/protocols/protocol/bgp/peer-groups/peer-group/config/remove-private-as + +## Telemetry Parameter coverage + +* /network-instances/network-instance/protocols/protocol/bgp/rib/attr-sets/attr-set/as4-path/as4-segment/state + +## Protocol/RPC Parameter coverage + +N/A + +## Minimum DUT platform requirement + +N/A \ No newline at end of file diff --git a/feature/experimental/bgp/otg_tests/bgp_remove_private_as/bgp_remove_private_as_test.go b/feature/experimental/bgp/otg_tests/bgp_remove_private_as/bgp_remove_private_as_test.go new file mode 100644 index 00000000000..4556cc49dba --- /dev/null +++ b/feature/experimental/bgp/otg_tests/bgp_remove_private_as/bgp_remove_private_as_test.go @@ -0,0 +1,454 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bgp_remove_private_as_test + +import ( + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/open-traffic-generator/snappi/gosnappi" + "github.com/openconfig/featureprofiles/internal/attrs" + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + otgtelemetry "github.com/openconfig/ondatra/gnmi/otg" + "github.com/openconfig/ondatra/otg" + "github.com/openconfig/ygnmi/ygnmi" + "github.com/openconfig/ygot/ygot" +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +// The testbed consists of ate:port1 -> dut:port1 and +// dut:port2 -> ate:port2. The first pair is called the "source" +// pair, and the second the "destination" pair. +// +// Source: ate:port1 -> dut:port1 subnet 192.0.2.0/30 +// Destination: dut:port2 -> ate:port2 subnet 192.0.2.4/30 +// +// Note that the first (.0, .3) and last (.4, .7) IPv4 addresses are +// reserved from the subnet for broadcast, so a /30 leaves exactly 2 +// usable addresses. This does not apply to IPv6 which allows /127 +// for point to point links, but we use /126 so the numbering is +// consistent with IPv4. + +const ( + advertisedRoutesv4Net = "203.0.113.1" + advertisedRoutesv4Prefix = 32 + peerGrpName1 = "BGP-PEER-GROUP1" + peerGrpName2 = "BGP-PEER-GROUP2" + routeCount = 254 + dutAS = 500 + ateAS1 = 100 + ateAS2 = 200 + plenIPv4 = 30 + plenIPv6 = 126 + removeASPath = true + policyName = "ALLOW" +) + +var ( + dutSrc = attrs.Attributes{ + Desc: "DUT to ATE source", + IPv4: "192.0.2.1", + IPv6: "2001:db8::192:0:2:1", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + ateSrc = attrs.Attributes{ + Name: "ateSrc", + IPv4: "192.0.2.2", + IPv6: "2001:db8::192:0:2:2", + MAC: "02:00:01:01:01:01", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + dutDst = attrs.Attributes{ + Desc: "DUT to ATE destination", + IPv4: "192.0.2.5", + IPv6: "2001:db8::192:0:2:5", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } + ateDst = attrs.Attributes{ + Name: "ateDst", + IPv4: "192.0.2.6", + IPv6: "2001:db8::192:0:2:6", + MAC: "02:00:02:01:01:01", + IPv4Len: plenIPv4, + IPv6Len: plenIPv6, + } +) + +// configreRoutePolicy adds route-policy config. +func configureRoutePolicy(t *testing.T, dut *ondatra.DUTDevice, name string, pr oc.E_RoutingPolicy_PolicyResultType) { + d := &oc.Root{} + rp := d.GetOrCreateRoutingPolicy() + pd := rp.GetOrCreatePolicyDefinition(name) + st, err := pd.AppendNewStatement("id-1") + if err != nil { + t.Fatal(err) + } + stc := st.GetOrCreateConditions() + stc.InstallProtocolEq = oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP + st.GetOrCreateActions().PolicyResult = pr + gnmi.Replace(t, dut, gnmi.OC().RoutingPolicy().Config(), rp) +} + +// configureDUT configures all the interfaces on the DUT. +func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + dc := gnmi.OC() + i1 := dutSrc.NewOCInterface(dut.Port(t, "port1").Name(), dut) + gnmi.Replace(t, dut, dc.Interface(i1.GetName()).Config(), i1) + + i2 := dutDst.NewOCInterface(dut.Port(t, "port2").Name(), dut) + gnmi.Replace(t, dut, dc.Interface(i2.GetName()).Config(), i2) +} + +// verifyPortsUp asserts that each port on the device is operating. +func verifyPortsUp(t *testing.T, dev *ondatra.Device) { + t.Helper() + for _, p := range dev.Ports() { + status := gnmi.Get(t, dev, gnmi.OC().Interface(p.Name()).OperStatus().State()) + if want := oc.Interface_OperStatus_UP; status != want { + t.Errorf("%s Status: got %v, want %v", p, status, want) + } + } +} + +// bgpCreateNbr creates a BGP object with neighbors pointing to ateSrc and ateDst. +func bgpCreateNbr(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { + nbr1v4 := &bgpNeighbor{as: ateAS1, neighborip: ateSrc.IPv4, isV4: true, peerGrp: peerGrpName1} + nbr2v4 := &bgpNeighbor{as: ateAS2, neighborip: ateDst.IPv4, isV4: true, peerGrp: peerGrpName2} + nbrs := []*bgpNeighbor{nbr1v4, nbr2v4} + + d := &oc.Root{} + ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := ni_proto.GetOrCreateBgp() + global := bgp.GetOrCreateGlobal() + global.RouterId = ygot.String(dutDst.IPv4) + global.As = ygot.Uint32(localAs) + global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + + // Note: we have to define the peer group even if we aren't setting any policy because it's + // invalid OC for the neighbor to be part of a peer group that doesn't exist. + pg1 := bgp.GetOrCreatePeerGroup(peerGrpName1) + pg1.PeerAs = ygot.Uint32(ateAS1) + pg1.PeerGroupName = ygot.String(peerGrpName1) + + pg2 := bgp.GetOrCreatePeerGroup(peerGrpName2) + pg2.PeerAs = ygot.Uint32(ateAS2) + pg2.PeerGroupName = ygot.String(peerGrpName2) + + if deviations.RoutePolicyUnderAFIUnsupported(dut) { + rpl := pg1.GetOrCreateApplyPolicy() + rpl.ImportPolicy = []string{policyName} + rpl.ExportPolicy = []string{policyName} + + rp2 := pg2.GetOrCreateApplyPolicy() + rp2.ImportPolicy = []string{policyName} + rp2.ExportPolicy = []string{policyName} + } else { + pgaf := pg1.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + pgaf.Enabled = ygot.Bool(true) + rpl := pgaf.GetOrCreateApplyPolicy() + rpl.ImportPolicy = []string{policyName} + rpl.ExportPolicy = []string{policyName} + + pgaf2 := pg2.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + pgaf2.Enabled = ygot.Bool(true) + rp2 := pgaf2.GetOrCreateApplyPolicy() + rp2.ImportPolicy = []string{policyName} + rp2.ExportPolicy = []string{policyName} + } + + for _, nbr := range nbrs { + nv4 := bgp.GetOrCreateNeighbor(nbr.neighborip) + nv4.PeerGroup = ygot.String(nbr.peerGrp) + nv4.PeerAs = ygot.Uint32(nbr.as) + nv4.Enabled = ygot.Bool(true) + af4 := nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + af4.Enabled = ygot.Bool(true) + af6 := nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + af6.Enabled = ygot.Bool(false) + } + return ni_proto +} + +// verifyBGPTelemetry checks that the dut has an established BGP session with reasonable settings. +func verifyBGPTelemetry(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + var nbrIP = []string{ateSrc.IPv4, ateDst.IPv4} + t.Logf("Verifying BGP state.") + statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + for _, nbr := range nbrIP { + var status *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState] + nbrPath := statePath.Neighbor(nbr) + t.Logf("Waiting for BGP neighbor to establish...") + status, ok := gnmi.Watch(t, dut, nbrPath.SessionState().State(), time.Minute, func(val *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState]) bool { + state, ok := val.Val() + return ok && state == oc.Bgp_Neighbor_SessionState_ESTABLISHED + }).Await(t) + if !ok { + t.Fatal("No BGP neighbor formed") + } + state, _ := status.Val() + t.Logf("BGP adjacency for %s: %s", nbr, state) + if want := oc.Bgp_Neighbor_SessionState_ESTABLISHED; state != want { + t.Errorf("BGP peer %s status got %v, want %d", nbr, status, want) + } + } +} + +// verifyPrefixesTelemetry confirms that the dut shows the correct numbers of installed, +// sent and received IPv4 prefixes. +func verifyPrefixesTelemetry(t *testing.T, dut *ondatra.DUTDevice, nbr string, wantInstalled, wantSent uint32) { + t.Helper() + statePath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + prefixesv4 := statePath.Neighbor(nbr).AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Prefixes() + if gotInstalled := gnmi.Get(t, dut, prefixesv4.Installed().State()); gotInstalled != wantInstalled { + t.Errorf("Installed prefixes mismatch: got %v, want %v", gotInstalled, wantInstalled) + } + if gotSent := gnmi.Get(t, dut, prefixesv4.Sent().State()); gotSent != wantSent { + t.Errorf("Sent prefixes mismatch: got %v, want %v", gotSent, wantSent) + } +} + +// configureOTG configures the interfaces and BGP protocols on an ATE, including +// advertising some(faked) networks over BGP. +func configureOTG(t *testing.T, otg *otg.OTG, asSeg []uint32, asSEQMode bool) gosnappi.Config { + t.Helper() + config := otg.NewConfig(t) + port1 := config.Ports().Add().SetName("port1") + port2 := config.Ports().Add().SetName("port2") + + iDut1Dev := config.Devices().Add().SetName(ateSrc.Name) + iDut1Eth := iDut1Dev.Ethernets().Add().SetName(ateSrc.Name + ".Eth").SetMac(ateSrc.MAC) + iDut1Eth.Connection().SetChoice(gosnappi.EthernetConnectionChoice.PORT_NAME).SetPortName(port1.Name()) + iDut1Ipv4 := iDut1Eth.Ipv4Addresses().Add().SetName(ateSrc.Name + ".IPv4") + iDut1Ipv4.SetAddress(ateSrc.IPv4).SetGateway(dutSrc.IPv4).SetPrefix(uint32(ateSrc.IPv4Len)) + iDut1Ipv6 := iDut1Eth.Ipv6Addresses().Add().SetName(ateSrc.Name + ".IPv6") + iDut1Ipv6.SetAddress(ateSrc.IPv6).SetGateway(dutSrc.IPv6).SetPrefix(uint32(ateSrc.IPv6Len)) + + iDut2Dev := config.Devices().Add().SetName(ateDst.Name) + iDut2Eth := iDut2Dev.Ethernets().Add().SetName(ateDst.Name + ".Eth").SetMac(ateDst.MAC) + iDut2Eth.Connection().SetChoice(gosnappi.EthernetConnectionChoice.PORT_NAME).SetPortName(port2.Name()) + iDut2Ipv4 := iDut2Eth.Ipv4Addresses().Add().SetName(ateDst.Name + ".IPv4") + iDut2Ipv4.SetAddress(ateDst.IPv4).SetGateway(dutDst.IPv4).SetPrefix(uint32(ateDst.IPv4Len)) + iDut2Ipv6 := iDut2Eth.Ipv6Addresses().Add().SetName(ateDst.Name + ".IPv6") + iDut2Ipv6.SetAddress(ateDst.IPv6).SetGateway(dutDst.IPv6).SetPrefix(uint32(ateDst.IPv6Len)) + + iDut1Bgp := iDut1Dev.Bgp().SetRouterId(iDut1Ipv4.Address()) + iDut1Bgp4Peer := iDut1Bgp.Ipv4Interfaces().Add().SetIpv4Name(iDut1Ipv4.Name()).Peers().Add().SetName(ateSrc.Name + ".BGP4.peer") + iDut1Bgp4Peer.SetPeerAddress(dutSrc.IPv4).SetAsNumber(ateAS1).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + iDut1Bgp4Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) + iDut1Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + + iDut2Bgp := iDut2Dev.Bgp().SetRouterId(iDut2Ipv4.Address()) + iDut2Bgp4Peer := iDut2Bgp.Ipv4Interfaces().Add().SetIpv4Name(iDut2Ipv4.Name()).Peers().Add().SetName(ateDst.Name + ".BGP4.peer") + iDut2Bgp4Peer.SetPeerAddress(dutDst.IPv4).SetAsNumber(ateAS2).SetAsType(gosnappi.BgpV4PeerAsType.EBGP) + iDut2Bgp4Peer.Capability().SetIpv4UnicastAddPath(true).SetIpv6UnicastAddPath(true) + iDut2Bgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(true) + + bgpNeti1Bgp4PeerRoutes := iDut1Bgp4Peer.V4Routes().Add().SetName(ateSrc.Name + ".BGP4.Route") + bgpNeti1Bgp4PeerRoutes.SetNextHopIpv4Address(iDut1Ipv4.Address()). + SetNextHopAddressType(gosnappi.BgpV4RouteRangeNextHopAddressType.IPV4). + SetNextHopMode(gosnappi.BgpV4RouteRangeNextHopMode.MANUAL) + bgpNeti1Bgp4PeerRoutes.Addresses().Add(). + SetAddress(advertisedRoutesv4Net). + SetPrefix(uint32(advertisedRoutesv4Prefix)). + SetCount(routeCount) + + bgpNeti1AsPath := bgpNeti1Bgp4PeerRoutes.AsPath().SetAsSetMode(gosnappi.BgpAsPathAsSetMode.INCLUDE_AS_SET) + + if asSEQMode { + bgpNeti1AsPath.Segments().Add().SetAsNumbers(asSeg).SetType(gosnappi.BgpAsPathSegmentType.AS_SEQ) + } else { + bgpNeti1AsPath.Segments().Add().SetAsNumbers(asSeg).SetType(gosnappi.BgpAsPathSegmentType.AS_SET) + } + + t.Logf("Pushing config to ATE and starting protocols...") + otg.PushConfig(t, config) + time.Sleep(30 * time.Second) + otg.StartProtocols(t) + time.Sleep(30 * time.Second) + + return config +} + +type bgpNeighbor struct { + as uint32 + neighborip string + isV4 bool + peerGrp string +} + +func verifyOTGBGPTelemetry(t *testing.T, otg *otg.OTG, c gosnappi.Config, state string) { + t.Helper() + for _, d := range c.Devices().Items() { + for _, ip := range d.Bgp().Ipv4Interfaces().Items() { + for _, configPeer := range ip.Peers().Items() { + nbrPath := gnmi.OTG().BgpPeer(configPeer.Name()) + _, ok := gnmi.Watch(t, otg, nbrPath.SessionState().State(), time.Minute, func(val *ygnmi.Value[otgtelemetry.E_BgpPeer_SessionState]) bool { + currState, ok := val.Val() + return ok && currState.String() == state + }).Await(t) + if !ok { + t.Errorf("No BGP neighbor formed for peer %s", configPeer.Name()) + } + } + } + for _, ip := range d.Bgp().Ipv6Interfaces().Items() { + for _, configPeer := range ip.Peers().Items() { + nbrPath := gnmi.OTG().BgpPeer(configPeer.Name()) + _, ok := gnmi.Watch(t, otg, nbrPath.SessionState().State(), time.Minute, func(val *ygnmi.Value[otgtelemetry.E_BgpPeer_SessionState]) bool { + currState, ok := val.Val() + return ok && currState.String() == state + }).Await(t) + if !ok { + t.Errorf("No BGP neighbor formed for peer %s", configPeer.Name()) + } + } + } + } +} + +// verifyBGPAsPath is to Validate AS Path attribute using bgp rib telemetry on ATE. +func verifyBGPAsPath(t *testing.T, otg *otg.OTG, config gosnappi.Config, asSeg []uint32, removeASPath bool) { + t.Helper() + _, ok := gnmi.WatchAll(t, otg, gnmi.OTG().BgpPeer(ateDst.Name+".BGP4.peer").UnicastIpv4PrefixAny().State(), + time.Minute, func(v *ygnmi.Value[*otgtelemetry.BgpPeer_UnicastIpv4Prefix]) bool { + return v.IsPresent() + }).Await(t) + + var wantASSeg = []uint32{dutAS, ateAS1} + if removeASPath { + for _, as := range asSeg { + if as < 64512 { + wantASSeg = append(wantASSeg, as) + } + } + } else { + wantASSeg = append(wantASSeg, asSeg...) + } + + if ok { + bgpPrefixes := gnmi.GetAll(t, otg, gnmi.OTG().BgpPeer(ateDst.Name+".BGP4.peer").UnicastIpv4PrefixAny().State()) + gotPrefixCount := len(bgpPrefixes) + if gotPrefixCount != routeCount { + t.Errorf("Received prefixes on otg are not as expected got prefixes %v, want prefixes %v", gotPrefixCount, routeCount) + } + for _, prefix := range bgpPrefixes { + for _, gotASSeg := range prefix.AsPath { + if ok := cmp.Diff(gotASSeg.AsNumbers, wantASSeg); ok != "" { + t.Errorf("Remove private AS is not working: gotAsSeg %v wantAsSeg %v for Prefix %v", gotASSeg, wantASSeg, prefix.GetAddress()) + } + } + } + } +} + +// TestRemovePrivateAS is to Validate that private AS numbers are stripped +// before advertisement to the eBGP neighbor. +func TestRemovePrivateAS(t *testing.T) { + dut := ondatra.DUT(t, "dut") + ate := ondatra.ATE(t, "ate") + otg := ate.OTG() + var otgConfig gosnappi.Config + + t.Run("Configure DUT interfaces", func(t *testing.T) { + configureDUT(t, dut) + }) + + t.Run("Configure DEFAULT network instance", func(t *testing.T) { + dutConfNIPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)) + gnmi.Replace(t, dut, dutConfNIPath.Type().Config(), oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_DEFAULT_INSTANCE) + }) + + dutConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + t.Run("Configure BGP Neighbors", func(t *testing.T) { + gnmi.Delete(t, dut, dutConfPath.Config()) + configureRoutePolicy(t, dut, policyName, oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) + dutConf := bgpCreateNbr(dutAS, ateAS1, dut) + gnmi.Replace(t, dut, dutConfPath.Config(), dutConf) + fptest.LogQuery(t, "DUT BGP Config", dutConfPath.Config(), gnmi.GetConfig(t, dut, dutConfPath.Config())) + }) + + cases := []struct { + desc string + asSeg []uint32 + asSEQMode bool + }{{ + desc: "AS Path SEQ 65501", + asSeg: []uint32{65501}, + asSEQMode: true, + }, { + desc: "AS Path SEQ 65501, 65507", + asSeg: []uint32{65501, 65507}, + asSEQMode: true, + }, { + desc: "AS Path SEQ 800, 65501, 65508", + asSeg: []uint32{800, 65501, 65508}, + asSEQMode: true, + }, { + desc: "AS Path SEQ 65501, 600", + asSeg: []uint32{65501, 600}, + asSEQMode: true, + }, { + desc: "AS Path SEQ 800, 65507, 600", + asSeg: []uint32{800, 65507, 600}, + asSEQMode: true, + }} + + for _, tc := range cases { + t.Run(tc.desc, func(t *testing.T) { + t.Logf("Start OTG Config.") + otgConfig = configureOTG(t, otg, tc.asSeg, tc.asSEQMode) + + t.Log("Verifying port status.") + verifyPortsUp(t, dut.Device) + + t.Log("Check BGP parameters.") + verifyBGPTelemetry(t, dut) + verifyOTGBGPTelemetry(t, otg, otgConfig, "ESTABLISHED") + t.Log("Verify BGP prefix telemetry.") + verifyPrefixesTelemetry(t, dut, ateSrc.IPv4, routeCount, 0) + verifyPrefixesTelemetry(t, dut, ateDst.IPv4, 0, routeCount) + + t.Log("Verify AS Path list received at ate Port2 including private AS number.") + verifyBGPAsPath(t, otg, otgConfig, tc.asSeg, !removeASPath) + + t.Log("Configure remove private AS on DUT.") + gnmi.Update(t, dut, dutConfPath.Bgp().PeerGroup(peerGrpName2).RemovePrivateAs().Config(), oc.Bgp_RemovePrivateAsOption_PRIVATE_AS_REMOVE_ALL) + + t.Log("Private AS numbers should be stripped off while advertising BGP routes into public AS.") + verifyBGPAsPath(t, otg, otgConfig, tc.asSeg, removeASPath) + + otg.StopProtocols(t) + time.Sleep(30 * time.Second) + + t.Log("Remove remove-private-AS on DUT.") + gnmi.Delete(t, dut, dutConfPath.Bgp().PeerGroup(peerGrpName2).RemovePrivateAs().Config()) + }) + } +} diff --git a/feature/experimental/bgp/otg_tests/bgp_remove_private_as/metadata.textproto b/feature/experimental/bgp/otg_tests/bgp_remove_private_as/metadata.textproto new file mode 100644 index 00000000000..7d1b701fdd3 --- /dev/null +++ b/feature/experimental/bgp/otg_tests/bgp_remove_private_as/metadata.textproto @@ -0,0 +1,26 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "2b4372c2-8827-4624-837c-f44b1a54edf7" +plan_id: "RT-1.11" +description: "BGP remove private AS" +testbed: TESTBED_DUT_ATE_2LINKS +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + interface_enabled: true + default_network_instance: "default" + } +} +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + interface_enabled: true + } +} +tags: TAGS_AGGREGATION + From 233321e97c344b44d48e67a615ee50d27755673f Mon Sep 17 00:00:00 2001 From: jasdeep-hundal Date: Fri, 15 Sep 2023 09:27:09 -0700 Subject: [PATCH 39/43] Remove packet size spec from My Station MAC OTG test (#2132) --- .../otg_tests/my_station_mac_test/my_station_mac_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/feature/experimental/interface/my_station_mac/otg_tests/my_station_mac_test/my_station_mac_test.go b/feature/experimental/interface/my_station_mac/otg_tests/my_station_mac_test/my_station_mac_test.go index 19da3df11f3..c3f14282844 100644 --- a/feature/experimental/interface/my_station_mac/otg_tests/my_station_mac_test/my_station_mac_test.go +++ b/feature/experimental/interface/my_station_mac/otg_tests/my_station_mac_test/my_station_mac_test.go @@ -158,7 +158,6 @@ func testTraffic( flow.TxRx().Port().SetTxName("port1").SetRxName("port2") flow.Metrics().SetEnable(true) eth := flow.Packet().Add().Ethernet() - flow.Size().SetFixed(100) eth.Src().SetValue(ateSrc.MAC) eth.Dst().SetChoice("value").SetValue(myStationMAC) if ipType == "IPv4" { From f76f1788c1027c2cd207b60191fd74d4ed15938f Mon Sep 17 00:00:00 2001 From: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> Date: Fri, 15 Sep 2023 13:01:54 -0400 Subject: [PATCH 40/43] raw.GNOI -> binding.GNOIClients (#2134) --- .../route_addition_during_failover_test.go | 4 ++-- .../route_removal_during_failover_test.go | 3 +-- .../route_addition_during_failover_test.go | 4 ++-- .../route_removal_during_failover_test.go | 3 +-- .../system_generic_health_check_test.go | 4 ++-- .../packet_link_qualification_test.go | 8 ++++---- 6 files changed, 12 insertions(+), 14 deletions(-) diff --git a/feature/experimental/gribi/ate_tests/route_addition_during_failover_test/route_addition_during_failover_test.go b/feature/experimental/gribi/ate_tests/route_addition_during_failover_test/route_addition_during_failover_test.go index 43d3557f15d..cb3eb1093e5 100644 --- a/feature/experimental/gribi/ate_tests/route_addition_during_failover_test/route_addition_during_failover_test.go +++ b/feature/experimental/gribi/ate_tests/route_addition_during_failover_test/route_addition_during_failover_test.go @@ -33,9 +33,9 @@ import ( "github.com/openconfig/gribigo/constants" "github.com/openconfig/gribigo/fluent" "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/binding" "github.com/openconfig/ondatra/gnmi" "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ondatra/raw" "github.com/openconfig/testt" "github.com/openconfig/ygot/ygot" @@ -121,7 +121,7 @@ var ipBlock1FlowArgs = &flowArgs{ } // coreFileCheck function is used to check if cores are found on the DUT. -func coreFileCheck(t *testing.T, dut *ondatra.DUTDevice, gnoiClient raw.GNOI, sysConfigTime uint64, retry bool) { +func coreFileCheck(t *testing.T, dut *ondatra.DUTDevice, gnoiClient binding.GNOIClients, sysConfigTime uint64, retry bool) { t.Helper() t.Log("Checking for core files on DUT") diff --git a/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go b/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go index bce6c166e4f..768dca762c5 100644 --- a/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go +++ b/feature/experimental/gribi/ate_tests/route_removal_during_failover_test/route_removal_during_failover_test.go @@ -37,7 +37,6 @@ import ( "github.com/openconfig/ondatra/binding" "github.com/openconfig/ondatra/gnmi" "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ondatra/raw" "github.com/openconfig/testt" "github.com/openconfig/ygot/ygot" @@ -101,7 +100,7 @@ var ( ) // coreFileCheck function is used to check if any cores found during test execution. -func coreFilecheck(t *testing.T, dut *ondatra.DUTDevice, gnoiClient raw.GNOI, sysConfigTime uint64) { +func coreFilecheck(t *testing.T, dut *ondatra.DUTDevice, gnoiClient binding.GNOIClients, sysConfigTime uint64) { // vendorCoreFilePath and vendorCoreProcName should be provided to fetch core file on dut. if _, ok := vendorCoreFilePath[dut.Vendor()]; !ok { t.Fatalf("Please add support for vendor %v in var vendorCoreFilePath ", dut.Vendor()) diff --git a/feature/experimental/gribi/otg_tests/route_addition_during_failover_test/route_addition_during_failover_test.go b/feature/experimental/gribi/otg_tests/route_addition_during_failover_test/route_addition_during_failover_test.go index 2bdd4ce46bc..d16124f01d7 100644 --- a/feature/experimental/gribi/otg_tests/route_addition_during_failover_test/route_addition_during_failover_test.go +++ b/feature/experimental/gribi/otg_tests/route_addition_during_failover_test/route_addition_during_failover_test.go @@ -36,9 +36,9 @@ import ( "github.com/openconfig/gribigo/constants" "github.com/openconfig/gribigo/fluent" "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/binding" "github.com/openconfig/ondatra/gnmi" "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ondatra/raw" "github.com/openconfig/testt" "github.com/openconfig/ygot/ygot" @@ -125,7 +125,7 @@ var ipBlock1FlowArgs = &flowArgs{ } // coreFileCheck function is used to check if cores are found on the DUT. -func coreFileCheck(t *testing.T, dut *ondatra.DUTDevice, gnoiClient raw.GNOI, sysConfigTime uint64, retry bool) { +func coreFileCheck(t *testing.T, dut *ondatra.DUTDevice, gnoiClient binding.GNOIClients, sysConfigTime uint64, retry bool) { t.Helper() t.Log("Checking for core files on DUT") diff --git a/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go b/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go index 830c35b4856..0e4e8785cb2 100644 --- a/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go +++ b/feature/experimental/gribi/otg_tests/route_removal_during_failover_test/route_removal_during_failover_test.go @@ -40,7 +40,6 @@ import ( "github.com/openconfig/ondatra/binding" "github.com/openconfig/ondatra/gnmi" "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ondatra/raw" "github.com/openconfig/testt" "github.com/openconfig/ygot/ygot" @@ -105,7 +104,7 @@ var ( ) // coreFileCheck function is used to check if any cores found during test execution. -func coreFilecheck(t *testing.T, dut *ondatra.DUTDevice, gnoiClient raw.GNOI, sysConfigTime uint64) { +func coreFilecheck(t *testing.T, dut *ondatra.DUTDevice, gnoiClient binding.GNOIClients, sysConfigTime uint64) { // vendorCoreFilePath and vendorCoreProcName should be provided to fetch core file on dut. if _, ok := vendorCoreFilePath[dut.Vendor()]; !ok { t.Fatalf("Please add support for vendor %v in var vendorCoreFilePath ", dut.Vendor()) diff --git a/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go b/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go index b53e4e8a8ba..f38ddec870f 100644 --- a/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go +++ b/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go @@ -25,9 +25,9 @@ import ( "github.com/openconfig/featureprofiles/internal/deviations" "github.com/openconfig/featureprofiles/internal/fptest" "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/binding" "github.com/openconfig/ondatra/gnmi" "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ondatra/raw" "github.com/openconfig/ygnmi/ygnmi" "golang.org/x/exp/slices" @@ -63,7 +63,7 @@ const ( ) // coreFileCheck function is used to check if cores are found on the DUT. -func coreFileCheck(t *testing.T, dut *ondatra.DUTDevice, gnoiClient raw.GNOI, sysConfigTime uint64, retry bool) { +func coreFileCheck(t *testing.T, dut *ondatra.DUTDevice, gnoiClient binding.GNOIClients, sysConfigTime uint64, retry bool) { t.Helper() t.Log("Checking for core files on DUT") diff --git a/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go b/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go index 9fc81b19a4d..87e0fd89dcc 100644 --- a/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go +++ b/feature/gnoi/packet_link_qualification/tests/packet_link_qualification_test/packet_link_qualification_test.go @@ -24,9 +24,9 @@ import ( "github.com/openconfig/featureprofiles/internal/fptest" plqpb "github.com/openconfig/gnoi/packet_link_qualification" "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/binding" "github.com/openconfig/ondatra/gnmi" "github.com/openconfig/ondatra/gnmi/oc" - "github.com/openconfig/ondatra/raw" "github.com/openconfig/ygot/ygot" "google.golang.org/protobuf/types/known/durationpb" ) @@ -159,7 +159,7 @@ func TestListDelete(t *testing.T) { gnoiClient1 := dut1.RawAPIs().GNOI(t) gnoiClient2 := dut2.RawAPIs().GNOI(t) - clients := []raw.GNOI{gnoiClient1, gnoiClient2} + clients := []binding.GNOIClients{gnoiClient1, gnoiClient2} for i, client := range clients { t.Logf("Check client: %d", i+1) listResp, err := client.LinkQualification().List(context.Background(), &plqpb.ListRequest{}) @@ -334,7 +334,7 @@ func TestLinkQualification(t *testing.T) { t.Logf("Wait for %v seconds: %d/%d", sleepTime.Seconds(), i+1, counter) time.Sleep(sleepTime) testDone := true - for i, client := range []raw.GNOI{gnoiClient1, gnoiClient2} { + for i, client := range []binding.GNOIClients{gnoiClient1, gnoiClient2} { t.Logf("Check client: %d", i+1) listResp, err := client.LinkQualification().List(context.Background(), &plqpb.ListRequest{}) @@ -364,7 +364,7 @@ func TestLinkQualification(t *testing.T) { var generatorPktsSent, generatorPktsRxed, reflectorPktsSent, reflectorPktsRxed uint64 - for i, client := range []raw.GNOI{gnoiClient1, gnoiClient2} { + for i, client := range []binding.GNOIClients{gnoiClient1, gnoiClient2} { t.Logf("Check client: %d", i+1) getResp, err := client.LinkQualification().Get(context.Background(), getRequest) t.Logf("LinkQualification().Get(): %v, err: %v", getResp, err) From a6f9af6bb9559b1785d9dc3ab797f3636e096de4 Mon Sep 17 00:00:00 2001 From: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> Date: Fri, 15 Sep 2023 13:03:13 -0400 Subject: [PATCH 41/43] Replace uber atomic with sync/atomic (#2133) * Use sync/atomic instead of uber's atomic * Use Store instead of Add --- feature/gribi/mplsutil/compliance.go | 10 +++++++--- go.mod | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/feature/gribi/mplsutil/compliance.go b/feature/gribi/mplsutil/compliance.go index 65856ae0d16..f26fbe3914a 100644 --- a/feature/gribi/mplsutil/compliance.go +++ b/feature/gribi/mplsutil/compliance.go @@ -5,6 +5,7 @@ package mplsutil import ( "context" "fmt" + "sync/atomic" "testing" "github.com/openconfig/gribigo/chk" @@ -12,12 +13,15 @@ import ( "github.com/openconfig/gribigo/compliance" "github.com/openconfig/gribigo/constants" "github.com/openconfig/gribigo/fluent" - "go.uber.org/atomic" ) var ( // electionID is the global election ID used between test cases. - electionID = atomic.NewUint64(1) + electionID = func() *atomic.Uint64 { + eid := new(atomic.Uint64) + eid.Store(1) + return eid + }() ) // flushServer removes all entries from the server and can be called between @@ -57,7 +61,7 @@ func modify(t *testing.T, c *fluent.GRIBIClient, ops []func()) []*client.OpResul // // The DUT is expected to have a next-hop of 192.0.2.2 that is resolvable. func PushLabelStack(t *testing.T, c *fluent.GRIBIClient, defaultNIName string, baseLabel, numLabels int, trafficFunc TrafficFunc) { - defer electionID.Inc() + defer electionID.Add(1) defer flushServer(t, c) var labels []uint32 diff --git a/go.mod b/go.mod index 7ffd5345c57..5b92e0e4a96 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/google/uuid v1.3.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/open-traffic-generator/snappi/gosnappi v0.12.3 + github.com/openconfig/entity-naming v0.0.0-20230829162409-b28ee246e213 github.com/openconfig/gnmi v0.10.0 github.com/openconfig/gnoi v0.1.0 github.com/openconfig/gnsi v1.2.3 @@ -97,7 +98,6 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/networkop/meshnet-cni v0.3.1-0.20230525201116-d7c306c635cf // indirect github.com/open-traffic-generator/ixia-c-operator v0.3.4 // indirect - github.com/openconfig/entity-naming v0.0.0-20230829162409-b28ee246e213 // indirect github.com/openconfig/grpctunnel v0.0.0-20220819142823-6f5422b8ca70 // indirect github.com/openconfig/lemming/operator v0.2.0 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect From a6115671323d159ffe0133456b10198383202770 Mon Sep 17 00:00:00 2001 From: Greg Dennis <5436032+greg-dennis@users.noreply.github.com> Date: Fri, 15 Sep 2023 13:53:18 -0400 Subject: [PATCH 42/43] ni_proto -> niProto (#2135) --- .../bgp_graceful_restart_test.go | 6 +++--- .../route_installation_test.go | 6 +++--- .../route_installation_test.go | 6 +++--- .../bgp_prefix_limit_test/bgp_prefix_limit_test.go | 6 +++--- .../bgp_prefix_limit_test/bgp_prefix_limit_test.go | 6 +++--- feature/bgp/tests/local_bgp_test/local_bgp_test.go | 6 +++--- .../bgp_2byte_4byte_asn/bgp_2byte_4byte_asn_test.go | 6 +++--- .../bgp_always_compare_med_test.go | 6 +++--- .../bgp_long_lived_graceful_restart_test.go | 12 ++++++------ .../bgp_remove_private_as_test.go | 6 +++--- .../bgp_afi_safi_defaults_test.go | 6 +++--- .../bgp_always_compare_med_test.go | 6 +++--- .../bgp_remove_private_as_test.go | 6 +++--- 13 files changed, 42 insertions(+), 42 deletions(-) diff --git a/feature/bgp/gracefulrestart/ate_tests/bgp_graceful_restart_test/bgp_graceful_restart_test.go b/feature/bgp/gracefulrestart/ate_tests/bgp_graceful_restart_test/bgp_graceful_restart_test.go index 443b9ee4a83..d2f431464e0 100644 --- a/feature/bgp/gracefulrestart/ate_tests/bgp_graceful_restart_test/bgp_graceful_restart_test.go +++ b/feature/bgp/gracefulrestart/ate_tests/bgp_graceful_restart_test/bgp_graceful_restart_test.go @@ -176,8 +176,8 @@ func buildNbrList(asN uint32) []*bgpNeighbor { func bgpWithNbr(as uint32, nbrs []*bgpNeighbor, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { d := &oc.Root{} ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := ni_proto.GetOrCreateBgp() + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() g := bgp.GetOrCreateGlobal() g.As = ygot.Uint32(as) @@ -246,7 +246,7 @@ func bgpWithNbr(as uint32, nbrs []*bgpNeighbor, dut *ondatra.DUTDevice) *oc.Netw af4.Enabled = ygot.Bool(false) } } - return ni_proto + return niProto } func checkBgpStatus(t *testing.T, dut *ondatra.DUTDevice) { diff --git a/feature/bgp/policybase/ate_tests/route_installation_test/route_installation_test.go b/feature/bgp/policybase/ate_tests/route_installation_test/route_installation_test.go index 1e1c0d5ad11..efb73b817d8 100644 --- a/feature/bgp/policybase/ate_tests/route_installation_test/route_installation_test.go +++ b/feature/bgp/policybase/ate_tests/route_installation_test/route_installation_test.go @@ -162,8 +162,8 @@ func bgpCreateNbr(localAs, peerAs uint32, policy string, dut *ondatra.DUTDevice) d := &oc.Root{} ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := ni_proto.GetOrCreateBgp() + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() global := bgp.GetOrCreateGlobal() global.RouterId = ygot.String(dutDst.IPv4) global.As = ygot.Uint32(localAs) @@ -219,7 +219,7 @@ func bgpCreateNbr(localAs, peerAs uint32, policy string, dut *ondatra.DUTDevice) } } - return ni_proto + return niProto } // configureBGPPolicy configures a BGP routing policy to accept or reject routes based on prefix match conditions diff --git a/feature/bgp/policybase/otg_tests/route_installation_test/route_installation_test.go b/feature/bgp/policybase/otg_tests/route_installation_test/route_installation_test.go index 267b90e6031..f3ebd27c1bb 100644 --- a/feature/bgp/policybase/otg_tests/route_installation_test/route_installation_test.go +++ b/feature/bgp/policybase/otg_tests/route_installation_test/route_installation_test.go @@ -170,8 +170,8 @@ func bgpCreateNbr(localAs, peerAs uint32, policy string, dut *ondatra.DUTDevice) d := &oc.Root{} ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := ni_proto.GetOrCreateBgp() + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() global := bgp.GetOrCreateGlobal() global.RouterId = ygot.String(dutDst.IPv4) global.As = ygot.Uint32(localAs) @@ -226,7 +226,7 @@ func bgpCreateNbr(localAs, peerAs uint32, policy string, dut *ondatra.DUTDevice) } } - return ni_proto + return niProto } // configureBGPPolicy configures a BGP routing policy to accept or reject routes based on prefix match conditions diff --git a/feature/bgp/prefixlimit/ate_tests/bgp_prefix_limit_test/bgp_prefix_limit_test.go b/feature/bgp/prefixlimit/ate_tests/bgp_prefix_limit_test/bgp_prefix_limit_test.go index d6330bfb0ff..ad4b5708625 100644 --- a/feature/bgp/prefixlimit/ate_tests/bgp_prefix_limit_test/bgp_prefix_limit_test.go +++ b/feature/bgp/prefixlimit/ate_tests/bgp_prefix_limit_test/bgp_prefix_limit_test.go @@ -235,8 +235,8 @@ func createBGPNeighbor(localAs, peerAs, pLimit uint32, restartTime uint16, dut * d := &oc.Root{} ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := ni_proto.GetOrCreateBgp() + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() global := bgp.GetOrCreateGlobal() global.As = ygot.Uint32(localAs) @@ -302,7 +302,7 @@ func createBGPNeighbor(localAs, peerAs, pLimit uint32, restartTime uint16, dut * } } } - return ni_proto + return niProto } func configureRoutePolicy(t *testing.T, dut *ondatra.DUTDevice, name string, pr oc.E_RoutingPolicy_PolicyResultType) { diff --git a/feature/bgp/prefixlimit/otg_tests/bgp_prefix_limit_test/bgp_prefix_limit_test.go b/feature/bgp/prefixlimit/otg_tests/bgp_prefix_limit_test/bgp_prefix_limit_test.go index 1f560ccd644..0615b353950 100644 --- a/feature/bgp/prefixlimit/otg_tests/bgp_prefix_limit_test/bgp_prefix_limit_test.go +++ b/feature/bgp/prefixlimit/otg_tests/bgp_prefix_limit_test/bgp_prefix_limit_test.go @@ -267,8 +267,8 @@ func createBGPNeighbor(localAs, peerAs, pLimit uint32, restartTime uint16, dut * d := &oc.Root{} ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := ni_proto.GetOrCreateBgp() + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() global := bgp.GetOrCreateGlobal() global.As = ygot.Uint32(localAs) @@ -334,7 +334,7 @@ func createBGPNeighbor(localAs, peerAs, pLimit uint32, restartTime uint16, dut * } } } - return ni_proto + return niProto } func configureRoutePolicy(t *testing.T, dut *ondatra.DUTDevice, name string, pr oc.E_RoutingPolicy_PolicyResultType) { diff --git a/feature/bgp/tests/local_bgp_test/local_bgp_test.go b/feature/bgp/tests/local_bgp_test/local_bgp_test.go index a72fda73da3..113e15d151c 100644 --- a/feature/bgp/tests/local_bgp_test/local_bgp_test.go +++ b/feature/bgp/tests/local_bgp_test/local_bgp_test.go @@ -61,8 +61,8 @@ func bgpWithNbr(as uint32, routerID string, nbr *oc.NetworkInstance_Protocol_Bgp d := &oc.Root{} ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := ni_proto.GetOrCreateBgp() + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() bgp.GetOrCreateGlobal().As = ygot.Uint32(as) bgp.GetOrCreateGlobal().GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) @@ -88,7 +88,7 @@ func bgpWithNbr(as uint32, routerID string, nbr *oc.NetworkInstance_Protocol_Bgp } bgp.AppendNeighbor(nbr) - return ni_proto + return niProto } func configureNIType(t *testing.T) { diff --git a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/bgp_2byte_4byte_asn_test.go b/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/bgp_2byte_4byte_asn_test.go index b799247619f..6eff10b6001 100644 --- a/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/bgp_2byte_4byte_asn_test.go +++ b/feature/experimental/bgp/ate_tests/bgp_2byte_4byte_asn/bgp_2byte_4byte_asn_test.go @@ -218,8 +218,8 @@ func configureATE(t *testing.T, ateParams *bgpNbr, connectionType string) *ondat func createBgpNeighbor(nbr *bgpNbr, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { d := &oc.Root{} ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := ni_proto.GetOrCreateBgp() + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() global := bgp.GetOrCreateGlobal() global.As = ygot.Uint32(nbr.localAS) @@ -244,5 +244,5 @@ func createBgpNeighbor(nbr *bgpNbr, dut *ondatra.DUTDevice) *oc.NetworkInstance_ afisafi6.Enabled = ygot.Bool(true) neighbor.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(false) } - return ni_proto + return niProto } diff --git a/feature/experimental/bgp/ate_tests/bgp_always_compare_med/bgp_always_compare_med_test.go b/feature/experimental/bgp/ate_tests/bgp_always_compare_med/bgp_always_compare_med_test.go index 8ea2b06d88a..41529acbeb4 100644 --- a/feature/experimental/bgp/ate_tests/bgp_always_compare_med/bgp_always_compare_med_test.go +++ b/feature/experimental/bgp/ate_tests/bgp_always_compare_med/bgp_always_compare_med_test.go @@ -141,8 +141,8 @@ func bgpCreateNbr(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkIns dutOcRoot := &oc.Root{} ni1 := dutOcRoot.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := ni_proto.GetOrCreateBgp() + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() global := bgp.GetOrCreateGlobal() global.RouterId = ygot.String(dutDst2.IPv4) global.As = ygot.Uint32(localAs) @@ -196,7 +196,7 @@ func bgpCreateNbr(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkIns af6.Enabled = ygot.Bool(false) } } - return ni_proto + return niProto } // verifyBgpTelemetry checks that the dut has an established BGP session with reasonable settings. diff --git a/feature/experimental/bgp/ate_tests/bgp_long_lived_graceful_restart/bgp_long_lived_graceful_restart_test.go b/feature/experimental/bgp/ate_tests/bgp_long_lived_graceful_restart/bgp_long_lived_graceful_restart_test.go index 788f59da58e..47569ff2ce2 100644 --- a/feature/experimental/bgp/ate_tests/bgp_long_lived_graceful_restart/bgp_long_lived_graceful_restart_test.go +++ b/feature/experimental/bgp/ate_tests/bgp_long_lived_graceful_restart/bgp_long_lived_graceful_restart_test.go @@ -320,8 +320,8 @@ func buildNbrList(asN uint32) []*bgpNeighbor { func bgpWithNbr(as uint32, nbrs []*bgpNeighbor, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { d := &oc.Root{} ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := ni_proto.GetOrCreateBgp() + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() g := bgp.GetOrCreateGlobal() g.As = ygot.Uint32(as) @@ -382,7 +382,7 @@ func bgpWithNbr(as uint32, nbrs []*bgpNeighbor, dut *ondatra.DUTDevice) *oc.Netw af4.Enabled = ygot.Bool(false) } } - return ni_proto + return niProto } func checkBgpStatus(t *testing.T, dut *ondatra.DUTDevice, nbrIP []*bgpNeighbor) { @@ -950,8 +950,8 @@ func configureDUTNewPeers(t *testing.T, dut *ondatra.DUTDevice, nbrs []*bgpNeigh d := &oc.Root{} dutConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := ni_proto.GetOrCreateBgp() + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() // Note: we have to define the peer group even if we aren't setting any policy because it's // invalid OC for the neighbor to be part of a peer group that doesn't exist. @@ -968,7 +968,7 @@ func configureDUTNewPeers(t *testing.T, dut *ondatra.DUTDevice, nbrs []*bgpNeigh af6 := nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) af6.Enabled = ygot.Bool(false) } - gnmi.Update(t, dut, dutConfPath.Config(), ni_proto) + gnmi.Update(t, dut, dutConfPath.Config(), niProto) fptest.LogQuery(t, "DUT BGP Config", dutConfPath.Config(), gnmi.GetConfig(t, dut, dutConfPath.Config())) } diff --git a/feature/experimental/bgp/ate_tests/bgp_remove_private_as/bgp_remove_private_as_test.go b/feature/experimental/bgp/ate_tests/bgp_remove_private_as/bgp_remove_private_as_test.go index 438be221daa..4e643f41d41 100644 --- a/feature/experimental/bgp/ate_tests/bgp_remove_private_as/bgp_remove_private_as_test.go +++ b/feature/experimental/bgp/ate_tests/bgp_remove_private_as/bgp_remove_private_as_test.go @@ -122,8 +122,8 @@ func bgpCreateNbr(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkIns d := &oc.Root{} ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := ni_proto.GetOrCreateBgp() + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() global := bgp.GetOrCreateGlobal() global.RouterId = ygot.String(dutDst.IPv4) global.As = ygot.Uint32(localAs) @@ -172,7 +172,7 @@ func bgpCreateNbr(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkIns af6 := nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) af6.Enabled = ygot.Bool(false) } - return ni_proto + return niProto } // verifyBGPTelemetry checks that the dut has an established BGP session with reasonable settings. diff --git a/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go b/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go index 572343caf54..34123d395a0 100644 --- a/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go +++ b/feature/experimental/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go @@ -124,8 +124,8 @@ func bgpCreateNbr(t *testing.T, localAs, peerAs uint32, dut *ondatra.DUTDevice, nbrs := []*bgpNeighbor{nbr1, nbr2, nbr3, nbr4} dutOcRoot := &oc.Root{} ni1 := dutOcRoot.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := ni_proto.GetOrCreateBgp() + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() global := bgp.GetOrCreateGlobal() global.RouterId = ygot.String(dutPort2.IPv4) global.As = ygot.Uint32(localAs) @@ -176,7 +176,7 @@ func bgpCreateNbr(t *testing.T, localAs, peerAs uint32, dut *ondatra.DUTDevice, pg2af6.Enabled = ygot.Bool(true) } } - return ni_proto + return niProto } func verifyOtgBgpTelemetry(t *testing.T, otg *otg.OTG, c gosnappi.Config, state string) { diff --git a/feature/experimental/bgp/otg_tests/bgp_always_compare_med/bgp_always_compare_med_test.go b/feature/experimental/bgp/otg_tests/bgp_always_compare_med/bgp_always_compare_med_test.go index dc0aad5b685..fbfd870ad5c 100644 --- a/feature/experimental/bgp/otg_tests/bgp_always_compare_med/bgp_always_compare_med_test.go +++ b/feature/experimental/bgp/otg_tests/bgp_always_compare_med/bgp_always_compare_med_test.go @@ -149,8 +149,8 @@ func bgpCreateNbr(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkIns dutOcRoot := &oc.Root{} ni1 := dutOcRoot.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := ni_proto.GetOrCreateBgp() + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() global := bgp.GetOrCreateGlobal() global.RouterId = ygot.String(dutDst2.IPv4) global.As = ygot.Uint32(localAs) @@ -180,7 +180,7 @@ func bgpCreateNbr(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkIns af6 := nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) af6.Enabled = ygot.Bool(false) } - return ni_proto + return niProto } func sendTraffic(t *testing.T, otg *otg.OTG, c gosnappi.Config) { diff --git a/feature/experimental/bgp/otg_tests/bgp_remove_private_as/bgp_remove_private_as_test.go b/feature/experimental/bgp/otg_tests/bgp_remove_private_as/bgp_remove_private_as_test.go index 4556cc49dba..ecc45775967 100644 --- a/feature/experimental/bgp/otg_tests/bgp_remove_private_as/bgp_remove_private_as_test.go +++ b/feature/experimental/bgp/otg_tests/bgp_remove_private_as/bgp_remove_private_as_test.go @@ -142,8 +142,8 @@ func bgpCreateNbr(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkIns d := &oc.Root{} ni1 := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) - ni_proto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") - bgp := ni_proto.GetOrCreateBgp() + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() global := bgp.GetOrCreateGlobal() global.RouterId = ygot.String(dutDst.IPv4) global.As = ygot.Uint32(localAs) @@ -192,7 +192,7 @@ func bgpCreateNbr(localAs, peerAs uint32, dut *ondatra.DUTDevice) *oc.NetworkIns af6 := nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) af6.Enabled = ygot.Bool(false) } - return ni_proto + return niProto } // verifyBGPTelemetry checks that the dut has an established BGP session with reasonable settings. From a937f790130c7dcd7953e818b879c58b2be74cd9 Mon Sep 17 00:00:00 2001 From: ANISH-GOTTAPU <48308607+ANISH-GOTTAPU@users.noreply.github.com> Date: Sat, 16 Sep 2023 00:22:32 +0530 Subject: [PATCH 43/43] disable ATE port test (#2109) --- .../backup_nhg_test/backup_nhg_test.go | 53 +++++++++++-------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/feature/experimental/backup_nhg/otg_tests/backup_nhg_test/backup_nhg_test.go b/feature/experimental/backup_nhg/otg_tests/backup_nhg_test/backup_nhg_test.go index 2b26b73c914..f30c2a43cd7 100644 --- a/feature/experimental/backup_nhg/otg_tests/backup_nhg_test/backup_nhg_test.go +++ b/feature/experimental/backup_nhg/otg_tests/backup_nhg_test/backup_nhg_test.go @@ -183,8 +183,8 @@ func TestDirectBackupNexthopGroup(t *testing.T) { tcArgs.configureBackupNextHopGroup(t, false) - baselineFlow := tcArgs.createFlow("Baseline Path Flow", ateTop, &atePort2) - backupFlow := tcArgs.createFlow("Backup Path Flow", ateTop, &atePort3) + baselineFlow := tcArgs.createFlow("Baseline_Path_Flow", ateTop, &atePort2) + backupFlow := tcArgs.createFlow("Backup_Path_Flow", ateTop, &atePort3) backupIPIPFlow := tcArgs.createIPIPFlow("Backup IP Over IP Path Flow", ateTop, &atePort3) tcArgs.ate.OTG().PushConfig(t, ateTop) tcArgs.ate.OTG().StartProtocols(t) @@ -194,22 +194,34 @@ func TestDirectBackupNexthopGroup(t *testing.T) { applyImpairmentFn func() removeImpairmentFn func() }{ - // Disabling otg / kne ports has no effect - // { - // desc: "Disable ATE port-2", - // applyImpairmentFn: func() { - // ateP2 := ate.Port(t, "port2") - // dutP2 := dut.Port(t, "port2") - // ate.Actions().NewSetPortState().WithPort(ateP2).WithEnabled(false).Send(t) - // dut.Telemetry().Interface(dutP2.Name()).OperStatus().Await(t, time.Minute, telemetry.Interface_OperStatus_DOWN) - // }, - // removeImpairmentFn: func() { - // ateP2 := ate.Port(t, "port2") - // dutP2 := dut.Port(t, "port2") - // ate.Actions().NewSetPortState().WithPort(ateP2).WithEnabled(true).Send(t) - // dut.Telemetry().Interface(dutP2.Name()).OperStatus().Await(t, time.Minute, telemetry.Interface_OperStatus_UP) - // }, - // }, + { + desc: "Disable ATE port-2", + applyImpairmentFn: func() { + ateP2 := ate.Port(t, "port2") + dutP2 := dut.Port(t, "port2") + if deviations.ATEPortLinkStateOperationsUnsupported(tcArgs.ate) { + gnmi.Replace(t, dut, gnmi.OC().Interface(dutP2.Name()).Enabled().Config(), false) + gnmi.Await(t, dut, gnmi.OC().Interface(dutP2.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_DOWN) + } else { + portStateAction := gosnappi.NewControlState() + portStateAction.Port().Link().SetPortNames([]string{ateP2.ID()}).SetState(gosnappi.StatePortLinkState.DOWN) + tcArgs.ate.OTG().SetControlState(t, portStateAction) + } + }, + removeImpairmentFn: func() { + ateP2 := ate.Port(t, "port2") + dutP2 := dut.Port(t, "port2") + if deviations.ATEPortLinkStateOperationsUnsupported(tcArgs.ate) { + gnmi.Replace(t, dut, gnmi.OC().Interface(dutP2.Name()).Enabled().Config(), true) + gnmi.Await(t, dut, gnmi.OC().Interface(dutP2.Name()).OperStatus().State(), time.Minute, oc.Interface_OperStatus_UP) + } else { + portStateAction := gosnappi.NewControlState() + portStateAction.Port().Link().SetPortNames([]string{ateP2.ID()}).SetState(gosnappi.StatePortLinkState.UP) + tcArgs.ate.OTG().SetControlState(t, portStateAction) + otgutils.WaitForARP(t, ate.OTG(), tcArgs.ateTop, "IPv4") + } + }, + }, { desc: "Disable DUT port-2", applyImpairmentFn: func() { @@ -357,8 +369,7 @@ func configureNetworkInstance(t *testing.T, dut *ondatra.DUTDevice) { // createFlow returns a flow from atePort1 to the dstPfx, expected to arrive on ATE interface dst. func (a *testArgs) createFlow(name string, ateTop gosnappi.Config, dst *attrs.Attributes) string { - modName := strings.Replace(name, " ", "_", -1) - flowipv4 := ateTop.Flows().Add().SetName(modName) + flowipv4 := ateTop.Flows().Add().SetName(name) flowipv4.Metrics().SetEnable(true) e1 := flowipv4.Packet().Add().Ethernet() e1.Src().SetValue(atePort1.MAC) @@ -367,7 +378,7 @@ func (a *testArgs) createFlow(name string, ateTop gosnappi.Config, dst *attrs.At v4.Src().SetValue(atePort1.IPv4) v4.Dst().SetValue(dstPfx) - return modName + return flowipv4.Name() } // createIPIPFlow returns a flow from atePort1 to the dstPfx, expected to arrive on ATE interface dst.