TestSuite changes for VGC

Change-Id: I180edb346c309827d125e371083f9accc2014f0e
diff --git a/Makefile b/Makefile
index 5613b84..01ff850 100644
--- a/Makefile
+++ b/Makefile
@@ -40,7 +40,9 @@
 # Robot config
 ROBOT_SANITY_SINGLE_PON_FILE    ?= $(ROOT_DIR)/tests/data/bbsim-kind.yaml
 ROBOT_SANITY_DT_SINGLE_PON_FILE    ?= $(ROOT_DIR)/tests/data/bbsim-kind-dt.yaml
+ROBOT_SANITY_DT_SINGLE_PON_FILE_VGC    ?= $(ROOT_DIR)/tests/data/bbsim-kind-dt-vgc.yaml
 ROBOT_SANITY_MULTIPLE_OLT_FILE    ?= $(ROOT_DIR)/tests/data/bbsim-kind-2OLTx2ONUx2PON.yaml
+ROBOT_SANITY_MULTIPLE_OLT_FILE_VGC    ?= $(ROOT_DIR)/tests/data/bbsim-kind-2OLTx2ONUx2PON_VGC.yaml
 ROBOT_SANITY_DT_MULTIPLE_OLT_FILE    ?= $(ROOT_DIR)/tests/data/bbsim-kind-2OLTx2ONUx2PON-dt.yaml
 ROBOT_SANITY_TT_MULTIPLE_OLT_FILE    ?= $(ROOT_DIR)/tests/data/bbsim-kind-2OLTx2ONUx2PON-tt.yaml
 ROBOT_FAIL_SINGLE_PON_FILE      ?= $(ROOT_DIR)/tests/data/bbsim-kind.yaml
@@ -60,6 +62,7 @@
 ROBOT_SANITY_TT_MULTI_UNI_SINGLE_PON_FILE    ?= $(ROOT_DIR)/tests/data/bbsim-kind-multi-uni-tt.yaml
 ROBOT_SANITY_TT_MULTI_UNI_MULTIPLE_OLT_FILE     ?= $(ROOT_DIR)/tests/data/bbsim-kind-multi-uni-2OLTx2ONUx2PON-tt.yaml
 ROBOT_SANITY_DT_FTTB_SINGLE_PON_FILE    ?= $(ROOT_DIR)/tests/data/bbsim-kind-dt-fttb-1OLTx1PONx2ONUx2UNI.yaml
+ROBOT_SANITY_DT_FTTB_SINGLE_PON_FILE_VGC    ?= $(ROOT_DIR)/tests/data/bbsim-kind-dt-fttb-1OLTx1PONx2ONUx2UNI.yaml
 ROBOT_SANITY_TIM_SINGLE_PON_FILE    ?= $(ROOT_DIR)/tests/data/bbsim-kind-tim.yaml
 ROBOT_SANITY_TIM_SINGLE_PON_MULTI_ONU_FILE    ?= $(ROOT_DIR)/tests/data/bbsim-kind-tim-OLTxPONx2ONU.yaml
 ROBOT_SANITY_TIM_MULTI_PON_MULTI_ONU_FILE    ?= $(ROOT_DIR)/tests/data/bbsim-kind-tim-OLTx2PONx2ONU.yaml
@@ -102,12 +105,24 @@
 sanity-kind-dt: ROBOT_FILE := Voltha_DT_PODTests.robot
 sanity-kind-dt: voltha-dt-test
 
+# target to invoke DT Workflow Sanity for VGC
+sanity-kind-dt-vgc: ROBOT_MISC_ARGS += -i sanityDt $(ROBOT_DEBUG_LOG_OPT)
+sanity-kind-dt-vgc: ROBOT_CONFIG_FILE := $(ROBOT_SANITY_DT_SINGLE_PON_FILE_VGC)
+sanity-kind-dt-vgc: ROBOT_FILE := Voltha_DT_PODTests_VGC.robot
+sanity-kind-dt-vgc: voltha-dt-test
+
 # target to invoke DT FTTB Workflow Sanity
 sanity-kind-dt-fttb: ROBOT_MISC_ARGS += -i sanityDtFttb $(ROBOT_DEBUG_LOG_OPT)
 sanity-kind-dt-fttb: ROBOT_CONFIG_FILE := $(ROBOT_SANITY_DT_FTTB_SINGLE_PON_FILE)
 sanity-kind-dt-fttb: ROBOT_FILE := Voltha_DT_FTTB_Tests.robot
 sanity-kind-dt-fttb: voltha-dt-test
 
+# target to invoke DT FTTB Workflow Sanity for VGC
+sanity-kind-dt-fttb-vgc: ROBOT_MISC_ARGS += -i sanityDtFttb $(ROBOT_DEBUG_LOG_OPT)
+sanity-kind-dt-fttb-vgc: ROBOT_CONFIG_FILE := $(ROBOT_SANITY_DT_FTTB_SINGLE_PON_FILE_VGC)
+sanity-kind-dt-fttb-vgc: ROBOT_FILE := Voltha_DT_FTTB_Tests_VGC.robot
+sanity-kind-dt-fttb-vgc: voltha-dt-test
+
 functional-single-kind: ROBOT_MISC_ARGS += -i sanityORfunctional -e PowerSwitch $(ROBOT_DEBUG_LOG_OPT)
 functional-single-kind: ROBOT_CONFIG_FILE := $(ROBOT_SANITY_SINGLE_PON_FILE)
 functional-single-kind: bbsim-kind
@@ -121,6 +136,13 @@
 functional-single-kind-dt: ROBOT_FILE := Voltha_DT_PODTests.robot
 functional-single-kind-dt: voltha-dt-test
 
+# target to invoke DT Workflow Functional scenarios
+functional-single-kind-dt-vgc: ROBOT_MISC_ARGS += -i sanityDtORfunctionalDt -e PowerSwitch $(ROBOT_DEBUG_LOG_OPT)
+functional-single-kind-dt-vgc: ROBOT_CONFIG_FILE := $(ROBOT_SANITY_DT_SINGLE_PON_FILE_VGC)
+functional-single-kind-dt-vgc: ROBOT_FILE := Voltha_DT_PODTests_VGC.robot
+functional-single-kind-dt-vgc: voltha-dt-test
+
+
 # target to invoke TT Workflow Sanity
 sanity-kind-tt: ROBOT_MISC_ARGS += -i sanityTT $(ROBOT_DEBUG_LOG_OPT)
 sanity-kind-tt: ROBOT_CONFIG_FILE := $(ROBOT_SANITY_TT_SINGLE_PON_FILE)
@@ -442,6 +464,16 @@
 bbsim-multiolt-kind-dt: ROBOT_CONFIG_FILE := $(ROBOT_SANITY_MULTIPLE_OLT_FILE)
 bbsim-multiolt-kind-dt: voltha-dt-test
 
+bbsim-multiolt-kind-dt-vgc: ROBOT_MISC_ARGS += -X $(ROBOT_DEBUG_LOG_OPT) -e PowerSwitch -e MultiOLTPhysicalRebootDt
+bbsim-multiolt-kind-dt-vgc: ROBOT_FILE := Voltha_DT_MultiOLT_Tests_VGC.robot
+bbsim-multiolt-kind-dt-vgc: ROBOT_CONFIG_FILE := $(ROBOT_SANITY_MULTIPLE_OLT_FILE_VGC)
+bbsim-multiolt-kind-dt-vgc: voltha-dt-test
+
+multiolt-kind-dt-vgc: ROBOT_MISC_ARGS += -X $(ROBOT_DEBUG_LOG_OPT) -i functionalDt
+multiolt-kind-dt-vgc: ROBOT_FILE := Voltha_DT_MultiOLT_Tests_VGC.robot
+multiolt-kind-dt-vgc: ROBOT_CONFIG_FILE := $(ROBOT_SANITY_MULTIPLE_OLT_FILE_VGC)
+multiolt-kind-dt-vgc: voltha-dt-test
+
 multiolt-kind-dt: ROBOT_MISC_ARGS += -X $(ROBOT_DEBUG_LOG_OPT) -i functionalDt
 multiolt-kind-dt: ROBOT_FILE := Voltha_DT_MultiOLT_Tests.robot
 multiolt-kind-dt: ROBOT_CONFIG_FILE := $(ROBOT_SANITY_MULTIPLE_OLT_FILE)
