Skip to content
Snippets Groups Projects
principalNetworkDomain_test.go 16.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • Manuel Kieweg's avatar
    Manuel Kieweg committed
    package nucleus
    
    
    import (
    	"code.fbi.h-da.de/cocsn/gosdn/mocks"
    	"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
    	"errors"
    	"github.com/google/uuid"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	"github.com/openconfig/ygot/ygot"
    
    	"github.com/stretchr/testify/mock"
    	"reflect"
    	"testing"
    )
    
    func TestNewPND(t *testing.T) {
    
    	pnd := newPnd()
    
    	if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil {
    
    	type args struct {
    		name        string
    		description string
    		sbi         SouthboundInterface
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		pid         uuid.UUID
    
    		name    string
    		args    args
    		want    PrincipalNetworkDomain
    		wantErr bool
    
    	}{
    		{
    			name: "default",
    			args: args{
    				name:        "default",
    				description: "default test pnd",
    
    				sbi:         &OpenConfig{id: defaultSbiID},
    				pid:         defaultPndID,
    
    			want:    &pnd,
    			wantErr: false,
    
    		},
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			got, err := NewPND(tt.args.name, tt.args.description, tt.args.pid, tt.args.sbi)
    
    			if (err != nil) != tt.wantErr {
    				t.Errorf("NewPND() error = %v, wantErr %v", err, tt.wantErr)
    				return
    			}
    			if !reflect.DeepEqual(got, tt.want) {
    
    				t.Errorf("NewPND() = %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_AddDevice(t *testing.T) {
    	type args struct {
    
    Malte Bauch's avatar
    Malte Bauch committed
    		device interface{}
    
    	}
    	tests := []struct {
    		name    string
    		args    args
    		wantErr bool
    	}{
    		{
    			name: "default",
    
    			args: args{
    				device: &Device{
    
    		{
    			name: "already exists",
    			args: args{
    				device: &Device{
    
    Malte Bauch's avatar
    Malte Bauch committed
    		{
    			name: "fails wrong type",
    			args: args{device: &pndImplementation{
    				id: did,
    			}},
    			wantErr: true,
    		},
    
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    
    			pnd := newPnd()
    
    			if tt.name == "already exists" {
    
    				pnd.devices.store[did] = &Device{UUID: did}
    
    			err := pnd.AddDevice(tt.args.device)
    			if (err != nil) != tt.wantErr {
    				t.Errorf("AddDevice() error = %v, wantErr %v", err, tt.wantErr)
    
    			if tt.name != "fails wrong type" {
    				if err == nil {
    					_, ok := pnd.devices.store[did]
    					if !ok {
    						t.Errorf("AddDevice() Device %v not in device store %v",
    							tt.args.device, pnd.devices)
    					}
    					if err := pnd.devices.delete(did); err != nil {
    						t.Error(err)
    					}
    				}
    
    		})
    	}
    }
    
    func Test_pndImplementation_AddSbi(t *testing.T) {
    	type args struct {
    
    Malte Bauch's avatar
    Malte Bauch committed
    		sbi interface{}
    
    	}
    	tests := []struct {
    		name    string
    		args    args
    		wantErr bool
    	}{
    
    		{
    			name: "default",
    			args: args{
    				sbi: &OpenConfig{
    
    					id: defaultSbiID,
    
    		{
    			name: "already exists",
    			args: args{
    				sbi: &OpenConfig{
    
    					id: defaultSbiID,
    
    Malte Bauch's avatar
    Malte Bauch committed
    		{
    			name: "fails wrong type",
    			args: args{
    				sbi: &pndImplementation{
    
    					id: defaultSbiID,
    
    Malte Bauch's avatar
    Malte Bauch committed
    				},
    			},
    			wantErr: true,
    		},
    
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    
    			pnd := newPnd()
    
    			if tt.name == "already exists" {
    
    				pnd.sbic.store[defaultSbiID] = tt.args.sbi.(*OpenConfig)
    
    			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 {
    
    					_, ok := pnd.sbic.store[defaultSbiID]
    
    					if !ok {
    						t.Errorf("AddSbi() SBI %v not in device store %v",
    							tt.args.sbi, pnd.GetSBIs())
    					}
    
    					if err := pnd.sbic.delete(defaultSbiID); err != nil {
    
    		})
    	}
    }
    
    func Test_pndImplementation_ContainsDevice(t *testing.T) {
    	type args struct {
    		uuid   uuid.UUID
    		device *Device
    	}
    	tests := []struct {
    		name string
    		args args
    		want bool
    	}{
    		{name: "default", args: args{
    			uuid:   did,
    
    			device: &Device{UUID: did},
    
    		}, want: true},
    		{name: "fails", args: args{
    			uuid:   uuid.New(),
    
    			device: &Device{UUID: did},
    
    		{name: "fails empty", args: args{
    			uuid:   uuid.New(),
    
    			device: &Device{UUID: did},
    
    		}, want: false},
    
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    
    			pnd := newPnd()
    			if tt.name != "fails empty" {
    				if err := pnd.devices.add(tt.args.device); err != nil {
    					t.Error(err)
    				}
    			}
    
    			if got := pnd.ContainsDevice(tt.args.uuid); got != tt.want {
    
    				t.Errorf("ContainsDevice() = %v, want %v", got, tt.want)
    			}
    
    			if err := pnd.devices.delete(did); err != nil && tt.name != "fails empty" {
    				t.Error(err)
    			}
    
    		})
    	}
    }
    
    func Test_pndImplementation_Destroy(t *testing.T) {
    	type fields struct {
    		name        string
    		description string
    
    		sbi         sbiStore
    		devices     deviceStore
    
    	}
    	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,
    
    				sbic:        tt.fields.sbi,
    
    				devices:     tt.fields.devices,
    			}
    			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) {
    
    			pnd := newPnd()
    
    			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) {
    
    			pnd := newPnd()
    
    			if got := pnd.GetName(); got != tt.want {
    
    				t.Errorf("GetName() = %v, want %v", got, tt.want)
    			}
    		})
    	}
    }
    
    func Test_pndImplementation_GetSBIs(t *testing.T) {
    
    	pnd := newPnd()
    
    	tests := []struct {
    		name string
    
    		want *sbiStore
    
    		{name: "default", want: &pnd.sbic},
    
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    
    			if got := pnd.GetSBIs(); !reflect.DeepEqual(got, tt.want) {
    
    				t.Errorf("GetSBIs() = %v, want %v", got, tt.want)
    			}
    		})
    	}
    }
    
    func Test_pndImplementation_MarshalDevice(t *testing.T) {
    	type args struct {
    		uuid uuid.UUID
    	}
    	tests := []struct {
    		name    string
    		args    args
    		want    string
    		wantErr bool
    	}{
    
    Malte Bauch's avatar
    Malte Bauch committed
    		{
    			name:    "default",
    			args:    args{did},
    			want:    "{\n\t\"Acl\": null,\n\t\"Bgp\": null,\n\t\"Components\": null,\n\t\"Interfaces\": null,\n\t\"LocalRoutes\": null,\n\t\"Messages\": null,\n\t\"NetworkInstances\": null,\n\t\"RoutingPolicy\": null,\n\t\"System\": null\n}",
    			wantErr: false,
    		},
    
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    
    			pnd := newPnd()
    
    				UUID:      tt.args.uuid,
    
    				GoStruct:  &openconfig.Device{},
    				SBI:       nil,
    
    			if err := pnd.addDevice(d); err != nil {
    				t.Error(err)
    			}
    
    			got, err := pnd.MarshalDevice(tt.args.uuid)
    
    			if (err != nil) != tt.wantErr {
    				t.Errorf("MarshalDevice() error = %v, wantErr %v", err, tt.wantErr)
    				return
    			}
    			if got != tt.want {
    				t.Errorf("MarshalDevice() got = %v, want %v", got, tt.want)
    			}
    
    			if err := pnd.devices.delete(did); err != nil {
    				t.Error(err)
    			}
    
    		})
    	}
    }
    
    func Test_pndImplementation_RemoveDevice(t *testing.T) {
    	type args struct {
    		uuid uuid.UUID
    	}
    	tests := []struct {
    		name    string
    		args    args
    		wantErr bool
    	}{
    		{name: "default", args: args{uuid: did}, wantErr: false},
    
    		{name: "fails", args: args{uuid: uuid.New()}, wantErr: true},
    		{name: "fails empty", args: args{uuid: did}, wantErr: true},
    
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    
    			pnd := newPnd()
    			if tt.name != "fails empty" {
    
    				d := &Device{UUID: did}
    
    				if err := pnd.addDevice(d); err != nil {
    					t.Error(err)
    				}
    			}
    
    			if err := pnd.RemoveDevice(tt.args.uuid); (err != nil) != tt.wantErr {
    
    				t.Errorf("RemoveDevice() error = %v, wantErr %v", err, tt.wantErr)
    			}
    
    			if pnd.devices.exists(did) && tt.name == "default" {
    				t.Errorf("RemoveDevice() device still in device store %v", pnd.devices)
    
    			}
    		})
    	}
    }
    
    func Test_pndImplementation_RemoveSbi(t *testing.T) {
    	type args struct {
    
    	}
    	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},
    
    		{name: "fails empty", args: args{id: defaultSbiID}, wantErr: true},
    
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    
    			pnd := &pndImplementation{
    				name:        "test-remove-sbi",
    				description: "test-remove-sbi",
    				sbic:        sbiStore{store{}},
    				devices:     deviceStore{store{}},
    
    				id:          defaultPndID,
    
    			}
    			if tt.name != "fails empty" {
    
    				if err := pnd.addSbi(&OpenConfig{id: defaultSbiID}); err != nil {
    
    					t.Error(err)
    				}
    			}
    			if err := pnd.RemoveSbi(tt.args.id); (err != nil) != tt.wantErr {
    
    				t.Errorf("RemoveSbi() error = %v, wantErr %v", err, tt.wantErr)
    			}
    
    			if pnd.sbic.exists(tt.args.id) {
    				t.Errorf("RemoveDevice() SBI still in SBI store %v", pnd.sbic)
    
    			}
    		})
    	}
    }
    
    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: did,
    				path: "",
    				rErr: errors.New("deliberate test fail"),
    			},
    			wantErr: true,
    		},
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    
    			deviceWithMockTransport := mockDevice()
    
    			pnd := newPnd()
    
    			tr := deviceWithMockTransport.Transport.(*mocks.Transport)
    			tr.On("Get", mockContext, mock.Anything).Return(mock.Anything, tt.args.rErr)
    			tr.On("ProcessResponse", mock.Anything, mock.Anything, mock.Anything).Return(tt.args.rErr)
    
    			_ = pnd.addDevice(&deviceWithMockTransport)
    			if err := pnd.Request(tt.args.uuid, tt.args.path); (err != nil) != tt.wantErr {
    
    				t.Errorf("Request() error = %v, wantErr %v", err, tt.wantErr)
    			}
    
    			if err := pnd.devices.delete(mdid); err != nil {
    				t.Error(err)
    			}
    
    		})
    	}
    }
    
    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{
    
    				path: "",
    				rErr: errors.New("deliberate test fail"),
    			},
    			wantErr: true,
    		},
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    
    			deviceWithMockTransport := mockDevice()
    
    			pnd := newPnd()
    
    			tr := deviceWithMockTransport.Transport.(*mocks.Transport)
    			tr.On("Get", mockContext, mock.Anything).Return(mock.Anything, tt.args.rErr)
    			tr.On("ProcessResponse", mock.Anything, mock.Anything, mock.Anything).Return(tt.args.rErr)
    
    			_ = pnd.addDevice(&deviceWithMockTransport)
    			if err := pnd.RequestAll(tt.args.path); (err != nil) != tt.wantErr {
    
    				t.Errorf("RequestAll() error = %v, wantErr %v", err, tt.wantErr)
    			}
    
    			if err := pnd.devices.delete(mdid); err != nil {
    				t.Error(err)
    			}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    
    func Test_pndImplementation_ChangeOND(t *testing.T) {
    	type fields struct {
    	}
    	type args struct {
    		uuid      uuid.UUID
    		operation interface{}
    		path      string
    		value     []string
    	}
    	tests := []struct {
    		name    string
    		fields  fields
    		args    args
    		wantErr bool
    	}{
    
    		{
    			name:   "update",
    			fields: fields{},
    			args: args{
    				uuid:      mdid,
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    				operation: TransportUpdate,
    
    				path:      "/system/config/hostname",
    				value:     []string{"ceos3000"},
    			},
    			wantErr: false,
    		},
    		{
    			name:   "replace",
    			fields: fields{},
    			args: args{
    				uuid:      mdid,
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    				operation: TransportReplace,
    
    				path:      "/system/config/hostname",
    				value:     []string{"ceos3000"},
    			},
    			wantErr: false,
    		},
    		{
    			name:   "delete",
    			fields: fields{},
    			args: args{
    				uuid:      mdid,
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    				operation: TransportDelete,
    
    				path:      "/system/config/hostname",
    			},
    			wantErr: false,
    		},
    		{
    			name:   "delete w/args",
    			fields: fields{},
    			args: args{
    				uuid:      mdid,
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    				operation: TransportDelete,
    
    				path:      "/system/config/hostname",
    				value:     []string{"ceos3000"},
    			},
    			wantErr: false,
    		},
    
    		// Negative test cases
    		{
    			name:   "invalid operation",
    			fields: fields{},
    			args: args{
    				uuid:      mdid,
    				operation: "INVALID",
    			},
    			wantErr: true,
    		},
    		{
    			name:   "invalid arg count",
    			fields: fields{},
    			args: args{
    				uuid:      mdid,
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    				operation: TransportUpdate,
    
    				path:      "/system/config/hostname",
    				value:     []string{"ceos3000", "ceos3001"},
    			},
    			wantErr: true,
    		},
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		{
    			name:   "invalid arg count - update, no args",
    			fields: fields{},
    			args: args{
    				uuid:      mdid,
    				operation: TransportUpdate,
    				path:      "/system/config/hostname",
    			},
    			wantErr: true,
    		},
    		{
    			name:   "invalid arg count - replace, no args",
    			fields: fields{},
    			args: args{
    				uuid:      mdid,
    				operation: TransportUpdate,
    				path:      "/system/config/hostname",
    			},
    			wantErr: true,
    		},
    
    		{
    			name:   "device not found",
    			fields: fields{},
    			args: args{
    				uuid:      did,
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    				operation: TransportUpdate,
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    
    			p := newPnd()
    			d := mockDevice()
    			if err := p.AddDevice(&d); err != nil {
    				t.Error(err)
    				return
    			}
    			if err := p.ChangeOND(tt.args.uuid, tt.args.operation, tt.args.path, tt.args.value...); (err != nil) != tt.wantErr {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    				t.Errorf("ChangeOND() error = %v, wantErr %v", err, tt.wantErr)
    
    				return
    			}
    			if !tt.wantErr {
    				if len(p.pendingChanges.store) != 1 {
    					t.Errorf("ChangeOND() unexpected change count. got %v, want 1", len(p.pendingChanges.store))
    				}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			}
    		})
    	}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    
    func Test_pndImplementation_GetDevice(t *testing.T) {
    	p := newPnd()
    	d, err := NewDevice(sbi, &GnmiTransportOptions{})
    	if err != nil {
    		t.Error(err)
    		return
    	}
    	if err = p.addDevice(d); err != nil {
    		t.Error(err)
    		return
    	}
    	type args struct {
    		uuid uuid.UUID
    	}
    	tests := []struct {
    		name    string
    		args    args
    		want    ygot.GoStruct
    		wantErr bool
    	}{
    		{
    			name:    "default",
    			args:    args{uuid: d.ID()},
    			want:    sbi.Schema().Root,
    			wantErr: false,
    		},
    		{
    			name:    "device not found",
    			args:    args{uuid: mdid},
    			want:    nil,
    			wantErr: true,
    		},
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    			got, err := p.GetDevice(tt.args.uuid)
    			if (err != nil) != tt.wantErr {
    				t.Errorf("GetDevice() error = %v, wantErr %v", err, tt.wantErr)
    				return
    			}
    			if !reflect.DeepEqual(got, tt.want) {
    				t.Errorf("GetDevice() got = %v, want %v", got, tt.want)
    			}
    		})
    	}
    }
    
    func Test_pndImplementation_Confirm(t *testing.T) {
    	tests := []struct {
    		name    string
    		wantErr bool
    	}{
    		{
    			name:    "default",
    			wantErr: false,
    		},
    		{
    			name:    "uncommitted",
    			wantErr: true,
    		},
    	}
    	for _, tt := range tests {
    		t.Run(tt.name, func(t *testing.T) {
    			pnd := newPnd()
    			d := mockDevice()
    			tr := d.Transport.(*mocks.Transport)
    			tr.On("Set", mockContext, mock.Anything, mock.Anything).Return(nil)
    			if err := pnd.addDevice(&d); err != nil {
    				t.Error(err)
    				return
    			}
    			if err := pnd.ChangeOND(d.ID(), TransportUpdate, "system/config/hostname", "ceos3000"); err != nil {
    				t.Error(err)
    				return
    			}
    			u := pnd.Pending()[0]
    			if tt.name != "uncommitted" {
    				if err := pnd.Commit(u); (err != nil) != tt.wantErr {
    					t.Errorf("Confirm() error = %v, wantErr %v", err, tt.wantErr)
    					return
    				}
    			}
    			if err := pnd.Confirm(u); (err != nil) != tt.wantErr {
    				t.Errorf("Confirm() error = %v, wantErr %v", err, tt.wantErr)
    			}
    		})
    	}
    }