[VOL-1754] :This is to handle olt disable/re-enable in inband scenario
            in which connection is through NNI interface.Disabling
            NNI interface so as to disable OLT may cause connection loss
            between adapter and agent.So,disabling olt is taken care by disabling
            all the PON ports associated with that device.

Change-Id: Iae81d9dbea8b7520bb66d086d9e77029863a57ef
diff --git a/agent/src/core.cc b/agent/src/core.cc
index 43ce76f..4fb84ca 100644
--- a/agent/src/core.cc
+++ b/agent/src/core.cc
@@ -161,9 +161,11 @@
     return dev_id;
 }
 
-// Stubbed defntion of bcmolt_cfg_get required for unit-test
-extern bcmos_errno bcmolt_cfg_get_stub(bcmolt_oltid olt_id, void* ptr);
-
+// Stubbed defntions of bcmolt_cfg_get required for unit-test
+#ifdef TEST_MODE
+extern bcmos_errno bcmolt_cfg_get__bal_state_stub(bcmolt_oltid olt_id, void* ptr);
+extern bcmos_errno bcmolt_cfg_get__olt_topology_stub(bcmolt_oltid olt_id, void* ptr);
+#endif
 /**
 * Returns the default NNI (Upstream direction) or PON (Downstream direction) scheduler
 * Every NNI port and PON port have default scheduler.
@@ -809,7 +811,7 @@
             bcmolt_odid dev;
             OPENOLT_LOG(INFO, openolt_log_id, "Enabling PON %d Devices ... \n", BCM_MAX_DEVS_PER_LINE_CARD);
             for (dev = 0; dev < BCM_MAX_DEVS_PER_LINE_CARD; dev++) {
-                bcmolt_device_cfg dev_cfg = { }; 
+                bcmolt_device_cfg dev_cfg = { };
                 bcmolt_device_key dev_key = { };
                 dev_key.device_id = dev;
                 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
@@ -854,43 +856,63 @@
 }
 
 Status Disable_() {
-    // bcmbal_access_terminal_cfg acc_term_obj;
-    // bcmbal_access_terminal_key key = { };
-    //
-    // if (state::is_activated) {
-    //     std::cout << "Disable OLT" << std::endl;
-    //     key.access_term_id = DEFAULT_ATERM_ID;
-    //     BCMBAL_CFG_INIT(&acc_term_obj, access_terminal, key);
-    //     BCMBAL_CFG_PROP_SET(&acc_term_obj, access_terminal, admin_state, BCMBAL_STATE_DOWN);
-    //     bcmos_errno err = bcmbal_cfg_set(DEFAULT_ATERM_ID, &(acc_term_obj.hdr));
-    //     if (err) {
-    //         std::cout << "ERROR: Failed to disable OLT" << std::endl;
-    //         return bcm_to_grpc_err(err, "Failed to disable OLT");
-    //     }
-    // }
-    // //If already disabled, generate an extra indication ????
-    // return Status::OK;
-    //This fails with Operation Not Supported, bug ???
+    //In the earlier implementation Disabling olt is done by disabling the NNI port associated with that.
+    //In inband scenario instead of using management interface to establish connection with adapter ,NNI interface will be used.
+    //Disabling NNI port on olt disable causes connection loss between adapter and agent.
+    //To overcome this disable is implemented by disabling all the PON ports
+    //associated with the device so as to support both in-band
+    //and out of band scenarios.
 
-    //TEMPORARY WORK AROUND
-    Status status = SetStateUplinkIf_(nni_intf_id, false);
-    if (status.ok()) {
-        state.deactivate();
-        OPENOLT_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
-        pushOltOperInd(nni_intf_id, "nni", "up");
+    Status status;
+    int failedCount = 0;
+    for (int i = 0; i < NumPonIf_(); i++) {
+        status = DisablePonIf_(i);
+        if (!status.ok()) {
+            failedCount+=1;
+            BCM_LOG(ERROR, openolt_log_id, "Failed to disable PON interface: %d\n", i);
+        }
     }
-    return status;
+    if (failedCount == 0) {
+        state.deactivate();
+        openolt::Indication ind;
+        openolt::OltIndication* olt_ind = new openolt::OltIndication;
+        olt_ind->set_oper_state("down");
+        ind.set_allocated_olt_ind(olt_ind);
+        BCM_LOG(INFO, openolt_log_id, "Disable OLT, add an extra indication\n");
+        oltIndQ.push(ind);
+        return Status::OK;
+    }
+    if (failedCount ==NumPonIf_()){
+        return grpc::Status(grpc::StatusCode::INTERNAL, "failed to disable olt ,all the PON ports are still in enabled state");
+    }
 
+    return grpc::Status(grpc::StatusCode::UNKNOWN, "failed to disable olt ,few PON ports are still in enabled state");
 }
 
 Status Reenable_() {
-    Status status = SetStateUplinkIf_(0, true);
-    if (status.ok()) {
-        state.activate();
-        OPENOLT_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
-        pushOltOperInd(0, "nni", "up");
+    Status status;
+    int failedCount = 0;
+    for (int i = 0; i < NumPonIf_(); i++) {
+        status = EnablePonIf_(i);
+        if (!status.ok()) {
+            failedCount+=1;
+            BCM_LOG(ERROR, openolt_log_id, "Failed to enable PON interface: %d\n", i);
+        }
     }
-    return status;
+    if (failedCount == 0){
+        state.activate();
+        openolt::Indication ind;
+        openolt::OltIndication* olt_ind = new openolt::OltIndication;
+        olt_ind->set_oper_state("up");
+        ind.set_allocated_olt_ind(olt_ind);
+        BCM_LOG(INFO, openolt_log_id, "Reenable OLT, add an extra indication\n");
+        oltIndQ.push(ind);
+        return Status::OK;
+    }
+    if (failedCount ==NumPonIf_()){
+        return grpc::Status(grpc::StatusCode::INTERNAL, "failed to re-enable olt ,all the PON ports are still in disabled state");
+    }
+    return grpc::Status(grpc::StatusCode::UNKNOWN, "failed to re-enable olt ,few PON ports are still in disabled state");
 }
 
 bcmos_errno get_pon_interface_status(bcmolt_interface pon_ni, bcmolt_interface_state *state) {
@@ -926,13 +948,13 @@
                 return err;
             }
             return flow_cfg.data.onu_id;
-        case FLOW_TYPE: 
+        case FLOW_TYPE:
             err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
             if (err) {
                 OPENOLT_LOG(ERROR, openolt_log_id,  "Failed to get flow_type\n");
                 return err;
             }
-            return flow_cfg.key.flow_type; 
+            return flow_cfg.key.flow_type;
         case SVC_PORT_ID: //svc_port_id
             BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, svc_port_id);
             err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
@@ -941,7 +963,7 @@
                 return err;
             }
             return flow_cfg.data.svc_port_id;
-        case PRIORITY:  
+        case PRIORITY:
             BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, priority);
             err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
             if (err) {
@@ -949,7 +971,7 @@
                 return err;
             }
             return flow_cfg.data.priority;
-        case COOKIE: //cookie 
+        case COOKIE: //cookie
             BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, cookie);
             err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
             if (err) {
@@ -1013,7 +1035,7 @@
                 return err;
             }
             return flow_cfg.data.classifier.i_vid;
-        case CLASSIFIER_I_PBITS: 
+        case CLASSIFIER_I_PBITS:
             BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
             err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
             if (err) {
@@ -1029,7 +1051,7 @@
                 return err;
             }
             return flow_cfg.data.classifier.ether_type;
-        case CLASSIFIER_IP_PROTO: 
+        case CLASSIFIER_IP_PROTO:
             BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
             err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
             if (err) {
@@ -1045,7 +1067,7 @@
                 return err;
             }
             return flow_cfg.data.classifier.src_port;
-        case CLASSIFIER_DST_PORT: 
+        case CLASSIFIER_DST_PORT:
             BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
             err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
             if (err) {
@@ -1053,7 +1075,7 @@
                 return err;
             }
             return flow_cfg.data.classifier.dst_port;
-        case CLASSIFIER_PKT_TAG_TYPE: 
+        case CLASSIFIER_PKT_TAG_TYPE:
             BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, classifier);
             err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
             if (err) {
@@ -1113,7 +1135,7 @@
                 return err;
             }
             return flow_cfg.data.action.o_vid;
-        case ACTION_O_PBITS: 
+        case ACTION_O_PBITS:
             BCMOLT_FIELD_SET_PRESENT(&flow_cfg.data, flow_cfg_data, action);
             err = bcmolt_cfg_get(dev_id, &flow_cfg.hdr);
             if (err) {
@@ -1153,19 +1175,19 @@
 }
 
 Status EnablePonIf_(uint32_t intf_id) {
-    bcmos_errno err = BCM_ERR_OK; 
+    bcmos_errno err = BCM_ERR_OK;
     bcmolt_pon_interface_cfg interface_obj;
     bcmolt_pon_interface_key intf_key = {.pon_ni = (bcmolt_interface)intf_id};
     bcmolt_pon_interface_set_pon_interface_state pon_interface_set_state;
     bcmolt_interface_state state;
 
-    err = get_pon_interface_status((bcmolt_interface)intf_id, &state); 
+    err = get_pon_interface_status((bcmolt_interface)intf_id, &state);
     if (err == BCM_ERR_OK) {
         if (state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
             OPENOLT_LOG(WARNING, openolt_log_id, "PON interface: %d already enabled\n", intf_id);
             return Status::OK;
         }
-    } 
+    }
     BCMOLT_CFG_INIT(&interface_obj, pon_interface, intf_key);
     BCMOLT_OPER_INIT(&pon_interface_set_state, pon_interface, set_pon_interface_state, intf_key);
     BCMOLT_MSG_FIELD_SET(&interface_obj, discovery.control, BCMOLT_CONTROL_STATE_ENABLE);
@@ -1203,7 +1225,7 @@
 
 Status ProbeDeviceCapabilities_() {
     bcmos_errno err;
-    bcmolt_device_cfg dev_cfg = { }; 
+    bcmolt_device_cfg dev_cfg = { };
     bcmolt_device_key dev_key = { };
     bcmolt_olt_cfg olt_cfg = { };
     bcmolt_olt_key olt_key = { };
@@ -1215,10 +1237,19 @@
     BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
     BCMOLT_MSG_FIELD_GET(&olt_cfg, bal_state);
     BCMOLT_FIELD_SET_PRESENT(&olt_cfg.data, olt_cfg_data, topology);
-    BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr, 
+    BCMOLT_CFG_LIST_BUF_SET(&olt_cfg, olt, topo.topology_maps.arr,
         sizeof(bcmolt_topology_map) * topo.topology_maps.len);
+    #ifdef TEST_MODE
+        // It is impossible to mock the setting of olt_cfg.data.bal_state because
+        // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
+        // set the olt_cfg.data.topology. So a new stub function is created and address
+        // of olt_cfg is passed. This is one-of case where we need to test add specific
+        // code in production code.
+    err = bcmolt_cfg_get__olt_topology_stub(dev_id, &olt_cfg);
+    #else
     err = bcmolt_cfg_get(dev_id, &olt_cfg.hdr);
-    if (err) { 
+    #endif
+    if (err) {
         OPENOLT_LOG(ERROR, openolt_log_id, "cfg: Failed to query OLT\n");
         return bcm_to_grpc_err(err, "cfg: Failed to query OLT");
     }
@@ -1226,14 +1257,14 @@
     num_of_nni_ports = olt_cfg.data.topology.num_switch_ports;
     num_of_pon_ports = olt_cfg.data.topology.topology_maps.len;
 
-    OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n", 
-            olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY 
+    OPENOLT_LOG(INFO, openolt_log_id, "OLT capabilitites, oper_state: %s\n",
+            olt_cfg.data.bal_state == BCMOLT_BAL_STATE_BAL_AND_SWITCH_READY
             ? "up" : "down");
 
     OPENOLT_LOG(INFO, openolt_log_id, "topology nni: %d pon: %d dev: %d\n",
             num_of_nni_ports,
             num_of_pon_ports,
-            BCM_MAX_DEVS_PER_LINE_CARD); 
+            BCM_MAX_DEVS_PER_LINE_CARD);
 
     for (int devid = 0; devid < BCM_MAX_DEVS_PER_LINE_CARD; devid++) {
         dev_key.device_id = devid;
@@ -1242,7 +1273,7 @@
         BCMOLT_MSG_FIELD_GET(&dev_cfg, chip_family);
         BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
         err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
-        if (err) { 
+        if (err) {
             OPENOLT_LOG(ERROR, openolt_log_id, "device: Failed to query OLT\n");
             return bcm_to_grpc_err(err, "device: Failed to query OLT");
         }
@@ -1290,7 +1321,7 @@
 
         interface_key.pon_ni = intf_id;
         BCMOLT_CFG_INIT(&interface_obj, pon_interface, interface_key);
-        if (board_technology == "XGS-PON") 
+        if (board_technology == "XGS-PON"
             BCMOLT_MSG_FIELD_GET(&interface_obj, xgs_ngpon2_trx);
         else if (board_technology == "GPON")
             BCMOLT_MSG_FIELD_GET(&interface_obj, gpon_trx);
@@ -1358,7 +1389,7 @@
     bcmolt_nni_interface_set_nni_state nni_interface_set_state;
     bcmolt_interface_state state;
 
-    err = get_nni_interface_status((bcmolt_interface)intf_id, &state); 
+    err = get_nni_interface_status((bcmolt_interface)intf_id, &state);
     if (err == BCM_ERR_OK) {
         if (set_state && state == BCMOLT_INTERFACE_STATE_ACTIVE_WORKING) {
             OPENOLT_LOG(WARNING, openolt_log_id, "NNI interface: %d already enabled\n", intf_id);
@@ -1427,8 +1458,8 @@
     BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
     BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
     err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
-    if (err == BCM_ERR_OK) { 
-        if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING || 
+    if (err == BCM_ERR_OK) {
+        if ((onu_cfg.data.onu_state == BCMOLT_ONU_STATE_PROCESSING ||
              onu_cfg.data.onu_state == BCMOLT_ONU_STATE_ACTIVE) ||
            (onu_cfg.data.onu_state == BCMOLT_ONU_STATE_INACTIVE &&
              onu_cfg.data.onu_old_state == BCMOLT_ONU_STATE_NOT_CONFIGURED))
@@ -1436,7 +1467,7 @@
     }
 
     OPENOLT_LOG(INFO, openolt_log_id,  "Enabling ONU %d on PON %d : vendor id %s, \
-vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id, 
+vendor specific %s, pir %d\n", onu_id, intf_id, vendor_id,
         vendor_specific_to_str(vendor_specific).c_str(), pir);
 
     memcpy(serial_number.vendor_id.arr, vendor_id, 4);
@@ -1474,11 +1505,11 @@
     BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
     BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
     err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
-    if (err == BCM_ERR_OK) { 
+    if (err == BCM_ERR_OK) {
         switch (onu_state) {
             case BCMOLT_ONU_OPERATION_ACTIVE:
                 BCMOLT_OPER_INIT(&onu_oper, onu, set_onu_state, onu_key);
-                BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data, 
+                BCMOLT_FIELD_SET(&onu_oper.data, onu_set_onu_state_data,
                     onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
                 err = bcmolt_oper_submit(dev_id, &onu_oper.hdr);
                 if (err != BCM_ERR_OK) {
@@ -1730,7 +1761,7 @@
         c_val.ip_proto, gemport_id, c_val.src_port,  c_val.dst_port, GET_PKT_TAG_TYPE(c_val.pkt_tag_type)); \
     OPENOLT_LOG(level, openolt_log_id, "action(cmds_bitmask %s, o_vid %d, o_pbits %d, i_vid %d, i_pbits %d)\n\n", \
         get_flow_acton_command(a_val.cmds_bitmask), a_val.o_vid, a_val.o_pbits, a_val.i_vid, a_val.i_pbits); \
-    } while(0) 
+    } while(0)
 
 #define FLOW_PARAM_LOG() \
     do { \
@@ -2857,9 +2888,9 @@
         // It is impossible to mock the setting of olt_cfg.data.bal_state because
         // the actual bcmolt_cfg_get passes the address of olt_cfg.hdr and we cannot
         // set the olt_cfg.data.bal_state. So a new stub function is created and address
-        // of olt_cfg is passed. This is one-of case where we need to add specific
-        // code in product code.
-        if (bcmolt_cfg_get_stub(dev_id, &olt_cfg)) {
+        // of olt_cfg is passed. This is one-of case where we need to add test specific
+        // code in production code.
+        if (bcmolt_cfg_get__bal_state_stub(dev_id, &olt_cfg)) {
         #else
         if (bcmolt_cfg_get(dev_id, &olt_cfg.hdr)) {
         #endif
diff --git a/agent/test/Makefile.in b/agent/test/Makefile.in
index b8fee22..b08f3c5 100644
--- a/agent/test/Makefile.in
+++ b/agent/test/Makefile.in
@@ -118,7 +118,7 @@
 TEST_BIN=test_openolt
 # The below way of getting source files is not working
 #TEST_SRCS = $($(filter-out src/bal_stub.cc, $(wildcard src/*.cc)))
-TEST_SRCS = src/main_test.cc src/bal_mocker.cc src/test_enable_olt.cc
+TEST_SRCS = src/main_test.cc src/bal_mocker.cc src/test_enable_olt.cc src/test_disable_reenable_olt.cc
 TEST_OBJS = $(TEST_SRCS:.cc=.o)
 build: $(TEST_OBJS)
 	$(CXX) $(shell cmock-config --libs) -L$(TEST_OPENOLT_LIB_DIR) -L/usr/lib/ -I/usr/include -I./inc -o $(TEST_BIN) $(TEST_OBJS) -lgmock -lgtest -lopenolt -lopenoltapi  $(LDFLAGS)
@@ -128,7 +128,7 @@
 
 # bcm_host_api_stubs
 BAL_API_DIR=bal-api-3.1.0
-bcm_host_api_stubs: 
+bcm_host_api_stubs:
 	# TODO: There is temporary hack below to introduce the definition of bcmos_mutex.
 	# This should ideally come as part of bal-api-3.1.0
 	if [ -d $(BAL_API_DIR) ]; then \
diff --git a/agent/test/src/test_disable_reenable_olt.cc b/agent/test/src/test_disable_reenable_olt.cc
new file mode 100644
index 0000000..01fa851
--- /dev/null
+++ b/agent/test/src/test_disable_reenable_olt.cc
@@ -0,0 +1,134 @@
+/*
+ * 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.
+ */
+#include "gtest/gtest.h"
+#include "bal_mocker.h"
+#include "core.h"
+using namespace testing;
+using namespace std;
+int num_of_pon_ports = 16;
+
+// This is used to set custom bcmolt_cfg value to bcmolt_cfg pointer coming in
+// .bcmolt_cfg_get__olt_topology_stub
+ACTION_P(SetArg1ToBcmOltCfg, value) {*static_cast<bcmolt_olt_cfg*>(arg1) = value;};
+
+
+// Create a mock function for bcmolt_cfg_get__olt_topology_stub C++ function
+MOCK_GLOBAL_FUNC2(bcmolt_cfg_get__olt_topology_stub, bcmos_errno(bcmolt_oltid, void*));
+
+class TestOltDisableReenable : public Test {
+ protected:
+  virtual void SetUp() {
+    NiceMock<BalMocker> balMock;
+    bcmos_errno bal_cfg_get_stub_res = BCM_ERR_OK;
+
+    bcmolt_olt_cfg olt_cfg = { };
+    bcmolt_olt_key olt_key = { };
+
+    BCMOLT_CFG_INIT(&olt_cfg, olt, olt_key);
+
+    olt_cfg.data.topology.topology_maps.len = num_of_pon_ports;
+    EXPECT_GLOBAL_CALL(bcmolt_cfg_get__olt_topology_stub, bcmolt_cfg_get__olt_topology_stub(_, _))
+                     .WillOnce(DoAll(SetArg1ToBcmOltCfg(olt_cfg), Return(bal_cfg_get_stub_res)));
+
+    ProbeDeviceCapabilities_();
+
+  }
+
+  virtual void TearDown() {
+    // Code here will be called immediately after each test
+    // (right before the destructor).
+  }
+};
+
+
+// Test Fixture for OltDisable
+
+// Test 1: OltDisableSuccess  case
+TEST_F(TestOltDisableReenable, OltDisableSuccess){
+    // NiceMock is used to suppress 'WillByDefault' return errors.
+    // This is described in https://github.com/arangodb-helper/gtest/blob/master/googlemock/docs/CookBook.md
+    NiceMock<BalMocker> balMock;
+    bcmos_errno bal_cfg_get_res = BCM_ERR_OK;
+
+    Status olt_disable_res;
+
+    EXPECT_CALL(balMock, bcmolt_cfg_get(_, _))
+                         .Times(num_of_pon_ports)
+                         .WillRepeatedly(Return(bal_cfg_get_res));
+
+    olt_disable_res = Disable_();
+    ASSERT_TRUE( olt_disable_res.error_message() == Status::OK.error_message() );
+
+}
+
+// Test 2: OltDisableAllPonFailed  case
+TEST_F(TestOltDisableReenable, OltDisableAllPonFailed){
+    // NiceMock is used to suppress 'WillByDefault' return errors.
+    // This is described in https://github.com/arangodb-helper/gtest/blob/master/googlemock/docs/CookBook.md
+    NiceMock<BalMocker> balMock;
+    bcmos_errno bal_cfg_get_res = BCM_ERR_INTERNAL;
+
+    Status olt_disable_res;
+
+    EXPECT_CALL(balMock, bcmolt_cfg_get(_, _))
+                         .Times(num_of_pon_ports)
+                         .WillRepeatedly(Return(bal_cfg_get_res));
+
+    olt_disable_res = Disable_();
+    ASSERT_TRUE( olt_disable_res.error_code() == grpc::StatusCode::INTERNAL);
+}
+
+
+// Test Fixture for OltReenable
+
+// Test 1: OltReenableSuccess  case
+TEST_F(TestOltDisableReenable, OltReenableSuccess){
+    // NiceMock is used to suppress 'WillByDefault' return errors.
+    // This is described in https://github.com/arangodb-helper/gtest/blob/master/googlemock/docs/CookBook.md
+    NiceMock<BalMocker> balMock;
+    bcmos_errno bal_cfg_get_res = BCM_ERR_OK;
+
+    Status olt_reenable_res;
+
+    EXPECT_CALL(balMock, bcmolt_cfg_get(_, _))
+                         .Times(num_of_pon_ports*2)
+                         .WillRepeatedly(Return(bal_cfg_get_res));
+
+    olt_reenable_res = Reenable_();
+    ASSERT_TRUE( olt_reenable_res.error_message() == Status::OK.error_message() );
+
+}
+
+// Test 2: OltReenableAllPonFailed  case
+TEST_F(TestOltDisableReenable, OltReenableAllPonFailed){
+    // NiceMock is used to suppress 'WillByDefault' return errors.
+    // This is described in https://github.com/arangodb-helper/gtest/blob/master/googlemock/docs/CookBook.md
+    NiceMock<BalMocker> balMock;
+    bcmos_errno bal_cfg_get_res = BCM_ERR_OK;
+    bcmos_errno olt_oper_res = BCM_ERR_INTERNAL;
+
+    Status olt_reenable_res;
+
+    EXPECT_CALL(balMock, bcmolt_cfg_get(_, _))
+                         .Times(num_of_pon_ports)
+                         .WillRepeatedly(Return(bal_cfg_get_res));
+    EXPECT_CALL(balMock,bcmolt_oper_submit(_, _))
+                         .Times(num_of_pon_ports)
+                         .WillRepeatedly(Return(olt_oper_res));
+    olt_reenable_res = Reenable_();
+    ASSERT_TRUE( olt_reenable_res.error_code() == grpc::StatusCode::INTERNAL);
+}
+
diff --git a/agent/test/src/test_enable_olt.cc b/agent/test/src/test_enable_olt.cc
index 5fbbf69..c4e60e7 100644
--- a/agent/test/src/test_enable_olt.cc
+++ b/agent/test/src/test_enable_olt.cc
@@ -31,12 +31,12 @@
 };
 
 // This is used to set custom bcmolt_cfg value to bcmolt_cfg pointer coming in
