diff --git a/build/ci/.terraform-ci.yml b/build/ci/.terraform-ci.yml
index c2dc2bda1359561e72600b136d427ecfa7f08880..64a9afccff47147749f84a648463464644d2d9e2 100644
--- a/build/ci/.terraform-ci.yml
+++ b/build/ci/.terraform-ci.yml
@@ -28,6 +28,7 @@ cache:
       variables:
         TF_VAR_container_tag: $CI_REGISTRY_IMAGE:mr-develop
     - if: $CI_COMMIT_BRANCH == "integration-test"
+    - if: $CI_COMMIT_BRANCH == "develop"
     - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
 
 init:
diff --git a/build/ci/.test.yml b/build/ci/.test.yml
index edab2169dae858100e7349a3341f09f9d369549e..1a0d55ac79da8ec7d1f653118ee217e81771a06e 100644
--- a/build/ci/.test.yml
+++ b/build/ci/.test.yml
@@ -11,13 +11,22 @@ integration-test:
   after_script:
     - go tool cover -func=coverage.out
 
+unit-test-merge-request:
+  image: golang:1.14
+  stage: integration-test
+  allow_failure: true
+  rules:
+    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH
+  script:
+    - go test -race $(go list ./... | grep -v /forks/ | grep -v /api/ | grep -v /mocks ) -v -coverprofile=coverage.out
+  after_script:
+    - go tool cover -func=coverage.out
 
 unit-test:
   image: golang:1.14
   stage: test
   allow_failure: true
   rules:
-    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH
     - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
   script:
     - go test -short -race $(go list ./... | grep -v /forks/ | grep -v /api/ | grep -v /mocks ) -v -coverprofile=coverage.out
diff --git a/cmd/gnmi-capabilities/capabilities.go b/cmd/gnmi-capabilities/capabilities.go
index de9475197ab197cd52fc3940c6b54f80670097ec..54601b8a7ede5805a0d1a3ad633424020a8fc736 100644
--- a/cmd/gnmi-capabilities/capabilities.go
+++ b/cmd/gnmi-capabilities/capabilities.go
@@ -17,7 +17,7 @@ func main() {
 		Password: "arista",
 		Encoding: gpb.Encoding_JSON_IETF,
 	}
-	transport,err := nucleus.NewGnmiTransport(cfg)
+	transport, err := nucleus.NewGnmiTransport(cfg)
 	if err != nil {
 		log.Error(err)
 	}
@@ -27,7 +27,7 @@ func main() {
 	}
 	modelData := resp.(*gpb.CapabilityResponse).SupportedModels
 	b := strings.Builder{}
-	for _,elem := range modelData {
+	for _, elem := range modelData {
 		_, err := b.WriteString(elem.Name)
 		if err != nil {
 			log.Error(err)
diff --git a/cmd/gnmi-telemetry/telemetry.go b/cmd/gnmi-telemetry/telemetry.go
index 3cb85fd508cdc8331d0331c358748a1509a00913..5064e40e0609c751ba714a3cac12c434f49a3e4f 100644
--- a/cmd/gnmi-telemetry/telemetry.go
+++ b/cmd/gnmi-telemetry/telemetry.go
@@ -39,7 +39,7 @@ func main() {
 		Password: "arista",
 		Encoding: gpb.Encoding_JSON_IETF,
 	}
-	transport,_ := nucleus.NewGnmiTransport(cfg)
+	transport, _ := nucleus.NewGnmiTransport(cfg)
 
 	device.Transport = transport
 
diff --git a/cmd/gosdn/main.go b/cmd/gosdn/main.go
index 4356fbc6a18839313c531ceade42c064a8ac5f07..367250512af6318f1ad84ec85c139bfec28e1206 100644
--- a/cmd/gosdn/main.go
+++ b/cmd/gosdn/main.go
@@ -16,5 +16,5 @@ func main() {
 	IsRunningChannel := make(chan bool)
 
 	// hand off to cmd for further processing
-		nucleus.StartAndRun(IsRunningChannel)
+	nucleus.StartAndRun(IsRunningChannel)
 }
diff --git a/forks/goarista/gnmi/client.go b/forks/goarista/gnmi/client.go
index bfb404ada10a59f474c993e184a1ade785ef63bf..33c3023b77760402803fef98bd8226c6917cb01e 100644
--- a/forks/goarista/gnmi/client.go
+++ b/forks/goarista/gnmi/client.go
@@ -235,7 +235,7 @@ func DialContext(ctx context.Context, cfg *Config) (pb.GNMIClient, error) {
 	return pb.NewGNMIClient(grpcconn), nil
 }
 
-// Dial connects to a gnmi service and returns a ciena
+// Dial connects to a gnmi service and returns a client
 func Dial(cfg *Config) (pb.GNMIClient, error) {
 	return DialContext(context.Background(), cfg)
 }
diff --git a/nucleus/cli-handling_test.go b/nucleus/cli-handling_test.go
index 6a5a49d394fb238c662d9458411c1d448328ddf4..522de1a0cfa12cea3ac919e23f5696865e7159f1 100644
--- a/nucleus/cli-handling_test.go
+++ b/nucleus/cli-handling_test.go
@@ -374,4 +374,4 @@ func Test_server_Shutdown(t *testing.T) {
 			}
 		})
 	}
