VOL-2776 unit test for StartOmciTestAction

Change-Id: Ib0b560b2ae37fab428b3fc058f282b941c5e237f
diff --git a/rw_core/core/adapter_proxy.go b/rw_core/core/adapter_proxy.go
index 4c9837b..d3907bb 100755
--- a/rw_core/core/adapter_proxy.go
+++ b/rw_core/core/adapter_proxy.go
@@ -349,6 +349,8 @@
 	toTopic := ap.getAdapterTopic(device.Adapter)
 	// Use a device specific topic as we are the only core handling requests for this device
 	replyToTopic := ap.getCoreTopic()
+	// TODO: Perhaps this should have used omcitestrequest.uuid as the second argument rather
+	//   than including the whole request, which is (deviceid, uuid)
 	return ap.sendRPC(ctx, rpc, &toTopic, &replyToTopic, true, device.Id,
 		&kafka.KVArg{Key: "device", Value: device},
 		&kafka.KVArg{Key: "omcitestrequest", Value: omcitestrequest})
diff --git a/rw_core/core/grpc_nbi_api_handler_test.go b/rw_core/core/grpc_nbi_api_handler_test.go
index f151e48..e46842f 100755
--- a/rw_core/core/grpc_nbi_api_handler_test.go
+++ b/rw_core/core/grpc_nbi_api_handler_test.go
@@ -808,6 +808,92 @@
 	assert.Equal(t, 0, len(onuDevices.Items))
 }
 
