From 1e6834bc66e3898bb03de534d9b1875ef5134ef0 Mon Sep 17 00:00:00 2001 From: Oliver Herms <oliver.herms@exaring.de> Date: Sun, 4 Nov 2018 13:31:00 +0100 Subject: [PATCH] Add integration test for gRPC interface --- apps/bmp-streamer/pkg/apiserver/server.go | 23 +-- .../bmp-streamer/pkg/apiserver/server_test.go | 142 +++++++++++++++++- protocols/bgp/server/bmp_server.go | 2 +- 3 files changed, 153 insertions(+), 14 deletions(-) diff --git a/apps/bmp-streamer/pkg/apiserver/server.go b/apps/bmp-streamer/pkg/apiserver/server.go index 0fe16ff0..5b886609 100644 --- a/apps/bmp-streamer/pkg/apiserver/server.go +++ b/apps/bmp-streamer/pkg/apiserver/server.go @@ -2,23 +2,28 @@ package apiserver import ( "fmt" + "net" pb "github.com/bio-routing/bio-rd/apps/bmp-streamer/pkg/bmpstreamer" - net "github.com/bio-routing/bio-rd/net" + bionet "github.com/bio-routing/bio-rd/net" netapi "github.com/bio-routing/bio-rd/net/api" "github.com/bio-routing/bio-rd/protocols/bgp/packet" - "github.com/bio-routing/bio-rd/protocols/bgp/server" "github.com/bio-routing/bio-rd/route" "github.com/bio-routing/bio-rd/routingtable" ) +type bmpServer interface { + SubscribeRIBs(client routingtable.RouteTableClient, rtr net.IP, afi uint8) + UnsubscribeRIBs(client routingtable.RouteTableClient, rtr net.IP, afi uint8) +} + // APIServer implements the BMP server API type APIServer struct { - bmpServer *server.BMPServer + bmpServer bmpServer } // New creates an new API server -func New(bmpServer *server.BMPServer) *APIServer { +func New(bmpServer bmpServer) *APIServer { return &APIServer{ bmpServer: bmpServer, } @@ -39,11 +44,11 @@ func (a *APIServer) AdjRIBInStream(req *pb.AdjRIBInStreamRequest, stream pb.RIBS r4 := newRIBClient() r6 := newRIBClient() - addr := net.IP{} + addr := bionet.IP{} if req.Router.Version == netapi.IP_IPv4 { - addr = net.IPv4(uint32(req.Router.Lower)) + addr = bionet.IPv4(uint32(req.Router.Lower)) } else if req.Router.Version == netapi.IP_IPv6 { - addr = net.IPv6(req.Router.Higher, req.Router.Lower) + addr = bionet.IPv6(req.Router.Higher, req.Router.Lower) } else { return fmt.Errorf("Unknown protocol") } @@ -97,7 +102,7 @@ func newRIBClient() *ribClient { } } -func (r *ribClient) AddPath(pfx net.Prefix, path *route.Path) error { +func (r *ribClient) AddPath(pfx bionet.Prefix, path *route.Path) error { r.ch <- update{ advertisement: true, route: route.NewRoute(pfx, path), @@ -106,7 +111,7 @@ func (r *ribClient) AddPath(pfx net.Prefix, path *route.Path) error { return nil } -func (r *ribClient) RemovePath(pfx net.Prefix, path *route.Path) bool { +func (r *ribClient) RemovePath(pfx bionet.Prefix, path *route.Path) bool { r.ch <- update{ advertisement: false, route: route.NewRoute(pfx, path), diff --git a/apps/bmp-streamer/pkg/apiserver/server_test.go b/apps/bmp-streamer/pkg/apiserver/server_test.go index 45f5a132..f14d877f 100644 --- a/apps/bmp-streamer/pkg/apiserver/server_test.go +++ b/apps/bmp-streamer/pkg/apiserver/server_test.go @@ -1,17 +1,39 @@ package apiserver import ( + "context" + "fmt" + "log" + "net" + "sync" "testing" + "time" pb "github.com/bio-routing/bio-rd/apps/bmp-streamer/pkg/bmpstreamer" - "github.com/bio-routing/bio-rd/net" + bionet "github.com/bio-routing/bio-rd/net" apinet "github.com/bio-routing/bio-rd/net/api" + "github.com/bio-routing/bio-rd/protocols/bgp/server" "github.com/bio-routing/bio-rd/protocols/bgp/types" "github.com/bio-routing/bio-rd/route" apiroute "github.com/bio-routing/bio-rd/route/api" + "github.com/bio-routing/bio-rd/routingtable" + "github.com/bio-routing/bio-rd/routingtable/locRIB" "github.com/stretchr/testify/assert" + "google.golang.org/grpc" + "google.golang.org/grpc/test/bufconn" ) +func TestNew(t *testing.T) { + b := &server.BMPServer{} + s := New(b) + + expected := &APIServer{ + bmpServer: b, + } + + assert.Equal(t, expected, s) +} + func TestUpdateToRIBUpdate(t *testing.T) { tests := []struct { name string @@ -22,11 +44,11 @@ func TestUpdateToRIBUpdate(t *testing.T) { name: "Basics advert.", u: update{ advertisement: true, - route: route.NewRoute(net.NewPfx(net.IPv4(200), 8), &route.Path{ + route: route.NewRoute(bionet.NewPfx(bionet.IPv4(200), 8), &route.Path{ Type: route.BGPPathType, BGPPath: &route.BGPPath{ PathIdentifier: 10, - NextHop: net.IPv4(210), + NextHop: bionet.IPv4(210), LocalPref: 20, ASPath: types.ASPath{ { @@ -38,7 +60,7 @@ func TestUpdateToRIBUpdate(t *testing.T) { MED: 1000, EBGP: true, BGPIdentifier: 1337, - Source: net.IPv4(220), + Source: bionet.IPv4(220), Communities: []uint32{10000, 20000}, LargeCommunities: []types.LargeCommunity{ { @@ -130,3 +152,115 @@ func TestUpdateToRIBUpdate(t *testing.T) { assert.Equal(t, test.expected, res, test.name) } } + +type mockBMPServer struct { + RIB *locRIB.LocRIB +} + +func newmockBMPServer() *mockBMPServer { + return &mockBMPServer{ + RIB: locRIB.New(), + } +} + +func (m *mockBMPServer) SubscribeRIBs(client routingtable.RouteTableClient, rtr net.IP, afi uint8) { + m.RIB.Register(client) +} + +func (m *mockBMPServer) UnsubscribeRIBs(client routingtable.RouteTableClient, rtr net.IP, afi uint8) { + m.RIB.Unregister(client) +} + +func TestIntegration(t *testing.T) { + bmpSrv := newmockBMPServer() + apiSrv := New(bmpSrv) + + bufSize := 1024 * 1024 + lis := bufconn.Listen(bufSize) + s := grpc.NewServer() + pb.RegisterRIBServiceServer(s, apiSrv) + go func() { + if err := s.Serve(lis); err != nil { + log.Fatalf("Server exited with error: %v", err) + } + }() + + ctx := context.Background() + + conn, err := grpc.DialContext(ctx, "bufnet", grpc.WithDialer(func(string, time.Duration) (net.Conn, error) { + return lis.Dial() + }), grpc.WithInsecure()) + if err != nil { + t.Fatalf("Failed to dial bufnet: %v", err) + } + defer conn.Close() + + var wg sync.WaitGroup + wg.Add(1) + go func() { + bmpSrv.RIB.AddPath(bionet.NewPfx(bionet.IPv4FromOctets(169, 254, 0, 0), 24), &route.Path{ + Type: route.BGPPathType, + BGPPath: &route.BGPPath{ + LocalPref: 1337, + NextHop: bionet.IPv4FromOctets(10, 0, 0, 1), + Source: bionet.IPv4FromOctets(10, 0, 0, 2), + }, + }) + wg.Done() + }() + + client := pb.NewRIBServiceClient(conn) + streamClient, err := client.AdjRIBInStream(ctx, &pb.AdjRIBInStreamRequest{ + Router: bionet.IPv4FromOctets(10, 0, 0, 1).ToProto(), + }) + if err != nil { + t.Fatalf("AdjRIBInStream client call failed: %v", err) + } + + wg.Add(1) + go func() { + fmt.Printf("Waiting for stream receive to return\n") + update, err := streamClient.Recv() + if err != nil { + t.Fatalf("Recv failed: %v", err) + } + + expected := &pb.RIBUpdate{ + Advertisement: true, + Peer: &apinet.IP{ + Lower: 167772162, + Version: apinet.IP_IPv4, + }, + Route: &apiroute.Route{ + Pfx: &apinet.Prefix{ + Address: &apinet.IP{ + Lower: 2851995648, + Version: apinet.IP_IPv4, + }, + Pfxlen: 24, + }, + Paths: []*apiroute.Path{ + { + Type: apiroute.Path_BGP, + BGPPath: &apiroute.BGPPath{ + LocalPref: 1337, + NextHop: &apinet.IP{ + Version: apinet.IP_IPv4, + Lower: 167772161, + }, + Source: &apinet.IP{ + Version: apinet.IP_IPv4, + Lower: 167772162, + }, + }, + }, + }, + }, + } + + assert.Equal(t, expected, update) + wg.Done() + }() + + wg.Wait() +} diff --git a/protocols/bgp/server/bmp_server.go b/protocols/bgp/server/bmp_server.go index d49355ee..1fe83080 100644 --- a/protocols/bgp/server/bmp_server.go +++ b/protocols/bgp/server/bmp_server.go @@ -93,7 +93,7 @@ func (b *BMPServer) AddRouter(addr net.IP, port uint16, rib4 *locRIB.LocRIB, rib defer b.gloablMu.Unlock() r := newRouter(addr, port, rib4, rib6) - b.routers[fmt.Sprintf("%s", r.address.String())] = r + b.routers[r.address.String()] = r go func(r *router) { for { -- GitLab