-}
\ No newline at end of file
+}
diff --git a/nucleus/device_test.go b/nucleus/device_test.go
index 0fa4ffa903a1f894325aaf5211341e19a2df754a..443744d8c8c91ac46a8fade40c91967effd125f7 100644
--- a/nucleus/device_test.go
+++ b/nucleus/device_test.go
@@ -1 +1,93 @@
 package nucleus
+
+import (
+	"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
+	"github.com/google/uuid"
+	"github.com/openconfig/ygot/ygot"
+	"reflect"
+	"testing"
+)
+
+func TestDevice_Id(t *testing.T) {
+	type fields struct {
+		GoStruct  ygot.GoStruct
+		SBI       SouthboundInterface
+		Config    DeviceConfig
+		Transport Transport
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   uuid.UUID
+	}{
+		{
+			name: "default",
+			fields: fields{
+				Config: DeviceConfig{
+					Uuid: did,
+				},
+			},
+			want: did,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			d := &Device{
+				GoStruct:  tt.fields.GoStruct,
+				SBI:       tt.fields.SBI,
+				Config:    tt.fields.Config,
+				Transport: tt.fields.Transport,
+			}
+			if got := d.Id(); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("Id() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestNewDevice(t *testing.T) {
+	sbi := &OpenConfig{}
+	type args struct {
+		sbi       SouthboundInterface
+		addr      string
+		username  string
+		password  string
+		transport Transport
+	}
+	tests := []struct {
+		name string
+		args args
+		want *Device
+	}{
+		{
+			name: "default",
+			args: args{
+				sbi:       sbi,
+				addr:      "testdevice",
+				username:  "testuser",
+				password:  "testpassword",
+				transport: &Gnmi{},
+			},
+			want: &Device{
+				GoStruct: &openconfig.Device{},
+				SBI:      sbi,
+				Config: DeviceConfig{
+					Uuid:     uuid.UUID{},
+					Address:  "testdevice",
+					Username: "testuser",
+					Password: "testpassword",
+				},
+				Transport: &Gnmi{},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got := NewDevice(tt.args.sbi, tt.args.addr, tt.args.username, tt.args.password, tt.args.transport)
+			tt.want.Config.Uuid = got.Id()
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("NewDevice() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/nucleus/errors.go b/nucleus/errors.go
index 9a92bf9e72caec1164702ff0e0f598765f75d4e8..93097feda2c967828ca09ab80dc729a043e2f0d2 100644
--- a/nucleus/errors.go
+++ b/nucleus/errors.go
@@ -40,4 +40,10 @@ type ErrUnsupportedPath struct {
 
 func (e ErrUnsupportedPath) Error() string {
 	return fmt.Sprintf("path %v is not supported", e.p)
-}
\ No newline at end of file
+}
+
+type ErrNotYetImplemented struct{}
+
+func (e ErrNotYetImplemented) Error() string {
+	return fmt.Sprintf("function not yet implemented")
+}
diff --git a/nucleus/gnmi_transport.go b/nucleus/gnmi_transport.go
index 784a402513deb35423f1276accc9ba48c3299525..f0022d2c934a663d21e02094166c5fa6d7128980 100644
--- a/nucleus/gnmi_transport.go
+++ b/nucleus/gnmi_transport.go
@@ -4,7 +4,6 @@ import (
 	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus/util"
 	"context"
-	"errors"
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
 	"github.com/openconfig/gnmi/proto/gnmi_ext"
 	"github.com/openconfig/goyang/pkg/yang"
@@ -84,17 +83,9 @@ func (g *Gnmi) ProcessResponse(resp interface{}, root interface{}, s *ytypes.Sch
 	rn := r.Notification
 	for _, msg := range rn {
 		for _, update := range msg.Update {
-			prefix := msg.Prefix
 			path := update.Path
 			fullPath := path
-			if prefix != nil {
-				var err error
-				fullPath, err = gnmiFullPath(prefix, path)
-				if err != nil {
-					return err
-				}
-			}
-			val,ok := update.Val.Value.(*gpb.TypedValue_JsonIetfVal)
+			val, ok := update.Val.Value.(*gpb.TypedValue_JsonIetfVal)
 			if ok {
 				opts := []ytypes.UnmarshalOpt{&ytypes.IgnoreExtraFields{}}
 				if err := g.Unmarshal(val.JsonIetfVal, extraxtPathElements(fullPath), root, opts...); err != nil {
@@ -115,40 +106,12 @@ func (g *Gnmi) ProcessResponse(resp interface{}, root interface{}, s *ytypes.Sch
 
 func extraxtPathElements(path *gpb.Path) []string {
 	elems := make([]string, len(path.Elem))
-	for i,e := range path.Elem {
+	for i, e := range path.Elem {
 		elems[i] = strings.Title(e.Name)
 	}
 	return elems
 }
 
-// extractModelKey extracts the model's key from the full path. Highly model specific for now
-// TODO: Remove hard coded model prefix
-// TODO: Figure out why path.Elem() is empty but path.Elememt() is deprecated
-func extractModelKey(path *gpb.Path) string {
-	var b strings.Builder
-	delim := "_"
-	b.WriteString("OpenconfigInterfaces")
-	for i := 0; i < len(path.Elem); i++ {
-		pathElement := path.Elem[i]
-		b.WriteString(delim)
-		b.WriteString(strings.Title(pathElement.Name))
-	}
-	return b.String()
-}
-
-// gnmiFullPath builds the full path from the prefix and path.
-// Copycat from forks/google/gnmi/server.go
-func gnmiFullPath(prefix, path *gpb.Path) (*gpb.Path, error) {
-	fullPath := &gpb.Path{Origin: path.Origin}
-	if path.GetElement() != nil {
-		return nil, errors.New("deprecated path element type is unsupported")
-	}
-	if path.GetElem() != nil {
-		fullPath.Elem = append(prefix.GetElem(), path.GetElem()...)
-	}
-	return fullPath, nil
-}
-
 // Capabilities calls GNMI capabilities
 func (g *Gnmi) Capabilities(ctx context.Context) (interface{}, error) {
 	ctx = gnmi.NewContext(ctx, g.config)
diff --git a/nucleus/gnmi_transport_test.go b/nucleus/gnmi_transport_test.go
index e54dff7b967d910eee3553ba5ede81a176864b8f..5ca60936c6ff7d28af51fd57febed7636cc20c54 100644
--- a/nucleus/gnmi_transport_test.go
+++ b/nucleus/gnmi_transport_test.go
@@ -8,6 +8,7 @@ import (
 	"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
 	"context"
 	log "github.com/golang/glog"
+	"github.com/golang/protobuf/proto"
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
 	"github.com/openconfig/goyang/pkg/yang"
 	"github.com/openconfig/ygot/ytypes"
@@ -20,10 +21,29 @@ import (
 // TestMain bootstraps all tests. Humongous beast
 // TODO: Move somewhere more sensible
 func TestMain(m *testing.M) {
+	gnmiMessages = map[string]proto.Message{
+		"../test/cap-resp-arista-ceos":                  &gpb.CapabilityResponse{},
+		"../test/req-full-node":                         &gpb.GetRequest{},
+		"../test/req-full-node-arista-ceos":             &gpb.GetRequest{},
+		"../test/req-interfaces-arista-ceos":            &gpb.GetRequest{},
+		"../test/req-interfaces-interface-arista-ceos":  &gpb.GetRequest{},
+		"../test/req-interfaces-wildcard":               &gpb.GetRequest{},
+		"../test/resp-full-node":                        &gpb.GetResponse{},
+		"../test/resp-full-node-arista-ceos":            &gpb.GetResponse{},
+		"../test/resp-interfaces-arista-ceos":           &gpb.GetResponse{},
+		"../test/resp-interfaces-interface-arista-ceos": &gpb.GetResponse{},
+		"../test/resp-interfaces-wildcard":              &gpb.GetResponse{},
+	}
+	for k, v := range gnmiMessages {
+		if err := util.Read(k, v); err != nil {
+			log.Fatalf("error parsing %v: %v", k, err)
+		}
+	}
 	testSetupGnmi()
 	testSetupPnd()
 	testSetupStore()
 	testSetupSbi()
+	testSetupIntegration()
 	os.Exit(m.Run())
 }
 
@@ -60,6 +80,7 @@ func mockTransport() Gnmi {
 	}
 }
 
+var gnmiMessages map[string]proto.Message
 var gnmiConfig *gnmi.Config
 var startGnmiTarget chan string
 var stopGnmiTarget chan bool
@@ -286,7 +307,7 @@ func TestGnmi_ProcessResponse(t *testing.T) {
 			name:   "Interfaces Interface",
 			fields: fields{Sbi: &OpenConfig{}},
 			args: args{
-				path: "../test/resp-full-node",
+				path: "../test/resp-interfaces-interface-arista-ceos",
 				root: &openconfig.Device{},
 			},
 			wantErr: true,
@@ -313,14 +334,11 @@ func TestGnmi_ProcessResponse(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			g := &Gnmi{
-				SetNode: tt.fields.Sbi.SetNode(),
+				SetNode:   tt.fields.Sbi.SetNode(),
 				Unmarshal: tt.fields.Sbi.(*OpenConfig).Unmarshal(),
 			}
 			s := tt.fields.Sbi.Schema()
-			resp := &gpb.GetResponse{}
-			if err := util.Read(tt.args.path, resp); err != nil {
-				t.Errorf("error reading file %v,", err)
-			}
+			resp := gnmiMessages[tt.args.path]
 			if err := g.ProcessResponse(resp, tt.args.root, s); (err != nil) != tt.wantErr {
 				t.Errorf("ProcessResponse() error = %v, wantErr %v", err, tt.wantErr)
 			}
@@ -382,11 +400,29 @@ func TestGnmi_SetConfig(t *testing.T) {
 		fields fields
 		args   args
 	}{
-		// TODO: Add test cases.
+		{
+			name: "default",
+			fields: fields{
+				SetNode:  nil,
+				RespChan: nil,
+				config:   nil,
+			},
+			args: args{
+				config: &gnmi.Config{
+					Addr:     "test:///",
+					Password: "test",
+					Username: "test",
+				},
+			},
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-
+			g := &Gnmi{}
+			g.SetConfig(tt.args.config)
+			if !reflect.DeepEqual(g.config, tt.args.config) {
+				t.Errorf("Type() = %v, want %v", g.config, tt.args.config)
+			}
 		})
 	}
 }
@@ -407,15 +443,11 @@ func TestGnmi_Subscribe(t *testing.T) {
 		args    args
 		wantErr bool
 	}{
-		// TODO: Add test cases.
+		{name: "nil client", fields: fields{}, args: args{}, wantErr: true},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			g := &Gnmi{
-				SetNode:  tt.fields.SetNode,
-				RespChan: tt.fields.RespChan,
-				config:   tt.fields.config,
-			}
+			g := &Gnmi{}
 			if err := g.Subscribe(tt.args.ctx, tt.args.params...); (err != nil) != tt.wantErr {
 				t.Errorf("Subscribe() error = %v, wantErr %v", err, tt.wantErr)
 			}
@@ -456,30 +488,10 @@ func TestGnmi_get(t *testing.T) {
 
 func TestGnmi_getWithRequest(t *testing.T) {
 	transport := mockTransport()
-	reqFullNode := &gpb.GetRequest{}
-	reqInterfacesWildcard := &gpb.GetRequest{}
-	respFullNode := &gpb.GetResponse{}
-	respInterfacesWildcard := &gpb.GetResponse{}
-	respInterfacesWildcardExp := &gpb.GetResponse{}
-	respFullNodeExp := &gpb.GetResponse{}
-	if err := util.Read("../test/req-full-node", reqFullNode); err != nil {
-		t.Errorf("error parsing req-full-node: %v", err)
-	}
-	if err := util.Read("../test/req-interfaces-wildcard", reqInterfacesWildcard); err != nil {
-		t.Errorf("error parsing req-interfaces-wildcard: %v", err)
-	}
-	if err := util.Read("../test/resp-full-node", respFullNode); err != nil {
-		t.Errorf("error parsing getFullNode: %v", err)
-	}
-	if err := util.Read("../test/resp-full-node", respFullNodeExp); err != nil {
-		t.Errorf("error parsing getFullNode: %v", err)
-	}
-	if err := util.Read("../test/resp-interfaces-wildcard", respInterfacesWildcard); err != nil {
-		t.Errorf("error parsing getFullNode: %v", err)
-	}
-	if err := util.Read("../test/resp-interfaces-wildcard", respInterfacesWildcardExp); err != nil {
-		t.Errorf("error parsing getFullNode: %v", err)
-	}
+	reqFullNode := gnmiMessages["../test/req-full-node"].(*gpb.GetRequest)
+	reqInterfacesWildcard := gnmiMessages["../test/req-interfaces-wildcard"].(*gpb.GetRequest)
+	respFullNode := gnmiMessages["../test/resp-full-node"].(*gpb.GetResponse)
+	respInterfacesWildcard := gnmiMessages["../test/resp-interfaces-wildcard"].(*gpb.GetResponse)
 
 	transport.client.(*mocks.GNMIClient).
 		On("Get", mockContext, reqFullNode).
@@ -509,7 +521,7 @@ func TestGnmi_getWithRequest(t *testing.T) {
 			args: args{
 				request: reqFullNode,
 			},
-			want:    respFullNodeExp,
+			want:    respFullNode,
 			wantErr: false,
 		},
 		{
@@ -518,7 +530,7 @@ func TestGnmi_getWithRequest(t *testing.T) {
 			args: args{
 				request: reqInterfacesWildcard,
 			},
-			want:    respInterfacesWildcardExp,
+			want:    respInterfacesWildcard,
 			wantErr: false,
 		},
 	}
@@ -544,48 +556,74 @@ func TestGnmi_subscribe(t *testing.T) {
 	// TODO: Design integration test for this one
 }
 
-func Test_extractModelKey(t *testing.T) {
+func TestNewGnmiTransport(t *testing.T) {
+	oc := &OpenConfig{}
+	respChan := make(chan *gpb.SubscribeResponse)
 	type args struct {
-		path *gpb.Path
-	}
-	tests := []struct {
-		name string
-		args args
-		want string
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := extractModelKey(tt.args.path); got != tt.want {
-				t.Errorf("extraxtPathElements() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func Test_gnmiFullPath(t *testing.T) {
-	type args struct {
-		prefix *gpb.Path
-		path   *gpb.Path
+		config *gnmi.Config
 	}
 	tests := []struct {
 		name    string
 		args    args
-		want    *gpb.Path
+		want    *Gnmi
 		wantErr bool
 	}{
-		// TODO: Add test cases.
+		{
+			name: "default",
+			args: args{config: &gnmi.Config{
+				Username: "test",
+				Password: "test",
+				Addr:     "localhost:13371",
+				Encoding: gpb.Encoding_PROTO,
+			}},
+			want: &Gnmi{
+				SetNode:   oc.SetNode(),
+				Unmarshal: oc.Unmarshal(),
+				RespChan:  respChan,
+				config: &gnmi.Config{
+					Username: "test",
+					Password: "test",
+					Addr:     "localhost:13371",
+					Encoding: gpb.Encoding_PROTO,
+				},
+				client: nil,
+			},
+			wantErr: false,
+		},
+		{
+			name:    "unsupported compression",
+			args:    args{config: &gnmi.Config{Compression: "brotli"}},
+			want:    nil,
+			wantErr: true,
+		},
+		{
+			name:    "certificate error no key file",
+			args:    args{config: &gnmi.Config{TLS: true, CertFile: "invalid", KeyFile: ""}},
+			want:    nil,
+			wantErr: true,
+		},
+		{
+			name:    "certificate error no ca file",
+			args:    args{config: &gnmi.Config{TLS: true, CAFile: "invalid"}},
+			want:    nil,
+			wantErr: true,
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := gnmiFullPath(tt.args.prefix, tt.args.path)
+			if tt.name == "defaul" {
+				startGnmiTarget <- gnmiConfig.Addr
+			}
+			got, err := NewGnmiTransport(tt.args.config)
 			if (err != nil) != tt.wantErr {
-				t.Errorf("gnmiFullPath() error = %v, wantErr %v", err, tt.wantErr)
+				t.Errorf("NewGnmiTransport() error = %v, wantErr %v", err, tt.wantErr)
 				return
 			}
 			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("gnmiFullPath() got = %v, want %v", got, tt.want)
+				t.Errorf("NewGnmiTransport() got = %v, want %v", got, tt.want)
+			}
+			if tt.name == "defaul" {
+				stopGnmiTarget <- true
 			}
 		})
 	}
diff --git a/nucleus/integration_test.go b/nucleus/integration_test.go
index 6d19a85281d2a6fa206bbacf4719e453ab84f51b..caed6e9d9974f4ed4a39a0399e5dddc13c877939 100644
--- a/nucleus/integration_test.go
+++ b/nucleus/integration_test.go
@@ -2,28 +2,37 @@ package nucleus
 
 import (
 	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
-	"code.fbi.h-da.de/cocsn/gosdn/nucleus/util"
 	"context"
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
+	"os"
 	"reflect"
 	"testing"
 	"time"
 )
 
 var address = "141.100.70.171:6030"
+var cfg *gnmi.Config
+
+func testSetupIntegration() {
+	a := os.Getenv("GOSDN_TEST_ENDPOINT")
+	if a != "" {
+		address = a
+	}
+
+	cfg = &gnmi.Config{
+		Addr:     address,
+		Username: "admin",
+		Password: "arista",
+		Encoding: gpb.Encoding_JSON_IETF,
+	}
+}
 
 func TestGnmi_SetIntegration(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping integration test")
 	}
-	t.Run("Test GNMI Set", func(t *testing.T){
-		cfg := &gnmi.Config{
-			Addr:     address,
-			Username: "admin",
-			Password: "arista",
-			Encoding: gpb.Encoding_JSON_IETF,
-		}
-		transport,err := NewGnmiTransport(cfg)
+	t.Run("Test GNMI Set", func(t *testing.T) {
+		transport, err := NewGnmiTransport(cfg)
 		if err != nil {
 			t.Error(err)
 		}
@@ -42,14 +51,8 @@ func TestGnmi_GetIntegration(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping integration test")
 	}
-	t.Run("Test GNMI Get", func(t *testing.T){
-		cfg := &gnmi.Config{
-			Addr:     address,
-			Username: "admin",
-			Password: "arista",
-			Encoding: gpb.Encoding_JSON_IETF,
-		}
-		transport,err := NewGnmiTransport(cfg)
+	t.Run("Test GNMI Get", func(t *testing.T) {
+		transport, err := NewGnmiTransport(cfg)
 		if err != nil {
 			t.Error(err)
 		}
@@ -68,14 +71,12 @@ func TestGnmi_SubscribeIntegration(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping integration test")
 	}
-	t.Run("Test GNMI Subscribe", func(t *testing.T){
-		cfg := &gnmi.Config{
-			Addr:     address,
-			Username: "admin",
-			Password: "arista",
-			Encoding: gpb.Encoding_JSON_IETF,
-		}
-		transport,err := NewGnmiTransport(cfg)
+	if os.Getenv("GOSDN_TEST_ENDPOINT") != "" {
+		t.Skip("skipping locally running integration test")
+	}
+
+	t.Run("Test GNMI Subscribe", func(t *testing.T) {
+		transport, err := NewGnmiTransport(cfg)
 		if err != nil {
 			t.Error(err)
 		}
@@ -111,31 +112,75 @@ func TestGnmi_CapabilitiesIntegration(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping integration test")
 	}
-	respones := map[string]*gpb.CapabilityResponse{
-		"../test/cap-resp-arista-ceos": {},
+	type fields struct {
+		config *gnmi.Config
 	}
-	for k,v := range respones {
-		if err := util.Read(k, v); err != nil {
-			t.Errorf("error parsing %v: %v", k, err)
-		}
-
-		t.Run("Test GNMI Capabilities", func(t *testing.T) {
-			cfg := &gnmi.Config{
-				Addr:     address,
-				Username: "admin",
-				Password: "arista",
-				Encoding: gpb.Encoding_JSON_IETF,
-			}
-			transport, err := NewGnmiTransport(cfg)
+	type args struct {
+		ctx context.Context
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		want    interface{}
+		wantErr bool
+	}{
+		{
+			name:    "supported models",
+			fields:  fields{config: cfg},
+			args:    args{ctx: context.Background()},
+			want:    gnmiMessages["../test/cap-resp-arista-ceos"].(*gpb.CapabilityResponse).SupportedModels,
+			wantErr: false,
+		},
+		{
+			name:    "supported encodings",
+			fields:  fields{config: cfg},
+			args:    args{ctx: context.Background()},
+			want:    gnmiMessages["../test/cap-resp-arista-ceos"].(*gpb.CapabilityResponse).SupportedEncodings,
+			wantErr: false,
+		},
+		{
+			name:    "gnmi version",
+			fields:  fields{config: cfg},
+			args:    args{ctx: context.Background()},
+			want:    gnmiMessages["../test/cap-resp-arista-ceos"].(*gpb.CapabilityResponse).GNMIVersion,
+			wantErr: false,
+		},
+		{
+			name:	 "destination unreachable",
+			fields:  fields{config: &gnmi.Config{
+				Addr: "203.0.113.10:6030",
+				},
+			},
+			args:    args{ctx: context.Background()},
+			want:    nil,
+			wantErr: true,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			g, err := NewGnmiTransport(tt.fields.config)
 			if err != nil {
 				t.Error(err)
+				return
 			}
-			resp, err := transport.Capabilities(context.Background())
-			if err != nil {
-				t.Error(err)
+			resp, err := g.Capabilities(tt.args.ctx)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("Capabilities() error = %v, wantErr %v", err, tt.wantErr)
+				return
 			}
-			if !reflect.DeepEqual(resp, v) {
-				t.Errorf("Capabilities() = %v, want %v", resp, v)
+			var got interface{}
+			switch tt.name {
+			case "supported encodings":
+				got = resp.(*gpb.CapabilityResponse).SupportedEncodings
+			case "supported models":
+				got = resp.(*gpb.CapabilityResponse).SupportedModels
+			case "gnmi version":
+				got = resp.(*gpb.CapabilityResponse).GNMIVersion
+			default:
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("Type() = %v, want %v", got, tt.want)
 			}
 		})
 	}
@@ -153,4 +198,4 @@ func TestPndImplementation_RequestIntegration(t *testing.T) {
 		t.Skip("skipping integration test")
 	}
 	t.Fail()
-}
\ No newline at end of file
+}
diff --git a/nucleus/restconf_transport.go b/nucleus/restconf_transport.go
index 84d904a562b6c87d84378814b8247ad0df484747..606f818ff0301bdc5d2e37d6a4273f7851c5b6e1 100644
--- a/nucleus/restconf_transport.go
+++ b/nucleus/restconf_transport.go
@@ -9,21 +9,21 @@ type Restconf struct {
 }
 
 func (r Restconf) Get(ctx context.Context, params ...string) (interface{}, error) {
-	panic("implement me")
+	return nil, &ErrNotYetImplemented{}
 }
 
 func (r Restconf) Set(ctx context.Context, params ...string) (interface{}, error) {
-	panic("implement me")
+	return nil, &ErrNotYetImplemented{}
 }
 
 func (r Restconf) Subscribe(ctx context.Context, params ...string) error {
-	panic("implement me")
+	return &ErrNotYetImplemented{}
 }
 
 func (r Restconf) Type() string {
-	panic("implement me")
+	return "restconf"
 }
 
 func (r Restconf) ProcessResponse(resp interface{}, root interface{}, models *ytypes.Schema) error {
-	panic("implement me")
+	return &ErrNotYetImplemented{}
 }
diff --git a/nucleus/restconf_transport_test.go b/nucleus/restconf_transport_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..5f1eb1e352f2cb8214686c5215eea419c465dcd4
--- /dev/null
+++ b/nucleus/restconf_transport_test.go
@@ -0,0 +1,126 @@
+package nucleus
+
+import (
+	"context"
+	"github.com/openconfig/ygot/ytypes"
+	"reflect"
+	"testing"
+)
+
+func TestRestconf_Get(t *testing.T) {
+	type args struct {
+		ctx    context.Context
+		params []string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    interface{}
+		wantErr bool
+	}{
+		{name: "not implemented", args: args{}, want: nil, wantErr: true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			r := Restconf{}
+			got, err := r.Get(tt.args.ctx, tt.args.params...)
+			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 TestRestconf_ProcessResponse(t *testing.T) {
+	type args struct {
+		resp   interface{}
+		root   interface{}
+		models *ytypes.Schema
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{name: "not implemented", args: args{}, wantErr: true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			r := Restconf{}
+			if err := r.ProcessResponse(tt.args.resp, tt.args.root, tt.args.models); (err != nil) != tt.wantErr {
+				t.Errorf("ProcessResponse() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestRestconf_Set(t *testing.T) {
+	type args struct {
+		ctx    context.Context
+		params []string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    interface{}
+		wantErr bool
+	}{
+		{name: "not implemented", args: args{}, want: nil, wantErr: true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			r := Restconf{}
+			got, err := r.Set(tt.args.ctx, tt.args.params...)
+			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 TestRestconf_Subscribe(t *testing.T) {
+	type args struct {
+		ctx    context.Context
+		params []string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{name: "not implemented", args: args{}, wantErr: true},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			r := Restconf{}
+			if err := r.Subscribe(tt.args.ctx, tt.args.params...); (err != nil) != tt.wantErr {
+				t.Errorf("Subscribe() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestRestconf_Type(t *testing.T) {
+	tests := []struct {
+		name string
+		want string
+	}{
+		{name: "not implemented", want: "restconf"},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			r := Restconf{}
+			if got := r.Type(); got != tt.want {
+				t.Errorf("Type() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/nucleus/southbound_test.go b/nucleus/southbound_test.go
index ccd0d298a5aacbdc857db743cbf1ddb8f624ee9a..951f7979c30723e9b2ff281f30c69588529eea93 100644
--- a/nucleus/southbound_test.go
+++ b/nucleus/southbound_test.go
@@ -124,7 +124,7 @@ func TestOpenConfig_Schema(t *testing.T) {
 
 func Test_unmarshal(t *testing.T) {
 	type args struct {
-		path string
+		path     string
 		goStruct interface{}
 		opt      []ytypes.UnmarshalOpt
 	}
@@ -137,7 +137,7 @@ func Test_unmarshal(t *testing.T) {
 			name: "fail",
 			args: args{
 				goStruct: &openconfig.Device{},
-				path: "../test/resp-interfaces-interface-arista-ceos",
+				path:     "../test/resp-interfaces-interface-arista-ceos",
 			},
 			wantErr: true,
 		},
@@ -190,7 +190,7 @@ func Test_unmarshal(t *testing.T) {
 			if err := unmarshal(bytes, fields, tt.args.goStruct, tt.args.opt...); (err != nil) != tt.wantErr {
 				t.Errorf("unmarshal() error = %v, wantErr %v", err, tt.wantErr)
 			}
-			if tt.args.goStruct.(*openconfig.Device).Interfaces == nil && tt.args.opt != nil{
+			if tt.args.goStruct.(*openconfig.Device).Interfaces == nil && tt.args.opt != nil {
 				t.Errorf("unmarshal() error: field Interfaces must not be nil")
 			}
 		})
diff --git a/nucleus/store_test.go b/nucleus/store_test.go
index 8a5f505093a312daf59602c0854a52917cd225c3..012b47a4f1d32634a070ad6d2d695c60eb44d95f 100644
--- a/nucleus/store_test.go
+++ b/nucleus/store_test.go
@@ -365,7 +365,7 @@ func Test_pndStore_get(t *testing.T) {
 					},
 				},
 			},
-			args:    args{id: defaultPndId},
+			args:    args{id: did},
 			wantErr: true,
 		},
 	}