CORD-1089 adding vtn service functionality tests against ciab environments

Change-Id: Ic2a277fa30ec7aaa02b7fb857ebab69fc98d4884
diff --git a/src/test/cord-api/Framework/utils/utils.py b/src/test/cord-api/Framework/utils/utils.py
index 1eaa299..fb1a797 100644
--- a/src/test/cord-api/Framework/utils/utils.py
+++ b/src/test/cord-api/Framework/utils/utils.py
@@ -6,6 +6,7 @@
 import robot
 import os.path
 from os.path import expanduser
+import uuid
 
 class utils(object):
 
@@ -213,6 +214,9 @@
            print "list of values found for ", fieldName, ";", uniq_list
         return fieldValue
 
+    def generate_uuid(self):
+        return uuid.uuid4()
+
 '''
 #Test
 dict_list = {
diff --git a/src/test/cord-api/Framework/utils/utils.robot b/src/test/cord-api/Framework/utils/utils.robot
new file mode 100644
index 0000000..0536a8a
--- /dev/null
+++ b/src/test/cord-api/Framework/utils/utils.robot
@@ -0,0 +1,74 @@
+*** Settings ***
+Documentation    Library for various utilities
+Library           SSHLibrary
+Library           HttpLibrary.HTTP
+Library           String
+Library           DateTime
+Library           Process
+Library           Collections
+Library           RequestsLibrary
+#Library           ${CURDIR}/readProperties.py
+#Resource          ${CURDIR}/utils.py
+
+*** Keywords ***
+Run Command On Remote System
+    [Arguments]    ${system}    ${cmd}    ${user}=${VM_USER}    ${pass}=${VM_PASS}    ${prompt}=$    ${prompt_timeout}=60s    ${use_key}=False
+    [Documentation]    SSH's into a remote host, executes command, and logs+returns output
+    BuiltIn.Log    Attempting to execute command "${cmd}" on remote system "${system}"
+    BuiltIn.Log    ${password}
+    ${conn_id}=    SSHLibrary.Open Connection    ${system}    prompt=${prompt}    timeout=${prompt_timeout}
+    Run Keyword If    '${use_key}' == 'False'    SSHLibrary.Login    ${user}    ${pass}    ELSE    SSHLibrary.Login With Public Key    ${user}    %{HOME}/.ssh/${SSH_KEY}    any
+    #SSHLibrary.Login    ${user}    ${pass}
+    ${output}=    SSHLibrary.Execute Command    ${cmd}
+    SSHLibrary.Close Connection
+    Log    ${output}
+    [Return]    ${output}
+
+Execute Command on CIAB Server in Specific VM
+    [Arguments]    ${system}    ${vm}    ${cmd}    ${user}=${VM_USER}    ${password}=${VM_PASS}    ${prompt}=$    ${use_key}=True
+    [Documentation]    SSHs into ${HOST} where CIAB is running and executes a command in the Prod Vagrant VM where all the containers are running
+    ${conn_id}=    SSHLibrary.Open Connection    ${system}    prompt=${prompt}    timeout=300s
+    Run Keyword If    '${use_key}' == 'False'    SSHLibrary.Login    ${user}    ${pass}    ELSE    SSHLibrary.Login With Public Key    ${user}    %{HOME}/.ssh/${SSH_KEY}    any
+    SSHLibrary.Write    ssh ${vm}
+    SSHLibrary.Read Until Prompt
+    SSHLibrary.Write    ${cmd}
+    ${output}=    SSHLibrary.Read Until Prompt
+    SSHLibrary.Close Connection
+    ${output}=    Get Line    ${output}    0
+    [Return]    ${output}
+
+Execute Command on Compute Node in CIAB
+    [Arguments]    ${system}    ${hostname}    ${cmd}    ${user}=${VM_USER}    ${password}=${VM_PASS}    ${prompt}=$    ${use_key}=True
+    [Documentation]    SSHs into ${HOST} where CIAB is running and executes a command in the Prod Vagrant VM where all the containers are running
+    ${conn_id}=    SSHLibrary.Open Connection    ${system}    prompt=${prompt}    timeout=300s
+    Run Keyword If    '${use_key}' == 'False'    SSHLibrary.Login    ${user}    ${pass}    ELSE    SSHLibrary.Login With Public Key    ${user}    %{HOME}/.ssh/${SSH_KEY}    any
+    SSHLibrary.Write    ssh prod
+    SSHLibrary.Read Until Prompt
+    SSHLibrary.Write    ssh root@${hostname}
+    SSHLibrary.Read Until    \#
+    SSHLibrary.Write    ${cmd}
+    ${output}=    SSHLibrary.Read Until   \#
+    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}    prod    docker ps | grep ${container_name} | awk '{print $1}'    ${user}    ${password}
+    Log    ${container_id}
+    [Return]    ${container_id}
+
+Get Docker Logs
+    [Arguments]    ${system}    ${container_id}    ${user}=${USER}    ${password}=${PASSWD}    ${prompt}=prod:~$
+    [Documentation]    Retrieves the id of the requested docker container running inside given ${HOST}
+    ##In Ciab, all containers are run in the prod vm so we must log into that
+    ${conn_id}=    SSHLibrary.Open Connection    ${system}    prompt=$    timeout=300s
+    SSHLibrary.Login With Public Key    ${USER}    %{HOME}/.ssh/${SSH_KEY}    any
+    #SSHLibrary.Login    ${HOST_USER}    ${HOST_PASSWORD}
+    SSHLibrary.Write    ssh prod
+    SSHLibrary.Read Until    ${prompt}
+    SSHLibrary.Write    docker logs -t ${container_id}
+    ${container_logs}=    SSHLibrary.Read Until    ${prompt}
+    SSHLibrary.Close Connection
+    Log    ${container_logs}
+    [Return]    ${container_logs}
\ No newline at end of file
diff --git a/src/test/cord-api/Tests/CordVTN.txt b/src/test/cord-api/Tests/CordVTN.txt
new file mode 100644
index 0000000..c9ee29e
--- /dev/null
+++ b/src/test/cord-api/Tests/CordVTN.txt
@@ -0,0 +1,234 @@
+*** Settings ***
+Documentation     Test suite for Utility Synchronizer API
+Suite Setup       Suite Setup
+Suite Teardown    Suite Teardown
+Variables         ../Framework/restApi.py
+Library           Collections
+Library           String
+Library           OperatingSystem
+Library           XML
+Library           RequestsLibrary
+Library           ../Framework/utils/utils.py
+Library           ../Framework/restApi.py
+Variables         ../Properties/RestApiProperties.py
+Resource           ../Framework/utils/utils.robot
+
+*** Variables ***
+${VM_USER}            admin
+${VM_PASS}            admin
+${SSH_KEY}            id_rsa.pub
+${ONOS_CORDVTN_API}   http://onos-cord:8182/onos/cordvtn
+
+*** Test Cases ***
+Get Compute Node Hostname + IP
+    [Documentation]    Logs into ciab server and executes a 'cord prov list' on the headnode to get the compute node
+    [Tags]    computenode
+    ${compute_node_hostname}=    Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    prod    cord prov list | grep node | awk '{print $2}'
+    ${compute_node_ip}=    Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    prod    cord prov list | grep node | awk '{print $4}'
+    Set Suite Variable    ${compute_node_hostname}
+    set suite variable    ${compute_node_ip}
+
+Get ONOSCORD Container ID
+    [Documentation]    Logs into ciab server and extracts the onoscord container id on the headnode
+    [Tags]    onoscord
+    ${onoscord_id}=    Get Docker Container ID    ${SERVER_IP}    onoscord    ${VM_USER}    ${VM_PASS}
+
+Validate Default OVS Flow Count
+    [Documentation]    Logs into the compute-node where OVS is running and validates the default flow count
+    [Tags]    ovsflows
+    ${ovs_flow_count}=    Execute Command on Compute Node in CIAB    ${SERVER_IP}    ${compute_node_hostname}    ovs-ofctl dump-flows br-int | wc -l
+    ${ovs_flow_count}=    Get Line    ${ovs_flow_count}    0
+    Should Be Equal As Integers    ${ovs_flow_count}    42
+
+Validate Default Flow Count in ONOS
+    [Documentation]    Validates the number of flows pushed down by onos (should match number flow count in ovs)
+    [Tags]    onosflows    notready
+    Log    Validating ONOS Flow Count
+
+Validate Current VTN Service Networks and Ports
+    [Documentation]    Makes rest calls to both XOS and ONOSCORD to validate the default VTN Service Networks + Ports
+    [Tags]    vtnservice
+    Validate Default CIAB Service Networks and Ports via XOS
+    ${serviceNetworks}=    Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    prod    curl -X GET -u karaf:karaf -H "Content-Type: application/json" http://onos-cord:8182/onos/cordvtn/serviceNetworks; echo
+    Validate Default CIAB Service Networks via ONOSCORD    ${serviceNetworks}
+    ${servicePorts}=    Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    prod    curl -X GET -u karaf:karaf -H "Content-Type: application/json" http://onos-cord:8182/onos/cordvtn/servicePorts; echo
+    Validate Default CIAB Service Ports via ONOSCORD    ${servicePorts}
+
+Create New VTN Service Network
+    [Documentation]    Makes a POST Request from the head-node to the ONOS Cord-VTN App to create a new service network
+    [Tags]    vtnservice
+    ${network_uuid}=    Generate UUID
+    Set Suite Variable    ${network_uuid}
+    ${networkCreation}=    Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    prod    curl -s -o /dev/null -w "\%{http_code}" -X POST -u karaf:karaf -H "Content-Type: application/json" -d '{"ServiceNetwork": {"id": "${network_uuid}", "type": "PRIVATE", "name": "APITEST", "segment_id": 2221, "subnet": "2.2.2.0/24", "service_ip": "2.2.2.1", "providers": [{"id": "${public_network_id}", "bidirectional": true}]}}' http://onos-cord:8182/onos/cordvtn/serviceNetworks; echo
+    Should Be Equal As Integers    ${networkCreation}    201
+    ${new_network}=    Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    prod    curl -X GET -u karaf:karaf -H "Content-Type: application/json" http://onos-cord:8182/onos/cordvtn/serviceNetworks/${network_uuid}; echo
+    Log    ${new_network}
+    ${name}=    Get Json Value    ${new_network}    /ServiceNetwork/name
+    ${type}=    Get Json Value    ${new_network}    /ServiceNetwork/type
+    ${segment_id}=    Get Json Value    ${new_network}    /ServiceNetwork/segment_id
+    ${subnet}=    Get Json Value    ${new_network}    /ServiceNetwork/subnet
+    ${service_ip}=    Get Json Value    ${new_network}    /ServiceNetwork/service_ip
+    Should Be Equal As Strings    ${name}    "APITEST"
+    Should Be Equal As Strings    ${type}    "PRIVATE"
+    Should Be Equal As Strings    ${segment_id}    2221
+    Should Be Equal As Strings    ${subnet}    "2.2.2.0/24"
+    Should Be Equal As Strings    ${service_ip}    "2.2.2.1"
+
+Create New VTN Service Port
+    [Documentation]    Makes a POST Request from the head-node to the ONOS Cord-VTN App to create a new service port for the newly created network
+    [Tags]    vtnservice
+    ${port_uuid}=    Generate UUID
+    Set Suite Variable    ${port_uuid}
+    ${networkCreation}=    Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    prod    curl -s -o /dev/null -w "\%{http_code}" -X POST -u karaf:karaf -H "Content-Type: application/json" -d '{"ServicePort": {"id": "${port_uuid}", "network_id": "${network_uuid}", "name": "APITESTPORT", "mac_address": "FA:16:3E:A8:A1:AA", "ip_address": "2.2.2.1", "floating_address_pairs":[{"ip_address":"3.3.3.1","mac_address":"02:42:0A:06:01:11"}]}}' http://onos-cord:8182/onos/cordvtn/servicePorts; echo
+    Should Be Equal As Integers    ${networkCreation}    201
+    ${new_port}=    Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    prod    curl -X GET -u karaf:karaf -H "Content-Type: application/json" http://onos-cord:8182/onos/cordvtn/servicePorts/${port_uuid}; echo
+    Log    ${new_port}
+    ${name}=    Get Json Value    ${new_port}    /ServicePort/name
+    ${netId}=    Get Json Value    ${new_port}    /ServicePort/network_id
+    ${mac_address}=    Get Json Value    ${new_port}    /ServicePort/mac_address
+    ${ip_address}=    Get Json Value    ${new_port}    /ServicePort/ip_address
+    ${floating_pairs}=    Get Json Value    ${new_port}    /ServicePort/floating_address_pairs
+    Should Be Equal As Strings    ${name}    "APITESTPORT"
+    Should Be Equal As Strings    ${netId}    "${network_uuid}"
+    Should Be Equal As Strings    ${mac_address}    "FA:16:3E:A8:A1:AA"
+    Should Be Equal As Strings    ${ip_address}    "2.2.2.1"
+
+Validate New Flows Pushed to OVS
+    [Documentation]    Logs into the compute-node where OVS is running and validates the default flow count
+    [Tags]    vtnservice
+    ${ovs_flow_count}=    Execute Command on Compute Node in CIAB    ${SERVER_IP}    ${compute_node_hostname}    ovs-ofctl dump-flows br-int | grep 2.2.2.0 | wc -l
+    ${ovs_flow_count}=    Get Line    ${ovs_flow_count}    0
+    Should Be Equal As Integers    ${ovs_flow_count}    3
+    ${flows_added}=    Execute Command on Compute Node in CIAB    ${SERVER_IP}    ${compute_node_hostname}    ovs-ofctl dump-flows br-int
+    ${flows_added}=    Get Lines Containing String    ${flows_added}    cookie=
+    Log    ${flows_added}
+    ## Match src/dst (bi-directional) rules on new flows added
+    Should Contain    ${flows_added}    nw_src=2.2.2.0/24,nw_dst=10.6.1.192/26
+    Should Contain    ${flows_added}    nw_src=10.6.1.192/26,nw_dst=2.2.2.0/24
+    Should Contain    ${flows_added}    nw_src=2.2.2.0/24,nw_dst=10.6.1.193
+
+Delete VTN Service Port
+    [Documentation]    Makes a DELETE Request from the head-node to the ONOS Cord-VTN App to delete the new service port
+    [Tags]    vtnservice
+    ${networkDeletion}=    Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    prod    curl -s -o /dev/null -w "\%{http_code}" -X DELETE -u karaf:karaf -H "Content-Type: application/json" http://onos-cord:8182/onos/cordvtn/servicePorts/${port_uuid}; echo
+    Should Be Equal As Integers    ${networkDeletion}    204
+    ${get_port}=    Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    prod    curl -s -o /dev/null -w "\%{http_code}" -X GET -u karaf:karaf -H "Content-Type: application/json" http://onos-cord:8182/onos/cordvtn/servicePorts/${port_uuid}; echo
+    Should Be Equal As Integers    ${get_port}    404
+
+Delete VTN Service Network
+    [Documentation]    Makes a DELETE Request from the head-node to the ONOS Cord-VTN App to delete the created service network
+    [Tags]    vtnservice
+    ${networkDeletion}=    Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    prod    curl -s -o /dev/null -w "\%{http_code}" -X DELETE -u karaf:karaf -H "Content-Type: application/json" http://onos-cord:8182/onos/cordvtn/serviceNetworks/${network_uuid}; echo
+    Should Be Equal As Integers    ${networkDeletion}    204
+    ${get_network}=    Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    prod    curl -s -o /dev/null -w "\%{http_code}" -X GET -u karaf:karaf -H "Content-Type: application/json" http://onos-cord:8182/onos/cordvtn/serviceNetworks/${network_uuid}; echo
+    Should Be Equal As Integers    ${get_network}    404
+
+Validate New Flows Removed From OVS
+    [Documentation]    Validates that the flow rules added by ONOS from the network creation has been removed
+    [Tags]    vtnservice
+    ${ovs_flow_count}=    Execute Command on Compute Node in CIAB    ${SERVER_IP}    ${compute_node_hostname}    ovs-ofctl dump-flows br-int | grep 2.2.2.0 | wc -l
+    ${ovs_flow_count}=    Get Line    ${ovs_flow_count}    0
+    Should Be Equal As Integers    ${ovs_flow_count}    0
+    ${flows_added}=    Execute Command on Compute Node in CIAB    ${SERVER_IP}    ${compute_node_hostname}    ovs-ofctl dump-flows br-int
+    ${flows_added}=    Get Lines Containing String    ${flows_added}    cookie=
+    Log    ${flows_added}
+    ## Validate flow rules arent in the flows table
+    Should Not Contain    ${flows_added}    nw_src=2.2.2.0/24,nw_dst=10.6.1.192/26
+    Should Not Contain    ${flows_added}    nw_src=10.6.1.192/26,nw_dst=2.2.2.0/24
+    Should Not Contain    ${flows_added}    nw_src=2.2.2.0/24,nw_dst=10.6.1.193
+
+*** Keywords ***
+Suite Setup
+    ${auth} =    Create List    ${USER}    ${PASSWD}
+    Create Session    ${SERVER_IP}    http://${SERVER_IP}:${SERVER_PORT}    auth=${AUTH}
+
+Suite Teardown
+    Delete All Sessions
+    Close All Connections
+
+CORD Get
+    [Documentation]    Make a rest call to the CORD controller
+    [Arguments]    ${session}    ${service}
+    ${resp}=    Get Request    ${session}    ${service}
+    Log    ${resp.content}
+    [Return]    ${resp}
+
+Validate Default CIAB Service Networks and Ports via XOS
+    [Documentation]    Using XOS API, this validates the default VTN Service Networks + Ports for a CIAB Environment
+    @{expected_types}=    Create List    PUBLIC    PRIVATE    MANAGEMENT_LOCAL    VSG
+    @{expected_owner_slices}=    Create List    mysite_public    mysite_exampleservice    mysite_management    mysite_vsg
+    @{expected_network_names}=    Create List    public    management    exampleservice_network    mysite_vsg-access
+    @{types}=    Create List
+    @{ownerSlices}=    Create List
+    @{network_names}=    Create List
+    ${resp}=    CORD GET    ${SERVER_IP}    /api/service/vtn/serviceNetworks/
+    Should Be Equal As Strings    ${resp.status_code}    200
+    ${jsondata}=    To Json    ${resp.content}
+    ${length}=    Get Length    ${jsondata['serviceNetworks']}
+    Should Be Equal As Integers    ${length}    4
+    : FOR    ${INDEX}    IN RANGE    0    ${length}
+    \    ${item}=    Get From List    ${jsondata['serviceNetworks']}    ${INDEX}
+    \    ${type}=    Get From Dictionary    ${item}    type
+    \    ${ownerSliceName}=    Get From Dictionary    ${item}    ownerSliceName
+    \    Append To List    ${types}    ${type}
+    \    Append To List    ${ownerSlices}    ${ownerSliceName}
+    : FOR    ${value}    IN    @{expected_types}
+    \    List Should Contain Value    ${types}    ${value}
+    : FOR    ${value}    IN    @{expected_owner_slices}
+    \    List Should Contain Value    ${ownerSlices}    ${value}
+    ${resp}=    CORD GET    ${SERVER_IP}    /api/service/vtn/servicePorts/
+    Should Be Equal As Strings    ${resp.status_code}    200
+    ${jsondata}=    To Json    ${resp.content}
+    ${length}=    Get Length    ${jsondata['servicePorts']}
+    Should Be Equal As Integers    ${length}    5
+    : FOR    ${INDEX}    IN RANGE    0    ${length}
+    \    ${item}=    Get From List    ${jsondata['servicePorts']}    ${INDEX}
+    \    ${network_name}=    Get From Dictionary    ${item}    network_name
+    \    Append To List    ${network_names}    ${network_name}
+    : FOR    ${value}    IN    @{expected_network_names}
+    \    List Should Contain Value    ${network_names}    ${value}
+    ${management_len}=    Count Values in List    ${network_names}    management
+    Should Be Equal As Integers    ${management_len}    2
+
+Validate Default CIAB Service Networks via ONOSCORD
+    [Documentation]    Validates the default VTN Service Network via ONOSCORD for a CIAB Environment
+    [Arguments]    ${jsondata}
+    @{network_ids}=    Create List
+    @{expected_types}=    Create List    PUBLIC    PRIVATE    MANAGEMENT_LOCAL    VSG
+    @{expected_names}=    Create List    public    exampleservice_network    management    mysite_vsg-access
+    @{types}=    Create List
+    @{names}=    Create List
+    ${jsondata}=    To Json    ${jsondata}
+    ${length}=    Get Length    ${jsondata['ServiceNetworks']}
+    Should Be Equal As Integers    ${length}    4
+    : FOR    ${INDEX}    IN RANGE    0    ${length}
+    \    ${item}=    Get From List    ${jsondata['ServiceNetworks']}    ${INDEX}
+    \    ${network_id}=    Get From Dictionary    ${item}    id
+    \    ${type}=    Get From Dictionary    ${item}    type
+    \    ${name}=    Get From Dictionary    ${item}    name
+    \    Append To List    ${network_ids}    ${network_id}
+    \    Append To List    ${types}    ${type}
+    \    Append To List    ${names}    ${name}
+    \    Run Keyword If    "${name}" == "management"    Set Suite Variable    ${management_network_id}    ${network_id}
+    \    Run Keyword If    "${name}" == "public"    Set Suite Variable    ${public_network_id}    ${network_id}
+    : FOR    ${value}    IN    @{expected_types}
+    \    List Should Contain Value    ${types}    ${value}
+    : FOR    ${value}    IN    @{expected_names}
+    \    List Should Contain Value    ${names}    ${value}
+    Set Suite Variable    ${network_ids}
+
+Validate Default CIAB Service Ports via ONOSCORD
+    [Documentation]    Validates the default VTN Service Ports via ONOSCORD for a CIAB Environment
+    [Arguments]    ${jsondata}
+    ${net_ids}=    Create List
+    ${jsondata}=    To Json    ${jsondata}
+    ${length}=    Get Length    ${jsondata['ServicePorts']}
+    Should Be Equal As Integers    ${length}    5
+    : FOR    ${INDEX}    IN RANGE    0    ${length}
+    \    ${item}=    Get From List    ${jsondata['ServicePorts']}    ${INDEX}
+    \    ${net_id}=    Get From Dictionary    ${item}    network_id
+    \    Append To List    ${net_ids}    ${net_id}
+    : FOR    ${value}    IN    @{net_ids}
+    \    List Should Contain Value    ${network_ids}    ${value}
+    ${management_len}=    Count Values in List    ${net_ids}    ${management_network_id}
+    Should Be Equal As Integers    ${management_len}    2