diff --git a/VERSION b/VERSION
index dcb27a7..e464374 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.12.5
+2.12.6
diff --git a/libraries/utils_vgc.robot b/libraries/utils_vgc.robot
new file mode 100755
index 0000000..65e0912
--- /dev/null
+++ b/libraries/utils_vgc.robot
@@ -0,0 +1,1191 @@
+# Copyright 2017-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.
+# robot test functions
+
+*** Settings ***
+Documentation     Library for various utilities
+Library           SSHLibrary
+Library           String
+Library           DateTime
+Library           Process
+Library           Collections
+Library           RequestsLibrary
+Library           OperatingSystem
+Library           CORDRobot
+Library           ImportResource    resources=CORDRobot
+Resource          ./voltctl.robot
+Resource          ./vgc.robot
+
+*** Keywords ***
+Check CLI Tools Configured
+    [Documentation]    Tests that use 'voltctl' and 'kubectl' should execute this keyword in suite setup
+    # check voltctl and kubectl configured
+    ${voltctl_rc}    ${voltctl_output}=    Run And Return Rc And Output    voltctl -c ${VOLTCTL_CONFIG} device list
+    Log    ${voltctl_output}
+    ${kubectl_rc}    ${kubectl_output}=    Run And Return Rc And Output    kubectl get pods
+    Log    ${kubectl_output}
+    Run Keyword If    ${voltctl_rc} != 0 or ${kubectl_rc} != 0    FATAL ERROR
+    ...    VOLTCTL and KUBECTL not configured. Please configure before executing tests.
+
+Common Test Suite Setup
+    [Documentation]    Setup the test suite
+    Set Global Variable    ${KUBECTL_CONFIG}    export KUBECONFIG=%{KUBECONFIG}
+    Set Global Variable    ${VOLTCTL_CONFIG}    %{VOLTCONFIG}
+    ${k8s_node_ip}=    Evaluate    ${nodes}[0].get("ip")
+    ${VGC_REST_IP}=    Get Environment Variable    VGC_REST_IP    ${k8s_node_ip}
+    ${VGC_SSH_IP}=     Get Environment Variable    VGC_SSH_IP     ${k8s_node_ip}
+    Set Global Variable    ${VGC_REST_IP}
+    Set Global Variable    ${VGC_SSH_IP}
+    ${k8s_node_user}=    Evaluate    ${nodes}[0].get("user")
+    ${k8s_node_pass}=    Evaluate    ${nodes}[0].get("pass")
+    Check CLI Tools Configured
+    ${HEADERS}    Create Dictionary    Content-Type=application/json
+    Create VGC Session
+    ${num_olts}    Get Length    ${olts}
+    ${list_olts}    Create List
+    # Create olt list from the configuration file
+    FOR    ${I}    IN RANGE    0    ${num_olts}
+        ${ip}    Evaluate    ${olts}[${I}].get("ip")
+        ${user}    Evaluate    ${olts}[${I}].get("user")
+        ${pass}    Evaluate    ${olts}[${I}].get("pass")
+        ${serial_number}    Evaluate    ${olts}[${I}].get("serial")
+        ${olt_ssh_ip}    Evaluate    ${olts}[${I}].get("sship")
+        ${type}    Evaluate    ${olts}[${I}].get("type")
+        ${power_switch_port}    Evaluate    ${olts}[${I}].get("power_switch_port")
+        ${orig_olt_port}    Evaluate    ${olts}[${I}].get("oltPort")
+        ${port}=    Set Variable If    "${orig_olt_port}" == "None"    ${OLT_PORT}    ${orig_olt_port}
+        ${onu_count}=    Get ONU Count For OLT    ${hosts.src}    ${serial_number}
+        ${onu_list}=    Get ONU List For OLT    ${hosts.src}    ${serial_number}
+        ${olt}    Create Dictionary    ip    ${ip}    user    ${user}    pass
+        ...    ${pass}    sn    ${serial_number}   onucount   ${onu_count}    type    ${type}
+        ...    sship    ${olt_ssh_ip}    oltport    ${port}    powerswitchport    ${power_switch_port}
+        ...    onus    ${onu_list}
+        Append To List    ${list_olts}    ${olt}
+    END
+    ${num_all_onus}=    Get Length    ${hosts.src}
+    ${num_all_onus}=    Convert to String    ${num_all_onus}
+    #send sadis file to vgc
+    ${sadis_file}=    Get Variable Value    ${sadis.file}
+    Log To Console    \nSadis File:${sadis_file}
+    Run Keyword Unless    '${sadis_file}' is '${None}'    Send File To VGC    ${sadis_file}   # apps/
+    Set Suite Variable    ${num_all_onus}
+    Set Suite Variable    ${num_olts}
+    Set Suite Variable    ${list_olts}
+    ${olt_count}=    Get Length    ${list_olts}
+    Set Suite Variable    ${olt_count}
+    @{container_list}=    Create List    ${OLT_ADAPTER_APP_LABEL}    adapter-open-onu    voltha-api-server
+    ...    voltha-ro-core    voltha-rw-core-11    voltha-rw-core-12    voltha-ofagent
+    Set Suite Variable    ${container_list}
+    ${datetime}=    Get Current Date
+    Set Suite Variable    ${datetime}
+
+Get ONU Count For OLT
+    [Arguments]    ${src}    ${serial_number}
+    [Documentation]    Gets ONU Count for the specified OLT
+    ${src_length}=    Get Length    ${src}
+    ${count}=    Set Variable    0
+    FOR    ${I}    IN RANGE    0     ${src_length}
+        ${sn}    Evaluate    ${src}[${I}].get("olt")
+        ${count}=    Run Keyword If    '${serial_number}' == '${sn}'    Evaluate    ${count} + 1
+        ...          ELSE  Set Variable  ${count}
+    END
+    [Return]    ${count}
+
+Get ONU List For OLT
+    [Arguments]    ${src}    ${serial_number}
+    [Documentation]    Gets ONU List for the specified OLT
+    ${src_length}=    Get Length    ${src}
+    ${onu_list}=    Create List
+    FOR    ${I}    IN RANGE    0     ${src_length}
+        ${sn}    Evaluate    ${src}[${I}].get("olt")
+        Run Keyword If    '${serial_number}' == '${sn}'    Append To List     ${onu_list}    ${src}[${I}][onu]
+        ...  ELSE  Set Variable  ${onu_list}
+    END
+    [Return]    ${onu_list}
+
+WPA Reassociate
+    [Documentation]    Executes a particular wpa_cli reassociate, which performs force reassociation
+    [Arguments]    ${iface}    ${ip}    ${user}    ${pass}=${None}
+    ...    ${container_type}=${None}    ${container_name}=${None}
+    #Below for loops are used instead of sleep time, to execute reassociate command and check status
+    FOR    ${i}    IN RANGE    70
+        ${output}=    Login And Run Command On Remote System
+        ...    wpa_cli -i ${iface} reassociate    ${ip}    ${user}
+        ...    ${pass}    ${container_type}    ${container_name}
+        ${passed}=    Run Keyword And Return Status    Should Contain    ${output}    OK
+        Exit For Loop If    ${passed}
+    END
+    Should Be True    ${passed}    Status does not contain 'SUCCESS'
+    FOR    ${i}    IN RANGE    70
+        ${output}=    Login And Run Command On Remote System
+        ...    wpa_cli -i ${iface} status | grep SUCCESS    ${ip}    ${user}
+        ...    ${pass}    ${container_type}    ${container_name}
+        ${passed}=    Run Keyword And Return Status    Should Contain    ${output}    SUCCESS
+        Exit For Loop If    ${passed}
+    END
+    Should Be True    ${passed}    Status does not contain 'SUCCESS'
+
+Validate Authentication After Reassociate
+    [Arguments]    ${auth_pass}    ${iface}    ${ip}    ${user}    ${pass}=${None}
+    ...    ${container_type}=${None}    ${container_name}=${None}
+    [Documentation]
+    ...    Executes a particular reassociate request on the RG using wpa_cli.
+    ...    auth_pass determines if authentication should pass
+    ${wpa_log}=    Catenate    SEPARATOR=.    /tmp/wpa    ${iface}    log
+    ${output}=    Login And Run Command On Remote System    truncate -s 0 ${wpa_log}; cat ${wpa_log}
+    ...    ${ip}    ${user}    ${pass}    ${container_type}    ${container_name}
+    Log    ${output}
+    Should Not Contain    ${output}    authentication completed successfully
+    WPA Reassociate    ${iface}    ${ip}    ${user}    ${pass}    ${container_type}    ${container_name}
+    Run Keyword If    '${auth_pass}' == 'True'    Wait Until Keyword Succeeds    ${timeout}    2s
+    ...    Check Remote File Contents    True    ${wpa_log}    ${iface}.*authentication completed successfully
+    ...    ${ip}    ${user}    ${pass}    ${container_type}    ${container_name}
+    Run Keyword If    '${auth_pass}' == 'False'    Sleep    20s
+    Run Keyword If    '${auth_pass}' == 'False'    Check Remote File Contents    False    /tmp/wpa.log
+    ...    ${iface}.*authentication completed successfully    ${ip}    ${user}    ${pass}
+    ...    ${container_type}    ${container_name}
+
+Send Dhclient Request To Release Assigned IP
+    [Arguments]    ${iface}    ${ip}    ${user}    ${path_dhcpleasefile}    ${pass}=${None}
+    ...    ${container_type}=${None}    ${container_name}=${None}
+    [Documentation]    Executes a dhclient with option to release ip against a particular interface on the RG (src)
+    ${result}=    Login And Run Command On Remote System
+    ...    dhclient -nw -r ${iface} && rm ${path_dhcpleasefile}/dhclient.*    ${ip}    ${user}
+    ...    ${pass}    ${container_type}    ${container_name}
+    Log    ${result}
+    #Should Contain    ${result}    DHCPRELEASE
+    [Return]    ${result}
+
+Check Remote File Contents For WPA Logs
+    [Arguments]    ${file_should_exist}    ${file}    ${pattern}    ${ip}    ${user}    ${pass}=${None}
+    ...    ${container_type}=${None}    ${container_name}=${None}    ${prompt}=~$
+    [Documentation]    Checks for particular pattern count in a file
+    ${result}=    Login And Run Command On Remote System
+    ...    cat ${file} | grep '${pattern}' | wc -l    ${ip}    ${user}    ${pass}
+    ...    ${container_type}    ${container_name}    ${prompt}
+    [Return]    ${result}
+
+Perform Sanity Test DT
+    [Documentation]    This keyword iterate all OLTs and performs Sanity Test Procedure for DT workflow
+    ...    For repeating sanity test without subscriber changes set flag supress_add_subscriber=True.
+    ...    In all other (common) cases flag has to be set False (default).
+    [Arguments]    ${supress_add_subscriber}=False
+    FOR    ${J}    IN RANGE    0    ${num_olts}
+        ${olt_serial_number}=    Set Variable    ${list_olts}[${J}][sn]
+        ${num_onus}=    Set Variable    ${list_olts}[${J}][onucount]
+        ${olt_device_id}=    Get OLTDeviceID From OLT List    ${olt_serial_number}
+        ${of_id}=    Wait Until Keyword Succeeds    ${timeout}    15s    Validate OLT Device in VGC
+        ...    ${olt_serial_number}
+        Set Global Variable    ${of_id}
+        ${nni_port}=    Wait Until Keyword Succeeds    ${timeout}    2s    Get NNI Port in VGC    ${of_id}
+        Perform Sanity Test DT Per OLT    ${of_id}    ${nni_port}    ${olt_serial_number}    ${num_onus}
+        ...    ${supress_add_subscriber}
+        # Verify VGC Flows
+        # Number of Access Flows on VGC equals 4 * the Number of Active ONUs (2 for each downstream and upstream)
+        ${vgc_flows_count}=    Evaluate    4 * ${num_onus}
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Subscriber Access Flows Added Count DT   ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${of_id}
+        ...    ${vgc_flows_count}
+        # Verify LLDP flow in VGC
+        #Wait Until Keyword Succeeds    ${timeout}    5s
+        #...     Verify LLDP Flow Added      ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${of_id}      1
+        # Verify VOLTHA Flows
+        # Number of per OLT Flows equals Twice the Number of Active ONUs (each for downstream and upstream) + 1 for LLDP
+        ${olt_flows}=    Evaluate    2 * ${num_onus}
+        # Number of per ONU Flows equals 2 (one each for downstream and upstream)
+        ${onu_flows}=    Set Variable    2
+        Run Keyword    Wait Until Keyword Succeeds    ${timeout}    5s    Validate OLT Flows
+        ...    ${olt_flows}    ${olt_device_id}
+        ${List_ONU_Serial}    Create List
+        Set Suite Variable    ${List_ONU_Serial}
+        Build ONU SN List    ${List_ONU_Serial}    ${olt_serial_number}
+        Log    ${List_ONU_Serial}
+        Wait Until Keyword Succeeds    ${timeout}    5s    Validate ONU Flows
+        ...    ${List_ONU_Serial}    ${onu_flows}
+    END
+
+
+Perform Sanity Test DT Per OLT
+    [Arguments]    ${of_id}    ${nni_port}    ${olt_serial_number}    ${num_onus}    ${supress_add_subscriber}=False
+    [Documentation]    This keyword performs Sanity Test Procedure for DT Workflow
+    ...    Sanity test performs dhcp and pings (without EAPOL and DHCP flows) for all the ONUs given for the POD
+    ...    This keyword can be used to call in any other tests where sanity check is required
+    ...    and avoids duplication of code.
+    ...    For repeating sanity test without subscriber changes set flag supress_add_subscriber=True.
+    ...    In all other (common) cases flag has to be set False (default).
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        Continue For Loop If    "${olt_serial_number}"!="${src['olt']}"
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        ${onu_port}=    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Get ONU Port in VGC    ${src['onu']}    ${of_id}    ${src['uni_id']}
+        # Check ONU port is Enabled in VGC
+        Wait Until Keyword Succeeds   120s   2s
+        ...    Verify UNI Port Is Enabled      ${src['onu']}    ${src['uni_id']}
+        Run Keyword Unless    ${supress_add_subscriber}
+        ...     Add Subscriber Details   ${of_id}    ${onu_port}
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Subscriber Access Flows Added For ONU DT in VGC   ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${of_id}
+        ...    ${onu_port}    ${nni_port}    ${src['s_tag']}
+        # Verify ONU state in voltha
+        ${onu_reasons}=  Create List     omci-flows-pushed
+        Run Keyword If    ${supress_add_subscriber}    Append To List    ${onu_reasons}    onu-reenabled
+        Wait Until Keyword Succeeds    ${timeout}    5s    Validate Device
+        ...    ENABLED    ACTIVE    REACHABLE
+        ...    ${src['onu']}    onu=True    onu_reason=${onu_reasons}
+        # Verify Meters in VGC
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Meters in VGC Ietf    ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${of_id}    ${onu_port}
+        # TODO: Yet to Verify on the GPON based Physical POD (VOL-2652)
+        Run Keyword If    ${has_dataplane}    Validate DHCP and Ping    True
+        ...    True    ${src['dp_iface_name']}    ${src['s_tag']}    ${src['c_tag']}    ${dst['dp_iface_ip_qinq']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        ...    ${dst['dp_iface_name']}    ${dst['ip']}    ${dst['user']}    ${dst['pass']}    ${dst['container_type']}
+        ...    ${dst['container_name']}
+    END
+
+Perform Sanity Test DT FTTB
+    [Documentation]    This keyword iterate all OLTs and performs Sanity Test Procedure for DT-FTTB workflow
+    ...    For repeating sanity test without subscriber changes set flag supress_add_subscriber=True.
+    ...    In all other (common) cases flag has to be set False (default).
+    [Arguments]    ${supress_add_subscriber}=False
+    FOR    ${J}    IN RANGE    0    ${num_olts}
+        ${olt_serial_number}=    Set Variable    ${list_olts}[${J}][sn]
+        ${olt_device_id}=    Get OLTDeviceID From OLT List    ${olt_serial_number}
+        ${of_id}=    Wait Until Keyword Succeeds    ${timeout}    15s    Validate OLT Device in VGC
+        ...    ${olt_serial_number}
+        ${nni_port}=    Wait Until Keyword Succeeds    ${timeout}    2s    Get NNI Port in VGC    ${of_id}
+        Perform Sanity Test DT FTTB Per OLT    ${of_id}    ${nni_port}    ${olt_serial_number}
+        ...    ${supress_add_subscriber}
+    END
+
+Perform Sanity Test DT FTTB Per OLT
+    [Arguments]    ${of_id}    ${nni_port}    ${olt_serial_number}    ${supress_add_subscriber}=False
+    [Documentation]    This keyword performs Sanity Test Procedure for DT-FTTB Workflow
+    ...    Sanity test performs dhcp and pings (without EAPOL and DHCP flows) for all the ONUs given for the POD
+    ...    This keyword can be used to call in any other tests where sanity check is required
+    ...    and avoids duplication of code.
+    ...    For repeating sanity test without subscriber changes set flag supress_add_subscriber=True.
+    ...    In all other (common) cases flag has to be set False (default).
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        Continue For Loop If    "${olt_serial_number}"!="${src['olt']}"
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        ${onu_port}=    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Get ONU Port in VGC    ${src['onu']}    ${of_id}    ${src['uni_id']}
+        # Check ONU port is Enabled in VGC
+        Wait Until Keyword Succeeds   120s   2s
+        ...    Verify UNI Port Is Enabled      ${src['onu']}    ${src['uni_id']}
+        Run Keyword Unless    ${supress_add_subscriber}
+        ...     Add Subscriber Details   ${of_id}    ${onu_port}
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify VGC Flows Added For DT FTTB    ${of_id}
+        ...    ${onu_port}    ${nni_port}    ${src['service']}
+        # Verify that the Subscriber is present at the given location
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Programmed Subscribers DT FTTB    ${of_id}
+        ...    ${onu_port}    ${src['service']}
+        # Verify ONU state in voltha
+        ${onu_reasons}=  Create List     omci-flows-pushed
+        Run Keyword If    ${supress_add_subscriber}    Append To List    ${onu_reasons}    onu-reenabled
+        Wait Until Keyword Succeeds    ${timeout}    5s    Validate Device
+        ...    ENABLED    ACTIVE    REACHABLE
+        ...    ${src['onu']}    onu=True    onu_reason=${onu_reasons}
+        # Verify Meters in VGC
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Meters in VGC Ietf    ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${of_id}    ${onu_port}
+        ...    FTTB_SUBSCRIBER_TRAFFIC
+        Run Keyword If    ${has_dataplane}    Validate DHCP and Ping    True
+        ...    True    ${src['dp_iface_name']}    ${src['s_tag']}    ${src['c_tag']}    ${dst['dp_iface_ip_qinq']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        ...    ${dst['dp_iface_name']}    ${dst['ip']}    ${dst['user']}    ${dst['pass']}    ${dst['container_type']}
+        ...    ${dst['container_name']}
+    END
+
+Validate All OLT Flows
+    [Documentation]    This keyword iterate all OLTs and performs Sanity Test Procedure for DT workflow
+    FOR    ${J}    IN RANGE    0    ${num_olts}
+        ${olt_serial_number}=    Set Variable    ${list_olts}[${J}][sn]
+        ${num_onus}=    Set Variable    ${list_olts}[${J}][onucount]
+        ${olt_device_id}=    Get OLTDeviceID From OLT List    ${olt_serial_number}
+        ${of_id}=    Wait Until Keyword Succeeds    ${timeout}    15s    Validate OLT Device in VGC
+        ...    ${olt_serial_number}
+        Set Global Variable    ${of_id}
+        # Verify VGC Flows
+        # Number of Access Flows on VGC equals 4 * the Number of Active ONUs (2 for each downstream and upstream)
+        ${vgc_flows_count}=    Evaluate    4 * ${num_onus}
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Subscriber Access Flows Added Count DT    ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${of_id}
+        ...    ${vgc_flows_count}
+        # Verify VOLTHA Flows
+        # Number of per OLT Flows equals Twice the Number of Active ONUs (each for downstream and upstream) + 1 for LLDP
+        ${olt_flows}=    Evaluate    2 * ${num_onus}
+        # Number of per ONU Flows equals 2 (one each for downstream and upstream)
+        ${onu_flows}=    Set Variable    2
+        Run Keyword    Wait Until Keyword Succeeds    ${timeout}    5s    Validate OLT Flows    ${olt_flows}
+        ...    ${olt_device_id}
+        ${List_ONU_Serial}    Create List
+        Set Suite Variable    ${List_ONU_Serial}
+        Build ONU SN List    ${List_ONU_Serial}    ${olt_serial_number}
+        Log    ${List_ONU_Serial}
+        Run Keyword    Wait Until Keyword Succeeds    ${timeout}    5s    Validate ONU Flows
+        ...    ${List_ONU_Serial}    ${onu_flows}
+    END
+
+Setup Soak
+    [Documentation]    Pre-test Setup for Soak Job
+    ${olt_ids}    Create List
+    FOR    ${I}    IN RANGE    0    ${num_olts}
+        ${olt_serial_number}=    Set Variable    ${list_olts}[${I}][sn]
+        ${olt_device_id}=    Get Device ID From SN    ${olt_serial_number}
+        ${logical_id}=    Get Logical Device ID From SN    ${olt_serial_number}
+        ${of_id}=    Wait Until Keyword Succeeds    ${timeout}    15s    Validate OLT Device in VGC
+        ...    ${olt_serial_number}
+        ${nni_port}=    Wait Until Keyword Succeeds    ${timeout}    2s    Get NNI Port in VGC    ${of_id}
+        ${olt}    Create Dictionary    device_id    ${olt_device_id}    logical_id    ${logical_id}
+        ...    of_id    ${of_id}    sn    ${olt_serial_number}
+        Append To List    ${olt_ids}    ${olt}
+    END
+    Set Global Variable    ${olt_ids}
+
+Setup
+    [Documentation]    Pre-test Setup
+    [Arguments]    ${skip_empty_device_list_test}=False
+    #test for empty device list
+    Run Keyword If    '${skip_empty_device_list_test}'=='False'    Test Empty Device List
+    # TBD: Need for this Sleep
+    Run Keyword If    ${has_dataplane}    Sleep    180s
+    # Create a list of olt ids (logical and device_id)
+    ${olt_ids}    Create List
+    FOR    ${I}    IN RANGE    0    ${num_olts}
+        #create/preprovision device
+        ${olt_device_id}=    Run Keyword If    "${list_olts}[${I}][type]" == "${None}"
+        ...    Create Device    ${list_olts}[${I}][ip]    ${list_olts}[${I}][oltport]
+        ...    ELSE    Create Device    ${list_olts}[${I}][ip]    ${list_olts}[${I}][oltport]    ${list_olts}[${I}][type]
+        ${olt_serial_number}=    Set Variable    ${list_olts}[${I}][sn]
+        #Set Suite Variable    ${olt_device_id}
+        #validate olt states
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate OLT Device    PREPROVISIONED    UNKNOWN    UNKNOWN    ${olt_device_id}    by_dev_id=True
+        Sleep    5s
+        Enable Device    ${olt_device_id}
+        # Increasing the timer to incorporate wait time for in-band
+        Wait Until Keyword Succeeds    540s    5s
+        ...    Validate OLT Device    ENABLED    ACTIVE    REACHABLE    ${olt_serial_number}
+        ${logical_id}=    Get Logical Device ID From SN    ${olt_serial_number}
+        # Set Suite Variable    ${logical_id}
+        ${of_id}=    Wait Until Keyword Succeeds    ${timeout}    15s    Validate OLT Device in VGC
+        ...    ${olt_serial_number}
+        ${olt}    Create Dictionary    device_id    ${olt_device_id}    logical_id    ${logical_id}
+        ...    of_id    ${of_id}    sn    ${olt_serial_number}
+        Append To List    ${olt_ids}    ${olt}
+    END
+    Set Global Variable    ${olt_ids}
+
+Get ofID From OLT List
+    [Documentation]    Retrieves the corresponding of_id for the OLT serial number specified
+    [Arguments]      ${serial_number}
+    FOR    ${I}    IN RANGE    0    ${olt_count}
+        ${sn}=    Get From Dictionary    ${olt_ids}[${I}]    sn
+        ${of_id}=    Run Keyword IF    "${serial_number}"=="${sn}"
+        ...    Get From Dictionary    ${olt_ids}[${I}]    of_id    ELSE    Set Variable    ${of_id}
+    END
+    [Return]    ${of_id}
+
+Get OLTDeviceID From OLT List
+    [Documentation]    Retrieves the corresponding olt_device_id  for the OLT serial number specified
+    [Arguments]      ${serial_number}
+    ${olt_device_id}=    Set Variable    0
+    FOR    ${I}    IN RANGE    0    ${olt_count}
+        ${sn}=    Get From Dictionary    ${olt_ids}[${I}]    sn
+        ${olt_device_id}=    Run Keyword IF    "${serial_number}"=="${sn}"
+        ...    Get From Dictionary    ${olt_ids}[${I}]    device_id    ELSE    Set Variable    ${olt_device_id}
+    END
+    [Return]    ${olt_device_id}
+
+Get Num of Onus From OLT SN
+    [Documentation]    Retrieves the corresponding number of ONUs for a given OLT based on serial number specified
+    [Arguments]      ${serial_number}
+    ${num_of_olt_onus}=    Set Variable    0
+    FOR    ${I}    IN RANGE    0    ${olt_count}
+        ${sn}=    Get From Dictionary    ${olt_ids}[${I}]    sn
+        ${num_of_olt_onus}=    Run Keyword IF    "${serial_number}"=="${sn}"
+        ...    Get From Dictionary    ${list_olts}[${I}]    onucount    ELSE    Set Variable    ${num_of_olt_onus}
+    END
+    [Return]    ${num_of_olt_onus}
+
+Validate ONUs After OLT Disable
+    [Documentation]    Validates the ONUs state in Voltha, ONUs port state in VGC
+    ...    and that pings do not succeed After corresponding OLT is Disabled
+    [Arguments]      ${num_onus}    ${olt_serial_number}
+    FOR    ${I}    IN RANGE    0    ${num_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        Continue For Loop If    "${olt_serial_number}"!="${src['olt']}"
+        ${of_id}=    Get ofID From OLT List    ${src['olt']}
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        ${onu_port}=    Wait Until Keyword Succeeds    ${timeout}    2s    Get ONU Port in VGC    ${src['onu']}
+        ...    ${of_id}
+        ${valid_onu_states}=    Create List    stopping-openomci    omci-flows-deleted
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate Device    ENABLED    DISCOVERED
+        ...    UNREACHABLE    ${src['onu']}    onu=True    onu_reason=${valid_onu_states}
+        Wait Until Keyword Succeeds   ${timeout}    2s
+        ...    Verify UNI Port Is Disabled   ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${src['onu']}    ${src['uni_id']}
+        Run Keyword If    ${has_dataplane}    Run Keyword And Continue On Failure
+        ...    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Check Ping    False    ${dst['dp_iface_ip_qinq']}    ${src['dp_iface_name']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+    END
+
+Delete All Devices and Verify
+    [Documentation]    Remove any devices from VOLTHA and VGC
+    [Arguments]    ${maclearning_enabled}=False
+    # Clear devices from VOLTHA
+    ${resp}=    Get Request    VGC    devices
+    ${jsondata}=    To Json   ${resp.content}
+    ${length}=    Get Length    ${jsondata['devices']}
+    ${matched}=    Set Variable     False
+    ${matched}=    Set Variable If   '${length}' == '${num_olts}'    True    False
+    Run Keyword If     ${matched}     Disable Devices In Voltha    Root=true
+    Wait Until Keyword Succeeds    ${timeout}    2s    Test Devices Disabled In Voltha    Root=true
+    Delete Devices In Voltha    Root=true
+    Wait Until Keyword Succeeds    ${timeout}    2s    Test Empty Device List
+    FOR    ${I}    IN RANGE    0    ${length}
+        ${value}=    Get From List    ${jsondata['devices']}    ${I}
+        ${device_id}=    Get From Dictionary    ${value}    id
+        ${olt_serial_number}=    Get From Dictionary    ${value}    serial
+        #${olt_serial_number}=    Set Variable    ${list_olts}[${I}][sn]
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate Deleted Device Cleanup In VGC    ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${olt_serial_number}    ${device_id}
+        ...    ${maclearning_enabled}
+    END
+    Wait Until Keyword Succeeds    ${timeout}    5s    Validate Cleanup In ETCD    ${INFRA_NAMESPACE}
+
+Teardown
+    [Documentation]    kills processes and cleans up interfaces on src+dst servers
+    Run Keyword If    ${has_dataplane}    Clean Up Linux
+
+Teardown Suite
+    [Documentation]    Clean up device if desired
+    Start Logging Setup or Teardown  Teardown-${SUITE NAME}
+    Run Keyword If    ${has_dataplane}    Clean Up Linux
+    Run Keyword If    ${teardown_device}    Deactivate Subscribers In VGC
+    Run Keyword If    ${teardown_device}    Delete All Devices and Verify
+    Run Keyword And Continue On Failure    Collect Logs
+    #Close All VGC SSH Connections
+    Run Keyword If    ${has_dataplane}    Clean Up All Nodes
+    Stop Logging Setup or Teardown    Teardown-${SUITE NAME}
+
+Delete Device and Verify
+    [Arguments]    ${olt_serial_number}
+    [Documentation]    Disable -> Delete devices via voltctl and verify its removed
+    ${olt_device_id}=    Get Device ID From SN    ${olt_serial_number}
+    ${rc}    ${output}=    Run and Return Rc and Output
+    ...    voltctl -c ${VOLTCTL_CONFIG} device disable ${olt_device_id}
+    Should Be Equal As Integers    ${rc}    0
+    Sleep    5s
+    Wait Until Keyword Succeeds    ${timeout}    5s
+    ...    Validate OLT Device    DISABLED    UNKNOWN    REACHABLE    ${olt_serial_number}
+    ${rc}    ${output}=    Run and Return Rc and Output
+    ...    voltctl -c ${VOLTCTL_CONFIG} device delete ${olt_device_id}
+    Sleep    50s
+    Should Be Equal As Integers    ${rc}    0
+    Wait Until Keyword Succeeds    ${timeout}    5s    Validate Device Removed    ${olt_device_id}
+    Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    15s
+    ...    Validate Deleted Device Cleanup In VGC    ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${olt_serial_number}    ${olt_device_id}
+
+Disable Enable PON Port Per OLT DT
+    [Arguments]    ${olt_serial_number}
+    [Documentation]    This keyword disables and then enables OLT PON port and
+    ...    also validate ONUs for each corresponding case
+    ${olt_device_id}=    Get OLTDeviceID From OLT List    ${olt_serial_number}
+    ${olt_pon_port_list}=    Retrieve OLT PON Ports    ${olt_device_id}
+    ${olt_pon_port_list_len}=    Get Length    ${olt_pon_port_list}
+    FOR    ${INDEX0}    IN RANGE    0    ${olt_pon_port_list_len}
+        ${olt_pon_port}=    Get From List    ${olt_pon_port_list}    ${INDEX0}
+        ${olt_peer_list}=    Retrieve Peer List From OLT PON Port    ${olt_device_id}    ${olt_pon_port}
+        ${olt_peer_list_len}=    Get Length    ${olt_peer_list}
+        # Disable the OLT PON Port and Validate OLT Device
+        DisableOrEnable OLT PON Port    disable    ${olt_device_id}    ${olt_pon_port}
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate OLT PON Port Status    ${olt_device_id}    ${olt_pon_port}
+        ...    DISABLED    DISCOVERED
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate OLT Device    ENABLED    ACTIVE    REACHABLE
+        ...    ${olt_serial_number}
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate ONUs for PON OLT Disable DT    ${olt_serial_number}    ${olt_peer_list}
+        # Enable the OLT PON Port back, and check ONU status are back to "ACTIVE"
+        DisableOrEnable OLT PON Port    enable    ${olt_device_id}    ${olt_pon_port}
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate OLT PON Port Status    ${olt_device_id}    ${olt_pon_port}
+        ...    ENABLED    ACTIVE
+        ${olt_peer_list_new}=    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Retrieve Peer List From OLT PON Port    ${olt_device_id}    ${olt_pon_port}    ${olt_peer_list_len}
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate ONUs for PON OLT Enable DT    ${olt_serial_number}    ${olt_peer_list_new}
+    END
+
+Validate ONUs for PON OLT Disable DT
+    [Arguments]    ${olt_sn}    ${olt_peer_list}
+    [Documentation]     This keyword validates that Ping fails for ONUs connected to Disabled OLT PON port
+    ...    And Pings succeed for other Active OLT PON port ONUs
+    ...    Also it removes subscriber and deletes ONUs for Disabled OLT PON port to replicate DT workflow
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        Continue For Loop If    "${olt_sn}"!="${src['olt']}"
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        ${of_id}=    Wait Until Keyword Succeeds    ${timeout}    15s    Validate OLT Device in VGC    ${src['olt']}
+        ${onu_port}=    Wait Until Keyword Succeeds    ${timeout}    2s    Get ONU Port in VGC    ${src['onu']}
+        ...    ${of_id}    ${src['uni_id']}
+        ${matched}=    Match ONU in PON OLT Peer List    ${olt_peer_list}    ${onu_device_id}
+        ${valid_onu_states}=    Create List    stopping-openomci    omci-flows-deleted
+        Run Keyword If    ${matched}
+        ...    Run Keywords
+        ...    Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate Device    ENABLED    DISCOVERED
+        ...    UNREACHABLE    ${src['onu']}    onu=True    onu_reason=${valid_onu_states}
+        ...    AND    Wait Until Keyword Succeeds   ${timeout}    2s
+        ...    Verify UNI Port Is Disabled   ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${src['onu']}    ${src['uni_id']}
+        ...    AND    Run Keyword If    ${has_dataplane}    Run Keyword And Continue On Failure
+        ...    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Check Ping    False    ${dst['dp_iface_ip_qinq']}    ${src['dp_iface_name']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}
+        ...    ${src['container_name']}
+        # Remove Subscriber Access (To replicate DT workflow)
+        ...    AND    Wait Until Keyword Succeeds    ${timeout}    2s     Remove Subscriber Access   ${of_id}   ${onu_port}
+        #Execute VGC CLI Command use single connection
+        #...    ${VGC_SSH_IP}    ${VGC_SSH_PORT}    volt-remove-subscriber-access ${of_id} ${onu_port}
+        # Delete ONU Device (To replicate DT workflow)
+        ...    AND    Delete Device    ${onu_device_id}
+        # Additional Sleep to let subscriber and ONU delete process
+        ...    AND    Sleep    10s
+        ...    ELSE
+        ...    Run Keyword If    ${has_dataplane}    Run Keyword And Continue On Failure
+        ...    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Check Ping    True    ${dst['dp_iface_ip_qinq']}    ${src['dp_iface_name']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}
+        ...    ${src['container_name']}
+    END
+
+Validate ONUs for PON OLT Enable DT
+    [Arguments]    ${olt_sn}    ${olt_peer_list}
+    [Documentation]    This keyword validates Ping succeeds for all Enabled/Acitve OLT PON ports
+    ...    Also performs subscriberAdd/DHCP/Ping for the ONUs on Re-Enabled OLT PON port
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        Continue For Loop If    "${olt_sn}"!="${src['olt']}"
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        ${of_id}=    Wait Until Keyword Succeeds    ${timeout}    15s    Validate OLT Device in VGC    ${src['olt']}
+        ${nni_port}=    Wait Until Keyword Succeeds    ${timeout}    2s    Get NNI Port in VGC    ${of_id}
+        ${onu_port}=    Wait Until Keyword Succeeds    ${timeout}    2s    Get ONU Port in VGC    ${src['onu']}
+        ...    ${of_id}    ${src['uni_id']}
+        ${matched}=    Match ONU in PON OLT Peer List    ${olt_peer_list}    ${onu_device_id}
+        Run Keyword If    ${matched}
+        ...    Run Keywords
+        # Perform Cleanup
+        ...    Run Keyword If    ${has_dataplane}    Clean Up Linux    ${onu_device_id}
+        # Verify ONU port status
+        ...    AND    Wait Until Keyword Succeeds   120s   2s
+        ...    Verify UNI Port Is Enabled    ${src['onu']}    ${src['uni_id']}
+        ...    AND    Wait Until Keyword Succeeds    ${timeout}    2
+       # ...    Execute VGC CLI Command use single connection    ${VGC_SSH_IP}    ${VGC_SSH_PORT}
+       # ...    volt-add-subscriber-access ${of_id} ${onu_port}
+        ...   Add Subscriber Details   ${of_id}   ${onu_port}
+        # Verify ONU state in voltha
+        ...    AND    Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate Device    ENABLED    ACTIVE    REACHABLE
+        ...    ${src['onu']}    onu=True    onu_reason=omci-flows-pushed
+        # Verify subscriber access flows are added for the ONU port
+        ...    AND    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Subscriber Access Flows Added For ONU DT In VGC   ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${of_id}
+        ...    ${onu_port}    ${nni_port}    ${src['s_tag']}
+        ...    AND    Run Keyword If    ${has_dataplane}
+        ...    Run Keyword And Continue On Failure    Validate DHCP and Ping    True
+        ...    True    ${src['dp_iface_name']}    ${src['s_tag']}    ${src['c_tag']}    ${dst['dp_iface_ip_qinq']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}
+        ...    ${src['container_type']}    ${src['container_name']}
+        ...    ${dst['dp_iface_name']}    ${dst['ip']}    ${dst['user']}    ${dst['pass']}
+        ...    ${dst['container_type']}    ${dst['container_name']}
+        ...    ELSE
+        ...    Run Keyword If    ${has_dataplane}    Run Keyword And Continue On Failure
+        ...    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Check Ping    True    ${dst['dp_iface_ip_qinq']}    ${src['dp_iface_name']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}
+        ...    ${src['container_name']}
+    END
+
+Match ONU in PON OLT Peer List
+    [Arguments]    ${olt_peer_list}    ${onu_device_id}
+    [Documentation]     This keyword matches if ONU device is present in OLT PON port peer list
+    ${matched}=    Set Variable    False
+    FOR    ${olt_peer}    IN    @{olt_peer_list}
+        ${matched}=    Set Variable If    '${onu_device_id}' == '${olt_peer}'    True    False
+        Exit For Loop If    ${matched}
+    END
+    [Return]    ${matched}
+
+Collect Logs
+    [Documentation]    Collect Logs from voltha for various commands
+    Run Keyword and Ignore Error    Get Device List from Voltha
+    FOR    ${I}    IN RANGE    0    ${num_olts}
+        Run Keyword and Ignore Error    Get Device Output from Voltha    ${olt_ids}[${I}][device_id]
+        Run Keyword and Ignore Error    Get Logical Device Output from Voltha    ${olt_ids}[${I}][logical_id]
+    END
+
+Verify ping is successful except for given device
+    [Arguments]    ${num_onus}    ${exceptional_onu}
+    [Documentation]    Checks that ping for all the devices are successful except the given ONU.
+    ${pingStatus}     Set Variable    True
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        ${pingStatus}     Run Keyword If    '${src['onu']}' == '${exceptional_onu}'    Set Variable     False
+        Run Keyword If    ${has_dataplane}    Run Keyword And Continue On Failure
+        ...    Wait Until Keyword Succeeds    60s    2s
+        ...    Check Ping    ${pingStatus}    ${dst['dp_iface_ip_qinq']}    ${src['dp_iface_name']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}   ${src['container_type']}    ${src['container_name']}
+    END
+
+Verify ping is successful for ONUs not on this OLT
+    [Arguments]    ${num_all_onus}    ${exceptional_olt_id}
+    [Documentation]    Checks that pings work for all the ONUs except for the ONUs on the given OLT.
+    #${pingStatus}     Set Variable    True
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        ${olt_device_id}=    Get Device ID From SN    ${src['olt']}
+        Continue For Loop If    "${olt_device_id}"=="${exceptional_olt_id}"
+        #${pingStatus}     Run Keyword If    '${olt_device_id}' == '${exceptional_olt_id}'    Set Variable     False
+        Run Keyword If    ${has_dataplane}    Run Keyword And Continue On Failure
+        ...    Wait Until Keyword Succeeds    60s    2s
+        ...    Check Ping    True    ${dst['dp_iface_ip_qinq']}    ${src['dp_iface_name']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}   ${src['container_type']}    ${src['container_name']}
+    END
+
+Echo Message to OLT Logs
+    [Arguments]    ${message}
+    [Documentation]     Echoes ${message} into the OLT logs
+    FOR    ${I}    IN RANGE    0    ${num_olts}
+        ${olt_user}    Evaluate    ${olts}[${I}].get("user")
+        ${olt_pass}    Evaluate    ${olts}[${I}].get("pass")
+        ${olt_ssh_ip}    Evaluate    ${olts}[${I}].get("sship")
+        ${olt_type}    Evaluate    ${olts}[${I}].get("type")
+        Continue For Loop If    "${olt_user}" == "${None}"
+        Continue For Loop If    "${olt_pass}" == "${None}"
+        ${command_timeout}=    Set Variable If   "${olt_type}"=="adtranolt"    300s    180s
+        Wait Until Keyword Succeeds    ${command_timeout}    10s    Execute Remote Command
+        ...    printf '%s\n' '' '' '${message}' '' >> /var/log/openolt.log
+        ...    ${olt_ssh_ip}    ${olt_user}    ${olt_pass}
+        Wait Until Keyword Succeeds    ${command_timeout}    10s    Execute Remote Command
+        ...    printf '%s\n' '' '' '${message}' '' >> /var/log/dev_mgmt_daemon.log
+        ...    ${olt_ssh_ip}    ${olt_user}    ${olt_pass}
+        Wait Until Keyword Succeeds    ${command_timeout}    10s    Execute Remote Command
+        ...    printf '%s\n' '' '' '${message}' '' >> /var/log/openolt_process_watchdog.log
+        ...    ${olt_ssh_ip}    ${olt_user}    ${olt_pass}
+    END
+
+Start Logging
+    [Arguments]    ${label}
+    [Documentation]    Start logging for test ${label}
+    ${kail_process}=     Run Keyword If    "${container_log_dir}" != "${None}"   Start Process    kail    -n    ${NAMESPACE}
+    ...    -n    ${INFRA_NAMESPACE}    cwd=${container_log_dir}   stdout=${label}-combined.log
+    Set Test Variable    ${kail_process}
+    Run Keyword If    ${has_dataplane}    Echo Message to OLT Logs     START ${label}
+
+Start Logging Setup or Teardown
+    [Arguments]    ${label}
+    [Documentation]    Start logging for suite ${label}
+    ${file}=    Replace String    ${label}    ${SPACE}  -
+    ${kail_process}=     Run Keyword If    "${container_log_dir}" != "${None}"   Start Process    kail    -n    ${NAMESPACE}
+    ...    -n    ${INFRA_NAMESPACE}    cwd=${container_log_dir}   stdout=${file}-combined.log
+    Set Suite Variable    ${kail_process}
+    Run Keyword If    ${has_dataplane}    Echo Message to OLT Logs     START ${label}
+
+Stop Logging Setup or Teardown
+    [Arguments]    ${label}
+    [Documentation]    End logging for suite;
+    Run    sync
+    Run Keyword If    ${kail_process}    Terminate Process    ${kail_process}
+    ${test_logfile}=    Run Keyword If    "${container_log_dir}" != "${None}"
+    ...    Join Path    ${container_log_dir}    ${label}-combined.log
+    Run Keyword If    ${has_dataplane}    Echo Message to OLT Logs     END ${label}
+
+Stop Logging
+    [Arguments]    ${label}
+    [Documentation]    End logging for test; remove logfile if test passed and ${logging} is set to False
+    Run    sync
+    Run Keyword If    ${kail_process}    Terminate Process    ${kail_process}
+    ${test_logfile}=    Run Keyword If    "${container_log_dir}" != "${None}"
+    ...    Join Path    ${container_log_dir}    ${label}-combined.log
+    Run Keyword If Test Passed
+    ...    Run Keyword If    "${logging}" == "False"
+    ...    Run Keyword If    "${test_logfile}" != "${None}"
+    ...    Remove File    ${test_logfile}
+    Run Keyword If    ${has_dataplane}    Echo Message to OLT Logs     END ${label}
+
+Clean Up Linux
+    [Documentation]    Kill processes and clean up interfaces on src+dst servers
+    [Arguments]    ${onu_id}=${EMPTY}
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        Continue For Loop If    '${onu_id}' != '${EMPTY}' and '${onu_id}' != '${onu_device_id}'
+        Execute Remote Command    sudo pkill wpa_supplicant    ${src['ip']}
+        ...    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        Execute Remote Command    sudo pkill dhclient    ${src['ip']}
+        ...    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        Execute Remote Command    sudo pkill mausezahn    ${src['ip']}
+        ...    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        Run Keyword If    '${dst['ip']}' != '${None}'    Execute Remote Command    pkill dhcpd
+        ...    ${dst['ip']}    ${dst['user']}    ${dst['pass']}    ${dst['container_type']}    ${dst['container_name']}
+        Delete IP Addresses from Interface on Remote Host    ${src['dp_iface_name']}    ${src['ip']}
+        ...    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        Run Keyword If    '${dst['ip']}' != '${None}'    Delete Interface on Remote Host
+        ...    ${dst['dp_iface_name']}.${src['s_tag']}    ${dst['ip']}    ${dst['user']}    ${dst['pass']}
+        ...    ${dst['container_type']}    ${dst['container_name']}
+        ${bng_ip}=    Get Variable Value    ${dst['noroot_ip']}
+        ${bng_user}=    Get Variable Value    ${dst['noroot_user']}
+        ${bng_pass}=    Get Variable Value    ${dst['noroot_pass']}
+        Run Keyword If    "${bng_ip}" != "${NONE}" and "${bng_user}" != "${NONE}" and "${bng_pass}" != "${NONE}"
+        ...    Execute Remote Command    sudo pkill mausezahn    ${bng_ip}    ${bng_user}    ${bng_pass}
+        ...    ${dst['container_type']}    ${dst['container_name']}
+    END
+
+Clean Up Linux Per OLT
+    [Documentation]    Kill processes and clean up interfaces on src+dst servers
+    [Arguments]    ${olt_serial_number}
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        ${sn}=    Get Device ID From SN    ${src['olt']}
+        #Continue For Loop If    '${onu_id}' != '${EMPTY}' and '${onu_id}' != '${onu_device_id}'
+        Continue For Loop If    '${olt_serial_number}' == '${sn}'
+        Execute Remote Command    sudo pkill wpa_supplicant    ${src['ip']}
+        ...    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        Execute Remote Command    sudo pkill dhclient    ${src['ip']}
+        ...    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        Execute Remote Command    sudo pkill mausezahn    ${src['ip']}
+        ...    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        Run Keyword If    '${dst['ip']}' != '${None}'    Execute Remote Command    pkill dhcpd
+        ...    ${dst['ip']}    ${dst['user']}    ${dst['pass']}    ${dst['container_type']}    ${dst['container_name']}
+        Delete IP Addresses from Interface on Remote Host    ${src['dp_iface_name']}    ${src['ip']}
+        ...    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        Run Keyword If    '${dst['ip']}' != '${None}'    Delete Interface on Remote Host
+        ...    ${dst['dp_iface_name']}.${src['s_tag']}    ${dst['ip']}    ${dst['user']}    ${dst['pass']}
+        ...    ${dst['container_type']}    ${dst['container_name']}
+        ${bng_ip}=    Get Variable Value    ${dst['noroot_ip']}
+        ${bng_user}=    Get Variable Value    ${dst['noroot_user']}
+        ${bng_pass}=    Get Variable Value    ${dst['noroot_pass']}
+        Run Keyword If    "${bng_ip}" != "${NONE}" and "${bng_user}" != "${NONE}" and "${bng_pass}" != "${NONE}"
+        ...    Execute Remote Command    sudo pkill mausezahn    ${bng_ip}    ${bng_user}    ${bng_pass}
+        ...    ${dst['container_type']}    ${dst['container_name']}
+    END
+
+Clean dhclient
+    [Documentation]    Kills dhclient processes only for all RGs
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        Execute Remote Command    sudo pkill dhclient    ${src['ip']}
+        ...    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+    END
+
+Clean WPA Process
+    [Documentation]    Kills wpa_supplicant processes only for all RGs
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        Run Keyword And Ignore Error    Kill Linux Process    [w]pa_supplicant    ${src['ip']}
+        ...    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+    END
+
+Should Be Larger Than
+    [Documentation]    Verify that value_1 is > value_2
+    [Arguments]    ${value_1}    ${value_2}
+    Run Keyword If    ${value_1} <= ${value_2}
+    ...    Fail    The value ${value_1} is not larger than ${value_2}
+
+Should Be Larger Than Or Equal To
+    [Documentation]    Verify that value_1 is >= value_2
+    [Arguments]    ${value_1}    ${value_2}
+    Run Keyword If    ${value_1} < ${value_2}
+    ...    Fail    The value ${value_1} is not larger than or equal to ${value_2}
+
+Should Be Lower Than
+    [Documentation]    Verify that value_1 is < value_2
+    [Arguments]    ${value_1}    ${value_2}
+    Run Keyword If    ${value_1} >= ${value_2}
+    ...    Fail    The value ${value_1} is not lower than ${value_2}
+
+Should Be Float
+    [Documentation]    Verify that value is a floating point number type
+    [Arguments]    ${value}
+    ${type}    Evaluate    type(${value}).__name__
+    Should Be Equal    ${type}    float
+
+Should Be Newer Than Or Equal To
+    [Documentation]    Compare two RFC3339 dates
+    [Arguments]    ${value_1}    ${value_2}
+    ${unix_v1}    Parse RFC3339    ${value_1}
+    ${unix_v2}    Parse RFC3339    ${value_2}
+    Run Keyword If    ${unix_v1} < ${unix_v2}
+    ...    Fail    The value ${value_1} is not newer than or equal to ${value_2}
+
+Get Current Time
+    [Documentation]    Return the current time in RFC3339 format
+    ${output}=    Run    date -u +"%FT%T%:z"
+    [return]     ${output}
+
+Parse RFC3339
+    [Documentation]     Parse an RFC3339 timestamp
+    [Arguments]    ${dateStr}
+    ${rc}    ${output}=    Run and Return Rc and Output     date --date="${dateStr}" "+%s"
+    Should Be Equal As Numbers    ${rc}    0
+    [return]    ${output}
+
+Execute Remote Command
+    [Documentation]    SSH into a remote host and execute a command on the bare host or in a container.
+    ...    This replaces and simplifies the Login And Run Command On Remote System keyword in CORDRobot.
+    [Arguments]    ${cmd}    ${ip}    ${user}    ${pass}=${None}
+    ...    ${container_type}=${None}    ${container_name}=${None}    ${timeout}=${None}
+    ${conn_id}=    SSHLibrary.Open Connection    ${ip}
+    Run Keyword If    '${pass}' != '${None}'
+    ...    SSHLibrary.Login    ${user}    ${pass}
+    ...    ELSE
+    ...    SSHLibrary.Login With Public Key    ${user}    %{HOME}/.ssh/id_rsa
+    ${namespace}=    Run Keyword If    '${container_type}' == 'K8S'    SSHLibrary.Execute Command
+    ...    kubectl get pods --all-namespaces | grep ${container_name} | awk '{print $1}'
+    ${stdout}    ${stderr}    ${rc}=    Run Keyword If    '${container_type}' == 'LXC'
+    ...        SSHLibrary.Execute Command    lxc exec ${container_name} -- ${cmd}
+    ...        return_stderr=True    return_rc=True    timeout=${timeout}
+    ...    ELSE IF    '${container_type}' == 'K8S'
+    ...        SSHLibrary.Execute Command    kubectl -n ${namespace} exec ${container_name} -- ${cmd}
+    ...        return_stderr=True    return_rc=True    timeout=${timeout}
+    ...    ELSE
+    ...        SSHLibrary.Execute Command    ${cmd}    return_stderr=True    return_rc=True    timeout=${timeout}
+
+    Log    ${stdout}
+    Log    ${stderr}
+    Log    ${rc}
+    SSHLibrary.Close Connection
+    [Return]    ${stdout}    ${stderr}    ${rc}
+
+Start Remote Command
+    [Documentation]    SSH into a remote host and execute a command on the bare host or in a container.
+    ...    This replaces and simplifies the Login And Run Command On Remote System keyword in CORDRobot.
+    [Arguments]    ${cmd}    ${ip}    ${user}    ${pass}=${None}
+    ...    ${container_type}=${None}    ${container_name}=${None}
+    ${conn_id}=    SSHLibrary.Open Connection    ${ip}
+    Run Keyword If    '${pass}' != '${None}'
+    ...    SSHLibrary.Login    ${user}    ${pass}
+    ...    ELSE
+    ...    SSHLibrary.Login With Public Key    ${user}    %{HOME}/.ssh/id_rsa
+    ${namespace}=    Run Keyword If    '${container_type}' == 'K8S'    SSHLibrary.Execute Command
+    ...    kubectl get pods --all-namespaces | grep ${container_name} | awk '{print $1}'
+    Run Keyword If    '${container_type}' == 'LXC'
+    ...        SSHLibrary.Start Command    lxc exec ${container_name} -- ${cmd}
+    ...    ELSE IF    '${container_type}' == 'K8S'
+    ...        SSHLibrary.Start Command    kubectl -n ${namespace} exec ${container_name} -- ${cmd}
+    ...    ELSE
+    ...        SSHLibrary.Start Command    ${cmd}
+    # It seems that closing the connection immediately will sometimes kill the command
+    Sleep    1s
+    SSHLibrary.Close Connection
+
+Run Iperf3 Test Client
+    [Arguments]    ${src}    ${server}    ${args}
+    [Documentation]    Login to ${src} and run the iperf3 client against ${server} using ${args}.
+    ...    Return a Dictionary containing the results of the test.
+    ${output}    ${stderr}    ${rc}=    Execute Remote Command    iperf3 -J -c ${server} ${args} -l 1024 -M 1350 | jq -M -c '.'
+    ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+    Should Be Equal As Integers    ${rc}    0
+    ${object}=    Evaluate    json.loads(r'''${output}''')    json
+    [Return]    ${object}
+
+Run Iperf Test Client for MCAST
+    [Arguments]    ${src}    ${server}    ${args}
+    [Documentation]    Login to ${src} and run the iperf client against ${server} using ${args}.
+    ...    Return a Dictionary containing the results of the test.
+    ${output}    ${stderr}    ${rc}=    Execute Remote Command    sudo iperf -c ${server} ${args} | jq -M -c '.'
+    ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+    Should Be Equal As Integers    ${rc}    0
+    ${object}=    Evaluate    json.loads(r'''${output}''')    json
+    [Return]    ${object}
+
+Run Ping In Background
+    [Arguments]    ${output_file}    ${dst_ip}    ${iface}    ${ip}    ${user}    ${pass}=${None}
+    ...    ${container_type}=${None}    ${container_name}=${None}
+    [Documentation]    Runs the 'ping' on remote system in background and stores the result in a file
+    ${result}=    Login And Run Command On Remote System
+    ...    echo "ping -I ${iface} ${dst_ip} > ${output_file} &" > ping.sh; chmod +x ping.sh; ./ping.sh
+    ...    ${ip}    ${user}    ${pass}    ${container_type}    ${container_name}
+    Log    ${result}
+
+Stop Ping Running In Background
+    [Arguments]    ${ip}    ${user}    ${pass}=${None}
+    ...    ${container_type}=${None}    ${container_name}=${None}
+    [Documentation]    Stops the 'ping' running in background on remote system
+    ${cmd}=    Run Keyword If    '${container_type}' == 'LXC' or '${container_type}' == 'K8S'
+    ...    Set Variable    kill -SIGINT `pgrep ping`
+    ...    ELSE
+    ...    Set Variable    sudo kill -SIGINT `pgrep ping`
+    ${result}=    Login And Run Command On Remote System
+    ...    ${cmd}    ${ip}    ${user}    ${pass}    ${container_type}    ${container_name}
+    Log    ${result}
+
+Retrieve Remote File Contents
+    [Documentation]    Retrieves the contents of the file on remote system
+    [Arguments]    ${file}    ${ip}    ${user}    ${pass}=${None}
+    ...    ${container_type}=${None}    ${container_name}=${None}    ${prompt}=~$
+    ${output}=    Login And Run Command On Remote System
+    ...    cat ${file}
+    ...    ${ip}    ${user}    ${pass}    ${container_type}    ${container_name}    ${prompt}
+    [Return]    ${output}
+
+RestoreONUs
+    [Documentation]    Restore all connected ONUs
+    [Arguments]    ${num_all_onus}
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${container_type}=    Get Variable Value    ${src['container_type']}    "null"
+        ${container_name}=    Get Variable Value    ${src['container_name']}    "null"
+        ${onu_type}=    Get Variable Value    ${src['onu_type']}    "null"
+        #Get ens6f0 from ens6f0.22
+        ${if_name}=    Replace String Using Regexp    ${src['dp_iface_name']}    \\..*    \
+        Run Keyword IF    '${onu_type}' == 'alpha'    AlphaONURestoreDefault    ${src['ip']}    ${src['user']}
+        ...    ${src['pass']}    ${if_name}    admin    admin    ${container_type}    ${container_name}
+    END
+
+AlphaONURestoreDefault
+    [Documentation]    Restore the Alpha ONU to factory setting
+    [Arguments]    ${rg_ip}    ${rg_user}    ${rg_pass}    ${onu_ifname}
+    ...    ${onu_user}    ${onu_pass}    ${container_type}=${None}    ${container_name}=${None}
+    ${output}=    Login And Run Command On Remote System    sudo ifconfig ${onu_ifname} 192.168.1.3/24
+    ...    ${rg_ip}    ${rg_user}    ${rg_pass}    ${container_type}    ${container_name}
+    ${cmd}    Catenate
+    ...    (echo open "192.168.1.1"; sleep 1;
+    ...    echo "${onu_user}"; sleep 1;
+    ...    echo "${onu_pass}"; sleep 1;
+    ...    echo "restoredefault"; sleep 1) | telnet
+    ${output}=    Login And Run Command On Remote System    ${cmd}
+    ...    ${rg_ip}    ${rg_user}    ${rg_pass}    ${container_type}    ${container_name}
+    Log To Console    ${output}
+    ${output}=    Login And Run Command On Remote System    sudo ifconfig ${onu_ifname} 0
+    ...    ${rg_ip}    ${rg_user}    ${rg_pass}    ${container_type}    ${container_name}
+
+Create traffic with each pbit and capture at other end
+    [Documentation]    Generates upstream traffic using Mausezahn tool
+    ...    with each pbit and validates reception at other end using tcpdump
+    [Arguments]    ${target_ip}    ${target_iface}    ${src_iface}
+    ...    ${packet_count}    ${packet_type}    ${c_vlan}    ${s_vlan}    ${direction}    ${tcpdump_filter}
+    ...    ${dst_ip}    ${dst_user}    ${dst_pass}    ${dst_container_type}    ${dst_container_name}
+    ...    ${src_ip}    ${src_user}    ${src_pass}    ${src_container_type}    ${src_container_name}
+    FOR    ${pbit}    IN RANGE    8
+        Execute Remote Command    sudo pkill mausezahn
+        ...    ${src_ip}    ${src_user}    ${src_pass}    ${src_container_type}    ${src_container_name}
+        ${var1}=    Set Variable    sudo mausezahn ${src_iface} -B ${target_ip} -c ${packet_count}
+        ${var2}=    Run Keyword If    "${direction}"=="downstream"
+        ...    Set Variable    -t ${packet_type} "dp=80, flags=rst, p=aa:aa:aa" -Q ${pbit}:${s_vlan},${pbit}:${c_vlan}
+        ...    ELSE
+        ...    Set Variable    -t ${packet_type} "dp=80, flags=rst, p=aa:aa:aa" -Q ${pbit}:${c_vlan}
+        ${cmd}=    Set Variable    ${var1} ${var2}
+        Start Remote Command    ${cmd}    ${src_ip}    ${src_user}    ${src_pass}
+        ...    ${src_container_type}    ${src_container_name}
+        ${output}    ${stderr}    ${rc}=    Execute Remote Command
+        ...    sudo tcpdump -l -U -c 30 -i ${target_iface} -e ${tcpdump_filter}
+        ...    ${dst_ip}    ${dst_user}    ${dst_pass}    ${dst_container_type}    ${dst_container_name}
+        ...    timeout=30 seconds
+        Execute Remote Command    sudo pkill mausezahn
+        ...    ${src_ip}    ${src_user}    ${src_pass}    ${src_container_type}    ${src_container_name}
+        Run Keyword If    "${tcpdump_filter}"=="tcp"
+        ...    Should Match Regexp    ${output}    , p ${pbit},
+    END
+
+Determine Number Of ONU
+    [Arguments]    ${olt_serial_number}=${EMPTY}    ${num_onus}=${num_all_onus}
+    [Documentation]    Determine the number of different ONUs for the given OLT taken from host.src
+    ${onu_list}    Create List
+    FOR    ${INDEX}    IN RANGE    0    ${num_onus}
+        Continue For Loop If    "${olt_serial_number}"!="${hosts.src[${INDEX}].olt}" and "${olt_serial_number}"!="${EMPTY}"
+        ${onu_id}=    Get Index From List    ${onu_list}   ${hosts.src[${INDEX}].onu}
+        Run Keyword If    -1 == ${onu_id}    Append To List    ${onu_list}    ${hosts.src[${INDEX}].onu}
+    END
+    ${real_num_onus}=    Get Length    ${onu_list}
+    [Return]    ${real_num_onus}
+
+Validate Cleanup In ETCD
+    [Documentation]    The keyword verifies that device, ports, flows, meters are all cleared in ETCD
+    [Arguments]    ${namespace}=default    ${defaultkvstoreprefix}=voltha/voltha_voltha
+    ${podname}=    Set Variable    etcd
+    ${kvstoreprefix}=    Get Kv Store Prefix    ${defaultkvstoreprefix}
+    # Log Devices Output and Verify Output Should be Empty
+    ${commandget}=    Catenate
+    ...    /bin/sh -c 'ETCDCTL_API=3 etcdctl get --prefix service/${kvstoreprefix}/devices --keys-only'
+    ${result}=    Exec Pod In Kube    ${namespace}    ${podname}    ${commandget}
+    Log    ${result}
+    Should Be Empty    ${result}    Stale Devices Data in Etcd!
+    # Log Flows Output and Verify Output Should be Empty
+    ${commandget}=    Catenate
+    ...    /bin/sh -c 'ETCDCTL_API=3 etcdctl get --prefix service/${kvstoreprefix}/flows --keys-only'
+    ${result}=    Exec Pod In Kube    ${namespace}    ${podname}    ${commandget}
+    Log    ${result}
+    Should Be Empty    ${result}    Stale Flows Data in Etcd!
+    # Log LogicalDevices Output and Verify Output Should be Empty
+    ${commandget}=    Catenate
+    ...    /bin/sh -c 'ETCDCTL_API=3 etcdctl get --prefix service/${kvstoreprefix}/logical_devices --keys-only'
+    ${result}=    Exec Pod In Kube    ${namespace}    ${podname}    ${commandget}
+    Log    ${result}
+    Should Be Empty    ${result}    Stale Logical Devices Data in Etcd!
+    # Log LogicalFlows Output and Verify Output Should be Empty
+    ${commandget}=    Catenate
+    ...    /bin/sh -c 'ETCDCTL_API=3 etcdctl get --prefix service/${kvstoreprefix}/logical_flows --keys-only'
+    ${result}=    Exec Pod In Kube    ${namespace}    ${podname}    ${commandget}
+    Log    ${result}
+    Should Be Empty    ${result}    Stale Logical Flows Data in Etcd!
+    # Log LogicalMeters Output and Verify Output Should be Empty
+    ${commandget}=    Catenate
+    ...    /bin/sh -c 'ETCDCTL_API=3 etcdctl get --prefix service/${kvstoreprefix}/logical_meters --keys-only'
+    ${result}=    Exec Pod In Kube    ${namespace}    ${podname}    ${commandget}
+    Log    ${result}
+    Should Be Empty    ${result}    Stale Logical Meters Data in Etcd!
+    # Log LogicalPorts Output and Verify Output Should be Empty
+    ${commandget}=    Catenate
+    ...    /bin/sh -c 'ETCDCTL_API=3 etcdctl get --prefix service/${kvstoreprefix}/logical_ports --keys-only'
+    ${result}=    Exec Pod In Kube    ${namespace}    ${podname}    ${commandget}
+    Log    ${result}
+    Should Be Empty    ${result}    Stale Logical Ports Data in Etcd!
+    # Log Openolt Output and Verify Output Should be Empty
+    ${commandget}=    Catenate
+    ...    /bin/sh -c 'ETCDCTL_API=3 etcdctl get --prefix service/${kvstoreprefix}/openolt --keys-only'
+    ${result}=    Exec Pod In Kube    ${namespace}    ${podname}    ${commandget}
+    Log    ${result}
+    Should Be Empty    ${result}    Stale Openolt Data in Etcd!
+    # Log Openonu Output and Verify Output Should be Empty
+    ${commandget}=    Catenate
+    ...    /bin/sh -c 'ETCDCTL_API=3 etcdctl get --prefix service/${kvstoreprefix}/openonu --keys-only'
+    ${result}=    Exec Pod In Kube    ${namespace}    ${podname}    ${commandget}
+    Log    ${result}
+    Should Be Empty    ${result}    Stale Openonu Data in Etcd!
+    # Log Ports Output and Verify Output Should be Empty
+    ${commandget}=    Catenate
+    ...    /bin/sh -c 'ETCDCTL_API=3 etcdctl get --prefix service/${kvstoreprefix}/ports --keys-only'
+    ${result}=    Exec Pod In Kube    ${namespace}    ${podname}    ${commandget}
+    Log    ${result}
+    Should Be Empty    ${result}    Stale Ports Data in Etcd!
+    # Log ResourceInstances Output and Verify Output Should be Empty
+    ${commandget}=    Catenate
+    ...    /bin/sh -c 'ETCDCTL_API=3 etcdctl get --prefix service/${kvstoreprefix}/resource_instances --keys-only'
+    ${result}=    Exec Pod In Kube    ${namespace}    ${podname}    ${commandget}
+    Log    ${result}
+    Should Be Empty    ${result}    Stale Resource Instances Data in Etcd!
+    # Log ResourceManager Output and Verify Output Should be Empty
+    ${commandget}=    Catenate
+    ...    /bin/sh -c 'ETCDCTL_API=3 etcdctl get --prefix service/${kvstoreprefix}/resource_manager --keys-only'
+    ${result}=    Exec Pod In Kube    ${namespace}    ${podname}    ${commandget}
+    Log    ${result}
+    Should Be Empty    ${result}    Stale Resource Manager Data in Etcd!
+
+Clean Up All Nodes
+    [Documentation]    Login to each node and kill all stale lxc prcoesses
+    ${num_nodes}=    Get Length    ${nodes}
+    FOR    ${I}    IN RANGE    0    ${num_nodes}
+        ${node_ip}=    Evaluate    ${nodes}[${I}].get("ip")
+        ${node_user}=    Evaluate    ${nodes}[${I}].get("user")
+        ${node_pass}=    Evaluate    ${nodes}[${I}].get("pass")
+        Run Keyword And Continue On Failure    Start Remote Command    kill -9 `pidof lxc`
+        ...    ${node_ip}    ${node_user}    ${node_pass}
+    END
+
+Reboot XGSPON ONU
+    [Documentation]   Reboots the XGSPON ONU and verifies the ONU state after the reboot
+    [Arguments]    ${olt_sn}    ${onu_sn}    ${reason}
+    FOR    ${I}    IN RANGE    0    ${num_olts}
+        ${serial_number}    Evaluate    ${olts}[${I}].get("serial")
+        Continue For Loop If    "${serial_number}"!="${olt_sn}"
+        ${board_tech}    Evaluate    ${olts}[${I}].get("board_technology")
+        ${onu_device_id}=    Get Device ID From SN    ${onu_sn}
+        Run Keyword If    "${board_tech}"=="XGS-PON"    Run Keywords
+        ...    Reboot Device    ${onu_device_id}
+        ...    AND    Wait Until Keyword Succeeds    120s    5s
+        ...    Validate Device    ENABLED    ACTIVE
+        ...    REACHABLE    ${onu_sn}    onu=True    onu_reason=${reason}
+    END
+
+Set Non-Critical Tag for XGSPON Tech
+    [Documentation]    Dynamically sets the test tag for xgs-pon based to non-critical
+    FOR    ${I}    IN RANGE    0    ${num_olts}
+        ${board_tech}    Evaluate    ${olts}[${I}].get("board_technology")
+        Run Keyword If    "${board_tech}"=="XGS-PON"    Run Keywords
+        ...    Set Tags    non-critical
+        ...    AND    Exit For Loop
+    END
+
+Perform Reboot ONUs and OLTs Physically
+    [Documentation]    This keyword reboots ONUs and OLTs physically
+    ...    It runs only on the PODs that are configured with PowerSwitch that
+    ...    controls the power off/on ONUs/OLT remotely (simulating a physical reboot)
+    [Arguments]    ${power_cycle_olt}=False
+    Power Switch Connection Suite    ${web_power_switch.ip}    ${web_power_switch.user}    ${web_power_switch.password}
+    @{onu_list}=    Create List
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        # If the power switch port is not specified, continue
+        Continue For Loop If    '${src["power_switch_port"]}' == '${None}'
+        # Skip if we have already handled this ONU
+        ${sn}=     Set Variable    ${src['onu']}
+        ${onu_id}=    Get Index From List    ${onu_list}   ${sn}
+        Continue For Loop If    -1 != ${onu_id}
+        Append To List    ${onu_list}    ${sn}
+        Disable Switch Outlet    ${src['power_switch_port']}
+        Sleep    10s
+        Enable Switch Outlet    ${src['power_switch_port']}
+    END
+    Pass Execution If    '${power_cycle_olt}'=='False'    Skipping OLT(s) Power Switch Reboot
+    # Waiting extra time for the ONUs to come up
+    Sleep    30s
+    FOR   ${I}    IN RANGE    0    ${olt_count}
+        ${olt_serial_number}=    Get From Dictionary    ${list_olts}[${I}]    sn
+        ${power_switch_port}=    Get From Dictionary    ${list_olts}[${I}]    powerswitchport
+        ${olt_ssh_ip}=    Get From Dictionary    ${list_olts}[${I}]   sship
+        # If the power switch port is not specified, continue
+        Continue For Loop If    '${power_switch_port}' == '${None}'
+        Disable Switch Outlet    ${power_switch_port}
+        Sleep    10s
+        Enable Switch Outlet    ${power_switch_port}
+        Run Keyword If    ${has_dataplane}    Wait Until Keyword Succeeds    120s    10s
+        ...    Check Remote System Reachability    True    ${olt_ssh_ip}
+    END
+    # Waiting extra time for the ONUs to come up
+    Sleep    60s
+
+Count Number of UNI ports for OLT
+    [Documentation]  Count Provisioned UNI ports, for ONUs connected with specified OLT
+    [Arguments]    ${olt_serial_number}     ${type_of_service}
+    ${num_of_provisioned_onus_ports}=      Evaluate     0
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        Continue For Loop If    "${olt_serial_number}"!="${src['olt']}"
+        Continue For Loop If    "${type_of_service}"!="${src['service_type']}"
+        ${num_of_provisioned_onus_ports}=      Evaluate     ${num_of_provisioned_onus_ports} + 1
+    END
+    [Return]    ${num_of_provisioned_onus_ports}
diff --git a/libraries/vgc.robot b/libraries/vgc.robot
new file mode 100755
index 0000000..508f48f
--- /dev/null
+++ b/libraries/vgc.robot
@@ -0,0 +1,812 @@
+# Copyright 2017-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.
+# vgc common functions
+
+*** Settings ***
+Documentation     Library for various utilities
+Library           SSHLibrary
+Library           String
+Library           DateTime
+Library           Process
+Library           Collections
+Library           RequestsLibrary
+Library           OperatingSystem
+
+*** Variables ***
+@{connection_list}
+${alias}                  VGC_SSH
+${ssh_read_timeout}       60s
+${ssh_prompt}             karaf@root >
+${ssh_regexp_prompt}      REGEXP:k.*a.*r.*a.*f.*@.*r.*o.*o.*t.* .*>.*
+${regexp_prompt}          (?ms)(.*)k(.*)a(.*)r(.*)a(.*)f(.*)@(.*)r(.*)o(.*)o(.*)t(.*) (.*)>(.*)
+${ssh_width}              400
+${disable_highlighter}    setopt disable-highlighter
+# ${keep_alive_interval} is set to 0s means sending the keepalive packet is disabled!
+${keep_alive_interval}    0s
+${INFRA_DT_NAMESPACE}      infra
+
+
+*** Keywords ***
+Create VGC Session
+    [Documentation]    Creates a VGC session
+    Create Session    VGC    http://${VGC_REST_IP}:${VGC_REST_PORT}/vgc/v1
+
+Validate OLT Device in VGC
+    #    FIXME use volt-olts to check that the OLT is VGC
+    [Arguments]    ${serial_number}
+    [Documentation]    Checks if olt has been connected to VGC
+    Create VGC Session
+    ${resp}=    Get Request    VGC    devices
+    Log     ${resp}
+    ${jsondata}=    To Json   ${resp.content}
+    Should Not Be Empty    ${jsondata['devices']}
+    ${length}=    Get Length    ${jsondata['devices']}
+    @{serial_numbers}=    Create List
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${value}=    Get From List    ${jsondata['devices']}    ${INDEX}
+        ${of_id}=    Get From Dictionary    ${value}    id
+        ${sn}=    Get From Dictionary    ${value}    serial
+        ${matched}=    Set Variable If    '${sn}' == '${serial_number}'    True    False
+        Exit For Loop If    ${matched}
+    END
+    Should Be True    ${matched}    No match for ${serial_number} found
+    [Return]    ${of_id}
+
+
+
+Validate Deleted Device Cleanup In VGC
+    [Arguments]    ${ip}    ${port}    ${olt_serial_number}    ${olt_of_id}    ${maclearning_enabled}=False
+    [Documentation]    The keyword verifies that ports, flows, meters, subscribers, dhcp are all cleared in VGC
+    # Verify Ports are Removed
+    ${ports}=    Get Request    VGC    devices/ports
+    ${port_json_resp}=    To Json   ${ports.content}
+    Should Not Contain    ${port_json_resp}     ${olt_of_id}    Ports have not been removed from VGC after cleanup
+    # Verify Subscribers are Removed
+    ${sub}=    Get Request    VGC    programmed-subscribers
+    ${sub_json_resp}=    To Json   ${sub.content}
+    Should Not Contain    ${sub_json_resp}     ${olt_of_id}   Subscriber have not been removed from VGC after cleanup
+    # Verify Flows are Removed
+    ${flows}=    Get Request    VGC    flows
+    ${flow_json_resp}=    To Json   ${flows.content}
+    Should Not Contain    ${flow_json_resp}     ${olt_of_id}    Flows have not been removed from VGC after cleanup
+    # Verify Meters are Removed
+    ${meter}=    Get Request    VGC    meters
+    ${meter_json_resp}=    To Json   ${meter.content}
+    Should Not Contain    ${meter_json_resp}     ${olt_of_id}   Meter have not been removed from VGC after cleanup
+    # Verify AAA-Users are Removed
+    # ${aaa}=    Execute ONOS CLI Command use single connection     ${ip}    ${port}
+    #...    aaa-users ${olt_of_id}
+    # ${aaa_count}=      Get Line Count      ${aaa}
+    #Should Be Equal As Integers    ${aaa_count}    0    AAA Users have not been removed from ONOS after cleanup
+    # Verify Dhcp-Allocations are Removed
+    ${dhcp}=    Get Request    VGC    allocations/${olt_of_id}
+    ${dhcp_json_resp}=    To Json   ${dhcp.content}
+    ${dhcp_count} =    Get Length      ${dhcp_json_resp}
+    #Should Be Equal    ${dhcp_json_resp}     ${None}     DHCP Allocations have not been removed from VGC after cleanup
+    Should Be Equal As Integers    ${dhcp_count}    0   DHCP Allocations have not been removed from VGC after cleanup
+    # Verify MAC Learner Mappings are Removed
+    # ${mac}=    Run Keyword If    ${maclearning_enabled}    Execute ONOS CLI Command use single connection     ${ip}    ${port}
+    # ...    mac-learner-get-mapping | grep -v INFO
+    # ${mac_count}=    Run Keyword If    ${maclearning_enabled}    Get Line Count    ${mac}
+    # ...    ELSE    Set Variable    0
+    # Should Be Equal As Integers    ${mac_count}    0   Client MAC Learner Mappings have not been removed from ONOS after cleanup
+
+
+Get NNI Port in VGC
+    [Arguments]    ${olt_of_id}
+    [Documentation]    Retrieves NNI port for the OLT in VGC
+    ${resp}=    Get Request    VGC    devices/${olt_of_id}/ports
+    ${jsondata}=    To Json    ${resp.content}
+    Should Not Be Empty    ${jsondata['ports']}
+    ${length}=    Get Length    ${jsondata['ports']}
+    @{ports}=    Create List
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${value}=    Get From List    ${jsondata['ports']}    ${INDEX}
+        ${annotations}=    Get From Dictionary    ${value}    annotations
+        ${nni_port}=    Get From Dictionary    ${value}    port
+        ${nniPortName}=    Catenate    SEPARATOR=    nni-    ${nni_port}
+        ${portName}=    Get From Dictionary    ${annotations}    portName
+        ${matched}=    Set Variable If    '${portName}' == '${nniPortName}'    True    False
+        Exit For Loop If    ${matched}
+    END
+    Should Be True    ${matched}    No match for NNI found for ${olt_of_id}
+    [Return]    ${nni_port}
+
+
+
+Get ONU Port in VGC
+    [Arguments]    ${onu_serial_number}    ${olt_of_id}    ${onu_uni_id}=1
+    [Documentation]    Retrieves ONU port for the ONU in VGC
+    ${onu_serial_number}=    Catenate    SEPARATOR=-    ${onu_serial_number}    ${onu_uni_id}
+    ${resp}=    Get Request    VGC    devices/${olt_of_id}/ports
+    ${jsondata}=    To Json    ${resp.content}
+    Should Not Be Empty    ${jsondata['ports']}
+    ${length}=    Get Length    ${jsondata['ports']}
+    @{ports}=    Create List
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${value}=    Get From List    ${jsondata['ports']}    ${INDEX}
+        ${annotations}=    Get From Dictionary    ${value}    annotations
+        ${onu_port}=    Get From Dictionary    ${value}    port
+        ${portName}=    Get From Dictionary    ${annotations}    portName
+        ${matched}=    Set Variable If    '${portName}' == '${onu_serial_number}'    True    False
+        Exit For Loop If    ${matched}
+    END
+    Should Be True    ${matched}    No match for ${onu_serial_number} found
+    [Return]    ${onu_port}
+
+
+
+Verify UNI Port Is Enabled
+    [Arguments]      ${onu_name}    ${onu_uni_id}=1
+    [Documentation]    Verifies if the ONU's UNI port is enabled in VGC
+    ${onu_serial_number}=    Catenate    SEPARATOR=-    ${onu_name}    ${onu_uni_id}
+    ${resp}=    Get Request    VGC    devices/ports
+    ${jsondata}=    To Json    ${resp.content}
+    Should Not Be Empty    ${jsondata['ports']}
+    ${length}=    Get Length    ${jsondata['ports']}
+    @{ports}=    Create List
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${value}=    Get From List    ${jsondata['ports']}    ${INDEX}
+        ${annotations}=    Get From Dictionary    ${value}    annotations
+        ${onu_port}=    Get From Dictionary    ${value}    port
+        ${portName}=    Get From Dictionary    ${annotations}    portName
+        ${portstatus}=    Get From Dictionary    ${value}    isEnabled
+        ${matched}=    Set Variable If    '${portName}' == '${onu_serial_number}'    True    False
+        Exit For Loop If    ${matched}
+    END
+    Should Be True    ${matched}    No match for ${onu_serial_number} found
+    Should be Equal 	${portstatus}     ${True}
+
+
+Verify UNI Port Is Disabled
+    [Arguments]      ${ip}    ${port}    ${onu_name}    ${onu_uni_id}=1
+    [Documentation]    Verifies if the ONU's UNI port is enabled in VGC
+    ${onu_serial_number}=    Catenate    SEPARATOR=-    ${onu_name}    ${onu_uni_id}
+    ${resp}=    Get Request    VGC    devices/ports
+    ${jsondata}=    To Json    ${resp.content}
+    Should Not Be Empty    ${jsondata['ports']}
+    ${length}=    Get Length    ${jsondata['ports']}
+    @{ports}=    Create List
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${value}=    Get From List    ${jsondata['ports']}    ${INDEX}
+        ${annotations}=    Get From Dictionary    ${value}    annotations
+        ${onu_port}=    Get From Dictionary    ${value}    port
+        ${portName}=    Get From Dictionary    ${annotations}    portName
+        ${portstatus}=    Get From Dictionary    ${value}    isEnabled
+        ${matched}=    Set Variable If    '${portName}' == '${onu_serial_number}'    True    False
+        Exit For Loop If    ${matched}
+    END
+    Should Be True    ${matched}    No match for ${onu_serial_number} found
+    Should be Equal 	${portstatus}     ${False}
+
+Close All VGC SSH Connections
+    [Documentation]    Close all VGC Connection and clear connection list.
+    SSHLibrary.Close All Connections
+    @{connection_list}    Create List
+
+
+
+Verify Subscriber Access Flows Added For ONU DT in VGC
+    [Arguments]    ${ip}    ${port}    ${olt_of_id}    ${onu_port}    ${nni_port}    ${s_tag}
+    [Documentation]    Verifies if the Subscriber Access Flows are added in VGC for the ONU
+    # Get all flows from VGC
+    ${resp}=    Get Request    VGC   flows/${olt_of_id}
+    ${jsondata}=    To Json    ${resp.content}
+    Should Not Be Empty    ${jsondata['flows']}
+    # Verify upstream table=0 flow
+    ${length}=    Get Length    ${jsondata['flows']}
+    @{flows}=    Create List
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${flow}=    Get From List    ${jsondata['flows']}    ${INDEX}
+        ${tableid}=     Get Table Id From Flow    ${flow}
+        ${inport}=     Get In Port From Flow    ${flow}
+        ${vlanvid}=    Get Vlan VId From Flow    ${flow}
+        ${outport}=    Get Out Port From Flow    ${flow}
+        ${matched}=    Set Variable If
+        ...    '${tableid}' == '0' and '${inport}' == '${onu_port}' and '${vlanvid}' == '4096' and '${outport}' == '1'
+        ...    True    False
+        Exit For Loop If    ${matched}
+    END
+    Should Be True    ${matched}    No match for upstream table 0 flow found
+    # Verify upstream table=1 flow
+    ${matched1}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${flow}=    Get From List    ${jsondata['flows']}    ${INDEX}
+        ${inport}=     Get In Port From Flow    ${flow}
+        ${vlanvid}=    Get Vlan VId From Flow    ${flow}
+        ${outport}=    Get Out Port From Flow    ${flow}
+        ${subtype}=    Get Subtype From Flow   ${flow}
+        ${vlanid}=     Get Vlan Id From Flow   ${flow}
+        ${res1}=    Evaluate    '${inport}' == '${onu_port}'
+        ${res2}=    Evaluate    '${vlanvid}' == '4096' and '${outport}' == '${nni_port}'
+        ${res3}=    Evaluate    '${subtype}' == 'VLAN_PUSH' and '${vlanid}' == '${s_tag}'
+        ${matched1}=     Set Variable If  ${res1} and ${res2} and ${res3}   True    False
+        Exit For Loop If    ${matched1}
+    END
+    Should Be True    ${matched1}    No match for upstream table 1 flow found
+    # Verify downstream table=0 flow
+    ${matched2}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${flow}=    Get From List    ${jsondata['flows']}    ${INDEX}
+        ${inport}=     Get In Port From Flow    ${flow}
+        ${vlanvid}=    Get Vlan VId From Flow    ${flow}
+        ${outport}=    Get Out Port From Flow    ${flow}
+        ${subtype}=    Get Subtype From Flow   ${flow}
+        ${res1}=    Evaluate    '${inport}' == '${nni_port}'
+        ${res2}=    Evaluate    '${vlanvid}' == '${s_tag}' and '${outport}' == '1'
+        ${res3}=    Evaluate    '${subtype}' == 'VLAN_POP'
+        ${matched2}=     Set Variable If  ${res1} and ${res2} and ${res3}   True    False
+        Exit For Loop If    ${matched2}
+    END
+    Should Be True    ${matched2}    No match for downstream table 0 flow found
+    # Verify downstream table=1 flow
+    ${matched3}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${flow}=    Get From List    ${jsondata['flows']}    ${INDEX}
+        ${inport}=     Get In Port From Flow    ${flow}
+        ${vlanvid}=    Get Vlan VId From Flow    ${flow}
+        ${outport}=    Get Out Port From Flow    ${flow}
+        ${matched3}=    Set Variable If
+        ...  '${inport}' == '${nni_port}' and '${vlanvid}' == '4096' and '${outport}' == '${onu_port}'
+        ...  True    False
+        Exit For Loop If    ${matched3}
+    END
+    Should Be True    ${matched3}    "No match for downstream table 1 flow found"
+
+Verify Subscriber Access Flows Added for DT FTTB
+    [Arguments]    ${olt_of_id}    ${onu_port}    ${nni_port}    ${s_tag}    ${c_tag}
+    [Documentation]    Verifies if the Subscriber Access Flows are added in ONOS for the ONU
+    # Get all flows from VGC
+    ${resp}=    Get Request    VGC   flows/${olt_of_id}
+    ${jsondata}=    To Json    ${resp.content}
+    Should Not Be Empty    ${jsondata['flows']}
+    # Upstream
+    # ONU
+    ${length}=    Get Length    ${jsondata['flows']}
+    @{flows}=    Create List
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${flow}=    Get From List    ${jsondata['flows']}    ${INDEX}
+        ${tableid}=     Get Table Id From Flow    ${flow}
+        ${inport}=     Get In Port From Flow    ${flow}
+        ${vlanvid}=    Get Vlan VId From Flow    ${flow}
+        ${outport}=    Get Out Port From Flow    ${flow}
+        ${matched}=    Set Variable If
+        ...    '${inport}' == '${onu_port}' and '${vlanvid}' == '${c_tag}' and '${outport}' == '1'
+        ...    True    False
+        Exit For Loop If    ${matched}
+    END
+    Should Be True    ${matched}    No match for upstream ONU flow found
+    # OLT
+    ${matched1}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${flow}=    Get From List    ${jsondata['flows']}    ${INDEX}
+        ${inport}=     Get In Port From Flow    ${flow}
+        ${vlanvid}=    Get Vlan VId From Flow    ${flow}
+        ${outport}=    Get Out Port From Flow    ${flow}
+        ${vlanid}=     Get Vlan Id From Flow For Fttb   ${flow}
+        ${res1}=    Evaluate    '${inport}' == '${onu_port}'
+        ${res2}=    Evaluate    '${vlanvid}' == '${c_tag}' and '${vlanid}' == '${s_tag}'
+        ${res3}=    Evaluate    '${outport}' == '${nni_port}'
+        ${matched1}=     Set Variable If  ${res1} and ${res2} and ${res3}   True    False
+        Exit For Loop If    ${matched1}
+    END
+    Should Be True    ${matched1}    No match for upstream OLT found
+    # Downstream
+    # OLT
+    ${matched2}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${flow}=    Get From List    ${jsondata['flows']}    ${INDEX}
+        ${inport}=     Get In Port From Flow    ${flow}
+        ${vlanvid}=    Get Vlan VId From Flow    ${flow}
+        ${outport}=    Get Out Port From Flow    ${flow}
+        ${vlanid}=     Get Vlan Id From Flow For Fttb   ${flow}
+        ${res1}=    Evaluate    '${inport}' == '${nni_port}'
+        ${res2}=    Evaluate    '${vlanvid}' == '${s_tag}' and '${vlanid}' == '${c_tag}'
+        ${res3}=    Evaluate    '${outport}' == '1'
+        ${matched2}=     Set Variable If  ${res1} and ${res2} and ${res3}   True    False
+        Exit For Loop If    ${matched2}
+    END
+    Should Be True    ${matched2}    No match for downstream OLT found
+    # ONU
+    ${matched3}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${flow}=    Get From List    ${jsondata['flows']}    ${INDEX}
+        ${inport}=     Get In Port From Flow    ${flow}
+        ${vlanvid}=    Get Vlan VId From Flow    ${flow}
+        ${tableid}=     Get Table Id From Flow    ${flow}
+        ${outport}=    Get Out Port From Flow    ${flow}
+        ${vlanid}=     Get Vlan Id From Flow For Fttb   ${flow}
+        ${res1}=    Evaluate    '${inport}' == '${nni_port}'
+        ${res2}=    Evaluate    '${vlanvid}' == '${c_tag}' and '${outport}' == '${onu_port}'
+        ${matched3}=     Set Variable If  ${res1} and ${res2}   True    False
+        Exit For Loop If    ${matched3}
+    END
+    Should Be True    ${matched3}    No match for downstream ONU found
+
+Verify DPU MGMT Flows Added for DT FTTB
+    [Arguments]    ${olt_of_id}    ${onu_port}    ${nni_port}    ${s_tag}    ${c_tag}
+    [Documentation]    Verifies if the DPU MGMT Flows are added in VGC for the ONU
+    # Get all flows from VGC
+    ${resp}=    Get Request    VGC   flows/${olt_of_id}
+    ${jsondata}=    To Json    ${resp.content}
+    Should Not Be Empty    ${jsondata['flows']}
+    # Upstream
+    # ONU
+    ${length}=    Get Length    ${jsondata['flows']}
+    @{flows}=    Create List
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${flow}=    Get From List    ${jsondata['flows']}    ${INDEX}
+        ${tableid}=     Get Table Id From Flow    ${flow}
+        ${inport}=     Get In Port From Flow    ${flow}
+        ${vlanvid}=    Get Vlan VId From Flow    ${flow}
+        ${vlanid}=     Get Vlan Id From Flow For Fttb   ${flow}
+        ${outport}=    Get Out Port From Flow    ${flow}
+        ${res1}=    Evaluate    '${inport}' == '${onu_port}'
+        ${res2}=    Evaluate    '${vlanvid}' == '${c_tag}' and '${vlanid}' == '${s_tag}'
+        ${res3}=    Evaluate    '${outport}' == '1'
+        ${matched}=     Set Variable If  ${res1} and ${res2} and ${res3}   True    False
+        Exit For Loop If    ${matched}
+    END
+    Should Be True    ${matched}    No match for upstream ONU flow found
+    # OLT
+    ${matched1}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${flow}=    Get From List    ${jsondata['flows']}    ${INDEX}
+        ${inport}=     Get In Port From Flow    ${flow}
+        ${vlanvid}=    Get Vlan VId From Flow    ${flow}
+        ${outport}=    Get Out Port From Flow    ${flow}
+        ${vlanid}=     Get Vlan Id From Flow For Fttb   ${flow}
+        ${matched1}=    Set Variable If
+        ...    '${inport}' == '${onu_port}' and '${vlanvid}' == '${s_tag}' and '${outport}' == '${nni_port}'
+        ...    True    False
+        ${matched1}=     Set Variable If  ${res1} and ${res2} and ${res3}   True    False
+        Log To Console  "bbb",'${inport}' == '${onu_port}' '${vlanvid}' == '${s_tag}' '${outport}' == '${nni_port}'
+        Exit For Loop If    ${matched1}
+    END
+    Should Be True    ${matched1}    No match for upstream OLT found
+    # Downstream
+    # OLT
+    ${matched2}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${flow}=    Get From List    ${jsondata['flows']}    ${INDEX}
+        ${inport}=     Get In Port From Flow    ${flow}
+        ${vlanvid}=    Get Vlan VId From Flow    ${flow}
+        ${outport}=    Get Out Port From Flow    ${flow}
+        ${vlanid}=     Get Vlan Id From Flow For Fttb   ${flow}
+        ${matched3}=    Set Variable If
+        ...    '${inport}' == '${nni_port}' and '${vlanvid}' == '${s_tag}' and '${outport}' == '1'
+        ...    True    False
+        Exit For Loop If    ${matched3}
+    END
+    Should Be True    ${matched3}    No match for downstream OLT found
+    # ONU
+    ${matched4}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${flow}=    Get From List    ${jsondata['flows']}    ${INDEX}
+        ${inport}=     Get In Port From Flow    ${flow}
+        ${vlanvid}=    Get Vlan VId From Flow    ${flow}
+        ${tableid}=     Get Table Id From Flow    ${flow}
+        ${outport}=    Get Out Port From Flow    ${flow}
+        ${vlanid}=     Get Vlan Id From Flow For Fttb   ${flow}
+        ${res1}=    Evaluate    '${inport}' == '${nni_port}'
+        ${res2}=    Evaluate    '${vlanvid}' == '${s_tag}' and '${vlanid}' == '${c_tag}'
+        ${res3}=    Evaluate    '${outport}' == '${onu_port}'
+        ${matched4}=     Set Variable If  ${res1} and ${res2} and ${res3}   True    False
+        Exit For Loop If    ${matched4}
+    END
+    Should Be True    ${matched4}    No match for downstream ONU found
+
+Verify VGC Flows Added for DT FTTB
+    [Arguments]    ${olt_of_id}    ${onu_port}    ${nni_port}    ${service}
+    [Documentation]    Verifies if the Flows are added in ONOS for the ONU
+    ${num_services}=    Get Length    ${service}
+    FOR     ${I}    IN RANGE    0    ${num_services}
+        ${service_name}=    Set Variable    ${service[${I}]['name']}
+        ${stag}=    Set Variable    ${service[${I}]['s_tag']}
+        ${ctag}=    Set Variable    ${service[${I}]['c_tag']}
+        Run Keyword If    '${service_name}' == 'FTTB_SUBSCRIBER_TRAFFIC'
+        ...    Verify Subscriber Access Flows Added for DT FTTB    ${olt_of_id}
+        ...    ${onu_port}    ${nni_port}    ${stag}    ${ctag}
+        ...    Verify DPU MGMT Flows Added for DT FTTB    ${olt_of_id}
+        ...    ${onu_port}    ${nni_port}    ${stag}    ${ctag}
+    END
+
+
+Add Subscriber Details
+    [Documentation]    Adds a particular subscriber
+    [Arguments]    ${of_id}    ${onu_port}
+    ${resp}=    Post Request    VGC    services/${of_id}/${onu_port}
+    Log   ${resp}
+    Should Be Equal As Strings    ${resp.status_code}    200
+
+Remove Subscriber Access
+    [Documentation]    Removes a particular subscriber
+    [Arguments]    ${of_id}    ${onu_port}
+    ${resp}=    Delete Request    VGC    services/${of_id}/${onu_port}
+    Log   ${resp}
+    Should Be Equal As Strings    ${resp.status_code}    200
+
+Send File To VGC
+    [Documentation]    Send the content of the file to VGC to selected section of configuration
+    ...   using Post Request
+    [Arguments]    ${CONFIG_FILE}    #${section}=${EMPTY}
+    ${Headers}=    Create Dictionary    Content-Type    application/json
+    ${File_Data}=    OperatingSystem.Get File    ${CONFIG_FILE}
+    Log    ${Headers}
+    Log    ${File_Data}
+    ${resp}=    Post Request    VGC
+    ...    network/configurations    headers=${Headers}    data=${File_Data}
+    Should Be Equal As Strings    ${resp.status_code}    200
+
+Verify No Pending Flows For ONU
+    [Arguments]    ${ip}    ${port}    ${onu_port}
+    [Documentation]    Verifies that there are no flows "PENDING" state for the ONU in VGC
+    ${resp}=    Get Request    VGC   flows/pending
+    ${jsondata}=    To Json    ${resp.content}
+    ${length}=    Get Length    ${jsondata['flows']}
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${flow}=    Get From List    ${jsondata['flows']}    ${INDEX}
+        ${inport}=     Get In Port From Flow    ${flow}
+        ${matched}=     Run Keyword If   '${inport}' == '${onu_port}'   Set Variable    ${TRUE}
+        Exit For Loop If    ${matched}
+    END
+    Should Be Equal   ${matched}     False    No match for  pending flow  found
+
+Get Pending Flow Count
+    [Documentation]    Get the count for flows "PENDING" state for the ONU in VGC
+    ${resp}=    Get Request    VGC   flows/pending
+    ${jsondata}=    To Json    ${resp.content}
+    ${length}=    Get Length    ${jsondata['flows']}
+    [Return]    ${length}
+
+Get In Port From Flow
+    [Documentation]    Fetches the port Record for IN_PORT
+    [Arguments]    ${flow}
+    ${selector}=    Get From Dictionary    ${flow}    selector
+    ${len}=    Get Length    ${selector['criteria']}
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${len}
+           ${criteria}=    Get From List    ${selector['criteria']}    ${INDEX}
+           ${type}=       Get From Dictionary    ${criteria}    type
+           ${port}=     Run Keyword If    '${type}' == 'IN_PORT'       Get From Dictionary    ${criteria}    port
+           ${matched}=    Set Variable If    '${type}' == 'IN_PORT'    True    False
+           Exit For Loop If    ${matched}
+    END
+    [Return]    ${port}
+
+
+
+Get Vlan VId From Flow
+    [Documentation]    Fetches the vlan Id
+    [Arguments]    ${flow}
+    ${selector}=    Get From Dictionary    ${flow}    selector
+    ${len}=    Get Length    ${selector['criteria']}
+    ${matched}=    Set Variable    False
+    ${vlanid}=     Set Variable
+    FOR    ${INDEX}    IN RANGE    0    ${len}
+           ${criteria}=    Get From List    ${selector['criteria']}    ${INDEX}
+           ${type}=       Get From Dictionary    ${criteria}    type
+           ${vlanid}=     Run Keyword If    '${type}' == 'VLAN_VID'       Get From Dictionary    ${criteria}    vlanId
+           ${matched}=    Set Variable If    '${type}' == 'VLAN_VID'    True    False
+           Exit For Loop If    ${matched}
+    END
+    [Return]    ${vlanid}
+
+
+Get Out Port From Flow
+    [Documentation]    Fetches the port for OUTPUT
+    [Arguments]    ${flow}
+    ${treatment}=    Get From Dictionary    ${flow}    treatment
+    ${len}=    Get Length    ${treatment['instructions']}
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${len}
+           ${instructions}=    Get From List    ${treatment['instructions']}    ${INDEX}
+           ${type}=       Get From Dictionary    ${instructions}    type
+           ${outport}=    Run Keyword If    '${type}' == 'OUTPUT'      Get From Dictionary    ${instructions}    port
+           ${matched}=    Set Variable If    '${type}' == 'OUTPUT'    True    False
+           Exit For Loop If    ${matched}
+    END
+    [Return]    ${outport}
+
+
+Get Subtype From Flow
+    [Documentation]    Fetches the L2MODIFICATION subtype
+    [Arguments]    ${flow}
+    ${treatment}=    Get From Dictionary    ${flow}    treatment
+    ${len}=    Get Length    ${treatment['instructions']}
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${len}
+           ${instructions}=    Get From List    ${treatment['instructions']}    ${INDEX}
+           ${type}=       Get From Dictionary    ${instructions}    type
+           ${subtype}=    Run Keyword If    '${type}' == 'L2MODIFICATION'      Get From Dictionary    ${instructions}    subtype
+           ${matched}=    Set Variable If    '${type}' == 'L2MODIFICATION'   True    False
+           Exit For Loop If    ${matched}
+    END
+    [Return]    ${subtype}
+
+Get Vlan Id From Flow For Fttb
+    [Documentation]    Fetch the VLAN id for L2MODIFICATION
+    [Arguments]    ${flow}
+    ${treatment}=    Get From Dictionary    ${flow}    treatment
+    ${len}=    Get Length    ${treatment['instructions']}
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${len}
+           ${instructions}=    Get From List    ${treatment['instructions']}    ${INDEX}
+           ${type}=       Get From Dictionary    ${instructions}    type
+           ${subtype}=    Run Keyword If    '${type}' == 'L2MODIFICATION'      Get From Dictionary    ${instructions}    subtype
+           ${vlanId}=    Run Keyword If    '${type}' == 'L2MODIFICATION' and '${subtype}' == 'VLAN_SET'
+           ...    Get From Dictionary    ${instructions}    vlanId
+           ${matched}=    Set Variable If    '${type}' == 'L2MODIFICATION' and '${subtype}' == 'VLAN_SET'   True    False
+           Exit For Loop If    ${matched}
+    END
+    [Return]      ${vlanId}
+
+Get Table Id From Flow
+    [Documentation]    Fetch the TableId
+    [Arguments]    ${flow}
+    ${tableid}=    Get From Dictionary    ${flow}    tableId
+    [Return]    ${tableid}
+
+Get Vlan Id From Flow
+    [Documentation]    Fetch the VLAN id for L2MODIFICATION
+    [Arguments]    ${flow}
+    ${treatment}=    Get From Dictionary    ${flow}    treatment
+    ${len}=    Get Length    ${treatment['instructions']}
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${len}
+           ${instructions}=    Get From List    ${treatment['instructions']}    ${INDEX}
+           ${type}=       Get From Dictionary    ${instructions}    type
+           ${subtype}=    Run Keyword If    '${type}' == 'L2MODIFICATION'      Get From Dictionary    ${instructions}    subtype
+           ${vlanId}=    Run Keyword If    '${type}' == 'L2MODIFICATION' and '${subtype}' == 'VLAN_ID'
+           ...    Get From Dictionary    ${instructions}    vlanId
+           ${matched}=    Set Variable If    '${type}' == 'L2MODIFICATION' and '${subtype}' == 'VLAN_ID'   True    False
+           Exit For Loop If    ${matched}
+    END
+    [Return]      ${vlanId}
+
+Get Subscribers for a Particular Service
+    [Documentation]    Filters the subscriber for a particular service
+    [Arguments]    ${olt_of_id}    ${subscriber_json}    ${filter}
+    ${subscribers_info}=    Get From Dictionary    ${subscriber_json}    subscribers
+    ${num_subscribers}=    Get Length    ${subscribers_info}
+    ${subscriber_list}    Create List
+    Return From Keyword If  '${filter}' == '${EMPTY}'   ${subscribers_info}
+    FOR    ${INDEX}    IN RANGE    0    ${num_subscribers}
+        ${subscriber}=    Get From List    ${subscribers_info}    ${INDEX}
+        ${res1}=    Evaluate    '${olt_of_id}' == '${subscriber["location"]}'
+        ${tag_subscriber_info}=    Get From Dictionary    ${subscriber}    tagInfo
+        ${ServiceName}=    Get From Dictionary    ${tag_subscriber_info}    serviceName
+        ${res2}=    Evaluate    '${filter}' == '${ServiceName}'
+        Run Keyword If    ${res1} and ${res2}
+        ...    Append To List    ${subscriber_list}    ${subscriber}
+        ${matched}=     Set Variable If  ${res1} and ${res2}   True    False
+        Exit For Loop If    ${matched}
+    END
+    Should Be True    ${matched}    No matching subscriber for OLT
+    [Return]    ${subscriber_list}
+
+Get Programmed Subscribers
+    [Arguments]    ${olt_of_id}    ${onu_port}    ${filter}=${EMPTY}
+    [Documentation]    Retrieves the subscriber details at a given location
+    ${programmed_sub}=      Get Request    VGC    programmed-subscribers
+    ${programmed_sub_json_resp}=    To Json   ${programmed_sub.content}
+    ${filtered_subscriber_list}=    Get Subscribers for a Particular Service    ${olt_of_id}    ${programmed_sub_json_resp}
+    ...    ${filter}
+    [Return]    ${filtered_subscriber_list}
+
+Verify Programmed Subscribers DT FTTB
+    [Arguments]    ${olt_of_id}    ${onu_port}    ${service}
+    [Documentation]    Verifies the subscriber is present at a given location
+    ${num_services}=    Get Length    ${service}
+    FOR    ${I}    IN RANGE    0    ${num_services}
+        ${service_name}=    Set Variable    ${service[${I}]['name']}
+        ${programmed_subscriber}=    Get Programmed Subscribers    ${olt_of_id}    ${onu_port}
+        ...    ${service_name}
+        Log    ${programmed_subscriber}
+        Should Not Be Empty    ${programmed_subscriber}
+    END
+
+Verify Meters in VGC Ietf
+    [Arguments]    ${ip}    ${port}    ${olt_of_id}    ${onu_port}    ${filter}=${EMPTY}
+    [Documentation]    Verifies the meters with BW Ietf format (currently, DT workflow uses this format)
+    ${programmed_sub_json_resp}=    Get Programmed Subscribers    ${olt_of_id}    ${onu_port}
+    ...    ${filter}
+    Log    ${programmed_sub_json_resp}
+    ${us_bw_profile}    ${ds_bw_profile}    Get Upstream and Downstream Bandwidth Profile Name
+    ...    ${programmed_sub_json_resp}
+    # Get upstream bandwidth profile details
+    ${us_cir}    ${us_cbs}    ${us_pir}    ${us_pbs}    ${us_gir}    Get Bandwidth Profile Details Ietf Rest
+    ...    ${us_bw_profile}
+    # Verify meter for upstream bandwidth profile
+    ${meter}=      Get Request    VGC    meters
+    ${meter_json_resp}=    To Json   ${meter.content}
+    Log    ${meter_json_resp}
+    ${rate}    ${burst_size}   Get Meter Param In Details
+    ...    ${meter_json_resp}  1
+    Log    ${rate}
+    Log    ${burst_size}
+    # for cir & cbs
+    ${matched}=    Set Variable If    '${rate}' == '${us_cir}' and '${burst_size}' == '${us_cbs}'   True    False
+    Should Be True    ${matched}
+    ${res1}=    Evaluate    '${rate}' == '${us_cir}' and '${burst_size}' == '${us_cbs}'
+    #for pir & pbs
+    ${rate}    ${burst_size}   Get Meter Param In Details
+    ...    ${meter_json_resp}  2
+    ${matched}=    Set Variable If    '${rate}' == '${us_pir}' and '${burst_size}' == '${us_pbs}'   True    False
+    Should Be True    ${matched}
+    ${res2}=    Evaluate    '${rate}' == '${us_pir}' and '${burst_size}' == '${us_pbs}'
+    #for gir
+    Run Keyword if  ${us_gir} != 0    Validate Guarenteed Information Rate    ${us_gir}  ${meter_json_resp}
+    # Get downstream bandwidth profile details
+    ${ds_cir}    ${ds_cbs}    ${ds_pir}    ${ds_pbs}    ${ds_gir}    Get Bandwidth Profile Details Ietf Rest
+    ...    ${ds_bw_profile}
+    # Verify meter for downstream bandwidth profile
+    ${meter}=      Get Request    VGC    meters
+    ${meter_json_resp}=    To Json   ${meter.content}
+    Log    ${meter_json_resp}
+    ${rate}    ${burst_size}   Get Meter Param In Details
+    ...    ${meter_json_resp}  1
+    Log    ${rate}
+    Log    ${burst_size}
+    # for cir & cbs
+    ${matched}=    Set Variable If    '${rate}' == '${ds_cir}' and '${burst_size}' == '${ds_cbs}'    True    False
+    Should Be True    ${matched}
+    #for pir & pbs
+    ${rate}    ${burst_size}   Get Meter Param In Details
+    ...    ${meter_json_resp}  2
+    ${matched}=    Set Variable If    '${rate}' == '${ds_pir}' and '${burst_size}' == '${ds_pbs}'  True    False
+    Should Be True    ${matched}
+    #for gir
+    Run Keyword If    ${ds_gir} != 0
+    ...    Validate Guarenteed Information Rate    ${ds_gir}  ${meter_json_resp}
+
+Validate Guarenteed Information Rate
+    [Documentation]    Validate gir for both upstream and downstream meters
+    [Arguments]    ${gir}    ${meter_json_resp}
+    ${rate}    ${burst_size}   Get Meter Param In Details
+    ...    ${meter_json_resp}  3
+    ${matched}=    Set Variable If    '${rate}' == '${gir}' and '${burst_size}' == '0'  True    False
+    Should Be True    ${matched}
+    [Return]    ${matched}
+
+Get Bandwidth Profile Details Ietf Rest
+    [Arguments]    ${bw_profile_id}
+    [Documentation]    Retrieves the details of the given Ietf standard based bandwidth profile using REST API
+    ${bw_profile_id}=    Remove String    ${bw_profile_id}    '    "
+    ${resp}=    Get Request    VGC    profiles/${bw_profile_id}
+    Log     ${resp}
+    ${jsondata}=    To Json    ${resp.content}
+    Should Not Be Empty    ${jsondata}
+    ${matched}=    Set Variable    False
+    ${bw_id}=    Get From Dictionary    ${jsondata}    id
+    ${matched}=    Set Variable If    '${bw_id}' == '${bw_profile_id}'    True    False
+    ${pir}=    Get From Dictionary    ${jsondata}    pir
+    ${pbs}=    Get From Dictionary    ${jsondata}    pbs
+    ${cir}=    Get From Dictionary    ${jsondata}    cir
+    ${cbs}=    Get From Dictionary    ${jsondata}    cbs
+    ${gir}=    Get From Dictionary    ${jsondata}    gir
+    Should Be True    ${matched}    No bandwidth profile found for id: ${bw_profile_id}
+    [Return]    ${cir}    ${cbs}    ${pir}    ${pbs}    ${gir}
+
+
+Get Upstream and Downstream Bandwidth Profile Name
+    [Arguments]    ${programmed_sub}
+    [Documentation]    Retrieves the upstream and downstream bandwidth profile name
+    ...    from the programmed subscriber
+    ${length}=    Get Length    ${programmed_sub}
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${value}=    Get From List    ${programmed_sub}    ${INDEX}
+        ${tagInfo_id}=    Get From Dictionary    ${value}    tagInfo
+        Log    ${tagInfo_id}
+        ${us_bw_profile}=    Get From Dictionary    ${tagInfo_id}    upstreamBandwidthProfile
+        Log    ${us_bw_profile}
+        ${ds_bw_profile}=    Get From Dictionary    ${tagInfo_id}    downstreamBandwidthProfile
+        Log    ${ds_bw_profile}
+    END
+    [Return]    ${us_bw_profile}    ${ds_bw_profile}
+
+Verify Subscriber Access Flows Added Count DT
+    [Arguments]    ${ip}    ${port}    ${olt_of_id}    ${expected_flows}
+    [Documentation]    Matches for total number of subscriber access flows added for all onus
+    ${resp}=    Get Request    VGC   flows/${olt_of_id}
+    ${jsondata}=    To Json    ${resp.content}
+    ${access_flows_added_count}=      Get Length      ${jsondata['flows']}
+    Should Be Equal As Integers    ${access_flows_added_count}    ${expected_flows}
+
+Get Meter Param In Details
+    [Arguments]    ${meter_json}    ${length}
+    [Documentation]    Retrieves the meter rate state burst-size
+    ${metername}=    Get From Dictionary    ${meter_json}    meters
+    Log    ${metername}
+    ${value}=    Get From List    ${metername}  0
+    ${bands_info}=    Get From Dictionary    ${value}    bands
+    Log    ${bands_info}
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+         ${value}=    Get From List    ${bands_info}    ${INDEX}
+         ${burst_size}=    Get From Dictionary    ${value}    burstSize
+         ${rate}=        Get From Dictionary    ${value}    rate
+    END
+    [Return]    ${rate}    ${burst_size}
+
+Delete Subscribers And BW Profile In VGC
+    [Documentation]    Delete Subscribers and bw profile  In VGC
+    Create VGC Session
+    ${resp}=    Get Request    VGC    programmed-subscribers
+    Log     ${resp}
+    ${jsondata}=    To Json   ${resp.content}
+    ${length}=    Get Length    ${jsondata['subscribers']}
+    @{serial_numbers}=    Create List
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${value}=    Get From List    ${jsondata['subscribers']}    ${INDEX}
+        ${taginfo}=    Get From Dictionary    ${value}    tagInfo
+        ${service_id}=    Get From Dictionary    ${taginfo}    serviceName
+        ${upstream_bw_id}=    Get From Dictionary    ${taginfo}    upstreamBandwidthProfile
+        ${downstream_bw_id}=    Get From Dictionary   ${taginfo}    downstreamBandwidthProfile
+        Delete Request    VGC    subscribers/${service_id}
+        Delete Request    VGC    profiles/${upstream_bw_id}
+        Delete Request    VGC    profiles/${downstream_bw_id}
+    END
+
+Deactivate Subscribers In VGC
+    [Documentation]    Deactivate Subscribers In VGC
+    Create VGC Session
+    ${resp}=    Get Request    VGC    devices/ports
+    Log     ${resp}
+    ${jsondata}=    To Json   ${resp.content}
+    ${length}=    Get Length    ${jsondata['ports']}
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${value}=    Get From List    ${jsondata['ports']}    ${INDEX}
+        ${annotations}=    Get From Dictionary    ${value}    annotations
+        ${portname}=    Get From Dictionary    ${annotations}    portName
+        Delete Request    VGC    services/${portname}
+    END
+
+Verify Device Flows Removed
+    [Arguments]    ${ip}    ${port}    ${olt_of_id}
+    [Documentation]    Verifies all flows are removed from the device
+    ${resp}=    Get Request    VGC   flows/${olt_of_id}
+    ${jsondata}=    To Json    ${resp.content}
+    ${flow_count}=      Get Length      ${jsondata['flows']}
+    Should Be Equal As Integers    ${flow_count}    0     Flows not removed
+
+Device Is Available In VGC
+    [Arguments]      ${olt_of_id}    ${available}=true
+    [Documentation]    Validates the device exists and it has the expected availability in VGC
+    ${resp}=    Get Request    VGC    devices
+    ${jsondata}=    To Json   ${resp.content}
+    Should Not Be Empty    ${jsondata['devices']}
+    ${length}=    Get Length    ${jsondata['devices']}
+    ${matched}=    Set Variable    False
+    FOR    ${INDEX}    IN RANGE    0    ${length}
+        ${value}=    Get From List    ${jsondata['devices']}    ${INDEX}
+        ${of_id}=    Get From Dictionary    ${value}    id
+        ${availability}=    Get From Dictionary    ${value}    available
+        Log    ${olt_of_id}
+        Log    ${of_id}
+        ${matched}=    Set Variable If    '${of_id}' == '${olt_of_id}' and '${available}' == '${availability}'    True    False
+        Exit For Loop If    ${matched}
+    END
+    Should Be True    ${matched}    No match for '${olt_of_id}' found
+    Should Be Equal    ${available}    ${availability}
+
diff --git a/libraries/voltctl.robot b/libraries/voltctl.robot
index 650c289..c212ada 100755
--- a/libraries/voltctl.robot
+++ b/libraries/voltctl.robot
@@ -22,7 +22,7 @@
 Library           Collections
 Library           RequestsLibrary
 Library           OperatingSystem
-Resource          ./utils.robot
+#Resource          ./utils.robot
 Resource          ./flows.robot
 
 *** Variables ***
diff --git a/tests/data/bbsim-kind-2OLTx2ONUx2PON_VGC.yaml b/tests/data/bbsim-kind-2OLTx2ONUx2PON_VGC.yaml
new file mode 100755
index 0000000..cf9841c
--- /dev/null
+++ b/tests/data/bbsim-kind-2OLTx2ONUx2PON_VGC.yaml
@@ -0,0 +1,102 @@
+---
+
+# Copyright 2017-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.
+
+# Automated deployment configuration for systems running BBSim
+
+# Change default values in tests
+has_dataplane: false
+external_libs: false
+teardown_device: true
+VGC_REST_PORT: 8181
+VGC_SSH_PORT: 8101
+OLT_PORT: 50060
+
+
+# Actual Unused sadis.file but ready to future implementation
+sadis.file: ../data/dt-sadis-multiolt-config-vgc.json
+
+
+nodes:
+  -
+    ip: '127.0.0.1'
+
+olts:
+  -
+    ip: bbsim0.voltha.svc
+    serial: BBSIM_OLT_10
+  -
+    ip: bbsim1.voltha.svc
+    serial: BBSIM_OLT_11
+
+hosts:
+  src:
+    -
+      onu: 'BBSM000a0001'
+      c_tag: '4096'
+      s_tag: '900'
+      olt: 'BBSIM_OLT_10'
+      uni_id: '1'
+    -
+      onu: 'BBSM000a0002'
+      c_tag: '4096'
+      s_tag: '904'
+      olt: 'BBSIM_OLT_10'
+      uni_id: '1'
+    -
+      onu: 'BBSM000a0101'
+      olt: 'BBSIM_OLT_10'
+      c_tag: '4096'
+      s_tag: '908'
+      uni_id: '1'
+    -
+      onu: 'BBSM000a0102'
+      olt: 'BBSIM_OLT_10'
+      c_tag: '4096'
+      s_tag: '912'
+      uni_id: '1'
+    -
+      onu: 'BBSM000b0001'
+      c_tag: '4096'
+      s_tag: '900'
+      olt: 'BBSIM_OLT_11'
+      uni_id: '1'
+    -
+      onu: 'BBSM000b0002'
+      c_tag: '4096'
+      s_tag: '904'
+      olt: 'BBSIM_OLT_11'
+      uni_id: '1'
+    -
+      onu: 'BBSM000b0101'
+      olt: 'BBSIM_OLT_11'
+      c_tag: '4096'
+      s_tag: '908'
+      uni_id: '1'
+    -
+      onu: 'BBSM000b0102'
+      olt: 'BBSIM_OLT_11'
+      c_tag: '4096'
+      s_tag: '912'
+      uni_id: '1'
+  dst:
+    - ip: null
+    - ip: null
+    - ip: null
+    - ip: null
+    - ip: null
+    - ip: null
+    - ip: null
+    - ip: null
diff --git a/tests/data/bbsim-kind-dt-vgc.yaml b/tests/data/bbsim-kind-dt-vgc.yaml
new file mode 100755
index 0000000..73824ca
--- /dev/null
+++ b/tests/data/bbsim-kind-dt-vgc.yaml
@@ -0,0 +1,51 @@
+---
+
+# Copyright 2017-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.
+
+# Automated deployment configuration for systems running BBSim
+
+# Change default values in tests
+workflow: DT
+has_dataplane: false
+teardown_device: true
+VGC_REST_PORT: 8181
+VGC_SSH_PORT: 8101
+OLT_PORT: 50060
+
+
+# Actual Unused sadis.file but ready to future implementation
+sadis.file: ../data/dt-sadis-config.json
+
+
+nodes:
+  -
+    ip: '127.0.0.1'
+
+olts:
+  -
+    ip: bbsim0
+    serial: BBSIM_OLT_10
+
+hosts:
+  src:
+    -
+      onu: 'BBSM000a0001'
+      olt: 'BBSIM_OLT_10'
+      c_tag: '4096'
+      s_tag: '900'
+      uni_id: '1'
+
+  dst:
+    - ip: null
diff --git a/tests/data/dt-sadis-config.json b/tests/data/dt-sadis-config.json
new file mode 100644
index 0000000..6284e18
--- /dev/null
+++ b/tests/data/dt-sadis-config.json
@@ -0,0 +1,49 @@
+{
+  "apps": {
+    "org.opencord.sadis": {
+      "bandwidthprofile": {
+        "entries": [
+          {
+            "id": "High-Speed-Internet",
+            "gir": 50000,
+            "cbs": 10000,
+            "cir": 50000,
+            "pbs": 1000,
+            "pir": 300000
+          }
+        ]
+      },
+      "sadis": {
+        "entries": [
+          {
+            "id": "BBSIM_OLT_10",
+            "nasId": "BBSIM_OLT_10",
+            "hardwareIdentifier": "28:b9:d9:e2:93:d6",
+            "uplinkPort": "16777216"
+          },
+          {
+            "id": "BBSM000a0001",
+            "nasPortId": "BBSM000a0001-1",
+            "circuitId": "BBSM000a0001-1",
+            "remoteId": "BBSM000a0001",
+            "uniTagList": [
+              {
+                "uniTagMatch": 4096,
+                "ponCTag": 4096,
+                "ponSTag": 900,
+                "usPonCTagPriority": 0,
+                "usPonSTagPriority": 0,
+                "dsPonCTagPriority": 0,
+                "dsPonSTagPriority": 0,
+                "technologyProfileId": 64,
+                "downstreamBandwidthProfile": "High-Speed-Internet",
+                "upstreamBandwidthProfile": "High-Speed-Internet",
+                "serviceName": "HSIA"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  }
+}
diff --git a/tests/data/dt-sadis-multiolt-config-vgc.json b/tests/data/dt-sadis-multiolt-config-vgc.json
new file mode 100644
index 0000000..e2460f1
--- /dev/null
+++ b/tests/data/dt-sadis-multiolt-config-vgc.json
@@ -0,0 +1,203 @@
+{
+  "apps": {
+    "org.opencord.sadis": {
+      "bandwidthprofile": {
+        "entries": [
+          {
+            "id": "High-Speed-Internet",
+            "gir": 50000,
+            "cbs": 10000,
+            "cir": 50000,
+            "pbs": 1000,
+            "pir": 300000
+          }
+        ]
+      },
+      "sadis": {
+        "entries": [
+          {
+            "id": "BBSIM_OLT_10",
+            "nasId": "BBSIM_OLT_10",
+            "hardwareIdentifier": "28:b9:d9:e2:93:d6",
+            "uplinkPort": "16777216"
+          },
+          {
+            "id": "BBSM000a0001",
+            "nasPortId": "BBSM000a0001-1",
+            "circuitId": "BBSM000a0001-1",
+            "remoteId": "BBSM000a0001",
+            "uniTagList": [
+              {
+                "uniTagMatch": 4096,
+                "ponCTag": 4096,
+                "ponSTag": 900,
+                "usPonCTagPriority": 0,
+                "usPonSTagPriority": 0,
+                "dsPonCTagPriority": 0,
+                "dsPonSTagPriority": 0,
+                "technologyProfileId": 64,
+                "downstreamBandwidthProfile": "High-Speed-Internet",
+                "upstreamBandwidthProfile": "High-Speed-Internet",
+                "serviceName": "HSIA"
+              }
+            ]
+          },
+          {
+            "id": "BBSM000a0002",
+            "nasPortId": "BBSM000a0002-1",
+            "circuitId": "BBSM000a0002-1",
+            "remoteId": "BBSM000a0002",
+            "uniTagList": [
+              {
+                "uniTagMatch": 4096,
+                "ponCTag": 4096,
+                "ponSTag": 904,
+                "usPonCTagPriority": 0,
+                "usPonSTagPriority": 0,
+                "dsPonCTagPriority": 0,
+                "dsPonSTagPriority": 0,
+                "technologyProfileId": 64,
+                "downstreamBandwidthProfile": "High-Speed-Internet",
+                "upstreamBandwidthProfile": "High-Speed-Internet",
+                "serviceName": "HSIA"
+              }
+            ]
+          },
+          {
+            "id": "BBSM000a0101",
+            "nasPortId": "BBSM000a0101-1",
+            "circuitId": "BBSM000a0101-1",
+            "remoteId": "BBSM000a0101",
+            "uniTagList": [
+              {
+                "uniTagMatch": 4096,
+                "ponCTag": 4096,
+                "ponSTag": 908,
+                "usPonCTagPriority": 0,
+                "usPonSTagPriority": 0,
+                "dsPonCTagPriority": 0,
+                "dsPonSTagPriority": 0,
+                "technologyProfileId": 64,
+                "downstreamBandwidthProfile": "High-Speed-Internet",
+                "upstreamBandwidthProfile": "High-Speed-Internet",
+                "serviceName": "HSIA"
+              }
+            ]
+          },
+          {
+            "id": "BBSM000a0102",
+            "nasPortId": "BBSM000a0102-1",
+            "circuitId": "BBSM000a0102-1",
+            "remoteId": "BBSM000a0102",
+            "uniTagList": [
+              {
+                "uniTagMatch": 4096,
+                "ponCTag": 4096,
+                "ponSTag": 912,
+                "usPonCTagPriority": 0,
+                "usPonSTagPriority": 0,
+                "dsPonCTagPriority": 0,
+                "dsPonSTagPriority": 0,
+                "technologyProfileId": 64,
+                "downstreamBandwidthProfile": "High-Speed-Internet",
+                "upstreamBandwidthProfile": "High-Speed-Internet",
+                "serviceName": "HSIA"
+              }
+            ]
+          },
+          {
+            "id": "BBSIM_OLT_11",
+            "nasId": "BBSIM_OLT_11",
+            "hardwareIdentifier": "28:b9:d9:e2:93:d6",
+            "uplinkPort": "16777216"
+          },
+          {
+            "id": "BBSM000b0001",
+            "nasPortId": "BBSM000b0001-1",
+            "circuitId": "BBSM000b0001-1",
+            "remoteId": "BBSM000b0001",
+            "uniTagList": [
+              {
+                "uniTagMatch": 4096,
+                "ponCTag": 4096,
+                "ponSTag": 900,
+                "usPonCTagPriority": 0,
+                "usPonSTagPriority": 0,
+                "dsPonCTagPriority": 0,
+                "dsPonSTagPriority": 0,
+                "technologyProfileId": 64,
+                "downstreamBandwidthProfile": "High-Speed-Internet",
+                "upstreamBandwidthProfile": "High-Speed-Internet",
+                "serviceName": "HSIA"
+              }
+            ]
+          },
+          {
+            "id": "BBSM000b0002",
+            "nasPortId": "BBSM000b0002-1",
+            "circuitId": "BBSM000b0002-1",
+            "remoteId": "BBSM000b0002",
+            "uniTagList": [
+              {
+                "uniTagMatch": 4096,
+                "ponCTag": 4096,
+                "ponSTag": 904,
+                "usPonCTagPriority": 0,
+                "usPonSTagPriority": 0,
+                "dsPonCTagPriority": 0,
+                "dsPonSTagPriority": 0,
+                "technologyProfileId": 64,
+                "downstreamBandwidthProfile": "High-Speed-Internet",
+                "upstreamBandwidthProfile": "High-Speed-Internet",
+                "serviceName": "HSIA"
+              }
+            ]
+          },
+          {
+            "id": "BBSM000b0101",
+            "nasPortId": "BBSM000b0101-1",
+            "circuitId": "BBSM000b0101-1",
+            "remoteId": "BBSM000b0101",
+            "uniTagList": [
+              {
+                "uniTagMatch": 4096,
+                "ponCTag": 4096,
+                "ponSTag": 908,
+                "usPonCTagPriority": 0,
+                "usPonSTagPriority": 0,
+                "dsPonCTagPriority": 0,
+                "dsPonSTagPriority": 0,
+                "technologyProfileId": 64,
+                "downstreamBandwidthProfile": "High-Speed-Internet",
+                "upstreamBandwidthProfile": "High-Speed-Internet",
+                "serviceName": "HSIA"
+              }
+            ]
+          },
+          {
+            "id": "BBSM000b0102",
+            "nasPortId": "BBSM000b0102-1",
+            "circuitId": "BBSM000b0102-1",
+            "remoteId": "BBSM000b0102",
+            "uniTagList": [
+              {
+                "uniTagMatch": 4096,
+                "ponCTag": 4096,
+                "ponSTag": 912,
+                "usPonCTagPriority": 0,
+                "usPonSTagPriority": 0,
+                "dsPonCTagPriority": 0,
+                "dsPonSTagPriority": 0,
+                "technologyProfileId": 64,
+                "downstreamBandwidthProfile": "High-Speed-Internet",
+                "upstreamBandwidthProfile": "High-Speed-Internet",
+                "serviceName": "HSIA"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  }
+}
+
diff --git a/tests/dt-workflow/Voltha_DT_FTTB_Tests_VGC.robot b/tests/dt-workflow/Voltha_DT_FTTB_Tests_VGC.robot
new file mode 100644
index 0000000..63c89fe
--- /dev/null
+++ b/tests/dt-workflow/Voltha_DT_FTTB_Tests_VGC.robot
@@ -0,0 +1,86 @@
+# Copyright 2022 - 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.
+# FIXME Can we use the same test against BBSim and Hardware?
+
+*** Settings ***
+Documentation     Test various DT FTTB end-to-end scenarios
+Suite Setup       Setup Suite
+Test Setup        Setup
+Test Teardown     Teardown
+Suite Teardown    Teardown Suite
+Library           Collections
+Library           String
+Library           OperatingSystem
+Library           XML
+Library           RequestsLibrary
+Library           ../../libraries/DependencyLibrary.py
+Resource          ../../libraries/vgc.robot
+Resource          ../../libraries/voltctl.robot
+Resource          ../../libraries/voltha.robot
+Resource          ../../libraries/utils_vgc.robot
+Resource          ../../libraries/k8s.robot
+Resource          ../../variables/variables.robot
+Resource          ../../libraries/power_switch.robot
+
+
+*** Variables ***
+${POD_NAME}       flex-ocp-cord
+${KUBERNETES_CONF}    ${KUBERNETES_CONFIGS_DIR}/${POD_NAME}.conf
+${KUBERNETES_CONFIGS_DIR}    ~/pod-configs/kubernetes-configs
+#${KUBERNETES_CONFIGS_DIR}    ${KUBERNETES_CONFIGS_DIR}/${POD_NAME}.conf
+${KUBERNETES_YAML}    ${KUBERNETES_CONFIGS_DIR}/${POD_NAME}.yml
+${HELM_CHARTS_DIR}    ~/helm-charts
+${VOLTHA_POD_NUM}    8
+${NAMESPACE}      voltha
+${INFRA_NAMESPACE}      default
+${timeout}        60s
+${of_id}          0
+${logical_id}     0
+${uprate}         0
+${dnrate}         0
+${has_dataplane}    True
+${teardown_device}    True
+${scripts}        ../../scripts
+
+# Per-test logging on failure is turned off by default; set this variable to enable
+${container_log_dir}    ${None}
+
+# logging flag to enable Collect Logs, can be passed via the command line too
+# example: -v logging:False
+${logging}    True
+
+*** Test Cases ***
+Sanity E2E Test for OLT/ONU on POD for DT FTTB
+    [Documentation]    Validates E2E Ping Connectivity and object states for the given scenario:
+    ...    Validate successful DHCP/E2E ping (no EAPOL and DHCP flows) for the tech profile that is used
+    ...    Traffic sent with same vlan from different RGs,
+    ...    should reach the NNI port on the OLT with the expected double tagged vlan ids
+    ...    Inner vlans from the RG should not change
+    [Tags]    sanityDtFttb
+    [Setup]    Start Logging    SanityTestDtFttb
+    [Teardown]    Run Keywords    Run Keyword If    ${logging}    Collect Logs
+    ...           AND             Stop Logging    SanityTestDtFttb
+    Setup
+    Run Keyword If    ${has_dataplane}    Clean Up Linux
+    Perform Sanity Test DT FTTB
+
+*** Keywords ***
+Setup Suite
+    [Documentation]    Set up the test suite
+    Common Test Suite Setup
+    #Restore all ONUs
+    #Run Keyword If    ${has_dataplane}    RestoreONUs    ${num_all_onus}
+    #power_switch.robot needs it to support different vendor's power switch
+    ${switch_type}=    Get Variable Value    ${web_power_switch.type}
+    Run Keyword If  "${switch_type}"!=""    Set Global Variable    ${powerswitch_type}    ${switch_type}
diff --git a/tests/dt-workflow/Voltha_DT_MultiOLT_Tests_VGC.robot b/tests/dt-workflow/Voltha_DT_MultiOLT_Tests_VGC.robot
new file mode 100755
index 0000000..654ebb1
--- /dev/null
+++ b/tests/dt-workflow/Voltha_DT_MultiOLT_Tests_VGC.robot
@@ -0,0 +1,189 @@
+# Copyright 2020 - 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.
+
+*** Settings ***
+Documentation     Test various end-to-end scenarios involing Multiple OLTs
+Suite Setup       Setup Suite
+Test Setup        Setup
+Test Teardown     Teardown
+Suite Teardown    Teardown Suite
+Library           Collections
+Library           String
+Library           OperatingSystem
+Library           XML
+Library           RequestsLibrary
+Library           ../../libraries/DependencyLibrary.py
+Resource          ../../libraries/vgc.robot
+Resource          ../../libraries/voltctl.robot
+Resource          ../../libraries/voltha.robot
+Resource          ../../libraries/utils_vgc.robot
+Resource          ../../libraries/k8s.robot
+Resource          ../../variables/variables.robot
+Resource          ../../libraries/power_switch.robot
+
+*** Variables ***
+${POD_NAME}       flex-ocp-cord
+${KUBERNETES_CONF}    ${KUBERNETES_CONFIGS_DIR}/${POD_NAME}.conf
+${KUBERNETES_CONFIGS_DIR}    ~/pod-configs/kubernetes-configs
+#${KUBERNETES_CONFIGS_DIR}    ${KUBERNETES_CONFIGS_DIR}/${POD_NAME}.conf
+${KUBERNETES_YAML}    ${KUBERNETES_CONFIGS_DIR}/${POD_NAME}.yml
+${HELM_CHARTS_DIR}    ~/helm-charts
+${VOLTHA_POD_NUM}    8
+${NAMESPACE}      voltha
+${INFRA_NAMESPACE}      default
+# For below variable value, using deployment name as using grep for
+# parsing radius pod name, we can also use full radius pod name
+${RESTART_POD_NAME}    radius
+${timeout}        60s
+${of_id}          0
+${logical_id}     0
+${has_dataplane}    True
+${teardown_device}    False
+${scripts}        ../../scripts
+
+# Per-test logging on failure is turned off by default; set this variable to enable
+${container_log_dir}    ${None}
+
+# logging flag to enable Collect Logs, can be passed via the command line too
+# example: -v logging:False
+${logging}    True
+
+*** Test Cases ***
+Verify OLT after Rebooting Physically for DT - Multiple OLT
+    [Documentation]    Test the physical reboot of the OLT
+    ...    Assuming that all the ONUs are DHCP/pingable (i.e. assuming sanityDt test was executed)
+    ...    Test performs a physical reboot, performs "reboot" from the OLT CLI
+    ...    Test runs when more than one OLT exists
+    ...    Only one OLT is rebooted in the test, while verifying if the ONUs on the
+    ...    other OLT are still functional
+    [Tags]    functionalDt   MultiOLTPhysicalRebootDt
+    [Setup]    Start Logging    MultiOlt_Physical_Dt
+    [Teardown]    Run Keywords    Collect Logs
+    ...           AND             Stop Logging    MultiOlt_Physical_Dt
+    # Execute the test when the number of OLTs are greater than one
+    Pass Execution If    ${olt_count} == 1    Skipping test: just one OLT
+    Clear All Devices Then Perform Setup And Sanity
+    # Reboot the first OLT from the list of olts - rebooting from the OLT CLI
+    ${olt_user}=    Get From Dictionary    ${list_olts}[0]    user
+    ${olt_pass}=    Get From Dictionary    ${list_olts}[0]    pass
+    ${olt_ssh_ip}=    Get From Dictionary    ${list_olts}[0]   sship
+    ${olt_serial_number}=    Get From Dictionary    ${list_olts}[0]    sn
+    ${olt_device_id}=    Get OLTDeviceID From OLT List    ${olt_serial_number}
+    Run Keyword If    ${has_dataplane}    Login And Run Command On Remote System
+    ...    reboot    ${olt_ssh_ip}    ${olt_user}    ${olt_pass}   prompt=#
+    # validate that the ONUs on the other OLTs are still functional
+    Verify ping is successful for ONUs not on this OLT     ${num_all_onus}    ${olt_device_id}
+
+    # validate that the ONUs on the rebooted OLT are not pingable
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        ${olt_serial_number}=    Get From Dictionary    ${list_olts}[0]    sn
+        Continue For Loop If    "${olt_serial_number}"!="${src['olt']}"
+        Run Keyword If    ${has_dataplane}    Run Keyword And Continue On Failure
+        ...    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Check Ping    False    ${dst['dp_iface_ip_qinq']}    ${src['dp_iface_name']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+    END
+    # Wait for the rebooted OLT to come back up
+    ${olt_user}=    Get From Dictionary    ${list_olts}[0]    user
+    ${olt_pass}=    Get From Dictionary    ${list_olts}[0]    pass
+    ${olt_ssh_ip}=    Get From Dictionary    ${list_olts}[0]   sship
+    ${olt_serial_number}=    Get From Dictionary    ${list_olts}[0]    sn
+    ${olt_device_id}=    Get OLTDeviceID From OLT List    ${olt_serial_number}
+    Run Keyword If    ${has_dataplane}    Wait Until Keyword Succeeds    120s    10s
+    ...    Check Remote System Reachability    True    ${olt_ssh_ip}
+    Wait Until Keyword Succeeds    360s    5s
+    ...    Validate OLT Device    ENABLED    ACTIVE
+    ...    REACHABLE    ${olt_serial_number}
+    # Waiting extra time for the ONUs to come up
+    Sleep    60s
+    Run Keyword If    ${has_dataplane}    Clean Up Linux
+    Perform Sanity Test DT
+
+Verify OLT Soft Reboot for DT - Multiple OLT
+    [Documentation]    Test soft reboot of the OLT using voltctl command
+    ...    Test runs when more than one OLT exists
+    ...    Only one OLT is rebooted in the test, while verifying if the ONUs on the
+    ...    other OLT are still functional
+    [Tags]    MultiOLTSoftRebootDt    functionalDt
+    [Setup]    Start Logging    MultiOLTSoftRebootDt
+    [Teardown]    Run Keywords    Collect Logs
+    ...           AND             Delete All Devices and Verify
+    ...           AND             Run Keyword If    ${logging}    Collect Logs
+    ...           AND             Stop Logging    MultiOLTSoftRebootDt
+    Pass Execution If    ${olt_count} == 1    Skipping test: just one OLT
+    Clear All Devices Then Perform Setup And Sanity
+    # Reboot the first OLT
+    ${olt_user}=    Get From Dictionary    ${list_olts}[0]    user
+    ${olt_pass}=    Get From Dictionary    ${list_olts}[0]    pass
+    ${olt_ssh_ip}=    Get From Dictionary    ${list_olts}[0]   sship
+    ${olt_serial_number}=    Get From Dictionary    ${list_olts}[0]    sn
+    ${olt_device_id}=    Get OLTDeviceID From OLT List    ${olt_serial_number}
+    Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    360s    5s
+    ...    Validate OLT Device    ENABLED    ACTIVE
+    ...    REACHABLE    ${olt_serial_number}
+    # Reboot the OLT using "voltctl device reboot" command
+    Reboot Device    ${olt_device_id}
+    # Wait for the OLT to actually go down
+    Wait Until Keyword Succeeds    360s    5s    Validate OLT Device    ENABLED    UNKNOWN    UNREACHABLE
+    ...    ${olt_serial_number}
+    # validate that the ONUs on the other OLTs are still functional
+    Verify ping is successful for ONUs not on this OLT     ${num_all_onus}    ${olt_device_id}
+    #Verify that ping fails for the ONUs where the OLT has been rebooted
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        ${olt_serial_number}=    Get From Dictionary    ${list_olts}[0]    sn
+        Continue For Loop If    "${olt_serial_number}"!="${src['olt']}"
+        Run Keyword If    ${has_dataplane}    Run Keyword And Continue On Failure
+        ...    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Check Ping    False    ${dst['dp_iface_ip_qinq']}    ${src['dp_iface_name']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+    END
+    # Check OLT state
+    ${olt_serial_number}=    Get From Dictionary    ${list_olts}[0]    sn
+    ${olt_ssh_ip}=    Get From Dictionary    ${list_olts}[0]    sship
+    ${olt_device_id}=    Get OLTDeviceID From OLT List    ${olt_serial_number}
+    # Wait for the OLT to come back up
+    Run Keyword If    ${has_dataplane}    Wait Until Keyword Succeeds    120s    10s
+    ...    Check Remote System Reachability    True    ${olt_ssh_ip}
+    # Check OLT states
+    Wait Until Keyword Succeeds    360s    5s
+    ...    Validate OLT Device    ENABLED    ACTIVE
+    ...    REACHABLE    ${olt_serial_number}
+    # Waiting extra time for the ONUs to come up
+    Sleep    60s
+    #Check after reboot that ONUs are active, DHCP and pingable
+    Run Keyword If    ${has_dataplane}    Clean Up Linux
+    Perform Sanity Test DT
+
+*** Keywords ***
+Setup Suite
+    [Documentation]    Set up the test suite
+    Common Test Suite Setup
+    #power_switch.robot needs it to support different vendor's power switch
+    ${switch_type}=    Get Variable Value    ${web_power_switch.type}
+    Run Keyword If  "${switch_type}"!=""    Set Global Variable    ${powerswitch_type}    ${switch_type}
+
+Clear All Devices Then Perform Setup And Sanity
+    [Documentation]    Remove any devices from VOLTHA and Verify in VGC
+    ...    Create New Device through Setup and Perform Sanity
+    # Remove all devices from voltha and nos
+    Delete All Devices and Verify
+    # Execute normal test Setup Keyword
+    Setup
+    # Performing Sanity Test to make sure subscribers are all DHCP and pingable
+    Run Keyword If    ${has_dataplane}    Clean Up Linux
+    Perform Sanity Test DT
diff --git a/tests/dt-workflow/Voltha_DT_PODTests_VGC.robot b/tests/dt-workflow/Voltha_DT_PODTests_VGC.robot
new file mode 100755
index 0000000..42d2a0d
--- /dev/null
+++ b/tests/dt-workflow/Voltha_DT_PODTests_VGC.robot
@@ -0,0 +1,503 @@
+# Copyright 2017 - 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.
+# FIXME Can we use the same test against BBSim and Hardware?
+
+*** Settings ***
+Documentation     Test various end-to-end scenarios
+Suite Setup       Setup Suite
+Test Setup        Setup
+Test Teardown     Teardown
+Suite Teardown    Teardown Suite
+Library           Collections
+Library           String
+Library           OperatingSystem
+Library           XML
+Library           RequestsLibrary
+Library           ../../libraries/DependencyLibrary.py
+Resource          ../../libraries/vgc.robot
+Resource          ../../libraries/voltctl.robot
+Resource          ../../libraries/voltha.robot
+Resource          ../../libraries/utils_vgc.robot
+Resource          ../../libraries/k8s.robot
+Resource          ../../variables/variables.robot
+Resource          ../../libraries/power_switch.robot
+
+
+*** Variables ***
+${POD_NAME}       bbsim-kind-dt
+${KUBERNETES_CONF}    ${KUBERNETES_CONFIGS_DIR}/${POD_NAME}.conf
+${KUBERNETES_CONFIGS_DIR}    ~/pod-configs/kubernetes-configs
+#${KUBERNETES_CONFIGS_DIR}    ${KUBERNETES_CONFIGS_DIR}/${POD_NAME}.conf
+#${KUBERNETES_YAML}    ${KUBERNETES_CONFIGS_DIR}/${POD_NAME}.yml
+${KUBERNETES_YAML}    /test/repos/voltha-system-tests/tests/data/bbsim-kind-dt-vgc.yaml
+${HELM_CHARTS_DIR}    ~/helm-charts
+${VOLTHA_POD_NUM}    8
+${NAMESPACE}      voltha
+${INFRA_NAMESPACE}      default
+# For below variable value, using deployment name as using grep for
+# parsing radius pod name, we can also use full radius pod name
+${RESTART_POD_NAME}    radius
+${timeout}        60s
+${of_id}          0
+${logical_id}     0
+${uprate}         0
+${dnrate}         0
+${has_dataplane}    True
+${teardown_device}    True
+${scripts}        ../../scripts
+# flag to reboot OLT through Power Switch
+${power_cycle_olt}    False
+
+# For dataplane bandwidth testing
+${upper_margin_pct}      105     # Allow 5% over the limit
+${lower_margin_pct}      90      # Allow 8% under the limit
+${udp_rate_multiplier}   1.10    # Send UDP at bw profile limit * rate_multiplier
+${udp_packet_bytes}      1470    # UDP payload in bytes
+
+# Per-test logging on failure is turned off by default; set this variable to enable
+${container_log_dir}    ${None}
+
+# logging flag to enable Collect Logs, can be passed via the command line too
+# example: -v logging:False
+${logging}    True
+
+# Flag specific to Soak Jobs
+${SOAK_TEST}    False
+${bbsim_port}    50060
+
+*** Test Cases ***
+Sanity E2E Test for OLT/ONU on POD for DT
+    [Documentation]    Validates E2E Ping Connectivity and object states for the given scenario:
+    ...    Validate successful DHCP/E2E ping (no EAPOL and DHCP flows) for the tech profile that is used
+    ...    Traffic sent with same vlan from different RGs,
+    ...    should reach the NNI port on the OLT with the expected double tagged vlan ids
+    ...    Inner vlans from the RG should not change
+    [Tags]    sanityDt   soak
+    [Setup]    Start Logging    SanityTestDt
+#    [Teardown]    Run Keywords    Run Keyword If    ${logging}    Collect Logs
+#    ...           AND             Stop Logging    SanityTestDt
+    Setup    ${SOAK_TEST}
+    Run Keyword If    ${has_dataplane}    Clean Up Linux
+    Perform Sanity Test DT
+
+Test Subscriber Delete and Add for DT
+    [Documentation]    Validates E2E Ping Connectivity and object states for the given scenario:
+    ...    Assuming that all the ONUs are DHCP/pingable (i.e. assuming sanityDt test was executed)
+    ...    Delete a subscriber and validate that the pings do not succeed and state is purged
+    ...    Disable and Enable the ONU (This is to replicate the existing DT behaviour)
+    ...    Re-add the subscriber, and validate that the flows are present and pings are successful
+    [Tags]    functionalDt    SubAddDeleteDt    soak
+    [Setup]    Run Keywords    Start Logging     SubAddDeleteDt
+    ...        AND    Run Keyword If    ${has_dataplane}    Set Non-Critical Tag for XGSPON Tech
+    [Teardown]    Run Keywords    Run Keyword If    ${logging}    Collect Logs
+    ...           AND             Stop Logging    SubAddDeleteDt
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        ${of_id}=    Get ofID From OLT List    ${src['olt']}
+        ${nni_port}=    Wait Until Keyword Succeeds    ${timeout}    2s    Get NNI Port in VGC    ${of_id}
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        ${olt_device_id}=    Get OLTDeviceID From OLT List    ${src['olt']}
+        ${num_of_olt_onus}=    Get Num of Onus From OLT SN    ${src['olt']}
+        ${onu_port}=    Wait Until Keyword Succeeds    ${timeout}    2s    Get ONU Port in VGC    ${src['onu']}
+        ...    ${of_id}    ${src['uni_id']}
+        # Remove Subscriber Access
+	    Delete Request    VGC    services/${of_id}/${onu_port}
+        Run Keyword If    ${has_dataplane}    Run Keyword And Continue On Failure
+        ...    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Check Ping    False    ${dst['dp_iface_ip_qinq']}    ${src['dp_iface_name']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+
+        # Number of Access Flows on VGC equals 4 * the Number of Active ONUs (2 for each downstream and upstream)
+        ${vgc_flows_count}=    Evaluate    4 * ( ${num_of_olt_onus} - 1 )
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Subscriber Access Flows Added Count DT    ${VGC_SSH_IP}    ${VGC_SSH_PORT}
+        ...    ${of_id}    ${vgc_flows_count}
+        # Verify VOLTHA flows for OLT equals twice the number of ONUS (minus ONU under test) + 1 for LLDP
+        ${olt_flows}=    Evaluate    2 * ( ${num_of_olt_onus} - 1 )
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s    Validate OLT Flows
+        ...    ${olt_flows}    ${olt_device_id}
+        # Verify VOLTHA flows for ONU under test is Zero
+        Run Keyword    Wait Until Keyword Succeeds    ${timeout}    5s    Validate Device Flows
+        ...    ${onu_device_id}    0
+        # Disable and Re-Enable the ONU (To replicate DT current workflow)
+        # TODO: Delete and Auto-Discovery Add of ONU (not yet supported)
+        Disable Device    ${onu_device_id}
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate Device    DISABLED    UNKNOWN
+        ...    REACHABLE    ${src['onu']}
+        Enable Device    ${onu_device_id}
+        Wait Until Keyword Succeeds    360s    5s
+        ...    Validate Device    ENABLED    ACTIVE
+        ...    REACHABLE    ${src['onu']}
+        # Add Subscriber Access
+	Post Request    VGC    services/${of_id}/${onu_port}
+        # Verify subscriber access flows are added for the ONU port
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Subscriber Access Flows Added for ONU DT in VGC    ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${of_id}
+        ...    ${onu_port}    ${nni_port}    ${src['s_tag']}
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate Device    ENABLED    ACTIVE
+        ...    REACHABLE    ${src['onu']}    onu=True    onu_reason=omci-flows-pushed
+        # Workaround for issue seen in VOL-4489. Keep this workaround until VOL-4489 is fixed.
+        Run Keyword If    ${has_dataplane}    Reboot XGSPON ONU    ${src['olt']}    ${src['onu']}    omci-flows-pushed
+        # Workaround ends here for issue seen in VOL-4489.
+        Run Keyword If    ${has_dataplane}    Run Keyword And Continue On Failure
+        ...    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Check Ping    True    ${dst['dp_iface_ip_qinq']}    ${src['dp_iface_name']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+    END
+    # Verify flows for all OLTs
+    Run Keyword    Wait Until Keyword Succeeds    ${timeout}    5s    Validate All OLT Flows
+
+Test Disable and Enable ONU for DT
+    [Documentation]    Validates E2E Ping Connectivity and object states for the given scenario:
+    ...    Assuming that all the ONUs are DHCP/pingable (i.e. assuming sanityDt test was executed)
+    ...    Perform disable on the ONUs and validate that the pings do not succeed
+    ...    Perform enable on the ONUs and validate that the pings are successful
+    [Tags]    functionalDt    DisableEnableONUDt    soak
+    [Setup]    Run Keywords    Start Logging    DisableEnableONUDt
+    ...        AND    Run Keyword If    ${has_dataplane}    Set Non-Critical Tag for XGSPON Tech
+    [Teardown]    Run Keywords    Run Keyword If    ${logging}    Collect Logs
+    ...           AND             Stop Logging    DisableEnableONUDt
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        ${of_id}=    Get ofID From OLT List    ${src['olt']}
+        ${onu_port}=    Wait Until Keyword Succeeds    ${timeout}    2s    Get ONU Port in VGC    ${src['onu']}
+        ...    ${of_id}    ${src['uni_id']}
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        Disable Device    ${onu_device_id}
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate Device    DISABLED    UNKNOWN
+        ...    REACHABLE    ${src['onu']}    onu=True    onu_reason=omci-admin-lock
+        Wait Until Keyword Succeeds   ${timeout}    2s
+        ...    Verify UNI Port Is Disabled   ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${src['onu']}    ${src['uni_id']}
+        # TODO: Yet to Verify on the GPON based Physical POD (VOL-2652)
+        Run Keyword If    ${has_dataplane}    Run Keyword And Continue On Failure
+        ...    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Check Ping    False    ${dst['dp_iface_ip_qinq']}    ${src['dp_iface_name']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        Sleep    5s
+        Enable Device    ${onu_device_id}
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    360s    5s
+        ...    Validate Device    ENABLED    ACTIVE
+        ...    REACHABLE    ${src['onu']}    onu=True    onu_reason=onu-reenabled
+        Wait Until Keyword Succeeds   ${timeout}    2s
+        ...    Verify UNI Port Is Enabled    ${src['onu']}    ${src['uni_id']}
+        # Workaround for issue seen in VOL-4489. Keep this workaround until VOL-4489 is fixed.
+        Run Keyword If    ${has_dataplane}    Reboot XGSPON ONU    ${src['olt']}    ${src['onu']}    omci-flows-pushed
+        # Workaround ends here for issue seen in VOL-4489.
+        Run Keyword If    ${has_dataplane}    Run Keyword And Continue On Failure
+        ...    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Check Ping    True    ${dst['dp_iface_ip_qinq']}    ${src['dp_iface_name']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+    END
+
+Test Disable and Delete OLT for DT
+    [Documentation]    Validates E2E Ping Connectivity and object states for the given scenario:
+    ...    Assuming that all the ONUs are DHCP/pingable (i.e. assuming sanityDt test was executed)
+    ...    Perform disable on the OLT and validate ONUs state and that the pings do not succeed
+    ...    Perform delete on the OLT, Re-do Setup (Recreate the OLT) and Perform Sanity Test DT
+    [Tags]    functionalDt    DisableDeleteOLTDt    soak
+    [Setup]    Start Logging    DisableDeleteOLTDt
+    [Teardown]    Run Keywords    Run Keyword If    ${logging}    Collect Logs
+    ...           AND             Stop Logging    DisableDeleteOLTDt
+    # Disable and Validate OLT Device
+    FOR   ${I}    IN RANGE    0    ${olt_count}
+        ${olt_serial_number}=    Get From Dictionary    ${olt_ids}[${I}]    sn
+        ${olt_device_id}=    Get OLTDeviceID From OLT List    ${olt_serial_number}
+        Disable Device    ${olt_device_id}
+        ${of_id}=    Get ofID From OLT List    ${olt_serial_number}
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate OLT Device    DISABLED    UNKNOWN    REACHABLE
+        ...    ${olt_serial_number}
+        ${num_onus}=    Set Variable    ${list_olts}[${I}][onucount]
+        # Validate ONUs
+        Run Keyword    Wait Until Keyword Succeeds    ${timeout}    5s    Validate ONUs After OLT Disable
+        ...    ${num_onus}    ${olt_serial_number}
+        # Verify VGC Flows
+        # Number of Access Flows on VGC equals 4 * the Number of Active ONUs (2 for each downstream and upstream)
+        ${vgc_flows_count}=    Evaluate    4 * ${num_onus}
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Subscriber Access Flows Added Count DT    ${VGC_SSH_IP}    ${VGC_SSH_PORT}
+        ...    ${of_id}    ${vgc_flows_count}
+        # Verify VOLTHA Flows
+        # Number of per OLT Flows equals Twice the Number of Active ONUs (each for downstream and upstream) + 1 for LLDP
+        ${olt_flows}=    Evaluate    2 * ${num_onus}
+        # Number of per ONU Flows equals 2 (one each for downstream and upstream)
+        ${onu_flows}=    Set Variable    2
+        Run Keyword    Wait Until Keyword Succeeds    ${timeout}    5s    Validate OLT Flows
+        ...    ${olt_flows}    ${olt_device_id}
+        ${List_ONU_Serial}    Create List
+        Set Suite Variable    ${List_ONU_Serial}
+        Build ONU SN List    ${List_ONU_Serial}    ${olt_serial_number}    ${num_onus}
+        Log    ${List_ONU_Serial}
+        Run Keyword    Wait Until Keyword Succeeds    ${timeout}    5s    Validate ONU Flows
+        ...    ${List_ONU_Serial}    ${onu_flows}
+        # Delete OLT and Validate Empty Device List
+        Delete Device    ${olt_device_id}
+        # Check that the OLT and the ONUs are actually removed from the system
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s    Validate Device Removed
+        ...    ${olt_serial_number}
+        Run Keyword and Continue On Failure    Validate all ONUS for OLT Removed    ${num_all_onus}    ${hosts}
+        ...    ${olt_serial_number}    ${timeout}
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Device Flows Removed    ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${of_id}
+    END
+    # Re-do Setup (Recreate the OLT) and Perform Sanity Test DT
+    Run Keyword    Setup    ${SOAK_TEST}
+    Run Keyword If    ${has_dataplane}    Clean Up Linux
+    Perform Sanity Test DT
+
+Test Disable and Enable OLT for DT
+    [Documentation]    Validates E2E Ping Connectivity and object states for the given scenario:
+    ...    Assuming that all the ONUs are DHCP/pingable (i.e. assuming sanityDt test was executed)
+    ...    Perform disable on the OLT and validate that the pings do not succeed
+    ...    Perform enable on the OLT and validate that the pings are successful
+    [Tags]    functionalDt    DisableEnableOLTDt   soak
+    [Setup]    Start Logging    DisableEnableOLTDt
+    [Teardown]    Run Keywords    Run Keyword If    ${logging}    Collect Logs
+    ...           AND             Stop Logging    DisableEnableOLTDt
+    # Disable and Validate OLT Device
+    FOR   ${I}    IN RANGE    0    ${olt_count}
+        ${olt_serial_number}=    Get From Dictionary    ${olt_ids}[${I}]    sn
+        ${olt_device_id}=    Get OLTDeviceID From OLT List    ${olt_serial_number}
+        ${rc}    ${output}=    Run and Return Rc and Output
+        ...    ${VOLTCTL_CONFIG}; voltctl device disable ${olt_device_id}
+        Should Be Equal As Integers    ${rc}    0
+        Wait Until Keyword Succeeds    ${timeout}    5s    Validate OLT Device    DISABLED    UNKNOWN    REACHABLE
+        ...    ${olt_serial_number}
+    END
+    # Validate ONUs
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        ${of_id}=    Get ofID From OLT List    ${src['olt']}
+        ${onu_port}=    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Get ONU Port in VGC    ${src['onu']}    ${of_id}    ${src['uni_id']}
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        Wait Until Keyword Succeeds   ${timeout}    2s
+        ...    Verify UNI Port Is Disabled   ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${src['onu']}    ${src['uni_id']}
+        Run Keyword If    ${has_dataplane}    Run Keyword And Continue On Failure
+        ...    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Check Ping    False    ${dst['dp_iface_ip_qinq']}    ${src['dp_iface_name']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        # Remove Subscriber Access (To replicate DT workflow)
+        ${onu_port_name}=    Catenate    SEPARATOR=-    ${src['onu']}    ${src['uni_id']}
+	Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Delete Request    VGC    services/${onu_port_name}
+        # Delete ONU Device (To replicate DT workflow)
+        Delete Device    ${onu_device_id}
+    END
+    Sleep    5s
+    # Enable the OLT back and check ONU, OLT status are back to "ACTIVE"
+    FOR   ${I}    IN RANGE    0    ${olt_count}
+        ${olt_serial_number}=    Get From Dictionary    ${olt_ids}[${I}]    sn
+        ${olt_device_id}=    Get OLTDeviceID From OLT List    ${olt_serial_number}
+        Enable Device    ${olt_device_id}
+        Wait Until Keyword Succeeds    ${timeout}    5s    Validate OLT Device    ENABLED    ACTIVE    REACHABLE
+        ...    ${olt_serial_number}
+        #TODO: Update for PON_OLT ETHERNET_NNI
+        #Wait Until Keyword Succeeds    ${timeout}    5s    Validate OLT Port Types
+        #...    PON_OLT    ETHERNET_NNI
+    END
+    # Waiting extra time for the ONUs to come up
+    Sleep    60s
+    Run Keyword If    ${has_dataplane}    Clean Up Linux
+    Perform Sanity Test DT
+
+Test Delete and ReAdd OLT for DT
+    [Documentation]    Validates E2E Ping Connectivity and object states for the given scenario:
+    ...    Assuming that all the ONUs are DHCP/pingable (i.e. assuming sanityDt test was executed)
+    ...    Disable and Delete the OLT
+    ...    Create/Enable the same OLT again
+    ...    Validate DHCP/E2E pings succeed for all the ONUs connected to the OLT
+    [Tags]    functionalDt    DeleteReAddOLTDt    soak
+    [Setup]    Start Logging    DeleteReAddOLTDt
+    [Teardown]    Run Keywords    Run Keyword If    ${logging}    Collect Logs
+    ...           AND             Stop Logging    DeleteReAddOLTDt
+    FOR    ${I}    IN RANGE    0    ${olt_count}
+        ${olt_serial_number}=    Get From Dictionary    ${olt_ids}[${I}]    sn
+        ${of_id}=    Get ofID From OLT List    ${olt_serial_number}
+        Delete Device and Verify    ${olt_serial_number}
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Device Flows Removed    ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${of_id}
+    END
+    # Recreate the OLTs
+    Setup    ${SOAK_TEST}
+    Run Keyword If    ${has_dataplane}    Clean Up Linux
+    Perform Sanity Test DT
+
+Test Disable ONUs and OLT Then Delete ONUs and OLT for DT
+    [Documentation]    On deployed POD, disable the ONU, disable the OLT and then delete ONU and OLT.
+    ...    This TC is to confirm that ONU removal is not impacting OLT
+    ...    Devices will be removed during the execution of this TC
+    ...    so calling setup at the end to add the devices back to avoid the confusion.
+    [Tags]    functionalDt    DisableDeleteONUOLTDt
+    [Setup]    Run Keywords    Start Logging    DisableDeleteONUOLTDt
+    ...        AND    Run Keyword If    ${has_dataplane}    Set Non-Critical Tag for XGSPON Tech
+    [Teardown]    Run Keywords    Run Keyword If    ${logging}    Collect Logs
+    ...           AND             Stop Logging    DisableDeleteONUOLTDt
+    @{onu_reason}=    Create List    initial-mib-downloaded    omci-flows-pushed
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate Device    ENABLED    ACTIVE
+        ...    REACHABLE    ${src['onu']}    onu=True    onu_reason=${onu_reason}
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate OLT Device    ENABLED    ACTIVE
+        ...    REACHABLE    ${src['olt']}
+        Disable Device    ${onu_device_id}
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate Device    DISABLED    UNKNOWN
+        ...    REACHABLE    ${src['onu']}    onu=false
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate OLT Device    ENABLED    ACTIVE
+        ...    REACHABLE    ${src['olt']}
+    END
+    # Disable all OLTs
+    FOR   ${I}    IN RANGE    0    ${olt_count}
+        ${olt_serial_number}=    Get From Dictionary    ${olt_ids}[${I}]    sn
+        ${olt_device_id}=    Get OLTDeviceID From OLT List    ${olt_serial_number}
+        ${rc}    ${output}=    Run and Return Rc and Output
+        ...    ${VOLTCTL_CONFIG}; voltctl device disable ${olt_device_id}
+        Should Be Equal As Integers    ${rc}    0
+        Wait Until Keyword Succeeds    ${timeout}    5s    Validate OLT Device    DISABLED    UNKNOWN    REACHABLE
+        ...    ${olt_serial_number}
+    END
+    # Validate ONUs after OLT disable
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate Device    DISABLED    DISCOVERED
+        ...    UNREACHABLE    ${src['onu']}    onu=false
+        Delete Device    ${onu_device_id}
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate OLT Device    DISABLED    UNKNOWN
+        ...    REACHABLE    ${src['olt']}
+    END
+    # Delete all OLTs
+    Delete All Devices and Verify
+
+    #Delete Device    ${olt_device_id}
+    #TODO: Fix the following assertion
+    #Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s    Test Empty Device List
+    #Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+    #...    Verify Device Flows Removed    ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${of_id}
+
+    # Re-do Setup (Recreate the OLT) and Perform Sanity Test DT
+    Run Keyword    Setup
+    Run Keyword If    ${has_dataplane}    Clean Up Linux
+    Perform Sanity Test DT
+
+Test Disable and Enable OLT PON Port for DT
+    [Documentation]    Validates E2E Ping Connectivity and object states for the given scenario:
+    ...    Assuming that all the ONUs are DHCP/pingable (i.e. assuming sanityDt test was executed)
+    ...    Perform disable on the OLT PON Port and validate that the pings do not succeed
+    ...    Perform enable on the OLT PON Port and validate that the pings are successful
+    [Tags]    functionalDt    DisableEnableOltPonPortDt    VOL-2577    soak
+    [Setup]    Run Keywords    Start Logging   DisableEnableOltPonPortDt
+    ...        AND    Run Keyword If    ${has_dataplane}    Set Non-Critical Tag for XGSPON Tech
+    [Teardown]    Run Keywords    Run Keyword If    ${logging}    Collect Logs
+    ...           AND             Stop Logging    DisableEnableOltPonPortDt
+    FOR   ${I}    IN RANGE    0    ${olt_count}
+        ${olt_serial_number}=    Get From Dictionary    ${olt_ids}[${I}]    sn
+        Disable Enable PON Port Per OLT DT    ${olt_serial_number}
+    END
+
+Test ONU Delete and Auto-Discovery for DT
+    [Documentation]    Tests the voltctl delete and Auto-Discovery of the ONU
+    [Tags]    functionalDt    VOL-3098    ONUAutoDiscoveryDt
+    [Setup]    Start Logging   ONUAutoDiscoveryDt
+    [Teardown]    Run Keywords    Run Keyword If    ${logging}    Collect Logs
+    ...           AND             Stop Logging    ONUAutoDiscoveryDt
+    Clear All Devices Then Create New Device
+    # Performing Sanity Test to make sure subscribers are all AUTH+DHCP and pingable
+    Run Keyword If    ${has_dataplane}    Clean Up Linux
+    Perform Sanity Test DT
+    FOR    ${I}    IN RANGE    0    ${num_all_onus}
+        ${src}=    Set Variable    ${hosts.src[${I}]}
+        ${dst}=    Set Variable    ${hosts.dst[${I}]}
+        ${of_id}=    Get ofID From OLT List    ${src['olt']}
+        ${onu_port}=    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Get ONU Port in VGC    ${src['onu']}    ${of_id}
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        ${nni_port}=    Wait Until Keyword Succeeds    ${timeout}    2s    Get NNI Port in VGC    ${of_id}
+        # Remove Subscriber
+        Delete Request    VGC    services/${of_id}/${onu_port}
+        # Additional sleep to let subscriber delete process
+        Sleep    10s
+        # Delete ONU and Verify Ping Fails
+        Delete Device    ${onu_device_id}
+        Run Keyword If    ${has_dataplane}    Verify ping is successful except for given device
+        ...    ${num_all_onus}    ${src['onu']}
+        # Verify that no pending flows exist for the ONU port
+        Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Verify No Pending Flows For ONU    ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${onu_port}
+        # ONU Auto-Discovery
+        ${onu_port}=    Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Get ONU Port in VGC    ${src['onu']}    ${of_id}    ${src['uni_id']}
+        # Check ONU port is Enabled in VGC
+        Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Verify UNI Port Is Enabled    ${src['onu']}    ${src['uni_id']}
+        ${onu_device_id}=    Get Device ID From SN    ${src['onu']}
+        Run Keyword If    ${has_dataplane}    Clean Up Linux    ${onu_device_id}
+        # Re-Add Subscriber
+        Add Subscriber Details    ${of_id}     ${onu_port}
+        #Post Request    VGC    services/${of_id}/${onu_port}
+        # Verify ONU state in voltha
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Validate Device    ENABLED    ACTIVE    REACHABLE
+        ...    ${src['onu']}    onu=True    onu_reason=omci-flows-pushed
+        # Verify that no pending flows exist for the ONU port
+        Wait Until Keyword Succeeds    ${timeout}    2s
+        ...    Verify No Pending Flows For ONU    ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${onu_port}
+        # Verify subscriber access flows are added for the ONU port
+        Run Keyword And Continue On Failure    Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Subscriber Access Flows Added For ONU DT in VGC   ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${of_id}
+        ...    ${onu_port}    ${nni_port}    ${src['s_tag']}
+        # Verify Meters in VGC
+        Wait Until Keyword Succeeds    ${timeout}    5s
+        ...    Verify Meters in VGC Ietf    ${VGC_SSH_IP}    ${VGC_SSH_PORT}    ${of_id}    ${onu_port}
+        Run Keyword If    ${has_dataplane}    Validate DHCP and Ping    True
+        ...    True    ${src['dp_iface_name']}    ${src['s_tag']}    ${src['c_tag']}    ${dst['dp_iface_ip_qinq']}
+        ...    ${src['ip']}    ${src['user']}    ${src['pass']}    ${src['container_type']}    ${src['container_name']}
+        ...    ${dst['dp_iface_name']}    ${dst['ip']}    ${dst['user']}    ${dst['pass']}    ${dst['container_type']}
+        ...    ${dst['container_name']}
+    END
+    # Verify flows for all OLTs
+    Wait Until Keyword Succeeds    ${timeout}    5s    Validate All OLT Flows
+
+*** Keywords ***
+Setup Suite
+    [Documentation]    Set up the test suite
+    Common Test Suite Setup
+    #Restore all ONUs
+    #Run Keyword If    ${has_dataplane}    RestoreONUs    ${num_all_onus}
+    #power_switch.robot needs it to support different vendor's power switch
+    ${switch_type}=    Get Variable Value    ${web_power_switch.type}
+    Run Keyword If  "${switch_type}"!=""    Set Global Variable    ${powerswitch_type}    ${switch_type}
+
+Clear All Devices Then Create New Device
+    [Documentation]    Remove any devices from VOLTHA and VGC
+    # Remove all devices from voltha and nos
+    Delete All Devices and Verify
+    # Execute normal test Setup Keyword
+    Setup
+