-// bcmolt_cfg_get_stub.
+// bcmolt_cfg_get__bal_state_stub.
 ACTION_P(SetArg1ToBcmOltCfg, value) { *static_cast<bcmolt_olt_cfg*>(arg1) = value; };
 
 
-// Create a mock function for bcmolt_cfg_get_stub C++ function
-MOCK_GLOBAL_FUNC2(bcmolt_cfg_get_stub, bcmos_errno(bcmolt_oltid, void*));
+// Create a mock function for bcmolt_cfg_get__bal_state_stub C++ function
+MOCK_GLOBAL_FUNC2(bcmolt_cfg_get__bal_state_stub, bcmos_errno(bcmolt_oltid, void*));
 
 
 // Test Fixture for OltEnable
@@ -59,7 +59,7 @@
     Status olt_enable_res;
 
     ON_CALL(balMock, bcmolt_host_init(_)).WillByDefault(Return(host_init_res));
-    EXPECT_GLOBAL_CALL(bcmolt_cfg_get_stub, bcmolt_cfg_get_stub(_, _))
+    EXPECT_GLOBAL_CALL(bcmolt_cfg_get__bal_state_stub, bcmolt_cfg_get__bal_state_stub(_, _))
                      .WillOnce(DoAll(SetArg1ToBcmOltCfg(olt_cfg), Return(bal_cfg_get_stub_res)));
     EXPECT_CALL(balMock, bcmolt_cfg_get(_, _))
                          .Times(BCM_MAX_DEVS_PER_LINE_CARD)
