From 9ff67b5ff44301d71aaf53d1877a0c0f2f861e13 Mon Sep 17 00:00:00 2001 From: liubovulitina Date: Thu, 30 Jan 2025 12:59:52 +0000 Subject: [PATCH] Add to Gribi Get() tests validation that the correct status is returned PiperOrigin-RevId: 721346682 --- chk/chk.go | 26 +++++++++++++++++++------ compliance/get.go | 21 ++++++++++++++------- fluent/fluent.go | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 13 deletions(-) diff --git a/chk/chk.go b/chk/chk.go index e00403ba..543e5362 100644 --- a/chk/chk.go +++ b/chk/chk.go @@ -27,15 +27,15 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/openconfig/gribigo/client" - "github.com/openconfig/gribigo/fluent" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/testing/protocmp" + "github.com/openconfig/gribigo/client" + "github.com/openconfig/gribigo/fluent" - spb "github.com/openconfig/gribi/v1/proto/service" gspb "google.golang.org/genproto/googleapis/rpc/status" + spb "github.com/openconfig/gribi/v1/proto/service" ) // resultOpt is an interface implemented by all options that can be @@ -374,17 +374,31 @@ func GetResponseHasEntries(t testing.TB, getres *spb.GetResponse, wants ...fluen switch v := wantProto.Entry.(type) { case *spb.AFTEntry_NextHopGroup: - if _, ok := ni.nhg[v.NextHopGroup.GetId()]; !ok { + if nhg, ok := ni.nhg[v.NextHopGroup.GetId()]; !ok { t.Fatalf("did not find entry, did not find nexthop group: %s, got:\n%s", v.NextHopGroup, getres) + } else { + programmedStatusMatch(t, nhg, wantProto) } case *spb.AFTEntry_NextHop: - if _, ok := ni.nh[v.NextHop.GetIndex()]; !ok { + if nh, ok := ni.nh[v.NextHop.GetIndex()]; !ok { t.Fatalf("did not find entry, did not find nexthop: %s, got:\n%s", v.NextHop, getres) + } else { + programmedStatusMatch(t, nh, wantProto) } case *spb.AFTEntry_Ipv4: - if _, ok := ni.ipv4[v.Ipv4.GetPrefix()]; !ok { + if ipv4, ok := ni.ipv4[v.Ipv4.GetPrefix()]; !ok { t.Fatalf("did not find entry, did not find ipv4: %s, got: %s\n", v.Ipv4, getres) + } else { + programmedStatusMatch(t, ipv4, wantProto) } } } } + +// programmedStatusMatch checks if the response's AFT entry FIB status matches the expected status. +// It skips the check if the expected status is UNAVAILABLE (default value). +func programmedStatusMatch(t testing.TB, resp *spb.AFTEntry, want *spb.AFTEntry) { + if want.GetFibStatus() != spb.AFTEntry_UNAVAILABLE && resp.GetFibStatus() != want.GetFibStatus() { + t.Fatalf("FIB status mismatch: %s, got: %s\n", want.GetFibStatus(), resp.GetFibStatus()) + } +} diff --git a/compliance/get.go b/compliance/get.go index 86a17226..ed95b7c0 100644 --- a/compliance/get.go +++ b/compliance/get.go @@ -69,7 +69,8 @@ func GetNH(c *fluent.GRIBIClient, wantACK fluent.ProgrammingResult, t testing.TB fluent.NextHopEntry(). WithNetworkInstance(defaultNetworkInstanceName). WithIndex(1). - WithIPAddress("192.0.2.3")) + WithIPAddress("192.0.2.3"). + WithFIBProgrammed(wantACK)) } @@ -129,7 +130,8 @@ func GetNHG(c *fluent.GRIBIClient, wantACK fluent.ProgrammingResult, t testing.T fluent.NextHopGroupEntry(). WithNetworkInstance(defaultNetworkInstanceName). WithID(1). - AddNextHop(1, 1), + AddNextHop(1, 1). + WithFIBProgrammed(wantACK), ) } @@ -208,7 +210,8 @@ func GetIPv4(c *fluent.GRIBIClient, wantACK fluent.ProgrammingResult, t testing. WithNetworkInstance(defaultNetworkInstanceName). WithNextHopGroup(1). WithPrefix("42.42.42.42/32"). - WithMetadata([]byte{1, 2, 3, 4, 5, 6, 7, 8}), + WithMetadata([]byte{1, 2, 3, 4, 5, 6, 7, 8}). + WithFIBProgrammed(wantACK), ) } @@ -287,7 +290,8 @@ func GetIPv6(c *fluent.GRIBIClient, wantACK fluent.ProgrammingResult, t testing. WithNetworkInstance(defaultNetworkInstanceName). WithNextHopGroup(1). WithPrefix("2001:db8::/32"). - WithMetadata([]byte{1, 2, 3, 4, 5, 6, 7, 8}), + WithMetadata([]byte{1, 2, 3, 4, 5, 6, 7, 8}). + WithFIBProgrammed(wantACK), ) } @@ -365,15 +369,18 @@ func GetIPv4Chain(c *fluent.GRIBIClient, wantACK fluent.ProgrammingResult, t tes fluent.IPv4Entry(). WithNetworkInstance(defaultNetworkInstanceName). WithNextHopGroup(1). - WithPrefix("42.42.42.42/32"), + WithPrefix("42.42.42.42/32"). + WithFIBProgrammed(wantACK), fluent.NextHopGroupEntry(). WithNetworkInstance(defaultNetworkInstanceName). WithID(1). - AddNextHop(1, 1), + AddNextHop(1, 1). + WithFIBProgrammed(wantACK), fluent.NextHopEntry(). WithNetworkInstance(defaultNetworkInstanceName). WithIndex(1). - WithIPAddress("192.0.2.3"), + WithIPAddress("192.0.2.3"). + WithFIBProgrammed(wantACK), ) } diff --git a/fluent/fluent.go b/fluent/fluent.go index 89a87c8a..9ab531a5 100644 --- a/fluent/fluent.go +++ b/fluent/fluent.go @@ -527,6 +527,8 @@ type ipv4Entry struct { // electionID is an explicit election ID to be used for an // operation using the entry. electionID *spb.Uint128 + // fibStatus is the FIB programming status of the entry. + fibStatus spb.AFTEntry_Status } // IPv4Entry returns a new gRIBI IPv4Entry builder. @@ -583,6 +585,15 @@ func (i *ipv4Entry) WithElectionID(low, high uint64) *ipv4Entry { return i } +// WithFIBProgrammed sets the FIB programming status of the entry to PROGRAMMED if +// the specified operation programming result is InstalledInFIB. +func (i *ipv4Entry) WithFIBProgrammed(r ProgrammingResult) *ipv4Entry { + if r == InstalledInFIB { + i.fibStatus = spb.AFTEntry_PROGRAMMED + } + return i +} + // OpProto implements the gRIBIEntry interface, returning a gRIBI AFTOperation. ID // is explicitly not populated such that they can be populated by // the function (e.g., AddEntry) to which they are an argument. @@ -603,6 +614,7 @@ func (i *ipv4Entry) EntryProto() (*spb.AFTEntry, error) { Entry: &spb.AFTEntry_Ipv4{ Ipv4: proto.Clone(i.pb).(*aftpb.Afts_Ipv4EntryKey), }, + FibStatus: i.fibStatus, }, nil } @@ -615,6 +627,8 @@ type ipv6Entry struct { // electionID is an explicit election ID to be used for an // operation using the entry. electionID *spb.Uint128 + // fibStatus is the FIB programming status of the entry. + fibStatus spb.AFTEntry_Status } // IPv6Entry returns a new gRIBI IPv6Entry builder. @@ -671,6 +685,15 @@ func (i *ipv6Entry) WithElectionID(low, high uint64) *ipv6Entry { return i } +// WithFIBProgrammed sets the FIB programming status of the entry to PROGRAMMED if +// the specified operation programming result is InstalledInFIB. +func (i *ipv6Entry) WithFIBProgrammed(r ProgrammingResult) *ipv6Entry { + if r == InstalledInFIB { + i.fibStatus = spb.AFTEntry_PROGRAMMED + } + return i +} + // OpProto implements the gRIBIEntry interface, returning a gRIBI AFTOperation. ID // is explicitly not populated such that they can be populated by // the function (e.g., AddEntry) to which they are an argument. @@ -691,6 +714,7 @@ func (i *ipv6Entry) EntryProto() (*spb.AFTEntry, error) { Entry: &spb.AFTEntry_Ipv6{ Ipv6: proto.Clone(i.pb).(*aftpb.Afts_Ipv6EntryKey), }, + FibStatus: i.fibStatus, }, nil } @@ -790,6 +814,8 @@ type nextHopEntry struct { // electionID is an explicit electionID to be used when the next-hop entry // is programmed. electionID *spb.Uint128 + // fibStatus is the FIB programming status of the entry. + fibStatus spb.AFTEntry_Status } // NextHopEntry returns a builder that can be used to build up a NextHop within @@ -963,6 +989,15 @@ func (n *nextHopEntry) WithElectionID(low, high uint64) *nextHopEntry { return n } +// WithFIBProgrammed sets the FIB programming status of the entry to PROGRAMMED if +// the specified operation programming result is InstalledInFIB. +func (n *nextHopEntry) WithFIBProgrammed(r ProgrammingResult) *nextHopEntry { + if r == InstalledInFIB { + n.fibStatus = spb.AFTEntry_PROGRAMMED + } + return n +} + // TODO(robjs): add additional NextHopEntry fields. // OpProto implements the GRIBIEntry interface, building a gRIBI AFTOperation. ID @@ -985,6 +1020,7 @@ func (n *nextHopEntry) EntryProto() (*spb.AFTEntry, error) { Entry: &spb.AFTEntry_NextHop{ NextHop: proto.Clone(n.pb).(*aftpb.Afts_NextHopKey), }, + FibStatus: n.fibStatus, }, nil } @@ -998,6 +1034,8 @@ type nextHopGroupEntry struct { // electionID is the explicit election ID to be used when this entry is used // in an AFTOperation. electionID *spb.Uint128 + // fibStatus is the FIB programming status of the entry. + fibStatus spb.AFTEntry_Status } // NextHopGroupEntry returns a builder that can be used to build up a NextHopGroup within @@ -1052,6 +1090,15 @@ func (n *nextHopGroupEntry) WithElectionID(low, high uint64) *nextHopGroupEntry return n } +// WithFIBProgrammed sets the FIB programming status of the entry to PROGRAMMED if +// the specified operation programming result is InstalledInFIB. +func (n *nextHopGroupEntry) WithFIBProgrammed(r ProgrammingResult) *nextHopGroupEntry { + if r == InstalledInFIB { + n.fibStatus = spb.AFTEntry_PROGRAMMED + } + return n +} + // OpProto implements the GRIBIEntry interface, building a gRIBI AFTOperation. ID // and ElectionID are explicitly not populated such that they can be populated by // the function (e.g., AddEntry) to which they are an argument. @@ -1072,6 +1119,7 @@ func (n *nextHopGroupEntry) EntryProto() (*spb.AFTEntry, error) { Entry: &spb.AFTEntry_NextHopGroup{ NextHopGroup: proto.Clone(n.pb).(*aftpb.Afts_NextHopGroupKey), }, + FibStatus: n.fibStatus, }, nil }