diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 70a8a814170..0ddfb1eacef 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -11,18 +11,23 @@ * @openconfig/featureprofiles-maintainers # /feature folders each have owners who are auto requested for review and may merge PR's +/feature/acl/ @alokmtri-g /feature/bgp/ @dplore +/feature/dhcp/ @alokmtri-g /feature/ethernet/ @ram-mac /feature/interface/ @ram-mac /feature/isis/ @rohit-rp +/feature/lldp/ @alokmtri-g /feature/mpls/ @swetha-haridasula /feature/mtu/ @swetha-haridasula /feature/networkinstance/ @swetha-haridasula +/feature/platform/ @amrindrr /feature/policy_forwarding/ @swetha-haridasula /feature/qos @sezhang2 /feature/routing_policy/ @swetha-haridasula /feature/security @mihirpitale-googler /feature/staticroute/ @swetha-haridasula +/feature/stp/ @alokmtri-g /feature/system @self-maurya /feature/vrrp @amrindrr diff --git a/feature/bgp/policybase/otg_tests/community_test/README.md b/feature/bgp/policybase/otg_tests/community_test/README.md index a068367488f..f1911b3c359 100644 --- a/feature/bgp/policybase/otg_tests/community_test/README.md +++ b/feature/bgp/policybase/otg_tests/community_test/README.md @@ -54,6 +54,27 @@ BGP policy configuration for Community Sets * Verify traffic is received on ATE port 1 for accepted prefixes. * Verify traffic is not received on ATE port 1 for rejected prefixes. +* RT-7.2.3 - Update community set and validate + 1. Configure a community-set named `update_comm_set` with "100:1" as member. + + 2. Create a `policy-definition` named 'community-match' with the following `statements` + * statement[name='accept_update_comm_set']/ + * conditions/bgp-conditions/match-community-set/config/community-set = 'update_comm_set' + * conditions/bgp-conditions/match-community-set/config/match-set-options = INVERT + * actions/config/policy-result = ACCEPT_ROUTE + + 3. Send traffic from ATE port-2 to all prefix-sets. + * Verify traffic is received on ATE port 1 for accepted prefixes for all community set except "100:1". + * Verify traffic is not received on ATE port 1 for rejected prefixes for community set "100:1". + + 4. Update the community-set named `update_comm_set` with "200:2" as member. + + 5. Send traffic from ATE port-2 to all prefix-sets. + * Verify traffic is received on ATE port 1 for accepted prefixes for all community set except "200:1". + * Verify traffic is not received on ATE port 1 for rejected prefixes for community set "200:1". + + + ### Expected community matches | prefix-set | any_my_3_comms | all_3_comms | no_3_comms | any_my_regex_comms | @@ -155,4 +176,4 @@ rpcs: gnmi: gNMI.Set: gNMI.Subscribe: -``` \ No newline at end of file +``` diff --git a/feature/bgp/policybase/otg_tests/community_test/community_test.go b/feature/bgp/policybase/otg_tests/community_test/community_test.go index 3d545c83c8b..c5164592725 100644 --- a/feature/bgp/policybase/otg_tests/community_test/community_test.go +++ b/feature/bgp/policybase/otg_tests/community_test/community_test.go @@ -225,32 +225,7 @@ type testCase struct { } func TestCommunitySet(t *testing.T) { - bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount2, nil) - bs.WithEBGP(t, []oc.E_BgpTypes_AFI_SAFI_TYPE{oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST}, []string{"port2"}, true, true) - - var communityMembers = [][][]int{ - { - {100, 1}, {200, 2}, {300, 3}, - }, - { - {100, 1}, {101, 1}, {200, 2}, - }, - { - {107, 1}, {108, 1}, {109, 1}, - }, - { - {400, 1}, {500, 1}, {600, 1}, - }, - } - - configureOTG(t, bs, prefixesV4, prefixesV6, communityMembers) - bs.PushAndStart(t) - - t.Log("Verify DUT BGP sessions up") - cfgplugins.VerifyDUTBGPEstablished(t, bs.DUT) - t.Log("Verify OTG BGP sessions up") - cfgplugins.VerifyOTGBGPEstablished(t, bs.ATE) - + bs := testSetup(t) ipv4 := bs.ATETop.Devices().Items()[1].Ethernets().Items()[0].Ipv4Addresses().Items()[0].Address() ipv6 := bs.ATETop.Devices().Items()[1].Ethernets().Items()[0].Ipv6Addresses().Items()[0].Address() @@ -319,3 +294,79 @@ func TestCommunitySet(t *testing.T) { }) } } + +func testSetup(t *testing.T) *cfgplugins.BGPSession { + t.Helper() + + bs := cfgplugins.NewBGPSession(t, cfgplugins.PortCount2, nil) + bs.WithEBGP(t, []oc.E_BgpTypes_AFI_SAFI_TYPE{oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST, oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST}, []string{"port2"}, true, true) + + var communityMembers = [][][]int{ + { + {100, 1}, {200, 2}, {300, 3}, + }, + { + {100, 1}, {101, 1}, {200, 2}, + }, + { + {107, 1}, {108, 1}, {109, 1}, + }, + { + {400, 1}, {500, 1}, {600, 1}, + }, + } + + configureOTG(t, bs, prefixesV4, prefixesV6, communityMembers) + bs.PushAndStart(t) + + t.Log("Verify DUT BGP sessions up") + cfgplugins.VerifyDUTBGPEstablished(t, bs.DUT) + t.Log("Verify OTG BGP sessions up") + cfgplugins.VerifyOTGBGPEstablished(t, bs.ATE) + + return bs +} + +func TestCommunitySetUpdate(t *testing.T) { + bs := testSetup(t) + ipv4 := bs.ATETop.Devices().Items()[1].Ethernets().Items()[0].Ipv4Addresses().Items()[0].Address() + ipv6 := bs.ATETop.Devices().Items()[1].Ethernets().Items()[0].Ipv6Addresses().Items()[0].Address() + + commMatch := [3]string{"100:1"} + configureImportBGPPolicy(t, bs.DUT, ipv4, ipv6, "update_comm_set", commMatch, oc.BgpPolicy_MatchSetOptionsType_INVERT) + validateCommunitySetUpdateTraffic(t, bs) + + // change community match set + commMatch = [3]string{"200:2"} + configureImportBGPPolicy(t, bs.DUT, ipv4, ipv6, "update_comm_set", commMatch, oc.BgpPolicy_MatchSetOptionsType_INVERT) + validateCommunitySetUpdateTraffic(t, bs) +} + +func validateCommunitySetUpdateTraffic(t *testing.T, bs *cfgplugins.BGPSession) { + t.Helper() + + sleepTime := time.Duration(totalPackets/trafficPps) + 2 + bs.ATETop.Flows().Clear() + for index, prefixPairV4 := range prefixesV4 { + configureFlow(t, bs, prefixPairV4, "ipv4", index) + configureFlow(t, bs, prefixesV6[index], "ipv6", index) + } + bs.PushAndStartATE(t) + + // Verify BGP session after its reset with OTG push config & start + cfgplugins.VerifyDUTBGPEstablished(t, bs.DUT) + + t.Logf("Starting traffic for IPv4 and v6") + bs.ATE.OTG().StartTraffic(t) + time.Sleep(sleepTime * time.Second) + bs.ATE.OTG().StopTraffic(t) + otgutils.LogFlowMetrics(t, bs.ATE.OTG(), bs.ATETop) + + testResults := [4]bool{false, false, true, true} + for index, prefixPairV4 := range prefixesV4 { + t.Logf("Validating traffic test for IPv4 prefixes: [%s, %s]. Expected Result: [%t]", prefixPairV4[0], prefixPairV4[1], testResults[index]) + verifyTraffic(t, bs.ATE, "ipv4", testResults[index], index) + t.Logf("Validating traffic test for IPv6 prefixes: [%s, %s]. Expected Result: [%t]", prefixesV6[index][0], prefixesV6[index][1], testResults[index]) + verifyTraffic(t, bs.ATE, "ipv6", testResults[index], index) + } +} diff --git a/feature/experimental/basic_entries_installed_in_gribi/gribi_ip4_entry/feature.textproto b/feature/experimental/basic_entries_installed_in_gribi/gribi_ip4_entry/feature.textproto deleted file mode 100644 index 14e9565fdd7..00000000000 --- a/feature/experimental/basic_entries_installed_in_gribi/gribi_ip4_entry/feature.textproto +++ /dev/null @@ -1,70 +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 -# -# https://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. -# -# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto -# proto-message: FeatureProfile - -id { - name: "experimental_basic_entries_installed_in_gribi_gribi_ip4_entry" - version: 1 -} - -telemetry_path { - path: "/network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/next-hop-group" -} -telemetry_path { - path: "/network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/origin-protocol" -} -telemetry_path { - path: "/network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/prefix" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hop-groups/next-hop-group/id" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/index" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/state/index" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/id" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hops/next-hop/index" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hops/next-hop/interface-ref/state/interface" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hops/next-hop/interface-ref/state/subinterface" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hops/next-hop/state/index" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hops/next-hop/state/ip-address" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hops/next-hop/state/mac-address" -} -telemetry_path { - path: "/network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/decapsulate-header" -} -telemetry_path { - path: "/network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/counters/octets-forwarded" -} -telemetry_path { - path: "/network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/counters/packets-forwarded" -} diff --git a/feature/experimental/gnmi_service/benchmarking_drained_configuration_convergence_time/feature.textproto b/feature/experimental/gnmi_service/benchmarking_drained_configuration_convergence_time/feature.textproto deleted file mode 100644 index fc6bb224159..00000000000 --- a/feature/experimental/gnmi_service/benchmarking_drained_configuration_convergence_time/feature.textproto +++ /dev/null @@ -1,31 +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 -# -# https://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. -# -# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto -# proto-message: FeatureProfile - -id { - name: "experimental_gnmi_service_benchmarking_drained_configuration_convergence_time" - version: 1 -} - -config_path { - path: "/routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-med" -} -config_path { - path: "/routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/repeat-n" -} -config_path { - path: "/routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/asn" -} diff --git a/feature/experimental/gnmi_service/telemetry_port_speed/feature.textproto b/feature/experimental/gnmi_service/telemetry_port_speed/feature.textproto deleted file mode 100644 index f7a6d7df109..00000000000 --- a/feature/experimental/gnmi_service/telemetry_port_speed/feature.textproto +++ /dev/null @@ -1,31 +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 -# -# https://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. -# -# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto -# proto-message: FeatureProfile - -id { - name: "experimental_gnmi_service_telemetry_port_speed" - version: 1 -} - -telemetry_path { - path: "/interfaces/interface/state/oper-status" -} -telemetry_path { - path: "/interfaces/interface/ethernet/state/port-speed" -} -telemetry_path { - path: "/interfaces/interface/aggregation/state/lag-speed" -} diff --git a/feature/experimental/hierarchical_gribi_entries/base_hierarchical_route_installation/feature.textproto b/feature/experimental/hierarchical_gribi_entries/base_hierarchical_route_installation/feature.textproto deleted file mode 100644 index f4d10b21f31..00000000000 --- a/feature/experimental/hierarchical_gribi_entries/base_hierarchical_route_installation/feature.textproto +++ /dev/null @@ -1,73 +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 -# -# https://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. -# -# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto -# proto-message: FeatureProfile - -id { - name: "experimental_hierarchical_gribi_entries_base_hierarchical_route_installation" - version: 1 -} - -telemetry_path { - path: "/network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/next-hop-group" -} -telemetry_path { - path: "/network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/origin-protocol" -} -telemetry_path { - path: "/network-instances/network-instance/afts/ipv4-unicast/ipv4-entry/state/prefix" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hop-groups/next-hop-group/id" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/index" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/state/index" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/id" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hops/next-hop/index" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hops/next-hop/interface-ref/state/interface" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hops/next-hop/interface-ref/state/subinterface" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hops/next-hop/state/index" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hops/next-hop/state/ip-address" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hops/next-hop/state/mac-address" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/backup-next-hop-group" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hop-groups/next-hop-group/state/color" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hops/next-hop/state/origin-protocol" -} -telemetry_path { - path: "/network-instances/network-instance/afts/next-hops/next-hop/state/pushed-mpls-label-stack" -} diff --git a/feature/experimental/hierarchical_gribi_entries/traffic_balancing_according_to_weights/feature.textproto b/feature/experimental/hierarchical_gribi_entries/traffic_balancing_according_to_weights/feature.textproto deleted file mode 100644 index 2f8a1e24a06..00000000000 --- a/feature/experimental/hierarchical_gribi_entries/traffic_balancing_according_to_weights/feature.textproto +++ /dev/null @@ -1,25 +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 -# -# https://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. -# -# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto -# proto-message: FeatureProfile - -id { - name: "experimental_hierarchical_gribi_entries_traffic_balancing_according_to_weights" - version: 1 -} - -telemetry_path { - path: "/network-instances/network-instance/afts/next-hop-groups/next-hop-group/next-hops/next-hop/state/weight" -} diff --git a/feature/experimental/lacp_and_base_interface/aggregate_interfaces/feature.textproto b/feature/experimental/lacp_and_base_interface/aggregate_interfaces/feature.textproto deleted file mode 100644 index b9f58a8ae68..00000000000 --- a/feature/experimental/lacp_and_base_interface/aggregate_interfaces/feature.textproto +++ /dev/null @@ -1,94 +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 -# -# https://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. -# -# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto -# proto-message: FeatureProfile - -id { - name: "experimental_lacp_and_base_interface_aggregate_interfaces" - version: 1 -} - -config_path { - path: "/interfaces/interface/ethernet/config/mac-address" -} -config_path { - path: "/interfaces/interface/ethernet/config/port-speed" -} -config_path { - path: "/interfaces/interface/ethernet/config/duplex-mode" -} -config_path { - path: "/interfaces/interface/ethernet/config/aggregate-id" -} -config_path { - path: "/interfaces/interface/aggregation/config/lag-type" -} -config_path { - path: "/interfaces/interface/aggregation/config/min-links" -} -config_path { - path: "/lacp/config/system-priority" -} -config_path { - path: "/lacp/interfaces/interface/config/name" -} -config_path { - path: "/lacp/interfaces/interface/config/interval" -} -config_path { - path: "/lacp/interfaces/interface/config/lacp-mode" -} -config_path { - path: "/lacp/interfaces/interface/config/system-id-mac" -} -config_path { - path: "/lacp/interfaces/interface/config/system-priority" -} -telemetry_path { - path: "/lacp/interfaces/interface/members/member/state/counters/lacp-in-pkts" -} -telemetry_path { - path: "/lacp/interfaces/interface/members/member/state/counters/lacp-errors" -} -telemetry_path { - path: "/lacp/interfaces/interface/members/member/state/counters/lacp-timeout-transitions" -} -telemetry_path { - path: "/lacp/interfaces/interface/members/member/state/counters/lacp-tx-errors" -} -telemetry_path { - path: "/lacp/interfaces/interface/members/member/state/counters/lacp-out-pkts" -} -telemetry_path { - path: "/lacp/interfaces/interface/members/member/state/counters/lacp-rx-errors" -} -telemetry_path { - path: "/lacp/interfaces/interface/members/member/state/oper-key" -} -telemetry_path { - path: "/lacp/interfaces/interface/members/member/state/last-change" -} -telemetry_path { - path: "/lacp/interfaces/interface/members/member/state/partner-id" -} -telemetry_path { - path: "/lacp/interfaces/interface/members/member/state/system-id" -} -telemetry_path { - path: "/lacp/interfaces/interface/members/member/state/port-num" -} -telemetry_path { - path: "/lacp/interfaces/interface/state/system-priority" -} diff --git a/feature/experimental/platform/tests/breakout_configuration/README.md b/feature/experimental/platform/tests/breakout_configuration/README.md deleted file mode 100644 index d70c053e362..00000000000 --- a/feature/experimental/platform/tests/breakout_configuration/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# PLT-1.1: Interface breakout Test - -## Summary - -Validate Interface breakout configuration. - -## Procedure - - -* This test is carried out for different breakout types -* Connect DUT with ATE to all interfaces in the breakout port -* Configure each interface with test IP addressing -* Verify correct interface state and speed reported -* Verify that DUT responds to ARP/ICMP on all tested interfaces - -## Config Parameter coverage - -* /components/component/port/breakout-mode/groups/group/index -* /components/component/port/breakout-mode/groups/group/config -* /components/component/port/breakout-mode/groups/group/config/index -* /components/component/port/breakout-mode/groups/group/config/num-breakouts -* /components/component/port/breakout-mode/groups/group/config/breakout-speed -* /components/component/port/breakout-mode/groups/group/config/num-physical-channels - - -## Telemetry Parameter coverage - * interfaces/interface/state - * interfaces/interface/ethernet/stateOutput power thresholds: - -## Minimum DUT Platform Requirement - -* Breakout types - 4x100G, 2x100G and 4x10G \ No newline at end of file diff --git a/feature/experimental/route_redistribution/feature.textproto b/feature/experimental/route_redistribution/feature.textproto deleted file mode 100644 index fa276b3ca6b..00000000000 --- a/feature/experimental/route_redistribution/feature.textproto +++ /dev/null @@ -1,86 +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 -# -# https://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. -# -# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto -# proto-message: FeatureProfile - -id { - name: "experimental_route_redistribution" - version: 1 -} - -# https://github.com/openconfig/public/blob/e9e3a82693d1f26c61d7fbf85b3b2d0418d4af9e/doc/network_instance_redistribution.md -# Protocol tables -config_path { - path: "/network-instances/network-instance/tables/table/config/protocol" -} -config_path { - path: "/network-instances/network-instance/tables/table/config/address-family" -} -telemetry_path { - path: "/network-instances/network-instance/tables/table/state/protocol" -} -telemetry_path { - path: "/network-instances/network-instance/tables/table/state/address-family" -} - - -# Table-connections -config_path { - path: "/network-instances/network-instance/table-connections/table-connection/config/src-protocol" -} -config_path { - path: "/network-instances/network-instance/table-connections/table-connection/config/dst-protocol" -} -config_path { - path: "/network-instances/network-instance/table-connections/table-connection/config/address-family" -} -config_path { - path: "/network-instances/network-instance/table-connections/table-connection/config/import-policy" -} -config_path { - path: "/network-instances/network-instance/table-connections/table-connection/config/default-import-policy" -} -telemetry_path { - path: "/network-instances/network-instance/table-connections/table-connection/state/src-protocol" -} -telemetry_path { - path: "/network-instances/network-instance/table-connections/table-connection/state/dst-protocol" -} -telemetry_path { - path: "/network-instances/network-instance/table-connections/table-connection/state/address-family" -} -telemetry_path { - path: "/network-instances/network-instance/table-connections/table-connection/state/import-policy" -} -telemetry_path { - path: "/network-instances/network-instance/table-connections/table-connection/state/default-import-policy" -} - - - -feature_profile_dependency { - name: "bgp" - version: 1 -} - -feature_profile_dependency { - name: "localaggregates" - version: 1 -} - -feature_profile_dependency { - name: "bgp_policybase" - version: 1 -} diff --git a/feature/experimental/telemetry_only/feature.textproto b/feature/experimental/telemetry_only/feature.textproto deleted file mode 100644 index 829203c9478..00000000000 --- a/feature/experimental/telemetry_only/feature.textproto +++ /dev/null @@ -1,459 +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 -# -# https://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. -# -# proto-file: github.com/openconfig/featureprofiles/proto/feature.proto -# proto-message: FeatureProfile - -id { - name: "experimental_telemetry_only" - version: 1 -} - -# Fan -telemetry_path { - path: "/components/component/fan/state/speed" -} - -# Pipeline-counters lookup block -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/lookup-block/state/nexthop-memory" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/lookup-block/state/nexthop-memory-used" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/lookup-block/state/acl-memory-total-entries" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/lookup-block/state/acl-memory-used-entries" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/lookup-block/state/acl-memory-total-bytes" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/lookup-block/state/acl-memory-used-bytes" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/lookup-block/state/lookup-memory" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/lookup-block/state/lookup-memory-used" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/oversubscription" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/no-route" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/no-label" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/no-nexthop" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/invalid-packet" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/forwarding-policy" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/incorrect-software-state" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/rate-limit" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/lookup-block/state/fragment-total-drops" -} - -# Pipeline counters queueing block -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/queueing-block/state/in-bytes" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/queueing-block/state/out-bytes" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/queueing-block/state/queue-memory" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/queueing-block/state/queue-memory-used" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/queueing-block/state/loopback-packets" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/queueing-block/state/loopback-bytes" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/queueing-block/state/oversubscription" -} - -# Pipeline counters fabric block -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/fabric-block/state/in-bytes" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/fabric-block/state/out-bytes" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/fabric-block/state/in-packets" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/fabric-block/state/out-packets" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/fabric-block/state/in-low-priority-cells" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/fabric-block/state/out-low-priority-cells" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/fabric-block/state/in-high-priority-packets" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/fabric-block/state/out-high-priority-packets" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/fabric-block/state/in-low-priority-packets" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/fabric-block/state/out-low-priority-packets" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/fabric-block/state/oversubscription" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/fabric-block/state/lost-packets" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/fabric-block/state/out-high-priority" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/fabric-block/state/fabric-aggregate" -} - -# Pipeline counters host interface block -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/host-interface-block/state/out-packets" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/host-interface-block/state/in-bytes" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/host-interface-block/state/out-bytes" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/host-interface-block/state/fragment-punt-pkts" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/host-interface-block/state/in-high-priority-packets" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/host-interface-block/state/out-high-priority-packets" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/host-interface-block/state/in-low-priority-packets" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/packet/host-interface-block/state/out-low-priority-packets" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/host-interface-block/state/oversubscription" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/host-interface-block/state/rate-limit" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/host-interface-block/state/in-high-priority" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/host-interface-block/state/out-high-priority" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/host-interface-block/state/in-low-priority" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/host-interface-block/state/out-low-priority" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/host-interface-block/state/fragment-punt" -} -telemetry_path { - path: "/components/component/integrated-circuit/pipeline-counters/drop/host-interface-block/state/host-aggregate" -} - - -# Port -telemetry_path { - path: "/components/component/port/breakout-mode/groups/group/state/breakout-speed" -} -telemetry_path { - path: "/components/component/port/breakout-mode/groups/group/state/index" -} -telemetry_path { - path: "/components/component/port/breakout-mode/groups/group/state/num-breakouts" -} -telemetry_path { - path: "/components/component/port/breakout-mode/groups/group/state/num-physical-channels" -} -config_path { - path: "/components/component/port/breakout-mode/groups/group/config/breakout-speed" -} -config_path { - path: "/components/component/port/breakout-mode/groups/group/config/index" -} -config_path { - path: "/components/component/port/breakout-mode/groups/group/config/num-breakouts" -} -config_path { - path: "/components/component/port/breakout-mode/groups/group/config/num-physical-channels" -} - -# Power supply -telemetry_path { - path: "/components/component/power-supply/state/input-current" -} -telemetry_path { - path: "/components/component/power-supply/state/output-current" -} -telemetry_path { - path: "/components/component/power-supply/state/output-voltage" -} - -# integrated circuit backplane -telemetry_path { - path: "/components/component/integrated-circuit/backplane-facing-capacity/state/total" -} -telemetry_path { - path: "/components/component/integrated-circuit/backplane-facing-capacity/state/consumed-capacity" -} -telemetry_path { - path: "/components/component/integrated-circuit/backplane-facing-capacity/state/available-pct" -} - -telemetry_path { - path: "/components/component/properties/property/state/value" -} -telemetry_path { - path: "/components/component/subcomponents/subcomponent/state/name" -} -telemetry_path { - path: "/components/component/state/description" -} -telemetry_path { - path: "/components/component/properties/property/state/value" -} -telemetry_path { - path: "/components/component/state/parent" -} -telemetry_path { - path: "/components/component/subcomponents/subcomponent/state/name" -} -telemetry_path { - path: "/components/component/integrated-circuit/state/node-id" -} -telemetry_path { - path: "/components/component/state/empty" -} -telemetry_path { - path: "/components/component/state/firmware-version" -} -telemetry_path { - path: "/components/component/state/hardware-version" -} -telemetry_path { - path: "/components/component/state/mfg-date" -} -telemetry_path { - path: "/components/component/state/mfg-name" -} -telemetry_path { - path: "/components/component/state/name" -} -telemetry_path { - path: "/components/component/state/oper-status" -} -telemetry_path { - path: "/components/component/state/parent" -} -telemetry_path { - path: "/components/component/state/part-no" -} -telemetry_path { - path: "/components/component/state/serial-no" -} -telemetry_path { - path: "/components/component/state/software-version" -} -telemetry_path { - path: "/components/component/state/temperature/instant" -} -telemetry_path { - path: "/components/component/state/type" -} -telemetry_path { - path: "/components/component/transceiver/physical-channels/channel/state/input-power/instant" -} -telemetry_path { - path: "/components/component/transceiver/physical-channels/channel/state/laser-bias-current/instant" -} -telemetry_path { - path: "/components/component/transceiver/physical-channels/channel/state/output-power/instant" -} -telemetry_path { - path: "/components/component/transceiver/state/form-factor" -} -telemetry_path { - path: "/interfaces/interface/aggregation/state/member" -} -telemetry_path { - path: "/interfaces/interface/ethernet/state/counters/in-maxsize-exceeded" -} -telemetry_path { - path: "/interfaces/interface/hold-time/state/down" -} -telemetry_path { - path: "/interfaces/interface/hold-time/state/up" -} -telemetry_path { - path: "/interfaces/interface/state/counters/carrier-transitions" -} -telemetry_path { - path: "/interfaces/interface/state/counters/in-discards" -} -telemetry_path { - path: "/interfaces/interface/state/counters/in-fcs-errors" -} -telemetry_path { - path: "/interfaces/interface/state/counters/in-pkts" -} -telemetry_path { - path: "/interfaces/interface/state/cpu" -} -telemetry_path { - path: "/interfaces/interface/state/hardware-port" -} -telemetry_path { - path: "/interfaces/interface/state/last-change" -} -telemetry_path { - path: "/interfaces/interface/state/management" -} -telemetry_path { - path: "/interfaces/interface/state/physical-channel" -} -telemetry_path { - path: "/interfaces/interface/state/transceiver" -} -telemetry_path { - path: "/interfaces/interface/subinterfaces/subinterface/ipv4/addresses/address/state/ip" -} -telemetry_path { - path: "/interfaces/interface/subinterfaces/subinterface/ipv4/addresses/address/state/prefix-length" -} -telemetry_path { - path: "/interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/state/ip" -} -telemetry_path { - path: "/interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/state/prefix-length" -} -telemetry_path { - path: "/interfaces/interface/subinterfaces/subinterface/state/index" -} -telemetry_path { - path: "/lacp/interfaces/interface/members/member/state/activity" -} -telemetry_path { - path: "/lacp/interfaces/interface/members/member/state/collecting" -} -telemetry_path { - path: "/lacp/interfaces/interface/members/member/state/distributing" -} -telemetry_path { - path: "/lacp/interfaces/interface/state/system-id-mac" -} -telemetry_path { - path: "/qos/interfaces/interface/output/queues/queue/state/dropped-pkts" -} -telemetry_path { - path: "/qos/interfaces/interface/output/queues/queue/state/name" -} -telemetry_path { - path: "/qos/interfaces/interface/output/queues/queue/state/transmit-octets" -} -telemetry_path { - path: "/qos/interfaces/interface/output/queues/queue/state/transmit-pkts" -} -telemetry_path { - path: "/qos/interfaces/interface/output/scheduler-policy/state/name" -} -telemetry_path { - path: "/system/alarms/alarm/state/id" -} -telemetry_path { - path: "/system/alarms/alarm/state/resource" -} -telemetry_path { - path: "/system/alarms/alarm/state/severity" -} -telemetry_path { - path: "/system/alarms/alarm/state/text" -} -telemetry_path { - path: "/system/alarms/alarm/state/time-created" -} -telemetry_path { - path: "/system/alarms/alarm/state/type-id" -} -telemetry_path { - path: "/system/cpus/cpu/state/total/avg" -} -telemetry_path { - path: "/system/memory/state/counters/correctable-ecc-errors" -} -telemetry_path { - path: "/system/memory/state/counters/uncorrectable-ecc-errors" -} -telemetry_path { - path: "/system/memory/state/free" -} -telemetry_path { - path: "/system/memory/state/physical" -} -telemetry_path { - path: "/system/memory/state/used" -} -telemetry_path { - path: "/system/processes/process/state/cpu-utilization" -} -telemetry_path { - path: "/system/processes/process/state/memory-usage" -} -telemetry_path { - path: "/system/processes/process/state/name" -} -telemetry_path { - path: "/system/processes/process/state/pid" -} -telemetry_path { - path: "/system/state/hostname" -} -config_path { - path: "/components/component/config/name" -} -config_path { - path: "/components/component/integrated-circuit/config/node-id" -} diff --git a/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/metadata.textproto b/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/metadata.textproto index 693fd78a761..7eae9761928 100644 --- a/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/metadata.textproto +++ b/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/metadata.textproto @@ -13,6 +13,7 @@ platform_exceptions: { ipv4_missing_enabled: true interface_counters_from_container: true subinterface_packet_counters_missing: true + interface_counters_update_delayed: true } } platform_exceptions: { diff --git a/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/telemetry_interface_packet_counters_test.go b/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/telemetry_interface_packet_counters_test.go index cf9310999ee..9cc8591a9ab 100644 --- a/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/telemetry_interface_packet_counters_test.go +++ b/feature/gnmi/otg_tests/telemetry_interface_packet_counters_test/telemetry_interface_packet_counters_test.go @@ -244,6 +244,31 @@ func fetchInAndOutPkts(t *testing.T, dut *ondatra.DUTDevice, i1, i2 *interfaces. return inPkts, outPkts } +func waitForCountersUpdate(t *testing.T, dut *ondatra.DUTDevice, i1, i2 *interfaces.InterfacePath, + inTarget, outTarget uint64) (map[string]uint64, map[string]uint64) { + inWatcher := gnmi.Watch(t, dut, i1.Counters().InUnicastPkts().State(), time.Second*60, func(v *ygnmi.Value[uint64]) bool { + got, present := v.Val() + return present && got >= inTarget + }) + outWatcher := gnmi.Watch(t, dut, i2.Counters().OutUnicastPkts().State(), + time.Second*60, func(v *ygnmi.Value[uint64]) bool { + got, present := v.Val() + return present && got >= outTarget + }) + + inPktsV, ok := inWatcher.Await(t) + if !ok { + t.Fatalf("InPkts counter did not update in time") + } + outPktsV, ok := outWatcher.Await(t) + if !ok { + t.Fatalf("OutPkts counter did not update in time") + } + inPkts, _ := inPktsV.Val() + outPkts, _ := outPktsV.Val() + return map[string]uint64{"parent": inPkts}, map[string]uint64{"parent": outPkts} +} + func TestIntfCounterUpdate(t *testing.T) { dut := ondatra.DUT(t, "dut") dp1 := dut.Port(t, "port1") @@ -378,7 +403,14 @@ func TestIntfCounterUpdate(t *testing.T) { } } - dutInPktsAfterTraffic, dutOutPktsAfterTraffic := fetchInAndOutPkts(t, dut, i1, i2) + var dutInPktsAfterTraffic, dutOutPktsAfterTraffic map[string]uint64 + if deviations.InterfaceCountersUpdateDelayed(dut) { + dutInPktsAfterTraffic, dutOutPktsAfterTraffic = waitForCountersUpdate(t, dut, i1, i2, + dutInPktsBeforeTraffic["parent"]+ateInPkts["parent"], + dutOutPktsBeforeTraffic["parent"]+ateOutPkts["parent"]) + } else { + dutInPktsAfterTraffic, dutOutPktsAfterTraffic = fetchInAndOutPkts(t, dut, i1, i2) + } t.Logf("inPkts: %v and outPkts: %v after traffic: ", dutInPktsAfterTraffic, dutOutPktsAfterTraffic) for k := range dutInPktsAfterTraffic { diff --git a/feature/experimental/gribi/otg_tests/backup_nhg_action/README.md b/feature/gribi/otg_tests/backup_nhg_action/README.md similarity index 95% rename from feature/experimental/gribi/otg_tests/backup_nhg_action/README.md rename to feature/gribi/otg_tests/backup_nhg_action/README.md index c500f4c352d..5a99843fca5 100644 --- a/feature/experimental/gribi/otg_tests/backup_nhg_action/README.md +++ b/feature/gribi/otg_tests/backup_nhg_action/README.md @@ -94,15 +94,18 @@ Different test scenarios requires different setups. traffic with decapsulated traffic with destination IP as `InnerDstIP_1` at ATE port-4. -## Config Parameter coverage - -No new configuration covered. - -## Telemetry Parameter coverage - -No new telemetry covered. - -## Protocol/RPC Parameter coverage +## OpenConfig Path and RPC Coverage +```yaml +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: + gribi: + gRIBI.Get: + gRIBI.Modify: + gRIBI.Flush: +``` ## Minimum DUT platform requirement diff --git a/feature/experimental/gribi/otg_tests/backup_nhg_action/backup_nhg_action_test.go b/feature/gribi/otg_tests/backup_nhg_action/backup_nhg_action_test.go similarity index 100% rename from feature/experimental/gribi/otg_tests/backup_nhg_action/backup_nhg_action_test.go rename to feature/gribi/otg_tests/backup_nhg_action/backup_nhg_action_test.go diff --git a/feature/experimental/gribi/otg_tests/backup_nhg_action/metadata.textproto b/feature/gribi/otg_tests/backup_nhg_action/metadata.textproto similarity index 100% rename from feature/experimental/gribi/otg_tests/backup_nhg_action/metadata.textproto rename to feature/gribi/otg_tests/backup_nhg_action/metadata.textproto diff --git a/feature/gribi/otg_tests/backup_ngp_multiple_nh_pbf_test/README.md b/feature/gribi/otg_tests/backup_nhg_multiple_nh_pbf_test/README.md similarity index 100% rename from feature/gribi/otg_tests/backup_ngp_multiple_nh_pbf_test/README.md rename to feature/gribi/otg_tests/backup_nhg_multiple_nh_pbf_test/README.md diff --git a/feature/gribi/otg_tests/backup_ngp_multiple_nh_pbf_test/backup_nhg_multiple_nh_pbf_test.go b/feature/gribi/otg_tests/backup_nhg_multiple_nh_pbf_test/backup_nhg_multiple_nh_pbf_test.go similarity index 100% rename from feature/gribi/otg_tests/backup_ngp_multiple_nh_pbf_test/backup_nhg_multiple_nh_pbf_test.go rename to feature/gribi/otg_tests/backup_nhg_multiple_nh_pbf_test/backup_nhg_multiple_nh_pbf_test.go diff --git a/feature/gribi/otg_tests/backup_ngp_multiple_nh_pbf_test/metadata.textproto b/feature/gribi/otg_tests/backup_nhg_multiple_nh_pbf_test/metadata.textproto similarity index 100% rename from feature/gribi/otg_tests/backup_ngp_multiple_nh_pbf_test/metadata.textproto rename to feature/gribi/otg_tests/backup_nhg_multiple_nh_pbf_test/metadata.textproto diff --git a/feature/experimental/backup_nhg/otg_tests/backup_nhg_test/README.md b/feature/gribi/otg_tests/backup_nhg_single_nh_test/README.md similarity index 82% rename from feature/experimental/backup_nhg/otg_tests/backup_nhg_test/README.md rename to feature/gribi/otg_tests/backup_nhg_single_nh_test/README.md index bf5f86fcab1..0d940b7de61 100644 --- a/feature/experimental/backup_nhg/otg_tests/backup_nhg_test/README.md +++ b/feature/gribi/otg_tests/backup_nhg_single_nh_test/README.md @@ -31,21 +31,18 @@ containing a single NH. * Interface DUT port-2 is disabled. * Remove the entry for 192.0.2.254/32. -## Config Parameter coverage - -No new configuration covered. - -## Telemetry Parameter coverage - -No new telemetry covered. - -## Protocol/RPC Parameter coverage - -* gRIBI - * Modify - * ModifyRequest - * NextHopGroup - * backup_nexthop_group +## OpenConfig Path and RPC Coverage +```yaml +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: + gribi: + gRIBI.Get: + gRIBI.Modify: + gRIBI.Flush: +``` ## Minimum DUT platform requirement diff --git a/feature/experimental/backup_nhg/otg_tests/backup_nhg_test/backup_nhg_test.go b/feature/gribi/otg_tests/backup_nhg_single_nh_test/backup_nhg_test.go similarity index 100% rename from feature/experimental/backup_nhg/otg_tests/backup_nhg_test/backup_nhg_test.go rename to feature/gribi/otg_tests/backup_nhg_single_nh_test/backup_nhg_test.go diff --git a/feature/experimental/backup_nhg/otg_tests/backup_nhg_test/metadata.textproto b/feature/gribi/otg_tests/backup_nhg_single_nh_test/metadata.textproto similarity index 100% rename from feature/experimental/backup_nhg/otg_tests/backup_nhg_test/metadata.textproto rename to feature/gribi/otg_tests/backup_nhg_single_nh_test/metadata.textproto diff --git a/feature/gribi/otg_tests/gribi_route_test/README.md b/feature/gribi/otg_tests/gribi_route_test/README.md new file mode 100644 index 00000000000..2f709e4ab43 --- /dev/null +++ b/feature/gribi/otg_tests/gribi_route_test/README.md @@ -0,0 +1,174 @@ +# RT-14.2: GRIBI Route Test + +## Summary + +Ensure Traffic is Encap/Decap to NextHop based on Gribi structure. + +## Topology + +ATE port-1 <------> port-1 DUT +DUT port-2 <------> port-2 ATE +DUT port-3 <------> port-3 ATE + +## Variables +``` +# Magic source IP addresses used in this test + * ipv4_outer_src_111 = 198.51.100.111 + * ipv4PrefixEncapped = ipv4InnerDst = 138.0.11.8 + * ipv4PrefixNotEncapped = ipv4OuterDst222 = 198.50.100.65 +``` + +## Baseline + +### VRF Selection Policy + +``` +network-instances { + network-instance { + name: DEFAULT + policy-forwarding { + policies { + policy { + policy-id: "vrf_selection_policy_c" + rules { + rule { + sequence-id: 1 + ipv4 { + protocol: 4 + source-address: "ipv4_outer_src_111" + } + action { + network-instance: "ENCAP_TE_VRF_A" + } + } + rule { + sequence-id: 2 + ipv4 { + protocol: 41 + dscp-set: [dscp_encap_a_1, dscp_encap_a_2] + source-address: "ipv4_outer_src_222" + } + action { + network-instance: "TRANSIT_TE_VRF" + } + } + } + } + } + } + } +} +``` +``` +### Install the following gRIBI AFTs. + +- IPv4Entry {0.0.0.0/0 (TRANSIT_TE_VRF)} -> NHG#1 (DEFAULT VRF) -> { + {NH#1, DEFAULT VRF, weight:1}, + } + NH#1 -> { + decapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 + network_instance: "DEFAULT" + } +- IPv4Entry {198.50.100.64/32 (TRANSIT_TE_VRF)} -> NHG#2 (DEFAULT VRF) -> { + {NH#2, DEFAULT VRF, weight:1}, interface-ref:dut-port-2-interface, + } +- IPv4Entry {198.50.100.64/32 (TE_VRF_111)} -> NHG#3 (DEFAULT VRF) -> { + {NH#3, DEFAULT VRF, weight:1}, interface-ref:dut-port-2-interface, + } +- IPv4Entry {0.0.0.0/0 (ENCAP_TE_VRF_A)} -> NHG#5 (DEFAULT VRF) -> { + {NH#5, DEFAULT VRF, weight:1, interface-ref:dut-port-3-interface}, + } +- IPv4Entry {138.0.11.8/32 (ENCAP_TE_VRF_A)} -> NHG#4 (DEFAULT VRF) -> { + {NH#4, DEFAULT VRF, weight:1}, + } + NH#4 -> { + encapsulate_header: OPENCONFIGAFTTYPESENCAPSULATIONHEADERTYPE_IPV4 + ip_in_ip { + dst_ip: "198.50.100.64" + src_ip: "ipv4_outer_src_111" + } + network_instance: "TE_VRF_111" + } +``` +- Install a BGP route in default VRF to route traffic out of DUT port-3. + +## Procedure + +The DUT should be reset to the baseline after each of the following tests. + +Test-1, Match on source prefix, flow hits ENCAP_TE_VRF_A followed by TE_VRF_111 + +``` + 1. Send flow with source IP ipv4_outer_src_111 with destination IP ipv4PrefixEncapped. + 2. Verify v4 packet matched with tunnel prefix and encapped -> hit TE_VRF_111 + and egress via port-2. + 3. No traffic loss in steady state + +``` +Test-2, Match on source prefix, flow hits ENCAP_TE_VRF_A followed by Default VRF + +``` + 1. Send flow with source IP ipv4_outer_src_111 with destination IP ipv4PrefixNotEncapped. + 2. Verify v4 packet not matched with tunnel prefix and egress via port-3. + 3. No traffic loss in steady state + +``` +Test-3, Match on source prefix and protocol, flow hits TRANSIT_TE_VRF +match with Tunnel prefix /32 + +``` + 1. Send the following 4in4 flows to DUT port-1: + * inner_src: `ipv4_inner_src` + * inner_dst: `ipv4InnerDst` + * outter_src: `ipv4_outter_src_111` + * outter_dst: `ipv4_outter_decap_no_match` + * proto: `4` + 2. Verify packet matched with tunnel prefix and egress via port-2. + 3. No traffic loss in steady state + +``` +Test-4, Match on source prefix and protocol, flow hits TRANSIT_TE_VRF matched with 0/0 prefix, decap & sent to default vrf +``` + 1. Send the following 4in4 flows to DUT port-1: + * inner_src: `ipv4_inner_src` + * inner_dst: `ipv4InnerDst` + * outter_src: `ipv4_outter_src_111` + * outter_dst: `ipv4_outter_decap_match` + * proto: `4` + 2. Verify packet not matched with tunnel prefix, decap and failback + to default vrf. + 3. No traffic loss in steady state + +``` +## Config Parameter Coverage + +* network-instances/network-instance/name +* network-instances/network-instance/policy-forwarding/policies/policy/policy-id +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/sequence-id +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/protocol +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/source-address +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/source-address +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/config/network-instance + +## Telemetry Parameter Coverage + +* network-instances/network-instance/name +* network-instances/network-instance/policy-forwarding/policies/policy/policy-id +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/sequence-id +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/protocol +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv4/source-address +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/ipv6/source-address +* network-instances/network-instance/policy-forwarding/policies/policy/rules/rule/action/config/network-instance + +## OpenConfig Path and RPC Coverage +```yaml +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: + gribi: + gRIBI.Get: + gRIBI.Modify: + gRIBI.Flush: +``` diff --git a/feature/gribi/otg_tests/gribi_route_test/gribi_route_test.go b/feature/gribi/otg_tests/gribi_route_test/gribi_route_test.go new file mode 100644 index 00000000000..2038b0e1899 --- /dev/null +++ b/feature/gribi/otg_tests/gribi_route_test/gribi_route_test.go @@ -0,0 +1,726 @@ +package gribi_route_test + +import ( + "context" + "fmt" + "log" + "os" + "strconv" + "testing" + "time" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "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/gribi" + "github.com/openconfig/featureprofiles/internal/otgutils" + "github.com/openconfig/gribigo/chk" + "github.com/openconfig/gribigo/constants" + "github.com/openconfig/gribigo/fluent" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ondatra/otg" + "github.com/openconfig/ygnmi/ygnmi" + "github.com/openconfig/ygot/ygot" +) + +const ( + niTransitTeVrf = "TRANSIT_TE_VRF" + niEncapTeVrfA = "ENCAP_TE_VRF_A" + niTEVRF111 = "TE_VRF_111" + vrfPolC = "vrf_selection_policy_c" + seqIDBase = uint32(10) + ipv4OuterSrc111 = "198.51.100.111" + ipv4OuterSrc111WithMask = "198.51.100.111/32" + ipv4InnerDst = "138.0.11.8" + ipv4OuterDst111 = "198.50.100.64" + ipv4OuterDst222 = "198.50.100.65" + peerGrpName = "BGP-PEER-GROUP1" + asn = 65501 + tolerancePct = 2 + checkEncap = true +) + +var ( + dutPort1 = attrs.Attributes{ + Desc: "DUT Port 1", + IPv4: "192.0.2.1", + IPv4Len: 30, + } + dutPort2 = attrs.Attributes{ + Desc: "DUT Port 2", + IPv4: "192.0.2.5", + IPv4Len: 30, + } + dutPort3 = attrs.Attributes{ + Desc: "DUT Port 3", + IPv4: "192.0.2.9", + IPv4Len: 30, + } + + atePort1 = attrs.Attributes{ + Name: "port1", + MAC: "02:00:01:01:01:01", + Desc: "ATE Port 1", + IPv4: "192.0.2.2", + IPv4Len: 30, + } + atePort2 = attrs.Attributes{ + Name: "port2", + MAC: "02:00:02:01:01:01", + Desc: "ATE Port 2", + IPv4: "192.0.2.6", + IPv4Len: 30, + } + atePort3 = attrs.Attributes{ + Name: "port3", + MAC: "02:00:03:01:01:01", + Desc: "ATE Port 3", + IPv4: "192.0.2.10", + IPv4Len: 30, + } +) + +type bgpNeighbor struct { + Name string + dutIPv4 string + ateIPv4 string + MAC string +} + +var ( + bgpNbr1 = bgpNeighbor{ + Name: "port1", + dutIPv4: "192.0.2.1", + ateIPv4: "192.0.2.2", + MAC: "02:00:01:01:01:01", + } + bgpNbr2 = bgpNeighbor{ + Name: "port2", + dutIPv4: "192.0.2.5", + ateIPv4: "192.0.2.6", + MAC: "02:00:02:01:01:01", + } + bgpNbr3 = bgpNeighbor{ + Name: "port3", + dutIPv4: "192.0.2.9", + ateIPv4: "192.0.2.10", + MAC: "02:00:03:01:01:01", + } +) + +type packetValidation struct { + portName string + outDstIP []string + inHdrIP string + validateDecap bool + validateNoDecap bool + validateEncap bool +} + +type policyFwRule struct { + SeqID uint32 + family string + protocol oc.UnionUint8 + dscpSet []uint8 + sourceAddr string + ni string +} + +// testArgs holds the objects needed by a test case. +type testArgs struct { + dut *ondatra.DUTDevice + ctx context.Context + client *fluent.GRIBIClient + ate *ondatra.ATEDevice + otgConfig gosnappi.Config + otg *otg.OTG +} + +type flowArgs struct { + flowName string + outHdrSrcIP, outHdrDstIP string + InnHdrSrcIP, InnHdrDstIP string + InnHdrSrcIPv6, InnHdrDstIPv6 string + isIPInIP bool +} + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func TestGRIBIFailover(t *testing.T) { + dut := ondatra.DUT(t, "dut") + configureDUT(t, dut) + ate := ondatra.ATE(t, "ate") + top := configureOTG(t, ate) + t.Log("Configure VRF_Policy") + configureVrfSelectionPolicyC(t, dut) + t.Log("Configure GRIBI") + configureGribiRoute(t, dut) + + llAddress, found := gnmi.Watch(t, ate.OTG(), gnmi.OTG().Interface("port1.Eth").Ipv4Neighbor(dutPort1.IPv4).LinkLayerAddress().State(), time.Minute, func(val *ygnmi.Value[string]) bool { + return val.IsPresent() + }).Await(t) + if !found { + t.Fatalf("Could not get the LinkLayerAddress %s", llAddress) + } + dstMac, _ := llAddress.Val() + + verifyBgpTelemetry(t, dut) + + args := &testArgs{ + dut: dut, + ate: ate, + otgConfig: top, + otg: ate.OTG(), + } + t.Run("RT-14.2.1: Traffic Prefix Match to Tunnel Prefix, Encapped and Egress via Port2", func(t *testing.T) { + flow := createFlow(&flowArgs{flowName: "flow4in4", + InnHdrSrcIP: ipv4OuterSrc111, InnHdrDstIP: ipv4InnerDst}, dstMac) + sendTraffic(t, args, top, ate, flow, 30, []string{"port2"}) + if ok := verifyTrafficFlow(t, ate, flow); !ok { + t.Fatal("Packet Dropped, LossPct for flow ") + } + captureAndValidatePackets(t, args, &packetValidation{portName: atePort2.Name, + outDstIP: []string{ipv4OuterDst111}, inHdrIP: ipv4InnerDst, validateEncap: true}) + }) + + t.Run("RT-14.2.2: Traffic Prefix not Matched to Tunnel Prefix, Egress via Port3", func(t *testing.T) { + flow := createFlow(&flowArgs{flowName: "flow4in4", + InnHdrSrcIP: ipv4OuterSrc111, InnHdrDstIP: ipv4OuterDst222}, dstMac) + sendTraffic(t, args, top, ate, flow, 30, []string{"port3"}) + if ok := verifyTrafficFlow(t, ate, flow); !ok { + t.Fatal("Packet Dropped, LossPct for flow ") + } + }) + + t.Run("RT-14.2.3: Traffic Match to Transit_Vrf, Match Tunnel Prefix Egress to Port2", func(t *testing.T) { + flow := createFlow(&flowArgs{flowName: "flow4in4", + outHdrSrcIP: ipv4OuterSrc111, outHdrDstIP: ipv4OuterDst111, + InnHdrSrcIP: ipv4OuterSrc111, InnHdrDstIP: ipv4InnerDst, isIPInIP: true}, dstMac) + sendTraffic(t, args, top, ate, flow, 30, []string{"port2"}) + if ok := verifyTrafficFlow(t, ate, flow); !ok { + t.Fatal("Packet Dropped, LossPct for flow ") + } + captureAndValidatePackets(t, args, &packetValidation{portName: atePort2.Name, + outDstIP: []string{ipv4OuterDst111}, inHdrIP: ipv4InnerDst, validateNoDecap: true}) + }) + + t.Run("RT-14.2.4: Traffic Match to Transit_Vrf, noMatch Tunnel Prefix Egress to Port3", func(t *testing.T) { + flow := createFlow(&flowArgs{flowName: "flow4in4", + outHdrSrcIP: ipv4OuterSrc111, outHdrDstIP: ipv4OuterDst222, + InnHdrSrcIP: ipv4OuterSrc111, InnHdrDstIP: ipv4InnerDst, isIPInIP: true}, dstMac) + sendTraffic(t, args, top, ate, flow, 30, []string{"port3"}) + if ok := verifyTrafficFlow(t, ate, flow); !ok { + t.Fatal("Packet Dropped, LossPct for flow ") + } + captureAndValidatePackets(t, args, &packetValidation{portName: atePort3.Name, + outDstIP: []string{ipv4OuterDst222}, inHdrIP: ipv4InnerDst, validateDecap: true}) + }) +} + +// configureDUT configures port1-3 on the DUT. +func configureDUT(t *testing.T, dut *ondatra.DUTDevice) { + t.Logf("configureDUT") + p1 := dut.Port(t, "port1") + p2 := dut.Port(t, "port2") + p3 := dut.Port(t, "port3") + + gnmi.Replace(t, dut, gnmi.OC().Interface(p1.Name()).Config(), dutPort1.NewOCInterface(p1.Name(), dut)) + gnmi.Replace(t, dut, gnmi.OC().Interface(p2.Name()).Config(), dutPort2.NewOCInterface(p2.Name(), dut)) + gnmi.Replace(t, dut, gnmi.OC().Interface(p3.Name()).Config(), dutPort3.NewOCInterface(p3.Name(), dut)) + + if deviations.ExplicitPortSpeed(dut) { + fptest.SetPortSpeed(t, p1) + fptest.SetPortSpeed(t, p2) + fptest.SetPortSpeed(t, p3) + } + if deviations.ExplicitInterfaceInDefaultVRF(dut) { + fptest.AssignToNetworkInstance(t, dut, p1.Name(), deviations.DefaultNetworkInstance(dut), 0) + fptest.AssignToNetworkInstance(t, dut, p2.Name(), deviations.DefaultNetworkInstance(dut), 0) + fptest.AssignToNetworkInstance(t, dut, p3.Name(), deviations.DefaultNetworkInstance(dut), 0) + } + configNonDefaultNetworkInstance(t, dut) + dutConfPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + gnmi.Delete(t, dut, dutConfPath.Config()) + dutConf := bgpCreateNbr(asn, dut) + gnmi.Replace(t, dut, dutConfPath.Config(), dutConf) +} + +func bgpCreateNbr(localAs uint32, dut *ondatra.DUTDevice) *oc.NetworkInstance_Protocol { + dutOcRoot := &oc.Root{} + ni1 := dutOcRoot.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + niProto := ni1.GetOrCreateProtocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP") + bgp := niProto.GetOrCreateBgp() + + global := bgp.GetOrCreateGlobal() + global.RouterId = ygot.String(dutPort3.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) + pg1 := bgp.GetOrCreatePeerGroup(peerGrpName) + pg1.PeerAs = ygot.Uint32(localAs) + + bgpNbr := bgp.GetOrCreateNeighbor(bgpNbr3.ateIPv4) + bgpNbr.PeerGroup = ygot.String(peerGrpName) + bgpNbr.PeerAs = ygot.Uint32(localAs) + bgpNbr.Enabled = ygot.Bool(true) + bgpNbrT := bgpNbr.GetOrCreateTransport() + bgpNbrT.LocalAddress = ygot.String(bgpNbr3.dutIPv4) + af4 := bgpNbr.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST) + af4.Enabled = ygot.Bool(true) + af6 := bgpNbr.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST) + af6.Enabled = ygot.Bool(true) + + return niProto +} + +// configureOTGBGP configure BGP on ATE +func configureOTGBGP(t *testing.T, dev gosnappi.Device, top gosnappi.Config, nbr bgpNeighbor) { + t.Helper() + iDutBgp := dev.Bgp().SetRouterId(nbr.ateIPv4) + iDutBgp4Peer := iDutBgp.Ipv4Interfaces().Add().SetIpv4Name(nbr.Name + ".IPv4").Peers().Add().SetName(nbr.Name + ".BGP4.peer") + iDutBgp4Peer.SetPeerAddress(nbr.dutIPv4).SetAsNumber(asn).SetAsType(gosnappi.BgpV4PeerAsType.IBGP) + iDutBgp4Peer.LearnedInformationFilter().SetUnicastIpv4Prefix(true).SetUnicastIpv6Prefix(false) + + bgpNeti1Bgp4PeerRoutes := iDutBgp4Peer.V4Routes().Add().SetName(nbr.Name + ".BGP4.Route") + bgpNeti1Bgp4PeerRoutes.SetNextHopIpv4Address(nbr.ateIPv4). + SetNextHopAddressType(gosnappi.BgpV4RouteRangeNextHopAddressType.IPV4). + SetNextHopMode(gosnappi.BgpV4RouteRangeNextHopMode.MANUAL) + bgpNeti1Bgp4PeerRoutes.Addresses().Add().SetAddress(ipv4InnerDst).SetPrefix(32).SetCount(1) +} + +func configureOTG(t *testing.T, ate *ondatra.ATEDevice) gosnappi.Config { + t.Logf("configureOTG") + config := gosnappi.NewConfig() + var dev gosnappi.Device + for i, ap := range []bgpNeighbor{bgpNbr1, bgpNbr2, bgpNbr3} { + // DUT and ATE ports are connected by the same names. + port := config.Ports().Add().SetName(ap.Name) + portName := fmt.Sprintf("port%s", strconv.Itoa(i+1)) + dev = config.Devices().Add().SetName(portName) + eth := dev.Ethernets().Add().SetName(portName + ".Eth").SetMac(ap.MAC) + eth.Connection().SetPortName(port.Name()) + eth.Ipv4Addresses().Add().SetName(portName + ".IPv4"). + SetAddress(ap.ateIPv4).SetGateway(ap.dutIPv4). + SetPrefix(30) + } + configureOTGBGP(t, dev, config, bgpNbr3) + ate.OTG().PushConfig(t, config) + ate.OTG().StartProtocols(t) + return config +} + +// seqIDOffset returns sequence ID offset added with seqIDBase (10), to avoid sequences +// like 1, 10, 11, 12,..., 2, 21, 22, ... while being sent by Ondatra to the DUT. +// It now generates sequences like 11, 12, 13, ..., 19, 20, 21,..., 99. +func seqIDOffset(dut *ondatra.DUTDevice, i uint32) uint32 { + if deviations.PfRequireSequentialOrderPbrRules(dut) { + return i + seqIDBase + } + return i +} + +// configureNetworkInstance configures vrfs DECAP_TE_VRF,ENCAP_TE_VRF_A,ENCAP_TE_VRF_B, +// TE_VRF_222, TE_VRF_111. +func configNonDefaultNetworkInstance(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + c := &oc.Root{} + vrfs := []string{niTransitTeVrf, niEncapTeVrfA, niTEVRF111} + for _, vrf := range vrfs { + ni := c.GetOrCreateNetworkInstance(vrf) + ni.Type = oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_L3VRF + gnmi.Replace(t, dut, gnmi.OC().NetworkInstance(vrf).Config(), ni) + } + gnmi.Update(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Name().Config(), deviations.DefaultNetworkInstance(dut)) +} + +func configureVrfSelectionPolicyC(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + d := &oc.Root{} + time.Sleep(100 * time.Second) + dutPolFwdPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).PolicyForwarding() + + pfRule1 := &policyFwRule{SeqID: 1, family: "ipv4", protocol: 4, sourceAddr: ipv4OuterSrc111WithMask, + ni: niTransitTeVrf} + pfRule2 := &policyFwRule{SeqID: 2, family: "ipv4", sourceAddr: ipv4OuterSrc111WithMask, + ni: niEncapTeVrfA} + + pfRuleList := []*policyFwRule{pfRule1, pfRule2} + ni := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)) + niP := ni.GetOrCreatePolicyForwarding() + niPf := niP.GetOrCreatePolicy(vrfPolC) + niPf.SetType(oc.Policy_Type_VRF_SELECTION_POLICY) + for _, pfRule := range pfRuleList { + pfR := niPf.GetOrCreateRule(seqIDOffset(dut, pfRule.SeqID)) + if pfRule.family == "ipv4" { + pfRProtoIP := pfR.GetOrCreateIpv4() + if pfRule.protocol != 0 { + pfRProtoIP.Protocol = oc.UnionUint8(pfRule.protocol) + } + if pfRule.sourceAddr != "" { + pfRProtoIP.SourceAddress = ygot.String(pfRule.sourceAddr) + } + } else if pfRule.family == "ipv6" { + pfRProtoIP := pfR.GetOrCreateIpv6() + if pfRule.dscpSet != nil { + pfRProtoIP.DscpSet = pfRule.dscpSet + } + } + + pfRAction := pfR.GetOrCreateAction() + pfRAction.NetworkInstance = ygot.String(pfRule.ni) + } + p1 := dut.Port(t, "port1") + interfaceID := p1.Name() + if deviations.InterfaceRefInterfaceIDFormat(dut) { + interfaceID = interfaceID + ".0" + } + intf := niP.GetOrCreateInterface(interfaceID) + intf.ApplyVrfSelectionPolicy = ygot.String(vrfPolC) + intf.GetOrCreateInterfaceRef().Interface = ygot.String(p1.Name()) + intf.GetOrCreateInterfaceRef().Subinterface = ygot.Uint32(0) + if deviations.InterfaceRefConfigUnsupported(dut) { + intf.InterfaceRef = nil + } + // gnmi.Update(t, dut, gnmi.OC().NetworkInstance("DEFAULT").Name().Config(), "DEFAULT") + gnmi.Replace(t, dut, dutPolFwdPath.Config(), niP) +} + +func configureGribiRoute(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + ctx := context.Background() + gribic := dut.RawAPIs().GRIBI(t) + client := fluent.NewClient() + client.Connection().WithStub(gribic).WithPersistence().WithInitialElectionID(12, 0). + WithRedundancyMode(fluent.ElectedPrimaryClient).WithFIBACK() + client.Start(ctx, t) + defer client.Stop(t) + gribi.FlushAll(client) + client.StartSending(ctx, t) + gribi.BecomeLeader(t, client) + + tcArgs := &testArgs{ + ctx: ctx, + client: client, + dut: dut, + } + tcArgs.client.Modify().AddEntry(t, + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(tcArgs.dut)). + WithIndex(uint64(1)).WithDecapsulateHeader(fluent.IPinIP). + WithNextHopNetworkInstance(deviations.DefaultNetworkInstance(dut)), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(tcArgs.dut)). + WithID(uint64(1)).AddNextHop(uint64(1), uint64(1)), + + fluent.IPv4Entry().WithNetworkInstance(niTransitTeVrf).WithNextHopGroupNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithPrefix("0.0.0.0/0").WithNextHopGroup(uint64(1))) + + if err := awaitTimeout(tcArgs.ctx, t, tcArgs.client, 90*time.Second); err != nil { + t.Logf("Could not program entries via client, got err, check error codes: %v", err) + } + + tcArgs.client.Modify().AddEntry(t, + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(tcArgs.dut)). + WithIndex(uint64(2)).WithIPAddress(atePort2.IPv4), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(tcArgs.dut)). + WithID(uint64(2)).AddNextHop(uint64(2), uint64(1)), + + fluent.IPv4Entry().WithNetworkInstance(niTransitTeVrf).WithNextHopGroupNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithPrefix(ipv4OuterDst111+"/32").WithNextHopGroup(uint64(2))) + + if err := awaitTimeout(tcArgs.ctx, t, tcArgs.client, 90*time.Second); err != nil { + t.Logf("Could not program entries via client, got err, check error codes: %v", err) + } + + defaultVRFIPList := []string{"0.0.0.0/0", ipv4OuterDst111 + "/32"} + for ip := range defaultVRFIPList { + chk.HasResult(t, tcArgs.client.Results(t), + fluent.OperationResult(). + WithIPv4Operation(defaultVRFIPList[ip]). + WithOperationType(constants.Add). + WithProgrammingResult(fluent.InstalledInFIB). + AsResult(), + chk.IgnoreOperationID(), + ) + } + + tcArgs.client.Modify().AddEntry(t, + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(tcArgs.dut)). + WithIndex(uint64(3)).WithIPAddress(atePort2.IPv4), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(tcArgs.dut)). + WithID(uint64(3)).AddNextHop(uint64(3), uint64(1)), + + fluent.IPv4Entry().WithNetworkInstance(niTEVRF111). + WithNextHopGroupNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithPrefix(ipv4OuterDst111+"/32").WithNextHopGroup(uint64(3))) + + if err := awaitTimeout(tcArgs.ctx, t, tcArgs.client, 90*time.Second); err != nil { + t.Logf("Could not program entries via client, got err, check error codes: %v", err) + } + + chk.HasResult(t, tcArgs.client.Results(t), + fluent.OperationResult(). + WithIPv4Operation(ipv4OuterDst111+"/32"). + WithOperationType(constants.Add). + WithProgrammingResult(fluent.InstalledInFIB). + AsResult(), + chk.IgnoreOperationID(), + ) + // Encap + tcArgs.client.Modify().AddEntry(t, + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(tcArgs.dut)). + WithIndex(uint64(4)).WithEncapsulateHeader(fluent.IPinIP).WithIPinIP(ipv4OuterSrc111, ipv4OuterDst111). + WithNextHopNetworkInstance(niTEVRF111), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(tcArgs.dut)). + WithID(uint64(4)).AddNextHop(uint64(4), uint64(1)), + + fluent.IPv4Entry().WithNetworkInstance(niEncapTeVrfA). + WithNextHopGroupNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithPrefix(ipv4InnerDst+"/32").WithNextHopGroup(uint64(4))) + + if err := awaitTimeout(tcArgs.ctx, t, tcArgs.client, 90*time.Second); err != nil { + t.Logf("Could not program entries via client, got err, check error codes: %v", err) + } + + tcArgs.client.Modify().AddEntry(t, + fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(tcArgs.dut)). + WithIndex(uint64(5)).WithIPAddress(atePort3.IPv4), + fluent.NextHopGroupEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(tcArgs.dut)). + WithID(uint64(5)).AddNextHop(uint64(5), uint64(1)), + + fluent.IPv4Entry().WithNetworkInstance(niEncapTeVrfA). + WithNextHopGroupNetworkInstance(deviations.DefaultNetworkInstance(dut)). + WithPrefix("0.0.0.0/0").WithNextHopGroup(uint64(5))) + + if err := awaitTimeout(tcArgs.ctx, t, tcArgs.client, 90*time.Second); err != nil { + t.Logf("Could not program entries via client, got err, check error codes: %v", err) + } + + defaultVRFIPList = []string{"0.0.0.0/0", ipv4InnerDst + "/32"} + for ip := range defaultVRFIPList { + chk.HasResult(t, tcArgs.client.Results(t), + fluent.OperationResult(). + WithIPv4Operation(defaultVRFIPList[ip]). + WithOperationType(constants.Add). + WithProgrammingResult(fluent.InstalledInFIB). + AsResult(), + chk.IgnoreOperationID(), + ) + } + +} + +// awaitTimeout calls a fluent client Await, adding a timeout to the context. +func awaitTimeout(ctx context.Context, t testing.TB, c *fluent.GRIBIClient, timeout time.Duration) error { + t.Helper() + subctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + return c.Await(subctx, t) +} + +func createFlow(flowValues *flowArgs, dstMac string) gosnappi.Flow { + flow := gosnappi.NewFlow().SetName(flowValues.flowName) + flow.Metrics().SetEnable(true) + flow.Size().SetFixed(512) + flow.Rate().SetPps(100) + flow.Duration().Continuous() + ethHeader := flow.Packet().Add().Ethernet() + ethHeader.Src().SetValue(atePort1.MAC) + ethHeader.Dst().SetValue(dstMac) + // Outer IP header + if flowValues.isIPInIP { + outerIPHdr := flow.Packet().Add().Ipv4() + outerIPHdr.Src().SetValue(flowValues.outHdrSrcIP) + outerIPHdr.Dst().SetValue(flowValues.outHdrDstIP) + innerIPHdr := flow.Packet().Add().Ipv4() + innerIPHdr.Src().SetValue(flowValues.InnHdrSrcIP) + innerIPHdr.Dst().SetValue(flowValues.InnHdrDstIP) + } else { + innerIPHdr := flow.Packet().Add().Ipv4() + innerIPHdr.Src().SetValue(flowValues.InnHdrSrcIP) + innerIPHdr.Dst().SetValue(flowValues.InnHdrDstIP) + } + return flow +} + +// testTraffic sends traffic flow for duration seconds and returns the +// number of packets sent out. +func sendTraffic(t *testing.T, args *testArgs, top gosnappi.Config, ate *ondatra.ATEDevice, flow gosnappi.Flow, duration int, port []string) { + t.Helper() + top.Flows().Clear() + + args.otgConfig.Captures().Clear() + args.otgConfig.Captures().Add().SetName("packetCapture"). + SetPortNames(port). + SetFormat(gosnappi.CaptureFormat.PCAP) + + flow.TxRx().Port().SetTxName("port1").SetRxNames([]string{"port2", "port3"}) + flow.Metrics().SetEnable(true) + top.Flows().Append(flow) + + ate.OTG().PushConfig(t, top) + time.Sleep(30 * time.Second) + ate.OTG().StartProtocols(t) + time.Sleep(30 * time.Second) + + cs := gosnappi.NewControlState() + cs.Port().Capture().SetState(gosnappi.StatePortCaptureState.START) + args.otg.SetControlState(t, cs) + + ate.OTG().StartTraffic(t) + time.Sleep(time.Duration(duration) * time.Second) + ate.OTG().StopTraffic(t) + + cs.Port().Capture().SetState(gosnappi.StatePortCaptureState.STOP) + args.otg.SetControlState(t, cs) + otgutils.LogFlowMetrics(t, ate.OTG(), top) + otgutils.LogPortMetrics(t, ate.OTG(), top) +} + +// verifyTrafficFlow verify the each flow on ATE +func verifyTrafficFlow(t *testing.T, ate *ondatra.ATEDevice, flow gosnappi.Flow) bool { + rxPkts := gnmi.Get(t, ate.OTG(), gnmi.OTG().Flow(flow.Name()).Counters().InPkts().State()) + txPkts := gnmi.Get(t, ate.OTG(), gnmi.OTG().Flow(flow.Name()).Counters().OutPkts().State()) + lostPkt := txPkts - rxPkts + if got := (lostPkt * 100 / txPkts); got >= tolerancePct { + return false + } + return true +} + +// verifyBgpTelemetry verifies BGP telemetry. +func verifyBgpTelemetry(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + t.Logf("Verifying BGP state.") + bgpPath := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, "BGP").Bgp() + + nbrPath := bgpPath.Neighbor(bgpNbr3.ateIPv4) + // Get BGP adjacency state. + t.Logf("Waiting for BGP neighbor to establish...") + var status *ygnmi.Value[oc.E_Bgp_Neighbor_SessionState] + 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 { + fptest.LogQuery(t, "BGP reported state", nbrPath.State(), gnmi.Get(t, dut, nbrPath.State())) + t.Fatal("No BGP neighbor formed") + } + state, _ := status.Val() + t.Logf("BGP adjacency for %s: %v", bgpNbr3.ateIPv4, state) + if want := oc.Bgp_Neighbor_SessionState_ESTABLISHED; state != want { + t.Errorf("BGP peer %s status got %d, want %d", bgpNbr3.ateIPv4, state, want) + } +} + +func captureAndValidatePackets(t *testing.T, args *testArgs, packetVal *packetValidation) { + bytes := args.otg.GetCapture(t, gosnappi.NewCaptureRequest().SetPortName(packetVal.portName)) + f, err := os.CreateTemp("", "pcap") + if err != nil { + t.Fatalf("ERROR: Could not create temporary pcap file: %v\n", err) + } + if _, err := f.Write(bytes); err != nil { + t.Fatalf("ERROR: Could not write bytes to pcap file: %v\n", err) + } + f.Close() + handle, err := pcap.OpenOffline(f.Name()) + if err != nil { + log.Fatal(err) + } + defer handle.Close() + packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) + if packetVal.validateDecap { + validateTrafficDecap(t, packetSource) + } + if packetVal.validateNoDecap { + validateTrafficNonDecap(t, packetSource, packetVal.outDstIP[0], packetVal.inHdrIP) + } + if packetVal.validateEncap { + validateTrafficEncap(t, packetSource, packetVal.outDstIP, packetVal.inHdrIP) + } + args.otgConfig.Captures().Clear() + args.otg.PushConfig(t, args.otgConfig) + time.Sleep(30 * time.Second) +} + +func validateTrafficDecap(t *testing.T, packetSource *gopacket.PacketSource) { + t.Helper() + for packet := range packetSource.Packets() { + ipLayer := packet.Layer(layers.LayerTypeIPv4) + if ipLayer == nil { + continue + } + ipPacket, _ := ipLayer.(*layers.IPv4) + innerPacket := gopacket.NewPacket(ipPacket.Payload, ipPacket.NextLayerType(), gopacket.Default) + ipInnerLayer := innerPacket.Layer(layers.LayerTypeIPv4) + if ipInnerLayer != nil { + t.Errorf("Packets are not decapped, Inner IP header is not removed.") + } + } +} + +func validateTrafficNonDecap(t *testing.T, packetSource *gopacket.PacketSource, outDstIP, inHdrIP string) { + t.Helper() + t.Log("Validate traffic non decap routes") + var packetCheckCount uint32 = 1 + for packet := range packetSource.Packets() { + if packetCheckCount >= 5 { + break + } + ipLayer := packet.Layer(layers.LayerTypeIPv4) + if ipLayer == nil { + continue + } + ipPacket, _ := ipLayer.(*layers.IPv4) + innerPacket := gopacket.NewPacket(ipPacket.Payload, ipPacket.NextLayerType(), gopacket.Default) + ipInnerLayer := innerPacket.Layer(layers.LayerTypeIPv4) + if ipInnerLayer != nil { + if ipPacket.DstIP.String() != outDstIP { + t.Errorf("Negatice test for Decap failed. Traffic sent to route which does not match the decap route are decaped") + } + ipInnerPacket, _ := ipInnerLayer.(*layers.IPv4) + if ipInnerPacket.DstIP.String() != inHdrIP { + t.Errorf("Negatice test for Decap failed. Traffic sent to route which does not match the decap route are decaped") + } + t.Logf("Traffic for non decap routes passed.") + break + } + } +} + +func validateTrafficEncap(t *testing.T, packetSource *gopacket.PacketSource, outDstIP []string, innerIP string) { + t.Helper() + t.Log("Validate traffic non decap routes") + var packetCheckCount uint32 = 1 + for packet := range packetSource.Packets() { + if packetCheckCount >= 5 { + break + } + ipLayer := packet.Layer(layers.LayerTypeIPv4) + if ipLayer == nil { + continue + } + ipPacket, _ := ipLayer.(*layers.IPv4) + innerPacket := gopacket.NewPacket(ipPacket.Payload, ipPacket.NextLayerType(), gopacket.Default) + ipInnerLayer := innerPacket.Layer(layers.LayerTypeIPv4) + if ipInnerLayer != nil { + if len(outDstIP) == 2 { + if ipPacket.DstIP.String() != outDstIP[0] || ipPacket.DstIP.String() != outDstIP[1] { + t.Errorf("Packets are not encapsulated as expected") + } + } else { + if ipPacket.DstIP.String() != outDstIP[0] { + t.Errorf("Packets are not encapsulated as expected") + } + } + t.Logf("Traffic for encap routes passed.") + break + } + } +} diff --git a/feature/gribi/otg_tests/gribi_route_test/metadata.textproto b/feature/gribi/otg_tests/gribi_route_test/metadata.textproto new file mode 100644 index 00000000000..333a3e00ed4 --- /dev/null +++ b/feature/gribi/otg_tests/gribi_route_test/metadata.textproto @@ -0,0 +1,55 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "8beaac46-9b7b-49c4-9bde-62ad630aa6c7" +plan_id: "RT-14.2" +description: "GRIBI Route Test" +testbed: TESTBED_DUT_ATE_4LINKS + +platform_exceptions: { + platform: { + vendor: CISCO + } + deviations: { + gribi_mac_override_with_static_arp: true + interface_ref_interface_id_format: true + pf_require_match_default_rule: true + pf_require_sequential_order_pbr_rules: true + ttl_copy_unsupported: true + isis_single_topology_required: true + } +} +platform_exceptions: { + platform: { + vendor: NOKIA + } + deviations: { + explicit_port_speed: true + explicit_interface_in_default_vrf: true + aggregate_atomic_update: true + interface_enabled: true + missing_value_for_defaults: true + missing_isis_interface_afi_safi_enable: true + } +} + +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + interface_enabled: true + default_network_instance: "default" + omit_l2_mtu: true + isis_instance_enabled_required: true + isis_interface_afi_unsupported: true + missing_isis_interface_afi_safi_enable: true + isis_require_same_l1_metric_with_l2_metric: true + route_policy_under_afi_unsupported: true + static_protocol_name: "STATIC" + aggregate_atomic_update: true + missing_value_for_defaults: true + max_ecmp_paths: true + explicit_interface_in_default_vrf: false + } +} diff --git a/feature/interface/aggregate/otg_tests/balancing_test/README.md b/feature/interface/aggregate/otg_tests/balancing_test/README.md index aceda7e25b6..d09453272e8 100644 --- a/feature/interface/aggregate/otg_tests/balancing_test/README.md +++ b/feature/interface/aggregate/otg_tests/balancing_test/README.md @@ -41,3 +41,26 @@ None ## Minimum DUT platform requirement vRX + +## OpenConfig Path and RPC Coverage + +The below yaml defines the OC paths and RPC intended to be covered by this test. + +```yaml +paths: + /interfaces/interface/ethernet/config/aggregate-id: + /interfaces/interface/aggregation/config/lag-type: + /lacp/config/system-priority: + /lacp/interfaces/interface/config/name: + /lacp/interfaces/interface/config/interval: + /lacp/interfaces/interface/config/lacp-mode: + /lacp/interfaces/interface/config/system-id-mac: + /lacp/interfaces/interface/config/system-priority: + +rpcs: + gnmi: + gNMI.Set: + union_replace: false + gNMI.Subscribe: + on_change: false +``` 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 07b576adf29..0a84eef0ae2 100644 --- a/feature/interface/aggregate/otg_tests/balancing_test/balancing_test.go +++ b/feature/interface/aggregate/otg_tests/balancing_test/balancing_test.go @@ -569,6 +569,30 @@ func (tc *testCase) testFlow(t *testing.T, l3header string) { if pkts == 0 { t.Errorf("Flow sent packets: got %v, want non zero", pkts) } + + if deviations.InterfaceCountersUpdateDelayed(tc.dut) { + batch := gnmi.OCBatch() + for _, port := range tc.dutPorts[1:] { + batch.AddPaths(gnmi.OC().Interface(port.Name()).Counters()) + } + + _, ok := gnmi.Watch(t, tc.dut, batch.State(), time.Second*60, func(v *ygnmi.Value[*oc.Root]) bool { + got, present := v.Val() + if !present { + return false + } + totalPks := uint64(0) + for _, port := range tc.dutPorts[1:] { + totalPks += got.GetInterface(port.Name()).GetCounters().GetOutPkts() - beforeTrafficCounters[port.Name()].GetOutPkts() + } + return totalPks >= pkts + }).Await(t) + + if !ok { + t.Fatalf("Counters did not update in time") + } + } + afterTrafficCounters := tc.getCounters(t, "after") tc.verifyCounterDiff(t, beforeTrafficCounters, afterTrafficCounters) } diff --git a/feature/interface/aggregate/otg_tests/balancing_test/metadata.textproto b/feature/interface/aggregate/otg_tests/balancing_test/metadata.textproto index 68c8eb17c3a..f29298037aa 100644 --- a/feature/interface/aggregate/otg_tests/balancing_test/metadata.textproto +++ b/feature/interface/aggregate/otg_tests/balancing_test/metadata.textproto @@ -11,6 +11,7 @@ platform_exceptions: { } deviations: { ipv4_missing_enabled: true + interface_counters_update_delayed: true } } platform_exceptions: { diff --git a/feature/experimental/interface/interface_loopback_aggregate/otg_tests/interface_loopback_aggregate/README.md b/feature/interface/interface_loopback_aggregate/otg_tests/interface_loopback_aggregate/README.md similarity index 100% rename from feature/experimental/interface/interface_loopback_aggregate/otg_tests/interface_loopback_aggregate/README.md rename to feature/interface/interface_loopback_aggregate/otg_tests/interface_loopback_aggregate/README.md diff --git a/feature/experimental/interface/interface_loopback_aggregate/otg_tests/interface_loopback_aggregate/interface_loopback_aggregate_test.go b/feature/interface/interface_loopback_aggregate/otg_tests/interface_loopback_aggregate/interface_loopback_aggregate_test.go similarity index 100% rename from feature/experimental/interface/interface_loopback_aggregate/otg_tests/interface_loopback_aggregate/interface_loopback_aggregate_test.go rename to feature/interface/interface_loopback_aggregate/otg_tests/interface_loopback_aggregate/interface_loopback_aggregate_test.go diff --git a/feature/experimental/interface/interface_loopback_aggregate/otg_tests/interface_loopback_aggregate/metadata.textproto b/feature/interface/interface_loopback_aggregate/otg_tests/interface_loopback_aggregate/metadata.textproto similarity index 100% rename from feature/experimental/interface/interface_loopback_aggregate/otg_tests/interface_loopback_aggregate/metadata.textproto rename to feature/interface/interface_loopback_aggregate/otg_tests/interface_loopback_aggregate/metadata.textproto diff --git a/feature/experimental/interface/my_station_mac/otg_tests/my_station_mac_test/README.md b/feature/interface/my_station_mac/otg_tests/my_station_mac_test/README.md similarity index 100% rename from feature/experimental/interface/my_station_mac/otg_tests/my_station_mac_test/README.md rename to feature/interface/my_station_mac/otg_tests/my_station_mac_test/README.md diff --git a/feature/experimental/interface/my_station_mac/otg_tests/my_station_mac_test/metadata.textproto b/feature/interface/my_station_mac/otg_tests/my_station_mac_test/metadata.textproto similarity index 100% rename from feature/experimental/interface/my_station_mac/otg_tests/my_station_mac_test/metadata.textproto rename to feature/interface/my_station_mac/otg_tests/my_station_mac_test/metadata.textproto diff --git a/feature/experimental/interface/my_station_mac/otg_tests/my_station_mac_test/my_station_mac_test.go b/feature/interface/my_station_mac/otg_tests/my_station_mac_test/my_station_mac_test.go similarity index 100% rename from feature/experimental/interface/my_station_mac/otg_tests/my_station_mac_test/my_station_mac_test.go rename to feature/interface/my_station_mac/otg_tests/my_station_mac_test/my_station_mac_test.go diff --git a/feature/interface/singleton/otg_tests/singleton_test/README.md b/feature/interface/singleton/otg_tests/singleton_test/README.md index a80de7b2ef8..d8d218db6f9 100644 --- a/feature/interface/singleton/otg_tests/singleton_test/README.md +++ b/feature/interface/singleton/otg_tests/singleton_test/README.md @@ -169,3 +169,56 @@ a new testbed configuration with the desired port types. ## Minimum DUT Platform Requirement vRX + +## OpenConfig Path and RPC Coverage + +The below yaml defines the OC paths and RPC intended to be covered by this test. + +```yaml +paths: + /interfaces/interface/ethernet/state/counters/in-mac-pause-frames: + /interfaces/interface/ethernet/state/counters/out-mac-pause-frames: + /interfaces/interface/ethernet/state/mac-address: + /interfaces/interface/state/counters/in-broadcast-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-octets: + /interfaces/interface/state/counters/in-unicast-pkts: + /interfaces/interface/state/counters/in-unknown-protos: + /interfaces/interface/state/counters/out-broadcast-pkts: + /interfaces/interface/state/counters/out-discards: + /interfaces/interface/state/counters/out-errors: + /interfaces/interface/state/counters/out-multicast-pkts: + /interfaces/interface/state/counters/out-octets: + /interfaces/interface/state/counters/out-pkts: + /interfaces/interface/state/counters/out-unicast-pkts: + /interfaces/interface/subinterfaces/subinterface/ipv4/state/mtu: + /interfaces/interface/subinterfaces/subinterface/ipv6/state/mtu: + /interfaces/interface/state/oper-status: + /interfaces/interface/subinterfaces/subinterface/ipv4/addresses/address/ip: + /interfaces/interface/subinterfaces/subinterface/ipv4/state/counters/in-pkts: + /interfaces/interface/subinterfaces/subinterface/ipv4/state/counters/out-pkts: + /interfaces/interface/subinterfaces/subinterface/ipv6/addresses/address/ip: + /interfaces/interface/subinterfaces/subinterface/ipv6/state/counters/in-discarded-pkts: + /interfaces/interface/subinterfaces/subinterface/ipv6/state/counters/in-pkts: + /interfaces/interface/subinterfaces/subinterface/ipv6/state/counters/out-discarded-pkts: + /interfaces/interface/subinterfaces/subinterface/ipv6/state/counters/out-pkts: + /interfaces/interface/ethernet/state/aggregate-id: + /interfaces/interface/ethernet/state/port-speed: + /interfaces/interface/state/admin-status: + /interfaces/interface/state/description: + /interfaces/interface/state/type: + /interfaces/interface/subinterfaces/subinterface/ipv6/state/counters/out-forwarded-pkts: + /interfaces/interface/state/hardware-port: + /interfaces/interface/state/id: + /interfaces/interface/state/counters/in-fcs-errors: + /interfaces/interface/state/counters/carrier-transitions: + +rpcs: + gnmi: + gNMI.Set: + union_replace: false + gNMI.Subscribe: + on_change: false +``` diff --git a/feature/interface/singleton/otg_tests/singleton_test/metadata.textproto b/feature/interface/singleton/otg_tests/singleton_test/metadata.textproto index 76237f19190..926a5a3d560 100644 --- a/feature/interface/singleton/otg_tests/singleton_test/metadata.textproto +++ b/feature/interface/singleton/otg_tests/singleton_test/metadata.textproto @@ -12,6 +12,7 @@ platform_exceptions: { deviations: { ip_neighbor_missing: true ipv4_missing_enabled: true + interface_counters_update_delayed: true } } platform_exceptions: { 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 4b38868f6ee..ffe41e929ff 100644 --- a/feature/interface/singleton/otg_tests/singleton_test/singleton_test.go +++ b/feature/interface/singleton/otg_tests/singleton_test/singleton_test.go @@ -30,6 +30,7 @@ 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" @@ -430,6 +431,36 @@ func (tc *testCase) testFlow(t *testing.T, packetSize uint16, configIPHeader otg t.Logf("ap1 out-octets %d -> ap2 in-octets %d", aicp1.GetCounters().GetOutOctets(), aicp2.GetCounters().GetInOctets()) } + // Flow counters + otgutils.LogFlowMetrics(t, tc.ate.OTG(), tc.top) + fp := gnmi.Get(t, tc.ate.OTG(), gnmi.OTG().Flow(flow.Name()).State()) + fpc := fp.GetCounters() + + // Pragmatic check on the average in and out packet sizes. IPv4 may + // fragment the packet unless DF bit is set. IPv6 never fragments. + // Under no circumstances should DUT send packets greater than MTU. + + octets := fpc.GetOutOctets() + ateOutPkts := fpc.GetOutPkts() + ateInPkts := fpc.GetInPkts() + + if deviations.InterfaceCountersUpdateDelayed(tc.dut) { + batch := gnmi.OCBatch() + batch.AddPaths( + gnmi.OC().Interface(p1.Name()).Counters(), + gnmi.OC().Interface(p2.Name()).Counters(), + ) + gnmi.Watch(t, tc.dut, batch.State(), time.Second*60, func(v *ygnmi.Value[*oc.Root]) bool { + got, present := v.Val() + if !present { + return false + } + diffP1 := diffCounters(p1InBefore, inCounters(got.GetInterface(p1.Name()).GetCounters())) + diffP2 := diffCounters(p2OutBefore, outCounters(got.GetInterface(p2.Name()).GetCounters())) + return (diffP1.unicast+diffP1.drop >= ateOutPkts) && (diffP2.unicast >= ateInPkts-diffP2.drop) + }).Await(t) + } + // After Traffic Unicast, Multicast, Broadcast Counter p1InAfter := inCounters(gnmi.Get(t, tc.dut, p1Counter.State())) p2OutAfter := outCounters(gnmi.Get(t, tc.dut, p2Counter.State())) @@ -449,18 +480,6 @@ func (tc *testCase) testFlow(t *testing.T, packetSize uint16, configIPHeader otg t.Errorf("Large number of outbound Broadcast packets %d, want <= 100)", p2OutDiff.broadcast) } - // Flow counters - otgutils.LogFlowMetrics(t, tc.ate.OTG(), tc.top) - fp := gnmi.Get(t, tc.ate.OTG(), gnmi.OTG().Flow(flow.Name()).State()) - fpc := fp.GetCounters() - - // Pragmatic check on the average in and out packet sizes. IPv4 may - // fragment the packet unless DF bit is set. IPv6 never fragments. - // Under no circumstances should DUT send packets greater than MTU. - - octets := fpc.GetOutOctets() - ateOutPkts := fpc.GetOutPkts() - ateInPkts := fpc.GetInPkts() if ateOutPkts == 0 { t.Error("Flow did not send any packet") } else if avg := octets / ateOutPkts; avg > uint64(tc.mtu) { diff --git a/feature/networkinstance/otg_tests/defaults_test/README.md b/feature/networkinstance/otg_tests/defaults_test/README.md index 9e7da08764d..a5ac736175e 100644 --- a/feature/networkinstance/otg_tests/defaults_test/README.md +++ b/feature/networkinstance/otg_tests/defaults_test/README.md @@ -2,12 +2,21 @@ TODO(robshakir): fill in test plan from code already written. +## Description + +This test verifies that the IPv4 and IPv6 address families are enabled within a network instance by default. + +## Test Procedure + +* Configure an ATE with port1 connected to DUT port1, and port2 connected to DUT port2. +* Configure the DUT to have: + * these interfaces within the `DEFAULT` network instance and validate that traffic can be forwarded between ATE port1 and ATE port2. + * these interfaces within a non-default `L3VRF` and validate that traffic can be forwarded between ATE port1 and ATE port2. + ## OpenConfig Path and RPC Coverage The below yaml defines the OC paths intended to be covered by this test. OC paths used for test setup are not listed here. -TODO(robshakir): fill in coverage from code already written. - ```yaml paths: rpcs: diff --git a/feature/platform/tests/breakout_configuration/README.md b/feature/platform/tests/breakout_configuration/README.md new file mode 100644 index 00000000000..1cccdf903c4 --- /dev/null +++ b/feature/platform/tests/breakout_configuration/README.md @@ -0,0 +1,41 @@ +# PLT-1.1: Interface breakout Test + +## Summary + +Validate Interface breakout configuration. + +## Procedure + + +* This test is carried out for different breakout types +* Connect DUT with ATE to all interfaces in the breakout port +* Configure each interface with test IP addressing +* Verify correct interface state and speed reported +* Verify that DUT responds to ARP/ICMP on all tested interfaces + +## OpenConfig Path and RPC Coverage + +The below yaml defines the OC paths intended to be covered by this test. OC +paths used for test setup are not listed here. + +```yaml +paths: + /components/component/port/breakout-mode/groups/group/index: + platform_type: [ "PORT" ] + /components/component/port/breakout-mode/groups/group/config/index: + platform_type: [ "PORT" ] + /components/component/port/breakout-mode/groups/group/config/num-breakouts: + platform_type: [ "PORT" ] + /components/component/port/breakout-mode/groups/group/config/breakout-speed: + platform_type: [ "PORT" ] + /components/component/port/breakout-mode/groups/group/config/num-physical-channels: + platform_type: [ "PORT" ] +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` + +## Minimum DUT Platform Requirement + +* Breakout types - 4x100G, 2x100G and 4x10G diff --git a/feature/experimental/platform/tests/optics_thresholds_test/README.md b/feature/platform/tests/optics_thresholds_test/README.md similarity index 52% rename from feature/experimental/platform/tests/optics_thresholds_test/README.md rename to feature/platform/tests/optics_thresholds_test/README.md index 39f318faab4..9126d3eb914 100644 --- a/feature/experimental/platform/tests/optics_thresholds_test/README.md +++ b/feature/platform/tests/optics_thresholds_test/README.md @@ -8,7 +8,7 @@ Validate optics high and low thresholds for input power, output power, temperatu * Connect at least one optical ethernet interface to ATE. * Check all the transceivers with inslalled optcs. -* Validate that the following optics threshold telemetry paths exist for each optics. +* Validate that the optics threshold telemetry paths exist for each optics. * Output power thresholds: * /components/component/Ethernet/properties/property/laser-tx-power-low-alarm-threshold/state/value * /components/component/Ethernet/properties/property/laser-tx-power-high-alarm-threshold/state/value @@ -30,32 +30,17 @@ Validate optics high and low thresholds for input power, output power, temperatu * /components/component/Ethernet/properties/property/laser-bias-current-low-warn-threshold/state/value * /components/component/Ethernet/properties/property/laser-bias-current-high-warn-threshold/state/value - -## Config Parameter coverage +## OpenConfig Path and RPC Coverage -* None +The below yaml defines the OC paths intended to be covered by this test. OC +paths used for test setup are not listed here. + +```yaml +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` -## Telemetry Parameter coverage - * Output power thresholds: - * /components/component/Ethernet/properties/property/laser-tx-power-low-alarm-threshold/state/value - * /components/component/Ethernet/properties/property/laser-tx-power-high-alarm-threshold/state/value - * /components/component/Ethernet/properties/property/laser-tx-power-low-warn-threshold/state/value - * /components/component/Ethernet/properties/property/laser-tx-power-high-warn-threshold/state/value - * Input power threshold: - * /components/component/Ethernet/properties/property/laser-rx-power-low-alarm-threshold/state/value - * /components/component/Ethernet/properties/property/laser-rx-power-high-alarm-threshold/state/value - * /components/component/Ethernet/properties/property/laser-rx-power-low-warn-threshold/state/value - * /components/component/Ethernet/properties/property/laser-rx-power-high-warn-threshold/state/value - * Optics temperature threshold: - * /components/component/Ethernet/properties/property/laser-temperature-low-alarm-threshold/state/value - * /components/component/Ethernet/properties/property/laser-temperature-high-alarm-threshold/state/value - * /components/component/Ethernet/properties/property/laser-temperature-low-warn-threshold/state/value - * /components/component/Ethernet/properties/property/laser-temperature-high-warn-threshold/state/value - * Optics bias-current threshold: - * /components/component/Ethernet/properties/property/laser-bias-current-low-alarm-threshold/state/value - * /components/component/Ethernet/properties/property/laser-bias-current-high-alarm-threshold/state/value - * /components/component/Ethernet/properties/property/laser-bias-current-low-warn-threshold/state/value - * /components/component/Ethernet/properties/property/laser-bias-current-high-warn-threshold/state/value - ## Notes: * The model for optics threshold paths is not finalized. We may need to update those paths after the model is finalized. diff --git a/feature/experimental/platform/tests/optics_thresholds_test/metadata.textproto b/feature/platform/tests/optics_thresholds_test/metadata.textproto similarity index 100% rename from feature/experimental/platform/tests/optics_thresholds_test/metadata.textproto rename to feature/platform/tests/optics_thresholds_test/metadata.textproto diff --git a/feature/experimental/platform/tests/optics_thresholds_test/optics_thresholds_test.go b/feature/platform/tests/optics_thresholds_test/optics_thresholds_test.go similarity index 100% rename from feature/experimental/platform/tests/optics_thresholds_test/optics_thresholds_test.go rename to feature/platform/tests/optics_thresholds_test/optics_thresholds_test.go diff --git a/feature/platform/transceiver/tests/zr_laser_bias_current_test/zr_laser_bias_current_test.go b/feature/platform/transceiver/tests/zr_laser_bias_current_test/zr_laser_bias_current_test.go index 80e67d6649b..bdc31e8f363 100644 --- a/feature/platform/transceiver/tests/zr_laser_bias_current_test/zr_laser_bias_current_test.go +++ b/feature/platform/transceiver/tests/zr_laser_bias_current_test/zr_laser_bias_current_test.go @@ -15,10 +15,10 @@ package zr_laser_bias_current_test import ( - "reflect" "testing" "time" + "github.com/openconfig/featureprofiles/internal/cfgplugins" "github.com/openconfig/featureprofiles/internal/components" "github.com/openconfig/featureprofiles/internal/deviations" "github.com/openconfig/featureprofiles/internal/fptest" @@ -29,12 +29,6 @@ import ( "github.com/openconfig/ygot/ygot" ) -const ( - dp16QAM = 1 - targetOutputPower = -10 - frequency = 193500000 -) - func TestMain(m *testing.M) { fptest.RunTests(m) } @@ -43,93 +37,73 @@ func TestMain(m *testing.M) { // dut:port1 <--> port2:dut // -func verifyLaserBiasCurrent(t *testing.T, pStream *samplestream.SampleStream[float64], sensorName string) float64 { - laserBias := pStream.Next() +func verifyLaserBiasValue(t *testing.T, laserBiasValue float64) { + t.Helper() + if laserBiasValue <= 0 && laserBiasValue >= 131 { + t.Errorf("The laser bias value is not between 0 and 131") + } +} + +func verifyLaserBiasCurrentAll(t *testing.T, p1Stream *samplestream.SampleStream[*oc.Component_OpticalChannel_LaserBiasCurrent], dut1 *ondatra.DUTDevice) { + laserBias := p1Stream.Next() if laserBias == nil { - t.Fatalf("laserBias telemetry %q was not streamed in the most recent subscription interval", sensorName) + t.Fatalf("laserBias telemetry was not streamed in the most recent subscription interval") } laserBiasVal, ok := laserBias.Val() if !ok { - t.Fatalf("LaserBias %q telemetry is not present", sensorName) - } - if reflect.TypeOf(laserBiasVal).Kind() != reflect.Float64 { - t.Errorf("Return value is not type float64") - } - if laserBiasVal <= 0 && laserBiasVal >= 131 { - t.Errorf("The laser bias value is not between 0 and 131") + t.Fatalf("LaserBias telemetry is not present") } - t.Logf("laserBias value: %f", laserBiasVal) - return laserBiasVal -} - -func verifyLaserBiasCurrentAll(t *testing.T, pStreamInstant *samplestream.SampleStream[float64], pStreamAvg *samplestream.SampleStream[float64], pStreamMax *samplestream.SampleStream[float64], pStreamMin *samplestream.SampleStream[float64], dut1 *ondatra.DUTDevice) { - laserbiasInstant := verifyLaserBiasCurrent(t, pStreamInstant, "laserbiasInstant") - t.Logf("laserBias Instant value: %f", laserbiasInstant) + laserBiasInstant := laserBiasVal.GetInstant() + t.Logf("laserBias Instant value: %f", laserBiasInstant) if deviations.MissingZROpticalChannelTunableParametersTelemetry(dut1) { t.Log("Skipping Min/Max/Avg Tunable Parameters Telemetry validation. Deviation MissingZROpticalChannelTunableParametersTelemetry enabled.") } else { - laserbiasMin := verifyLaserBiasCurrent(t, pStreamMin, "laserbiasMin") - t.Logf("laserBias Min value: %f", laserbiasMin) - laserbiasMax := verifyLaserBiasCurrent(t, pStreamMax, "laserbiasMax") - t.Logf("laserBias Max value: %f", laserbiasMax) - laserbiasAvg := verifyLaserBiasCurrent(t, pStreamAvg, "laserbiasAvg") - t.Logf("laserBias Avg value: %f", laserbiasAvg) - if laserbiasAvg >= laserbiasMin && laserbiasAvg <= laserbiasMax { - t.Logf("The average is between the maximum and minimum values") + laserBiasMin := laserBiasVal.GetMin() + verifyLaserBiasValue(t, laserBiasMin) + t.Logf("laserBias Min value: %f", laserBiasMin) + laserBiasMax := laserBiasVal.GetMax() + verifyLaserBiasValue(t, laserBiasMax) + t.Logf("laserBias Max value: %f", laserBiasMax) + laserBiasAvg := laserBiasVal.GetAvg() + verifyLaserBiasValue(t, laserBiasAvg) + t.Logf("laserBias Avg value: %f", laserBiasMin) + if laserBiasAvg >= laserBiasMin && laserBiasAvg <= laserBiasMax { + t.Logf("The average %f is between the maximum and minimum values", laserBiasAvg) } else { - t.Fatalf("The average is not between the maximum and minimum values Avg:%f Min:%f Max:%f", laserbiasAvg, laserbiasMin, laserbiasMax) + t.Fatalf("The average is not between the maximum and minimum values Avg:%f Min:%f Max:%f", laserBiasAvg, laserBiasMin, laserBiasMax) } } } -func interfaceConfig(t *testing.T, dut1 *ondatra.DUTDevice, dp *ondatra.Port) { - d := &oc.Root{} - i := d.GetOrCreateInterface(dp.Name()) - i.Enabled = ygot.Bool(true) - i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd - gnmi.Replace(t, dut1, gnmi.OC().Interface(dp.Name()).Config(), i) - OCcomponent := components.OpticalChannelComponentFromPort(t, dut1, dp) - gnmi.Replace(t, dut1, gnmi.OC().Component(OCcomponent).OpticalChannel().Config(), &oc.Component_OpticalChannel{ - TargetOutputPower: ygot.Float64(targetOutputPower), - Frequency: ygot.Uint64(frequency), - }) -} - func TestZRLaserBiasCurrentState(t *testing.T) { dut1 := ondatra.DUT(t, "dut") dp1 := dut1.Port(t, "port1") dp2 := dut1.Port(t, "port2") t.Logf("dut1: %v", dut1) t.Logf("dut1 dp1 name: %v", dp1.Name()) - interfaceConfig(t, dut1, dp1) - interfaceConfig(t, dut1, dp2) + cfgplugins.InterfaceConfig(t, dut1, dp1) + cfgplugins.InterfaceConfig(t, dut1, dp2) intUpdateTime := 2 * time.Minute gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) transceiverState := gnmi.Get(t, dut1, gnmi.OC().Interface(dp1.Name()).Transceiver().State()) if dp1.PMD() != ondatra.PMD400GBASEZR { t.Fatalf("%s Transceiver is not 400ZR its of type: %v", transceiverState, dp1.PMD()) } - OCcomponent := components.OpticalChannelComponentFromPort(t, dut1, dp1) - component1 := gnmi.OC().Component(OCcomponent) - p1StreamInstant := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Instant().State(), 10*time.Second) - p1StreamMin := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Min().State(), 10*time.Second) - p1StreamMax := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Max().State(), 10*time.Second) - p1StreamAvg := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Avg().State(), 10*time.Second) - defer p1StreamAvg.Close() - defer p1StreamMax.Close() - defer p1StreamMin.Close() - defer p1StreamInstant.Close() - verifyLaserBiasCurrentAll(t, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin, dut1) + componentName := components.OpticalChannelComponentFromPort(t, dut1, dp1) + component := gnmi.OC().Component(componentName) + p1Stream := samplestream.New(t, dut1, component.OpticalChannel().LaserBiasCurrent().State(), 10*time.Second) + defer p1Stream.Close() + verifyLaserBiasCurrentAll(t, p1Stream, dut1) } -func TestZRLaserBiasCurrentStateInterface_Flap(t *testing.T) { +func TestZRLaserBiasCurrentStateInterfaceFlap(t *testing.T) { dut1 := ondatra.DUT(t, "dut") dp1 := dut1.Port(t, "port1") dp2 := dut1.Port(t, "port2") t.Logf("dut1: %v", dut1) t.Logf("dut1 dp1 name: %v", dp1.Name()) - interfaceConfig(t, dut1, dp1) - interfaceConfig(t, dut1, dp2) + cfgplugins.InterfaceConfig(t, dut1, dp1) + cfgplugins.InterfaceConfig(t, dut1, dp2) intUpdateTime := 2 * time.Minute // Check interface is up gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) @@ -144,25 +118,19 @@ func TestZRLaserBiasCurrentStateInterface_Flap(t *testing.T) { i.Enabled = ygot.Bool(false) i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd gnmi.Replace(t, dut1, gnmi.OC().Interface(dp1.Name()).Config(), i) - OCcomponent := components.OpticalChannelComponentFromPort(t, dut1, dp1) - component1 := gnmi.OC().Component(OCcomponent) - p1StreamInstant := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Instant().State(), 10*time.Second) - p1StreamMin := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Min().State(), 10*time.Second) - p1StreamMax := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Max().State(), 10*time.Second) - p1StreamAvg := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Avg().State(), 10*time.Second) - defer p1StreamInstant.Close() - defer p1StreamMin.Close() - defer p1StreamMax.Close() - defer p1StreamAvg.Close() - verifyLaserBiasCurrentAll(t, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin, dut1) - // Wait 120 sec cooling off period + componentName := components.OpticalChannelComponentFromPort(t, dut1, dp1) + component := gnmi.OC().Component(componentName) + p1Stream := samplestream.New(t, dut1, component.OpticalChannel().LaserBiasCurrent().State(), 10*time.Second) + defer p1Stream.Close() + verifyLaserBiasCurrentAll(t, p1Stream, dut1) + // Wait 120 sec cooling-off period gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_DOWN) + verifyLaserBiasCurrentAll(t, p1Stream, dut1) // Enable interface - verifyLaserBiasCurrentAll(t, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin, dut1) i.Enabled = ygot.Bool(true) gnmi.Replace(t, dut1, gnmi.OC().Interface(dp1.Name()).Config(), i) gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) - verifyLaserBiasCurrentAll(t, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin, dut1) + verifyLaserBiasCurrentAll(t, p1Stream, dut1) } func TestZRLaserBiasCurrentStateTransceiverOnOff(t *testing.T) { @@ -171,8 +139,8 @@ func TestZRLaserBiasCurrentStateTransceiverOnOff(t *testing.T) { dp2 := dut1.Port(t, "port2") t.Logf("dut1: %v", dut1) t.Logf("dut1 dp1 name: %v", dp1.Name()) - interfaceConfig(t, dut1, dp1) - interfaceConfig(t, dut1, dp2) + cfgplugins.InterfaceConfig(t, dut1, dp1) + cfgplugins.InterfaceConfig(t, dut1, dp2) intUpdateTime := 2 * time.Minute gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) transceiverState := gnmi.Get(t, dut1, gnmi.OC().Interface(dp1.Name()).Transceiver().State()) @@ -180,21 +148,17 @@ func TestZRLaserBiasCurrentStateTransceiverOnOff(t *testing.T) { if dp1.PMD() != ondatra.PMD400GBASEZR { t.Fatalf("%s Transceiver is not 400ZR its of type: %v", transceiverState, dp1.PMD()) } - OCcomponent := components.OpticalChannelComponentFromPort(t, dut1, dp1) - component1 := gnmi.OC().Component(OCcomponent) - p1StreamInstant := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Instant().State(), 10*time.Second) - p1StreamMin := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Min().State(), 10*time.Second) - p1StreamMax := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Max().State(), 10*time.Second) - p1StreamAvg := samplestream.New(t, dut1, component1.OpticalChannel().LaserBiasCurrent().Avg().State(), 10*time.Second) - defer p1StreamInstant.Close() - defer p1StreamMin.Close() - defer p1StreamMax.Close() - defer p1StreamAvg.Close() - // Disable interface transceiver power off + componentName := components.OpticalChannelComponentFromPort(t, dut1, dp1) + component := gnmi.OC().Component(componentName) + p1Stream := samplestream.New(t, dut1, component.OpticalChannel().LaserBiasCurrent().State(), 10*time.Second) + defer p1Stream.Close() + verifyLaserBiasCurrentAll(t, p1Stream, dut1) + // power off interface transceiver + gnmi.Update(t, dut1, gnmi.OC().Component(dp1.Name()).Name().Config(), dp1.Name()) gnmi.Update(t, dut1, gnmi.OC().Component(dp1.Name()).Transceiver().Enabled().Config(), false) - verifyLaserBiasCurrentAll(t, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin, dut1) - // Enable interface transceiver power on + verifyLaserBiasCurrentAll(t, p1Stream, dut1) + // power on interface transceiver gnmi.Update(t, dut1, gnmi.OC().Component(dp1.Name()).Transceiver().Enabled().Config(), true) gnmi.Await(t, dut1, gnmi.OC().Interface(dp1.Name()).OperStatus().State(), intUpdateTime, oc.Interface_OperStatus_UP) - verifyLaserBiasCurrentAll(t, p1StreamInstant, p1StreamAvg, p1StreamMax, p1StreamMin, dut1) + verifyLaserBiasCurrentAll(t, p1Stream, dut1) } diff --git a/feature/experimental/system/gnmi/benchmarking/internal/setup/setup.go b/feature/system/gnmi/benchmarking/internal/setup/setup.go similarity index 100% rename from feature/experimental/system/gnmi/benchmarking/internal/setup/setup.go rename to feature/system/gnmi/benchmarking/internal/setup/setup.go diff --git a/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/README.md b/feature/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/README.md similarity index 59% rename from feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/README.md rename to feature/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/README.md index 80b76298f1e..43312a43c90 100644 --- a/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/README.md +++ b/feature/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/README.md @@ -35,21 +35,24 @@ defined in the case): * Measure time between t=0 and all BGP received routes on ATE to report changed metric. -## Config Parameter coverage - - * BGP - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-med - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/repeat-n - * /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/as-number - - * ISIS - * /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/metric - * /network-instances/network-instance/protocols/protocol/isis/global/lsp-bit/overload-bit/state/set-bit - -## Telemetry Parameter coverage - - * ISIS - * /interfaces/interfaces/levels/level/adjacencies/adjacency/state/adjacency-state - * BGP - * /afi-safis/afi-safi/state/prefixes/sent - * /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor +## OpenConfig Path and RPC Coverage + +The below yaml defines the OC paths intended to be covered by this test. OC +paths used for test setup are not listed here. + +```yaml +paths: + ## Config Parameter coverage + /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/config/set-med: + /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/repeat-n: + /routing-policy/policy-definitions/policy-definition/statements/statement/actions/bgp-actions/set-as-path-prepend/config/asn: + /network-instances/network-instance/protocols/protocol/isis/interfaces/interface/levels/level/afi-safi/af/state/metric: + /network-instances/network-instance/protocols/protocol/isis/global/lsp-bit/overload-bit/state/set-bit: + + ## Telemetry Parameter coverage + /network-instances/network-instance/protocols/protocol/bgp/neighbors/neighbor/afi-safis/afi-safi/state/prefixes/sent: +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` diff --git a/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_bgp_test.go b/feature/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_bgp_test.go similarity index 99% rename from feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_bgp_test.go rename to feature/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_bgp_test.go index 3b12bc1d5e5..53bdf999d3f 100644 --- a/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_bgp_test.go +++ b/feature/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_bgp_test.go @@ -21,7 +21,7 @@ import ( "time" "github.com/google/go-cmp/cmp" - "github.com/openconfig/featureprofiles/feature/experimental/system/gnmi/benchmarking/internal/setup" + "github.com/openconfig/featureprofiles/feature/system/gnmi/benchmarking/internal/setup" "github.com/openconfig/featureprofiles/internal/deviations" "github.com/openconfig/featureprofiles/internal/fptest" "github.com/openconfig/ondatra" diff --git a/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_isis_test.go b/feature/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_isis_test.go similarity index 98% rename from feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_isis_test.go rename to feature/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_isis_test.go index e8bf2d5cfd2..fbdbba61792 100644 --- a/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_isis_test.go +++ b/feature/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/drained_configuration_convergence_time_isis_test.go @@ -20,7 +20,7 @@ import ( "testing" "time" - "github.com/openconfig/featureprofiles/feature/experimental/system/gnmi/benchmarking/internal/setup" + "github.com/openconfig/featureprofiles/feature/system/gnmi/benchmarking/internal/setup" "github.com/openconfig/featureprofiles/internal/deviations" "github.com/openconfig/ondatra" "github.com/openconfig/ondatra/gnmi" diff --git a/feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/metadata.textproto b/feature/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/metadata.textproto similarity index 100% rename from feature/experimental/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/metadata.textproto rename to feature/system/gnmi/benchmarking/otg_tests/drained_configuration_convergence_time/metadata.textproto diff --git a/feature/experimental/system/gnmi/benchmarking/tests/full_configuration_replace_test/README.md b/feature/system/gnmi/benchmarking/tests/full_configuration_replace_test/README.md similarity index 100% rename from feature/experimental/system/gnmi/benchmarking/tests/full_configuration_replace_test/README.md rename to feature/system/gnmi/benchmarking/tests/full_configuration_replace_test/README.md diff --git a/feature/experimental/system/gnmi/benchmarking/tests/full_configuration_replace_test/full_configuration_replace_test.go b/feature/system/gnmi/benchmarking/tests/full_configuration_replace_test/full_configuration_replace_test.go similarity index 97% rename from feature/experimental/system/gnmi/benchmarking/tests/full_configuration_replace_test/full_configuration_replace_test.go rename to feature/system/gnmi/benchmarking/tests/full_configuration_replace_test/full_configuration_replace_test.go index e07d56bb4aa..03d8878c59e 100644 --- a/feature/experimental/system/gnmi/benchmarking/tests/full_configuration_replace_test/full_configuration_replace_test.go +++ b/feature/system/gnmi/benchmarking/tests/full_configuration_replace_test/full_configuration_replace_test.go @@ -19,7 +19,7 @@ import ( "testing" "time" - "github.com/openconfig/featureprofiles/feature/experimental/system/gnmi/benchmarking/internal/setup" + "github.com/openconfig/featureprofiles/feature/system/gnmi/benchmarking/internal/setup" "github.com/openconfig/featureprofiles/internal/args" "github.com/openconfig/featureprofiles/internal/deviations" "github.com/openconfig/featureprofiles/internal/fptest" diff --git a/feature/experimental/system/gnmi/benchmarking/tests/full_configuration_replace_test/metadata.textproto b/feature/system/gnmi/benchmarking/tests/full_configuration_replace_test/metadata.textproto similarity index 100% rename from feature/experimental/system/gnmi/benchmarking/tests/full_configuration_replace_test/metadata.textproto rename to feature/system/gnmi/benchmarking/tests/full_configuration_replace_test/metadata.textproto diff --git a/feature/experimental/system/health/tests/system_generic_health_check/README.md b/feature/system/health/tests/system_generic_health_check/README.md similarity index 100% rename from feature/experimental/system/health/tests/system_generic_health_check/README.md rename to feature/system/health/tests/system_generic_health_check/README.md diff --git a/feature/experimental/system/health/tests/system_generic_health_check/metadata.textproto b/feature/system/health/tests/system_generic_health_check/metadata.textproto similarity index 100% rename from feature/experimental/system/health/tests/system_generic_health_check/metadata.textproto rename to feature/system/health/tests/system_generic_health_check/metadata.textproto diff --git a/feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go b/feature/system/health/tests/system_generic_health_check/system_generic_health_check_test.go similarity index 100% rename from feature/experimental/system/health/tests/system_generic_health_check/system_generic_health_check_test.go rename to feature/system/health/tests/system_generic_health_check/system_generic_health_check_test.go diff --git a/feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/README.md b/feature/tunnel/otg_tests/tunnel_acl_based_test/README.md similarity index 66% rename from feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/README.md rename to feature/tunnel/otg_tests/tunnel_acl_based_test/README.md index 073bc96cac8..f7f4769287a 100644 --- a/feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/README.md +++ b/feature/tunnel/otg_tests/tunnel_acl_based_test/README.md @@ -14,10 +14,20 @@ Verify the DSCP value of original packet header after GRE acl based tunnel encap * verify dscp value of original packet after encapsulation. * verify that no traffic drops in all flows. -## Config Parameter coverage - -* /acl/interfaces/interface/ingress-acl-sets/ingress-acl-set/config/set-name -* /acl/interfaces/interface/ingress-acl-sets/ingress-acl-set/config/set-type +## OpenConfig Path and RPC Coverage + +The below yaml defines the OC paths intended to be covered by this test. OC +paths used for test setup are not listed here. + +```yaml +paths: + /acl/interfaces/interface/ingress-acl-sets/ingress-acl-set/config/set-name: + /acl/interfaces/interface/ingress-acl-sets/ingress-acl-set/config/type: +rpcs: + gnmi: + gNMI.Subscribe: + gNMI.Set: +``` ## Validation coverage diff --git a/feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/metadata.textproto b/feature/tunnel/otg_tests/tunnel_acl_based_test/metadata.textproto similarity index 100% rename from feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/metadata.textproto rename to feature/tunnel/otg_tests/tunnel_acl_based_test/metadata.textproto diff --git a/feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/tun_acl_dscp_test.go b/feature/tunnel/otg_tests/tunnel_acl_based_test/tun_acl_dscp_test.go similarity index 100% rename from feature/experimental/tunnel/otg_tests/tunnel_acl_based_test/tun_acl_dscp_test.go rename to feature/tunnel/otg_tests/tunnel_acl_based_test/tun_acl_dscp_test.go diff --git a/feature/experimental/tunnel/otg_tests/tunnel_interface_based_ipv6_gre_encapsulation_test/README.md b/feature/tunnel/otg_tests/tunnel_interface_based_ipv6_gre_encapsulation_test/README.md similarity index 94% rename from feature/experimental/tunnel/otg_tests/tunnel_interface_based_ipv6_gre_encapsulation_test/README.md rename to feature/tunnel/otg_tests/tunnel_interface_based_ipv6_gre_encapsulation_test/README.md index 0bfc7dbe99f..076b0069e74 100644 --- a/feature/experimental/tunnel/otg_tests/tunnel_interface_based_ipv6_gre_encapsulation_test/README.md +++ b/feature/tunnel/otg_tests/tunnel_interface_based_ipv6_gre_encapsulation_test/README.md @@ -71,4 +71,13 @@ Validate Interface based Ipv6 GRE Tunnel Config. - state/counters/out-forwarded-pkts - state/counters/out-forwarded-octets - state/counters/out-discarded-pkt - - Fragmentation and assembly counters Filter counters Output to display the traffic is spread across the different tunnel subnet ranges/NH groups/Interfaces \ No newline at end of file + - Fragmentation and assembly counters Filter counters Output to display the traffic is spread across the different tunnel subnet ranges/NH groups/Interfaces + +## OpenConfig Path and RPC Coverage +```yaml +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: +``` diff --git a/feature/experimental/tunnel/otg_tests/tunnel_interface_based_ipv6_gre_encapsulation_test/metadata.textproto b/feature/tunnel/otg_tests/tunnel_interface_based_ipv6_gre_encapsulation_test/metadata.textproto similarity index 100% rename from feature/experimental/tunnel/otg_tests/tunnel_interface_based_ipv6_gre_encapsulation_test/metadata.textproto rename to feature/tunnel/otg_tests/tunnel_interface_based_ipv6_gre_encapsulation_test/metadata.textproto diff --git a/feature/experimental/tunnel/otg_tests/tunnel_interface_based_ipv6_gre_encapsulation_test/tunnel_interface_based_ipv6_gre_encapsulation_test.go b/feature/tunnel/otg_tests/tunnel_interface_based_ipv6_gre_encapsulation_test/tunnel_interface_based_ipv6_gre_encapsulation_test.go similarity index 100% rename from feature/experimental/tunnel/otg_tests/tunnel_interface_based_ipv6_gre_encapsulation_test/tunnel_interface_based_ipv6_gre_encapsulation_test.go rename to feature/tunnel/otg_tests/tunnel_interface_based_ipv6_gre_encapsulation_test/tunnel_interface_based_ipv6_gre_encapsulation_test.go diff --git a/feature/experimental/tunnel/otg_tests/tunnel_interface_based_resize_test/README.md b/feature/tunnel/otg_tests/tunnel_interface_based_resize_test/README.md similarity index 98% rename from feature/experimental/tunnel/otg_tests/tunnel_interface_based_resize_test/README.md rename to feature/tunnel/otg_tests/tunnel_interface_based_resize_test/README.md index 1bdd0384ace..24925300655 100644 --- a/feature/experimental/tunnel/otg_tests/tunnel_interface_based_resize_test/README.md +++ b/feature/tunnel/otg_tests/tunnel_interface_based_resize_test/README.md @@ -101,3 +101,12 @@ TODO: OpenConfig definition required for Tunnel protocol under interfaces/interf * state/counters/out-forwarded-pkts * state/counters/out-forwarded-octets * state/counters/out-discarded-pkts + +## OpenConfig Path and RPC Coverage +```yaml +rpcs: + gnmi: + gNMI.Get: + gNMI.Set: + gNMI.Subscribe: +``` diff --git a/internal/deviations/deviations.go b/internal/deviations/deviations.go index 2edc187f7a2..95fa92b453d 100644 --- a/internal/deviations/deviations.go +++ b/internal/deviations/deviations.go @@ -1151,6 +1151,12 @@ func ComponentMfgDateUnsupported(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetComponentMfgDateUnsupported() } +// InterfaceCountersUpdateDelayed returns true if telemetry for interface counters +// does not return the latest counter values. +func InterfaceCountersUpdateDelayed(dut *ondatra.DUTDevice) bool { + return lookupDUTDeviations(dut).GetInterfaceCountersUpdateDelayed() +} + // OTNChannelTribUnsupported returns true if TRIB parameter is unsupported under OTN channel configuration func OTNChannelTribUnsupported(dut *ondatra.DUTDevice) bool { return lookupDUTDeviations(dut).GetOtnChannelTribUnsupported() diff --git a/proto/metadata.proto b/proto/metadata.proto index 4259558297c..00236eddc3c 100644 --- a/proto/metadata.proto +++ b/proto/metadata.proto @@ -621,8 +621,10 @@ message Metadata { bool eth_channel_ingress_parameters_unsupported = 222; // Cisco numbering for eth channel assignment starts from 1 instead of 0 bool eth_channel_assignment_cisco_numbering = 223; + // Devices needs time to update interface counters. + bool interface_counters_update_delayed = 224; // Cisco numbering for OTN channel assignment starts from 1 instead of 0 - bool otn_channel_assignment_cisco_numbering = 224; + bool otn_channel_assignment_cisco_numbering = 225; // Reserved field numbers and identifiers. reserved 84, 9, 28, 20, 90, 97, 55, 89, 19, 36, 35, 40, 173; } diff --git a/proto/metadata_go_proto/metadata.pb.go b/proto/metadata_go_proto/metadata.pb.go index 68a520eba07..139b2058c16 100644 --- a/proto/metadata_go_proto/metadata.pb.go +++ b/proto/metadata_go_proto/metadata.pb.go @@ -15,7 +15,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.34.2 -// protoc v5.28.0 +// protoc v5.27.1 // source: metadata.proto package metadata_go_proto @@ -903,8 +903,8 @@ type Metadata_Deviations struct { EthChannelIngressParametersUnsupported bool `protobuf:"varint,222,opt,name=eth_channel_ingress_parameters_unsupported,json=ethChannelIngressParametersUnsupported,proto3" json:"eth_channel_ingress_parameters_unsupported,omitempty"` // Cisco numbering for eth channel assignment starts from 1 instead of 0 EthChannelAssignmentCiscoNumbering bool `protobuf:"varint,223,opt,name=eth_channel_assignment_cisco_numbering,json=ethChannelAssignmentCiscoNumbering,proto3" json:"eth_channel_assignment_cisco_numbering,omitempty"` - // Cisco numbering for OTN channel assignment starts from 1 instead of 0 - OtnChannelAssignmentCiscoNumbering bool `protobuf:"varint,224,opt,name=otn_channel_assignment_cisco_numbering,json=otnChannelAssignmentCiscoNumbering,proto3" json:"otn_channel_assignment_cisco_numbering,omitempty"` + // Devices needs time to update interface counters. + InterfaceCountersUpdateDelayed bool `protobuf:"varint,224,opt,name=interface_counters_update_delayed,json=interfaceCountersUpdateDelayed,proto3" json:"interface_counters_update_delayed,omitempty"` } func (x *Metadata_Deviations) Reset() { @@ -2353,9 +2353,9 @@ func (x *Metadata_Deviations) GetEthChannelAssignmentCiscoNumbering() bool { return false } -func (x *Metadata_Deviations) GetOtnChannelAssignmentCiscoNumbering() bool { +func (x *Metadata_Deviations) GetInterfaceCountersUpdateDelayed() bool { if x != nil { - return x.OtnChannelAssignmentCiscoNumbering + return x.InterfaceCountersUpdateDelayed } return false } @@ -2423,7 +2423,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, 0xbb, 0x7e, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb2, 0x7e, 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, @@ -2457,7 +2457,7 @@ var file_metadata_proto_rawDesc = []byte{ 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, 0x8e, 0x76, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x61, 0x74, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x1a, 0x85, 0x76, 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, 0x67, 0x45, @@ -3392,50 +3392,50 @@ var file_metadata_proto_rawDesc = []byte{ 0x62, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x18, 0xdf, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x22, 0x65, 0x74, 0x68, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x69, 0x73, 0x63, 0x6f, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x6e, - 0x67, 0x12, 0x53, 0x0a, 0x26, 0x6f, 0x74, 0x6e, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, - 0x5f, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x69, 0x73, 0x63, - 0x6f, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x18, 0xe0, 0x01, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x22, 0x6f, 0x74, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x73, - 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x69, 0x73, 0x63, 0x6f, 0x4e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x4a, 0x04, 0x08, 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, - 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, - 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, - 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, 0x13, 0x10, 0x14, 0x4a, 0x04, 0x08, 0x24, - 0x10, 0x25, 0x4a, 0x04, 0x08, 0x23, 0x10, 0x24, 0x4a, 0x04, 0x08, 0x28, 0x10, 0x29, 0x4a, 0x06, - 0x08, 0xad, 0x01, 0x10, 0xae, 0x01, 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, 0xfa, 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, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, - 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, - 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, - 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 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, + 0x67, 0x12, 0x4a, 0x0a, 0x21, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x64, + 0x65, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x18, 0xe0, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x4a, 0x04, 0x08, + 0x54, 0x10, 0x55, 0x4a, 0x04, 0x08, 0x09, 0x10, 0x0a, 0x4a, 0x04, 0x08, 0x1c, 0x10, 0x1d, 0x4a, + 0x04, 0x08, 0x14, 0x10, 0x15, 0x4a, 0x04, 0x08, 0x5a, 0x10, 0x5b, 0x4a, 0x04, 0x08, 0x61, 0x10, + 0x62, 0x4a, 0x04, 0x08, 0x37, 0x10, 0x38, 0x4a, 0x04, 0x08, 0x59, 0x10, 0x5a, 0x4a, 0x04, 0x08, + 0x13, 0x10, 0x14, 0x4a, 0x04, 0x08, 0x24, 0x10, 0x25, 0x4a, 0x04, 0x08, 0x23, 0x10, 0x24, 0x4a, + 0x04, 0x08, 0x28, 0x10, 0x29, 0x4a, 0x06, 0x08, 0xad, 0x01, 0x10, 0xae, 0x01, 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, 0xfa, 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, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x45, + 0x53, 0x54, 0x42, 0x45, 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x41, 0x54, 0x45, 0x5f, 0x38, 0x4c, + 0x49, 0x4e, 0x4b, 0x53, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x45, 0x53, 0x54, 0x42, 0x45, + 0x44, 0x5f, 0x44, 0x55, 0x54, 0x5f, 0x34, 0x30, 0x30, 0x5a, 0x52, 0x10, 0x08, 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 ( diff --git a/proto/ocpaths.proto b/proto/ocpaths.proto index 46f3bd41717..ea7d21e6d57 100644 --- a/proto/ocpaths.proto +++ b/proto/ocpaths.proto @@ -58,6 +58,10 @@ message OCPath { // A set of opaque tags that are used for this path. These tags can be used // to group paths according to use-case specific criteria. repeated string tags = 4; + + // GNMIRpc describes expected (or supported) behavior for a particular + // Openconfig path. + GNMIRpc gnmi_rpc = 5; } // OCPathConstraint enumerates platform_types that are required to be supported @@ -76,3 +80,39 @@ message OCPathConstraint { string platform_type = 1; } } + +// GNMIRpc describes expected (or supported) behavior for a particular +// Openconfig path. +message GNMIRpc { + bool get = 1; + bool set = 2; + bool subscribe = 3; + + // SubscribeMode, describes how updates are triggered for the request. + enum SubscribeMode { + UNSPECIFIED_SUBSCRIBE_MODE = 0; + NO_READ_SUPPORT = 1; // No requirement / support for path. + STREAM = 2; // Values streamed by the target (Sec. 3.5.1.5.2). + ONCE = 3; // Values sent once-off by the target (Sec. 3.5.1.5.1). + POLL = 4; // Values sent in response to a poll request (Sec. 3.5.1.5.3). + } + repeated SubscribeMode sub_mode = 4; + + // StreamMode is the mode of a streamed subscription, specifying how the + // target must return values for that subscription. + // Reference: gNMI Specification Section 3.5.1.3 + enum StreamMode { + UNSPECIFIED_STREAM_MODE = 0; + NO_STREAMING_SUPPORT = 1; // No requirement / support for streaming path. + TARGET_DEFINED = 2; // The target selects for each element. + ON_CHANGE = 3; // The target sends an update on element value change. + SAMPLE = 4; // The target samples values according to the interval. + } + repeated StreamMode stream_mode = 5; + + // If listed as part of a requirement, sample_interval_nanoseconds is the + // maximum allowable interval between updates. + // If listed as part of the description of level of support, it should be the + // smallest, recommended value. + uint64 sample_interval_nanoseconds = 6; +} diff --git a/testregistry.textproto b/testregistry.textproto index 533758476f2..13f6945e21a 100644 --- a/testregistry.textproto +++ b/testregistry.textproto @@ -741,6 +741,24 @@ test: { readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/experimental/policy/policy_vrf_selection/ate_tests/protocol_dscp_rules_for_vrf_selection_test/README.md" exec: " " } +test: { + id: "RT-3.3" + description: "Multiple VRFs and GUE DECAP in Default VRF" + readme: "" + exec: " " +} +test: { + id: "RT-3.31" + description: "DSCP based traffic steering from default VRF to non-Default VRF using Policy based VRF selection plus GUE DECAP" + readme: "" + exec: " " +} +test: { + id: "RT-3.32" + description: "DSCP based traffic steering from Non-default VRF to Default VRF using Policy based VRF selection plus GUE DECAP and ENCAP" + readme: "" + exec: " " +} test: { id: "RT-4.10" description: "AFTs Route Summary"