@@ -110,7 +110,7 @@
     state.deactivate();
 
     ON_CALL(balMock, bcmolt_host_init(_)).WillByDefault(Return(host_init_res));
-    EXPECT_GLOBAL_CALL(bcmolt_cfg_get_stub, bcmolt_cfg_get_stub(_, _))
+    EXPECT_GLOBAL_CALL(bcmolt_cfg_get__bal_state_stub, bcmolt_cfg_get__bal_state_stub(_, _))
                      .WillOnce(DoAll(SetArg1ToBcmOltCfg(olt_cfg), Return(bal_cfg_get_stub_res)));
     EXPECT_CALL(balMock, bcmolt_cfg_get(_, _))
                          .Times(BCM_MAX_DEVS_PER_LINE_CARD)
@@ -143,7 +143,7 @@
     state.deactivate();
 
     ON_CALL(balMock, bcmolt_host_init(_)).WillByDefault(Return(host_init_res));
-    EXPECT_GLOBAL_CALL(bcmolt_cfg_get_stub, bcmolt_cfg_get_stub(_, _))
+    EXPECT_GLOBAL_CALL(bcmolt_cfg_get__bal_state_stub, bcmolt_cfg_get__bal_state_stub(_, _))
                      .WillOnce(DoAll(SetArg1ToBcmOltCfg(olt_cfg), Return(bal_cfg_get_stub_res)));
     EXPECT_CALL(balMock, bcmolt_cfg_get(_, _))
                          .Times(BCM_MAX_DEVS_PER_LINE_CARD)
@@ -178,7 +178,7 @@
     state.deactivate();
 
     ON_CALL(balMock, bcmolt_host_init(_)).WillByDefault(Return(host_init_res));
-    EXPECT_GLOBAL_CALL(bcmolt_cfg_get_stub, bcmolt_cfg_get_stub(_, _))
+    EXPECT_GLOBAL_CALL(bcmolt_cfg_get__bal_state_stub, bcmolt_cfg_get__bal_state_stub(_, _))
                      .WillOnce(DoAll(SetArg1ToBcmOltCfg(olt_cfg), Return(bal_cfg_get_stub_res)));
     EXPECT_CALL(balMock, bcmolt_cfg_get(_, _))
                          .Times(BCM_MAX_DEVS_PER_LINE_CARD)