diff --git a/go.mod b/go.mod
index cec3a1d5e20c459677d3225f5bda04b71e285efa..6c65f7786aa111c2a925ccf6459bf331d106f05f 100644
--- a/go.mod
+++ b/go.mod
@@ -9,19 +9,19 @@ require (
 	github.com/gdamore/tcell/v2 v2.0.1-0.20201017141208-acf90d56d591
 	github.com/go-openapi/runtime v0.19.22
 	github.com/go-openapi/strfmt v0.19.5
-	github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
+	github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
 	github.com/golang/protobuf v1.4.2
 	github.com/google/uuid v1.1.2
 	github.com/neo4j/neo4j-go-driver v1.8.3
 	github.com/onsi/ginkgo v1.13.0 // indirect
 	github.com/openconfig/gnmi v0.0.0-20200617225440-d2b4e6a45802
-	github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696 // indirect
+	github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696
 	github.com/openconfig/ygot v0.8.11
 	github.com/rivo/tview v0.0.0-20201018122409-d551c850a743
 	github.com/sirupsen/logrus v1.4.2
 	github.com/spf13/viper v1.7.1
 	github.com/tidwall/gjson v1.6.3
-	golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect
+	golang.org/x/net v0.0.0-20200904194848-62affa334b73
 	google.golang.org/grpc v1.29.1
 	google.golang.org/protobuf v1.25.0
 )
diff --git a/nucleus/clientConfig.go b/nucleus/clientConfig.go
index 0dc63e1c5d0a03cb8a8efd9a27bef9a243458a7a..297e7a7fe53d3dcc9c67dad5e09f95601141da65 100644
--- a/nucleus/clientConfig.go
+++ b/nucleus/clientConfig.go
@@ -2,6 +2,7 @@ package nucleus
 
 // ClientConfig contains SBI ciena
 // configuration parameters
