Multiple cherrypicks to cord-tester 4.0 branch

Change-Id: Ibbeaef75635e697ad52da7ee23b77b353ab48ad7
diff --git a/src/test/cord-api/Framework/utils/onosUtils.py b/src/test/cord-api/Framework/utils/onosUtils.py
new file mode 100644
index 0000000..06420a6
--- /dev/null
+++ b/src/test/cord-api/Framework/utils/onosUtils.py
@@ -0,0 +1,45 @@
+# 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.
+
+import paramiko
+
+def onos_command_execute(host, portNum, cmd, user='karaf', passwd='karaf'):
+    """
+    :param host: onos-cord or onos-fabric
+    :param portNum: 8102 or 8101
+    :param cmd: command to execute
+    :param user: onos/karaf
+    :param passwd: onos/karaf
+    :return: output of command executed inside onos karaf (shell)
+    """
+    try:
+        client = paramiko.SSHClient()
+        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+        client.connect(host, port=int(portNum), username=user, password=passwd)
+        stdin, stdout, stderr = client.exec_command(cmd)
+        while not stdout.channel.exit_status_ready():
+            if stdout.channel.recv_ready():
+                return stdout.read()
+    finally:
+        client.close()
+
+def get_compute_node_ip(compute_node):
+    """
+    :param compute_node: one compute node information from output of 'cordvtn-nodes'
+    :return: data_ip of that compute node
+    """
+    for line in compute_node.splitlines():
+        columns = line.split()
+        if len(columns) >= 2:
+            return columns[2].split("/")[0]
\ No newline at end of file
diff --git a/src/test/cord-api/Framework/utils/utils.py b/src/test/cord-api/Framework/utils/utils.py
index c5586fe..bb825a0 100644
--- a/src/test/cord-api/Framework/utils/utils.py
+++ b/src/test/cord-api/Framework/utils/utils.py
@@ -26,6 +26,7 @@
 import random
 import re
 import yaml
+import glob
 
 class utils(object):
 
@@ -41,6 +42,19 @@
         dataList = data[strListName]
         return dataList
 
