diff --git a/cli/cli_test.go b/cli/cli_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..df6c6ec4d09668c3cf7996599a03bf129441ccf4
--- /dev/null
+++ b/cli/cli_test.go
@@ -0,0 +1,259 @@
+package cli
+
+import (
+	"code.fbi.h-da.de/cocsn/gosdn/forks/google/gnmi"
+	"context"
+	gpb "github.com/openconfig/gnmi/proto/gnmi"
+	"github.com/openconfig/ygot/ygot"
+	"reflect"
+	"testing"
+)
+
+func TestCapabilities(t *testing.T) {
+	type args struct {
+		a string
+		u string
+		p 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) {
+			if err := Capabilities(tt.args.a, tt.args.u, tt.args.p); (err != nil) != tt.wantErr {
+				t.Errorf("Capabilities() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestGet(t *testing.T) {
+	type args struct {
+		a    string
+		u    string
+		p    string
+		args []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) {
+			if err := Get(tt.args.a, tt.args.u, tt.args.p, tt.args.args...); (err != nil) != tt.wantErr {
+				t.Errorf("Get() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestHttpGet(t *testing.T) {
+	type args struct {
+		apiEndpoint string
+		f           string
+		args        []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) {
+			if err := HttpGet(tt.args.apiEndpoint, tt.args.f, tt.args.args...); (err != nil) != tt.wantErr {
+				t.Errorf("HttpGet() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestLeafPaths(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 := LeafPaths(); (err != nil) != tt.wantErr {
+				t.Errorf("LeafPaths() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestPathTraversal(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 := PathTraversal(); (err != nil) != tt.wantErr {
+				t.Errorf("PathTraversal() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestSet(t *testing.T) {
+	type args struct {
+		a    string
+		u    string
+		p    string
+		typ  string
+		args []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) {
+			if err := Set(tt.args.a, tt.args.u, tt.args.p, tt.args.typ, tt.args.args...); (err != nil) != tt.wantErr {
+				t.Errorf("Set() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestSubscribe(t *testing.T) {
+	type args struct {
+		a         string
+		u         string
+		p         string
+		sample    int64
+		heartbeat int64
+		args      []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) {
+			if err := Subscribe(tt.args.a, tt.args.u, tt.args.p, tt.args.sample, tt.args.heartbeat, tt.args.args...); (err != nil) != tt.wantErr {
+				t.Errorf("Subscribe() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestTarget(t *testing.T) {
+	type args struct {
+		bindAddr 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) {
+			if err := Target(tt.args.bindAddr); (err != nil) != tt.wantErr {
+				t.Errorf("Target() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_callback(t *testing.T) {
+	type args struct {
+		newConfig ygot.ValidatedGoStruct
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := callback(tt.args.newConfig); (err != nil) != tt.wantErr {
+				t.Errorf("callback() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func Test_newServer(t *testing.T) {
+	type args struct {
+		model  *gnmi.Model
+		config []byte
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    *server
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := newServer(tt.args.model, tt.args.config)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("newServer() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("newServer() got = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func Test_server_Get(t *testing.T) {
+	type fields struct {
+		Server *gnmi.Server
+	}
+	type args struct {
+		ctx context.Context
+		req *gpb.GetRequest
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		want    *gpb.GetResponse
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			s := &server{
+				Server: tt.fields.Server,
+			}
+			got, err := s.Get(tt.args.ctx, tt.args.req)
+			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)
+			}
+		})
+	}
+}
diff --git a/nucleus/controller.go b/nucleus/controller.go
index e239bca0d3f6e3cc57d948ea8fffb3e10575ec4f..d11781461112cf87a6da752f87d09076099f22b2 100644
--- a/nucleus/controller.go
+++ b/nucleus/controller.go
@@ -20,7 +20,7 @@ type Core struct {
 var c *Core
 
 //Initialize does start-up housekeeping like reading controller config files
-func initialize(ctx context.Context) error {
+func initialize() error {
 	c = &Core{
 		database: database.Database{},
 		pndc:     pndStore{},
@@ -36,9 +36,9 @@ func initialize(ctx context.Context) error {
 	if err := createSouthboundInterfaces(); err != nil {
 		return err
 	}
-	// TODO: Start grpc listener here
 
-	if err := httpApi(ctx); err != nil {
+	// TODO: Start grpc listener here
+	if err := httpApi(); err != nil {
 		return err
 	}
 
@@ -48,21 +48,35 @@ func initialize(ctx context.Context) error {
 }
 
 // deprecated
-// AttachDatabase connects to the database and passes the connection to the controller core
+// attachDatabase connects to the database and passes the connection to the controller core
 func attachDatabase() {
 	c.database = database.NewDatabaseClient()
 }
 
-// CreateSouthboundInterfaces initializes the controller with its supported SBIs
+// createSouthboundInterfaces initializes the controller with its supported SBIs
 func createSouthboundInterfaces() error {
-	if err := c.sbic.add(&OpenConfig{id: uuid.New()}); err != nil {
+	sbi := &OpenConfig{id: uuid.New()}
+	if err := c.sbic.add(sbi); err != nil {
+		return err
+	}
+	return createPrincipalNetworkDomain(sbi)
+}
+
+// createPrincipalNetworkDomain initializes the controller with an initial PND
+func createPrincipalNetworkDomain(sbi SouthboundInterface) error{
+	pnd, err := NewPND("base", "gosdn base pnd", uuid.New(), sbi)
+	if err != nil {
+		return err
+	}
+	err = c.pndc.add(pnd)
+	if err != nil {
 		return err
 	}
 	return nil
 }
 
 func Run(ctx context.Context) error {
-	if err := initialize(ctx); err != nil {
+	if err := initialize(); err != nil {
 		log.WithFields(log.Fields{}).Error(err)
 		return err
 	}
diff --git a/nucleus/errors_test.go b/nucleus/errors_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..09d172db926b14465fb4e16f641017a4f6d430ae
--- /dev/null
+++ b/nucleus/errors_test.go
@@ -0,0 +1,196 @@
+package nucleus
+
+import "testing"
+
+func TestErrAlreadyExists_Error(t *testing.T) {
+	type fields struct {
+		item interface{}
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			e := &ErrAlreadyExists{
+				item: tt.fields.item,
+			}
+			if got := e.Error(); got != tt.want {
+				t.Errorf("Error() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestErrInvalidParameters_Error(t *testing.T) {
+	type fields struct {
+		f interface{}
+		r interface{}
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			e := ErrInvalidParameters{
+				f: tt.fields.f,
+				r: tt.fields.r,
+			}
+			if got := e.Error(); got != tt.want {
+				t.Errorf("Error() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestErrInvalidTransportOptions_Error(t *testing.T) {
+	type fields struct {
+		t interface{}
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			e := ErrInvalidTransportOptions{
+				t: tt.fields.t,
+			}
+			if got := e.Error(); got != tt.want {
+				t.Errorf("Error() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestErrInvalidTypeAssertion_Error(t *testing.T) {
+	type fields struct {
+		v interface{}
+		t interface{}
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			e := ErrInvalidTypeAssertion{
+				v: tt.fields.v,
+				t: tt.fields.t,
+			}
+			if got := e.Error(); got != tt.want {
+				t.Errorf("Error() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestErrNilClient_Error(t *testing.T) {
+	tests := []struct {
+		name string
+		want string
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			e := &ErrNilClient{}
+			if got := e.Error(); got != tt.want {
+				t.Errorf("Error() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestErrNil_Error(t *testing.T) {
+	tests := []struct {
+		name string
+		want string
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			e := &ErrNil{}
+			if got := e.Error(); got != tt.want {
+				t.Errorf("Error() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestErrNotFound_Error(t *testing.T) {
+	type fields struct {
+		id interface{}
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			e := &ErrNotFound{
+				id: tt.fields.id,
+			}
+			if got := e.Error(); got != tt.want {
+				t.Errorf("Error() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestErrNotYetImplemented_Error(t *testing.T) {
+	tests := []struct {
+		name string
+		want string
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			e := ErrNotYetImplemented{}
+			if got := e.Error(); got != tt.want {
+				t.Errorf("Error() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestErrUnsupportedPath_Error(t *testing.T) {
+	type fields struct {
+		p interface{}
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		want   string
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			e := ErrUnsupportedPath{
+				p: tt.fields.p,
+			}
+			if got := e.Error(); got != tt.want {
+				t.Errorf("Error() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/nucleus/http.go b/nucleus/http.go
index 5d6e17763a453df3296dd274da715e8ffac5203e..3c2980c9a031b785bed60b3a23eab13544547eb2 100644
--- a/nucleus/http.go
+++ b/nucleus/http.go
@@ -2,7 +2,6 @@ package nucleus
 
 import (
 	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
-	"context"
 	"fmt"
 	"github.com/google/uuid"
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
@@ -13,124 +12,121 @@ import (
 
 const basePath = "/api"
 
-func httpApi(ctx context.Context) (err error) {
-	id := c.sbic.UUIDs()[0]
-	sbi, err := c.sbic.get(id)
+// deprecated
+func httpApi() (err error) {
+	http.HandleFunc(basePath, httpHandler)
+
+	go func() {
+		err = http.ListenAndServe(":8080", nil)
+		if err != nil {
+			return
+		}
+	}()
+	return nil
+}
+
+func httpHandler(writer http.ResponseWriter, request *http.Request) {
+	log.WithFields(log.Fields{
+		"request": request,
+	}).Debug("incoming request")
+
+	query, err := url.ParseQuery(request.URL.RawQuery)
 	if err != nil {
+		log.Error(err)
 		return
 	}
-	pnd, err := NewPND("http", "http base pnd", uuid.New(), sbi)
+
+	id, err := uuid.Parse(query.Get("uuid"))
 	if err != nil {
-		return
+		log.Error(err)
 	}
-	err = c.pndc.add(pnd)
+
+	pid, err := uuid.Parse(query.Get("pnd"))
 	if err != nil {
-		return
+		log.Error(err)
 	}
 
-	httpHandler := func(writer http.ResponseWriter, request *http.Request) {
-		log.WithFields(log.Fields{
-			"request": request,
-		}).Debug("incoming request")
+	pnd, err := c.pndc.get(pid)
+
+	sbi := pnd.GetSBIs()
 
-		query, err := url.ParseQuery(request.URL.RawQuery)
+	switch query.Get("q") {
+	case "addDevice":
+		d, err := NewDevice(sbi, &GnmiTransportOptions{
+			Config: gnmi.Config{
+				Addr:     query.Get("address"),
+				Password: query.Get("password"),
+				Username: query.Get("username"),
+				Encoding: gpb.Encoding_JSON_IETF,
+			},
+			SetNode:   sbi.SetNode(),
+			Unmarshal: sbi.(*OpenConfig).Unmarshal(),
+			RespChan:  make(chan *gpb.SubscribeResponse),
+		})
+		err = pnd.AddDevice(d)
 		if err != nil {
+			writer.WriteHeader(http.StatusBadRequest)
 			log.Error(err)
 			return
 		}
-
-		id, err := uuid.Parse(query.Get("uuid"))
+		writer.WriteHeader(http.StatusCreated)
+		fmt.Fprintf(writer, "device added\n")
+		fmt.Fprintf(writer, "UUID: %v\n", d.Uuid)
+	case "request":
+		err = pnd.Request(id, query.Get("path"))
 		if err != nil {
+			switch err.(type) {
+			case *ErrNotFound:
+				writer.WriteHeader(http.StatusNotFound)
+			default:
+				writer.WriteHeader(http.StatusInternalServerError)
+			}
 			log.Error(err)
+			return
 		}
-
-		switch query.Get("q") {
-		case "addDevice":
-			d, err := NewDevice(sbi, &GnmiTransportOptions{
-				Config: gnmi.Config{
-					Addr:     query.Get("address"),
-					Password: query.Get("password"),
-					Username: query.Get("username"),
-					Encoding: gpb.Encoding_JSON_IETF,
-				},
-				SetNode:   sbi.SetNode(),
-				Unmarshal: sbi.(*OpenConfig).Unmarshal(),
-				RespChan:  make(chan *gpb.SubscribeResponse),
-			})
-			err = pnd.AddDevice(d)
-			if err != nil {
-				writer.WriteHeader(http.StatusBadRequest)
-				log.Error(err)
-				return
-			}
-			writer.WriteHeader(http.StatusCreated)
-			fmt.Fprintf(writer, "device added\n")
-			fmt.Fprintf(writer, "UUID: %v\n", d.Uuid)
-		case "request":
-			err = pnd.Request(id, query.Get("path"))
-			if err != nil {
-				switch err.(type) {
-				case *ErrNotFound:
-					writer.WriteHeader(http.StatusNotFound)
-				default:
-					writer.WriteHeader(http.StatusInternalServerError)
-				}
-				log.Error(err)
-				return
-			}
-			writer.WriteHeader(http.StatusOK)
-		case "requestAll":
-			err = pnd.RequestAll(query.Get("path"))
-			if err != nil {
-				switch err.(type) {
-				case *ErrNotFound:
-					writer.WriteHeader(http.StatusNotFound)
-				default:
-					writer.WriteHeader(http.StatusInternalServerError)
-				}
-				log.Error(err)
-				return
-			}
-			writer.WriteHeader(http.StatusOK)
-		case "getDevice":
-			device, err := pnd.MarshalDevice(id)
-			if err != nil {
-				switch err.(type) {
-				case *ErrNotFound:
-					writer.WriteHeader(http.StatusNotFound)
-				default:
-					writer.WriteHeader(http.StatusInternalServerError)
-				}
-				log.Error(err)
-				return
-			}
-			writer.Header().Set("Content-Type", "application/json")
-			fmt.Fprintf(writer, "%v", device)
-		case "getIDs":
-			ids := pnd.(*pndImplementation).devices.UUIDs()
-			for i, id := range ids {
-				fmt.Fprintf(writer, "%v: %v\n", i+1, id)
+		writer.WriteHeader(http.StatusOK)
+	case "requestAll":
+		err = pnd.RequestAll(query.Get("path"))
+		if err != nil {
+			switch err.(type) {
+			case *ErrNotFound:
+				writer.WriteHeader(http.StatusNotFound)
+			default:
+				writer.WriteHeader(http.StatusInternalServerError)
 			}
-		case "set":
-			resp, err := pnd.(*pndImplementation).Set(id, query.Get("path"), query.Get("value"))
-			if err != nil {
+			log.Error(err)
+			return
+		}
+		writer.WriteHeader(http.StatusOK)
+	case "getDevice":
+		device, err := pnd.MarshalDevice(id)
+		if err != nil {
+			switch err.(type) {
+			case *ErrNotFound:
+				writer.WriteHeader(http.StatusNotFound)
+			default:
 				writer.WriteHeader(http.StatusInternalServerError)
-				log.Error(err)
-				return
 			}
-			writer.WriteHeader(http.StatusOK)
-			fmt.Fprintln(writer, resp)
-		default:
-			writer.WriteHeader(http.StatusBadRequest)
+			log.Error(err)
+			return
 		}
-	}
-	http.HandleFunc(basePath, httpHandler)
-
-	go func() {
-		err = http.ListenAndServe(":8080", nil)
+		writer.Header().Set("Content-Type", "application/json")
+		fmt.Fprintf(writer, "%v", device)
+	case "getIDs":
+		ids := pnd.(*pndImplementation).devices.UUIDs()
+		for i, id := range ids {
+			fmt.Fprintf(writer, "%v: %v\n", i+1, id)
+		}
+	case "set":
+		resp, err := pnd.(*pndImplementation).Set(id, query.Get("path"), query.Get("value"))
 		if err != nil {
+			writer.WriteHeader(http.StatusInternalServerError)
+			log.Error(err)
 			return
 		}
-	}()
-	return nil
-}
+		writer.WriteHeader(http.StatusOK)
+		fmt.Fprintln(writer, resp)
+	default:
+		writer.WriteHeader(http.StatusBadRequest)
+	}
+}
\ No newline at end of file
diff --git a/nucleus/http_test.go b/nucleus/http_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..9221ee253c7b7d4890e472d98dcf9122f59d164c
--- /dev/null
+++ b/nucleus/http_test.go
@@ -0,0 +1,26 @@
+package nucleus
+
+import (
+	"context"
+	"testing"
+)
+
+func Test_httpApi(t *testing.T) {
+	type args struct {
+		ctx context.Context
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := httpApi(tt.args.ctx); (err != nil) != tt.wantErr {
+				t.Errorf("httpApi() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}