Newer
Older
"io"
"code.fbi.h-da.de/danet/gosdn/api/go/gosdn/csbi"
cpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/csbi"
ppb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/pnd"
spb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/southbound"
tpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/transport"
"code.fbi.h-da.de/danet/gosdn/controller/conflict"
Fabian Seidl
committed
eventservice "code.fbi.h-da.de/danet/gosdn/controller/eventService"
eventInterfaces "code.fbi.h-da.de/danet/gosdn/controller/interfaces/event"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkdomain"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkelement"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/southbound"
"code.fbi.h-da.de/danet/gosdn/controller/mocks"
"code.fbi.h-da.de/danet/gosdn/controller/nucleus/util"
"code.fbi.h-da.de/danet/gosdn/controller/store"
"code.fbi.h-da.de/danet/gosdn/models/generated/openconfig"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/mock"
)
func TestNewPND(t *testing.T) {
type args struct {
name string
description string
}{
{
name: "default",
args: args{
name: "default",
description: "default test pnd",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewPND(tt.args.name, tt.args.description, tt.args.pid, nil, nil)
if (err != nil) != tt.wantErr {
t.Errorf("NewPND() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got.GetName() != tt.want.GetName() {
t.Errorf("NewPND.GetName() = %v, want %v", got, tt.want)
}
if got.ID() != tt.want.ID() {
t.Errorf("NewPND.ID() = %v, want %v", got, tt.want)
}
if got.GetDescription() != tt.want.GetDescription() {
t.Errorf("NewPND.GetDescription() = %v, want %v", got, tt.want)
}
})
}
}
func Test_destroy(t *testing.T) {
tests := []struct {
name string
wantErr bool
}{
{name: "dummy", wantErr: false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := destroy(); (err != nil) != tt.wantErr {
t.Errorf("destroy() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func Test_pndImplementation_AddNetworkElement(t *testing.T) {
name string
opts *tpb.TransportOption
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "default",
name: "fridolin",
opts: &tpb.TransportOption{
TransportOption: &tpb.TransportOption_GnmiTransportOption{
GnmiTransportOption: &tpb.GnmiTransportOption{},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil {
t.Error(err)
}
_, err := pnd.AddNetworkElement(tt.args.name, tt.args.opts, defaultSbiID)
if (err != nil) != tt.wantErr {
t.Errorf("AddNetworkElement() error = %v, wantErr %v", err, tt.wantErr)
if tt.name != "fails wrong type" {
if err == nil {
mne, err := pnd.networkElementService.Get(store.Query{Name: tt.args.name})
t.Errorf("AddNetworkElement() error = %v", err)
if mne.Name() != tt.args.name {
t.Errorf("AddNetworkElement() got = %v, want %v", mne.Name(), tt.args.name)
if err := pnd.networkElementService.Delete(mne); err != nil {
// TODO: refactor test to use store interface instead if direct access.
func Test_pndImplementation_AddSbi(t *testing.T) {
type args struct {
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "default",
args: args{
sbi: &OpenConfig{
},
},
wantErr: false,
},
// {
// name: "already exists",
// args: args{
// sbi: &OpenConfig{
// id: defaultSbiID,
// },
// },
// wantErr: true,
// },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := pnd.AddSbi(tt.args.sbi)
if (err != nil) != tt.wantErr {
t.Errorf("AddSbi() error = %v, wantErr %v", err, tt.wantErr)
if tt.name != "fails wrong type" {
if err == nil {
sbi, err := pnd.southboundService.Get(store.Query{ID: defaultSbiID})
if err != nil {
t.Errorf("AddSbi() SBI %v not in network element store %v",
tt.args.sbi, sbi)
if err := pnd.southboundService.Delete(sbi); err != nil {
})
}
}
func Test_pndImplementation_Destroy(t *testing.T) {
type fields struct {
name string
description string
sbi southbound.Service
networkElements networkelement.Service
}
tests := []struct {
name string
fields fields
wantErr bool
}{
{name: "dummy", fields: fields{}, wantErr: false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
pnd := &pndImplementation{
Name: tt.fields.name,
Description: tt.fields.description,
southboundService: tt.fields.sbi,
networkElementService: tt.fields.networkElements,
}
if err := pnd.Destroy(); (err != nil) != tt.wantErr {
t.Errorf("Destroy() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func Test_pndImplementation_GetDescription(t *testing.T) {
tests := []struct {
name string
want string
}{
{name: "default", want: "default test pnd"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := pnd.GetDescription(); got != tt.want {
t.Errorf("GetDescription() = %v, want %v", got, tt.want)
}
})
}
}
func Test_pndImplementation_GetName(t *testing.T) {
tests := []struct {
name string
want string
}{
{name: "default", want: "default"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := pnd.GetName(); got != tt.want {
t.Errorf("GetName() = %v, want %v", got, tt.want)
}
})
}
}
func Test_pndImplementation_MarshalNetworkElement(t *testing.T) {
type args struct {
uuid uuid.UUID
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
want: "{\n\t\"Acl\": null,\n\t\"Bfd\": null,\n\t\"Components\": null,\n\t\"Interfaces\": null,\n\t\"Keychains\": null,\n\t\"Lldp\": null,\n\t\"Messages\": null,\n\t\"NetworkInstances\": null,\n\t\"RoutingPolicy\": null,\n\t\"System\": null\n}",
args: args{mneid},
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sbi, err := NewSBI(spb.Type_TYPE_OPENCONFIG)
if err != nil {
t.Error("could not create sbi")
}
err = pnd.addSbi(sbi)
if err != nil {
t.Error("could not add sbi")
}
mne := &CommonNetworkElement{
_, err = pnd.addNetworkElement(mne)
got, err := pnd.MarshalNetworkElement(tt.args.uuid.String())
if (err != nil) != tt.wantErr {
t.Errorf("MarshalNetworkElement() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("MarshalNetworkElement() got = %v, want %v", got, tt.want)
if err := pnd.networkElementService.Delete(mne); err != nil {
func Test_pndImplementation_RemoveNetworkElement(t *testing.T) {
type args struct {
uuid uuid.UUID
}
tests := []struct {
name string
args args
wantErr bool
}{
{name: "default", args: args{uuid: mneid}, wantErr: false},
{name: "fails", args: args{uuid: uuid.New()}, wantErr: true},
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sbi, err := NewSBI(spb.Type_TYPE_OPENCONFIG)
if err != nil {
t.Error("could not create sbi")
}
err = pnd.addSbi(sbi)
if err != nil {
t.Error("could not add sbi")
}
mne := &CommonNetworkElement{
UUID: mneid,
Model: &openconfig.Device{},
sbi: sbi,
transport: nil,
}
_, err = pnd.addNetworkElement(mne)
if err := pnd.RemoveNetworkElement(tt.args.uuid); (err != nil) != tt.wantErr {
t.Errorf("RemoveNetworkElement() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func Test_pndImplementation_RemoveSbi(t *testing.T) {
type args struct {
id uuid.UUID
}
tests := []struct {
name string
args args
wantErr bool
}{
{name: "default", args: args{id: defaultSbiID}, wantErr: false},
{name: "fails", args: args{id: uuid.New()}, wantErr: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Fabian Seidl
committed
eventService := eventservice.NewMockEventService()
sbiStore := NewMemorySbiStore()
networkElementStore := NewMemoryNetworkElementStore()
Fabian Seidl
committed
sbiService := NewSbiService(sbiStore, eventService)
networkElementService := NewNetworkElementService(networkElementStore, sbiService, eventService)
pnd := &pndImplementation{
Name: "test-remove-sbi",
Description: "test-remove-sbi",
southboundService: sbiService,
networkElementService: networkElementService,
Id: defaultPndID,
}
sbi, err := NewSBI(spb.Type_TYPE_OPENCONFIG, defaultSbiID)
if err != nil {
t.Error("could not create sbi")
}
err = pnd.addSbi(sbi)
if err != nil {
t.Error("could not add sbi")
}
if err := pnd.RemoveSbi(tt.args.id); (err != nil) != tt.wantErr {
t.Errorf("RemoveSbi() error = %v, wantErr %v", err, tt.wantErr)
}
foundSbi, _ := pnd.southboundService.Get(store.Query{ID: tt.args.id})
if foundSbi != nil {
t.Errorf("RemoveSbi() SBI still in SBI store %v", pnd.southboundService)
if tt.name == "exclusively remove associated network elements" {
allNetworkElements, _ := pnd.networkElementService.GetAll()
if len(allNetworkElements) != 1 {
t.Errorf("RemoveSbi() non associated network elements should remain in the storage %v", allNetworkElements)
allNetworkElements, _ := pnd.networkElementService.GetAll()
if len(allNetworkElements) != 0 {
t.Errorf("RemoveSbi() associated network elements have not been removed correctly %v", len(allNetworkElements))
}
}
})
}
}
func Test_pndImplementation_RemoveSbiWithAssociatedNetworkElements(t *testing.T) {
opts := &tpb.TransportOption{
TransportOption: &tpb.TransportOption_GnmiTransportOption{
GnmiTransportOption: &tpb.GnmiTransportOption{},
},
}
}
tests := []struct {
name string
args args
wantErr bool
}{
{name: "exclusively remove associated network elements", args: args{id: defaultSbiID}, wantErr: false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Fabian Seidl
committed
eventService := eventservice.NewMockEventService()
sbiStore := NewMemorySbiStore()
networkElementStore := NewMemoryNetworkElementStore()
Fabian Seidl
committed
sbiService := NewSbiService(sbiStore, eventService)
networkElementService := NewNetworkElementService(networkElementStore, sbiService, eventService)
Name: "test-remove-sbi",
Description: "test-remove-sbi",
southboundService: sbiService,
networkElementService: networkElementService,
Id: defaultPndID,
sbi, err := NewSBI(spb.Type_TYPE_OPENCONFIG, defaultSbiID)
if err != nil {
t.Error("could not create sbi")
}
err = pnd.addSbi(sbi)
if err != nil {
t.Error("could not add sbi")
}
if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil {
t.Error(err)
}
_, err = pnd.AddNetworkElement("associatedNetworkElement", opts, tt.args.id)
t.Error(err)
}
_, err = pnd.AddNetworkElement("associatedNetworkElement2", opts, tt.args.id)
t.Error(err)
}
if tt.name == "exclusively remove associated network elements" {
newID := uuid.New()
if err := pnd.addSbi(&OpenConfig{id: newID}); err != nil {
t.Error(err)
}
_, err := pnd.AddNetworkElement("associatedNetworkElement2", opts, newID)
t.Error(err)
}
if err := pnd.RemoveSbi(tt.args.id); (err != nil) != tt.wantErr {
t.Errorf("RemoveSbi() error = %v, wantErr %v", err, tt.wantErr)
}
foundSbi, _ := pnd.southboundService.Get(store.Query{ID: tt.args.id})
if foundSbi != nil {
t.Errorf("RemoveSbi() SBI still in SBI store %v", pnd.southboundService)
}
if tt.name == "exclusively remove associated network elements" {
allNetworkElements, _ := pnd.southboundService.GetAll()
if len(allNetworkElements) != 1 {
t.Errorf("RemoveSbi() non associated network elements should remain in the storage %v", allNetworkElements)
}
} else {
allNetworkElements, _ := pnd.southboundService.GetAll()
if len(allNetworkElements) != 0 {
t.Errorf("RemoveSbi() associated network elements have not been removed correctly %v", len(allNetworkElements))
}
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
}
})
}
}
func Test_pndImplementation_Request(t *testing.T) {
type args struct {
uuid uuid.UUID
path string
rErr error
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "default",
args: args{
uuid: mdid,
path: "",
rErr: nil,
},
wantErr: false,
},
{
name: "error",
args: args{
uuid: mneid,
path: "",
rErr: errors.New("deliberate test fail"),
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sbiService := NewGenericService[southbound.SouthboundInterface]()
networkElementService := NewNetworkElementServiceMock()
pnd := pndImplementation{
Name: "default",
Description: "default test pnd",
southboundService: &sbiService,
networkElementService: networkElementService,
changes: store.NewChangeStore(),
Id: defaultPndID,
}
sbi, err := NewSBI(spb.Type_TYPE_OPENCONFIG)
if err != nil {
t.Error("could not create sbi")
}
err = pnd.addSbi(sbi)
if err != nil {
t.Error("could not add sbi")
}
transport := mocks.Transport{}
transport.On("Get", mockContext, mock.Anything).Return(&gpb.GetResponse{}, tt.args.rErr)
transport.On("ProcessResponse", mock.Anything, mock.Anything, mock.Anything).Return(tt.args.rErr)
networkElementWithMockTransport := &CommonNetworkElement{
UUID: mdid,
Model: &openconfig.Device{},
sbi: sbi,
transport: &transport,
}
_, _ = pnd.addNetworkElement(networkElementWithMockTransport)
_, err = pnd.Request(tt.args.uuid, tt.args.path)
if (err != nil) != tt.wantErr {
t.Errorf("Request() error = %v, wantErr %v", err, tt.wantErr)
}
mne, _ := pnd.networkElementService.Get(store.Query{ID: mdid})
if mne == nil {
return
}
if err := pnd.networkElementService.Delete(mne); err != nil {
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
})
}
}
func Test_pndImplementation_RequestAll(t *testing.T) {
type args struct {
uuid uuid.UUID
path string
rErr error
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "default",
args: args{
uuid: mdid,
path: "",
rErr: nil,
},
wantErr: false,
},
{
name: "error",
args: args{
uuid: mneid,
path: "",
rErr: errors.New("deliberate test fail"),
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sbiService := NewGenericService[southbound.SouthboundInterface]()
networkElementService := NewNetworkElementServiceMock()
pnd := pndImplementation{
Name: "default",
Description: "default test pnd",
southboundService: &sbiService,
networkElementService: networkElementService,
changes: store.NewChangeStore(),
Id: defaultPndID,
sbi, err := NewSBI(spb.Type_TYPE_OPENCONFIG)
if err != nil {
t.Error("could not create sbi")
}
err = pnd.addSbi(sbi)
if err != nil {
t.Error("could not add sbi")
transport := mocks.Transport{}
transport.On("Get", mockContext, mock.Anything).Return(&gpb.GetResponse{}, tt.args.rErr)
transport.On("ProcessResponse", mock.Anything, mock.Anything, mock.Anything).Return(tt.args.rErr)
networkElementWithMockTransport := &CommonNetworkElement{
UUID: mdid,
Model: &openconfig.Device{},
sbi: sbi,
transport: &transport,
}
_, _ = pnd.addNetworkElement(networkElementWithMockTransport)
mne, _ := pnd.networkElementService.Get(store.Query{ID: mdid})
if mne == nil {
return
}
if err := pnd.networkElementService.Delete(mne); err != nil {
func Test_pndImplementation_ChangeMNE(t *testing.T) {
opts := &tpb.TransportOption{
TransportOption: &tpb.TransportOption_GnmiTransportOption{
GnmiTransportOption: &tpb.GnmiTransportOption{},
},
path string
value []string
}
tests := []struct {
name string
args args
wantErr bool
}{
path: "/system/config/hostname",
value: []string{"ceos3000"},
},
wantErr: false,
},
{
operation: ppb.ApiOperation_API_OPERATION_REPLACE,
path: "/system/config/hostname",
value: []string{"ceos3000"},
},
wantErr: false,
},
{
path: "/system/config/hostname",
},
wantErr: false,
},
{
path: "/system/config/hostname",
value: []string{"ceos3000"},
},
wantErr: false,
},
// Negative test cases
{
},
wantErr: true,
},
{
path: "/system/config/hostname",
value: []string{"ceos3000", "ceos3001"},
},
wantErr: true,
},
path: "/system/config/hostname",
},
wantErr: true,
},
{
path: "/system/config/hostname",
},
wantErr: true,
},
name: "network element not found",
},
wantErr: true,
},
pnd := newPnd()
if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil {
t.Error(err)
}
_, err := pnd.AddNetworkElement("testnetworkElement", opts, defaultSbiID)
t.Error(err)
return
}
networkElements, err := pnd.networkElementService.GetAllAsLoaded()
if err != nil {
err := errors.New("error fetching network element")
neUUID, err := uuid.Parse(networkElements[0].ID)
if err != nil {
err := errors.New("error parsing network element uuid")
t.Error(err)
return
}
_, err = pnd.ChangeMNE(neUUID, tt.args.operation, tt.args.path, tt.args.value...)
if (err != nil) != tt.wantErr {
t.Errorf("ChangeMNE() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr {
t.Errorf("ChangeMNE() unexpected change count. got %v, want 1", len(pnd.changes.Store))
func Test_pndImplementation_GetNetworkElement(t *testing.T) {
opts := &tpb.TransportOption{
Address: "",
Username: "test",
Password: "test",
TransportOption: &tpb.TransportOption_GnmiTransportOption{
GnmiTransportOption: &tpb.GnmiTransportOption{},
},
}
sbi, err := NewSBI(spb.Type_TYPE_OPENCONFIG)
if err != nil {
t.Errorf("NewSBI() error = %v", err)
return
err = pnd.addSbi(sbi)
if err != nil {
t.Error(err)
return
}
mne, err := NewNetworkElement("default", mneid, opts, sbi, conflict.Metadata{ResourceVersion: 0})
if err != nil {
t.Error(err)
return
}
_, err = pnd.addNetworkElement(mne)
type args struct {
uuid uuid.UUID
}
tests := []struct {
name string
args args
want ygot.GoStruct
wantErr bool
}{
{
name: "default",
args: args{uuid: mneid},
want: sbi.Schema().Root,
wantErr: false,
},
{
name: "network element not found",
args: args{uuid: mdid},
want: nil,
wantErr: true,
},
}
for _, tt := range tests {
foundNetworkElement, err := pnd.GetNetworkElement(tt.args.uuid.String())
t.Errorf("GetNetworkElement() error = %v, wantErr %v", err, tt.wantErr)
if foundNetworkElement != nil {
if !reflect.DeepEqual(foundNetworkElement.(networkelement.NetworkElement).GetModel(), tt.want) {
t.Errorf("GetNetworkElement() got = %v, want %v", foundNetworkElement.(networkelement.NetworkElement).GetModel(), tt.want)
func Test_pndImplementation_GetNetworkElementByName(t *testing.T) {
opts := &tpb.TransportOption{
Address: "",
Username: "test",
Password: "test",
TransportOption: &tpb.TransportOption_GnmiTransportOption{
GnmiTransportOption: &tpb.GnmiTransportOption{},
},
}
sbi, err := NewSBI(spb.Type_TYPE_OPENCONFIG)
if err != nil {
t.Errorf("NewSBI() error = %v", err)
return
err = pnd.addSbi(sbi)
if err != nil {
t.Error(err)
return
}
mne, err := NewNetworkElement("my-mne", mneid, opts, sbi, conflict.Metadata{ResourceVersion: 0})
if err != nil {
t.Error(err)
return
}
_, err = pnd.addNetworkElement(mne)
t.Error(err)
return
}
type args struct {
name string
}
tests := []struct {
name string
args args
want ygot.GoStruct
wantErr bool
}{
{
name: "default",
args: args{name: mne.Name()},
want: sbi.Schema().Root,
wantErr: false,
},
{
name: "network element not found",
args: args{name: "test-mne"},
want: nil,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
foundNetworkElement, err := pnd.GetNetworkElement(tt.args.name)
if (err != nil) != tt.wantErr {
t.Errorf("GetNetworkElementByName() error = %v, wantErr %v", err, tt.wantErr)
if foundNetworkElement != nil {
if !reflect.DeepEqual(foundNetworkElement.(networkelement.NetworkElement).GetModel(), tt.want) {
t.Errorf("GetNetworkElementByName() got = %v, want %v", foundNetworkElement.(networkelement.NetworkElement).GetModel(), tt.want)
})
}
}
func Test_pndImplementation_Confirm(t *testing.T) {
tests := []struct {
name string
wantErr bool
}{
{
name: "default",
wantErr: false,
},
{
name: "uncommitted",
wantErr: true,
},
}
sbiService := NewGenericService[southbound.SouthboundInterface]()
networkElementService := NewNetworkElementServiceMock()
pnd := pndImplementation{
Name: "default",
Description: "default test pnd",
southboundService: &sbiService,
networkElementService: networkElementService,
changes: store.NewChangeStore(),
Id: defaultPndID,
mne := mockNetworkElement()
tr, ok := mne.Transport().(*mocks.Transport)
if !ok {
log.Errorf("Confirm(), failed type conversion: %v", ok)
}
tr.On("Set", mockContext, mock.Anything, mock.Anything, mock.Anything).Return(nil)
_, err := pnd.addNetworkElement(mne)