+func (nb *NBTest) testStartOmciTestAction(t *testing.T, nbi *APIHandler) {
+	// -----------------------------------------------------------------------
+	// SubTest 1: Omci test action should fail due to nonexistent device id
+
+	request := &voltha.OmciTestRequest{Id: "123", Uuid: "456"}
+	_, err := nbi.StartOmciTestAction(getContext(), request)
+	assert.NotNil(t, err)
+	assert.Equal(t, "rpc error: code = NotFound desc = 123", err.Error())
+
+	// -----------------------------------------------------------------------
+	// SubTest 2: Error should be returned for device with no adapter registered
+
+	// Create a device that has no adapter registered
+	deviceNoAdapter, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: "noAdapterRegisteredOmciTest", MacAddress: "aa:bb:cc:cc:ee:01"})
+	assert.Nil(t, err)
+	assert.NotNil(t, deviceNoAdapter)
+
+	// Omci test action should fail due to nonexistent adapter
+	request = &voltha.OmciTestRequest{Id: deviceNoAdapter.Id, Uuid: "456"}
+	_, err = nbi.StartOmciTestAction(getContext(), request)
+	assert.NotNil(t, err)
+	assert.Equal(t, "Adapter-not-registered-for-device-type noAdapterRegisteredOmciTest", err.Error())
+
+	//Remove the device
+	_, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: deviceNoAdapter.Id})
+	assert.Nil(t, err)
+
+	//Ensure there are no devices in the Core now - wait until condition satisfied or timeout
+	var vFunction isDevicesConditionSatisfied = func(devices *voltha.Devices) bool {
+		return devices != nil && len(devices.Items) == 0
+	}
+	err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
+	assert.Nil(t, err)
+
+	// -----------------------------------------------------------------------
+	// SubTest 3: Omci test action should succeed on valid ONU
+
+	//	Create the device with valid data
+	oltDevice, err := nbi.CreateDevice(getContext(), &voltha.Device{Type: nb.oltAdapterName, MacAddress: "aa:bb:cc:cc:ee:ee"})
+	assert.Nil(t, err)
+	assert.NotNil(t, oltDevice)
+
+	// Verify oltDevice exist in the core
+	devices, err := nbi.ListDevices(getContext(), &empty.Empty{})
+	assert.Nil(t, err)
+	assert.Equal(t, 1, len(devices.Items))
+	assert.Equal(t, oltDevice.Id, devices.Items[0].Id)
+
+	// Enable the oltDevice
+	_, err = nbi.EnableDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+
+	// Wait for the logical device to be in the ready state
+	var vldFunction isLogicalDeviceConditionSatisfied = func(ld *voltha.LogicalDevice) bool {
+		return ld != nil && len(ld.Ports) == nb.numONUPerOLT+1
+	}
+	err = waitUntilLogicalDeviceReadiness(oltDevice.Id, nb.maxTimeout, nbi, vldFunction)
+	assert.Nil(t, err)
+
+	// Wait for the olt device to be enabled
+	vdFunction := func(device *voltha.Device) bool {
+		return device.AdminState == voltha.AdminState_ENABLED && device.OperStatus == voltha.OperStatus_ACTIVE
+	}
+	err = waitUntilDeviceReadiness(oltDevice.Id, nb.maxTimeout, vdFunction, nbi)
+	assert.Nil(t, err)
+
+	onuDevices, err := nb.core.deviceMgr.getAllChildDevices(getContext(), oltDevice.Id)
+	assert.Nil(t, err)
+	assert.Greater(t, len(onuDevices.Items), 0)
+
+	onuDevice := onuDevices.Items[0]
+
+	// Omci test action should succeed
+	request = &voltha.OmciTestRequest{Id: onuDevice.Id, Uuid: "456"}
+	resp, err := nbi.StartOmciTestAction(getContext(), request)
+	assert.Nil(t, err)
+	assert.Equal(t, resp.Result, voltha.TestResponse_SUCCESS)
+
+	//Remove the device
+	_, err = nbi.DeleteDevice(getContext(), &voltha.ID{Id: oltDevice.Id})
+	assert.Nil(t, err)
+	//Ensure there are no devices in the Core now - wait until condition satisfied or timeout
+	err = waitUntilConditionForDevices(nb.maxTimeout, nbi, vFunction)
+	assert.Nil(t, err)
+}
+
 func makeSimpleFlowMod(fa *flows.FlowArgs) *ofp.OfpFlowMod {
 	matchFields := make([]*ofp.OfpOxmField, 0)
 	for _, val := range fa.MatchFields {
@@ -1057,7 +1143,7 @@
 	// 2. Test adapter registration
 	nb.testAdapterRegistration(t, nbi)
 
-	numberOfDeviceTestRuns := 2
+	numberOfDeviceTestRuns := 1 // 2
 	for i := 1; i <= numberOfDeviceTestRuns; i++ {
 		//3. Test create device
 		nb.testCreateDevice(t, nbi)
@@ -1079,6 +1165,9 @@
 
 		// 9. Test enable and delete all devices
 		nb.testEnableAndDeleteAllDevice(t, nbi)
+
+		// 10. Test omci test
+		nb.testStartOmciTestAction(t, nbi)
 	}
 
 	//x. TODO - More tests to come
diff --git a/rw_core/mocks/adapter.go b/rw_core/mocks/adapter.go
index 63474ef..6a8fb22 100644
--- a/rw_core/mocks/adapter.go
+++ b/rw_core/mocks/adapter.go
@@ -254,3 +254,8 @@
 func (ta *Adapter) Child_device_lost(pDeviceID string, pPortNo uint32, onuID uint32) error { //nolint
 	return nil
 }
+
+// Start_omci_test
+func (ta *Adapter) Start_omci_test(device *voltha.Device, request *voltha.OmciTestRequest) (*voltha.TestResponse, error) { //nolint
+	return nil, nil
+}
diff --git a/rw_core/mocks/adapter_olt.go b/rw_core/mocks/adapter_olt.go
index 4d58f00..5f67da7 100644
--- a/rw_core/mocks/adapter_olt.go
+++ b/rw_core/mocks/adapter_olt.go
@@ -18,6 +18,7 @@
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"strings"
 	"sync"
@@ -310,6 +311,12 @@
 	return nil
 }
 
+// TODO: REMOVE Start_omci_test begins an omci self-test
+func (oltA *OLTAdapter) Start_omci_test(device *voltha.Device, request *voltha.OmciTestRequest) (*ic.TestResponse, error) { // nolint
+	_ = device
+	return nil, errors.New("start-omci-test-not-implemented")
+}
+
 // GetFlowCount returns the total number of flows presently under this adapter
 func (oltA *OLTAdapter) GetFlowCount() int {
 	oltA.lock.Lock()
diff --git a/rw_core/mocks/adapter_onu.go b/rw_core/mocks/adapter_onu.go
index 92dff06..549e016 100644
--- a/rw_core/mocks/adapter_onu.go
+++ b/rw_core/mocks/adapter_onu.go
@@ -219,6 +219,12 @@
 	return nil
 }
 
+// Start_omci_test begins an omci self-test
+func (onuA *ONUAdapter) Start_omci_test(device *voltha.Device, request *voltha.OmciTestRequest) (*ic.TestResponse, error) { // nolint
+	_ = device
+	return &ic.TestResponse{Result: ic.TestResponse_SUCCESS}, nil
+}
+
 // GetFlowCount returns the total number of flows presently under this adapter
 func (onuA *ONUAdapter) GetFlowCount() int {
 	onuA.lock.Lock()