+    def readFile(self, path, single=True):
+        dataDict = {}
+        for fileName in glob.glob(path):
+            print "Reading ", fileName
+            data = open(fileName).read()
+            dataDict[fileName] = data
+            if bool(single):
+                return data
+        return dataDict
+
+    def readFiles(self, path):
+        return self.readFile(path, single=False)
+
     '''
     @method compare_dict
     @Description: validates if contents of dict1 exists in dict2
@@ -260,37 +274,3 @@
             names['name']=i
             dnames.append(names.copy())
         return dnames
-
-'''
-#Test
-dict_list = {
- "humanReadableName": "cordSubscriber-17",
-        "id": 17,
-        "features": {
-            "uplink_speed": 1000000000,
-            "downlink_speed": 1000000000,
-            "status": "enabled"
-        },
-        "identity": {
-            "account_num": "20",
-            "name": "My House"
-        },
-        "related": {}
-    }
-input_dict = {
- "s_tag" : "111",
- "c_tag" : "222",
- "subscriber" : ""
- }
-new_value = 3
-test = utils()
-#data=test.jsonToList("Subscribers.json","SubscriberInfo")
-#print  test.jsonToList("Subscribers.json","SubscriberInfo")
-#print "index 1...",test.listToDict(data,1)
-#result = test.getDictFromListOfDict(dict_list,"email",21)
-#result = test.getFieldValueFromDict(dict_list,"id")
-#result = test.getDictFromListOfDict(dict_list,"account_num",21)
-#result = test.setFieldValueInDict(input_dict,"subscriber",new_value)
-result = test.getAllFieldValues(list1,"instance_name")
-print "finalllllll result....", result
-'''
diff --git a/src/test/cord-api/Framework/utils/utils.robot b/src/test/cord-api/Framework/utils/utils.robot
index 2bf46f8..db559e5 100644
--- a/src/test/cord-api/Framework/utils/utils.robot
+++ b/src/test/cord-api/Framework/utils/utils.robot
@@ -89,10 +89,18 @@
     ${output}=    Run    ${cmd}
     [Return]    ${output}
 
+Execute ONOS Command
+    [Arguments]    ${onos}    ${port}    ${cmd}    ${user}=karaf    ${pass}=karaf
+    ${conn_id}=    SSHLibrary.Open Connection    ${onos}    port=${port}    prompt=onos>    timeout=300s
+    SSHLibrary.Login    ${user}    ${pass}
+    ${output}=    SSHLibrary.Execute Command    ${cmd}
+    SSHLibrary.Close Connection
+    [Return]    ${output}
+
 Get Docker Container ID
-    [Arguments]    ${system}    ${container_name}    ${user}=${USER}    ${password}=${PASSWD}
-    [Documentation]    Retrieves the id of the requested docker container running inside given ${HOST}
-    ${container_id}=    Execute Command on CIAB Server in Specific VM    ${system}    head1    docker ps | grep ${container_name} | awk '{print $1}'    ${user}    ${password}
+    [Arguments]    ${container_name}
+    [Documentation]    Retrieves the id of the requested docker container running inside headnode
+    ${container_id}=     Run    docker ps | grep ${container_name} | awk '{print $1}'
     Log    ${container_id}
     [Return]    ${container_id}
 
@@ -114,8 +122,16 @@
 Remove Value From List
     [Arguments]    ${list}    ${val}
     ${length}=    Get Length    ${list}
-    : FOR    ${INDEX}    IN RANGE    0    ${length}-1
+    : FOR    ${INDEX}    IN RANGE    0    ${length}
     \    Log    ${list[${INDEX}]}
     \    ${value}=    Get Dictionary Values    ${list[${INDEX}]}
     \    Log    ${value[0]}
     \    Run Keyword If    '${value[0]}' == '${val}'    Remove From List    ${list}    ${INDEX}
+    \    Run Keyword If    '${value[0]}' == '${val}'    Exit For Loop
+
+Test Ping
+    [Arguments]    ${interface}    ${host}
+    [Documentation]    Ping hosts to check connectivity
+    ${result}=   Run    ping -I ${interface} -c 5 ${host}
+    Should Contain    ${result}    64 bytes
+    Should Not Contain    ${result}    Destination Host Unreachable
\ No newline at end of file
diff --git a/src/test/cord-api/Tests/Ch_DefaultServiceCheck.txt b/src/test/cord-api/Tests/Ch_DefaultServiceCheck.txt
index 2613475..6b73369 100644
--- a/src/test/cord-api/Tests/Ch_DefaultServiceCheck.txt
+++ b/src/test/cord-api/Tests/Ch_DefaultServiceCheck.txt
@@ -29,6 +29,7 @@
     ##need to remove openstack and onos from xos_services list in each manifest as these services arent treated as typical xos synchronizers
     utils.Remove Value From List    ${dynamicServiceList}    openstack
     utils.Remove Value From List    ${dynamicServiceList}    onos
+    utils.Remove Value From List    ${dynamicServiceList}    exampleservice
     Log    ${dynamicServiceList}
 
 Verify Service Sanity
diff --git a/src/test/diag/dockerContainers.json b/src/test/diag/dockerContainers.json
new file mode 100644
index 0000000..13c29c3
--- /dev/null
+++ b/src/test/diag/dockerContainers.json
@@ -0,0 +1,118 @@
+{
+    "docker-containers-rcord":
+    [
+        "allocator",
+        "generator",
+        "automation",
+        "provisioner",
+        "registry",
+        "harvester",
+        "registry-mirror",
+        "storage",
+        "switchq",
+        "mavenrepo",
+        "onosfabric_xos-onos_1",
+        "onoscord_xos-onos_1",
+        "rcord_consul_1",
+        "rcord_onos-synchronizer_1",
+        "rcord_xos_chameleon_1",
+        "rcord_xos_redis_1",
+        "rcord_xos_core_1",
+        "rcord_xos_tosca_1",
+        "rcord_registrator_1",
+        "rcord_xos_db_1",
+        "rcord_xos_ui_1",
+        "rcord_xos_gui_1",
+        "rcord_xos_ws_1",
+        "rcord_vrouter-synchronizer_1",
+        "rcord_exampleservice-synchronizer_1",
+        "rcord_vsg-synchronizer_1",
+        "rcord_vtn-synchronizer_1",
+        "rcord_vtr-synchronizer_1",
+        "rcord_fabric-synchronizer_1",
+        "rcord_openstack-synchronizer_1"
+    ],
+    "docker-containers-ecord-global":
+    [
+        "ecordglobal_consul_1",
+        "ecordglobal_onos-synchronizer_1",
+        "ecordglobal_xos_chameleon_1",
+        "ecordglobal_xos_redis_1",
+        "mavenrepo",
+        "ecordglobal_xos_core_1",
+        "ecordglobal_xos_tosca_1",
+        "onoscord_xos-onos_1",
+        "ecordglobal_registrator_1",
+        "ecordglobal_xos_db_1",
+        "ecordglobal_xos_ui_1",
+        "ecordglobal_vnaas-synchronizer_1",
+        "ecordglobal_xos_gui_1",
+        "ecordglobal_xos_ws_1"
+    ],
+    "docker-containers-ecord":
+    [
+        "allocator",
+        "generator",
+        "automation",
+        "provisioner",
+        "registry",
+        "harvester",
+        "registry-mirror",
+        "storage",
+        "switchq",
+        "ecord_onos-synchronizer_1",
+        "ecord_vrouter-synchronizer_1",
+        "ecord_addressmanager-synchronizer_1",
+        "ecord_consul_1",
+        "ecord_fabric-synchronizer_1",
+        "ecord_openstack-synchronizer_1",
+        "ecord_registrator_1",
+        "ecord_vee-synchronizer_1",
+        "ecord_veg-synchronizer_1",
+        "ecord_vrouter-synchronizer_1",
+        "ecord_vtn-synchronizer_1",
+        "ecord_xos_chameleon_1",
+        "ecord_xos_core_1",
+        "ecord_xos_db_1",
+        "ecord_xos_gui_1",
+        "ecord_xos_redis_1",
+        "ecord_xos_tosca_1",
+        "ecord_xos_ui_1",
+        "ecord_xos_ws_1",
+        "onoscord_xos-onos_1",
+        "onosfabric_xos-onos_1"
+    ],
+    "docker-containers-mcord-ng40":
+    [
+        "allocator",
+        "generator",
+        "automation",
+        "provisioner",
+        "registry",
+        "harvester",
+        "registry-mirror",
+        "storage",
+        "switchq",
+        "mavenrepo",
+        "mcordng40_xos_ws_1",
+        "mcordng40_xos_gui_1",
+        "mcordng40_xos_chameleon_1",
+	"mcordng40_xos_tosca_1",
+	"mcordng40_xos_ui_1",
+	"mcordng40_xos_core_1",
+	"mcordng40_openstack-synchronizer_1",
+	"mcordng40_vepc-synchronizer_1",
+	"mcordng40_vtn-synchronizer_1",
+	"mcordng40_vspgwc-synchronizer_1",
+	"mcordng40_fabric-synchronizer_1",
+	"mcordng40_venb-synchronizer_1",
+	"mcordng40_onos-synchronizer_1",
+	"mcordng40_vspgwu-synchronizer_1",
+	"mcordng40_xos_redis_1",
+	"mcordng40_xos_db_1",
+	"mcordng40_registrator_1",
+	"mcordng40_consul_1",
+	"onosfabric_xos-onos_1",
+	"onoscord_xos-onos_1"
+    ]
+}
diff --git a/src/test/diag/onosApps.json b/src/test/diag/onosApps.json
new file mode 100644
index 0000000..5ea01d7
--- /dev/null
+++ b/src/test/diag/onosApps.json
@@ -0,0 +1,93 @@
+{
+    "onos-fabric-rcord":
+    [
+        "org.onosproject.drivers",
+        "org.onosproject.segmentrouting",
+        "org.onosproject.optical-model",
+        "org.onosproject.fpm",
+        "org.onosproject.hostprovider",
+        "org.onosproject.lldpprovider",
+        "org.onosproject.fibinstaller",
+        "org.onosproject.cpr",
+        "org.onosproject.vrouter",
+        "org.onosproject.netcfghostprovider",
+        "org.onosproject.openflow-base",
+        "org.onosproject.openflow"
+    ],
+    "onos-cord-rcord":
+    [
+        "org.onosproject.drivers",
+        "org.onosproject.optical-model",
+        "org.onosproject.openflow-base",
+        "org.onosproject.ovsdb-base",
+        "org.onosproject.drivers.ovsdb",
+        "org.onosproject.dhcp",
+        "org.opencord.config",
+        "org.opencord.vtn"
+    ],
+    "onos-cord-ecord-global":
+    [
+        "org.onosproject.drivers",
+        "org.opencord.ce.api",
+        "org.opencord.ce.global.app"
+    ],
+    "onos-fabric-ecord":
+    [
+        "org.onosproject.drivers",
+        "org.onosproject.netcfghostprovider",
+        "org.onosproject.optical-model",
+        "org.onosproject.lldpprovider",
+        "org.onosproject.segmentrouting",
+        "org.onosproject.hostprovider",
+        "org.onosproject.openflow-base",
+        "org.onosproject.openflow",
+        "org.onosproject.fpm",
+        "org.opencord.ce.api",
+        "org.opencord.ce.local.bigswitch",
+        "org.opencord.ce.local.channel.http",
+        "org.opencord.ce.local.fabric"
+    ],
+    "onos-cord-ecord":
+    [
+        "org.onosproject.drivers",
+        "org.onosproject.ovsdb-base",
+        "org.onosproject.drivers.ovsdb",
+        "org.onosproject.faultmanagement",
+        "org.onosproject.netconf",
+        "org.onosproject.yang",
+        "org.onosproject.optical-model",
+        "org.onosproject.openflow-base",
+        "org.onosproject.config",
+        "org.onosproject.netconfsb",
+        "org.onosproject.drivers.netconf",
+        "org.onosproject.models.microsemi",
+        "org.onosproject.dhcp",
+        "org.opencord.ce.api",
+        "org.opencord.ce.local.bigswitch",
+        "org.opencord.ce.local.channel.http",
+        "org.opencord.ce.local.vee",
+        "org.opencord.config",
+        "org.opencord.vtn"
+    ],
+    "onos-fabric-mcord-ng40":
+    [
+        "org.onosproject.drivers",
+        "org.onosproject.optical-model",
+        "org.onosproject.openflow-base",
+        "org.onosproject.hostprovider",
+        "org.onosproject.netcfghostprovider",
+        "org.onosproject.lldpprovider",
+        "org.onosproject.openflow"
+    ],
+    "onos-cord-mcord-ng40":
+    [
+        "org.onosproject.drivers",
+        "org.onosproject.optical-model",
+        "org.onosproject.openflow-base",
+        "org.onosproject.dhcp",
+        "org.onosproject.ovsdb-base",
+        "org.onosproject.drivers.ovsdb",
+        "org.opencord.config",
+        "org.opencord.vtn"
+    ]
+}
diff --git a/src/test/diag/verifyCollectDiag.robot b/src/test/diag/verifyCollectDiag.robot
new file mode 100644
index 0000000..4dd3e6d
--- /dev/null
+++ b/src/test/diag/verifyCollectDiag.robot
@@ -0,0 +1,90 @@
+# Copyright 2017-present Radisys Corporation
+#
+# 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 suite for checking results collected by `make collect-diag` command
+Library           OperatingSystem
+Library           ../cord-api/Framework/utils/onosUtils.py
+Library           ../cord-api/Framework/utils/utils.py
+Resource          ../cord-api/Framework/utils/utils.robot
+
+*** Variables ***
+${DOCKER_CONTAINERS_FILE}       ${CURDIR}/dockerContainers.json
+${ONOS_APPS_FILE}       	${CURDIR}/onosApps.json
+${CORD_PROFILE}			rcord
+${CORD_SCENARIO}		cord
+
+*** Test Cases ***
+Verify Docker Containers
+    [Documentation]    Verify expected containers are up and running
+    ${dockerContainersExpected}    utils.jsonToList    ${DOCKER_CONTAINERS_FILE}    docker-containers-${CORD_PROFILE}
+    : FOR    ${container}    IN    @{dockerContainersExpected}
+    \    Run Keyword And Continue On Failure    Verify Docker Container    ${container}
+
+Verify Synchronizer Logs
+    [Documentation]    Verify synchronizer logs are correct
+    ${synchronizerLogs}    utils.readFiles    /home/cord/diag-*/docker/*synchronizer*
+    : FOR    ${key}    IN    @{synchronizerLogs.keys()}
+    \    @{name}=    Split String    ${key}    -synchronizer
+    \    @{name}=    Split String From Right   @{name}[0]    _    1
+    \    ${synchronizerLog}=    Get From Dictionary    ${synchronizerLogs}    ${key}
+    \    Run Keyword And Continue On Failure    Verify Synchronizer Log    ${name}    ${synchronizerLog}
+
+Verify ONOS
+    [Documentation]    Verify ONOS status, applications and logs
+    Run Keyword If    '${CORD_PROFILE}' != 'ecord-global'   Verify ONOS-Fabric    ${CORD_PROFILE}
+    Verify ONOS-CORD    ${CORD_PROFILE}
+
+*** Keywords ***
+Verify Docker Container
+    [Arguments]    ${container}
+    OperatingSystem.File Should Exist    /home/cord/diag-*/docker/${container}
+
+Verify Synchronizer Log
+    [Arguments]    ${name}    ${log}
+    ${config}    utils.readFile    /opt/cord/orchestration/xos_services/*/xos/synchronizer/@{name}[1]_config.yaml
+    ${match1}=    Get Lines Matching Regexp    ${config}    ^steps_dir: ".*"$
+    ${match2}=    Get Lines Matching Regexp    ${config}    ^model_policies_dir: ".*"$
+    Run Keyword If    '${match1}' != '${EMPTY}'    Should Contain    ${log}    Waiting for event or timeout    msg= "Waiting for event or timeout" not found in @{name}[1] synchronizer log
+    ...    ELSE IF    '${match2}' != '${EMPTY}'    Should Contain    ${log}    Loaded model policies    msg= "Loaded model policies" not found in @{name}[1] synchronizer log
+
+Verify ONOS-Fabric
+    [Arguments]    ${cord_profile}
+    Run Keyword And Continue On Failure    Verify ONOS Status    onos-fabric
+    Run Keyword And Continue On Failure    Verify ONOS Applications    onos-fabric    ${cord_profile}
+    Run Keyword And Continue On Failure    Verify ONOS Log    onos-fabric
+
+Verify ONOS-CORD
+    [Arguments]    ${cord_profile}
+    Run Keyword And Continue On Failure    Verify ONOS Status    onos-cord
+    Run Keyword And Continue On Failure    Verify ONOS Applications    onos-cord    ${cord_profile}
+    Run Keyword And Continue On Failure    Verify ONOS Log    onos-cord
+
+Verify ONOS Status
+    [Arguments]    ${onosName}
+    ${onosStatus}    utils.readFile    /home/cord/diag-*/${onosName}/nodes
+    Should Contain    ${onosStatus}    READY
+
+Verify ONOS Applications
+    [Arguments]    ${onosName}    ${cordProfile}
+    ${onosAppsExpected}    utils.jsonToList    ${ONOS_APPS_FILE}    ${onosName}-${cordProfile}
+    ${onosApps}    utils.readFile    /home/cord/diag-*/${onosName}/apps_-s_-a
+    : FOR    ${app}    IN    @{onosAppsExpected}
+    \    Should Contain    ${onosApps}    ${app}
+
+Verify ONOS Log
+    [Arguments]    ${onosName}
+    ${onosLog}    utils.readFile    /home/cord/diag-*/${onosName}/log_display
+    Should Not Contain    ${onosLog}    ERROR
diff --git a/src/test/robot/SanityPhyPOD.robot b/src/test/robot/SanityPhyPOD.robot
index 5899cbe..9e09072 100755
--- a/src/test/robot/SanityPhyPOD.robot
+++ b/src/test/robot/SanityPhyPOD.robot
@@ -1,18 +1,3 @@
-
-# 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.
-
 # Copyright 2017-present Radisys Corporation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,30 +13,99 @@
 # limitations under the License.
 
 
-
-
-
 *** Settings ***
-Documentation     Test suite for checking default maas,xos and onos containers and fabric switch default services and maas cli commands 
-Library       OperatingSystem
-Resource      ../cord-api/Framework/utils/utils.robot
+Documentation     Test suite for checking default maas,xos and onos containers and fabric switch default services and maas cli commands
+Library           OperatingSystem
+Library           ../cord-api/Framework/utils/onosUtils.py
+Library           ../cord-api/Framework/utils/utils.py
+Resource          ../cord-api/Framework/utils/utils.robot
 
 *** Variables ***
-@{MAAS_SERVICE_STATUS}    start/running    is running
-@{JUJU_SERVICE_STATUS}    active           is ready
-@{LXD_CONTAINER_STATUS}   RUNNING
-@{BOOT_RESOURCES_OUTPUT}  ubuntu/trusty
-${FABRIC_SWITCH_PROMPT}    #
-${FABRIC_SWITCH_USER}     root
-${FABRIC_SWITCH_PASSWD}    onl
-@{FABRIC_SERVICE_STATUS}    is running
-${IP_PATTERN}     (\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)
+@{MAAS_SERVICE_STATUS}        start/running    is running
+@{JUJU_SERVICE_STATUS}        active           is ready    unknown
+@{LXD_CONTAINER_STATUS}       RUNNING
+@{BOOT_RESOURCES_OUTPUT}      ubuntu/trusty
+${FABRIC_SWITCH_PROMPT}       \#
+${FABRIC_SWITCH_USER}         root
+${FABRIC_SWITCH_PASSWD}       onl
+@{FABRIC_SERVICE_STATUS}      is running
+${IP_PATTERN}                 (\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)
+${PUBLIC_IFACE}               eth2
+${NUM_OF_SWITCHES}            4
+${CORD_PROFILE}               rcord
+${FABRIC}                     on
+${DOCKER_CONTAINERS_FILE}     ${CURDIR}/../diag/dockerContainers.json
 
 *** Test Cases ***
-Verify headnode interfaces detected
-    Verify HeadNode Interfaces
+Verify Headnode Interfaces
+    [Tags]    fabric
+    [Documentation]    Verifies the headnode interface is up and has external connectivity
+    Verify HeadNode Interfaces Detected
+    Test Ping    ${PUBLIC_IFACE}    www.opennetworking.org
 
-Verify the state MAAS service
+Get Compute Node and Fabric Info
+    [Documentation]    Get all information pretaining to the compute nodes and fabric
+    ${nodes}=    Create List
+    ${hostnames}=    Create List
+    ${hostname_prefixes}=    Create List
+    ${node_ips}=    Create List
+    ${node_data_ips}=    Create List
+    ${node_count}    Run    cord prov list | grep node | wc -l
+    ${node_count}=    Convert To Integer    ${node_count}
+    Log    ${node_count}
+    ##Get hostname
+    : FOR    ${INDEX}    IN RANGE    1    ${node_count}+1
+    \    ${hostname}=    Run    cord prov list | grep node | awk '{print $2}' | sed -n ${INDEX}p
+    \    Append To List    ${hostnames}    ${hostname}
+    ##Get hostname prefixes
+    : FOR    ${INDEX}    IN RANGE    0    ${node_count}
+    \    ${hostname_prefix}=    Remove String    ${hostnames[${INDEX}]}    .cord.lab
+    \    Append To List    ${hostname_prefixes}    ${hostname_prefix}
+    ##Get compute node data ips
+    ${cordvtnnodes}=    ONOS Command Execute    onos-cord    8102    cordvtn-nodes | grep fabric
+    ${nds}=    Split To Lines    ${cordvtnnodes}
+    : FOR    ${i}    IN    @{nds}
+    \    ${data_ip}=    Get Compute Node IP    ${i}
+    \    Append To List    ${node_data_ips}    ${data_ip}
+    ##Get compute node ips
+    : FOR    ${i}    IN    @{hostname_prefixes}
+    \    ${node_ip}=    Run    cord harvest list | grep ${i} | awk '{print $4}'
+    \    Append To List    ${node_ips}    ${node_ip}
+    @{switch_ips}=    Discover FABRIC IPs
+    Set Suite Variable    ${switch_ips}
+    Set Suite Variable    ${hostnames}
+    Set Suite Variable    ${hostname_prefixes}
+    Set Suite Variable    ${node_ips}
+    Set Suite Variable    ${node_data_ips}
+
+Verify Compute Nodes Pingability Through Fabric
+    [Documentation]    Verifies that the two compute nodes can ping each other through the fabric
+    [Tags]    fabric
+    ##Verify pingablilty across compute nodes
+    : FOR    ${src}    IN    @{hostname_prefixes}
+    \    Ping All Compute Nodes Through Fabric    ${src}
+
+Verify Compute Nodes to Fabric Pingability
+    [Documentation]    Verifies that the two compute nodes can ping the switches
+    [Tags]    fabric
+    ##Verify pingability from compute nodes to fabric
+    : FOR    ${src}    IN    @{hostname_prefixes}
+    \    Ping All Fabric Switches    ${src}
+
+Verify CordVTN Nodes
+    [Documentation]    Verifies that the cordvtn app running in onos identifies the nodes and devices (fabric)
+    ${nodes}=    Execute ONOS Command    onos-cord    8102    cordvtn-nodes
+    : FOR    ${i}    IN    @{node_ips}
+    \    ${node_1}=    Get Lines Containing String    ${nodes}    ${i}
+    \    Run Keyword If    "${FABRIC}" == "on"    Verify CordVTN Node    ${node_1}    COMPLETE    ${i}
+    \    Run Keyword If    "${FABRIC}" == "off"    Verify CordVTN Node    ${node_1}    DEVICE_CREATED    ${i}
+    ${ports}=    Execute ONOS Command    onos-cord    8102    cordvtn-ports
+    ${devices}=    Execute ONOS Command    onos-fabric    8101    devices
+    @{switch_ips}=    Discover FABRIC IPs
+    : FOR    ${i}    IN    @{switch_ips}
+    \    Should Contain    ${devices}    ${i}
+
+Verify MAAS Service State
     [Template]     Verify MAAS Service
     maas-dhcpd
     maas-regiond
@@ -59,46 +113,12 @@
     maas-proxy
     bind9
 
-Verify the state of MAAS Containers
-    [Template]      Verify Containers   
-    cord-maas-automation    
-    cord-maas-switchq    
-    cord-provisioner    
-    cord-ip-allocator    
-    cord-dhcp-harvester
-    config-generator    
+Verify Docker Containers State
+    ${dockerContainers}    utils.jsonToList    ${DOCKER_CONTAINERS_FILE}    docker-containers-${CORD_PROFILE}
+    : FOR    ${container}    IN    @{dockerContainers}
+    \    Verify Containers    ${container}
 
-Verify the state of XOS Containers
-    [Template]      Verify Containers   
-    xos-gui    
-    xos-ws    
-    chameleon    
-    xos-ui
-    onos-synchronizer
-    vrouter-synchronizer
-    exampleservice-synchronizer
-    vsg-synchronizer    
-    gui-extension-rcord
-    gui-extension-vtr
-    vtn-synchronizer
-    vtr-synchronizer
-    fabric-synchronizer
-    openstack-synchronizer
-    xos-postgres
-
-Verify the state of ONOS Containers
-    [Template]      Verify Containers   
-    onosproject/onos
-    xos/onos
- 
-Verify the state of other Containers
-    [Template]      Verify Containers   
-    redis 
-    mavenrepo
-    registry-mirror
-    registry
-
-Verify the state of juju services
+Verify Juju Services State
     [Template]    Verify JUJU Service
     ceilometer
     ceilometer-agent
@@ -106,115 +126,130 @@
     keystone
     mongodb
     nagios
-    neturon-api
+    neutron-api
     nova-cloud-controller
     nova-compute
     openstack-dashboard
     percona-cluster
     rabbitmq-server
 
-Verify the state of openstack lxd containers
-    [Template]    Verify Openstack LXD Containers 
+Verify Openstack LXD Containers State
+    [Template]    Verify Openstack LXD Containers
     ceilometer
     glance
     keystone
     mongodb
     nagios
-    neutron-api 
+    neutron-api
     nova-cloud-controller
     openstack-dashboard
     percona-cluster
     rabbitmq-server
-    #testclient
 
 Verify MAAS CLI commands
+    [Tags]    notready
     Login MAAS Server
     Verify MAAS CLI Commands   boot-resources read | jq 'map(select(.type == "Synced"))'    ubuntu/trusty
-    Verify MAAS CLI Commands   devices list | jq '.' | jq '.[]'.hostname | wc -l     3 
-    #Verify MAAS CLI Commands   events query | jq '.' | jq .events[].id | wc -l    100 
+    Verify MAAS CLI Commands   devices list | jq '.' | jq '.[]'.hostname | wc -l     ${NUM_OF_SWITCHES}
+    #Verify MAAS CLI Commands   events query | jq '.' | jq .events[].id | wc -l    100
     Verify MAAS CLI Commands   fabrics read | jq '.' | jq .[].name | wc -l    4
     Verify MAAS CLI Commands   networks read | jq '.' | jq .[].name | wc -l    4
     Verify MAAS CLI Commands   node-groups list | jq '.' | jq .[].status | wc -l    1
     Verify MAAS CLI Commands   subnets read | jq '.' | jq .[].name | wc -l    4
     Verify MAAS CLI Commands   nodes list | jq '.' | jq .[].substatus_name | wc -l    1
-    Verify MAAS CLI Commands   zones read | jq '.' | jq .[].name | wc -l   2 
+    Verify MAAS CLI Commands   zones read | jq '.' | jq .[].name | wc -l   2
     Logout MAAS Server
 
 Verify Fabric Switch Service
-    ${fabric_ip}=    Discover FABRIC IP    ${FABRIC_SWITCH_MAC}   
-    Verify Fabric Switch Service    ${fabric_ip}    faultd
-    Verify Fabric Switch Service    ${fabric_ip}    netplug 
-    Verify Fabric Switch Service    ${fabric_ip}    ofdpa
-    Verify Fabric Switch Service    ${fabric_ip}    onlp-snmpd
-    Verify Fabric Switch Service    ${fabric_ip}    onlpd
-    Verify Fabric Switch Service    ${fabric_ip}    resolvconf 
-    Verify Fabric Switch Service    ${fabric_ip}    rsyslog
-    Verify Fabric Switch Service    ${fabric_ip}    snmpd 
-    Verify Fabric Switch Service    ${fabric_ip}    ssh 
-    Verify Fabric Switch Service    ${fabric_ip}    sxdkernel 
-    Verify Fabric Switch Service    ${fabric_ip}    udev 
-    Verify Fabric Switch Service    ${fabric_ip}    watchdog 
-
+    [Tags]    fabric
+    @{switch_ips}=    Discover FABRIC IPs
+    : FOR    ${i}    IN    @{switch_ips}
+    \    Verify Fabric Switch Service    ${i}    faultd
+    \    Verify Fabric Switch Service    ${i}    netplug
+    \    Verify Fabric Switch Service    ${i}    onlp-snmpd
+    \    Verify Fabric Switch Service    ${i}    onlpd
+    \    Verify Fabric Switch Service    ${i}    rsyslog
+    \    Verify Fabric Switch Service    ${i}    snmpd
+    \    Verify Fabric Switch Service    ${i}    ssh
+    \    Verify Fabric Switch Service    ${i}    udev
+    \    Verify Fabric Switch Service    ${i}    watchdog
 
 *** Keywords ***
-Verify HeadNode Interfaces
+Verify HeadNode Interfaces Detected
     ${cmd}=    Catenate    SEPARATOR=|   sudo ethtool mgmtbr    grep 'Link detected:'    awk '{ print $3 }'
-    ${output}=    Run     ${cmd} 
+    ${output}=    Run     ${cmd}
     Should Contain    ${output}    yes    msg= mgmtbr is not detected !!!. Reason:
     ${cmd}=    Catenate    SEPARATOR=|   sudo ethtool fabric    grep 'Link detected:'    awk '{ print $3 }'
-    ${output}=    Run     ${cmd} 
+    ${output}=    Run     ${cmd}
     Should Contain    ${output}    yes    msg= fabric interface is not detected !!!. Reason:
 
+Verify CordVTN Node
+    [Arguments]    ${node}    ${status}    ${ip}
+    Should Contain    ${node}    ${status}
+    Should Contain    ${node}    ${ip}
 
-Verify Containers 
-    [Arguments]    ${name} 
-    ${cmd}=    Catenate    SEPARATOR=|   docker ps -a  grep -v grep  grep ${name}    awk '{print $7,$8,$9,$10,$11}'     
-    ${output}=    Run     ${cmd} 
-    Should Contain    ${output}    Up    msg= ${name} is not running !!!. Reason:
+Verify Containers
+    [Arguments]    ${name}
+    ${container_id}=    Get Docker Container ID    ${name}
+    ${output}=    Run     docker inspect --format="{{ .State.Running }}" ${container_id}
+    Should Contain    ${output}    true    msg=${name} is not running !!!. Reason:
 
 Verify MAAS Service
     [Arguments]    ${name}
-    ${cmd}=    Catenate   sudo service    ${name}   status 
-    ${output}=    Run     ${cmd} 
+    ${cmd}=    Catenate   sudo service ${name} status
+    ${output}=    Run     ${cmd}
     Should Contain Any    ${output}    @{MAAS_SERVICE_STATUS}    msg= ${name} is not running !!!. Reason:
 
-
 Verify JUJU Service
     [Arguments]    ${name}
     ${cmd}    Catenate    SEPARATOR=|    juju status --format=tabular    grep -v grep    grep ${name}/0    awk '{ print $2,$7,$8,$9,$10}'
-    ${output}=    Run     ${cmd} 
+    ${output}=    Run     ${cmd}
     Should Contain Any    ${output}    @{JUJU_SERVICE_STATUS}    msg= ${name} is not running !!!. Reason:
 
 Verify Openstack LXD Containers
     [Arguments]    ${name}
     ${cmd}    Catenate    SEPARATOR=|    sudo lxc list    grep -v grep    grep ${name}-1    awk '{ print $2,$4 }'
-    ${output}=    Run     ${cmd} 
+    ${output}=    Run     ${cmd}
     Should Contain Any    ${output}    @{LXD_CONTAINER_STATUS}    msg= ${name} is not running !!!. Reason:
 
 Verify MAAS CLI Commands
     [Arguments]    ${name}    ${expected}
     ${cmd}    Catenate    maas cord ${name}
-    ${output}=    Run     ${cmd} 
-    Should Contain    ${output}    ${expected}    msg=Reason:   
+    ${output}=    Run     ${cmd}
+    Should Contain    ${output}    ${expected}    msg=Reason:
 
-Login MAAS Server 
-    ${cmd}   Catenate   maas login cord http://localhost/MAAS/api/1.0 $(sudo maas-region-admin apikey --user=cord) 
-    ${output}=    Run     ${cmd} 
+Login MAAS Server
+    ${cmd}   Catenate   maas login cord http://localhost/MAAS/api/1.0 $(sudo maas-region-admin apikey --user=cord)
+    ${output}=    Run     ${cmd}
     Should Contain   ${output}   You are now logged in to the MAAS  msg= MAAS login failure !!!. Reason:
 
-Logout MAAS Server 
-    ${cmd}   Catenate   maas logout cord 
-    ${output}=    Run     ${cmd} 
+Logout MAAS Server
+    ${cmd}   Catenate   maas logout cord
+    ${output}=    Run     ${cmd}
 
-Discover FABRIC IP
-    [Arguments]    ${fabric_mac}
-    ${cmd}   Catenate    SEPARATOR=|  cord switch list   grep -v IP   awk '{ print $3 }' 
-    ${output}=    Run     ${cmd} 
-    ${ret}=    Should Match Regexp    ${output}    ${IP_PATTERN}    msg="unable to get ip"   
-    [Return]   ${ret[0]} 
+Discover FABRIC IPs
+    ${switches}=    Run    cord prov list | grep fabric | awk '{print $4}'
+    @{switch_ips}=    Split To Lines    ${switches}
+    [Return]    ${switch_ips}
 
 Verify Fabric Switch Service
     [Arguments]    ${ip}    ${name}
-    ${cmd}=    Catenate    service   ${name}   status 
-    ${output}=    Run Command On Remote System    ${ip}    ${cmd}   ${FABRIC_SWITCH_USER}   ${FABRIC_SWITCH_PASSWD}    ${FABRIC_SWITCH_PROMPT}   60s   False 
+    ${cmd}=    Catenate    service   ${name}   status
+    ${output}=    Run Command On Remote System    ${ip}    ${cmd}   ${FABRIC_SWITCH_USER}   ${FABRIC_SWITCH_PASSWD}    ${FABRIC_SWITCH_PROMPT}   60s   False
     Should Contain Any    ${output}    @{FABRIC_SERVICE_STATUS}    msg= ${name} is not running !!!. Reason:
+
+Ping All Compute Nodes Through Fabric
+    [Arguments]    ${src_ip}
+    : FOR    ${dst_ip}    IN    @{node_data_ips}
+    \    Verify Ping    ubuntu    ${src_ip}    ${dst_ip}
+
+Ping All Fabric Switches
+    [Arguments]    ${src_ip}
+    : FOR    ${dst_ip}    IN    @{switch_ips}
+    \    Verify Ping    ubuntu    ${src_ip}    ${dst_ip}
+
+Verify Ping
+    [Arguments]    ${srcName}    ${srcIP}    ${dst}
+    ${result}=    Run    ssh ${srcName}@${srcIP} "ping -c 3 ${dst}"
+    Should Contain    ${result}    64 bytes
+    Should Not Contain    ${result}    Destination Host Unreachable
diff --git a/src/test/setup/requirements.txt b/src/test/setup/requirements.txt
index 57cdaed..71676b7 100644
--- a/src/test/setup/requirements.txt
+++ b/src/test/setup/requirements.txt
@@ -12,11 +12,12 @@
 robotframework-requests
 robotframework-sshlibrary
 robotframework-httplibrary
-paramiko==1.10.1
+paramiko==2.3.1
 twisted
 pexpect
 apiclient
 pyyaml
+pyopenssl
 #python-libmaas
 #maasclient
 #maasutil