From cdf69579169253027a557ccd2b47c8fa1f5da894 Mon Sep 17 00:00:00 2001 From: wenovus Date: Tue, 22 Aug 2023 13:29:05 -0700 Subject: [PATCH 1/8] Refactor Policy Tests --- Makefile | 4 + bgp/tests/local_tests/community_set_test.go | 4 +- bgp/tests/local_tests/policy_test.go | 188 ++++++++++++------ bgp/tests/local_tests/prefix_set_test.go | 2 +- .../local_tests/session_establish_test.go | 8 + .../proto/policyval/policy_validation.pb.go | 106 ++++++---- .../proto/policyval/policy_validation.proto | 3 + 7 files changed, 204 insertions(+), 111 deletions(-) diff --git a/Makefile b/Makefile index f8c073bb..f13b3acc 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,10 @@ buildfile: bazel run //:gazelle -- update-repos -to_macro=repositories.bzl%go_repositories -from_file=go.mod bazel run //:gazelle +.PHONY: genprotos +genprotos: + tools/genproto.sh + .PHONY: load-debug load-debug: DOCKER_BUILDKIT=1 docker build . --target debug -f Dockerfile.lemming -t "us-west1-docker.pkg.dev/openconfig-lemming/release/lemming:ga" diff --git a/bgp/tests/local_tests/community_set_test.go b/bgp/tests/local_tests/community_set_test.go index 76cadf26..31399f53 100644 --- a/bgp/tests/local_tests/community_set_test.go +++ b/bgp/tests/local_tests/community_set_test.go @@ -52,7 +52,7 @@ func TestCommunitySet(t *testing.T) { ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT, }}, }, - installSetPolicies: func(t *testing.T, dut2 *ygnmi.Client) { + installImportSetPolicies: func(t *testing.T, dut2 *ygnmi.Client) { if debug { fmt.Println("Installing test policies") } @@ -87,7 +87,7 @@ func TestCommunitySet(t *testing.T) { Replace(t, dut2, ocpath.Root().RoutingPolicy().PolicyDefinition(policyName).Config(), &oc.RoutingPolicy_PolicyDefinition{Statement: policy}) Replace(t, dut2, bgp.BGPPath.Neighbor(dut1spec.RouterID).ApplyPolicy().ImportPolicy().Config(), []string{policyName}) }, - installPolicies: func(t *testing.T, dut2 *ygnmi.Client) { + installExportFilterPolicies: func(t *testing.T, dut2 *ygnmi.Client) { if debug { fmt.Println("Installing test policies") } diff --git a/bgp/tests/local_tests/policy_test.go b/bgp/tests/local_tests/policy_test.go index 080913e2..2124da4f 100644 --- a/bgp/tests/local_tests/policy_test.go +++ b/bgp/tests/local_tests/policy_test.go @@ -36,13 +36,20 @@ const ( // PolicyTestCase contains the specifications for a single policy test. // -// Limitations: -// * Does not check path attributes. -// * Only checks export policies. +// Topology: +// +// DUT1 -> DUT2 -> DUT3 +// ^ +// | +// DUT4 -> DUT5 +// +// Currently, all policies are installed on DUT2, and by convention, +// the import policies set attributes, and export policy to DUT3 filters +// prefixes. type PolicyTestCase struct { - spec *valpb.PolicyTestCase - installSetPolicies func(t *testing.T, dut2 *ygnmi.Client) - installPolicies func(t *testing.T, dut2 *ygnmi.Client) + spec *valpb.PolicyTestCase + installImportSetPolicies func(t *testing.T, dut2 *ygnmi.Client) + installExportFilterPolicies func(t *testing.T, dut2 *ygnmi.Client) } // testPolicy is the helper policy integration tests can call to instantiate @@ -58,6 +65,66 @@ func testPolicy(t *testing.T, testspec PolicyTestCase) { }) } +func testPropagation(t *testing.T, routeTest *valpb.RouteTestCase, prevDUT, currDUT, nextDUT *ygnmi.Client, prevRouterID, currRouterID, nextRouterID string, filterPoliciesInstalled bool) { + t.Helper() + v4uni := bgp.BGPPath.Rib().AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast() + + prefix := routeTest.GetInput().GetReachPrefix() + // Check propagation to AdjRibOutPre for all prefixes. + Await(t, prevDUT, v4uni.Neighbor(currRouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) + Await(t, prevDUT, v4uni.Neighbor(currRouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) + Await(t, currDUT, v4uni.Neighbor(prevRouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) + Await(t, currDUT, v4uni.Neighbor(prevRouterID).AdjRibInPost().Route(prefix, 0).Prefix().State(), prefix) + switch { + case routeTest.GetExpectedResult() == policyval.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT, !filterPoliciesInstalled: + Await(t, currDUT, v4uni.LocRib().Route(prefix, oc.UnionString(prevRouterID), 0).Prefix().State(), prefix) + Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) + t.Logf("Waiting for %s to be propagated", prefix) + Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) + Await(t, nextDUT, v4uni.Neighbor(currRouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) + case routeTest.GetExpectedResult() == policyval.RouteTestResult_ROUTE_TEST_RESULT_DISCARD: + Await(t, currDUT, v4uni.LocRib().Route(prefix, oc.UnionString(prevRouterID), 0).Prefix().State(), prefix) + Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) + w := Watch(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { + _, ok := val.Val() + return ok + }) + if _, ok := w.Await(t); ok { + t.Errorf("prefix %q (%s) was not rejected from adj-rib-out-post of %v within timeout.", prefix, routeTest.GetDescription(), currDUT) + } else { + t.Logf("prefix %q (%s) was successfully rejected from adj-rib-out-post of %v within timeout.", prefix, routeTest.GetDescription(), currDUT) + } + w = Watch(t, nextDUT, v4uni.Neighbor(currRouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { + _, ok := val.Val() + return ok + }) + if _, ok := w.Await(t); ok { + t.Errorf("prefix %q (%s) was not rejected from adj-rib-in-pre of %v within timeout.", prefix, routeTest.GetDescription(), nextDUT) + } else { + t.Logf("prefix %q (%s) was successfully rejected from adj-rib-in-pre of %v within timeout.", prefix, routeTest.GetDescription(), nextDUT) + } + case routeTest.GetExpectedResult() == policyval.RouteTestResult_ROUTE_TEST_RESULT_NOT_PREFERRED: + w := Watch(t, currDUT, v4uni.LocRib().Route(prefix, oc.UnionString(prevRouterID), 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { + _, ok := val.Val() + return ok + }) + if _, ok := w.Await(t); ok { + t.Errorf("prefix %q with origin %q (%s) was selected into loc-rib of %v.", prefix, prevRouterID, routeTest.GetDescription(), currDUT) + } else { + t.Logf("prefix %q with origin %q (%s) was successfully not selected into loc-rib of %v within timeout.", prefix, prevRouterID, routeTest.GetDescription(), currDUT) + } + w = Watch(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { + _, ok := val.Val() + return ok + }) + if _, ok := w.Await(t); ok { + t.Errorf("prefix %q (%s) was not rejected from adj-rib-out-pre of %v within timeout.", prefix, routeTest.GetDescription(), currDUT) + } else { + t.Logf("prefix %q (%s) was successfully rejected from adj-rib-out-pre of %v within timeout.", prefix, routeTest.GetDescription(), currDUT) + } + } +} + func testPolicyAux(t *testing.T, testspec PolicyTestCase, installPolicyAfterRoutes bool) { dut1, stop1 := newLemming(t, dut1spec, []*AddIntfAction{{ name: "eth0", @@ -71,29 +138,50 @@ func testPolicyAux(t *testing.T, testspec PolicyTestCase, installPolicyAfterRout defer stop2() dut3, stop3 := newLemming(t, dut3spec, nil) defer stop3() + dut4, stop4 := newLemming(t, dut4spec, []*AddIntfAction{{ + name: "eth0", + ifindex: 0, + enabled: true, + prefix: "192.0.2.2/30", + niName: "DEFAULT", + }}) + defer stop4() + dut5, stop5 := newLemming(t, dut5spec, nil) + defer stop5() installDefaultPolicies := func() { // Clear the path for routes to be propagated. + // DUT1 -> DUT2 -> DUT3 Replace(t, dut1, bgp.BGPPath.Neighbor(dut2spec.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) Replace(t, dut2, bgp.BGPPath.Neighbor(dut1spec.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) Replace(t, dut2, bgp.BGPPath.Neighbor(dut3spec.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) Replace(t, dut3, bgp.BGPPath.Neighbor(dut2spec.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + + // This is an alternate source of routes towards DUT2 and thereby DUT3. + // Note that this path is longer than the above path: + // DUT4 -> DUT5 -> DUT2 (-> DUT3) + Replace(t, dut4, bgp.BGPPath.Neighbor(dut5spec.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut5, bgp.BGPPath.Neighbor(dut4spec.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut5, bgp.BGPPath.Neighbor(dut2spec.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut2, bgp.BGPPath.Neighbor(dut5spec.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) } installDefaultPolicies() - if testspec.installSetPolicies != nil { - testspec.installSetPolicies(t, dut2) + if testspec.installImportSetPolicies != nil { + testspec.installImportSetPolicies(t, dut2) } - if testspec.installPolicies != nil && !installPolicyAfterRoutes { - testspec.installPolicies(t, dut2) + if testspec.installExportFilterPolicies != nil && !installPolicyAfterRoutes { + testspec.installExportFilterPolicies(t, dut2) } establishSessionPair(t, dut1, dut2, dut1spec, dut2spec) establishSessionPair(t, dut2, dut3, dut2spec, dut3spec) + establishSessionPair(t, dut4, dut5, dut4spec, dut5spec) + establishSessionPair(t, dut5, dut2, dut5spec, dut2spec) for _, routeTest := range testspec.spec.RouteTests { - // Install all test routes into DUT1. + // Install all regular test routes into DUT1. route := &oc.NetworkInstance_Protocol_Static{ Prefix: ygot.String(routeTest.GetInput().GetReachPrefix()), NextHop: map[string]*oc.NetworkInstance_Protocol_Static_NextHop{ @@ -107,34 +195,30 @@ func testPolicyAux(t *testing.T, testspec PolicyTestCase, installPolicyAfterRout installStaticRoute(t, dut1, route) } + for _, routeTest := range testspec.spec.LongerPathRouteTests { + // Install all longer-path test routes into DUT4. + route := &oc.NetworkInstance_Protocol_Static{ + Prefix: ygot.String(routeTest.GetInput().GetReachPrefix()), + NextHop: map[string]*oc.NetworkInstance_Protocol_Static_NextHop{ + "single": { + Index: ygot.String("single"), + NextHop: oc.UnionString("192.0.2.1"), + Recurse: ygot.Bool(true), + }, + }, + } + installStaticRoute(t, dut4, route) + } + staticp := ocpath.Root().NetworkInstance(fakedevice.DefaultNetworkInstance).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, fakedevice.StaticRoutingProtocol) v := GetAll(t, dut1, staticp.StaticAny().Config()) t.Logf("Installed static route on %v: %s", dut1, formatYgot(v)) - v4uni := bgp.BGPPath.Rib().AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast() - for _, routeTest := range testspec.spec.RouteTests { - prefix := routeTest.GetInput().GetReachPrefix() - // Check propagation to AdjRibOutPre for all prefixes. - Await(t, dut1, v4uni.Neighbor(dut2spec.RouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) - Await(t, dut1, v4uni.Neighbor(dut2spec.RouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) - Await(t, dut2, v4uni.Neighbor(dut1spec.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) - Await(t, dut2, v4uni.Neighbor(dut1spec.RouterID).AdjRibInPost().Route(prefix, 0).Prefix().State(), prefix) - Await(t, dut2, v4uni.LocRib().Route(prefix, oc.UnionString(dut1spec.RouterID), 0).Prefix().State(), prefix) - Await(t, dut2, v4uni.Neighbor(dut3spec.RouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) - if routeTest.GetExpectedResult() == policyval.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT || installPolicyAfterRoutes { - t.Logf("Waiting for %s to be propagated", prefix) - Await(t, dut2, v4uni.Neighbor(dut3spec.RouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) - Await(t, dut3, v4uni.Neighbor(dut2spec.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) - } else { - w := Watch(t, dut2, v4uni.Neighbor(dut3spec.RouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { - _, ok := val.Val() - return ok - }) - if _, ok := w.Await(t); ok { - t.Errorf("prefix %q (%s) was not rejected.", prefix, routeTest.GetDescription()) - } - } + testPropagation(t, routeTest, dut1, dut2, dut3, dut1spec.RouterID, dut2spec.RouterID, dut3spec.RouterID, !installPolicyAfterRoutes) + } + for _, routeTest := range testspec.spec.LongerPathRouteTests { + testPropagation(t, routeTest, dut5, dut2, dut3, dut5spec.RouterID, dut2spec.RouterID, dut3spec.RouterID, !installPolicyAfterRoutes) } if installPolicyAfterRoutes { @@ -154,7 +238,7 @@ func testPolicyAux(t *testing.T, testspec PolicyTestCase, installPolicyAfterRout } awaitNewSession <- nil }() - testspec.installPolicies(t, dut2) + testspec.installExportFilterPolicies(t, dut2) // Changing policy resets the BGP session, which causes routes // to disappear from the AdjRIBs, so we need to wait for // re-establishment first. @@ -163,36 +247,10 @@ func testPolicyAux(t *testing.T, testspec PolicyTestCase, installPolicyAfterRout } for _, routeTest := range testspec.spec.RouteTests { - prefix := routeTest.GetInput().GetReachPrefix() - - Await(t, dut2, v4uni.Neighbor(dut1spec.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) - Await(t, dut2, v4uni.Neighbor(dut1spec.RouterID).AdjRibInPost().Route(prefix, 0).Prefix().State(), prefix) - Await(t, dut2, v4uni.LocRib().Route(prefix, oc.UnionString(dut1spec.RouterID), 0).Prefix().State(), prefix) - Await(t, dut2, v4uni.Neighbor(dut3spec.RouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) - if routeTest.GetExpectedResult() == policyval.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT { - Await(t, dut2, v4uni.Neighbor(dut3spec.RouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) - Await(t, dut3, v4uni.Neighbor(dut2spec.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) - } else { - // Check rejected prefix has been withdrawn from AdjRib-out of DUT2 and AdjRib-in of DUT3. - w := Watch(t, dut2, v4uni.Neighbor(dut3spec.RouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { - _, ok := val.Val() - return !ok - }) - if _, ok := w.Await(t); !ok { - t.Errorf("prefix %q (%s) was not rejected within timeout.", prefix, routeTest.GetDescription()) - } else { - t.Logf("prefix %q (%s) was successfully rejected from DUT2's AdjRibOutPost within timeout.", prefix, routeTest.GetDescription()) - } - w = Watch(t, dut3, v4uni.Neighbor(dut2spec.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { - _, ok := val.Val() - return !ok - }) - if _, ok := w.Await(t); !ok { - t.Errorf("prefix %q (%s) was not withdrawn from DUT3 within timeout.", prefix, routeTest.GetDescription()) - } else { - t.Logf("prefix %q (%s) was successfully not seen at DUT3's AdjRibInPre within timeout.", prefix, routeTest.GetDescription()) - } - } + testPropagation(t, routeTest, dut1, dut2, dut3, dut1spec.RouterID, dut2spec.RouterID, dut3spec.RouterID, true) + } + for _, routeTest := range testspec.spec.LongerPathRouteTests { + testPropagation(t, routeTest, dut5, dut2, dut3, dut5spec.RouterID, dut2spec.RouterID, dut3spec.RouterID, true) } } } diff --git a/bgp/tests/local_tests/prefix_set_test.go b/bgp/tests/local_tests/prefix_set_test.go index fe6d0e2f..f642aa7e 100644 --- a/bgp/tests/local_tests/prefix_set_test.go +++ b/bgp/tests/local_tests/prefix_set_test.go @@ -44,7 +44,7 @@ func TestPrefixSet(t *testing.T) { ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT, }}, }, - installPolicies: func(t *testing.T, dut2 *ygnmi.Client) { + installExportFilterPolicies: func(t *testing.T, dut2 *ygnmi.Client) { if debug { fmt.Println("Installing test policies") } diff --git a/bgp/tests/local_tests/session_establish_test.go b/bgp/tests/local_tests/session_establish_test.go index 22792257..2500fc5e 100644 --- a/bgp/tests/local_tests/session_establish_test.go +++ b/bgp/tests/local_tests/session_establish_test.go @@ -81,6 +81,14 @@ var ( AS: 64503, RouterID: "127.0.0.4", } + dut5spec = DeviceSpec{ + ID: 5, + gnmiPort: 9539, + gribiPort: 9540, + bgpPort: 1115, + AS: 64504, + RouterID: "127.0.0.5", + } ) func ygnmiClient(t *testing.T, target string, port int) *ygnmi.Client { diff --git a/bgp/tests/proto/policyval/policy_validation.pb.go b/bgp/tests/proto/policyval/policy_validation.pb.go index 26ad11b9..d31d16bc 100644 --- a/bgp/tests/proto/policyval/policy_validation.pb.go +++ b/bgp/tests/proto/policyval/policy_validation.pb.go @@ -23,9 +23,10 @@ const ( type RouteTestResult int32 const ( - RouteTestResult_ROUTE_TEST_RESULT_UNSPECIFIED RouteTestResult = 0 - RouteTestResult_ROUTE_TEST_RESULT_ACCEPT RouteTestResult = 1 - RouteTestResult_ROUTE_TEST_RESULT_DISCARD RouteTestResult = 2 + RouteTestResult_ROUTE_TEST_RESULT_UNSPECIFIED RouteTestResult = 0 + RouteTestResult_ROUTE_TEST_RESULT_ACCEPT RouteTestResult = 1 + RouteTestResult_ROUTE_TEST_RESULT_DISCARD RouteTestResult = 2 + RouteTestResult_ROUTE_TEST_RESULT_NOT_PREFERRED RouteTestResult = 3 ) // Enum value maps for RouteTestResult. @@ -34,11 +35,13 @@ var ( 0: "ROUTE_TEST_RESULT_UNSPECIFIED", 1: "ROUTE_TEST_RESULT_ACCEPT", 2: "ROUTE_TEST_RESULT_DISCARD", + 3: "ROUTE_TEST_RESULT_NOT_PREFERRED", } RouteTestResult_value = map[string]int32{ - "ROUTE_TEST_RESULT_UNSPECIFIED": 0, - "ROUTE_TEST_RESULT_ACCEPT": 1, - "ROUTE_TEST_RESULT_DISCARD": 2, + "ROUTE_TEST_RESULT_UNSPECIFIED": 0, + "ROUTE_TEST_RESULT_ACCEPT": 1, + "ROUTE_TEST_RESULT_DISCARD": 2, + "ROUTE_TEST_RESULT_NOT_PREFERRED": 3, } ) @@ -74,8 +77,9 @@ type PolicyTestCase struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` - RouteTests []*RouteTestCase `protobuf:"bytes,4,rep,name=route_tests,json=routeTests,proto3" json:"route_tests,omitempty"` + Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + RouteTests []*RouteTestCase `protobuf:"bytes,4,rep,name=route_tests,json=routeTests,proto3" json:"route_tests,omitempty"` + LongerPathRouteTests []*RouteTestCase `protobuf:"bytes,5,rep,name=longer_path_route_tests,json=longerPathRouteTests,proto3" json:"longer_path_route_tests,omitempty"` } func (x *PolicyTestCase) Reset() { @@ -124,6 +128,13 @@ func (x *PolicyTestCase) GetRouteTests() []*RouteTestCase { return nil } +func (x *PolicyTestCase) GetLongerPathRouteTests() []*RouteTestCase { + if x != nil { + return x.LongerPathRouteTests + } + return nil +} + type TestRoute struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -241,36 +252,44 @@ var file_bgp_tests_proto_policyval_policy_validation_proto_rawDesc = []byte{ 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x76, 0x61, 0x6c, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x75, 0x0a, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0b, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xce, 0x01, 0x0a, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0b, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x20, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, + 0x73, 0x65, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x73, 0x12, 0x57, + 0x0a, 0x17, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, - 0x65, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x73, 0x22, 0x2e, 0x0a, - 0x09, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, - 0x61, 0x63, 0x68, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x72, 0x65, 0x61, 0x63, 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0xb2, 0x01, - 0x0a, 0x0d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, - 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x32, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x05, - 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x4b, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, - 0x64, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x2a, 0x71, 0x0a, 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, 0x54, - 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, - 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x55, 0x54, - 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x41, 0x43, - 0x43, 0x45, 0x50, 0x54, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, - 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x44, 0x49, 0x53, 0x43, - 0x41, 0x52, 0x44, 0x10, 0x02, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x65, 0x52, 0x14, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x50, 0x61, 0x74, 0x68, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x73, 0x22, 0x2e, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x52, + 0x6f, 0x75, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x63, 0x68, 0x5f, 0x70, 0x72, + 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x61, 0x63, + 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0xb2, 0x01, 0x0a, 0x0d, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x05, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, + 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, + 0x4b, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x0e, 0x65, 0x78, + 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2a, 0x96, 0x01, 0x0a, + 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, + 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, 0x54, 0x45, 0x53, + 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x10, + 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, + 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x44, 0x49, 0x53, 0x43, 0x41, 0x52, 0x44, 0x10, 0x02, + 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, + 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x46, 0x45, 0x52, + 0x52, 0x45, 0x44, 0x10, 0x03, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6c, 0x65, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x2f, 0x62, 0x67, 0x70, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x76, 0x61, 0x6c, @@ -299,13 +318,14 @@ var file_bgp_tests_proto_policyval_policy_validation_proto_goTypes = []interface } var file_bgp_tests_proto_policyval_policy_validation_proto_depIdxs = []int32{ 3, // 0: policy_validation.PolicyTestCase.route_tests:type_name -> policy_validation.RouteTestCase - 2, // 1: policy_validation.RouteTestCase.input:type_name -> policy_validation.TestRoute - 0, // 2: policy_validation.RouteTestCase.expected_result:type_name -> policy_validation.RouteTestResult - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 3, // 1: policy_validation.PolicyTestCase.longer_path_route_tests:type_name -> policy_validation.RouteTestCase + 2, // 2: policy_validation.RouteTestCase.input:type_name -> policy_validation.TestRoute + 0, // 3: policy_validation.RouteTestCase.expected_result:type_name -> policy_validation.RouteTestResult + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_bgp_tests_proto_policyval_policy_validation_proto_init() } diff --git a/bgp/tests/proto/policyval/policy_validation.proto b/bgp/tests/proto/policyval/policy_validation.proto index 399044f8..4899a046 100644 --- a/bgp/tests/proto/policyval/policy_validation.proto +++ b/bgp/tests/proto/policyval/policy_validation.proto @@ -22,6 +22,7 @@ option go_package = "github.com/openconfig/lemming/bgp/tests/proto/policyval"; message PolicyTestCase { string description = 1; repeated RouteTestCase route_tests = 4; + repeated RouteTestCase longer_path_route_tests = 5; } // This message represents a single prefix and its associated BGP attributes. @@ -36,6 +37,8 @@ enum RouteTestResult { ROUTE_TEST_RESULT_ACCEPT = 1; // Discard the input TestRoute. ROUTE_TEST_RESULT_DISCARD = 2; + // Input TestRoute not selected by best path selection. + ROUTE_TEST_RESULT_NOT_PREFERRED = 3; } // Specifies an input route and expected output. From 32945bd7248dcd9769ba312a2494780aad7aec08 Mon Sep 17 00:00:00 2001 From: wenovus Date: Tue, 22 Aug 2023 16:26:47 -0700 Subject: [PATCH 2/8] Add another field --- bgp/tests/local_tests/community_set_test.go | 6 +- bgp/tests/local_tests/policy_test.go | 12 ++- bgp/tests/local_tests/prefix_set_test.go | 6 +- .../proto/policyval/policy_validation.pb.go | 73 +++++++++++-------- .../proto/policyval/policy_validation.proto | 3 +- 5 files changed, 62 insertions(+), 38 deletions(-) diff --git a/bgp/tests/local_tests/community_set_test.go b/bgp/tests/local_tests/community_set_test.go index 31399f53..b3b00c3f 100644 --- a/bgp/tests/local_tests/community_set_test.go +++ b/bgp/tests/local_tests/community_set_test.go @@ -43,13 +43,15 @@ func TestCommunitySet(t *testing.T) { Input: &valpb.TestRoute{ ReachPrefix: "10.33.0.0/16", }, - ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_DISCARD, + ExpectedResultBeforePolicy: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT, + ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_DISCARD, }, { Description: "Accepted route", Input: &valpb.TestRoute{ ReachPrefix: "10.3.0.0/16", }, - ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT, + ExpectedResultBeforePolicy: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT, + ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT, }}, }, installImportSetPolicies: func(t *testing.T, dut2 *ygnmi.Client) { diff --git a/bgp/tests/local_tests/policy_test.go b/bgp/tests/local_tests/policy_test.go index 2124da4f..365cb76e 100644 --- a/bgp/tests/local_tests/policy_test.go +++ b/bgp/tests/local_tests/policy_test.go @@ -68,6 +68,10 @@ func testPolicy(t *testing.T, testspec PolicyTestCase) { func testPropagation(t *testing.T, routeTest *valpb.RouteTestCase, prevDUT, currDUT, nextDUT *ygnmi.Client, prevRouterID, currRouterID, nextRouterID string, filterPoliciesInstalled bool) { t.Helper() v4uni := bgp.BGPPath.Rib().AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast() + expectedResult := routeTest.GetExpectedResultBeforePolicy() + if filterPoliciesInstalled { + expectedResult = routeTest.GetExpectedResult() + } prefix := routeTest.GetInput().GetReachPrefix() // Check propagation to AdjRibOutPre for all prefixes. @@ -75,14 +79,14 @@ func testPropagation(t *testing.T, routeTest *valpb.RouteTestCase, prevDUT, curr Await(t, prevDUT, v4uni.Neighbor(currRouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) Await(t, currDUT, v4uni.Neighbor(prevRouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) Await(t, currDUT, v4uni.Neighbor(prevRouterID).AdjRibInPost().Route(prefix, 0).Prefix().State(), prefix) - switch { - case routeTest.GetExpectedResult() == policyval.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT, !filterPoliciesInstalled: + switch expectedResult { + case policyval.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT: Await(t, currDUT, v4uni.LocRib().Route(prefix, oc.UnionString(prevRouterID), 0).Prefix().State(), prefix) Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) t.Logf("Waiting for %s to be propagated", prefix) Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) Await(t, nextDUT, v4uni.Neighbor(currRouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) - case routeTest.GetExpectedResult() == policyval.RouteTestResult_ROUTE_TEST_RESULT_DISCARD: + case policyval.RouteTestResult_ROUTE_TEST_RESULT_DISCARD: Await(t, currDUT, v4uni.LocRib().Route(prefix, oc.UnionString(prevRouterID), 0).Prefix().State(), prefix) Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) w := Watch(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { @@ -103,7 +107,7 @@ func testPropagation(t *testing.T, routeTest *valpb.RouteTestCase, prevDUT, curr } else { t.Logf("prefix %q (%s) was successfully rejected from adj-rib-in-pre of %v within timeout.", prefix, routeTest.GetDescription(), nextDUT) } - case routeTest.GetExpectedResult() == policyval.RouteTestResult_ROUTE_TEST_RESULT_NOT_PREFERRED: + case policyval.RouteTestResult_ROUTE_TEST_RESULT_NOT_PREFERRED: w := Watch(t, currDUT, v4uni.LocRib().Route(prefix, oc.UnionString(prevRouterID), 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { _, ok := val.Val() return ok diff --git a/bgp/tests/local_tests/prefix_set_test.go b/bgp/tests/local_tests/prefix_set_test.go index f642aa7e..6fb928cd 100644 --- a/bgp/tests/local_tests/prefix_set_test.go +++ b/bgp/tests/local_tests/prefix_set_test.go @@ -35,13 +35,15 @@ func TestPrefixSet(t *testing.T) { Input: &valpb.TestRoute{ ReachPrefix: "10.33.0.0/16", }, - ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_DISCARD, + ExpectedResultBeforePolicy: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT, + ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_DISCARD, }, { Description: "Accepted route", Input: &valpb.TestRoute{ ReachPrefix: "10.3.0.0/16", }, - ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT, + ExpectedResultBeforePolicy: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT, + ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT, }}, }, installExportFilterPolicies: func(t *testing.T, dut2 *ygnmi.Client) { diff --git a/bgp/tests/proto/policyval/policy_validation.pb.go b/bgp/tests/proto/policyval/policy_validation.pb.go index d31d16bc..3af5d556 100644 --- a/bgp/tests/proto/policyval/policy_validation.pb.go +++ b/bgp/tests/proto/policyval/policy_validation.pb.go @@ -187,9 +187,10 @@ type RouteTestCase struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` - Input *TestRoute `protobuf:"bytes,2,opt,name=input,proto3" json:"input,omitempty"` - ExpectedResult RouteTestResult `protobuf:"varint,3,opt,name=expected_result,json=expectedResult,proto3,enum=policy_validation.RouteTestResult" json:"expected_result,omitempty"` + Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + Input *TestRoute `protobuf:"bytes,2,opt,name=input,proto3" json:"input,omitempty"` + ExpectedResultBeforePolicy RouteTestResult `protobuf:"varint,3,opt,name=expected_result_before_policy,json=expectedResultBeforePolicy,proto3,enum=policy_validation.RouteTestResult" json:"expected_result_before_policy,omitempty"` + ExpectedResult RouteTestResult `protobuf:"varint,4,opt,name=expected_result,json=expectedResult,proto3,enum=policy_validation.RouteTestResult" json:"expected_result,omitempty"` } func (x *RouteTestCase) Reset() { @@ -238,6 +239,13 @@ func (x *RouteTestCase) GetInput() *TestRoute { return nil } +func (x *RouteTestCase) GetExpectedResultBeforePolicy() RouteTestResult { + if x != nil { + return x.ExpectedResultBeforePolicy + } + return RouteTestResult_ROUTE_TEST_RESULT_UNSPECIFIED +} + func (x *RouteTestCase) GetExpectedResult() RouteTestResult { if x != nil { return x.ExpectedResult @@ -268,32 +276,38 @@ var file_bgp_tests_proto_policyval_policy_validation_proto_rawDesc = []byte{ 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x73, 0x22, 0x2e, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x63, 0x68, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x61, 0x63, - 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0xb2, 0x01, 0x0a, 0x0d, 0x52, 0x6f, 0x75, 0x74, + 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0x99, 0x02, 0x0a, 0x0d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, - 0x4b, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, - 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x0e, 0x65, 0x78, - 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2a, 0x96, 0x01, 0x0a, - 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, - 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, 0x54, 0x45, 0x53, - 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x10, - 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, - 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x44, 0x49, 0x53, 0x43, 0x41, 0x52, 0x44, 0x10, 0x02, - 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, - 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x50, 0x52, 0x45, 0x46, 0x45, 0x52, - 0x52, 0x45, 0x44, 0x10, 0x03, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6c, - 0x65, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x2f, 0x62, 0x67, 0x70, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x73, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x76, 0x61, 0x6c, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x0a, 0x1d, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x1a, 0x65, 0x78, 0x70, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x4b, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x22, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x2a, 0x96, 0x01, 0x0a, 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, + 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x55, 0x54, 0x45, + 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, + 0x55, 0x54, 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, + 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x4f, 0x55, 0x54, + 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x44, 0x49, + 0x53, 0x43, 0x41, 0x52, 0x44, 0x10, 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x4f, 0x55, 0x54, 0x45, + 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x4e, 0x4f, 0x54, + 0x5f, 0x50, 0x52, 0x45, 0x46, 0x45, 0x52, 0x52, 0x45, 0x44, 0x10, 0x03, 0x42, 0x39, 0x5a, 0x37, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6c, 0x65, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x2f, 0x62, 0x67, + 0x70, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x76, 0x61, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -320,12 +334,13 @@ var file_bgp_tests_proto_policyval_policy_validation_proto_depIdxs = []int32{ 3, // 0: policy_validation.PolicyTestCase.route_tests:type_name -> policy_validation.RouteTestCase 3, // 1: policy_validation.PolicyTestCase.longer_path_route_tests:type_name -> policy_validation.RouteTestCase 2, // 2: policy_validation.RouteTestCase.input:type_name -> policy_validation.TestRoute - 0, // 3: policy_validation.RouteTestCase.expected_result:type_name -> policy_validation.RouteTestResult - 4, // [4:4] is the sub-list for method output_type - 4, // [4:4] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name + 0, // 3: policy_validation.RouteTestCase.expected_result_before_policy:type_name -> policy_validation.RouteTestResult + 0, // 4: policy_validation.RouteTestCase.expected_result:type_name -> policy_validation.RouteTestResult + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name } func init() { file_bgp_tests_proto_policyval_policy_validation_proto_init() } diff --git a/bgp/tests/proto/policyval/policy_validation.proto b/bgp/tests/proto/policyval/policy_validation.proto index 4899a046..44770ef4 100644 --- a/bgp/tests/proto/policyval/policy_validation.proto +++ b/bgp/tests/proto/policyval/policy_validation.proto @@ -50,5 +50,6 @@ enum RouteTestResult { message RouteTestCase { string description = 1; TestRoute input = 2; - RouteTestResult expected_result = 3; + RouteTestResult expected_result_before_policy = 3; + RouteTestResult expected_result = 4; } From 1bcbde4f34776d9b278585a0b5050cf1aa434178 Mon Sep 17 00:00:00 2001 From: wenovus Date: Tue, 22 Aug 2023 19:05:21 -0700 Subject: [PATCH 3/8] Add alternate path --- bgp/tests/local_tests/policy_test.go | 41 ++++-- .../local_tests/session_establish_test.go | 8 +- .../proto/policyval/policy_validation.pb.go | 123 ++++++++++-------- .../proto/policyval/policy_validation.proto | 3 +- 4 files changed, 105 insertions(+), 70 deletions(-) diff --git a/bgp/tests/local_tests/policy_test.go b/bgp/tests/local_tests/policy_test.go index 365cb76e..28739fe2 100644 --- a/bgp/tests/local_tests/policy_test.go +++ b/bgp/tests/local_tests/policy_test.go @@ -95,6 +95,7 @@ func testPropagation(t *testing.T, routeTest *valpb.RouteTestCase, prevDUT, curr }) if _, ok := w.Await(t); ok { t.Errorf("prefix %q (%s) was not rejected from adj-rib-out-post of %v within timeout.", prefix, routeTest.GetDescription(), currDUT) + break } else { t.Logf("prefix %q (%s) was successfully rejected from adj-rib-out-post of %v within timeout.", prefix, routeTest.GetDescription(), currDUT) } @@ -114,18 +115,15 @@ func testPropagation(t *testing.T, routeTest *valpb.RouteTestCase, prevDUT, curr }) if _, ok := w.Await(t); ok { t.Errorf("prefix %q with origin %q (%s) was selected into loc-rib of %v.", prefix, prevRouterID, routeTest.GetDescription(), currDUT) + break } else { t.Logf("prefix %q with origin %q (%s) was successfully not selected into loc-rib of %v within timeout.", prefix, prevRouterID, routeTest.GetDescription(), currDUT) } - w = Watch(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { - _, ok := val.Val() - return ok - }) - if _, ok := w.Await(t); ok { - t.Errorf("prefix %q (%s) was not rejected from adj-rib-out-pre of %v within timeout.", prefix, routeTest.GetDescription(), currDUT) - } else { - t.Logf("prefix %q (%s) was successfully rejected from adj-rib-out-pre of %v within timeout.", prefix, routeTest.GetDescription(), currDUT) - } + Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) + Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) + Await(t, nextDUT, v4uni.Neighbor(currRouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) + default: + t.Fatalf("Invalid or unhandled policy result: %v", expectedResult) } } @@ -146,11 +144,17 @@ func testPolicyAux(t *testing.T, testspec PolicyTestCase, installPolicyAfterRout name: "eth0", ifindex: 0, enabled: true, - prefix: "192.0.2.2/30", + prefix: "192.0.2.1/30", niName: "DEFAULT", }}) defer stop4() - dut5, stop5 := newLemming(t, dut5spec, nil) + dut5, stop5 := newLemming(t, dut5spec, []*AddIntfAction{{ + name: "eth0", + ifindex: 0, + enabled: true, + prefix: "193.0.2.1/30", + niName: "DEFAULT", + }}) defer stop5() installDefaultPolicies := func() { @@ -214,6 +218,21 @@ func testPolicyAux(t *testing.T, testspec PolicyTestCase, installPolicyAfterRout installStaticRoute(t, dut4, route) } + for _, routeTest := range testspec.spec.AlternatePathRouteTests { + // Install all alternate-path test routes into DUT5. + route := &oc.NetworkInstance_Protocol_Static{ + Prefix: ygot.String(routeTest.GetInput().GetReachPrefix()), + NextHop: map[string]*oc.NetworkInstance_Protocol_Static_NextHop{ + "single": { + Index: ygot.String("single"), + NextHop: oc.UnionString("193.0.2.1"), + Recurse: ygot.Bool(true), + }, + }, + } + installStaticRoute(t, dut5, route) + } + staticp := ocpath.Root().NetworkInstance(fakedevice.DefaultNetworkInstance).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, fakedevice.StaticRoutingProtocol) v := GetAll(t, dut1, staticp.StaticAny().Config()) t.Logf("Installed static route on %v: %s", dut1, formatYgot(v)) diff --git a/bgp/tests/local_tests/session_establish_test.go b/bgp/tests/local_tests/session_establish_test.go index 2500fc5e..0516935a 100644 --- a/bgp/tests/local_tests/session_establish_test.go +++ b/bgp/tests/local_tests/session_establish_test.go @@ -62,7 +62,7 @@ var ( gnmiPort: 8339, gribiPort: 8340, bgpPort: 1112, - AS: 64501, + AS: 64500, RouterID: "127.0.0.2", } dut3spec = DeviceSpec{ @@ -70,7 +70,7 @@ var ( gnmiPort: 9339, gribiPort: 9340, bgpPort: 1113, - AS: 64502, + AS: 64501, RouterID: "127.0.0.3", } dut4spec = DeviceSpec{ @@ -78,7 +78,7 @@ var ( gnmiPort: 9439, gribiPort: 9440, bgpPort: 1114, - AS: 64503, + AS: 64502, RouterID: "127.0.0.4", } dut5spec = DeviceSpec{ @@ -86,7 +86,7 @@ var ( gnmiPort: 9539, gribiPort: 9540, bgpPort: 1115, - AS: 64504, + AS: 64500, RouterID: "127.0.0.5", } ) diff --git a/bgp/tests/proto/policyval/policy_validation.pb.go b/bgp/tests/proto/policyval/policy_validation.pb.go index 3af5d556..5cfe277a 100644 --- a/bgp/tests/proto/policyval/policy_validation.pb.go +++ b/bgp/tests/proto/policyval/policy_validation.pb.go @@ -77,9 +77,10 @@ type PolicyTestCase struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` - RouteTests []*RouteTestCase `protobuf:"bytes,4,rep,name=route_tests,json=routeTests,proto3" json:"route_tests,omitempty"` - LongerPathRouteTests []*RouteTestCase `protobuf:"bytes,5,rep,name=longer_path_route_tests,json=longerPathRouteTests,proto3" json:"longer_path_route_tests,omitempty"` + Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + RouteTests []*RouteTestCase `protobuf:"bytes,4,rep,name=route_tests,json=routeTests,proto3" json:"route_tests,omitempty"` + AlternatePathRouteTests []*RouteTestCase `protobuf:"bytes,5,rep,name=alternate_path_route_tests,json=alternatePathRouteTests,proto3" json:"alternate_path_route_tests,omitempty"` + LongerPathRouteTests []*RouteTestCase `protobuf:"bytes,6,rep,name=longer_path_route_tests,json=longerPathRouteTests,proto3" json:"longer_path_route_tests,omitempty"` } func (x *PolicyTestCase) Reset() { @@ -128,6 +129,13 @@ func (x *PolicyTestCase) GetRouteTests() []*RouteTestCase { return nil } +func (x *PolicyTestCase) GetAlternatePathRouteTests() []*RouteTestCase { + if x != nil { + return x.AlternatePathRouteTests + } + return nil +} + func (x *PolicyTestCase) GetLongerPathRouteTests() []*RouteTestCase { if x != nil { return x.LongerPathRouteTests @@ -260,54 +268,60 @@ var file_bgp_tests_proto_policyval_policy_validation_proto_rawDesc = []byte{ 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x76, 0x61, 0x6c, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x11, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xce, 0x01, 0x0a, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xad, 0x02, 0x0a, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, - 0x73, 0x65, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x73, 0x12, 0x57, - 0x0a, 0x17, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x72, 0x6f, - 0x75, 0x74, 0x65, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x20, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, - 0x65, 0x52, 0x14, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x50, 0x61, 0x74, 0x68, 0x52, 0x6f, 0x75, - 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x73, 0x22, 0x2e, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x63, 0x68, 0x5f, 0x70, 0x72, - 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x61, 0x63, - 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0x99, 0x02, 0x0a, 0x0d, 0x52, 0x6f, 0x75, 0x74, - 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x05, 0x69, - 0x6e, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, - 0x65, 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, - 0x65, 0x0a, 0x1d, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, - 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x1a, 0x65, 0x78, 0x70, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x4b, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x22, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x2a, 0x96, 0x01, 0x0a, 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x55, 0x54, 0x45, - 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, - 0x55, 0x54, 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, - 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x4f, 0x55, 0x54, - 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x44, 0x49, - 0x53, 0x43, 0x41, 0x52, 0x44, 0x10, 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x4f, 0x55, 0x54, 0x45, - 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x4e, 0x4f, 0x54, - 0x5f, 0x50, 0x52, 0x45, 0x46, 0x45, 0x52, 0x52, 0x45, 0x44, 0x10, 0x03, 0x42, 0x39, 0x5a, 0x37, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6c, 0x65, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x2f, 0x62, 0x67, - 0x70, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x76, 0x61, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x65, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x73, 0x12, 0x5d, + 0x0a, 0x1a, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, + 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, + 0x43, 0x61, 0x73, 0x65, 0x52, 0x17, 0x61, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x50, + 0x61, 0x74, 0x68, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x73, 0x12, 0x57, 0x0a, + 0x17, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, + 0x52, 0x14, 0x6c, 0x6f, 0x6e, 0x67, 0x65, 0x72, 0x50, 0x61, 0x74, 0x68, 0x52, 0x6f, 0x75, 0x74, + 0x65, 0x54, 0x65, 0x73, 0x74, 0x73, 0x22, 0x2e, 0x0a, 0x09, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, + 0x75, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x61, 0x63, 0x68, 0x5f, 0x70, 0x72, 0x65, + 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x61, 0x63, 0x68, + 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0x99, 0x02, 0x0a, 0x0d, 0x52, 0x6f, 0x75, 0x74, 0x65, + 0x54, 0x65, 0x73, 0x74, 0x43, 0x61, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x05, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x65, + 0x73, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x65, + 0x0a, 0x1d, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, + 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x1a, 0x65, 0x78, 0x70, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x50, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x4b, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x2a, 0x96, 0x01, 0x0a, 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x65, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, + 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x55, + 0x54, 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x41, + 0x43, 0x43, 0x45, 0x50, 0x54, 0x10, 0x01, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x4f, 0x55, 0x54, 0x45, + 0x5f, 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x44, 0x49, 0x53, + 0x43, 0x41, 0x52, 0x44, 0x10, 0x02, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x5f, + 0x54, 0x45, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x53, 0x55, 0x4c, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, + 0x50, 0x52, 0x45, 0x46, 0x45, 0x52, 0x52, 0x45, 0x44, 0x10, 0x03, 0x42, 0x39, 0x5a, 0x37, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x6c, 0x65, 0x6d, 0x6d, 0x69, 0x6e, 0x67, 0x2f, 0x62, 0x67, 0x70, + 0x2f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x76, 0x61, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -332,15 +346,16 @@ var file_bgp_tests_proto_policyval_policy_validation_proto_goTypes = []interface } var file_bgp_tests_proto_policyval_policy_validation_proto_depIdxs = []int32{ 3, // 0: policy_validation.PolicyTestCase.route_tests:type_name -> policy_validation.RouteTestCase - 3, // 1: policy_validation.PolicyTestCase.longer_path_route_tests:type_name -> policy_validation.RouteTestCase - 2, // 2: policy_validation.RouteTestCase.input:type_name -> policy_validation.TestRoute - 0, // 3: policy_validation.RouteTestCase.expected_result_before_policy:type_name -> policy_validation.RouteTestResult - 0, // 4: policy_validation.RouteTestCase.expected_result:type_name -> policy_validation.RouteTestResult - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 3, // 1: policy_validation.PolicyTestCase.alternate_path_route_tests:type_name -> policy_validation.RouteTestCase + 3, // 2: policy_validation.PolicyTestCase.longer_path_route_tests:type_name -> policy_validation.RouteTestCase + 2, // 3: policy_validation.RouteTestCase.input:type_name -> policy_validation.TestRoute + 0, // 4: policy_validation.RouteTestCase.expected_result_before_policy:type_name -> policy_validation.RouteTestResult + 0, // 5: policy_validation.RouteTestCase.expected_result:type_name -> policy_validation.RouteTestResult + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_bgp_tests_proto_policyval_policy_validation_proto_init() } diff --git a/bgp/tests/proto/policyval/policy_validation.proto b/bgp/tests/proto/policyval/policy_validation.proto index 44770ef4..b5ea4d90 100644 --- a/bgp/tests/proto/policyval/policy_validation.proto +++ b/bgp/tests/proto/policyval/policy_validation.proto @@ -22,7 +22,8 @@ option go_package = "github.com/openconfig/lemming/bgp/tests/proto/policyval"; message PolicyTestCase { string description = 1; repeated RouteTestCase route_tests = 4; - repeated RouteTestCase longer_path_route_tests = 5; + repeated RouteTestCase alternate_path_route_tests = 5; + repeated RouteTestCase longer_path_route_tests = 6; } // This message represents a single prefix and its associated BGP attributes. From 1ca83278ca1254665adbb9380973006ae18fb001 Mon Sep 17 00:00:00 2001 From: wenovus Date: Wed, 23 Aug 2023 08:09:05 -0700 Subject: [PATCH 4/8] Fix lint --- bgp/tests/local_tests/policy_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bgp/tests/local_tests/policy_test.go b/bgp/tests/local_tests/policy_test.go index 28739fe2..ba8d8e7e 100644 --- a/bgp/tests/local_tests/policy_test.go +++ b/bgp/tests/local_tests/policy_test.go @@ -96,18 +96,18 @@ func testPropagation(t *testing.T, routeTest *valpb.RouteTestCase, prevDUT, curr if _, ok := w.Await(t); ok { t.Errorf("prefix %q (%s) was not rejected from adj-rib-out-post of %v within timeout.", prefix, routeTest.GetDescription(), currDUT) break - } else { - t.Logf("prefix %q (%s) was successfully rejected from adj-rib-out-post of %v within timeout.", prefix, routeTest.GetDescription(), currDUT) } + t.Logf("prefix %q (%s) was successfully rejected from adj-rib-out-post of %v within timeout.", prefix, routeTest.GetDescription(), currDUT) + w = Watch(t, nextDUT, v4uni.Neighbor(currRouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { _, ok := val.Val() return ok }) if _, ok := w.Await(t); ok { t.Errorf("prefix %q (%s) was not rejected from adj-rib-in-pre of %v within timeout.", prefix, routeTest.GetDescription(), nextDUT) - } else { - t.Logf("prefix %q (%s) was successfully rejected from adj-rib-in-pre of %v within timeout.", prefix, routeTest.GetDescription(), nextDUT) + break } + t.Logf("prefix %q (%s) was successfully rejected from adj-rib-in-pre of %v within timeout.", prefix, routeTest.GetDescription(), nextDUT) case policyval.RouteTestResult_ROUTE_TEST_RESULT_NOT_PREFERRED: w := Watch(t, currDUT, v4uni.LocRib().Route(prefix, oc.UnionString(prevRouterID), 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { _, ok := val.Val() @@ -116,9 +116,9 @@ func testPropagation(t *testing.T, routeTest *valpb.RouteTestCase, prevDUT, curr if _, ok := w.Await(t); ok { t.Errorf("prefix %q with origin %q (%s) was selected into loc-rib of %v.", prefix, prevRouterID, routeTest.GetDescription(), currDUT) break - } else { - t.Logf("prefix %q with origin %q (%s) was successfully not selected into loc-rib of %v within timeout.", prefix, prevRouterID, routeTest.GetDescription(), currDUT) } + t.Logf("prefix %q with origin %q (%s) was successfully not selected into loc-rib of %v within timeout.", prefix, prevRouterID, routeTest.GetDescription(), currDUT) + Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) Await(t, nextDUT, v4uni.Neighbor(currRouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) From 20fb49ad1c110d99fea54cc9f052e42cfb83123b Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 24 Aug 2023 10:03:18 -0700 Subject: [PATCH 5/8] refactor BGP integration tests --- bgp/gobgp.go | 14 +- bgp/tests/local_tests/community_set_test.go | 23 ++- bgp/tests/local_tests/policy_test.go | 162 ++++++++---------- bgp/tests/local_tests/prefix_set_test.go | 5 +- .../local_tests/route_propagation_test.go | 41 ++--- .../local_tests/session_establish_test.go | 146 +++++++--------- bgp/tests/local_tests/ygnmi_test.go | 28 +-- repositories.bzl | 32 ++-- 8 files changed, 211 insertions(+), 240 deletions(-) diff --git a/bgp/gobgp.go b/bgp/gobgp.go index 9879547f..601cf846 100644 --- a/bgp/gobgp.go +++ b/bgp/gobgp.go @@ -135,6 +135,7 @@ func (t *bgpDeclTask) startGoBGPFuncDecl(_ context.Context, yclient *ygnmi.Clien BGPPath.NeighborAny().NeighborAddress().Config().PathStruct(), BGPPath.NeighborAny().NeighborPort().Config().PathStruct(), // BGP Policy statements + RoutingPolicyPath.PolicyDefinitionAny().Name().Config().PathStruct(), RoutingPolicyPath.PolicyDefinitionAny().StatementMap().Config().PathStruct(), BGPPath.NeighborAny().ApplyPolicy().DefaultImportPolicy().Config().PathStruct(), BGPPath.NeighborAny().ApplyPolicy().DefaultExportPolicy().Config().PathStruct(), @@ -236,7 +237,9 @@ func (t *bgpDeclTask) startGoBGPFuncDecl(_ context.Context, yclient *ygnmi.Clien }, func(d *api.Destination) { log.V(1).Infof("%s: GoBGP global table path: %v", t.targetName, d) }); err != nil { - log.Errorf("GoBGP ListPath call failed (global table): %v", err) + if err.Error() != "bgp server hasn't started yet" { + log.Errorf("GoBGP ListPath call failed (global table): %v", err) + } } else { log.V(1).Info("GoBGP ListPath call completed (global table)") } @@ -255,7 +258,7 @@ func (t *bgpDeclTask) startGoBGPFuncDecl(_ context.Context, yclient *ygnmi.Clien // TODO: For locally-originated routes figure out how to get the originating protocol. origin = oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_UNSET } else { - origin = oc.UnionString(path.SourceId) + origin = oc.UnionString(path.NeighborIp) } // TODO: this ID should match the ID in adj-rib-in-post. locRib.GetOrCreateRoute(route.Prefix, origin, uint32(j)) @@ -272,6 +275,7 @@ func (t *bgpDeclTask) startGoBGPFuncDecl(_ context.Context, yclient *ygnmi.Clien t.queryTable(neigh, "adj-rib-in", api.TableType_ADJ_IN, func(routes []*api.Destination) { for _, route := range routes { for j, path := range route.Paths { + // TODO: this ID should be retrieved from the update message. neighContainer.GetOrCreateAdjRibInPre().GetOrCreateRoute(route.Prefix, uint32(j)) if !path.Filtered { neighContainer.GetOrCreateAdjRibInPost().GetOrCreateRoute(route.Prefix, uint32(j)) @@ -325,7 +329,9 @@ func (t *bgpDeclTask) queryTable(neighbor, tableName string, tableType api.Table routes = append(routes, d) log.V(0).Infof("%s: GoBGP %s table path (neighbor if applicable: %q): %v", t.targetName, tableName, neighbor, d) }); err != nil { - log.Errorf("GoBGP ListPath call failed (%s table): %v", tableType, err) + if err.Error() != "bgp server hasn't started yet" { + log.Errorf("GoBGP ListPath call failed (%s table): %v", tableType, err) + } } else { log.V(1).Info("GoBGP ListPath call completed (%s table)", tableName) f(routes) @@ -389,6 +395,8 @@ func intendedToGoBGP(bgpoc *oc.NetworkInstance_Protocol_Bgp, policyoc *oc.Routin bgpConfig.Global.Config.As = global.GetAs() bgpConfig.Global.Config.RouterId = global.GetRouterId() bgpConfig.Global.Config.Port = int32(listenPort) + // Have GoBGP listen only on this address instead of all addresses. + bgpConfig.Global.Config.LocalAddressList = []string{global.GetRouterId()} localAddress := "" if localAddr, err := netip.ParseAddr(global.GetRouterId()); err == nil && localAddr.IsLoopback() { diff --git a/bgp/tests/local_tests/community_set_test.go b/bgp/tests/local_tests/community_set_test.go index b3b00c3f..d8270b90 100644 --- a/bgp/tests/local_tests/community_set_test.go +++ b/bgp/tests/local_tests/community_set_test.go @@ -21,7 +21,6 @@ import ( "github.com/openconfig/lemming/bgp" "github.com/openconfig/lemming/gnmi/oc" "github.com/openconfig/lemming/gnmi/oc/ocpath" - "github.com/openconfig/ygnmi/ygnmi" valpb "github.com/openconfig/lemming/bgp/tests/proto/policyval" ) @@ -54,7 +53,7 @@ func TestCommunitySet(t *testing.T) { ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT, }}, }, - installImportSetPolicies: func(t *testing.T, dut2 *ygnmi.Client) { + installPolicies: func(t *testing.T, dut1, dut2, dut3, dut4, dut5 *Device) { if debug { fmt.Println("Installing test policies") } @@ -66,6 +65,7 @@ func TestCommunitySet(t *testing.T) { // Create prefix set prefixSetName := "accept-" + prefix1 prefix1Path := ocpath.Root().RoutingPolicy().DefinedSets().PrefixSet(prefixSetName).Prefix(prefix1, "exact").IpPrefix() + Replace(t, dut1, prefix1Path.Config(), prefix1) Replace(t, dut2, prefix1Path.Config(), prefix1) policy := &oc.RoutingPolicy_PolicyDefinition_Statement_OrderedMap{} @@ -86,16 +86,13 @@ func TestCommunitySet(t *testing.T) { // Accept the route so that it may be advertised. stmt.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE) // Install policy - Replace(t, dut2, ocpath.Root().RoutingPolicy().PolicyDefinition(policyName).Config(), &oc.RoutingPolicy_PolicyDefinition{Statement: policy}) - Replace(t, dut2, bgp.BGPPath.Neighbor(dut1spec.RouterID).ApplyPolicy().ImportPolicy().Config(), []string{policyName}) - }, - installExportFilterPolicies: func(t *testing.T, dut2 *ygnmi.Client) { - if debug { - fmt.Println("Installing test policies") - } + Replace(t, dut1, ocpath.Root().RoutingPolicy().PolicyDefinition(policyName).Config(), &oc.RoutingPolicy_PolicyDefinition{Statement: policy}) + Replace(t, dut1, bgp.BGPPath.Neighbor(dut2.RouterID).ApplyPolicy().ExportPolicy().Config(), []string{policyName}) + + ////////////////////// // Policy to reject routes with the given community set - policyName := "def2" + policyName = "def2" // Create community set rejectCommSetName := "reject-community-set" @@ -105,8 +102,8 @@ func TestCommunitySet(t *testing.T) { }) Replace(t, dut2, ocpath.Root().RoutingPolicy().DefinedSets().BgpDefinedSets().CommunitySet(rejectCommSetName).MatchSetOptions().Config(), oc.RoutingPolicy_MatchSetOptionsType_ANY) - policy := &oc.RoutingPolicy_PolicyDefinition_Statement_OrderedMap{} - stmt, err := policy.AppendNew("stmt2") + policy = &oc.RoutingPolicy_PolicyDefinition_Statement_OrderedMap{} + stmt, err = policy.AppendNew("stmt2") if err != nil { t.Fatalf("Cannot append new BGP policy statement: %v", err) } @@ -115,7 +112,7 @@ func TestCommunitySet(t *testing.T) { stmt.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_REJECT_ROUTE) // Install policy Replace(t, dut2, ocpath.Root().RoutingPolicy().PolicyDefinition(policyName).Config(), &oc.RoutingPolicy_PolicyDefinition{Statement: policy}) - Replace(t, dut2, bgp.BGPPath.Neighbor(dut3spec.RouterID).ApplyPolicy().ExportPolicy().Config(), []string{policyName}) + Replace(t, dut2, bgp.BGPPath.Neighbor(dut1.RouterID).ApplyPolicy().ImportPolicy().Config(), []string{policyName}) }, }) } diff --git a/bgp/tests/local_tests/policy_test.go b/bgp/tests/local_tests/policy_test.go index ba8d8e7e..2e6180f3 100644 --- a/bgp/tests/local_tests/policy_test.go +++ b/bgp/tests/local_tests/policy_test.go @@ -31,25 +31,25 @@ import ( const ( debug = true - rejectTimeout = 10 * time.Second + rejectTimeout = 20 * time.Second ) // PolicyTestCase contains the specifications for a single policy test. // // Topology: // -// DUT1 -> DUT2 -> DUT3 -// ^ -// | -// DUT4 -> DUT5 +// DUT1 (AS 64500) -> DUT2 (AS 64500) -> DUT3 (AS 64501) +// ^ +// | +// DUT4 (AS 64502) -> DUT5 (AS 64500) // -// Currently, all policies are installed on DUT2, and by convention, -// the import policies set attributes, and export policy to DUT3 filters -// prefixes. +// Currently by convention, all policies are installed on DUT1 (export), DUT5 +// (export), and DUT2 (import). This is because GoBGP only withdraws routes on +// import policy change after a soft reset: +// https://github.com/osrg/gobgp/blob/master/docs/sources/policy.md#policy-and-soft-reset type PolicyTestCase struct { - spec *valpb.PolicyTestCase - installImportSetPolicies func(t *testing.T, dut2 *ygnmi.Client) - installExportFilterPolicies func(t *testing.T, dut2 *ygnmi.Client) + spec *valpb.PolicyTestCase + installPolicies func(t *testing.T, dut1, dut2, dut3, dut4, dut5 *Device) } // testPolicy is the helper policy integration tests can call to instantiate @@ -65,7 +65,7 @@ func testPolicy(t *testing.T, testspec PolicyTestCase) { }) } -func testPropagation(t *testing.T, routeTest *valpb.RouteTestCase, prevDUT, currDUT, nextDUT *ygnmi.Client, prevRouterID, currRouterID, nextRouterID string, filterPoliciesInstalled bool) { +func testPropagation(t *testing.T, routeTest *valpb.RouteTestCase, prevDUT, currDUT, nextDUT *Device, filterPoliciesInstalled bool) { t.Helper() v4uni := bgp.BGPPath.Rib().AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast() expectedResult := routeTest.GetExpectedResultBeforePolicy() @@ -75,60 +75,60 @@ func testPropagation(t *testing.T, routeTest *valpb.RouteTestCase, prevDUT, curr prefix := routeTest.GetInput().GetReachPrefix() // Check propagation to AdjRibOutPre for all prefixes. - Await(t, prevDUT, v4uni.Neighbor(currRouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) - Await(t, prevDUT, v4uni.Neighbor(currRouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) - Await(t, currDUT, v4uni.Neighbor(prevRouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) - Await(t, currDUT, v4uni.Neighbor(prevRouterID).AdjRibInPost().Route(prefix, 0).Prefix().State(), prefix) + Await(t, prevDUT, v4uni.Neighbor(currDUT.RouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) + Await(t, prevDUT, v4uni.Neighbor(currDUT.RouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) + Await(t, currDUT, v4uni.Neighbor(prevDUT.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) switch expectedResult { case policyval.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT: - Await(t, currDUT, v4uni.LocRib().Route(prefix, oc.UnionString(prevRouterID), 0).Prefix().State(), prefix) - Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) t.Logf("Waiting for %s to be propagated", prefix) - Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) - Await(t, nextDUT, v4uni.Neighbor(currRouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) + Await(t, currDUT, v4uni.Neighbor(prevDUT.RouterID).AdjRibInPost().Route(prefix, 0).Prefix().State(), prefix) + Await(t, currDUT, v4uni.LocRib().Route(prefix, oc.UnionString(prevDUT.RouterID), 0).Prefix().State(), prefix) + Await(t, currDUT, v4uni.Neighbor(nextDUT.RouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) + Await(t, currDUT, v4uni.Neighbor(nextDUT.RouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) + Await(t, nextDUT, v4uni.Neighbor(currDUT.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) case policyval.RouteTestResult_ROUTE_TEST_RESULT_DISCARD: - Await(t, currDUT, v4uni.LocRib().Route(prefix, oc.UnionString(prevRouterID), 0).Prefix().State(), prefix) - Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) - w := Watch(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { + w := Watch(t, currDUT, v4uni.Neighbor(prevDUT.RouterID).AdjRibInPost().Route(prefix, 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { _, ok := val.Val() - return ok + return !ok }) - if _, ok := w.Await(t); ok { - t.Errorf("prefix %q (%s) was not rejected from adj-rib-out-post of %v within timeout.", prefix, routeTest.GetDescription(), currDUT) + if _, ok := w.Await(t); !ok { + t.Errorf("prefix %q (%s) was not rejected from adj-rib-in-post of %v (neighbour %v) within timeout.", prefix, routeTest.GetDescription(), currDUT, prevDUT.ID) break } - t.Logf("prefix %q (%s) was successfully rejected from adj-rib-out-post of %v within timeout.", prefix, routeTest.GetDescription(), currDUT) + t.Logf("prefix %q (%s) was successfully rejected from adj-rib-in-post of %v (neighbour %v) within timeout.", prefix, routeTest.GetDescription(), currDUT, prevDUT.ID) - w = Watch(t, nextDUT, v4uni.Neighbor(currRouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { + // Test withdrawal in the case of InstallPolicyAfterRoutes. + w = Watch(t, nextDUT, v4uni.Neighbor(currDUT.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { _, ok := val.Val() - return ok + return !ok }) - if _, ok := w.Await(t); ok { - t.Errorf("prefix %q (%s) was not rejected from adj-rib-in-pre of %v within timeout.", prefix, routeTest.GetDescription(), nextDUT) + if _, ok := w.Await(t); !ok { + t.Errorf("prefix %q (%s) was not rejected from adj-rib-in-pre of %v (neighbour %v) within timeout.", prefix, routeTest.GetDescription(), nextDUT, currDUT.ID) break } - t.Logf("prefix %q (%s) was successfully rejected from adj-rib-in-pre of %v within timeout.", prefix, routeTest.GetDescription(), nextDUT) + t.Logf("prefix %q (%s) was successfully rejected from adj-rib-in-pre of %v (neighbour %v) within timeout.", prefix, routeTest.GetDescription(), nextDUT, currDUT.ID) case policyval.RouteTestResult_ROUTE_TEST_RESULT_NOT_PREFERRED: - w := Watch(t, currDUT, v4uni.LocRib().Route(prefix, oc.UnionString(prevRouterID), 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { + Await(t, currDUT, v4uni.Neighbor(prevDUT.RouterID).AdjRibInPost().Route(prefix, 0).Prefix().State(), prefix) + w := Watch(t, currDUT, v4uni.LocRib().Route(prefix, oc.UnionString(prevDUT.RouterID), 0).Prefix().State(), rejectTimeout, func(val *ygnmi.Value[string]) bool { _, ok := val.Val() - return ok + return !ok }) - if _, ok := w.Await(t); ok { - t.Errorf("prefix %q with origin %q (%s) was selected into loc-rib of %v.", prefix, prevRouterID, routeTest.GetDescription(), currDUT) + if _, ok := w.Await(t); !ok { + t.Errorf("prefix %q with origin %q (%s) was selected into loc-rib of %v.", prefix, prevDUT.ID, routeTest.GetDescription(), currDUT) break } - t.Logf("prefix %q with origin %q (%s) was successfully not selected into loc-rib of %v within timeout.", prefix, prevRouterID, routeTest.GetDescription(), currDUT) + t.Logf("prefix %q with origin %q (%s) was successfully not selected into loc-rib of %v within timeout.", prefix, prevDUT.ID, routeTest.GetDescription(), currDUT) - Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) - Await(t, currDUT, v4uni.Neighbor(nextRouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) - Await(t, nextDUT, v4uni.Neighbor(currRouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) + Await(t, currDUT, v4uni.Neighbor(nextDUT.RouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) + Await(t, currDUT, v4uni.Neighbor(nextDUT.RouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) + Await(t, nextDUT, v4uni.Neighbor(currDUT.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) default: t.Fatalf("Invalid or unhandled policy result: %v", expectedResult) } } func testPolicyAux(t *testing.T, testspec PolicyTestCase, installPolicyAfterRoutes bool) { - dut1, stop1 := newLemming(t, dut1spec, []*AddIntfAction{{ + dut1, stop1 := newLemming(t, 1, 64500, []*AddIntfAction{{ name: "eth0", ifindex: 0, enabled: true, @@ -136,11 +136,11 @@ func testPolicyAux(t *testing.T, testspec PolicyTestCase, installPolicyAfterRout niName: "DEFAULT", }}) defer stop1() - dut2, stop2 := newLemming(t, dut2spec, nil) + dut2, stop2 := newLemming(t, 2, 64500, nil) defer stop2() - dut3, stop3 := newLemming(t, dut3spec, nil) + dut3, stop3 := newLemming(t, 3, 64501, nil) defer stop3() - dut4, stop4 := newLemming(t, dut4spec, []*AddIntfAction{{ + dut4, stop4 := newLemming(t, 4, 64502, []*AddIntfAction{{ name: "eth0", ifindex: 0, enabled: true, @@ -148,7 +148,7 @@ func testPolicyAux(t *testing.T, testspec PolicyTestCase, installPolicyAfterRout niName: "DEFAULT", }}) defer stop4() - dut5, stop5 := newLemming(t, dut5spec, []*AddIntfAction{{ + dut5, stop5 := newLemming(t, 5, 64500, []*AddIntfAction{{ name: "eth0", ifindex: 0, enabled: true, @@ -160,33 +160,26 @@ func testPolicyAux(t *testing.T, testspec PolicyTestCase, installPolicyAfterRout installDefaultPolicies := func() { // Clear the path for routes to be propagated. // DUT1 -> DUT2 -> DUT3 - Replace(t, dut1, bgp.BGPPath.Neighbor(dut2spec.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) - Replace(t, dut2, bgp.BGPPath.Neighbor(dut1spec.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) - Replace(t, dut2, bgp.BGPPath.Neighbor(dut3spec.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) - Replace(t, dut3, bgp.BGPPath.Neighbor(dut2spec.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut1, bgp.BGPPath.Neighbor(dut2.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut2, bgp.BGPPath.Neighbor(dut1.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut2, bgp.BGPPath.Neighbor(dut3.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut3, bgp.BGPPath.Neighbor(dut2.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) // This is an alternate source of routes towards DUT2 and thereby DUT3. // Note that this path is longer than the above path: // DUT4 -> DUT5 -> DUT2 (-> DUT3) - Replace(t, dut4, bgp.BGPPath.Neighbor(dut5spec.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) - Replace(t, dut5, bgp.BGPPath.Neighbor(dut4spec.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) - Replace(t, dut5, bgp.BGPPath.Neighbor(dut2spec.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) - Replace(t, dut2, bgp.BGPPath.Neighbor(dut5spec.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut4, bgp.BGPPath.Neighbor(dut5.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut5, bgp.BGPPath.Neighbor(dut4.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut5, bgp.BGPPath.Neighbor(dut2.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut2, bgp.BGPPath.Neighbor(dut5.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) } installDefaultPolicies() - if testspec.installImportSetPolicies != nil { - testspec.installImportSetPolicies(t, dut2) + if testspec.installPolicies != nil && !installPolicyAfterRoutes { + testspec.installPolicies(t, dut1, dut2, dut3, dut4, dut5) } - if testspec.installExportFilterPolicies != nil && !installPolicyAfterRoutes { - testspec.installExportFilterPolicies(t, dut2) - } - - establishSessionPair(t, dut1, dut2, dut1spec, dut2spec) - establishSessionPair(t, dut2, dut3, dut2spec, dut3spec) - establishSessionPair(t, dut4, dut5, dut4spec, dut5spec) - establishSessionPair(t, dut5, dut2, dut5spec, dut2spec) + establishSessionPairs(t, []DevicePair{{dut1, dut2}, {dut2, dut3}, {dut4, dut5}, {dut5, dut2}}...) for _, routeTest := range testspec.spec.RouteTests { // Install all regular test routes into DUT1. @@ -238,42 +231,33 @@ func testPolicyAux(t *testing.T, testspec PolicyTestCase, installPolicyAfterRout t.Logf("Installed static route on %v: %s", dut1, formatYgot(v)) for _, routeTest := range testspec.spec.RouteTests { - testPropagation(t, routeTest, dut1, dut2, dut3, dut1spec.RouterID, dut2spec.RouterID, dut3spec.RouterID, !installPolicyAfterRoutes) + testPropagation(t, routeTest, dut1, dut2, dut3, !installPolicyAfterRoutes) } for _, routeTest := range testspec.spec.LongerPathRouteTests { - testPropagation(t, routeTest, dut5, dut2, dut3, dut5spec.RouterID, dut2spec.RouterID, dut3spec.RouterID, !installPolicyAfterRoutes) + testPropagation(t, routeTest, dut5, dut2, dut3, !installPolicyAfterRoutes) } if installPolicyAfterRoutes { - awaitNewSession := make(chan error) - go func() { - if _, err := AwaitWithErr(dut2, bgp.BGPPath.Neighbor(dut3spec.RouterID).SessionState().State(), oc.Bgp_Neighbor_SessionState_IDLE); err != nil { - awaitNewSession <- err - } - if _, err := AwaitWithErr(dut3, bgp.BGPPath.Neighbor(dut2spec.RouterID).SessionState().State(), oc.Bgp_Neighbor_SessionState_IDLE); err != nil { - awaitNewSession <- err - } - if _, err := AwaitWithErr(dut2, bgp.BGPPath.Neighbor(dut3spec.RouterID).SessionState().State(), oc.Bgp_Neighbor_SessionState_ESTABLISHED); err != nil { - awaitNewSession <- err - } - if _, err := AwaitWithErr(dut3, bgp.BGPPath.Neighbor(dut2spec.RouterID).SessionState().State(), oc.Bgp_Neighbor_SessionState_ESTABLISHED); err != nil { - awaitNewSession <- err - } - awaitNewSession <- nil - }() - testspec.installExportFilterPolicies(t, dut2) - // Changing policy resets the BGP session, which causes routes - // to disappear from the AdjRIBs, so we need to wait for - // re-establishment first. - if err := <-awaitNewSession; err != nil { - t.Fatal(err) + if testspec.installPolicies != nil { + testspec.installPolicies(t, dut1, dut2, dut3, dut4, dut5) } + // Changing policy currently causes a hard reset of the BGP + // session, which causes routes to disappear from the AdjRIBs, + // so we need to wait for re-establishment first. To do this, + // we sleep for a reasonable amount of time for the sessions to + // be teared down. + // + // TODO(wenbli): Check if we can make the config amenable to a + // soft reset. + time.Sleep(10 * time.Second) + awaitSessionEstablished(t, dut2, dut1) + awaitSessionEstablished(t, dut2, dut5) for _, routeTest := range testspec.spec.RouteTests { - testPropagation(t, routeTest, dut1, dut2, dut3, dut1spec.RouterID, dut2spec.RouterID, dut3spec.RouterID, true) + testPropagation(t, routeTest, dut1, dut2, dut3, true) } for _, routeTest := range testspec.spec.LongerPathRouteTests { - testPropagation(t, routeTest, dut5, dut2, dut3, dut5spec.RouterID, dut2spec.RouterID, dut3spec.RouterID, true) + testPropagation(t, routeTest, dut5, dut2, dut3, true) } } } diff --git a/bgp/tests/local_tests/prefix_set_test.go b/bgp/tests/local_tests/prefix_set_test.go index 6fb928cd..7c924e8a 100644 --- a/bgp/tests/local_tests/prefix_set_test.go +++ b/bgp/tests/local_tests/prefix_set_test.go @@ -21,7 +21,6 @@ import ( "github.com/openconfig/lemming/bgp" "github.com/openconfig/lemming/gnmi/oc" "github.com/openconfig/lemming/gnmi/oc/ocpath" - "github.com/openconfig/ygnmi/ygnmi" valpb "github.com/openconfig/lemming/bgp/tests/proto/policyval" ) @@ -46,7 +45,7 @@ func TestPrefixSet(t *testing.T) { ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT, }}, }, - installExportFilterPolicies: func(t *testing.T, dut2 *ygnmi.Client) { + installPolicies: func(t *testing.T, dut1, dut2, _, _, _ *Device) { if debug { fmt.Println("Installing test policies") } @@ -71,7 +70,7 @@ func TestPrefixSet(t *testing.T) { stmt.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_REJECT_ROUTE) // Install policy Replace(t, dut2, ocpath.Root().RoutingPolicy().PolicyDefinition(policyName).Config(), &oc.RoutingPolicy_PolicyDefinition{Statement: policy}) - Replace(t, dut2, bgp.BGPPath.Neighbor(dut3spec.RouterID).ApplyPolicy().ExportPolicy().Config(), []string{policyName}) + Replace(t, dut2, bgp.BGPPath.Neighbor(dut1.RouterID).ApplyPolicy().ImportPolicy().Config(), []string{policyName}) }, }) } diff --git a/bgp/tests/local_tests/route_propagation_test.go b/bgp/tests/local_tests/route_propagation_test.go index d1a5d12d..31cb52ee 100644 --- a/bgp/tests/local_tests/route_propagation_test.go +++ b/bgp/tests/local_tests/route_propagation_test.go @@ -22,11 +22,10 @@ import ( "github.com/openconfig/lemming/gnmi/fakedevice" "github.com/openconfig/lemming/gnmi/oc" "github.com/openconfig/lemming/gnmi/oc/ocpath" - "github.com/openconfig/ygnmi/ygnmi" "github.com/openconfig/ygot/ygot" ) -func installStaticRoute(t *testing.T, dut *ygnmi.Client, route *oc.NetworkInstance_Protocol_Static) { +func installStaticRoute(t *testing.T, dut *Device, route *oc.NetworkInstance_Protocol_Static) { staticp := ocpath.Root().NetworkInstance(fakedevice.DefaultNetworkInstance). Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_STATIC, fakedevice.StaticRoutingProtocol) Replace(t, dut, staticp.Static(*route.Prefix).Config(), route) @@ -42,7 +41,7 @@ func formatYgot(v any) string { } func TestRoutePropagation(t *testing.T) { - dut1, stop1 := newLemming(t, dut1spec, []*AddIntfAction{{ + dut1, stop1 := newLemming(t, 1, 64500, []*AddIntfAction{{ name: "eth0", ifindex: 0, enabled: true, @@ -56,11 +55,11 @@ func TestRoutePropagation(t *testing.T) { niName: "DEFAULT", }}) defer stop1() - dut2, stop2 := newLemming(t, dut2spec, nil) + dut2, stop2 := newLemming(t, 2, 64501, nil) defer stop2() - dut3, stop3 := newLemming(t, dut3spec, nil) + dut3, stop3 := newLemming(t, 3, 64502, nil) defer stop3() - dut4, stop4 := newLemming(t, dut4spec, nil) + dut4, stop4 := newLemming(t, 4, 64503, nil) defer stop4() installDefaultPolicies := func() { @@ -70,18 +69,16 @@ func TestRoutePropagation(t *testing.T) { // route_propagation_test.go:68: Replace(t) on ygnmi client (target: "dut1") at /network-instances/network-instance[name=DEFAULT]/protocols/protocol[identifier=BGP][name=BGP]/bgp/neighbors/neighbor[neighbor-address=127.0.0.2]/apply-policy/config/default-export-policy: Replace(t) at path origin:"openconfig" elem:{name:"network-instances"} elem:{name:"network-instance" key:{key:"name" value:"DEFAULT"}} elem:{name:"protocols"} elem:{name:"protocol" key:{key:"identifier" value:"BGP"} key:{key:"name" value:"BGP"}} elem:{name:"bgp"} elem:{name:"neighbors"} elem:{name:"neighbor" key:{key:"neighbor-address" value:"127.0.0.2"}} elem:{name:"apply-policy"} elem:{name:"config"} elem:{name:"default-export-policy"}: rpc error: code = Internal desc = update is stale, update is stale, update is stale fmt.Println("Installing default policies") // Clear the path for routes to be propagated. - Replace(t, dut1, bgp.BGPPath.Neighbor(dut2spec.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) - Replace(t, dut2, bgp.BGPPath.Neighbor(dut1spec.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) - Replace(t, dut2, bgp.BGPPath.Neighbor(dut3spec.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) - Replace(t, dut3, bgp.BGPPath.Neighbor(dut2spec.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) - Replace(t, dut3, bgp.BGPPath.Neighbor(dut4spec.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) - Replace(t, dut4, bgp.BGPPath.Neighbor(dut3spec.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut1, bgp.BGPPath.Neighbor(dut2.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut2, bgp.BGPPath.Neighbor(dut1.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut2, bgp.BGPPath.Neighbor(dut3.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut3, bgp.BGPPath.Neighbor(dut2.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut3, bgp.BGPPath.Neighbor(dut4.RouterID).ApplyPolicy().DefaultExportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) + Replace(t, dut4, bgp.BGPPath.Neighbor(dut3.RouterID).ApplyPolicy().DefaultImportPolicy().Config(), oc.RoutingPolicy_DefaultPolicyType_ACCEPT_ROUTE) } installDefaultPolicies() - establishSessionPair(t, dut1, dut2, dut1spec, dut2spec) - establishSessionPair(t, dut2, dut3, dut2spec, dut3spec) - establishSessionPair(t, dut3, dut4, dut3spec, dut4spec) + establishSessionPairs(t, []DevicePair{{dut1, dut2}, {dut2, dut3}, {dut3, dut4}}...) prefix := "10.10.10.0/24" installStaticRoute(t, dut1, &oc.NetworkInstance_Protocol_Static{ @@ -101,17 +98,17 @@ func TestRoutePropagation(t *testing.T) { v4uni := ocpath.Root().NetworkInstance(fakedevice.DefaultNetworkInstance).Protocol(oc.PolicyTypes_INSTALL_PROTOCOL_TYPE_BGP, fakedevice.BGPRoutingProtocol).Bgp().Rib().AfiSafi(oc.BgpTypes_AFI_SAFI_TYPE_IPV4_UNICAST).Ipv4Unicast() // Check route is in Adj-In of dut2. - Await(t, dut2, v4uni.Neighbor(dut1spec.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) - Await(t, dut2, v4uni.Neighbor(dut1spec.RouterID).AdjRibInPost().Route(prefix, 0).Prefix().State(), prefix) + Await(t, dut2, v4uni.Neighbor(dut1.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) + Await(t, dut2, v4uni.Neighbor(dut1.RouterID).AdjRibInPost().Route(prefix, 0).Prefix().State(), prefix) // Check route is in Loc-RIB of dut2. - Await(t, dut2, v4uni.LocRib().Route(prefix, oc.UnionString(dut1spec.RouterID), 0).Prefix().State(), prefix) + Await(t, dut2, v4uni.LocRib().Route(prefix, oc.UnionString(dut1.RouterID), 0).Prefix().State(), prefix) // Check route is in Adj-Out of dut2. - Await(t, dut2, v4uni.Neighbor(dut3spec.RouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) - Await(t, dut2, v4uni.Neighbor(dut3spec.RouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) + Await(t, dut2, v4uni.Neighbor(dut3.RouterID).AdjRibOutPre().Route(prefix, 0).Prefix().State(), prefix) + Await(t, dut2, v4uni.Neighbor(dut3.RouterID).AdjRibOutPost().Route(prefix, 0).Prefix().State(), prefix) // Check route is in Adj-In of dut3. - Await(t, dut3, v4uni.Neighbor(dut2spec.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) + Await(t, dut3, v4uni.Neighbor(dut2.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) // Check route is in Adj-In of dut4. - Await(t, dut4, v4uni.Neighbor(dut3spec.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) + Await(t, dut4, v4uni.Neighbor(dut3.RouterID).AdjRibInPre().Route(prefix, 0).Prefix().State(), prefix) } diff --git a/bgp/tests/local_tests/session_establish_test.go b/bgp/tests/local_tests/session_establish_test.go index 0516935a..1805a6d5 100644 --- a/bgp/tests/local_tests/session_establish_test.go +++ b/bgp/tests/local_tests/session_establish_test.go @@ -19,7 +19,9 @@ package local_test import ( "context" "fmt" + "net" "net/netip" + "sync/atomic" "testing" "github.com/openconfig/lemming" @@ -39,61 +41,26 @@ import ( // TODO: Consolidate test helper code with integration and other unit tests. -type DeviceSpec struct { - ID uint - gnmiPort uint - gribiPort uint - bgpPort uint16 - AS uint32 - RouterID string +type Device struct { + yc *ygnmi.Client + ID uint + AS uint32 + bgpPort uint16 + RouterID string +} + +func nextLocalHostAddr() string { + // Start at 127.0.0.2 + return netip.AddrFrom4([4]byte{127, 0, 0, byte(nextLocalHostAddrIndex.Add(1) + 1)}).String() } var ( - dut1spec = DeviceSpec{ - ID: 1, - gnmiPort: 7339, - gribiPort: 7340, - bgpPort: 1111, - AS: 64500, - RouterID: "127.0.0.1", - } - dut2spec = DeviceSpec{ - ID: 2, - gnmiPort: 8339, - gribiPort: 8340, - bgpPort: 1112, - AS: 64500, - RouterID: "127.0.0.2", - } - dut3spec = DeviceSpec{ - ID: 3, - gnmiPort: 9339, - gribiPort: 9340, - bgpPort: 1113, - AS: 64501, - RouterID: "127.0.0.3", - } - dut4spec = DeviceSpec{ - ID: 4, - gnmiPort: 9439, - gribiPort: 9440, - bgpPort: 1114, - AS: 64502, - RouterID: "127.0.0.4", - } - dut5spec = DeviceSpec{ - ID: 5, - gnmiPort: 9539, - gribiPort: 9540, - bgpPort: 1115, - AS: 64500, - RouterID: "127.0.0.5", - } + nextLocalHostAddrIndex = &atomic.Uint32{} ) -func ygnmiClient(t *testing.T, target string, port int) *ygnmi.Client { +func ygnmiClient(t *testing.T, target, dialTarget string) *ygnmi.Client { t.Helper() - conn, err := grpc.Dial(fmt.Sprintf("localhost:%d", port), grpc.WithTransportCredentials(local.NewCredentials())) + conn, err := grpc.Dial(dialTarget, grpc.WithTransportCredentials(local.NewCredentials())) if err != nil { t.Fatalf("cannot dial gNMI server, %v", err) } @@ -158,12 +125,15 @@ func bgpWithNbr(as uint32, routerID string, nbr *oc.NetworkInstance_Protocol_Bgp return bgp } -func newLemming(t *testing.T, dev DeviceSpec, connectedIntfs []*AddIntfAction) (*ygnmi.Client, func()) { - opts := []lemming.Option{lemming.WithTransportCreds(insecure.NewCredentials()), lemming.WithGRIBIAddr(fmt.Sprintf(":%d", dev.gribiPort)), lemming.WithGNMIAddr(fmt.Sprintf(":%d", dev.gnmiPort)), lemming.WithBGPPort(dev.bgpPort)} +func newLemming(t *testing.T, ID uint, AS uint32, connectedIntfs []*AddIntfAction) (*Device, func()) { + routerID := nextLocalHostAddr() + gnmiTarget := net.JoinHostPort(routerID, "7339") + gribiTarget := net.JoinHostPort(routerID, "7340") + opts := []lemming.Option{lemming.WithTransportCreds(insecure.NewCredentials()), lemming.WithGRIBIAddr(gribiTarget), lemming.WithGNMIAddr(gnmiTarget), lemming.WithBGPPort(1111)} - target := fmt.Sprintf("dut%d", dev.ID) + target := fmt.Sprintf("dut%d", ID) - l, err := lemming.New(target, fmt.Sprintf("unix:/tmp/zserv-test%d.api", dev.ID), opts...) + l, err := lemming.New(target, fmt.Sprintf("unix:/tmp/zserv-test%d.api", ID), opts...) if err != nil { t.Fatal(err) } @@ -172,47 +142,55 @@ func newLemming(t *testing.T, dev DeviceSpec, connectedIntfs []*AddIntfAction) ( configureInterface(t, intf, l.GNMI()) } - return ygnmiClient(t, target, int(dev.gnmiPort)), func() { l.Stop() } + return &Device{ + yc: ygnmiClient(t, target, gnmiTarget), + ID: ID, + AS: AS, + bgpPort: 1111, + RouterID: routerID, + }, func() { l.Stop() } +} + +type DevicePair struct { + first *Device + second *Device } -func establishSessionPair(t *testing.T, dut1, dut2 *ygnmi.Client, spec1, spec2 DeviceSpec) { +func establishSessionPairs(t *testing.T, dutPairs ...DevicePair) { t.Helper() - dutConf := bgpWithNbr(spec1.AS, spec1.RouterID, &oc.NetworkInstance_Protocol_Bgp_Neighbor{ - PeerAs: ygot.Uint32(spec2.AS), - NeighborAddress: ygot.String(spec2.RouterID), - NeighborPort: ygot.Uint16(spec2.bgpPort), - }) - dut2Conf := bgpWithNbr(spec2.AS, spec2.RouterID, &oc.NetworkInstance_Protocol_Bgp_Neighbor{ - PeerAs: ygot.Uint32(spec1.AS), - NeighborAddress: ygot.String(spec1.RouterID), - NeighborPort: ygot.Uint16(spec1.bgpPort), - }) - Update(t, dut1, bgp.BGPPath.Config(), dutConf) - Update(t, dut2, bgp.BGPPath.Config(), dut2Conf) - - awaitSessionEstablished(t, dut1, dut2, spec1, spec2) + for _, pair := range dutPairs { + dut1, dut2 := pair.first, pair.second + dutConf := bgpWithNbr(dut1.AS, dut1.RouterID, &oc.NetworkInstance_Protocol_Bgp_Neighbor{ + PeerAs: ygot.Uint32(dut2.AS), + NeighborAddress: ygot.String(dut2.RouterID), + NeighborPort: ygot.Uint16(dut2.bgpPort), + }) + dut2Conf := bgpWithNbr(dut2.AS, dut2.RouterID, &oc.NetworkInstance_Protocol_Bgp_Neighbor{ + PeerAs: ygot.Uint32(dut1.AS), + NeighborAddress: ygot.String(dut1.RouterID), + NeighborPort: ygot.Uint16(dut1.bgpPort), + }) + Update(t, dut1, bgp.BGPPath.Config(), dutConf) + Update(t, dut2, bgp.BGPPath.Config(), dut2Conf) + } + + for _, pair := range dutPairs { + dut1, dut2 := pair.first, pair.second + awaitSessionEstablished(t, dut1, dut2) + } } -func awaitSessionEstablished(t *testing.T, dut1, dut2 *ygnmi.Client, spec1, spec2 DeviceSpec) { +func awaitSessionEstablished(t *testing.T, dut1, dut2 *Device) { t.Helper() - Await(t, dut1, bgp.BGPPath.Neighbor(spec2.RouterID).SessionState().State(), oc.Bgp_Neighbor_SessionState_ESTABLISHED) - Await(t, dut2, bgp.BGPPath.Neighbor(spec1.RouterID).SessionState().State(), oc.Bgp_Neighbor_SessionState_ESTABLISHED) + Await(t, dut1, bgp.BGPPath.Neighbor(dut2.RouterID).SessionState().State(), oc.Bgp_Neighbor_SessionState_ESTABLISHED) + Await(t, dut2, bgp.BGPPath.Neighbor(dut1.RouterID).SessionState().State(), oc.Bgp_Neighbor_SessionState_ESTABLISHED) } func TestSessionEstablish(t *testing.T) { - dut1, stop1 := newLemming(t, dut1spec, nil) + dut1, stop1 := newLemming(t, 1, 64500, nil) defer stop1() - dut2, stop2 := newLemming(t, dut2spec, nil) - defer stop2() - - establishSessionPair(t, dut1, dut2, dut1spec, dut2spec) -} - -func TestEstablishDifferentIP(t *testing.T) { - dut2, stop2 := newLemming(t, dut2spec, nil) + dut2, stop2 := newLemming(t, 2, 64501, nil) defer stop2() - dut3, stop3 := newLemming(t, dut3spec, nil) - defer stop3() - establishSessionPair(t, dut2, dut3, dut2spec, dut3spec) + establishSessionPairs(t, DevicePair{first: dut1, second: dut2}) } diff --git a/bgp/tests/local_tests/ygnmi_test.go b/bgp/tests/local_tests/ygnmi_test.go index ec861740..63aa0ae8 100644 --- a/bgp/tests/local_tests/ygnmi_test.go +++ b/bgp/tests/local_tests/ygnmi_test.go @@ -35,8 +35,9 @@ const ( // Get fetches the value of a SingletonQuery with a ONCE subscription, // failing the test fatally if no value is present at the path. // Use Lookup to also get metadata or tolerate no value present. -func Get[T any](t testing.TB, c *ygnmi.Client, q ygnmi.SingletonQuery[T]) T { +func Get[T any](t testing.TB, dut *Device, q ygnmi.SingletonQuery[T]) T { t.Helper() + c := dut.yc v, err := ygnmi.Get(context.Background(), c, q) if err != nil { t.Fatalf("Get(t) on %s at %v: %v", c, q, err) @@ -49,16 +50,17 @@ func Get[T any](t testing.TB, c *ygnmi.Client, q ygnmi.SingletonQuery[T]) T { // Use Lookup to also get metadata or tolerate no value present. // Note: This is a workaround for Go's type inference not working for this use case and may be removed in a subsequent release. // Note: This is equivalent to calling Get with a ConfigQuery and providing a fully-qualified type parameter. -func GetConfig[T any](t testing.TB, c *ygnmi.Client, q ygnmi.ConfigQuery[T]) T { +func GetConfig[T any](t testing.TB, dut *Device, q ygnmi.ConfigQuery[T]) T { t.Helper() - return Get[T](t, c, q) + return Get[T](t, dut, q) } // GetAll fetches the value of a WildcardQuery with a ONCE subscription skipping any non-present paths. // It fails the test fatally if no value is present at the path // Use LookupAll to also get metadata or tolerate no values present. -func GetAll[T any](t testing.TB, c *ygnmi.Client, q ygnmi.WildcardQuery[T]) []T { +func GetAll[T any](t testing.TB, dut *Device, q ygnmi.WildcardQuery[T]) []T { t.Helper() + c := dut.yc v, err := ygnmi.GetAll(context.Background(), c, q) if err != nil { t.Fatalf("GetAll(t) on %s at %v: %v", c, q, err) @@ -67,8 +69,9 @@ func GetAll[T any](t testing.TB, c *ygnmi.Client, q ygnmi.WildcardQuery[T]) []T } // Update updates the configuration at the given query path with the val. -func Update[T any](t testing.TB, c *ygnmi.Client, q ygnmi.ConfigQuery[T], val T) *ygnmi.Result { +func Update[T any](t testing.TB, dut *Device, q ygnmi.ConfigQuery[T], val T) *ygnmi.Result { t.Helper() + c := dut.yc res, err := ygnmi.Update(context.Background(), c, q, val) if err != nil { t.Fatalf("Update(t) on %v at %v: %v", c, q, err) @@ -77,8 +80,9 @@ func Update[T any](t testing.TB, c *ygnmi.Client, q ygnmi.ConfigQuery[T], val T) } // Replace replaces the configuration at the given query path with the val. -func Replace[T any](t testing.TB, c *ygnmi.Client, q ygnmi.ConfigQuery[T], val T) *ygnmi.Result { +func Replace[T any](t testing.TB, dut *Device, q ygnmi.ConfigQuery[T], val T) *ygnmi.Result { t.Helper() + c := dut.yc res, err := ygnmi.Replace(context.Background(), c, q, val) if err != nil { t.Fatalf("Replace(t) on %v at %v: %v", c, q, err) @@ -87,8 +91,9 @@ func Replace[T any](t testing.TB, c *ygnmi.Client, q ygnmi.ConfigQuery[T], val T } // Delete deletes the configuration at the given query path. -func Delete[T any](t testing.TB, c *ygnmi.Client, q ygnmi.ConfigQuery[T]) *ygnmi.Result { +func Delete[T any](t testing.TB, dut *Device, q ygnmi.ConfigQuery[T]) *ygnmi.Result { t.Helper() + c := dut.yc res, err := ygnmi.Delete(context.Background(), c, q) if err != nil { t.Fatalf("Delete(t) on %v at %v: %v", c, q, err) @@ -100,8 +105,9 @@ func Delete[T any](t testing.TB, c *ygnmi.Client, q ygnmi.ConfigQuery[T]) *ygnmi // blocking until a value that is deep equal to the specified val is received // or the timeout is reached. To wait for a generic predicate, or to make a // non-blocking call, use the Watch method instead. -func Await[T any](t testing.TB, c *ygnmi.Client, q ygnmi.SingletonQuery[T], val T) *ygnmi.Value[T] { +func Await[T any](t testing.TB, dut *Device, q ygnmi.SingletonQuery[T], val T) *ygnmi.Value[T] { t.Helper() + c := dut.yc ctx, cancel := context.WithTimeout(context.Background(), awaitTimeLimit) defer cancel() v, err := ygnmi.Await(ctx, c, q, val) @@ -114,9 +120,10 @@ func Await[T any](t testing.TB, c *ygnmi.Client, q ygnmi.SingletonQuery[T], val // AwaitWithErr is the same as Await except an error is returned. // // Its purpose is to add a better error message. -func AwaitWithErr[T any](c *ygnmi.Client, q ygnmi.SingletonQuery[T], val T) (*ygnmi.Value[T], error) { +func AwaitWithErr[T any](dut *Device, q ygnmi.SingletonQuery[T], val T) (*ygnmi.Value[T], error) { ctx, cancel := context.WithTimeout(context.Background(), awaitTimeLimit) defer cancel() + c := dut.yc v, err := ygnmi.Await(ctx, c, q, val) if err != nil { return v, fmt.Errorf("Await(t) on %v at %v: %v", c, q, err) @@ -173,8 +180,9 @@ func (w *Watcher[T]) Cancel() { // or the timeout is reached. Calling Await on the returned Watcher waits for the subscription // to complete. It returns the last observed value and a boolean that indicates whether // that value satisfies the predicate. -func Watch[T any](t testing.TB, c *ygnmi.Client, q ygnmi.SingletonQuery[T], timeout time.Duration, pred func(*ygnmi.Value[T]) bool) *Watcher[T] { +func Watch[T any](t testing.TB, dut *Device, q ygnmi.SingletonQuery[T], timeout time.Duration, pred func(*ygnmi.Value[T]) bool) *Watcher[T] { t.Helper() + c := dut.yc ctx, cancel := context.WithTimeout(context.Background(), timeout) w := ygnmi.Watch(ctx, c, q, func(v *ygnmi.Value[T]) error { if ok := pred(v); ok { diff --git a/repositories.bzl b/repositories.bzl index b2d6bd1c..64deb6c7 100644 --- a/repositories.bzl +++ b/repositories.bzl @@ -48,8 +48,8 @@ def go_repositories(): go_repository( name = "com_github_alecthomas_units", importpath = "github.com/alecthomas/units", - sum = "h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E=", - version = "v0.0.0-20190717042225-c3de453c63f4", + sum = "h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=", + version = "v0.0.0-20211218093645-b94a6e3cc137", ) go_repository( name = "com_github_andybalholm_brotli", @@ -1157,8 +1157,8 @@ def go_repositories(): go_repository( name = "com_github_julienschmidt_httprouter", importpath = "github.com/julienschmidt/httprouter", - sum = "h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=", - version = "v1.2.0", + sum = "h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=", + version = "v1.3.0", ) go_repository( name = "com_github_jung_kurt_gofpdf", @@ -1226,8 +1226,8 @@ def go_repositories(): go_repository( name = "com_github_konsorten_go_windows_terminal_sequences", importpath = "github.com/konsorten/go-windows-terminal-sequences", - sum = "h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=", - version = "v1.0.1", + sum = "h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=", + version = "v1.0.3", ) go_repository( @@ -1420,8 +1420,8 @@ def go_repositories(): go_repository( name = "com_github_mwitkow_go_conntrack", importpath = "github.com/mwitkow/go-conntrack", - sum = "h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc=", - version = "v0.0.0-20161129095857-cc309e4a2223", + sum = "h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=", + version = "v0.0.0-20190716064945-2f068394615f", ) go_repository( @@ -1572,8 +1572,8 @@ def go_repositories(): "gazelle:resolve go github.com/p4lang/p4runtime/go/p4/v1 @com_github_p4lang_p4runtime//:p4runtime_go_proto", ], importpath = "github.com/openconfig/ondatra", - sum = "h1:hR1OQ5oW5BFz4BX5HU7jhh45Wy9eIAQULnljowfNDhU=", - version = "v0.2.5", + sum = "h1:abEI0qO4Q/BrXV/qi2unXn8dpkZFp9DF8rw6kZod5/E=", + version = "v0.2.7", ) go_repository( name = "com_github_openconfig_testt", @@ -2393,8 +2393,8 @@ def go_repositories(): go_repository( name = "com_google_cloud_go_gaming", importpath = "cloud.google.com/go/gaming", - sum = "h1:5qZmZEWzMf8GEFgm9NeC3bjFRpt7x4S6U7oLbxaf7N8=", - version = "v1.10.1", + sum = "h1:7vEhFnZmd931Mo7sZ6pJy7uQPDxF7m7v8xtBheG08tc=", + version = "v1.9.0", ) go_repository( name = "com_google_cloud_go_gkebackup", @@ -2423,8 +2423,8 @@ def go_repositories(): go_repository( name = "com_google_cloud_go_grafeas", importpath = "cloud.google.com/go/grafeas", - sum = "h1:oyTL/KjiUeBs9eYLw/40cpSZglUC+0F7X4iu/8t7NWs=", - version = "v0.3.0", + sum = "h1:CYjC+xzdPvbV65gi6Dr4YowKcmLo045pm18L0DhdELM=", + version = "v0.2.0", ) go_repository( name = "com_google_cloud_go_gsuiteaddons", @@ -3321,8 +3321,8 @@ def go_repositories(): go_repository( name = "org_golang_x_tools", importpath = "golang.org/x/tools", - sum = "h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=", - version = "v0.9.1", + sum = "h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=", + version = "v0.7.0", ) go_repository( name = "org_golang_x_xerrors", From 643da447145db6c81fb621c3338d54477d999bc2 Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 24 Aug 2023 10:14:40 -0700 Subject: [PATCH 6/8] Fix lint --- bgp/tests/local_tests/session_establish_test.go | 8 ++++---- bgp/tests/local_tests/ygnmi_test.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bgp/tests/local_tests/session_establish_test.go b/bgp/tests/local_tests/session_establish_test.go index 1805a6d5..17c884f7 100644 --- a/bgp/tests/local_tests/session_establish_test.go +++ b/bgp/tests/local_tests/session_establish_test.go @@ -125,15 +125,15 @@ func bgpWithNbr(as uint32, routerID string, nbr *oc.NetworkInstance_Protocol_Bgp return bgp } -func newLemming(t *testing.T, ID uint, AS uint32, connectedIntfs []*AddIntfAction) (*Device, func()) { +func newLemming(t *testing.T, id uint, AS uint32, connectedIntfs []*AddIntfAction) (*Device, func()) { routerID := nextLocalHostAddr() gnmiTarget := net.JoinHostPort(routerID, "7339") gribiTarget := net.JoinHostPort(routerID, "7340") opts := []lemming.Option{lemming.WithTransportCreds(insecure.NewCredentials()), lemming.WithGRIBIAddr(gribiTarget), lemming.WithGNMIAddr(gnmiTarget), lemming.WithBGPPort(1111)} - target := fmt.Sprintf("dut%d", ID) + target := fmt.Sprintf("dut%d", id) - l, err := lemming.New(target, fmt.Sprintf("unix:/tmp/zserv-test%d.api", ID), opts...) + l, err := lemming.New(target, fmt.Sprintf("unix:/tmp/zserv-test%d.api", id), opts...) if err != nil { t.Fatal(err) } @@ -144,7 +144,7 @@ func newLemming(t *testing.T, ID uint, AS uint32, connectedIntfs []*AddIntfActio return &Device{ yc: ygnmiClient(t, target, gnmiTarget), - ID: ID, + ID: id, AS: AS, bgpPort: 1111, RouterID: routerID, diff --git a/bgp/tests/local_tests/ygnmi_test.go b/bgp/tests/local_tests/ygnmi_test.go index 63aa0ae8..a94e67f4 100644 --- a/bgp/tests/local_tests/ygnmi_test.go +++ b/bgp/tests/local_tests/ygnmi_test.go @@ -29,7 +29,7 @@ import ( ) const ( - awaitTimeLimit = 20 * time.Second + awaitTimeLimit = 30 * time.Second ) // Get fetches the value of a SingletonQuery with a ONCE subscription, From 84c51487135ce163566aaf485588914da16dc3dd Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 24 Aug 2023 10:21:40 -0700 Subject: [PATCH 7/8] fix lint --- bgp/tests/local_tests/session_establish_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bgp/tests/local_tests/session_establish_test.go b/bgp/tests/local_tests/session_establish_test.go index 17c884f7..5cc114e0 100644 --- a/bgp/tests/local_tests/session_establish_test.go +++ b/bgp/tests/local_tests/session_establish_test.go @@ -125,7 +125,7 @@ func bgpWithNbr(as uint32, routerID string, nbr *oc.NetworkInstance_Protocol_Bgp return bgp } -func newLemming(t *testing.T, id uint, AS uint32, connectedIntfs []*AddIntfAction) (*Device, func()) { +func newLemming(t *testing.T, id uint, as uint32, connectedIntfs []*AddIntfAction) (*Device, func()) { routerID := nextLocalHostAddr() gnmiTarget := net.JoinHostPort(routerID, "7339") gribiTarget := net.JoinHostPort(routerID, "7340") @@ -145,7 +145,7 @@ func newLemming(t *testing.T, id uint, AS uint32, connectedIntfs []*AddIntfActio return &Device{ yc: ygnmiClient(t, target, gnmiTarget), ID: id, - AS: AS, + AS: as, bgpPort: 1111, RouterID: routerID, }, func() { l.Stop() } From e909526a10c78f866514068c3892c0f3b70f6c79 Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 24 Aug 2023 14:27:26 -0700 Subject: [PATCH 8/8] LocalAddresses exception for localhost RouterIDs --- bgp/gobgp.go | 10 +++++----- bgp/tests/local_tests/session_establish_test.go | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/bgp/gobgp.go b/bgp/gobgp.go index 601cf846..bcb2eb89 100644 --- a/bgp/gobgp.go +++ b/bgp/gobgp.go @@ -134,6 +134,7 @@ func (t *bgpDeclTask) startGoBGPFuncDecl(_ context.Context, yclient *ygnmi.Clien BGPPath.NeighborAny().PeerAs().Config().PathStruct(), BGPPath.NeighborAny().NeighborAddress().Config().PathStruct(), BGPPath.NeighborAny().NeighborPort().Config().PathStruct(), + BGPPath.NeighborAny().Transport().LocalAddress().Config().PathStruct(), // BGP Policy statements RoutingPolicyPath.PolicyDefinitionAny().Name().Config().PathStruct(), RoutingPolicyPath.PolicyDefinitionAny().StatementMap().Config().PathStruct(), @@ -395,12 +396,11 @@ func intendedToGoBGP(bgpoc *oc.NetworkInstance_Protocol_Bgp, policyoc *oc.Routin bgpConfig.Global.Config.As = global.GetAs() bgpConfig.Global.Config.RouterId = global.GetRouterId() bgpConfig.Global.Config.Port = int32(listenPort) - // Have GoBGP listen only on this address instead of all addresses. - bgpConfig.Global.Config.LocalAddressList = []string{global.GetRouterId()} - localAddress := "" if localAddr, err := netip.ParseAddr(global.GetRouterId()); err == nil && localAddr.IsLoopback() { - localAddress = localAddr.String() + // Have GoBGP listen only on local address instead of all + // addresses when testing BGP server on localhost. + bgpConfig.Global.Config.LocalAddressList = []string{localAddr.String()} } for neighAddr, neigh := range bgpoc.Neighbor { @@ -423,7 +423,7 @@ func intendedToGoBGP(bgpoc *oc.NetworkInstance_Protocol_Bgp, policyoc *oc.Routin }, Transport: bgpconfig.Transport{ Config: bgpconfig.TransportConfig{ - LocalAddress: localAddress, + LocalAddress: neigh.GetTransport().GetLocalAddress(), RemotePort: neigh.GetNeighborPort(), }, }, diff --git a/bgp/tests/local_tests/session_establish_test.go b/bgp/tests/local_tests/session_establish_test.go index 5cc114e0..7ec8cdeb 100644 --- a/bgp/tests/local_tests/session_establish_test.go +++ b/bgp/tests/local_tests/session_establish_test.go @@ -164,11 +164,17 @@ func establishSessionPairs(t *testing.T, dutPairs ...DevicePair) { PeerAs: ygot.Uint32(dut2.AS), NeighborAddress: ygot.String(dut2.RouterID), NeighborPort: ygot.Uint16(dut2.bgpPort), + Transport: &oc.NetworkInstance_Protocol_Bgp_Neighbor_Transport{ + LocalAddress: ygot.String(dut1.RouterID), + }, }) dut2Conf := bgpWithNbr(dut2.AS, dut2.RouterID, &oc.NetworkInstance_Protocol_Bgp_Neighbor{ PeerAs: ygot.Uint32(dut1.AS), NeighborAddress: ygot.String(dut1.RouterID), NeighborPort: ygot.Uint16(dut1.bgpPort), + Transport: &oc.NetworkInstance_Protocol_Bgp_Neighbor_Transport{ + LocalAddress: ygot.String(dut2.RouterID), + }, }) Update(t, dut1, bgp.BGPPath.Config(), dutConf) Update(t, dut2, bgp.BGPPath.Config(), dut2Conf)