+// Deprecated in favor of spf viper
 type ClientConfig struct {
 	Identifier           string `toml:"identifier"`
 	Endpoint             string `toml:"endpoint"`
diff --git a/nucleus/device_test.go b/nucleus/device_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..3f89d7d0fd7844082c76c530eed2d2acf4118007
--- /dev/null
+++ b/nucleus/device_test.go
@@ -0,0 +1,37 @@
+package nucleus
+
+import (
+	"github.com/openconfig/ygot/ygot"
+	log "github.com/sirupsen/logrus"
+	"testing"
+)
+
+func TestDevice_Add(t *testing.T) {
+	type fields struct {
+		Device    ygot.GoStruct
+		SBI       SouthboundInterface
+		Config    DeviceConfig
+		Transport Transport
+	}
+	type args struct {
+		resp interface{}
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			d := Device{
+				Device:    tt.fields.Device,
+				SBI:       tt.fields.SBI,
+				Config:    tt.fields.Config,
+				Transport: tt.fields.Transport,
+			}
+			log.Debug(d.SBI.SbiIdentifier())
+		})
+	}
+}
\ No newline at end of file
diff --git a/nucleus/gnmi_transport_test.go b/nucleus/gnmi_transport_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..24af7305c9a272af5d4cced6441d1994fb88ddd0
--- /dev/null
+++ b/nucleus/gnmi_transport_test.go
@@ -0,0 +1,194 @@
+package nucleus
+
+import (
+	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
+	"context"
+	gpb "github.com/openconfig/gnmi/proto/gnmi"
+	"github.com/openconfig/gnmi/proto/gnmi_ext"
+	"reflect"
+	"testing"
+)
+
+func TestGetWithRequest(t *testing.T) {
+	type args struct {
+		ctx context.Context
+		req *gpb.GetRequest
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    interface{}
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := GetWithRequest(tt.args.ctx, tt.args.req)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("GetWithRequest() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("GetWithRequest() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestGnmi_Capabilities(t *testing.T) {
+	type args struct {
+		ctx context.Context
+	}
+	tests := []struct {
+		name    string
+		g       Gnmi
+		args    args
+		want    interface{}
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := tt.g.Capabilities(tt.args.ctx)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("Capabilities() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("Capabilities() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestGnmi_Close(t *testing.T) {
+	tests := []struct {
+		name    string
+		g       Gnmi
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := tt.g.Close(); (err != nil) != tt.wantErr {
+				t.Errorf("Close() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestGnmi_Get(t *testing.T) {
+	type args struct {
+		ctx    context.Context
+		paths  [][]string
+		origin string
+	}
+	tests := []struct {
+		name    string
+		g       Gnmi
+		args    args
+		want    interface{}
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := tt.g.Get(tt.args.ctx, tt.args.paths, tt.args.origin)
+			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 TestGnmi_GetConfig(t *testing.T) {
+	tests := []struct {
+		name string
+		g    Gnmi
+		want interface{}
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := tt.g.GetConfig(); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("GetConfig() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestGnmi_Set(t *testing.T) {
+	type args struct {
+		ctx    context.Context
+		setOps []*gnmi.Operation
+		exts   []*gnmi_ext.Extension
+	}
+	tests := []struct {
+		name    string
+		g       Gnmi
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := tt.g.Set(tt.args.ctx, tt.args.setOps, tt.args.exts...); (err != nil) != tt.wantErr {
+				t.Errorf("Set() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestGnmi_SetConfig(t *testing.T) {
+	type args struct {
+		in0 interface{}
+	}
+	tests := []struct {
+		name    string
+		g       Gnmi
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := tt.g.SetConfig(tt.args.in0); (err != nil) != tt.wantErr {
+				t.Errorf("SetConfig() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestGnmi_Subscribe(t *testing.T) {
+	type args struct {
+		ctx              context.Context
+		subscribeOptions *gnmi.SubscribeOptions
+		respChan         chan<- *gpb.SubscribeResponse
+	}
+	tests := []struct {
+		name    string
+		g       Gnmi
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := tt.g.Subscribe(tt.args.ctx, tt.args.subscribeOptions, tt.args.respChan); (err != nil) != tt.wantErr {
+				t.Errorf("Subscribe() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
diff --git a/nucleus/principalNetworkDomain_test.go b/nucleus/principalNetworkDomain_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..133195a8d7e0cf2a3203c2c1bfc6aa4d74602a52
--- /dev/null
+++ b/nucleus/principalNetworkDomain_test.go
@@ -0,0 +1,281 @@
+package nucleus
+
+import (
+	"github.com/google/uuid"
+	"reflect"
+	"testing"
+)
+
+func TestNewPND(t *testing.T) {
+	type args struct {
+		name string
+		sbi  SouthboundInterface
+	}
+	tests := []struct {
+		name string
+		args args
+		want PrincipalNetworkDomain
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := NewPND(tt.args.name, tt.args.sbi); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("NewPND() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_addSbi(t *testing.T) {
+	tests := []struct {
+		name    string
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := addSbi(); (err != nil) != tt.wantErr {
+				t.Errorf("addSbi() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_destroy(t *testing.T) {
+	tests := []struct {
+		name    string
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	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 fields struct {
+		name    string
+		sbi     map[string]SouthboundInterface
+		devices map[uuid.UUID]Device
+	}
+	type args struct {
+		device Device
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pnd := &pndImplementation{
+				name:    tt.fields.name,
+				sbi:     tt.fields.sbi,
+				devices: tt.fields.devices,
+			}
+			if err := pnd.AddDevice(tt.args.device); (err != nil) != tt.wantErr {
+				t.Errorf("AddDevice() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_pndImplementation_AddSbi(t *testing.T) {
+	type fields struct {
+		name    string
+		sbi     map[string]SouthboundInterface
+		devices map[uuid.UUID]Device
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pnd := &pndImplementation{
+				name:    tt.fields.name,
+				sbi:     tt.fields.sbi,
+				devices: tt.fields.devices,
+			}
+			if err := pnd.AddSbi(); (err != nil) != tt.wantErr {
+				t.Errorf("AddSbi() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_pndImplementation_Destroy(t *testing.T) {
+	type fields struct {
+		name    string
+		sbi     map[string]SouthboundInterface
+		devices map[uuid.UUID]Device
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pnd := &pndImplementation{
+				name:    tt.fields.name,
+				sbi:     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_RemoveDevice(t *testing.T) {
+	type fields struct {
+		name    string
+		sbi     map[string]SouthboundInterface
+		devices map[uuid.UUID]Device
+	}
+	type args struct {
+		uuid uuid.UUID
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pnd := &pndImplementation{
+				name:    tt.fields.name,
+				sbi:     tt.fields.sbi,
+				devices: tt.fields.devices,
+			}
+			if err := pnd.RemoveDevice(tt.args.uuid); (err != nil) != tt.wantErr {
+				t.Errorf("RemoveDevice() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_pndImplementation_RemoveSbi(t *testing.T) {
+	type fields struct {
+		name    string
+		sbi     map[string]SouthboundInterface
+		devices map[uuid.UUID]Device
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pnd := &pndImplementation{
+				name:    tt.fields.name,
+				sbi:     tt.fields.sbi,
+				devices: tt.fields.devices,
+			}
+			if err := pnd.RemoveSbi(); (err != nil) != tt.wantErr {
+				t.Errorf("RemoveSbi() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_pndImplementation_addDevice(t *testing.T) {
+	type fields struct {
+		name    string
+		sbi     map[string]SouthboundInterface
+		devices map[uuid.UUID]Device
+	}
+	type args struct {
+		device Device
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pnd := &pndImplementation{
+				name:    tt.fields.name,
+				sbi:     tt.fields.sbi,
+				devices: tt.fields.devices,
+			}
+			if err := pnd.addDevice(tt.args.device); (err != nil) != tt.wantErr {
+				t.Errorf("addDevice() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_pndImplementation_removeDevice(t *testing.T) {
+	type fields struct {
+		name    string
+		sbi     map[string]SouthboundInterface
+		devices map[uuid.UUID]Device
+	}
+	type args struct {
+		uuid uuid.UUID
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			pnd := &pndImplementation{
+				name:    tt.fields.name,
+				sbi:     tt.fields.sbi,
+				devices: tt.fields.devices,
+			}
+			if err := pnd.removeDevice(tt.args.uuid); (err != nil) != tt.wantErr {
+				t.Errorf("removeDevice() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_removeSbi(t *testing.T) {
+	tests := []struct {
+		name    string
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := removeSbi(); (err != nil) != tt.wantErr {
+				t.Errorf("removeSbi() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
diff --git a/nucleus/restconf_transport_test.go b/nucleus/restconf_transport_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..57fb9de6f74e08b09fd1a93e551286d87b4358aa
--- /dev/null
+++ b/nucleus/restconf_transport_test.go
@@ -0,0 +1,67 @@
+package nucleus
+
+import (
+	"context"
+	"reflect"
+	"testing"
+)
+
+func TestRestconf_GetConfig(t *testing.T) {
+	tests := []struct {
+		name string
+		want interface{}
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			rc := &Restconf{}
+			if got := rc.GetConfig(); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("GetConfig() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestRestconf_SetConfig(t *testing.T) {
+	type args struct {
+		in0 interface{}
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			rc := &Restconf{}
+			if err := rc.SetConfig(tt.args.in0); (err != nil) != tt.wantErr {
+				t.Errorf("SetConfig() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestRestconf_Subscribe(t *testing.T) {
+	type args struct {
+		ctx    context.Context
+		params []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) {
+			rc := &Restconf{}
+			if err := rc.Subscribe(tt.args.ctx, tt.args.params...); (err != nil) != tt.wantErr {
+				t.Errorf("Subscribe() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
diff --git a/nucleus/southbound.go b/nucleus/southbound.go
index 69d37e843686e00bb482e0052ed3e717e0d23286..a3aa5af682a41581b53ce03e69526a5e34454349 100644
--- a/nucleus/southbound.go
+++ b/nucleus/southbound.go
@@ -3,7 +3,7 @@ package nucleus
 // SouthboundInterface provides an
 // interface for SBI implementations
 type SouthboundInterface interface {
-	GetSBIString() string
+	SbiIdentifier() string
 }
 
 type Tapi struct {
@@ -13,7 +13,7 @@ type OpenConfig struct {
 	transport Transport
 }
 
-func (oc *OpenConfig) GetSBIString() string {
+func (oc *OpenConfig) SbiIdentifier() string {
 	return "openconfig"
 }
 
diff --git a/nucleus/southbound_test.go b/nucleus/southbound_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..447696fa7cb6350f089bed728ea31b5ea01af477
--- /dev/null
+++ b/nucleus/southbound_test.go
@@ -0,0 +1,50 @@
+package nucleus
+
+import "testing"
+
+func TestOpenConfig_SbiIdentifier(t *testing.T) {
+	type fields struct {
+		transport Transport
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		{name: "default", want: "openconfig"},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oc := &OpenConfig{
+				transport: tt.fields.transport,
+			}
+			if got := oc.SbiIdentifier(); got != tt.want {
+				t.Errorf("SbiIdentifier() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestOpenConfig_OpenconfigInterfaces(t *testing.T) {
+	type fields struct {
+		transport Transport
+	}
+	type args struct {
+		device Device
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			oc := &OpenConfig{
+				transport: tt.fields.transport,
+			}
+			oc.OpenconfigInterfaces(tt.args.device)
+		})
+	}
+}
\ No newline at end of file