diff --git a/cli/grpc.go b/cli/grpc.go index efe7c20d3c54c5f5e8dedec2b068a496a80ec2cd..3293fe25cc2746fcb10287d269172d2d9675ca1f 100644 --- a/cli/grpc.go +++ b/cli/grpc.go @@ -168,7 +168,7 @@ func commitConfirm(addr, pnd string, changes []*ppb.SetChange) (*ppb.SetResponse // AddDevice adds a new device to the controller. The device name is optional. // If no name is provided a name will be generated upon device creation. -func AddDevice(addr, username, password, pnd, deviceAddress, deviceName string, sbi spb.Type) error { +func AddDevice(addr, username, password, sbi, pnd, deviceAddress, deviceName string) error { pndClient, err := nbi.PndClient(addr, grpcWithInsecure) if err != nil { return err @@ -180,13 +180,16 @@ func AddDevice(addr, username, password, pnd, deviceAddress, deviceName string, { Address: deviceAddress, Sbi: &spb.SouthboundInterface{ - Type: sbi, + Id: sbi, }, DeviceName: deviceName, TransportOption: &tpb.TransportOption{ Address: addr, Username: username, Password: password, + TransportOption: &tpb.TransportOption_GnmiTransportOption{ + GnmiTransportOption: &tpb.GnmiTransportOption{}, + }, }, }, }, @@ -196,6 +199,8 @@ func AddDevice(addr, username, password, pnd, deviceAddress, deviceName string, resp, err := pndClient.Set(ctx, req) if err != nil { return err + } else if resp.Status != ppb.SetResponse_OK { + log.Error(resp.Status) } log.Info(resp.String()) return nil @@ -211,7 +216,7 @@ func GetDevice(addr, pid, path string, did ...string) (*ppb.GetResponse, error) } var all bool - if len(did) != 0 { + if len(did) == 0 { all = true } diff --git a/cli/grpc_test.go b/cli/grpc_test.go index 2faf56cb4f023d027dba02e6ed9db6b11bbf63ad..6ed2dcc6e97d0ad36b3707938611fc6bff48dcf6 100644 --- a/cli/grpc_test.go +++ b/cli/grpc_test.go @@ -6,14 +6,15 @@ import ( "reflect" "strconv" "testing" - "time" pb "code.fbi.h-da.de/cocsn/api/go/gosdn/core" ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd" spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound" + "code.fbi.h-da.de/cocsn/gosdn/forks/google/gnmi" nbi "code.fbi.h-da.de/cocsn/gosdn/northbound/server" "code.fbi.h-da.de/cocsn/gosdn/nucleus" "github.com/google/uuid" + "github.com/openconfig/ygot/ygot" log "github.com/sirupsen/logrus" "google.golang.org/grpc" "k8s.io/apimachinery/pkg/util/rand" @@ -27,83 +28,59 @@ const testPid = "06aa4994-80f7-4751-99a4-6826b72d0057" const testCuid = "cf628f4b-393d-44a5-affb-949dfe5c3c27" const testDid = "1c37ff20-0169-44e0-bf37-b64787a979d5" -func startGrpcServer() (*grpc.Server, string, error) { +func startGrpcServer() (*grpc.Server, string, string, error) { port := rand.IntnRange(1025, 65536) sock := "localhost:" + strconv.Itoa(port) pndc := nucleus.NewPndStore() pid, err := uuid.Parse(testPid) if err != nil { - return nil, "", err + return nil, "", "", err } - pnd, err := nucleus.NewPND("testpnd", "test pnd", pid, nil) + sbi := nucleus.NewSBI(spb.Type_OPENCONFIG) + pnd, err := nucleus.NewPND("testpnd", "test pnd", pid, sbi) if err != nil { - return nil, "", err + return nil, "", "", err } if err := pndc.Add(pnd); err != nil { - return nil, "", err + return nil, "", "", err } + lis, err := net.Listen("tcp", sock) if err != nil { - return nil, "", err + return nil, "", "", err } grpcServer := grpc.NewServer() northbound := nbi.NewNBI(pndc) pb.RegisterCoreServer(grpcServer, northbound.Core) ppb.RegisterPndServer(grpcServer, northbound.Pnd) go func() { - log.Fatal(grpcServer.Serve(lis)) + if err := grpcServer.Serve(lis); err != nil { + log.Fatal(err) + } }() - return grpcServer, sock, nil + return grpcServer, sock, sbi.ID().String(), nil } func TestAddDevice(t *testing.T) { type args struct { + addr string username string password string + sbi string pnd string - deviceName string deviceAddress string - sbi spb.Type + deviceName string } tests := []struct { name string args args wantErr bool }{ - { - name: "default", - args: args{ - username: testUser, - password: testPassword, - pnd: testPid, - deviceName: "testDevice", - sbi: spb.Type_OPENCONFIG, - }, - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } - return - } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable - } - if err := AddDevice( - sock, - tt.args.username, - tt.args.password, - tt.args.pnd, - tt.args.deviceName, - tt.args.deviceAddress, - tt.args.sbi, - ); (err != nil) != tt.wantErr { + if err := AddDevice(tt.args.addr, tt.args.username, tt.args.password, tt.args.sbi, tt.args.pnd, tt.args.deviceAddress, tt.args.deviceName); (err != nil) != tt.wantErr { t.Errorf("AddDevice() error = %v, wantErr %v", err, tt.wantErr) } }) @@ -112,6 +89,7 @@ func TestAddDevice(t *testing.T) { func TestAddPnd(t *testing.T) { type args struct { + addr string name string description string sbi string @@ -121,81 +99,61 @@ func TestAddPnd(t *testing.T) { args args wantErr bool }{ - { - name: "default", - args: args{ - name: "test", - description: "test", - sbi: "openconfig", - }, - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } - return - } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable - } - if err := AddPnd(sock, tt.args.name, tt.args.description, tt.args.sbi); (err != nil) != tt.wantErr { + if err := AddPnd(tt.args.addr, tt.args.name, tt.args.description, tt.args.sbi); (err != nil) != tt.wantErr { t.Errorf("AddPnd() error = %v, wantErr %v", err, tt.wantErr) } }) } } +func TestCapabilities(t *testing.T) { + type args struct { + a string + u string + p string + } + tests := []struct { + name string + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := Capabilities(tt.args.a, tt.args.u, tt.args.p); (err != nil) != tt.wantErr { + t.Errorf("Capabilities() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + func TestCommit(t *testing.T) { type args struct { + addr string pnd string cuids []string } tests := []struct { name string args args - want ppb.SetResponseStatus + want *ppb.SetResponse wantErr bool }{ - { - name: "default", - args: args{ - pnd: testPid, - cuids: []string{ - testCuid, - }, - }, - want: ppb.SetResponse_OK, - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } - return - } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable - } - - got, err := Commit(sock, tt.args.pnd, tt.args.cuids...) - if err != nil { - if !tt.wantErr { - t.Errorf("Commit() error = %v, wantErr %v", err, tt.wantErr) - } + got, err := Commit(tt.args.addr, tt.args.pnd, tt.args.cuids...) + if (err != nil) != tt.wantErr { + t.Errorf("Commit() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got.Status, tt.want) { + if !reflect.DeepEqual(got, tt.want) { t.Errorf("Commit() got = %v, want %v", got, tt.want) } }) @@ -204,49 +162,26 @@ func TestCommit(t *testing.T) { func TestConfirm(t *testing.T) { type args struct { + addr string pnd string cuids []string } tests := []struct { name string args args - want ppb.SetResponseStatus + want *ppb.SetResponse wantErr bool }{ - { - name: "default", - args: args{ - pnd: testPid, - cuids: []string{ - testCuid, - }, - }, - want: ppb.SetResponse_OK, - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } - return - } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable - } - - got, err := Confirm(sock, tt.args.pnd, tt.args.cuids...) - if err != nil { - if !tt.wantErr { - t.Errorf("Confirm() error = %v, wantErr %v", err, tt.wantErr) - } + got, err := Confirm(tt.args.addr, tt.args.pnd, tt.args.cuids...) + if (err != nil) != tt.wantErr { + t.Errorf("Confirm() error = %v, wantErr %v", err, tt.wantErr) return } - if !reflect.DeepEqual(got.Status, tt.want) { + if !reflect.DeepEqual(got, tt.want) { t.Errorf("Confirm() got = %v, want %v", got, tt.want) } }) @@ -255,6 +190,7 @@ func TestConfirm(t *testing.T) { func TestDelete(t *testing.T) { type args struct { + addr string did string pid string path string @@ -262,35 +198,14 @@ func TestDelete(t *testing.T) { tests := []struct { name string args args - want ppb.SetResponseStatus + want *ppb.SetResponse wantErr bool }{ - { - name: "default", - args: args{ - did: "", - pid: "", - path: "", - }, - want: ppb.SetResponse_OK, - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } - return - } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable - } - - got, err := Delete(sock, tt.args.did, tt.args.pid, tt.args.path) + got, err := Delete(tt.args.addr, tt.args.did, tt.args.pid, tt.args.path) if (err != nil) != tt.wantErr { t.Errorf("Delete() error = %v, wantErr %v", err, tt.wantErr) return @@ -304,7 +219,8 @@ func TestDelete(t *testing.T) { func TestGetChanges(t *testing.T) { type args struct { - pnd string + addr string + pnd string } tests := []struct { name string @@ -312,36 +228,11 @@ func TestGetChanges(t *testing.T) { want *ppb.GetResponse wantErr bool }{ - { - name: "default", - args: args{ - pnd: testPid, - }, - want: &ppb.GetResponse{ - Timestamp: time.Now().UnixNano(), - Pnd: &ppb.PrincipalNetworkDomain{}, - Ond: nil, - Sbi: nil, - Change: nil, - }, - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } - return - } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable - } - - got, err := GetChanges(sock, tt.args.pnd) + got, err := GetChanges(tt.args.addr, tt.args.pnd) if (err != nil) != tt.wantErr { t.Errorf("GetChanges() error = %v, wantErr %v", err, tt.wantErr) return @@ -355,6 +246,7 @@ func TestGetChanges(t *testing.T) { func TestGetDevice(t *testing.T) { type args struct { + addr string pid string path string did []string @@ -365,42 +257,11 @@ func TestGetDevice(t *testing.T) { want *ppb.GetResponse wantErr bool }{ - { - name: "default", - args: args{ - pid: testPid, - path: testPath, - did: []string{testDid}, - }, - want: &ppb.GetResponse{ - Timestamp: time.Now().UnixNano(), - Ond: []*ppb.OrchestratedNetworkingDevice{ - { - Id: testDid, - Name: "testOnd", - Device: nil, - Sbi: nil, - }, - }, - }, - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } - return - } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable - } - - got, err := GetDevice(sock, tt.args.pid, tt.args.path, tt.args.did...) + got, err := GetDevice(tt.args.addr, tt.args.pid, tt.args.path, tt.args.did...) if (err != nil) != tt.wantErr { t.Errorf("GetDevice() error = %v, wantErr %v", err, tt.wantErr) return @@ -413,38 +274,20 @@ func TestGetDevice(t *testing.T) { } func TestGetIds(t *testing.T) { + type args struct { + addr string + } tests := []struct { name string + args args want []*ppb.PrincipalNetworkDomain wantErr bool }{ - { - name: "default", - want: []*ppb.PrincipalNetworkDomain{ - { - Id: testPid, - Name: "testPnd", - Description: "testPnd", - }, - }, - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } - return - } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable - } - - got, err := GetIds(sock) + got, err := GetIds(tt.args.addr) if (err != nil) != tt.wantErr { t.Errorf("GetIds() error = %v, wantErr %v", err, tt.wantErr) return @@ -458,6 +301,7 @@ func TestGetIds(t *testing.T) { func TestGetPnd(t *testing.T) { type args struct { + addr string args []string } tests := []struct { @@ -466,37 +310,11 @@ func TestGetPnd(t *testing.T) { want *pb.GetResponse wantErr bool }{ - { - name: "default", - args: args{args: []string{testPid}}, - want: &pb.GetResponse{ - Timestamp: time.Now().UnixNano(), - Pnd: []*ppb.PrincipalNetworkDomain{ - { - Id: testPid, - Name: "testPnd", - Description: "testPnd", - }, - }, - }, - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } - return - } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable - } - - got, err := GetPnd(sock, tt.args.args...) + got, err := GetPnd(tt.args.addr, tt.args.args...) if (err != nil) != tt.wantErr { t.Errorf("GetPnd() error = %v, wantErr %v", err, tt.wantErr) return @@ -509,30 +327,19 @@ func TestGetPnd(t *testing.T) { } func TestInit(t *testing.T) { + type args struct { + addr string + } tests := []struct { name string + args args wantErr bool }{ - { - name: "default", - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } - return - } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable - } - - if err := Init(sock); (err != nil) != tt.wantErr { + if err := Init(tt.args.addr); (err != nil) != tt.wantErr { t.Errorf("Init() error = %v, wantErr %v", err, tt.wantErr) } }) @@ -541,6 +348,7 @@ func TestInit(t *testing.T) { func TestReplace(t *testing.T) { type args struct { + addr string did string pid string path string @@ -552,36 +360,11 @@ func TestReplace(t *testing.T) { want *ppb.SetResponse wantErr bool }{ - { - name: "default", - args: args{ - did: testDid, - pid: testPid, - path: testPath, - value: "ceos3000", - }, - want: &ppb.SetResponse{ - Timestamp: time.Now().UnixNano(), - Status: ppb.SetResponse_OK, - }, - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } - return - } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable - } - - got, err := Replace(sock, tt.args.did, tt.args.pid, tt.args.path, tt.args.value) + got, err := Replace(tt.args.addr, tt.args.did, tt.args.pid, tt.args.path, tt.args.value) if (err != nil) != tt.wantErr { t.Errorf("Replace() error = %v, wantErr %v", err, tt.wantErr) return @@ -593,8 +376,55 @@ func TestReplace(t *testing.T) { } } +func TestSubscribe(t *testing.T) { + type args struct { + address string + username string + password string + deviceName string + sample int64 + heartbeat int64 + args []string + } + tests := []struct { + name string + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := Subscribe(tt.args.address, tt.args.username, tt.args.password, tt.args.deviceName, tt.args.sample, tt.args.heartbeat, tt.args.args...); (err != nil) != tt.wantErr { + t.Errorf("Subscribe() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestTarget(t *testing.T) { + type args struct { + bindAddr string + } + tests := []struct { + name string + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := Target(tt.args.bindAddr); (err != nil) != tt.wantErr { + t.Errorf("Target() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + func TestUpdate(t *testing.T) { type args struct { + addr string did string pid string path string @@ -606,36 +436,11 @@ func TestUpdate(t *testing.T) { want *ppb.SetResponse wantErr bool }{ - { - name: "default", - args: args{ - did: testDid, - pid: testPid, - path: testPath, - value: "ceos3000", - }, - want: &ppb.SetResponse{ - Timestamp: time.Now().UnixNano(), - Status: ppb.SetResponse_OK, - }, - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } - return - } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable - } - - got, err := Update(sock, tt.args.did, tt.args.pid, tt.args.path, tt.args.value) + got, err := Update(tt.args.addr, tt.args.did, tt.args.pid, tt.args.path, tt.args.value) if (err != nil) != tt.wantErr { t.Errorf("Update() error = %v, wantErr %v", err, tt.wantErr) return @@ -647,8 +452,29 @@ func TestUpdate(t *testing.T) { } } +func Test_callback(t *testing.T) { + type args struct { + newConfig ygot.ValidatedGoStruct + } + tests := []struct { + name string + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := callback(tt.args.newConfig); (err != nil) != tt.wantErr { + t.Errorf("callback() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + func Test_commitConfirm(t *testing.T) { type args struct { + addr string pnd string changes []*ppb.SetChange } @@ -658,39 +484,11 @@ func Test_commitConfirm(t *testing.T) { want *ppb.SetResponse wantErr bool }{ - { - name: "default", - args: args{ - pnd: testPid, - changes: []*ppb.SetChange{ - { - Cuid: testCuid, - Op: ppb.SetChange_COMMIT, - }, - }, - }, - want: &ppb.SetResponse{ - Timestamp: time.Now().UnixNano(), - Status: ppb.SetResponse_OK, - }, - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } - return - } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable - } - - got, err := commitConfirm(sock, tt.args.pnd, tt.args.changes) + got, err := commitConfirm(tt.args.addr, tt.args.pnd, tt.args.changes) if (err != nil) != tt.wantErr { t.Errorf("commitConfirm() error = %v, wantErr %v", err, tt.wantErr) return @@ -703,48 +501,54 @@ func Test_commitConfirm(t *testing.T) { } func Test_getAllCore(t *testing.T) { + type args struct { + ctx context.Context + addr string + } tests := []struct { name string + args args want *pb.GetResponse wantErr bool }{ - { - name: "default", - want: &pb.GetResponse{ - Timestamp: time.Now().UnixNano(), - Pnd: []*ppb.PrincipalNetworkDomain{ - { - Id: testPid, - Name: "testPnd", - Description: "testPnd", - }, - }, - }, - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } + got, err := getAllCore(tt.args.ctx, tt.args.addr) + if (err != nil) != tt.wantErr { + t.Errorf("getAllCore() error = %v, wantErr %v", err, tt.wantErr) return } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("getAllCore() got = %v, want %v", got, tt.want) } + }) + } +} - ctx := context.Background() - got, err := getAllCore(ctx, sock) +func Test_newServer(t *testing.T) { + type args struct { + model *gnmi.Model + config []byte + } + tests := []struct { + name string + args args + want *server + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := newServer(tt.args.model, tt.args.config) if (err != nil) != tt.wantErr { - t.Errorf("getAllCore() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("newServer() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("getAllCore() got = %v, want %v", got, tt.want) + t.Errorf("newServer() got = %v, want %v", got, tt.want) } }) } @@ -752,8 +556,9 @@ func Test_getAllCore(t *testing.T) { func Test_sendChangeRequest(t *testing.T) { type args struct { - pid string - req *ppb.ChangeRequest + addr string + pid string + req *ppb.ChangeRequest } tests := []struct { name string @@ -761,69 +566,51 @@ func Test_sendChangeRequest(t *testing.T) { want *ppb.SetResponse wantErr bool }{ - { - name: "update", - args: args{ - pid: testPid, - req: &ppb.ChangeRequest{ - Id: testCuid, - Path: testPath, - Value: "ceos3000", - ApiOp: ppb.ApiOperation_UPDATE, - }, - }, - want: nil, - wantErr: false, - }, - { - name: "replace", - args: args{ - pid: testPid, - req: &ppb.ChangeRequest{ - Id: testCuid, - Path: testPath, - Value: "ceos3000", - ApiOp: ppb.ApiOperation_REPLACE, - }, - }, - want: nil, - wantErr: false, - }, - { - name: "delete", - args: args{ - pid: testPid, - req: &ppb.ChangeRequest{ - Id: testCuid, - Path: testPath, - ApiOp: ppb.ApiOperation_DELETE, - }, - }, - want: nil, - wantErr: false, - }, + // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - server, sock, err := startGrpcServer() - if err != nil { - if !tt.wantErr { - t.Error("startGrpcServer() error = cannot start grpc server") - } + got, err := sendChangeRequest(tt.args.addr, tt.args.pid, tt.args.req) + if (err != nil) != tt.wantErr { + t.Errorf("sendChangeRequest() error = %v, wantErr %v", err, tt.wantErr) return } - defer server.Stop() - if tt.name == "unreachable" { - sock = unreachable + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("sendChangeRequest() got = %v, want %v", got, tt.want) } + }) + } +} - got, err := sendChangeRequest(sock, tt.args.pid, tt.args.req) +func Test_server_Get(t *testing.T) { + type fields struct { + Server *gnmi.Server + } + type args struct { + ctx context.Context + req *pb.GetRequest + } + tests := []struct { + name string + fields fields + args args + want *pb.GetResponse + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := &server{ + Server: tt.fields.Server, + } + got, err := s.Get(tt.args.ctx, tt.args.req) if (err != nil) != tt.wantErr { - t.Errorf("sendChangeRequest() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr) return } if !reflect.DeepEqual(got, tt.want) { - t.Errorf("sendChangeRequest() got = %v, want %v", got, tt.want) + t.Errorf("Get() got = %v, want %v", got, tt.want) } }) } diff --git a/cmd/addDevice.go b/cmd/addDevice.go index b35a2654a958f0edef80ba5eee7b48c63e49c8e0..cf6773b501f705b7d078e94d568abf76276c8177 100644 --- a/cmd/addDevice.go +++ b/cmd/addDevice.go @@ -32,8 +32,6 @@ POSSIBILITY OF SUCH DAMAGE. package cmd import ( - spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound" - "code.fbi.h-da.de/cocsn/gosdn/cli" "github.com/spf13/cobra" ) @@ -51,10 +49,10 @@ if they diverge from the default credentials.`, apiEndpoint, username, password, + cliSbi, cliPnd, address, deviceName, - spb.Type_OPENCONFIG, ) }, } diff --git a/controller.go b/controller.go index 0f5b4085ff4c49fdad703419cdcb262e57ad227b..c6a434178c9cf4b1c15c46e1d9c8ff4bb2d06289 100644 --- a/controller.go +++ b/controller.go @@ -74,7 +74,9 @@ func startGrpcServer() error { pb.RegisterCoreServer(c.grpcServer, c.nbi.Core) ppb.RegisterPndServer(c.grpcServer, c.nbi.Pnd) go func() { - log.Fatal(c.grpcServer.Serve(lis)) + if err := c.grpcServer.Serve(lis); err != nil { + log.Fatal(err) + } }() return nil } diff --git a/northbound/server/core.go b/northbound/server/core.go index 38686e444ede8086777ea1256b944c69013661fd..60de83baded00b37a2c2d84166913f5b18cc7c8f 100644 --- a/northbound/server/core.go +++ b/northbound/server/core.go @@ -6,6 +6,8 @@ import ( pb "code.fbi.h-da.de/cocsn/api/go/gosdn/core" ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd" + spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound" + "code.fbi.h-da.de/cocsn/gosdn/nucleus" "github.com/google/uuid" ) @@ -45,5 +47,19 @@ func (s core) Get(ctx context.Context, request *pb.GetRequest) (*pb.GetResponse, } func (s core) Set(ctx context.Context, request *pb.SetRequest) (*pb.SetResponse, error) { - panic("implement me") + for _, r := range request.Pnd { + sbi := nucleus.NewSBI(spb.Type_OPENCONFIG) + + pnd, err := nucleus.NewPND(r.Name, r.Description, uuid.New(), sbi) + if err != nil { + return nil, err + } + if err := pndc.Add(pnd); err != nil { + return nil, err + } + } + return &pb.SetResponse{ + Timestamp: time.Now().UnixNano(), + Status: pb.SetResponse_OK, + }, nil } diff --git a/northbound/server/nbi.go b/northbound/server/nbi.go index d5f69ce38d9a8f579203c7fee864da918916ee27..4e5ebd77344c58a3a883163ece457a3446a66635 100644 --- a/northbound/server/nbi.go +++ b/northbound/server/nbi.go @@ -6,7 +6,7 @@ import ( var pndc *nucleus.PndStore -// NewNBI receives a PndStore and returns a nre gRPC *NorthboundInterface +// NewNBI receives a PndStore and returns a new gRPC *NorthboundInterface func NewNBI(pnds *nucleus.PndStore) *NorthboundInterface { pndc = pnds return &NorthboundInterface{ diff --git a/northbound/server/pnd.go b/northbound/server/pnd.go index ea12031e1c71d292fe97c1ee488108ee5b2c65b6..29e06c1baed9c721319e78e173809786347c6461 100644 --- a/northbound/server/pnd.go +++ b/northbound/server/pnd.go @@ -46,6 +46,9 @@ func handleGetPnd(pid uuid.UUID) (*ppb.GetResponse, error) { return nil, err } sbis, err := fillSbis(pnd, true) + if err != nil { + return nil, err + } return &ppb.GetResponse{ Timestamp: time.Now().UnixNano(), Pnd: &ppb.PrincipalNetworkDomain{ @@ -65,6 +68,9 @@ func handleGetSbi(pid uuid.UUID, req *ppb.GetRequest_Sbi) (*ppb.GetResponse, err return nil, err } sbis, err := fillSbis(pnd, req.Sbi.GetAll(), req.Sbi.Sid...) + if err != nil { + return nil, err + } return &ppb.GetResponse{ Timestamp: time.Now().UnixNano(), Sbi: sbis, @@ -89,6 +95,9 @@ func handleGetOnd(pid uuid.UUID, req *ppb.GetRequest_Ond) (*ppb.GetResponse, err return nil, err } onds, err := fillOnds(pnd, req.Ond.All, req.Ond.Did...) + if err != nil { + return nil, err + } return &ppb.GetResponse{ Timestamp: time.Now().UnixNano(), Ond: onds, @@ -101,6 +110,9 @@ func handleGetChange(pid uuid.UUID, req *ppb.GetRequest_Change) (*ppb.GetRespons return nil, err } changes, err := fillChanges(pnd, req.Change.All, req.Change.Cuid...) + if err != nil { + return nil, err + } return &ppb.GetResponse{ Timestamp: time.Now().UnixNano(), Change: changes, @@ -228,29 +240,29 @@ func fillChanges(pnd nucleus.PrincipalNetworkDomain, all bool, cuid ...string) ( func (p pnd) Set(ctx context.Context, request *ppb.SetRequest) (*ppb.SetResponse, error) { pid, err := uuid.Parse(request.Pid) if err != nil { - return nil, err + return handleSetError(), err } pnd, err := pndc.Get(pid) if err != nil { - return nil, err + return handleSetError(), err } ondResp, err := handleSetOnd(pnd, request.Ond) if err != nil { - return nil, err + return handleSetError(), err } sbiResp, err := handleSetSbi(pnd, request.Sbi) if err != nil { - return nil, err + return handleSetError(), err } changeResp, err := handleSetChange(pnd, request.Change) if err != nil { - return nil, err + return handleSetError(), err } changeRequestResp, err := handleChangeRequest(pnd, request.ChangeRequest) if err != nil { - return nil, err + return handleSetError(), err } return &ppb.SetResponse{ Timestamp: time.Now().UnixNano(), @@ -268,10 +280,10 @@ func handleSetOnd(pnd nucleus.PrincipalNetworkDomain, req []*ppb.SetOnd) (*ppb.S for _, r := range req { sid, err := uuid.Parse(r.Sbi.Id) if err != nil { - return nil, err + return handleSetError(), err } if err := pnd.AddDevice(r.DeviceName, r.TransportOption, sid); err != nil { - return nil, err + return handleSetError(), err } } return &ppb.SetResponse{ @@ -291,16 +303,16 @@ func handleSetChange(pnd nucleus.PrincipalNetworkDomain, req []*ppb.SetChange) ( for _, r := range req { cuid, err := uuid.Parse(r.Cuid) if err != nil { - return nil, err + return handleSetError(), err } switch r.Op { case ppb.SetChange_COMMIT: if err := pnd.Commit(cuid); err != nil { - return nil, err + return handleSetError(), err } case ppb.SetChange_CONFIRM: if err := pnd.Confirm(cuid); err != nil { - return nil, err + return handleSetError(), err } default: return nil, &errors.ErrInvalidParameters{ @@ -319,10 +331,10 @@ func handleChangeRequest(pnd nucleus.PrincipalNetworkDomain, req []*ppb.ChangeRe for _, r := range req { did, err := uuid.Parse(r.Id) if err != nil { - return nil, err + return handleSetError(), err } if err := pnd.ChangeOND(did, r.ApiOp, r.Path, r.Value); err != nil { - return nil, err + return handleSetError(), err } } return &ppb.SetResponse{ @@ -330,3 +342,10 @@ func handleChangeRequest(pnd nucleus.PrincipalNetworkDomain, req []*ppb.ChangeRe Status: ppb.SetResponse_OK, }, nil } + +func handleSetError() *ppb.SetResponse { + return &ppb.SetResponse{ + Timestamp: time.Now().UnixNano(), + Status: ppb.SetResponse_ERROR, + } +} diff --git a/northbound/server/server_test.go b/northbound/server/server_test.go new file mode 100644 index 0000000000000000000000000000000000000000..5f509d72e05434228d2cce9b6d61a560b4b086f1 --- /dev/null +++ b/northbound/server/server_test.go @@ -0,0 +1,520 @@ +package server + +import ( + "context" + "reflect" + "testing" + + pb "code.fbi.h-da.de/cocsn/api/go/gosdn/core" + ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd" + spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound" + "code.fbi.h-da.de/cocsn/gosdn/nucleus" + "github.com/google/uuid" +) + +func TestNewNBI(t *testing.T) { + pndc := nucleus.NewPndStore() + type args struct { + pnds *nucleus.PndStore + } + tests := []struct { + name string + args args + want *NorthboundInterface + }{ + { + name: "default", + args: args{ + pnds: pndc, + }, + want: &NorthboundInterface{ + Pnd: &pnd{}, + Core: &core{}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := NewNBI(tt.args.pnds); !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewNBI() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_core_Get(t *testing.T) { + type fields struct { + UnimplementedCoreServer pb.UnimplementedCoreServer + } + type args struct { + ctx context.Context + request *pb.GetRequest + } + tests := []struct { + name string + fields fields + args args + want *pb.GetResponse + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := core{ + UnimplementedCoreServer: tt.fields.UnimplementedCoreServer, + } + got, err := s.Get(tt.args.ctx, tt.args.request) + if (err != nil) != tt.wantErr { + t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Get() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_core_Set(t *testing.T) { + type fields struct { + UnimplementedCoreServer pb.UnimplementedCoreServer + } + type args struct { + ctx context.Context + request *pb.SetRequest + } + tests := []struct { + name string + fields fields + args args + want *pb.SetResponse + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := core{ + UnimplementedCoreServer: tt.fields.UnimplementedCoreServer, + } + got, err := s.Set(tt.args.ctx, tt.args.request) + if (err != nil) != tt.wantErr { + t.Errorf("Set() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Set() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_fillChanges(t *testing.T) { + type args struct { + pnd nucleus.PrincipalNetworkDomain + all bool + cuid []string + } + tests := []struct { + name string + args args + want []*ppb.Change + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := fillChanges(tt.args.pnd, tt.args.all, tt.args.cuid...) + if (err != nil) != tt.wantErr { + t.Errorf("fillChanges() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("fillChanges() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_fillOnds(t *testing.T) { + type args struct { + pnd nucleus.PrincipalNetworkDomain + all bool + did []string + } + tests := []struct { + name string + args args + want []*ppb.OrchestratedNetworkingDevice + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := fillOnds(tt.args.pnd, tt.args.all, tt.args.did...) + if (err != nil) != tt.wantErr { + t.Errorf("fillOnds() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("fillOnds() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_fillSbis(t *testing.T) { + type args struct { + pnd nucleus.PrincipalNetworkDomain + all bool + sid []string + } + tests := []struct { + name string + args args + want []*spb.SouthboundInterface + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := fillSbis(tt.args.pnd, tt.args.all, tt.args.sid...) + if (err != nil) != tt.wantErr { + t.Errorf("fillSbis() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("fillSbis() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_handleChangeRequest(t *testing.T) { + type args struct { + pnd nucleus.PrincipalNetworkDomain + req []*ppb.ChangeRequest + } + tests := []struct { + name string + args args + want *ppb.SetResponse + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := handleChangeRequest(tt.args.pnd, tt.args.req) + if (err != nil) != tt.wantErr { + t.Errorf("handleChangeRequest() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("handleChangeRequest() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_handleGetChange(t *testing.T) { + type args struct { + pid uuid.UUID + req *ppb.GetRequest_Change + } + tests := []struct { + name string + args args + want *ppb.GetResponse + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := handleGetChange(tt.args.pid, tt.args.req) + if (err != nil) != tt.wantErr { + t.Errorf("handleGetChange() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("handleGetChange() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_handleGetOnd(t *testing.T) { + type args struct { + pid uuid.UUID + req *ppb.GetRequest_Ond + } + tests := []struct { + name string + args args + want *ppb.GetResponse + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := handleGetOnd(tt.args.pid, tt.args.req) + if (err != nil) != tt.wantErr { + t.Errorf("handleGetOnd() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("handleGetOnd() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_handleGetPnd(t *testing.T) { + type args struct { + pid uuid.UUID + } + tests := []struct { + name string + args args + want *ppb.GetResponse + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := handleGetPnd(tt.args.pid) + if (err != nil) != tt.wantErr { + t.Errorf("handleGetPnd() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("handleGetPnd() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_handleGetSbi(t *testing.T) { + type args struct { + pid uuid.UUID + req *ppb.GetRequest_Sbi + } + tests := []struct { + name string + args args + want *ppb.GetResponse + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := handleGetSbi(tt.args.pid, tt.args.req) + if (err != nil) != tt.wantErr { + t.Errorf("handleGetSbi() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("handleGetSbi() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_handleSetChange(t *testing.T) { + type args struct { + pnd nucleus.PrincipalNetworkDomain + req []*ppb.SetChange + } + tests := []struct { + name string + args args + want *ppb.SetResponse + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := handleSetChange(tt.args.pnd, tt.args.req) + if (err != nil) != tt.wantErr { + t.Errorf("handleSetChange() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("handleSetChange() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_handleSetError(t *testing.T) { + tests := []struct { + name string + want *ppb.SetResponse + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := handleSetError(); !reflect.DeepEqual(got, tt.want) { + t.Errorf("handleSetError() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_handleSetOnd(t *testing.T) { + type args struct { + pnd nucleus.PrincipalNetworkDomain + req []*ppb.SetOnd + } + tests := []struct { + name string + args args + want *ppb.SetResponse + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := handleSetOnd(tt.args.pnd, tt.args.req) + if (err != nil) != tt.wantErr { + t.Errorf("handleSetOnd() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("handleSetOnd() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_handleSetSbi(t *testing.T) { + type args struct { + pnd nucleus.PrincipalNetworkDomain + req []*ppb.SetSbi + } + tests := []struct { + name string + args args + want *ppb.SetResponse + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := handleSetSbi(tt.args.pnd, tt.args.req) + if (err != nil) != tt.wantErr { + t.Errorf("handleSetSbi() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("handleSetSbi() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_pnd_Get(t *testing.T) { + type fields struct { + UnimplementedPndServer ppb.UnimplementedPndServer + } + type args struct { + ctx context.Context + request *ppb.GetRequest + } + tests := []struct { + name string + fields fields + args args + want *ppb.GetResponse + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := pnd{ + UnimplementedPndServer: tt.fields.UnimplementedPndServer, + } + got, err := p.Get(tt.args.ctx, tt.args.request) + if (err != nil) != tt.wantErr { + t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Get() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_pnd_Set(t *testing.T) { + type fields struct { + UnimplementedPndServer ppb.UnimplementedPndServer + } + type args struct { + ctx context.Context + request *ppb.SetRequest + } + tests := []struct { + name string + fields fields + args args + want *ppb.SetResponse + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := pnd{ + UnimplementedPndServer: tt.fields.UnimplementedPndServer, + } + got, err := p.Set(tt.args.ctx, tt.args.request) + if (err != nil) != tt.wantErr { + t.Errorf("Set() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Set() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_stringToUUID(t *testing.T) { + type args struct { + sid []string + } + tests := []struct { + name string + args args + want []uuid.UUID + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := stringToUUID(tt.args.sid) + if (err != nil) != tt.wantErr { + t.Errorf("stringToUUID() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("stringToUUID() got = %v, want %v", got, tt.want) + } + }) + } +}