diff --git a/tests/core/grpc_nbi_api_handler_client_test.go b/tests/core/grpc_nbi_api_handler_client_test.go
new file mode 100644
index 0000000..420bf39
--- /dev/null
+++ b/tests/core/grpc_nbi_api_handler_client_test.go
@@ -0,0 +1,693 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package core
+
+import (
+	"context"
+	"fmt"
+	com "github.com/opencord/voltha-go/adapters/common"
+	"github.com/golang/protobuf/ptypes/empty"
+	"github.com/opencord/voltha-go/common/log"
+	"github.com/opencord/voltha-go/protos/common"
+	"github.com/opencord/voltha-go/protos/openflow_13"
+	"github.com/opencord/voltha-go/protos/voltha"
+	"github.com/stretchr/testify/assert"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/grpc/status"
+	"os"
+	"os/exec"
+	"strings"
+	"testing"
+	"time"
+)
+
+var conn *grpc.ClientConn
+var stub voltha.VolthaServiceClient
+var testMode string
+
+/*
+Prerequite:  These tests require the rw_core to run prior to executing these test cases.
+*/
+
+var devices map[string]*voltha.Device
+
+//func init() {
+//	log.AddPackage(log.JSON, log.ErrorLevel, nil)
+//	log.UpdateAllLoggers(log.Fields{"instanceId": "testing"})
+//	log.SetAllLogLevel(log.ErrorLevel)
+//
+//	//Start kafka and Etcd
+//	startKafkaEtcd()
+//	time.Sleep(10 * time.Second) //TODO: Find a better way to ascertain they are up
+//
+//	stub = setupGrpcConnection()
+//	stub = voltha.NewVolthaServiceClient(conn)
+//	devices = make(map[string]*voltha.Device)
+//}
+
+func setup() {
+	var err error
+
+	if _, err = log.AddPackage(log.JSON, log.WarnLevel, log.Fields{"instanceId": "testing"}); err != nil {
+		log.With(log.Fields{"error": err}).Fatal("Cannot setup logging")
+	}
+	log.UpdateAllLoggers(log.Fields{"instanceId": "testing"})
+	log.SetAllLogLevel(log.ErrorLevel)
+
+	//Start kafka and Etcd
+	startKafka()
+	startEtcd()
+	time.Sleep(10 * time.Second) //TODO: Find a better way to ascertain they are up
+
+	stub = setupGrpcConnection()
+	testMode = common.TestModeKeys_api_test.String()
+	devices = make(map[string]*voltha.Device)
+}
+
+func setupGrpcConnection() voltha.VolthaServiceClient {
+	grpcHostIP := os.Getenv("DOCKER_HOST_IP")
+	grpcPort := 50057
+	grpcHost := fmt.Sprintf("%s:%d", grpcHostIP, grpcPort)
+	var err error
+	conn, err = grpc.Dial(grpcHost, grpc.WithInsecure())
+	if err != nil {
+		log.Fatalf("did not connect: %s", err)
+	}
+	return voltha.NewVolthaServiceClient(conn)
+}
+
+func clearAllDevices(clearMap bool) {
+	for key, _ := range devices {
+		ctx := context.Background()
+		response, err := stub.DeleteDevice(ctx, &voltha.ID{Id: key})
+		log.Infow("response", log.Fields{"res": response, "error": err})
+		if clearMap {
+			delete(devices, key)
+		}
+	}
+}
+
+// Verify if all ids are present in the global list of devices
+func hasAllIds(ids *voltha.IDs) bool {
+	if ids == nil && len(devices) == 0 {
+		return true
+	}
+	if ids == nil {
+		return false
+	}
+	for _, id := range ids.Items {
+		if _, exist := devices[id.Id]; !exist {
+			return false
+		}
+	}
+	return true
+}
+
+func startKafka() {
+	fmt.Println("Starting Kafka and Etcd ...")
+	command := "docker-compose"
+	cmd := exec.Command(command, "-f", "../../compose/docker-compose-zk-kafka-test.yml", "up", "-d")
+	if err := cmd.Run(); err != nil {
+		log.Fatal(err)
+	}
+}
+
+func startEtcd() {
+	fmt.Println("Starting Etcd ...")
+	command := "docker-compose"
+	cmd := exec.Command(command, "-f", "../../compose/docker-compose-etcd.yml", "up", "-d")
+	if err := cmd.Run(); err != nil {
+		log.Fatal(err)
+	}
+}
+
+func stopKafka() {
+	fmt.Println("Stopping Kafka and Etcd ...")
+	command := "docker-compose"
+	cmd := exec.Command(command, "-f", "../../compose/docker-compose-zk-kafka-test.yml", "down")
+	if err := cmd.Run(); err != nil {
+		// ignore error - as this is mostly due network being left behind as its being used by other
+		// containers
+		log.Warn(err)
+	}
+}
+
+func stopEtcd() {
+	fmt.Println("Stopping Etcd ...")
+	command := "docker-compose"
+	cmd := exec.Command(command, "-f", "../../compose/docker-compose-etcd.yml", "down")
+	if err := cmd.Run(); err != nil {
+		// ignore error - as this is mostly due network being left behind as its being used by other
+		// containers
+		log.Warn(err)
+	}
+}
+
+func startCore() {
+	fmt.Println("Starting voltha core ...")
+	command := "docker-compose"
+	cmd := exec.Command(command, "-f", "../../compose/rw_core.yml", "up", "-d")
+	if err := cmd.Run(); err != nil {
+		log.Fatal(err)
+	}
+}
+
+func stopCore() {
+	fmt.Println("Stopping voltha core ...")
+	command := "docker-compose"
+	cmd := exec.Command(command, "-f", "../../compose/rw_core.yml", "down")
+	if err := cmd.Run(); err != nil {
+		// ignore error - as this is mostly due network being left behind as its being used by other
+		// containers
+		log.Warn(err)
+	}
+}
+
+func startSimulatedOLTAndONUAdapters() {
+	fmt.Println("Starting simulated OLT and ONU adapters ...")
+	command := "docker-compose"
+	cmd := exec.Command(command, "-f", "../../compose/adapters-simulated.yml", "up", "-d")
+	if err := cmd.Run(); err != nil {
+		log.Fatal(err)
+	}
+}
+
+func stopSimulatedOLTAndONUAdapters() {
+	fmt.Println("Stopping simulated OLT and ONU adapters ...")
+	command := "docker-compose"
+	cmd := exec.Command(command, "-f", "../../compose/adapters-simulated.yml", "down")
+	if err := cmd.Run(); err != nil {
+		// ignore error - as this is mostly due network being left behind as its being used by other
+		// containers
+		log.Warn(err)
+	}
+}
+
+
+func TestListDeviceIds(t *testing.T) {
+	fmt.Println("Testing list Devices Ids ...")
+	//0. Start kafka and Ectd
+	startKafka()
+	startEtcd()
+
+	//1. Start the core
+	startCore()
+
+	// Wait until it's up - TODO: find a better way to check
+	time.Sleep(10 * time.Second)
+
+	//2. Create a set of devices into the Core
+	for i := 0; i < 10; i++ {
+		ctx := context.Background()
+		device := &voltha.Device{Type: "simulated_olt"}
+		response, err := stub.CreateDevice(ctx, device)
+		log.Infow("response", log.Fields{"res": response, "error": err})
+		assert.NotNil(t, response)
+		assert.Nil(t, err)
+		devices[response.Id] = response
+	}
+
+	//3. Verify devices have been added correctly
+	ctx := context.Background()
+	response, err := stub.ListDeviceIds(ctx, &empty.Empty{})
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Nil(t, err)
+	assert.True(t, hasAllIds(response))
+
+	//4. Stop the core
+	stopCore()
+
+	//5. Stop Kafka and Etcd
+	stopKafka()
+	stopEtcd()
+}
+
+func TestReconcileDevices(t *testing.T) {
+	fmt.Println("Testing Reconcile Devices ...")
+
+	//0. Start kafka and Ectd
+	startKafka()
+	startEtcd()
+
+	//1. Start the core
+	startCore()
+
+	// Wait until it's up - TODO: find a better way to check
+	time.Sleep(10 * time.Second)
+
+	//2. Create a set of devices into the Core
+	for i := 0; i < 10; i++ {
+		ctx := context.Background()
+		device := &voltha.Device{Type: "simulated_olt"}
+		response, err := stub.CreateDevice(ctx, device)
+		log.Infow("response", log.Fields{"res": response, "error": err})
+		assert.Nil(t, err)
+		devices[response.Id] = response
+	}
+	//3. Verify devices have been added correctly
+	ctx := context.Background()
+	response, err := stub.ListDeviceIds(ctx, &empty.Empty{})
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Nil(t, err)
+	assert.True(t, hasAllIds(response))
+
+	//4. Stop the core and restart it. This will start the core with no data in memory but
+	// etcd will still have the data.
+	stopCore()
+	time.Sleep(5 * time.Second)
+	startCore()
+	time.Sleep(10 * time.Second)
+
+	//5. Setup the connection again
+	stub = setupGrpcConnection()
+
+	//6. Verify there are no devices left
+	ctx = context.Background()
+	response, err = stub.ListDeviceIds(ctx, &empty.Empty{})
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Nil(t, err)
+	assert.Equal(t, len(response.Items), 0)
+
+	//7. Invoke reconcile with all stored list
+	toRestore := &voltha.IDs{Items: make([]*voltha.ID, 0)}
+	for key, _ := range devices {
+		toRestore.Items = append(toRestore.Items, &voltha.ID{Id: key})
+	}
+	ctx = context.Background()
+	_, err = stub.ReconcileDevices(ctx, toRestore)
+	assert.Nil(t, err)
+
+	//8. Verify all devices have been restored
+	ctx = context.Background()
+	response, err = stub.ListDeviceIds(ctx, &empty.Empty{})
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Nil(t, err)
+	assert.True(t, hasAllIds(response))
+
+	for _, id := range response.Items {
+		fmt.Println("id", id.Id)
+	}
+
+	//9. Store the core
+	stopCore()
+
+	//10. Stop Kafka and Etcd
+	stopKafka()
+	stopEtcd()
+}
+
+func TestDeviceManagement(t *testing.T) {
+	fmt.Println("Testing Device Management ...")
+
+	numberOfOLTDevices := 1
+
+	//0. Start kafka and Ectd
+	startKafka()
+	startEtcd()
+
+	//1. Start the core
+	startCore()
+
+	//2. Start the simulated adapters
+	startSimulatedOLTAndONUAdapters()
+
+	// Wait until the core and adapters sync up
+	time.Sleep(10 * time.Second)
+
+	//3. Create a set of devices into the Core
+	devices = make(map[string]*voltha.Device)
+	logicalDevices := make(map[string]*voltha.LogicalDevice)
+	for i := 0; i < numberOfOLTDevices; i++ {
+		ctx := context.Background()
+		randomMacAddress := strings.ToUpper(com.GetRandomMacAddress())
+		device := &voltha.Device{Type: "simulated_olt", MacAddress:randomMacAddress}
+		response, err := stub.CreateDevice(ctx, device)
+		log.Infow("response", log.Fields{"res": response, "error": err})
+		assert.Nil(t, err)
+		devices[response.Id] = response
+	}
+
+	//4. Enable all the devices
+	for id, _ := range devices {
+		ctx := context.Background()
+		response, err := stub.EnableDevice(ctx, &common.ID{Id:id})
+		log.Infow("response", log.Fields{"res": response, "error": err})
+		assert.Nil(t, err)
+	}
+
+	// Wait until all devices have been enabled
+	if numberOfOLTDevices < 5 {
+		time.Sleep(3 * time.Second)
+	} else if numberOfOLTDevices < 20 {
+		time.Sleep(20 * time.Second)
+	} else {
+		time.Sleep(30 * time.Second)
+	}
+	//time.Sleep(1 * time.Second * time.Duration(numberOfDevices))
+
+	//5. Verify that all devices are in enabled state
+	ctx := context.Background()
+	response, err := stub.ListDevices(ctx, &empty.Empty{})
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Nil(t, err)
+	assert.Equal(t, len(devices)*2, len(response.Items))
+	for _, d := range (response.Items) {
+		devices[d.Id] = d
+		assert.Equal(t, d.AdminState, voltha.AdminState_ENABLED)
+	}
+
+	//6. Get the logical devices
+	ctx = context.Background()
+	lresponse, lerr := stub.ListLogicalDevices(ctx, &empty.Empty{})
+	log.Infow("response", log.Fields{"res": response, "error": lerr})
+	assert.Nil(t, lerr)
+	assert.Equal(t, numberOfOLTDevices, len(lresponse.Items))
+	for _, ld := range (lresponse.Items) {
+		logicalDevices[ld.Id] = ld
+		// Ensure each logical device have two ports
+		assert.Equal(t, 2, len(ld.Ports))
+	}
+
+	//7. Disable all ONUs & check status & check logical device
+	for id, d := range devices {
+		ctx := context.Background()
+		if d.Type == "simulated_onu" {
+			response, err := stub.DisableDevice(ctx, &common.ID{Id:id})
+			log.Infow("response", log.Fields{"res": response, "error": err})
+			assert.Nil(t, err)
+		}
+	}
+
+	// Wait for all the changes to be populated
+	time.Sleep(3 * time.Second)
+
+	ctx = context.Background()
+	response, err = stub.ListDevices(ctx, &empty.Empty{})
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Nil(t, err)
+	assert.Equal(t, len(devices), len(response.Items))
+	for _, d := range (response.Items) {
+		if d.Type == "simulated_onu" {
+			assert.Equal(t, d.AdminState, voltha.AdminState_DISABLED)
+			devices[d.Id] = d
+		} else {
+			assert.Equal(t, d.AdminState, voltha.AdminState_ENABLED)
+		}
+	}
+
+	ctx = context.Background()
+	lresponse, lerr = stub.ListLogicalDevices(ctx, &empty.Empty{})
+	log.Infow("response", log.Fields{"res": response, "error": lerr})
+	assert.Nil(t, lerr)
+	assert.Equal(t, numberOfOLTDevices, len(lresponse.Items))
+	for _, ld := range (lresponse.Items) {
+		logicalDevices[ld.Id] = ld
+		// Ensure each logical device have one port - only olt port
+		assert.Equal(t, 1, len(ld.Ports))
+	}
+
+	//8. Enable all ONUs & check status & check logical device
+	for id, d := range devices {
+		ctx := context.Background()
+		if d.Type == "simulated_onu" {
+			response, err := stub.EnableDevice(ctx, &common.ID{Id:id})
+			log.Infow("response", log.Fields{"res": response, "error": err})
+			assert.Nil(t, err)
+		}
+	}
+
+	// Wait for all the changes to be populated
+	time.Sleep(3 * time.Second)
+
+	ctx = context.Background()
+	response, err = stub.ListDevices(ctx, &empty.Empty{})
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Nil(t, err)
+	assert.Equal(t, len(devices), len(response.Items))
+	for _, d := range (response.Items) {
+		assert.Equal(t, d.AdminState, voltha.AdminState_ENABLED)
+		devices[d.Id] = d
+	}
+
+	//ctx = context.Background()
+	//lresponse, lerr = stub.ListLogicalDevices(ctx, &empty.Empty{})
+	//log.Infow("response", log.Fields{"res": response, "error": lerr})
+	//assert.Nil(t, lerr)
+	//assert.Equal(t, numberOfOLTDevices, len(lresponse.Items))
+	//for _, ld := range (lresponse.Items) {
+	//	logicalDevices[ld.Id] = ld
+	//	// Ensure each logical device have two ports
+	//	assert.Equal(t, 2, len(ld.Ports))
+	//}
+
+	//9. Disable all OLTs & check status & check logical device
+
+	//10. Enable all OLTs & Enable all ONUs & check status & check logical device
+
+	//11. Disable all OLTs & check status & check logical device
+
+	//12. Delete all Devices & check status & check logical device
+
+	////13. Store simulated adapters
+	//stopSimulatedOLTAndONUAdapters()
+	//
+	////14. Store the core
+	//stopCore()
+	//
+	////15. Stop Kafka and Etcd
+	//stopKafka()
+	//stopEtcd()
+}
+
+
+func TestGetDevice(t *testing.T) {
+	var id common.ID
+	id.Id = "anyid"
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	response, err := stub.GetDevice(ctx, &id)
+	assert.Nil(t, response)
+	st, _ := status.FromError(err)
+	assert.Equal(t, id.Id, st.Message())
+	assert.Equal(t, codes.NotFound, st.Code())
+}
+
+func TestUpdateLogLevelError(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	level := voltha.Logging{PackageName: "github.com/opencord/voltha-go/rw_core/core", Level: common.LogLevel_ERROR}
+	response, err := stub.UpdateLogLevel(ctx, &level)
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Equal(t, &empty.Empty{}, response)
+	assert.Nil(t, err)
+}
+
+func TestGetVoltha(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	response, err := stub.GetVoltha(ctx, &empty.Empty{})
+	assert.Nil(t, response)
+	st, _ := status.FromError(err)
+	assert.Equal(t, "UnImplemented", st.Message())
+}
+
+func TestUpdateLogLevelDebug(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	level := voltha.Logging{PackageName: "github.com/opencord/voltha-go/rw_core/core", Level: common.LogLevel_DEBUG}
+	response, err := stub.UpdateLogLevel(ctx, &level)
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Equal(t, &empty.Empty{}, response)
+	assert.Nil(t, err)
+}
+
+func TestGetCoreInstance(t *testing.T) {
+	id := &voltha.ID{Id: "getCoreInstance"}
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	response, err := stub.GetCoreInstance(ctx, id)
+	assert.Nil(t, response)
+	st, _ := status.FromError(err)
+	assert.Equal(t, "UnImplemented", st.Message())
+}
+
+func TestGetLogicalDevice(t *testing.T) {
+	id := &voltha.ID{Id: "getLogicalDevice"}
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	response, err := stub.GetLogicalDevice(ctx, id)
+	assert.Nil(t, response)
+	st, _ := status.FromError(err)
+	assert.Equal(t, id.Id, st.Message())
+	assert.Equal(t, codes.NotFound, st.Code())
+}
+
+func TestGetLogicalDevicePort(t *testing.T) {
+	id := &voltha.LogicalPortId{Id: "GetLogicalDevicePort"}
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	response, err := stub.GetLogicalDevicePort(ctx, id)
+	assert.Nil(t, response)
+	st, _ := status.FromError(err)
+	assert.Equal(t, "UnImplemented", st.Message())
+}
+
+func TestListLogicalDevicePorts(t *testing.T) {
+	id := &voltha.ID{Id: "listLogicalDevicePorts"}
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	response, err := stub.ListLogicalDevicePorts(ctx, id)
+	assert.Nil(t, response)
+	st, _ := status.FromError(err)
+	assert.Equal(t, "UnImplemented", st.Message())
+}
+
+func TestListLogicalDeviceFlows(t *testing.T) {
+	id := &voltha.ID{Id: "ListLogicalDeviceFlows"}
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	response, err := stub.ListLogicalDeviceFlows(ctx, id)
+	assert.Nil(t, response)
+	st, _ := status.FromError(err)
+	assert.Equal(t, "UnImplemented", st.Message())
+}
+
+func TestListLogicalDeviceFlowGroups(t *testing.T) {
+	id := &voltha.ID{Id: "ListLogicalDeviceFlowGroups"}
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	response, err := stub.ListLogicalDeviceFlowGroups(ctx, id)
+	assert.Nil(t, response)
+	st, _ := status.FromError(err)
+	assert.Equal(t, "UnImplemented", st.Message())
+}
+
+func TestListDevices(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	response, _ := stub.ListDevices(ctx, &empty.Empty{})
+	assert.Equal(t, len(response.Items), 0)
+}
+
+func TestListAdapters(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	response, err := stub.ListAdapters(ctx, &empty.Empty{})
+	assert.Nil(t, response)
+	st, _ := status.FromError(err)
+	assert.Equal(t, "UnImplemented", st.Message())
+}
+
+func TestListLogicalDevices(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	response, _ := stub.ListLogicalDevices(ctx, &empty.Empty{})
+	assert.Equal(t, len(response.Items), 0)
+}
+
+func TestListCoreInstances(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	response, err := stub.ListCoreInstances(ctx, &empty.Empty{})
+	assert.Nil(t, response)
+	st, _ := status.FromError(err)
+	assert.Equal(t, "UnImplemented", st.Message())
+}
+
+func TestCreateDevice(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	device := &voltha.Device{Id: "newdevice"}
+	response, err := stub.CreateDevice(ctx, device)
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Equal(t, &voltha.Device{Id: "newdevice"}, response)
+	assert.Nil(t, err)
+}
+
+func TestEnableDevice(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	id := &voltha.ID{Id: "enabledevice"}
+	response, err := stub.EnableDevice(ctx, id)
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Equal(t, &empty.Empty{}, response)
+	assert.Nil(t, err)
+}
+
+func TestDisableDevice(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	id := &voltha.ID{Id: "DisableDevice"}
+	response, err := stub.DisableDevice(ctx, id)
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Equal(t, &empty.Empty{}, response)
+	assert.Nil(t, err)
+}
+
+func TestRebootDevice(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	id := &voltha.ID{Id: "RebootDevice"}
+	response, err := stub.RebootDevice(ctx, id)
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Equal(t, &empty.Empty{}, response)
+	assert.Nil(t, err)
+}
+
+func TestDeleteDevice(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	id := &voltha.ID{Id: "DeleteDevice"}
+	response, err := stub.DeleteDevice(ctx, id)
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Equal(t, &empty.Empty{}, response)
+	assert.Nil(t, err)
+}
+
+func TestEnableLogicalDevicePort(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	id := &voltha.LogicalPortId{Id: "EnableLogicalDevicePort"}
+	response, err := stub.EnableLogicalDevicePort(ctx, id)
+	if e, ok := status.FromError(err); ok {
+		log.Infow("response", log.Fields{"error": err, "errorcode": e.Code(), "msg": e.Message()})
+	}
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Equal(t, &empty.Empty{}, response)
+	assert.Nil(t, err)
+}
+
+func TestDisableLogicalDevicePort(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	id := &voltha.LogicalPortId{Id: "DisableLogicalDevicePort"}
+	response, err := stub.DisableLogicalDevicePort(ctx, id)
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Equal(t, &empty.Empty{}, response)
+	assert.Nil(t, err)
+}
+
+func TestUpdateLogicalDeviceFlowGroupTable(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	flow := &openflow_13.FlowGroupTableUpdate{Id: "UpdateLogicalDeviceFlowGroupTable"}
+	response, err := stub.UpdateLogicalDeviceFlowGroupTable(ctx, flow)
+	log.Infow("response", log.Fields{"res": response, "error": err})
+	assert.Equal(t, &empty.Empty{}, response)
+	assert.Nil(t, err)
+}
+
+func TestGetImageDownloadStatus(t *testing.T) {
+	ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs(testMode, "true"))
+	img := &voltha.ImageDownload{Id: "GetImageDownloadStatus"}
+	response, err := stub.GetImageDownloadStatus(ctx, img)
+	assert.Nil(t, response)
+	st, _ := status.FromError(err)
+	assert.Equal(t, "UnImplemented", st.Message())
+}
+
+// TODO: complete the remaining tests
+
+func shutdown() {
+	conn.Close()
+}
+
+func TestMain(m *testing.M) {
+	setup()
+	code := m.Run()
+	shutdown()
+	os.Exit(code)
+}
diff --git a/tests/core/nbi_test.go b/tests/core/nbi_test.go
deleted file mode 100644
index 6e1b531..0000000
--- a/tests/core/nbi_test.go
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright 2018-present Open Networking Foundation
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
-
- * http://www.apache.org/licenses/LICENSE-2.0
-
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package core
-
-import (
-	"context"
-	"fmt"
-	"github.com/golang/protobuf/ptypes/empty"
-	"github.com/opencord/voltha-go/common/log"
-	"github.com/opencord/voltha-go/protos/voltha"
-	"github.com/stretchr/testify/assert"
-	"google.golang.org/grpc"
-	"os"
-	"os/exec"
-	"testing"
-	"time"
-)
-
-var conn *grpc.ClientConn
-var stub voltha.VolthaServiceClient
-var devices map[string]*voltha.Device
-
-func init() {
-	log.AddPackage(log.JSON, log.ErrorLevel, nil)
-	log.UpdateAllLoggers(log.Fields{"instanceId": "testing"})
-	log.SetAllLogLevel(log.ErrorLevel)
-
-	//Start kafka and Etcd
-	startKafkaEtcd()
-	time.Sleep(10 * time.Second) //TODO: Find a better way to ascertain they are up
-
-	stub = setupGrpcConnection()
-	stub = voltha.NewVolthaServiceClient(conn)
-	devices = make(map[string]*voltha.Device)
-}
-
-func setupGrpcConnection() voltha.VolthaServiceClient {
-	grpcHostIP := os.Getenv("DOCKER_HOST_IP")
-	grpcPort := 50057
-	grpcHost := fmt.Sprintf("%s:%d", grpcHostIP, grpcPort)
-	var err error
-	conn, err = grpc.Dial(grpcHost, grpc.WithInsecure())
-	if err != nil {
-		log.Fatalf("did not connect: %s", err)
-	}
-	return voltha.NewVolthaServiceClient(conn)
-}
-
-func clearAllDevices(clearMap bool) {
-	for key, _ := range devices {
-		ctx := context.Background()
-		response, err := stub.DeleteDevice(ctx, &voltha.ID{Id: key})
-		log.Infow("response", log.Fields{"res": response, "error": err})
-		if clearMap {
-			delete(devices, key)
-		}
-	}
-}
-
-// Verify if all ids are present in the global list of devices
-func hasAllIds(ids *voltha.IDs) bool {
-	if ids == nil && len(devices) == 0 {
-		return true
-	}
-	if ids == nil {
-		return false
-	}
-	for _, id := range ids.Items {
-		if _, exist := devices[id.Id]; !exist {
-			return false
-		}
-	}
-	return true
-}
-
-func startKafkaEtcd() {
-	fmt.Println("Starting Kafka and Etcd ...")
-	command := "docker-compose"
-	cmd := exec.Command(command, "-f", "../../compose/docker-compose-zk-kafka-test.yml", "up", "-d")
-	if err := cmd.Run(); err != nil {
-		log.Fatal(err)
-	}
-	cmd = exec.Command(command, "-f", "../../compose/docker-compose-etcd.yml", "up", "-d")
-	if err := cmd.Run(); err != nil {
-		log.Fatal(err)
-	}
-}
-
-func stopKafkaEtcd() {
-	fmt.Println("Stopping Kafka and Etcd ...")
-	command := "docker-compose"
-	cmd := exec.Command(command, "-f", "../../compose/docker-compose-zk-kafka-test.yml", "down")
-	if err := cmd.Run(); err != nil {
-		// ignore error - as this is mostly due network being left behind as its being used by other
-		// containers
-		log.Warn(err)
-	}
-	cmd = exec.Command(command, "-f", "../../compose/docker-compose-etcd.yml", "down")
-	if err := cmd.Run(); err != nil {
-		// ignore error - as this is mostly due network being left behind as its being used by other
-		// containers
-		log.Warn(err)
-	}
-}
-
-func startCore() {
-	fmt.Println("Starting voltha core ...")
-	command := "docker-compose"
-	cmd := exec.Command(command, "-f", "../../compose/rw_core.yml", "up", "-d")
-	if err := cmd.Run(); err != nil {
-		log.Fatal(err)
-	}
-}
-
-func stopCore() {
-	fmt.Println("Stopping voltha core ...")
-	command := "docker-compose"
-	cmd := exec.Command(command, "-f", "../../compose/rw_core.yml", "down")
-	if err := cmd.Run(); err != nil {
-		// ignore error - as this is mostly due network being left behind as its being used by other
-		// containers
-		log.Warn(err)
-	}
-}
-
-func TestListDeviceIds(t *testing.T) {
-	//1. Start the core
-	startCore()
-
-	// Wait until it's up - TODO: find a better way to check
-	time.Sleep(10 * time.Second)
-
-	//2. Create a set of devices into the Core
-	for i := 0; i < 10; i++ {
-		ctx := context.Background()
-		device := &voltha.Device{Type: "simulated_olt"}
-		response, err := stub.CreateDevice(ctx, device)
-		log.Infow("response", log.Fields{"res": response, "error": err})
-		assert.Nil(t, err)
-		devices[response.Id] = response
-	}
-
-	//3. Verify devices have been added correctly
-	ctx := context.Background()
-	response, err := stub.ListDeviceIds(ctx, &empty.Empty{})
-	log.Infow("response", log.Fields{"res": response, "error": err})
-	assert.Nil(t, err)
-	assert.True(t, hasAllIds(response))
-
-	//	4. Stop the core
-	stopCore()
-}
-
-func TestReconcileDevices(t *testing.T) {
-	//1. Start the core
-	startCore()
-
-	// Wait until it's up - TODO: find a better way to check
-	time.Sleep(10 * time.Second)
-
-	//2. Create a set of devices into the Core
-	for i := 0; i < 10; i++ {
-		ctx := context.Background()
-		device := &voltha.Device{Type: "simulated_olt"}
-		response, err := stub.CreateDevice(ctx, device)
-		log.Infow("response", log.Fields{"res": response, "error": err})
-		assert.Nil(t, err)
-		devices[response.Id] = response
-	}
-	//3. Verify devices have been added correctly
-	ctx := context.Background()
-	response, err := stub.ListDeviceIds(ctx, &empty.Empty{})
-	log.Infow("response", log.Fields{"res": response, "error": err})
-	assert.Nil(t, err)
-	assert.True(t, hasAllIds(response))
-
-	//4. Stop the core and restart it. This will start the core with no data in memory but
-	// etcd will still have the data.
-	stopCore()
-	time.Sleep(5 * time.Second)
-	startCore()
-	time.Sleep(10 * time.Second)
-
-	//5. Setup the connection again
-	stub = setupGrpcConnection()
-
-	//6. Verify there are no devices left
-	ctx = context.Background()
-	response, err = stub.ListDeviceIds(ctx, &empty.Empty{})
-	log.Infow("response", log.Fields{"res": response, "error": err})
-	assert.Nil(t, err)
-	assert.Equal(t, len(response.Items), 0)
-
-	//7. Invoke reconcile with all stored list
-	toRestore := &voltha.IDs{Items: make([]*voltha.ID, 0)}
-	for key, _ := range devices {
-		toRestore.Items = append(toRestore.Items, &voltha.ID{Id: key})
-	}
-	ctx = context.Background()
-	_, err = stub.ReconcileDevices(ctx, toRestore)
-	assert.Nil(t, err)
-
-	//8. Verify all devices have been restored
-	ctx = context.Background()
-	response, err = stub.ListDeviceIds(ctx, &empty.Empty{})
-	log.Infow("response", log.Fields{"res": response, "error": err})
-	assert.Nil(t, err)
-	assert.True(t, hasAllIds(response))
-
-	for _, id := range response.Items {
-		fmt.Println("id", id.Id)
-	}
-
-	//9. Store the core
-	stopCore()
-}
-
-func shutdown() {
-	conn.Close()
-	stopKafkaEtcd()
-}
-
-func TestMain(m *testing.M) {
-	code := m.Run()
-	shutdown()
-	os.Exit(code)
-}
