Skip to content

Commit

Permalink
Add support for the OTG GetConfig RPC. (#52)
Browse files Browse the repository at this point in the history
* Add support for the OTG `GetConfig` RPC.

 * (M) lwotg/lwotg(_test)?.go
   - This change adds support for the `GetConfig` OTG RPC, which simply
     returns the current configuration.

* Address review comments.
  • Loading branch information
robshakir authored Feb 6, 2024
1 parent d4c8638 commit 0e9dcc9
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
12 changes: 12 additions & 0 deletions lwotg/lwotg.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/openconfig/magna/intf"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
"k8s.io/klog/v2"
)

Expand Down Expand Up @@ -182,6 +183,17 @@ func (s *Server) SetConfig(ctx context.Context, req *otg.SetConfigRequest) (*otg
return &otg.SetConfigResponse{}, nil
}

// GetConfig retrieves the current OTG configuration from the lwotg instance, implementing the GetConfig
// RPC.
func (s *Server) GetConfig(_ context.Context, _ *emptypb.Empty) (*otg.GetConfigResponse, error) {
if s.cfg == nil {
return nil, status.Errorf(codes.NotFound, "no configuration has been specified")
}
return &otg.GetConfigResponse{
Config: s.cfg,
}, nil
}

// setTrafficGenFns sets the functions that will be used to generate traffic
// for the flows within the configuration.
func (s *Server) setTrafficGenFns(fns []*TXRXWrapper) {
Expand Down
67 changes: 67 additions & 0 deletions lwotg/lwotg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/testing/protocmp"
"google.golang.org/protobuf/types/known/emptypb"
)

func TestSetControlState(t *testing.T) {
Expand Down Expand Up @@ -338,3 +339,69 @@ func TestSetConfig(t *testing.T) {
})
}
}

func newServerAndClient(t *testing.T, lw *Server) otg.OpenapiClient {
t.Helper()

l, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatalf("cannot listen, %v", err)
}
t.Cleanup(func() { l.Close() })

s := grpc.NewServer(grpc.Creds(insecure.NewCredentials()))
otg.RegisterOpenapiServer(s, lw)
go s.Serve(l)
t.Cleanup(s.Stop)

conn, err := grpc.Dial(l.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
t.Fatalf("cannot dial server %s, err: %v", l.Addr().String(), err)
}
c := otg.NewOpenapiClient(conn)
return c
}

func TestGetConfig(t *testing.T) {
tests := []struct {
desc string
inInitialConfig *otg.Config
wantResponse *otg.GetConfigResponse
wantErr bool
}{{
desc: "no input config",
wantErr: true,
}, {
desc: "specified configuration",
inInitialConfig: &otg.Config{
Ports: []*otg.Port{{
Name: proto.String("port-one"),
}},
},
wantResponse: &otg.GetConfigResponse{
Config: &otg.Config{
Ports: []*otg.Port{{
Name: proto.String("port-one"),
}},
},
},
}}

for _, tt := range tests {
t.Run(tt.desc, func(t *testing.T) {
lw := New()
lw.cfg = tt.inInitialConfig

c := newServerAndClient(t, lw)

got, err := c.GetConfig(context.Background(), &emptypb.Empty{})
if (err != nil) != tt.wantErr {
t.Fatalf("GetConfig(): did not get expected error, got: %v, wantErr? %v", got, tt.wantErr)
}

if diff := cmp.Diff(got, tt.wantResponse, protocmp.Transform()); diff != "" {
t.Fatalf("did not get expected result, diff(-got,+want):\n%s", diff)
}
})
}
}

0 comments on commit 0e9dcc9

Please sign in to comment.