From 4550650fe4a2b41bc20612428f4e8d2d4f0f2c24 Mon Sep 17 00:00:00 2001 From: Ram Date: Wed, 19 Feb 2025 20:48:31 +0530 Subject: [PATCH 01/15] increase the timeout for addressing flakiness (#3831) --- .../power_admin_down_up_test/power_admin_down_up_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feature/platform/tests/power_admin_down_up_test/power_admin_down_up_test.go b/feature/platform/tests/power_admin_down_up_test/power_admin_down_up_test.go index 89163d8f605..75bc297530b 100644 --- a/feature/platform/tests/power_admin_down_up_test/power_admin_down_up_test.go +++ b/feature/platform/tests/power_admin_down_up_test/power_admin_down_up_test.go @@ -47,7 +47,7 @@ func TestFabricPowerAdmin(t *testing.T) { powerDownUp(t, dut, f, oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_FABRIC, 3*time.Minute) - helpers.ValidateOperStatusUPIntfs(t, dut, before, 5*time.Minute) + helpers.ValidateOperStatusUPIntfs(t, dut, before, 8*time.Minute) }) } } @@ -76,7 +76,7 @@ func TestLinecardPowerAdmin(t *testing.T) { powerDownUp(t, dut, l, oc.PlatformTypes_OPENCONFIG_HARDWARE_COMPONENT_LINECARD, 20*time.Minute) - helpers.ValidateOperStatusUPIntfs(t, dut, before, 5*time.Minute) + helpers.ValidateOperStatusUPIntfs(t, dut, before, 8*time.Minute) }) } } From 33f9c4351a08d5b582026c83b416a72a380a05dd Mon Sep 17 00:00:00 2001 From: Lakshmana Varahabhotla <77013369+vvlakshmanamurthy@users.noreply.github.com> Date: Wed, 19 Feb 2025 12:02:19 -0600 Subject: [PATCH 02/15] Update testregistry.textproto (#3820) Added PF1.8,PF1.9 & PF1.10 Co-authored-by: Darren Loher --- testregistry.textproto | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/testregistry.textproto b/testregistry.textproto index c222ed88850..ae9c1538dfa 100644 --- a/testregistry.textproto +++ b/testregistry.textproto @@ -456,6 +456,23 @@ test: { readme: "https://github.com/openconfig/featureprofiles/blob/main/feature/policy_forwarding/otg_tests/mpls_gre_udp_decap_test/README.md" exec: " " } +test: { + id: "PF-1.8" + description: "Ingress handling of the TTL, for all ingress packets decrement TTL , and for TTL=1 generate ICMP time exceeded message" + readme: " " + exec: " " +}test: { + id: "PF-1.9" + description: "Egress handling of the TTL, all egress packets should have their TTL decremented,egress packets with TTL=1 should generate ICMP time exceeded to source" + readme: " " + exec: " " +} +test: { + id: "PF-1.10" + description: "DSCP Egress handling, all egress packets IP, IPoGRE, IPoMPLSoGRE and IPoGUE, IPoMPLSoGUE should have their DSCP values re-written to 0x0 via egress QOS policy (or equivalent)" + readme: " " + exec: " " +} test: { id: "PLT-1.1" description: "Interface breakout Test" From 813b40ea5b6498c9a2abc1435a6cbfbf82d56f66 Mon Sep 17 00:00:00 2001 From: sudhirakondi <165871916+sudhirakondi@users.noreply.github.com> Date: Thu, 20 Feb 2025 15:16:54 +0530 Subject: [PATCH 03/15] Revert Deviation added in Pull #3347 (#3824) * reverting earlier introduced code with deviation (PR #3347) * enabling setpackets unrelated to the deviation * removing unused import --- .../static_lsp_test/metadata.textproto | 9 --- .../static_lsp_test/static_lsp_test.go | 64 +++---------------- 2 files changed, 9 insertions(+), 64 deletions(-) diff --git a/feature/gribi/otg_tests/static_lsp_test/metadata.textproto b/feature/gribi/otg_tests/static_lsp_test/metadata.textproto index 88d91863db3..5d5dbf8904f 100644 --- a/feature/gribi/otg_tests/static_lsp_test/metadata.textproto +++ b/feature/gribi/otg_tests/static_lsp_test/metadata.textproto @@ -13,12 +13,3 @@ platform_exceptions: { ipv4_missing_enabled: true } } - -platform_exceptions: { - platform: { - vendor: JUNIPER - } - deviations: { - static_lsp_unsupported: true - } -} diff --git a/feature/gribi/otg_tests/static_lsp_test/static_lsp_test.go b/feature/gribi/otg_tests/static_lsp_test/static_lsp_test.go index 4d80bc3f01b..f5cf1fe1fca 100644 --- a/feature/gribi/otg_tests/static_lsp_test/static_lsp_test.go +++ b/feature/gribi/otg_tests/static_lsp_test/static_lsp_test.go @@ -15,7 +15,6 @@ import ( "github.com/openconfig/featureprofiles/internal/attrs" "github.com/openconfig/featureprofiles/internal/deviations" "github.com/openconfig/featureprofiles/internal/fptest" - "github.com/openconfig/featureprofiles/internal/helpers" "github.com/openconfig/featureprofiles/internal/otgutils" "github.com/openconfig/ondatra" "github.com/openconfig/ondatra/gnmi" @@ -142,60 +141,15 @@ func configureOTG(t *testing.T) gosnappi.Config { // configureStaticLSP configures a static MPLS LSP with the provided parameters. func configureStaticLSP(t *testing.T, dut *ondatra.DUTDevice, lspName string, incomingLabel uint32, nextHopIP string) { - if deviations.StaticLspConfigUnsupported(dut) { - t.Logf("Push config via native CLI:%s", dut.Vendor()) - switch dut.Vendor() { - case ondatra.JUNIPER: - config := juniperMplsLSPConfig(t, dut, lspName, incomingLabel, nextHopIP) - helpers.GnmiCLIConfig(t, dut, config) - default: - t.Fatalf("StaticLspConfigUnsupported deviation needs cli configuration for vendor %s which is not defined", dut.Vendor()) - } - } else { - d := &oc.Root{} - // ConfigureDefaultNetworkInstance configures the default network instance name and type. - fptest.ConfigureDefaultNetworkInstance(t, dut) - mplsCfg := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)).GetOrCreateMpls() - staticMplsCfg := mplsCfg.GetOrCreateLsps().GetOrCreateStaticLsp(lspName) - staticMplsCfg.GetOrCreateEgress().SetIncomingLabel(oc.UnionUint32(incomingLabel)) - staticMplsCfg.GetOrCreateEgress().SetNextHop(nextHopIP) - staticMplsCfg.GetOrCreateEgress().SetPushLabel(oc.Egress_PushLabel_IMPLICIT_NULL) - gnmi.Update(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Mpls().Config(), mplsCfg) - } -} - -// juniperMplsLSPConfig is used to configure mpls lsp configuration via native cli as an alternative to below xpaths. -// /network-instances/network-instance/mpls/lsps/static-lsps/static-lsp/egress/config/next-hop -// /network-instances/network-instance/mpls/lsps/static-lsps/static-lsp/egress/config/incoming-label -// /network-instances/network-instance/mpls/lsps/static-lsps/static-lsp/egress/config/push-label -func juniperMplsLSPConfig(t *testing.T, dut *ondatra.DUTDevice, lspName string, incomingLabel uint32, nextHopIP string) string { - p1 := dut.Port(t, "port1").Name() - p2 := dut.Port(t, "port2").Name() - return fmt.Sprintf(` - interfaces { - %s { - unit %d { - family mpls; - } - } - %s { - unit %d { - family mpls; - } - } - } - protocols { - mpls { - interface %s; - interface %s; - static-label-switched-path %s { - transit %d { - next-hop %s; - pop; - } - } - } - }`, p1, 0, p2, 0, p1, p2, lspName, incomingLabel, nextHopIP) + d := &oc.Root{} + // ConfigureDefaultNetworkInstance configures the default network instance name and type. + fptest.ConfigureDefaultNetworkInstance(t, dut) + mplsCfg := d.GetOrCreateNetworkInstance(deviations.DefaultNetworkInstance(dut)).GetOrCreateMpls() + staticMplsCfg := mplsCfg.GetOrCreateLsps().GetOrCreateStaticLsp(lspName) + staticMplsCfg.GetOrCreateEgress().SetIncomingLabel(oc.UnionUint32(incomingLabel)) + staticMplsCfg.GetOrCreateEgress().SetNextHop(nextHopIP) + staticMplsCfg.GetOrCreateEgress().SetPushLabel(oc.Egress_PushLabel_IMPLICIT_NULL) + gnmi.Update(t, dut, gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Mpls().Config(), mplsCfg) } func createTrafficFlow(t *testing.T, From 1c021b63294d70b308ebb2ca6d9c4c6f42b764ac Mon Sep 17 00:00:00 2001 From: AmrNJ <155722765+AmrNJ@users.noreply.github.com> Date: Thu, 20 Feb 2025 21:40:10 +0530 Subject: [PATCH 04/15] Update base_adjacencies_test.go (#3835) --- .../otg_tests/base_adjacencies_test/base_adjacencies_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/feature/isis/otg_tests/base_adjacencies_test/base_adjacencies_test.go b/feature/isis/otg_tests/base_adjacencies_test/base_adjacencies_test.go index 77b0ccfa5d9..342782bee06 100644 --- a/feature/isis/otg_tests/base_adjacencies_test/base_adjacencies_test.go +++ b/feature/isis/otg_tests/base_adjacencies_test/base_adjacencies_test.go @@ -449,7 +449,6 @@ func TestAuthentication(t *testing.T) { ts := isissession.MustNew(t).WithISIS() ts.ConfigISIS(func(isis *oc.NetworkInstance_Protocol_Isis) { level := isis.GetOrCreateLevel(2) - level.Enabled = ygot.Bool(true) auth := level.GetOrCreateAuthentication() auth.Enabled = ygot.Bool(true) auth.AuthMode = tc.mode From b9fa8d1010f7baffb84125b44646a882db5962e5 Mon Sep 17 00:00:00 2001 From: Ram Date: Fri, 21 Feb 2025 12:16:07 +0530 Subject: [PATCH 05/15] fixed README.md related to global AFI-SAFI level behavior and also added the neighbor AFI-SAFI under global (#3834) Co-authored-by: Rohit Rattan --- feature/bgp/otg_tests/bgp_afi_safi_defaults/README.md | 5 ++--- .../bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/feature/bgp/otg_tests/bgp_afi_safi_defaults/README.md b/feature/bgp/otg_tests/bgp_afi_safi_defaults/README.md index 10037d7171c..b89367d3fa2 100644 --- a/feature/bgp/otg_tests/bgp_afi_safi_defaults/README.md +++ b/feature/bgp/otg_tests/bgp_afi_safi_defaults/README.md @@ -30,7 +30,7 @@ BGP AFI SAFI OC DEFAULTS TEST "IPv6-unicast enabled" boolean is left to OC default for the IPv4 peer". * Ensure that only IPv6-Unicast enabled boolean is made "true" for IPv6 neighbor. "IPv4-unicast enabled" boolean is left to OC default for the IPv6 peer". - * Ensure that there are no AFI-SAFI configurations at the global and peer-group levels. + * Ensure that there are no AFI-SAFI configurations at peer-group levels. * On the ATE side ensure that IPv4-unicast and IPv6-unicast AFI-SAFI are enabled==true for IPv4 and IPv6 neighbors. * Ensure that there is extended-next-hop encoding feature is configured via OC path and the @@ -46,7 +46,7 @@ BGP AFI SAFI OC DEFAULTS TEST * Configuration at the neighbor level is same as in [Test case-1] except for IPv4-unicast and IPv6-unicast being enabled at the peer-group level - * No configuration should be made at the global AFI-SAFI level + * No configuration should be made at the neighbor AFI-SAFI level * Verification: * For IPv4 neighbor, ensure that the IPv4 neighborship is up and both IPv4-unicast and @@ -78,7 +78,6 @@ BGP AFI SAFI OC DEFAULTS TEST * For IPv6 neighbor ensure that the IPv6 neighborship is not ESTABLISHED and IPv6-unicast capabilities are set to FALSE. - ## 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. diff --git a/feature/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go b/feature/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go index 77d1a362bc5..948ddf3157b 100644 --- a/feature/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go +++ b/feature/bgp/otg_tests/bgp_afi_safi_defaults/bgp_afi_safi_defaults_test.go @@ -166,8 +166,10 @@ func bgpCreateNbr(t *testing.T, localAs, peerAs uint32, dut *ondatra.DUTDevice, case globalLevel: if nbr.isV4 == true { global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) + nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Enabled = ygot.Bool(true) } else { global.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) + nv4.GetOrCreateAfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV6_UNICAST).Enabled = ygot.Bool(true) } if !isV4Only { if !deviations.BGPGlobalExtendedNextHopEncodingUnsupported(dut) { From aecebfef4795c1f8296c73f442c9b1ad4df41bb5 Mon Sep 17 00:00:00 2001 From: dipchauh <159579776+dipchauh@users.noreply.github.com> Date: Fri, 21 Feb 2025 04:09:42 -0500 Subject: [PATCH 06/15] Fix empty banner test (#3753) "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." --- .../system_banner_test/system_banner_test.go | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/feature/system/system_base_test/tests/system_banner_test/system_banner_test.go b/feature/system/system_base_test/tests/system_banner_test/system_banner_test.go index fdd39700e17..28b3a6ae0c7 100644 --- a/feature/system/system_base_test/tests/system_banner_test/system_banner_test.go +++ b/feature/system/system_base_test/tests/system_banner_test/system_banner_test.go @@ -57,10 +57,8 @@ func TestMotdBanner(t *testing.T) { t.Run("Get MOTD Config", func(t *testing.T) { if testCase.banner == "" { - if gnmi.LookupConfig(t, dut, config.Config()).IsPresent() { + if v, ok := gnmi.LookupConfig(t, dut, config.Config()).Val(); ok && v != "" { t.Errorf("MOTD Banner not empty") - } else { - t.Logf("No response for the path is expected as the config is empty") } } else { configGot := gnmi.Get(t, dut, config.Config()) @@ -73,10 +71,8 @@ func TestMotdBanner(t *testing.T) { t.Run("Get MOTD Telemetry", func(t *testing.T) { if testCase.banner == "" { - if gnmi.LookupConfig(t, dut, config.Config()).IsPresent() { + if v, ok := gnmi.Lookup(t, dut, state.State()).Val(); ok && v != "" { t.Errorf("MOTD Telemetry Banner not empty") - } else { - t.Logf("No response for the path is expected as the config is empty") } } else { stateGot := gnmi.Get(t, dut, state.State()) @@ -124,10 +120,8 @@ func TestLoginBanner(t *testing.T) { t.Run("Get Login Banner Config", func(t *testing.T) { if testCase.banner == "" { - if gnmi.LookupConfig(t, dut, config.Config()).IsPresent() { + if v, ok := gnmi.LookupConfig(t, dut, config.Config()).Val(); ok && v != "" { t.Errorf("Config Login Banner not empty") - } else { - t.Logf("No response for the path expected is expected as the config is empty") } } else { configGot := gnmi.Get(t, dut, config.Config()) @@ -140,10 +134,8 @@ func TestLoginBanner(t *testing.T) { t.Run("Get Login Banner Telemetry", func(t *testing.T) { if testCase.banner == "" { - if gnmi.LookupConfig(t, dut, config.Config()).IsPresent() { + if v, ok := gnmi.Lookup(t, dut, state.State()).Val(); ok && v != "" { t.Errorf("Telemetry Login Banner not empty") - } else { - t.Logf("No response for the path is expected as the config is empty") } } else { stateGot := gnmi.Get(t, dut, state.State()) From 79a1a1961fed5a5275799239eab8a1df747425ab Mon Sep 17 00:00:00 2001 From: Brandon Stoll Date: Fri, 21 Feb 2025 13:41:53 -0800 Subject: [PATCH 07/15] Update the groups who can authorize CI executions. (#3841) --- tools/ci-trigger/config.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/ci-trigger/config.go b/tools/ci-trigger/config.go index 3ab5af1e244..9061579e951 100644 --- a/tools/ci-trigger/config.go +++ b/tools/ci-trigger/config.go @@ -58,8 +58,7 @@ const ( // authorizedTeams is the list of GitHub organization teams authorized to launch Cloud Build jobs. var authorizedTeams = []string{ - "featureprofiles-maintainers", - "featureprofiles-quattro-tl", + "featureprofiles-writers", } // triggerKeywords is the list of authorized keywords to launch a test. The From dee7e7d8b80245ae1551a296d5beaf85f931b380 Mon Sep 17 00:00:00 2001 From: Brandon Stoll Date: Fri, 21 Feb 2025 15:37:05 -0800 Subject: [PATCH 08/15] Update ci-trigger to build using latest golang 1.x (#3842) --- tools/ci-trigger/cloudbuild.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/ci-trigger/cloudbuild.yaml b/tools/ci-trigger/cloudbuild.yaml index 41819d1663c..ac742d7d964 100644 --- a/tools/ci-trigger/cloudbuild.yaml +++ b/tools/ci-trigger/cloudbuild.yaml @@ -1,5 +1,5 @@ steps: - - name: golang:1.21 + - name: golang:1 entrypoint: /bin/bash args: [ '-c', 'go test -timeout 5m -v github.com/openconfig/featureprofiles/tools/ci-trigger/...'] - name: 'gcr.io/cloud-builders/docker' From 19e5b85a682e0c053def77ffe7a80be155420523 Mon Sep 17 00:00:00 2001 From: Brandon Stoll Date: Fri, 21 Feb 2025 18:17:01 -0800 Subject: [PATCH 09/15] Update ci-trigger's Dockerfile to use newest go1.x (#3843) --- tools/ci-trigger/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ci-trigger/Dockerfile b/tools/ci-trigger/Dockerfile index 9ef4a65f0c2..58d6abdd93e 100644 --- a/tools/ci-trigger/Dockerfile +++ b/tools/ci-trigger/Dockerfile @@ -1,8 +1,8 @@ -FROM golang:1.21 as builder +FROM golang:1 as builder WORKDIR /app COPY . /app/ RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o server github.com/openconfig/featureprofiles/tools/ci-trigger -FROM golang:1.21-alpine +FROM golang:1-alpine COPY --from=builder /app/server /server ENTRYPOINT ["/server"] CMD ["-alsologtostderr"] From 4b5f9e7be88eb6d8fbe6a343db9dcbdcd45a0f05 Mon Sep 17 00:00:00 2001 From: Ram Date: Mon, 24 Feb 2025 10:18:30 +0530 Subject: [PATCH 10/15] fixing ipv4_entry_test (#3836) --- .../ipv4_entry_test/ipv4_entry_test.go | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/feature/gribi/otg_tests/ipv4_entry_test/ipv4_entry_test.go b/feature/gribi/otg_tests/ipv4_entry_test/ipv4_entry_test.go index 7b44b9d500d..2dcf9965d41 100644 --- a/feature/gribi/otg_tests/ipv4_entry_test/ipv4_entry_test.go +++ b/feature/gribi/otg_tests/ipv4_entry_test/ipv4_entry_test.go @@ -117,10 +117,12 @@ func TestMain(m *testing.M) { func staticARPWithMagicUniversalIP(t *testing.T, dut *ondatra.DUTDevice) { t.Helper() + dummyIPCIDR1 := nh1IpAddr + "/32" + dummyIPCIDR2 := nh2IpAddr + "/32" p2 := dut.Port(t, "port2") p3 := dut.Port(t, "port3") s2 := &oc.NetworkInstance_Protocol_Static{ - Prefix: ygot.String(nh1IpAddr + "/32"), + Prefix: ygot.String(dummyIPCIDR1), NextHop: map[string]*oc.NetworkInstance_Protocol_Static_NextHop{ strconv.Itoa(nh1ID): { Index: ygot.String(strconv.Itoa(nh1ID)), @@ -131,7 +133,7 @@ func staticARPWithMagicUniversalIP(t *testing.T, dut *ondatra.DUTDevice) { }, } s3 := &oc.NetworkInstance_Protocol_Static{ - Prefix: ygot.String(nh2IpAddr + "/32"), + Prefix: ygot.String(dummyIPCIDR2), NextHop: map[string]*oc.NetworkInstance_Protocol_Static_NextHop{ strconv.Itoa(nh2ID): { Index: ygot.String(strconv.Itoa(nh2ID)), @@ -141,9 +143,24 @@ func staticARPWithMagicUniversalIP(t *testing.T, dut *ondatra.DUTDevice) { }, }, } + static1 := &oc.NetworkInstance_Protocol{ + Identifier: oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, + Name: ygot.String(deviations.StaticProtocolName(dut)), + Static: map[string]*oc.NetworkInstance_Protocol_Static{ + dummyIPCIDR1: s2, + }, + } + static2 := &oc.NetworkInstance_Protocol{ + Identifier: oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, + Name: ygot.String(deviations.StaticProtocolName(dut)), + Static: map[string]*oc.NetworkInstance_Protocol_Static{ + dummyIPCIDR2: s3, + }, + } + fptest.ConfigureDefaultNetworkInstance(t, dut) sp := gnmi.OC().NetworkInstance(deviations.DefaultNetworkInstance(dut)).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, deviations.StaticProtocolName(dut)) - gnmi.Replace(t, dut, sp.Static(nh1IpAddr+"/32").Config(), s2) - gnmi.Replace(t, dut, sp.Static(nh2IpAddr+"/32").Config(), s3) + gnmi.Update(t, dut, sp.Config(), static1) + gnmi.Update(t, dut, sp.Config(), static2) gnmi.Update(t, dut, gnmi.OC().Interface(p2.Name()).Config(), configStaticArp(p2, nh1IpAddr, staticDstMAC)) gnmi.Update(t, dut, gnmi.OC().Interface(p3.Name()).Config(), configStaticArp(p3, nh2IpAddr, staticDstMAC)) } @@ -349,7 +366,7 @@ func TestIPv4Entry(t *testing.T) { if tc.gribiMACOverrideWithStaticARPStaticRoute { staticARPWithMagicUniversalIP(t, dut) } else if tc.gribiMACOverrideWithStaticARP { - //Creating a Static ARP entry for staticDstMAC + // Creating a Static ARP entry for staticDstMAC d := gnmi.OC() p2 := dut.Port(t, "port2") p3 := dut.Port(t, "port3") @@ -359,7 +376,7 @@ func TestIPv4Entry(t *testing.T) { gnmi.Update(t, dut, d.Interface(p3.Name()).Config(), configStaticArp(p3, nh2IpAddr, staticDstMAC)) } if tc.gribiMACOverrideWithStaticARP || tc.gribiMACOverrideWithStaticARPStaticRoute { - //Programming a gRIBI flow with above IP/mac-address as the next-hop entry + // Programming a gRIBI flow with above IP/mac-address as the next-hop entry tc.entries = []fluent.GRIBIEntry{ fluent.NextHopEntry().WithNetworkInstance(deviations.DefaultNetworkInstance(dut)). WithIndex(nh1ID).WithInterfaceRef(dut.Port(t, "port2").Name()).WithIPAddress(nh1IpAddr).WithMacAddress(staticDstMAC), From d8f764e2ef2b862d71d8d3275016cc06615dd2f1 Mon Sep 17 00:00:00 2001 From: Ram Date: Mon, 24 Feb 2025 11:14:57 +0530 Subject: [PATCH 11/15] fix bgp_tcp_mss_path_mtu_test for issue with address family initialization (#3837) --- .../otg_tests/bgp_tcp_mss_path_mtu/bgp_tcp_mss_path_mtu_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/feature/bgp/otg_tests/bgp_tcp_mss_path_mtu/bgp_tcp_mss_path_mtu_test.go b/feature/bgp/otg_tests/bgp_tcp_mss_path_mtu/bgp_tcp_mss_path_mtu_test.go index 468f7480fdb..58975462e5f 100644 --- a/feature/bgp/otg_tests/bgp_tcp_mss_path_mtu/bgp_tcp_mss_path_mtu_test.go +++ b/feature/bgp/otg_tests/bgp_tcp_mss_path_mtu/bgp_tcp_mss_path_mtu_test.go @@ -118,6 +118,8 @@ func bgpCreateNbr(t *testing.T, dut *ondatra.DUTDevice, authPwd, routerID string global := bgp.GetOrCreateGlobal() global.RouterId = ygot.String(routerID) 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(peerGrpName1) pg1.PeerAs = ygot.Uint32(ateAS1) From 30f7ee83cfe0a07c550106627a396bf276469946 Mon Sep 17 00:00:00 2001 From: Pramod Maurya Date: Tue, 25 Feb 2025 11:02:04 +0530 Subject: [PATCH 12/15] added remote syslog test (#3845) --- .../logging/otg_tests/remote_syslog/README.md | 86 ++++ .../remote_syslog/metadata.textproto | 19 + .../remote_syslog/remote_syslog_test.go | 477 ++++++++++++++++++ .../logging/remote_syslog/feature.textproto | 59 --- .../logging/remote_syslog/otg_tests/README.md | 66 --- .../otg_tests/metadata.textproto | 7 - 6 files changed, 582 insertions(+), 132 deletions(-) create mode 100644 feature/system/logging/otg_tests/remote_syslog/README.md create mode 100644 feature/system/logging/otg_tests/remote_syslog/metadata.textproto create mode 100644 feature/system/logging/otg_tests/remote_syslog/remote_syslog_test.go delete mode 100644 feature/system/logging/remote_syslog/feature.textproto delete mode 100644 feature/system/logging/remote_syslog/otg_tests/README.md delete mode 100644 feature/system/logging/remote_syslog/otg_tests/metadata.textproto diff --git a/feature/system/logging/otg_tests/remote_syslog/README.md b/feature/system/logging/otg_tests/remote_syslog/README.md new file mode 100644 index 00000000000..1c988aee023 --- /dev/null +++ b/feature/system/logging/otg_tests/remote_syslog/README.md @@ -0,0 +1,86 @@ +# TR-6.1: Remote Syslog feature config + +## Summary + +Verify configuration of remote syslog host (server) in DEFAULT and non-default +VRF. + +## Procedure + +* Connect DUT port-1 with OTG port-1 and DUT port-2 with OTG port-2 +* Configure DUT $VRF-name network-instance and OTG with: + * interface(port-1), interface(port-2) with IPv4 and IPv6 address + * static host routes to syslog server addresses pointing OTG + interface(port-1) IP + * loopback interface with IPv4 and IPv6 address and netmasks of /32, /64 + respectively +* Configure syslog servers DUT + * Configure 1st IPv4 Syslog remote hosts in $VRF-name with: + * facility “local7” and severity “debug” + * (TODO when OC model published) compliance to RFC5424 (structured) + * source address equal to IPv4 address of loopback interface + * Configure 2nd IPv4 Syslog remote hosts in $VRF-name with: + * facility “local7” and severity “critical” + * (TODO when OC model published) compliance to RFC3164 (BSD/original) + * source address equal to IPv4 address of loopback interface + * Configure 3rd IPv6 Syslog remote hosts in $VRF-name with: + * non-standard remote port + * facility “local1” and severity “debug” + * (TODO when OC model published) compliance to RFC5424 (structured) + * source address equal to IPv6 address of loopback interface + * Configure 4th IPv6 Syslog remote hosts in $VRF-name with: + * facility “local7” and severity “critical” + * (TODO when OC model published) compliance to RFC3164 (BSD/original) + * source address equal to IPv6 address of loopback interface +* Test Procedure + * Read configuration of all 4 servers, verify it matches intent + * enable packet capture on OTG port-1 + * disable OTG port-2 so DUT interface(port-2) goes down, which should + generate log + * Observe on OTG capture: + * Syslog packet w/ DstIP of host 1st and 4th and standard dstPort. + * Syslog packet w/ DstIP of host 3rd and non-standard dstPort + * Note: no packet w/ DstIP of 2nd host is expected. + +### Test Case #1 - Default network instance + +``` +* Execute above procedure for $VRF-name = "DEFAULT" (default VRF) +``` + +### Test Case #2 - Non-Default network instance + +``` +* Execute above procedure for $VRF-name = "VRF-foo" +``` + +## OpenConfig Path and RPC Coverage + +```yaml +paths: + ## Config parameter coverage + /system/logging/remote-servers/remote-server/config/host: + /system/logging/remote-servers/remote-server/config/network-instance: + /system/logging/remote-servers/remote-server/config/remote-port: + /system/logging/remote-servers/remote-server/config/source-address: + /system/logging/remote-servers/remote-server/selectors/selector/config/facility: + /system/logging/remote-servers/remote-server/selectors/selector/config/severity: + + ## Telemetry parameter coverage + /system/logging/remote-servers/remote-server/state/host: + /system/logging/remote-servers/remote-server/state/network-instance: + /system/logging/remote-servers/remote-server/state/remote-port: + /system/logging/remote-servers/remote-server/state/source-address: + /system/logging/remote-servers/remote-server/selectors/selector/state/facility: + /system/logging/remote-servers/remote-server/selectors/selector/state/severity: + +rpcs: + gnmi: + gNMI.Get: + gNMI.Subscribe: + gNMI.Set: +``` + +## DUT + +FFF diff --git a/feature/system/logging/otg_tests/remote_syslog/metadata.textproto b/feature/system/logging/otg_tests/remote_syslog/metadata.textproto new file mode 100644 index 00000000000..6331971b622 --- /dev/null +++ b/feature/system/logging/otg_tests/remote_syslog/metadata.textproto @@ -0,0 +1,19 @@ +# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto +# proto-message: Metadata + +uuid: "1f83da73-9db4-43ae-a282-bc309ff64e0e" +plan_id: "TR-6.1" +description: "Remote Syslog feature config" +testbed: TESTBED_DUT_ATE_2LINKS +platform_exceptions: { + platform: { + vendor: ARISTA + } + deviations: { + omit_l2_mtu: true + interface_config_vrf_before_address: true + interface_enabled: true + default_network_instance: "default" + static_protocol_name: "STATIC" + } +} \ No newline at end of file diff --git a/feature/system/logging/otg_tests/remote_syslog/remote_syslog_test.go b/feature/system/logging/otg_tests/remote_syslog/remote_syslog_test.go new file mode 100644 index 00000000000..5ac04c0c873 --- /dev/null +++ b/feature/system/logging/otg_tests/remote_syslog/remote_syslog_test.go @@ -0,0 +1,477 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package remote_syslog_test + +import ( + "fmt" + "net" + "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/cfgplugins" + "github.com/openconfig/featureprofiles/internal/deviations" + "github.com/openconfig/featureprofiles/internal/fptest" + "github.com/openconfig/featureprofiles/internal/otgutils" + "github.com/openconfig/ondatra" + "github.com/openconfig/ondatra/gnmi" + "github.com/openconfig/ondatra/gnmi/oc" + "github.com/openconfig/ondatra/netutil" + "github.com/openconfig/ygot/ygot" +) + +const ( + pLen4 = 30 + pLen6 = 126 + trafficPps = 1000 + totalPackets = 30000 + flowV4 = "flowV4" + flowV6 = "flowV6" + v4Route = "203.0.113.0" + v6Route = "2001:db8:128:128::0" + v4RoutePrefix = uint32(24) + v6RoutePrefix = uint32(64) + lossTolerance = float64(1) +) + +var ( + dutSrc = &attrs.Attributes{ + Desc: "DUT Source", + IPv4: "192.0.2.1", + IPv6: "2001:DB8::192:0:2:1", + IPv4Len: pLen4, + IPv6Len: pLen6, + } + + ateSrc = &attrs.Attributes{ + Name: "port1", + MAC: "02:00:01:01:01:01", + Desc: "ATE Source", + IPv4: "192.0.2.2", + IPv6: "2001:DB8::192:0:2:2", + IPv4Len: pLen4, + IPv6Len: pLen6, + } + + dutDst = &attrs.Attributes{ + Desc: "DUT Destination", + IPv4: "192.0.2.5", + IPv6: "2001:DB8::192:0:2:5", + IPv4Len: pLen4, + IPv6Len: pLen6, + } + + ateDst = &attrs.Attributes{ + Name: "port2", + MAC: "02:00:02:01:01:01", + Desc: "ATE Destination", + IPv4: "192.0.2.6", + IPv6: "2001:DB8::192:0:2:6", + IPv4Len: pLen4, + IPv6Len: pLen6, + } + + dutLoopback = attrs.Attributes{ + Desc: "Loopback ip", + IPv4: "203.0.113.1", + IPv6: "2001:db8::203:0:113:1", + IPv4Len: 32, + IPv6Len: 128, + } + + lb string +) + +func TestMain(m *testing.M) { + fptest.RunTests(m) +} + +func TestRemoteSyslog(t *testing.T) { + dut := ondatra.DUT(t, "dut") + p1 := dut.Port(t, "port1") + p2 := dut.Port(t, "port2") + ate := ondatra.ATE(t, "ate") + lb = netutil.LoopbackInterface(t, dut, 0) + + top := configureATE(t, ate) + createFlow(t, top, true) + createFlow(t, top, false) + enableCapture(t, ate, top) + ate.OTG().PushConfig(t, top) + ate.OTG().StartProtocols(t) + + testCases := []struct { + name string + vrf string + }{ + { + name: "Default VRF", + vrf: deviations.DefaultNetworkInstance(dut), + }, + { + name: "Non-Default VRF", + vrf: "nondefaultvrfx", + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + if tc.vrf != deviations.DefaultNetworkInstance(dut) { + createAndAddInterfacesToVRF(t, dut, tc.vrf, []string{p1.Name(), p2.Name(), lb}, []uint32{0, 0, 0}) + } + + configureDUT(t, dut, &tc.vrf) + configureDUTLoopback(t, dut) + configureStaticRoute(t, dut, tc.vrf) + configureSyslog(t, dut, tc.vrf) + + otgutils.WaitForARP(t, ate.OTG(), top, "IPv4") + otgutils.WaitForARP(t, ate.OTG(), top, "IPv6") + + cs := startCapture(t, ate, top) + + sleepTime := time.Duration(totalPackets/trafficPps) + 2 + ate.OTG().StartTraffic(t) + flipATEPort(t, dut, ate, top, "port2", false) + time.Sleep(sleepTime * time.Second) + ate.OTG().StopTraffic(t) + + stopCapture(t, ate, cs) + + otgutils.LogFlowMetrics(t, ate.OTG(), top) + otgutils.LogPortMetrics(t, ate.OTG(), top) + + processCapture(t, ate, top) + + t.Cleanup(func() { + gnmi.Delete(t, dut, gnmi.OC().Interface(p1.Name()).Config()) + gnmi.Delete(t, dut, gnmi.OC().Interface(p2.Name()).Config()) + gnmi.Delete(t, dut, gnmi.OC().Interface(lb).Config()) + gnmi.Delete(t, dut, gnmi.OC().NetworkInstance(tc.vrf).Config()) + flipATEPort(t, dut, ate, top, "port2", true) + }) + }) + } +} + +// configureDUT configures port1 and port2 on the DUT +func configureDUT(t *testing.T, dut *ondatra.DUTDevice, vrfName *string) { + dp1 := dut.Port(t, "port1") + dp2 := dut.Port(t, "port2") + + gnmi.Update(t, dut, gnmi.OC().Interface(dp1.Name()).Config(), dutSrc.NewOCInterface(dp1.Name(), dut)) + gnmi.Update(t, dut, gnmi.OC().Interface(dp2.Name()).Config(), dutDst.NewOCInterface(dp2.Name(), dut)) + + if deviations.ExplicitPortSpeed(dut) { + fptest.SetPortSpeed(t, dp1) + fptest.SetPortSpeed(t, dp2) + } + if deviations.ExplicitInterfaceInDefaultVRF(dut) { + fptest.AssignToNetworkInstance(t, dut, dp1.Name(), deviations.DefaultNetworkInstance(dut), 0) + fptest.AssignToNetworkInstance(t, dut, dp2.Name(), deviations.DefaultNetworkInstance(dut), 0) + } + + if vrfName == nil { + fptest.ConfigureDefaultNetworkInstance(t, dut) + } +} + +// configureATE configures port1 and port2 on the ATE +func configureATE(t *testing.T, ate *ondatra.ATEDevice) gosnappi.Config { + top := gosnappi.NewConfig() + ap1 := ate.Port(t, "port1") + ap2 := ate.Port(t, "port2") + + ateSrc.AddToOTG(top, ap1, dutSrc) + ateDst.AddToOTG(top, ap2, dutDst) + + ate.OTG().PushConfig(t, top) + ate.OTG().StartProtocols(t) + + return top +} + +// configureDUTLoopback configures the loopback interface on the DUT +func configureDUTLoopback(t *testing.T, dut *ondatra.DUTDevice) { + t.Helper() + // lb = netutil.LoopbackInterface(t, dut, 0) + lo0 := gnmi.OC().Interface(lb).Subinterface(0) + ipv4Addrs := gnmi.LookupAll(t, dut, lo0.Ipv4().AddressAny().State()) + ipv6Addrs := gnmi.LookupAll(t, dut, lo0.Ipv6().AddressAny().State()) + foundV4 := false + for _, ip := range ipv4Addrs { + if v, ok := ip.Val(); ok { + foundV4 = true + dutLoopback.IPv4 = v.GetIp() + break + } + } + foundV6 := false + for _, ip := range ipv6Addrs { + if v, ok := ip.Val(); ok { + foundV6 = true + dutLoopback.IPv6 = v.GetIp() + break + } + } + if !foundV4 || !foundV6 { + lo1 := dutLoopback.NewOCInterface(lb, dut) + lo1.Type = oc.IETFInterfaces_InterfaceType_softwareLoopback + gnmi.Update(t, dut, gnmi.OC().Interface(lb).Config(), lo1) + } + + if deviations.ExplicitInterfaceInDefaultVRF(dut) { + fptest.AssignToNetworkInstance(t, dut, lb, deviations.DefaultNetworkInstance(dut), 0) + } +} + +func createAndAddInterfacesToVRF(t *testing.T, dut *ondatra.DUTDevice, vrfname string, intfNames []string, unit []uint32) { + root := &oc.Root{} + batchConfig := &gnmi.SetBatch{} + for index, intfName := range intfNames { + i := root.GetOrCreateInterface(intfName) + i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + i.Description = ygot.String(fmt.Sprintf("Port %s", strconv.Itoa(index+1))) + if intfName == netutil.LoopbackInterface(t, dut, 0) { + i.Type = oc.IETFInterfaces_InterfaceType_softwareLoopback + i.Description = ygot.String(fmt.Sprintf("Port %s", intfName)) + } + si := i.GetOrCreateSubinterface(unit[index]) + si.Enabled = ygot.Bool(true) + gnmi.BatchUpdate(batchConfig, gnmi.OC().Interface(intfName).Config(), i) + } + + mgmtNI := root.GetOrCreateNetworkInstance(vrfname) + mgmtNI.Type = oc.NetworkInstanceTypes_NETWORK_INSTANCE_TYPE_L3VRF + for index, intfName := range intfNames { + vi := mgmtNI.GetOrCreateInterface(intfName) + vi.Interface = ygot.String(intfName) + vi.Subinterface = ygot.Uint32(unit[index]) + } + gnmi.BatchReplace(batchConfig, gnmi.OC().NetworkInstance(vrfname).Config(), mgmtNI) + batchConfig.Set(t, dut) + t.Logf("Added interface %v to VRF %s", intfNames, vrfname) +} + +func configureStaticRoute(t *testing.T, dut *ondatra.DUTDevice, ni string) { + b := &gnmi.SetBatch{} + sV4 := &cfgplugins.StaticRouteCfg{ + NetworkInstance: ni, + Prefix: v4Route + "/30", + NextHops: map[string]oc.NetworkInstance_Protocol_Static_NextHop_NextHop_Union{ + "0": oc.UnionString(ateSrc.IPv4), + }, + } + if _, err := cfgplugins.NewStaticRouteCfg(b, sV4, dut); err != nil { + t.Fatalf("Failed to configure IPv4 static route: %v", err) + } + sV6 := &cfgplugins.StaticRouteCfg{ + NetworkInstance: ni, + Prefix: v6Route + "/126", + NextHops: map[string]oc.NetworkInstance_Protocol_Static_NextHop_NextHop_Union{ + "0": oc.UnionString(ateSrc.IPv6), + }, + } + if _, err := cfgplugins.NewStaticRouteCfg(b, sV6, dut); err != nil { + t.Fatalf("Failed to configure IPv6 static route: %v", err) + } + b.Set(t, dut) +} + +func configureSyslog(t *testing.T, dut *ondatra.DUTDevice, ni string) { + root := &oc.Root{} + logging := root.GetOrCreateSystem().GetOrCreateLogging() + + remoteServer1 := logging.GetOrCreateRemoteServer("203.0.113.1") + remoteServer1.SetNetworkInstance(ni) + remoteServer1.SetSourceAddress(dutLoopback.IPv4) + remoteServer1.GetOrCreateSelector( + oc.SystemLogging_SYSLOG_FACILITY_LOCAL7, + oc.SystemLogging_SyslogSeverity_DEBUG, + ) + + remoteServer2 := logging.GetOrCreateRemoteServer("203.0.113.2") + remoteServer2.SetNetworkInstance(ni) + remoteServer2.SetSourceAddress(dutLoopback.IPv4) + remoteServer2.GetOrCreateSelector( + oc.SystemLogging_SYSLOG_FACILITY_LOCAL7, + oc.SystemLogging_SyslogSeverity_CRITICAL, + ) + + remoteServer3 := logging.GetOrCreateRemoteServer("2001:db8:128:128::1") + remoteServer3.SetNetworkInstance(ni) + remoteServer3.SetRemotePort(5140) + remoteServer3.SetSourceAddress(dutLoopback.IPv6) + remoteServer3.GetOrCreateSelector( + oc.SystemLogging_SYSLOG_FACILITY_LOCAL1, + oc.SystemLogging_SyslogSeverity_DEBUG, + ) + + remoteServer4 := logging.GetOrCreateRemoteServer("2001:db8:128:128::2") + remoteServer4.SetNetworkInstance(ni) + remoteServer4.SetSourceAddress(dutLoopback.IPv6) + remoteServer4.GetOrCreateSelector( + oc.SystemLogging_SYSLOG_FACILITY_LOCAL7, + oc.SystemLogging_SyslogSeverity_CRITICAL, + ) + + gnmi.Replace(t, dut, gnmi.OC().System().Logging().Config(), logging) +} + +// createFlow creates a traffic flow with fixed number of packets +func createFlow(t *testing.T, top gosnappi.Config, isV4 bool) { + flowName := flowV4 + if !isV4 { + flowName = flowV6 + } + + flow := top.Flows().Add().SetName(flowName) + flow.Metrics().SetEnable(true) + if isV4 { + flow.TxRx().Device(). + SetTxNames([]string{ateSrc.Name + ".IPv4"}). + SetRxNames([]string{ateDst.Name + ".IPv4"}) + } else { + flow.TxRx().Device(). + SetTxNames([]string{ateSrc.Name + ".IPv6"}). + SetRxNames([]string{ateDst.Name + ".IPv6"}) + } + + flow.Duration().FixedPackets().SetPackets(totalPackets) + flow.Size().SetFixed(1500) + flow.Rate().SetPps(trafficPps) + + ethHdr := flow.Packet().Add().Ethernet() + ethHdr.Src().SetValue(ateSrc.MAC) + + if isV4 { + ipv4Hdr := flow.Packet().Add().Ipv4() + ipv4Hdr.Src().SetValue(ateSrc.IPv4) + ipv4Hdr.Dst().SetValue(ateDst.IPv4) + } else { + ipv6Hdr := flow.Packet().Add().Ipv6() + ipv6Hdr.Src().SetValue(ateSrc.IPv6) + ipv6Hdr.Dst().SetValue(ateDst.IPv6) + } +} + +func flipATEPort(t *testing.T, dut *ondatra.DUTDevice, ate *ondatra.ATEDevice, top gosnappi.Config, port string, enable bool) { + expStatus := oc.Interface_OperStatus_DOWN + if enable { + expStatus = oc.Interface_OperStatus_UP + } + if deviations.ATEPortLinkStateOperationsUnsupported(ate) { + dutP := dut.Port(t, port) + dc := gnmi.OC() + i := &oc.Interface{} + i.Enabled = ygot.Bool(enable) + i.Name = ygot.String(dutP.Name()) + i.Type = oc.IETFInterfaces_InterfaceType_ethernetCsmacd + gnmi.Update(t, dut, dc.Interface(dutP.Name()).Config(), i) + } else { + portStateAction := gosnappi.NewControlState() + if enable { + portStateAction.Port().Link().SetPortNames([]string{port}).SetState(gosnappi.StatePortLinkState.UP) + } else { + portStateAction.Port().Link().SetPortNames([]string{port}).SetState(gosnappi.StatePortLinkState.DOWN) + } + ate.OTG().SetControlState(t, portStateAction) + } + gnmi.Await(t, dut, gnmi.OC().Interface(dut.Port(t, port).Name()).OperStatus().State(), 2*time.Minute, expStatus) +} + +func enableCapture(t *testing.T, ate *ondatra.ATEDevice, config gosnappi.Config) { + t.Helper() + + config.Captures().Clear() + + // enable packet capture on this port + config.Captures().Add().SetName("sFlowpacketCapture"). + SetPortNames([]string{config.Ports().Items()[0].Name()}). + SetFormat(gosnappi.CaptureFormat.PCAP) + + pb, _ := config.Marshal().ToProto() + t.Log(pb.GetCaptures()) +} + +func startCapture(t *testing.T, ate *ondatra.ATEDevice, config gosnappi.Config) gosnappi.ControlState { + t.Helper() + + cs := gosnappi.NewControlState() + cs.Port().Capture().SetState(gosnappi.StatePortCaptureState.START) + ate.OTG().SetControlState(t, cs) + + return cs +} + +func stopCapture(t *testing.T, ate *ondatra.ATEDevice, cs gosnappi.ControlState) { + t.Helper() + cs.Port().Capture().SetState(gosnappi.StatePortCaptureState.STOP) + ate.OTG().SetControlState(t, cs) +} + +func processCapture(t *testing.T, ate *ondatra.ATEDevice, config gosnappi.Config) { + bytes := ate.OTG().GetCapture(t, gosnappi.NewCaptureRequest().SetPortName(config.Ports().Items()[0].Name())) + time.Sleep(30 * time.Second) + pcapFile, err := os.CreateTemp("", "pcap") + if err != nil { + t.Errorf("ERROR: Could not create temporary pcap file: %v\n", err) + } + if _, err := pcapFile.Write(bytes); err != nil { + t.Errorf("ERROR: Could not write bytes to pcap file: %v\n", err) + } + pcapFile.Close() + validatePackets(t, pcapFile.Name()) +} + +func validatePackets(t *testing.T, filename string) { + handle, err := pcap.OpenOffline(filename) + if err != nil { + t.Fatal(err) + } + defer handle.Close() + + loopbackV4 := net.ParseIP(dutLoopback.IPv4) + loopbackV6 := net.ParseIP(dutLoopback.IPv6) + packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) + + foundV4 := false + foundV6 := false + for packet := range packetSource.Packets() { + if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil { + ipv4, _ := ipLayer.(*layers.IPv4) + if ipv4.SrcIP.Equal(loopbackV4) { + foundV4 = true + t.Logf("tos %d, payload %d, content %d, length %d", ipv4.TOS, len(ipv4.Payload), len(ipv4.Contents), ipv4.Length) + } + } else if ipLayer := packet.Layer(layers.LayerTypeIPv6); ipLayer != nil { + ipv6, _ := ipLayer.(*layers.IPv6) + if ipv6.SrcIP.Equal(loopbackV6) { + foundV6 = true + t.Logf("tos %d, payload %d, content %d, length %d", ipv6.TrafficClass, len(ipv6.Payload), len(ipv6.Contents), ipv6.Length) + } + } + + } + + if !foundV4 { + t.Errorf("sflow packets not found: v4 %v, v6 %v", foundV4, foundV6) + } +} diff --git a/feature/system/logging/remote_syslog/feature.textproto b/feature/system/logging/remote_syslog/feature.textproto deleted file mode 100644 index 6c14fbb34ba..00000000000 --- a/feature/system/logging/remote_syslog/feature.textproto +++ /dev/null @@ -1,59 +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: "system_logging_remote_syslog" - version: 1 -} - -# remote syslog -config_path { - path: "/system/logging/remote-servers/remote-server/config/host" -} -config_path { - path: "/system/logging/remote-servers/remote-server/config/network-instance" -} -config_path { - path: "/system/logging/remote-servers/remote-server/config/remote-port" -} -config_path { - path: "/system/logging/remote-servers/remote-server/config/source-address" -} -config_path { - path: "/system/logging/remote-servers/remote-server/selectors/selector/config/facility" -} -config_path { - path: "/system/logging/remote-servers/remote-server/selectors/selector/config/severity" -} -telemetry_path { - path: "/system/logging/remote-servers/remote-server/state/host" -} -telemetry_path { - path: "/system/logging/remote-servers/remote-server/state/network-instance" -} -telemetry_path { - path: "/system/logging/remote-servers/remote-server/state/remote-port" -} -telemetry_path { - path: "/system/logging/remote-servers/remote-server/state/source-address" -} -telemetry_path { - path: "/system/logging/remote-servers/remote-server/selectors/selector/state/facility" -} -telemetry_path { - path: "/system/logging/remote-servers/remote-server/selectors/selector/state/severity" -} diff --git a/feature/system/logging/remote_syslog/otg_tests/README.md b/feature/system/logging/remote_syslog/otg_tests/README.md deleted file mode 100644 index c0c5930b0e9..00000000000 --- a/feature/system/logging/remote_syslog/otg_tests/README.md +++ /dev/null @@ -1,66 +0,0 @@ -# TR-6.1: Remote Syslog feature config - -## Summary - -Verify configuration of remote syslog host (server) in DEFAULT and non-default VRF. - -## Procedure -* connect DUT port-1 with OTG port-1 and DUT port-2 with OTG port-2 -* Configure DUT $VRF-name network-instance and OTG with: - * interface(port-1), interface(port-2) with IPv4 and IPv6 address - * static host routes to syslog servers's addresses pointing OTG interface(port-1) IP - * loopback interface with IPv4 and IPv6 address and netmasks of /32, /64 respectively -* Configure syslog servers DUT - * Configure 1st IPv4 Syslog remote hosts in $VRF-name with: - * facility “local7” and severity “debug” - * (TODO when OC model published) complince to RFC5424 (structured) - * source address equall to IPv4 address of loopback interface - * Configure 2nd IPv4 Syslog remote hosts in $VRF-name with: - * facility “local7” and severity “critical” - * (TODO when OC model published) complince to RFC3164 (BSD/original) - * source address equall to IPv4 address of loopback interface - * Configure 3nd IPv6 Syslog remote hosts in $VRF-name with: - * non-standard remote port - * facility “local1” and severity “debug” - * (TODO when OC model published) complince to RFC5424 (structured) - * source address equall to IPv6 address of loopback interface - * Configure 4nd IPv6 Syslog remote hosts in $VRF-name with: - * facility “local7” and severity “critical” - * (TODO when OC model published) complince to RFC3164 (BSD/original) - * source address equall to IPv6 address of loopback interface -* Test Procedure - * Read configuration of all 4 servers, verify it matches intent - * enable packet capture on OTG port-1 - * disable OTG port-2 so DUT interface(port-2) goes down, what should generate log - * Observe on OTG capture: - * Syslog packet w/ DstIP of host 1st and 4th and standard dstPort. - * Syslog packet w/ DstIP of host 3rd and non-standard dstPort - * Note: no packet w/ DstIP of 2nd host is expected. - -### Test Case #1 - Default network instance - * Execute above procedure for $VRF-name = "DEFAULT" (default VRF) - -### Test Case #2 - Non-Default network instance - * Execute above procedure for $VRF-name = "VRF-foo" - - -## Config parameter coverage -* /system/logging/remote-servers/remote-server/config/host -* /system/logging/remote-servers/remote-server/config/network-instance -* /system/logging/remote-servers/remote-server/config/remote-port -* /system/logging/remote-servers/remote-server/config/source-address -* /system/logging/remote-servers/remote-server/selectors/selector/config/facility -* /system/logging/remote-servers/remote-server/selectors/selector/config/severity - -## Telemetry parameter coverage -* /system/logging/remote-servers/remote-server/state/host -* /system/logging/remote-servers/remote-server/state/network-instance -* /system/logging/remote-servers/remote-server/state/remote-port -* /system/logging/remote-servers/remote-server/state/source-address -* /system/logging/remote-servers/remote-server/selectors/selector/state/facility -* /system/logging/remote-servers/remote-server/selectors/selector/state/severity - - -## DUT -FFF - diff --git a/feature/system/logging/remote_syslog/otg_tests/metadata.textproto b/feature/system/logging/remote_syslog/otg_tests/metadata.textproto deleted file mode 100644 index 001be11ca91..00000000000 --- a/feature/system/logging/remote_syslog/otg_tests/metadata.textproto +++ /dev/null @@ -1,7 +0,0 @@ -# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto -# proto-message: Metadata - -uuid: "1f83da73-9db4-43ae-a282-bc309ff64e0e" -plan_id: "TR-6.1" -description: "Remote Syslog feature config" -testbed: TESTBED_DUT_ATE_2LINKS From 5b8036af21a268c22ebfe23fd72ea1d4b8924c50 Mon Sep 17 00:00:00 2001 From: AmrNJ <155722765+AmrNJ@users.noreply.github.com> Date: Tue, 25 Feb 2025 11:07:05 +0530 Subject: [PATCH 13/15] Te 14.1 remove cisco deviation (#3838) * Update gribi_scaling_test.go Remove deviation block overrideScaleParams * Update metadata.textproto * Format of go file --- .../otg_tests/gribi_scaling/gribi_scaling_test.go | 10 ---------- .../gribi/otg_tests/gribi_scaling/metadata.textproto | 1 - 2 files changed, 11 deletions(-) diff --git a/feature/gribi/otg_tests/gribi_scaling/gribi_scaling_test.go b/feature/gribi/otg_tests/gribi_scaling/gribi_scaling_test.go index deb328c20c9..f1a979f70b4 100644 --- a/feature/gribi/otg_tests/gribi_scaling/gribi_scaling_test.go +++ b/feature/gribi/otg_tests/gribi_scaling/gribi_scaling_test.go @@ -263,7 +263,6 @@ func incrementMAC(mac string, i int) (string, error) { func TestScaling(t *testing.T) { dut := ondatra.DUT(t, "dut") - overrideScaleParams(dut) ate := ondatra.ATE(t, "ate") ctx := context.Background() @@ -399,12 +398,3 @@ func checkTraffic(t *testing.T, ate *ondatra.ATEDevice, top gosnappi.Config) { t.Errorf("FAIL- Got %v%% packet loss for %s ; expected < 1%%", lossPct, "flow") } } - -// overrideScaleParams allows to override the default scale parameters based on the DUT vendor. -func overrideScaleParams(dut *ondatra.DUTDevice) { - if deviations.OverrideDefaultNhScale(dut) { - if dut.Vendor() == ondatra.CISCO { - *fpargs.V4TunnelCount = 3328 - } - } -} diff --git a/feature/gribi/otg_tests/gribi_scaling/metadata.textproto b/feature/gribi/otg_tests/gribi_scaling/metadata.textproto index 393d30f1bd5..b0d851734a9 100644 --- a/feature/gribi/otg_tests/gribi_scaling/metadata.textproto +++ b/feature/gribi/otg_tests/gribi_scaling/metadata.textproto @@ -12,7 +12,6 @@ platform_exceptions: { deviations: { ipv4_missing_enabled: true interface_ref_interface_id_format: true - override_default_nh_scale: true } } platform_exceptions: { From 300f44f462e0c0f2c6cfae7ead12b55369120249 Mon Sep 17 00:00:00 2001 From: lvaish05 <168406079+lvaish05@users.noreply.github.com> Date: Wed, 26 Feb 2025 12:56:25 +0530 Subject: [PATCH 14/15] Health 1.1 system_generic_health_check (#3693) * removing deviations that are not required and adding code for components presence * skipping test for FFF * edited the check from lineCards to chassisLineCards --- .../metadata.textproto | 2 - .../system_generic_health_check_test.go | 43 ++++++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/feature/system/health/tests/system_generic_health_check/metadata.textproto b/feature/system/health/tests/system_generic_health_check/metadata.textproto index 7c47220cea4..b37466a0f83 100644 --- a/feature/system/health/tests/system_generic_health_check/metadata.textproto +++ b/feature/system/health/tests/system_generic_health_check/metadata.textproto @@ -10,11 +10,9 @@ platform_exceptions: { vendor: JUNIPER } deviations: { - linecard_cpu_utilization_unsupported: true consistent_component_names_unsupported: true controller_card_cpu_utilization_unsupported: true fabric_drop_counter_unsupported: true - linecard_memory_utilization_unsupported: true qos_voq_drop_counter_unsupported: true qos_inqueue_drop_counter_unsupported: true } diff --git a/feature/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 index 2c182375063..5b68e3b74cc 100644 --- a/feature/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 @@ -148,6 +148,22 @@ func TestComponentStatus(t *testing.T) { controllerCards := components.FindComponentsByType(t, dut, controllerCardType) lineCards := components.FindComponentsByType(t, dut, lineCardType) fabricCards := components.FindComponentsByType(t, dut, fabricCardType) + fabrics := make([]string, 0) + for _, f := range fabricCards { + compMtyVal, ok := gnmi.Lookup(t, dut, gnmi.OC().Component(f).Empty().State()).Val() + if !compMtyVal && ok { + fabrics = append(fabrics, f) + } + } + fabricCards = fabrics + chassisLineCards := make([]string, 0) + for _, lc := range lineCards { + compMtyVal, ok := gnmi.Lookup(t, dut, gnmi.OC().Component(lc).Empty().State()).Val() + if !compMtyVal && ok { + chassisLineCards = append(chassisLineCards, lc) + } + } + lineCards = chassisLineCards checkComponents := append(controllerCards, lineCards...) checkComponents = append(checkComponents, fabricCards...) if len(checkComponents) == 0 { @@ -246,6 +262,20 @@ func TestLineCardsNoHighCPUSpike(t *testing.T) { lineCards := components.FindComponentsByType(t, dut, lineCardType) cpuCards := components.FindComponentsByType(t, dut, cpuType) + chassisLineCards := make([]string, 0) + for _, lc := range lineCards { + compMtyVal, ok := gnmi.Lookup(t, dut, gnmi.OC().Component(lc).Empty().State()).Val() + if !compMtyVal && ok { + chassisLineCards = append(chassisLineCards, lc) + } + } + + for _, lc := range chassisLineCards { + if !gnmi.Get(t, dut, gnmi.OC().Component(lc).Removable().State()) { + t.Skipf("Skip the test on non-removable linecard.") + } + } + lineCards = chassisLineCards if len(lineCards) == 0 || len(cpuCards) == 0 { t.Errorf("ERROR: No controllerCard or cpuCard has been found.") } @@ -288,10 +318,19 @@ func TestComponentsNoHighMemoryUtilization(t *testing.T) { controllerCards := components.FindComponentsByType(t, dut, controllerCardType) lineCards := components.FindComponentsByType(t, dut, lineCardType) + chassisLineCards := make([]string, 0) + for _, lc := range lineCards { + compMtyVal, ok := gnmi.Lookup(t, dut, gnmi.OC().Component(lc).Empty().State()).Val() + if !compMtyVal && ok { + chassisLineCards = append(chassisLineCards, lc) + } + } + lineCards = chassisLineCards cardList := append(controllerCards, lineCards...) if len(cardList) == 0 { t.Errorf("ERROR: No card has been found.") } + for _, component := range cardList { t.Run(component, func(t *testing.T) { query := gnmi.OC().Component(component).State() @@ -301,7 +340,9 @@ func TestComponentsNoHighMemoryUtilization(t *testing.T) { if componentType == lineCardType && deviations.LinecardMemoryUtilizationUnsupported(dut) { t.Skipf("INFO: Skipping test for linecard component %s due to deviation linecard_memory_utilization_unsupported", component) } - + if componentType == lineCardType && !gnmi.Get(t, dut, gnmi.OC().Component(component).Removable().State()) { + t.Skipf("Skip the test on non-removable linecard.") + } memoryState := componentState.GetMemory() if memoryState == nil { t.Errorf("ERROR: %s - Device: %s - %s: %-40s - Type: %-20s - Memory data not available", From 84ffc4691aa64898858ba23ec1653e0a55625b41 Mon Sep 17 00:00:00 2001 From: arvbaska1 <123760606+arvbaska1@users.noreply.github.com> Date: Wed, 26 Feb 2025 05:04:07 -0500 Subject: [PATCH 15/15] RT-2.14 | Changes to isis drain test (#3844) * Changes to RT-2.14 test * comment space --- feature/isis/otg_tests/isis_drain_test/isis_drain_test.go | 7 +++++++ feature/isis/otg_tests/isis_drain_test/metadata.textproto | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/feature/isis/otg_tests/isis_drain_test/isis_drain_test.go b/feature/isis/otg_tests/isis_drain_test/isis_drain_test.go index 13ba419a8da..ecd49d7455f 100644 --- a/feature/isis/otg_tests/isis_drain_test/isis_drain_test.go +++ b/feature/isis/otg_tests/isis_drain_test/isis_drain_test.go @@ -239,6 +239,10 @@ func configureISISDUT(t *testing.T, dut *ondatra.DUTDevice, intfs []string) { isis := prot.GetOrCreateIsis() globalISIS := isis.GetOrCreateGlobal() + // Explicit Disable the default igp-ldp-sync enabled global leaf + isismpls := prot.GetOrCreateIsis().GetOrCreateGlobal().GetOrCreateMpls() + isismplsldpsync := isismpls.GetOrCreateIgpLdpSync() + isismplsldpsync.Enabled = ygot.Bool(false) if deviations.ISISInstanceEnabledRequired(dut) { globalISIS.Instance = ygot.String(isisInstance) } @@ -257,6 +261,9 @@ func configureISISDUT(t *testing.T, dut *ondatra.DUTDevice, intfs []string) { } for _, intfName := range intfs { isisIntf := isis.GetOrCreateInterface(intfName) + // Explicit Disable the default igp-ldp-sync enabled interface level leaf + isisintfmplsldpsync := isisIntf.GetOrCreateMpls().GetOrCreateIgpLdpSync() + isisintfmplsldpsync.Enabled = ygot.Bool(false) isisIntf.GetOrCreateInterfaceRef().Interface = ygot.String(intfName) isisIntf.GetOrCreateInterfaceRef().Subinterface = ygot.Uint32(0) if deviations.InterfaceRefConfigUnsupported(dut) { diff --git a/feature/isis/otg_tests/isis_drain_test/metadata.textproto b/feature/isis/otg_tests/isis_drain_test/metadata.textproto index e704ecde9cb..a88caac1300 100644 --- a/feature/isis/otg_tests/isis_drain_test/metadata.textproto +++ b/feature/isis/otg_tests/isis_drain_test/metadata.textproto @@ -22,7 +22,7 @@ platform_exceptions: { } deviations: { ipv4_missing_enabled: true - missing_isis_interface_afi_safi_enable: true + interface_ref_config_unsupported: true } } platform_exceptions: {