Skip to content
Snippets Groups Projects
Commit 4ca6a4ef authored by André Sterba's avatar André Sterba
Browse files

Refactor topology to enable testing and add nodeService tests

parent 1e1532da
No related branches found
No related tags found
5 merge requests!376Add additional example application hostname-checker,!349Northbound refactoring to implement NIB concept for devices,!343Add basic application framework and example application to show interaction between events an NBI,!339Create basic venv-manager for use with arista,!324Provide prototype implementation for topology handling
Pipeline #104641 failed
package nodes package nodes
import ( import (
"code.fbi.h-da.de/danet/gosdn/controller/store" "code.fbi.h-da.de/danet/gosdn/controller/topology/store"
"github.com/google/uuid" "github.com/google/uuid"
) )
......
package nodes
import (
"reflect"
"testing"
"code.fbi.h-da.de/danet/gosdn/controller/topology/store"
"github.com/google/uuid"
)
func getTestNode() Node {
return Node{
ID: uuid.MustParse("44fb4aa4-c53c-4cf9-a081-5aabc61c7610"),
Name: "Test-Node",
}
}
func getEmptyNode() Node {
return Node{
ID: uuid.Nil,
Name: "",
}
}
func getTestStoreWithNodes(t *testing.T, nodes []Node) Store {
store := store.NewGenericStore[Node]()
for _, node := range nodes {
err := store.Add(node)
if err != nil {
t.Fatalf("failed to prepare test store while adding node: %v", err)
}
}
return store
}
func TestNewNodeService(t *testing.T) {
type args struct {
store Store
}
tests := []struct {
name string
args args
want Service
}{
{
name: "should create a new node service",
args: args{
store: getTestStoreWithNodes(t, []Node{}),
},
want: NewNodeService(getTestStoreWithNodes(t, []Node{})),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := NewNodeService(tt.args.store); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewNodeService() = %v, want %v", got, tt.want)
}
})
}
}
func TestNodeService_EnsureExists(t *testing.T) {
type fields struct {
store Store
}
type args struct {
node Node
}
tests := []struct {
name string
fields fields
args args
want Node
wantErr bool
}{
// {
// name: "should add not existing node",
// fields: fields{
// store: store.NewGenericStore[Node](),
// },
// args: args{
// node: Node{
// ID: uuid.Nil,
// Name: "Test-Node",
// },
// },
// want: Node{
// Name: "Test-Node",
// },
// wantErr: false,
// },
{
name: "should error if node with uuid is not in store",
fields: fields{
store: store.NewGenericStore[Node](),
},
args: args{
node: getTestNode(),
},
want: getEmptyNode(),
wantErr: true,
},
{
name: "should return node that is in the store",
fields: fields{
store: getTestStoreWithNodes(t, []Node{getTestNode()}),
},
args: args{
node: getTestNode(),
},
want: getTestNode(),
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &NodeService{
store: tt.fields.store,
}
got, err := p.EnsureExists(tt.args.node)
if (err != nil) != tt.wantErr {
t.Errorf("NodeService.EnsureExists() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("NodeService.EnsureExists() = %v, want %v", got, tt.want)
}
})
}
}
func TestNodeService_Update(t *testing.T) {
type fields struct {
store Store
}
type args struct {
node Node
}
tests := []struct {
name string
fields fields
args args
want Node
wantErr bool
}{
{
name: "should update an existing node",
fields: fields{
store: store.NewGenericStore[Node](),
},
args: args{
node: getTestNode(),
},
want: getTestNode(),
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &NodeService{
store: tt.fields.store,
}
if err := p.Update(tt.args.node); (err != nil) != tt.wantErr {
t.Errorf("NodeService.Update() error = %v, wantErr %v", err, tt.wantErr)
}
updatedNode, err := p.Get(store.Query(tt.args.node))
if err != nil {
t.Errorf("NodeService.Get() failed %v", err)
}
if !reflect.DeepEqual(updatedNode, tt.want) {
t.Errorf("Got updated node = %v, want %v", updatedNode, tt.want)
}
})
}
}
func TestNodeService_Delete(t *testing.T) {
type fields struct {
store Store
}
type args struct {
node Node
}
tests := []struct {
name string
fields fields
args args
wantErr bool
}{
{
name: "should delete an existing node",
fields: fields{
store: store.NewGenericStore[Node](),
},
args: args{
node: getTestNode(),
},
wantErr: false,
},
{
name: "should fail if a node does not exists",
fields: fields{
store: store.NewGenericStore[Node](),
},
args: args{
node: getTestNode(),
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &NodeService{
store: tt.fields.store,
}
if err := p.Delete(tt.args.node); (err != nil) != tt.wantErr {
t.Errorf("NodeService.Delete() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func TestNodeService_Get(t *testing.T) {
type fields struct {
store Store
}
type args struct {
query store.Query
}
tests := []struct {
name string
fields fields
args args
want Node
wantErr bool
}{
{
name: "should error if node with uuid is not in store",
fields: fields{
store: store.NewGenericStore[Node](),
},
args: args{
query: store.Query{
ID: getTestNode().ID,
Name: getTestNode().Name,
},
},
want: getEmptyNode(),
wantErr: true,
},
{
name: "should return node that is in the store",
fields: fields{
store: getTestStoreWithNodes(t, []Node{getTestNode()}),
},
args: args{
query: store.Query{
ID: getTestNode().ID,
Name: getTestNode().Name,
},
},
want: getTestNode(),
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &NodeService{
store: tt.fields.store,
}
got, err := p.Get(tt.args.query)
if (err != nil) != tt.wantErr {
t.Errorf("NodeService.Get() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("NodeService.Get() = %v, want %v", got, tt.want)
}
})
}
}
func TestNodeService_GetAll(t *testing.T) {
type fields struct {
store Store
}
tests := []struct {
name string
fields fields
want []Node
wantErr bool
}{
{
name: "should fail if a node does not exists",
fields: fields{
store: getTestStoreWithNodes(t, []Node{getTestNode()}),
},
want: []Node{getTestNode()},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &NodeService{
store: tt.fields.store,
}
got, err := p.GetAll()
if (err != nil) != tt.wantErr {
t.Errorf("NodeService.GetAll() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("NodeService.GetAll() = %v, want %v", got, tt.want)
}
})
}
}
...@@ -6,7 +6,7 @@ import ( ...@@ -6,7 +6,7 @@ import (
"code.fbi.h-da.de/danet/gosdn/controller/nucleus/database" "code.fbi.h-da.de/danet/gosdn/controller/nucleus/database"
"code.fbi.h-da.de/danet/gosdn/controller/nucleus/errors" "code.fbi.h-da.de/danet/gosdn/controller/nucleus/errors"
"code.fbi.h-da.de/danet/gosdn/controller/store" "code.fbi.h-da.de/danet/gosdn/controller/topology/store"
"github.com/google/uuid" "github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/bson/primitive"
......
package topology package store
import ( import (
"errors" "errors"
"code.fbi.h-da.de/danet/gosdn/controller/store"
"github.com/google/uuid" "github.com/google/uuid"
) )
...@@ -17,8 +16,8 @@ type GenericStore[T storableConstraint] struct { ...@@ -17,8 +16,8 @@ type GenericStore[T storableConstraint] struct {
} }
// NewGenericStore returns a specific in-memory store for a type T. // NewGenericStore returns a specific in-memory store for a type T.
func NewGenericStore[T storableConstraint]() GenericStore[T] { func NewGenericStore[T storableConstraint]() *GenericStore[T] {
return GenericStore[T]{ return &GenericStore[T]{
Store: make(map[uuid.UUID]T), Store: make(map[uuid.UUID]T),
} }
} }
...@@ -37,7 +36,7 @@ func (t *GenericStore[T]) Add(item T) error { ...@@ -37,7 +36,7 @@ func (t *GenericStore[T]) Add(item T) error {
func (t *GenericStore[T]) Update(item T) error { func (t *GenericStore[T]) Update(item T) error {
_, ok := t.Store[item.GetID()] _, ok := t.Store[item.GetID()]
if ok { if ok {
return nil return errors.New("item not found")
} }
t.Store[item.GetID()] = item t.Store[item.GetID()] = item
...@@ -46,12 +45,17 @@ func (t *GenericStore[T]) Update(item T) error { ...@@ -46,12 +45,17 @@ func (t *GenericStore[T]) Update(item T) error {
} }
func (t *GenericStore[T]) Delete(item T) error { func (t *GenericStore[T]) Delete(item T) error {
_, ok := t.Store[item.GetID()]
if ok {
return errors.New("item not found")
}
delete(t.Store, item.GetID()) delete(t.Store, item.GetID())
return nil return nil
} }
func (t *GenericStore[T]) Get(query store.Query) (T, error) { func (t *GenericStore[T]) Get(query Query) (T, error) {
// First search for direct hit on UUID. // First search for direct hit on UUID.
item, ok := t.Store[query.ID] item, ok := t.Store[query.ID]
if !ok { if !ok {
......
package store
import "github.com/google/uuid"
type Query struct {
ID uuid.UUID
Name string
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment