Add SFC Tests 08/72108/64
authorgvrangan <venkatrangang@hcl.com>
Mon, 21 May 2018 20:29:08 +0000 (01:59 +0530)
committerVenkatrangan Govindarajan <venkatrangang@hcl.com>
Thu, 6 Sep 2018 06:44:52 +0000 (06:44 +0000)
- Tests the SFC Functionality
- Creates the configuration with one Service Function
  and ensures packet traverses via the SF
- Creates the symmeteric Chain configuration
  and tests the functionality

Change-Id: I74fbbd0f3c64f7676dbc50ff372493a71c84fc6b
Signed-off-by: gvrangan <venkatrangang@hcl.com>
csit/libraries/OpenStackOperations.robot
csit/libraries/Utils.robot
csit/suites/openstack/extensions/sfc.robot
csit/variables/Variables.robot

index 6f050e5838cf6c2006f3ba1551a24cdc6476c5d6..8ad82b621890c514dab858bfe0e5e6a0b394c137 100644 (file)
@@ -199,10 +199,39 @@ Get Router Id
     ${router_id} =    Collections.Get from List    ${splitted_output}    0
     [Return]    ${router_id}
 
+Add New Image From Url
+    [Arguments]    ${image_url}    ${image_name}
+    [Documentation]    To add new qcow2 images for testing.
+    ${rc}    ${output} =    OperatingSystem.Run And Return Rc And Output    wget ${image_url} -O /tmp/new_image.qcow2
+    BuiltIn.Log    ${output}
+    BuiltIn.Should Be True    '${rc}' == '0'
+    ${output} =    OpenStack CLI    openstack image create ${image_name} --file /tmp/new_image.qcow2 --disk-format qcow2 --container-format bare --public
+
+Create Flavor
+    [Arguments]    ${flavor_name}    ${ram_in_mb}    ${disk_in_gb}    ${ncpu}=1
+    [Documentation]    To create new flavors for instance deployment and testing
+    ${output} =    OpenStack CLI    openstack flavor create ${flavor_name} --ram ${ram_in_mb} --disk ${disk_in_gb} --vcpus ${ncpu}
+
+Create Keypair
+    [Arguments]    ${keyname}    ${public_key_file}
+    [Documentation]    To add keypairs to Openstack that can be used when ssh to instances using publickey authentication
+    ${output} =    OpenStack CLI    openstack keypair create ${keyname} --public-key ${public_key_file}
+
+Generate And Add Keypair
+    [Arguments]    ${keyname}    ${keyfilename}
+    [Documentation]    To generate keypair using ssh-keygen and add them to Openstack
+    ${result} =    Process.Run Process    ssh-keygen -b 2048 -t rsa -f ${JENKINS_WORKSPACE}/${keyfilename} -q -N ""    shell=True
+    BuiltIn.Log    ${result.stdout}
+    BuiltIn.Log    ${result.stderr}
+    BuiltIn.Should Be True    '${result.rc}' == '0'
+    OpenStackOperations.Create Keypair    ${keyname}    ${JENKINS_WORKSPACE}/${keyfilename}.pub
+    OpenStackOperations.Get ControlNode Connection
+    SSHLibrary.Put_File    ${JENKINS_WORKSPACE}/${keyfilename}    /tmp
+
 Create Vm Instances
     [Arguments]    ${net_name}    ${vm_instance_names}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default    ${min}=1
-    ...    ${max}=1
     [Documentation]    Create X Vm Instance with the net id of the Netowrk.
+    ..    ${max}=1
     ${image}    BuiltIn.Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
     ${net_id} =    OpenStackOperations.Get Net Id    ${net_name}
     : FOR    ${vm}    IN    @{vm_instance_names}
@@ -219,28 +248,30 @@ Create Vm Instance With Port
     [Arguments]    ${port_name}    ${vm_instance_name}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
     [Documentation]    Create One VM instance using given ${port_name} and for given ${compute_node}
     ${image} =    BuiltIn.Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
-    ${port_id} =    OpenStackOperations.Get Port Id    ${port_name}
-    ${output} =    OpenStack CLI    openstack server create --image ${image} --flavor ${flavor} --nic port-id=${port_id} ${vm_instance_name} --security-group ${sg}
+    ${output} =    OpenStack CLI    openstack server create --image ${image} --flavor ${flavor} --port ${port_name} --security-group ${sg} ${vm_instance_name}
 
-Create Vm Instance With Ports
-    [Arguments]    ${port_name}    ${port2_name}    ${vm_instance_name}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
-    [Documentation]    Create One VM instance using given ${port_name} and for given ${compute_node}
+Create Vm Instance With Ports And Key On Compute Node
+    [Arguments]    ${port1_name}    ${port2_name}    ${vm_instance_name}    ${node_hostname}    ${image}=${EMPTY}    ${flavor}=m1.nano
+    ...    ${sg}=default    ${keyname}=${EMPTY}
+    [Documentation]    Create One VM instance using given ${port1_name} and ${port2_name} with keyname for ssh and also on a specific compute node
     ${image}    BuiltIn.Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
-    ${port_id} =    OpenStackOperations.Get Port Id    ${port_name}
-    ${port2_id} =    OpenStackOperations.Get Port Id    ${port2_name}
-    ${output} =    OpenStack CLI    openstack server create --image ${image} --flavor ${flavor} --nic port-id=${port_id} --nic port-id=${port2_id} ${vm_instance_name} --security-group ${sg}
+    ${output} =    OpenStack CLI    openstack server create --image ${image} --flavor ${flavor} --port ${port1_name} --port ${port2_name} ${vm_instance_name} --security-group ${sg} --availability-zone nova:${node_hostname} --key-name ${keyname}
 
 Create Vm Instance With Port On Compute Node
     [Arguments]    ${port_name}    ${vm_instance_name}    ${node_hostname}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
     [Documentation]    Create One VM instance using given ${port_name} and for given ${node_hostname}
     ${image} =    BuiltIn.Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
-    ${port_id} =    OpenStackOperations.Get Port Id    ${port_name}
-    ${output} =    OpenStack CLI    openstack server create --image ${image} --flavor ${flavor} --nic port-id=${port_id} --security-group ${sg} --availability-zone nova:${node_hostname} ${vm_instance_name}
+    ${output} =    OpenStack CLI    openstack server create --image ${image} --flavor ${flavor} --port ${port_name} --security-group ${sg} --availability-zone nova:${node_hostname} ${vm_instance_name}
+
+Remove Security Group From Vm Instance
+    [Arguments]    ${vm_instance_name}    ${security_group}
+    [Documentation]    Delete the Security Group from the VM Instance.
+    ${output} =    OpenStack CLI    openstack server remove security group ${vm_instance_name} ${security_group}
 
 Create Vm Instance With Ports On Compute Node
     [Arguments]    ${port1_name}    ${port2_name}    ${vm_instance_name}    ${node_hostname}    ${image}=${EMPTY}    ${flavor}=m1.nano
     ...    ${sg}=default
-    [Documentation]    Create One VM instance using given ${port1_name}, ${port2_name} and for given ${node_hostname}
+    [Documentation]    Create One VM instance using given ${port1_name}, ${port2_name} and for given ${node_hostname} with no keys (cirros like)
     ${image} =    BuiltIn.Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
     ${port1_id} =    OpenStackOperations.Get Port Id    ${port1_name}
     ${port2_id} =    OpenStackOperations.Get Port Id    ${port2_name}
@@ -293,6 +324,27 @@ Get VM IP
     BuiltIn.Run Keyword If    '${fail_on_none}' == 'true'    BuiltIn.Should Not Contain    ${dhcp_ip}    None
     [Return]    ${vm_ip}    ${dhcp_ip}    ${vm_console_output}
 
+Verify If Instance Is Arpingable From DHCP Namespace
+    [Arguments]    ${net_name}    ${mac}    ${ip}
+    [Documentation]    Get the Port IP and check the arp -a from DHCP NS to ensure that the VM's have been assigned IP's
+    OpenStackOperations.Get ControlNode Connection
+    ${net_id} =    OpenStackOperations.Get Net Id    ${net_name}
+    ${output} =    Utils.Write Commands Until Expected Prompt    sudo ip netns exec qdhcp-${net_id} arping ${ip} -c3    ${DEFAULT_LINUX_PROMPT_STRICT}    timeout=60s
+    ${mac_uppercase} =    String.Convert To Upper Case    ${mac}
+    BuiltIn.Should Contain    ${output}    [${mac_uppercase}]
+
+Check If Instance Is Ready For Ssh Login Using PublicKey
+    [Arguments]    ${net_name}    ${vm_ip}    ${user}=centos    ${idfile}=/tmp/odlkey
+    [Documentation]    Ensure the VM is reachable from ssh as tests would require. This keyword will use publickey authentication
+    ${output} =    Execute Command on VM Instance with PublicKey Auth    ${net_name}    ${vm_ip}    ifconfig    user=${user}    idfile=${idfile}
+    BuiltIn.Should Contain    ${output}    ${vm_ip}
+
+Check If Instance Is Ready For Ssh Login Using Password
+    [Arguments]    ${net_name}    ${vm_ip}    ${user}=cirros
+    [Documentation]    Ensure the VM is reachable from ssh as tests would require. This keyword will use password authentication
+    ${output} =    Execute Command on VM Instance    ${net_name}    ${vm_ip}    ifconfig
+    BuiltIn.Should Contain    ${output}    ${vm_ip}
+
 Get VM IPs
     [Arguments]    @{vms}
     [Documentation]    Get the instance IP addresses and nameserver address for the list of given vms.
@@ -390,14 +442,13 @@ Close Vm Instance
     ${output} =    DevstackUtils.Write Commands Until Prompt And Log    exit
 
 Check If Console Is VmInstance
-    [Arguments]    ${console}=cirros
     [Documentation]    Check if the session has been able to login to the VM instance
     ${output} =    Utils.Write Commands Until Expected Prompt    id    ${OS_SYSTEM_PROMPT}
-    BuiltIn.Should Contain    ${output}    ${console}
+    BuiltIn.Should Not Contain    ${output}    jenkins
 
 Exit From Vm Console
     [Documentation]    Check if the session has been able to login to the VM instance and exit the instance
-    ${rcode} =    BuiltIn.Run Keyword And Return Status    OpenStackOperations.Check If Console Is VmInstance    cirros
+    ${rcode} =    BuiltIn.Run Keyword And Return Status    OpenStackOperations.Check If Console Is VmInstance
     BuiltIn.Run Keyword If    ${rcode}    DevstackUtils.Write Commands Until Prompt    exit
 
 Check Ping
@@ -420,17 +471,36 @@ Check Metadata Access
     BuiltIn.Should Contain    ${output}    200
 
 Execute Command on VM Instance
-    [Arguments]    ${net_name}    ${vm_ip}    ${cmd}    ${user}=cirros    ${password}=cubswin:)
+    [Arguments]    ${net_name}    ${vm_ip}    ${cmd}    ${user}=cirros    ${password}=cubswin:)    ${cmd_timeout}=30s
     [Documentation]    Login to the vm instance using ssh in the network, executes a command inside the VM and returns the ouput.
     OpenStackOperations.Get ControlNode Connection
     ${net_id} =    OpenStackOperations.Get Net Id    ${net_name}
-    ${output} =    Utils.Write Commands Until Expected Prompt    sudo ip netns exec qdhcp-${net_id} ssh ${user}@${vm_ip} -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null    password:
+    ${output} =    Utils.Write Commands Until Expected Prompt    sudo ip netns exec qdhcp-${net_id} ssh ${user}@${vm_ip} -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=password    password:
     ${output} =    Utils.Write Commands Until Expected Prompt    ${password}    ${OS_SYSTEM_PROMPT}
     ${rcode} =    BuiltIn.Run Keyword And Return Status    OpenStackOperations.Check If Console Is VmInstance
+    ${output} =    BuiltIn.Run Keyword If    ${rcode}    Utils.Write Commands Until Expected Prompt    ${cmd}    ${OS_SYSTEM_PROMPT}    timeout=${cmd_timeout}
+    [Teardown]    Exit From Vm Console
+    [Return]    ${output}
+
+Execute Command on VM Instance With PublicKey Auth
+    [Arguments]    ${net_name}    ${vm_ip}    ${cmd}    ${user}=centos    ${idfile}=/tmp/odlkey
+    [Documentation]    Login to the vm instance using ssh publickey in the network, executes a command inside the VM and returns the ouput.
+    OpenStackOperations.Get ControlNode Connection
+    ${net_id} =    OpenStackOperations.Get Net Id    ${net_name}
+    ${output} =    Utils.Write Commands Until Expected Prompt    sudo ip netns exec qdhcp-${net_id} ssh -i ${idfile} ${user}@${vm_ip} -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=publickey    prompt=${OS_SYSTEM_PROMPT}    timeout=60s
+    ${rcode} =    BuiltIn.Run Keyword And Return Status    OpenStackOperations.Check If Console Is VmInstance
     ${output} =    BuiltIn.Run Keyword If    ${rcode}    Utils.Write Commands Until Expected Prompt    ${cmd}    ${OS_SYSTEM_PROMPT}
     [Teardown]    Exit From Vm Console
     [Return]    ${output}
 
+Copy File To VM Instance With PublicKey Auth
+    [Arguments]    ${net_name}    ${vm_ip}    ${file_to_copy}    ${user}=centos    ${idfile}=/tmp/odlkey
+    [Documentation]    Login to the vm instance using ssh publickey in the network, executes a command inside the VM and returns the ouput.
+    OpenStackOperations.Get ControlNode Connection
+    ${net_id} =    OpenStackOperations.Get Net Id    ${net_name}
+    ${rc} =    SSHLibrary.Execute Command    sudo ip netns exec qdhcp-${net_id} scp -i ${idfile} -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=publickey ${file_to_copy} ${user}@${vm_ip}:/tmp/    return_stdout=False    return_rc=True
+    BuiltIn.Should Be True    '${rc}' == '0'
+
 Test Operations From Vm Instance
     [Arguments]    ${net_name}    ${src_ip}    ${dest_ips}    ${user}=cirros    ${password}=cubswin:)    ${ttl}=64
     ...    ${ping_should_succeed}=True    ${check_metadata}=True
@@ -842,23 +912,21 @@ Remove Security Group From VM
     ${output} =    OpenStack CLI    openstack server remove security group ${vm} ${sg}
 
 Create SFC Flow Classifier
-    [Arguments]    ${name}    ${src_ip}    ${dest_ip}    ${protocol}    ${dest_port}    ${neutron_src_port}
+    [Arguments]    ${name}    ${src_ip}    ${dest_ip}    ${protocol}    ${neutron_src_port}    ${args}=${EMPTY}
     [Documentation]    Create a flow classifier for SFC
-    ${output} =    OpenStack CLI    openstack sfc flow classifier create --ethertype IPv4 --source-ip-prefix ${src_ip}/32 --destination-ip-prefix ${dest_ip}/32 --protocol ${protocol} --destination-port ${dest_port}:${dest_port} --logical-source-port ${neutron_src_port} ${name}
+    ${output} =    OpenStack CLI    openstack sfc flow classifier create --ethertype IPv4 --source-ip-prefix ${src_ip}/32 --destination-ip-prefix ${dest_ip}/32 --protocol ${protocol} --logical-source-port ${neutron_src_port} ${args} ${name}
     BuiltIn.Should Contain    ${output}    ${name}
     [Return]    ${output}
 
 Delete SFC Flow Classifier
     [Arguments]    ${name}
     [Documentation]    Delete a SFC flow classifier
-    OpenStackOperations.Get ControlNode Connection
     ${output} =    OpenStack CLI    openstack sfc flow classifier delete ${name}
     [Return]    ${output}
 
 Create SFC Port Pair
     [Arguments]    ${name}    ${port_in}    ${port_out}
     [Documentation]    Creates a neutron port pair for SFC
-    OpenStackOperations.Get ControlNode Connection
     ${output} =    OpenStack CLI    openstack sfc port pair create --ingress=${port_in} --egress=${port_out} ${name}
     BuiltIn.Should Contain    ${output}    ${name}
     [Return]    ${output}
@@ -891,12 +959,24 @@ Delete SFC Port Pair Group
     [Return]    ${output}
 
 Create SFC Port Chain
-    [Arguments]    ${name}    ${pg1}    ${pg2}    ${fc}
+    [Arguments]    ${name}    ${args}=${EMPTY}
     [Documentation]    Creates a port pair chain with two port groups and a singel classifier.
-    ${output} =    OpenStack CLI    openstack sfc port chain create --port-pair-group ${pg1} --port-pair-group ${pg2} --flow-classifier ${fc} ${name}
+    ${output} =    OpenStack CLI    openstack sfc port chain create ${name} ${args}
     BuiltIn.Should Contain    ${output}    ${name}
     [Return]    ${output}
 
+Update SFC Port Chain With A New Flow Classifier
+    [Arguments]    ${name}    ${fc}
+    [Documentation]    Adds a Flow Classifier to a Port Chain
+    ${output} =    OpenStack CLI    openstack sfc port chain set ${name} --flow-classifier ${fc}
+    [Return]    ${output}
+
+Update SFC Port Chain Removing A Flow Classifier
+    [Arguments]    ${name}    ${fc}
+    [Documentation]    Adds a Flow Classifier to a Port Chain
+    ${output} =    OpenStack CLI    openstack sfc port chain unset ${name} --flow-classifier ${fc}
+    [Return]    ${output}
+
 Delete SFC Port Chain
     [Arguments]    ${name}
     [Documentation]    Delete a SFC port chain
index dffd25f96f54916ad85ceea927b6d377a13b6815..186f6ac3c76771e269a392cf99aae27d04581c1e 100644 (file)
@@ -561,3 +561,9 @@ Check Diagstatus
     ${resp}    RequestsLibrary.Get Request    diagstatus_session    /diagstatus
     Run Keyword If    "${check_status}" == "True"    BuiltIn.Should Be Equal As Strings    ${resp.status_code}    ${expected_status}
     [Return]    ${resp}
+
+Download File On Openstack Node
+    [Arguments]    ${conn_id}    ${save_file_name}    ${url}
+    [Documentation]    Download a file from web to the node. the input will be a session ID with established SSH connection.
+    SSHLibrary.Switch Connection    ${conn_id}
+    Utils.Write Commands Until Expected Prompt    wget -O /tmp/${save_file_name} ${url}    ${DEFAULT_LINUX_PROMPT_STRICT}
index eeb5958a358a3f135351c21ef4d404a14086ac89..8c28f9d7592bff36b5a6021d252e606d65101654 100644 (file)
@@ -9,6 +9,7 @@ Library           SSHLibrary
 Library           OperatingSystem
 Library           RequestsLibrary
 Resource          ../../../libraries/DevstackUtils.robot
+Resource          ../../../libraries/LiveMigration.robot
 Resource          ../../../libraries/OpenStackOperations.robot
 Resource          ../../../libraries/SetupUtils.robot
 Resource          ../../../libraries/Utils.robot
@@ -18,51 +19,135 @@ Resource          ../../../libraries/KarafKeywords.robot
 ${SECURITY_GROUP}    sg-sfc
 @{NETWORKS}       network_1
 @{SUBNETS}        l2_subnet_1
-@{NET_1_VMS}      sf1    sf2    sf3    source_vm    dest_vm
+@{NET_1_VMS}      sf1    sourcevm    destvm
+@{NON_SF_VMS}     sourcevm    destvm
 @{SUBNET_CIDRS}    30.0.0.0/24
-@{PORTS}          p1in    p1out    p2in    p2out    p3in    p3out    source_vm_port
-...               dest_vm_port
+@{PORTS}          p1in    p1out    source_vm_port    dest_vm_port
+${CURL_COMMAND}    curl -v --connect-timeout 25
+${HTTP_SUCCESS}    200 OK
+${HTTP_FAILURE}    connect() timed out!
+${WEBSERVER_80}    while true; do echo -e "HTTP/1.0 200 OK\r\nContent-Length: 21\r\n\r\nWelcome to web-server80" | sudo nc -l -p 80 ; done
+${WEBSERVER_81}    while true; do echo -e "HTTP/1.0 200 OK\r\nContent-Length: 21\r\n\r\nWelcome to web-server81" | sudo nc -l -p 81 ; done
+${WEBSERVER_82}    while true; do echo -e "HTTP/1.0 200 OK\r\nContent-Length: 21\r\n\r\nWelcome to web-server82" | sudo nc -l -p 82 ; done
+${CLOUD_IMAGE}    "https://cloud-images.ubuntu.com/releases/18.04/release/ubuntu-18.04-server-cloudimg-amd64.img"
+${CLOUD_IMAGE_NAME}    ubuntu
+${CLOUD_FLAVOR_NAME}    ubuntu
+${CLOUD_USER_NAME}    ubuntu
+${VXLAN_TOOL_URL}    "https://git.opendaylight.org/gerrit/gitweb?p=sfc.git;a=blob_plain;f=sfc-test/nsh-tools/vxlan_tool.py;h=1445292405bc17516d03e4a448ac2e0f65d38e79;hb=HEAD"
+@{NETVIRT_DIAG_SERVICES}    OPENFLOW    IFM    ITM    DATASTORE    ELAN
 
 *** Test Cases ***
-Create Flow Classifiers
+Create Flow Classifiers For Basic Test
     [Documentation]    Create SFC Flow Classifier for TCP traffic between source VM and destination VM
-    OpenStackOperations.Create SFC Flow Classifier    FC_http    @{NET1_VM_IPS}[3]    @{NET1_VM_IPS}[4]    tcp    80    source_vm_port
+    OpenStackOperations.Create SFC Flow Classifier    FC_80    @{NET1_VM_IPS}[0]    @{NET1_VM_IPS}[1]    tcp    source_vm_port    args=--destination-port 80:80
+    OpenStackOperations.Create SFC Flow Classifier    FC_81    @{NET1_VM_IPS}[0]    @{NET1_VM_IPS}[1]    tcp    source_vm_port    args=--destination-port 81:81
 
-Create Port Pairs
+Create Port Pair
     [Documentation]    Create SFC Port Pairs
-    OpenStackOperations.Create SFC Port Pair    PP1    p1in    p1out
-    OpenStackOperations.Create SFC Port Pair    PP2    p2in    p2out
-    OpenStackOperations.Create SFC Port Pair    PP3    p3in    p3out
+    OpenStackOperations.Create SFC Port Pair    SFPP1    p1in    p1out
 
 Create Port Pair Groups
     [Documentation]    Create SFC Port Pair Groups
-    OpenStackOperations.Create SFC Port Pair Group With Two Pairs    PG1    PP1    PP2
-    OpenStackOperations.Create SFC Port Pair Group    PG2    PP3
-
-Create Port Chain
-    [Documentation]    Create SFC Port Chain using two port groups an classifier created previously
-    OpenStackOperations.Create SFC Port Chain    PC1    PG1    PG2    FC_http
-
-Start Web Server On Destination VM
-    [Documentation]    Start a simple web server on the destination VM
-    OpenStackOperations.Execute Command on VM Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[4]    while true; do echo -e "HTTP/1.0 200 OK\r\nContent-Length: 21\r\n\r\nWelcome to web-server" | sudo nc -l -p 80 ; done &
-
-Add Static Routing On Service Function VMs
-    [Documentation]    Enable eth1 and add static routing between the ports on the SF VMs
-    : FOR    ${index}    IN RANGE    0    2
-    \    OpenStackOperations.Execute Command on VM Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[${index}]    sudo sh -c 'echo "auto eth1" >> /etc/network/interfaces'
-    \    OpenStackOperations.Execute Command on VM Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[${index}]    sudo sh -c 'echo "iface eth1 inet dhcp" >> /etc/network/interfaces'
-    \    OpenStackOperations.Execute Command on VM Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[${index}]    sudo /etc/init.d/S40network restart
-    \    OpenStackOperations.Execute Command on VM Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[${index}]    sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
-    \    OpenStackOperations.Execute Command on VM Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[${index}]    sudo ip route add @{NET1_VM_IPS}[3] dev eth0
-    \    OpenStackOperations.Execute Command on VM Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[${index}]    sudo ip route add @{NET1_VM_IPS}[4] dev eth1
-
-Connectivity Tests From Vm Instance1 In net_1
-    [Documentation]    Login to the source VM instance, and send a HTTP GET using curl to the destination VM instance
-    # FIXME need to somehow verify it goes through SFs (flows?)
-    ${DEST_VM_LIST}    BuiltIn.Create List    @{NET1_VM_IPS}[4]
-    OpenStackOperations.Test Operations From Vm Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[3]    ${DEST_VM_LIST}
-    OpenStackOperations.Execute Command on VM Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[3]    curl http://@{NET1_VM_IPS}[4]
+    OpenStackOperations.Create SFC Port Pair Group    SFPPG1    SFPP1
+
+Test Communication From Vm Instance1 In net_1 No SF
+    [Documentation]    Login to the source VM instance, and send a HTTP GET using curl to the destination VM instance, If the SF handles the traffic, there will be delay causing the time for curl to be higher.
+    ${DEST_VM_LIST}    BuiltIn.Create List    @{NET1_VM_IPS}[1]
+    ${curl_resp}    OpenStackOperations.Execute Command on VM Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[0]    ${CURL_COMMAND} http://@{NET1_VM_IPS}[1]
+    BuiltIn.Should Contain    ${curl_resp}    ${HTTP_SUCCESS}
+    ${curl_resp}    OpenStackOperations.Execute Command on VM Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[0]    ${CURL_COMMAND} http://@{NET1_VM_IPS}[1]:81
+    BuiltIn.Should Contain    ${curl_resp}    ${HTTP_SUCCESS}
+    [Teardown]    BuiltIn.Run Keywords    OpenStackOperations.Get Test Teardown Debugs
+    ...    AND    OpenStackOperations.Get Test Teardown Debugs For SFC
+    ...    AND    OpenStackOperations.Exit From Vm Console
+
+Create Port Chain For Src->Dest Port 80
+    [Documentation]    Create SFC Port Chain using port group and classifier created previously
+    OpenStackOperations.Create SFC Port Chain    SFPC1    args=--port-pair-group SFPPG1 --flow-classifier FC_80
+
+Test Communication From Vm Instance1 In net_1 Port 80 via SF
+    [Documentation]    Login to the source VM instance, and send a HTTP GET using curl to the destination VM instance, If the SF handles the traffic, there will be delay causing the time for curl to be higher.
+    Start Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}    args=--do forward --interface ens2 --output ens3 --verbose off
+    Wait Until Keyword Succeeds    3x    10s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} http://@{NET1_VM_IPS}[1]    ${HTTP_SUCCESS}
+    Wait Until Keyword Succeeds    3x    10s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} http://@{NET1_VM_IPS}[1]:81    ${HTTP_SUCCESS}
+    Stop Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}
+    Start Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}    args=--do forward --interface ens2 --output ens3 --verbose off --block 80
+    BuiltIn.Comment    Port 80 communication should fail as the SF blocks the same
+    Wait Until Keyword Succeeds    3x    10s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} http://@{NET1_VM_IPS}[1]    ${HTTP_FAILURE}
+    BuiltIn.Comment    Test to confirm Port 81 is not blocked
+    Wait Until Keyword Succeeds    3x    10s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} http://@{NET1_VM_IPS}[1]:81    ${HTTP_SUCCESS}
+    Stop Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}
+    Start Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}    args=--do forward --interface ens2 --output ens3 --verbose off --block 81
+    Wait Until Keyword Succeeds    3x    10s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} http://@{NET1_VM_IPS}[1]    ${HTTP_SUCCESS}
+    Wait Until Keyword Succeeds    3x    10s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} http://@{NET1_VM_IPS}[1]:81    ${HTTP_SUCCESS}
+    Stop Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}
+    [Teardown]    BuiltIn.Run Keywords    OpenStackOperations.Get Test Teardown Debugs
+    ...    AND    OpenStackOperations.Get Test Teardown Debugs For SFC
+    ...    AND    OpenStackOperations.Exit From Vm Console
+
+Update Port Chain To Use Flow Classifier For Port 81
+    [Documentation]    Update Port Chain to use FC_82 and FC_83 instead of FC_80 and FC_81
+    OpenStackOperations.Update SFC Port Chain With A New Flow Classifier    SFPC1    FC_81
+    OpenStackOperations.Update SFC Port Chain Removing A Flow Classifier    SFPC1    FC_80
+
+Test Communication From Vm Instance1 In net_1 Port 81 via SF
+    [Documentation]    Login to the source VM instance, and send a HTTP GET using curl to the destination VM instance, If the SF handles the traffic, there will be delay causing the time for curl to be higher.
+    Stop Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}
+    Start Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}    args=--do forward --interface ens2 --output ens3 --verbose off
+    Wait Until Keyword Succeeds    3x    10s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} http://@{NET1_VM_IPS}[1]    ${HTTP_SUCCESS}
+    Wait Until Keyword Succeeds    3x    10s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} http://@{NET1_VM_IPS}[1]:81    ${HTTP_SUCCESS}
+    ...    cmd_timeout=60s
+    Stop Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}
+    Start Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}    args=--do forward --interface ens2 --output ens3 --verbose off --block 81
+    Wait Until Keyword Succeeds    3x    10s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} http://@{NET1_VM_IPS}[1]    ${HTTP_SUCCESS}
+    Wait Until Keyword Succeeds    3x    10s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} http://@{NET1_VM_IPS}[1]:81    ${HTTP_FAILURE}
+    ...    cmd_timeout=60s
+    BuiltIn.Comment    Port 81 communication should fail as the SF blocks the same
+    BuiltIn.Comment    Test to confirm Port 80 does not continue to get routed through SF
+    Stop Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}
+    Start Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}    args=--do forward --interface ens2 --output ens3 --verbose off --block 80
+    Wait Until Keyword Succeeds    3x    10s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} http://@{NET1_VM_IPS}[1]    ${HTTP_SUCCESS}
+    Wait Until Keyword Succeeds    3x    10s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} http://@{NET1_VM_IPS}[1]:81    ${HTTP_SUCCESS}
+    ...    cmd_timeout=60s
+    Stop Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}
+    [Teardown]    BuiltIn.Run Keywords    OpenStackOperations.Get Test Teardown Debugs
+    ...    AND    OpenStackOperations.Get Test Teardown Debugs For SFC
+    ...    AND    OpenStackOperations.Exit From Vm Console
+
+Delete And Recreate Port Chain And Flow Classifiers For Symmetric Test
+    OpenStackOperations.Create SFC Flow Classifier    FC_SYM    @{NET1_VM_IPS}[0]    @{NET1_VM_IPS}[1]    tcp    source_vm_port    args=--destination-port 82:82 --source-port 2000 --logical-destination-port dest_vm_port
+    OpenStackOperations.Delete SFC Port Chain    SFPC1
+    OpenStackOperations.Create SFC Port Chain    SFPSYM    args=--port-pair-group SFPPG1 --flow-classifier FC_SYM --chain-parameters symmetric=true
+
+Test Communication From Vm Instance1 For Symmetric Chain
+    [Documentation]    Login to the source VM instance, and send a HTTP GET using curl to the destination VM instance, If the SF handles the traffic, there will be delay causing the time for curl to be higher.
+    Stop Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}
+    Start Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}    args=--do forward --interface ens2 --output ens3 --verbose off
+    Start Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}    args=--do forward --interface ens3 --output ens2 --verbose off
+    Wait Until Keyword Succeeds    8x    20s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} --local-port 2000 -m 60 http://@{NET1_VM_IPS}[1]:82    ${HTTP_SUCCESS}
+    ...    cmd_timeout=80s
+    BuiltIn.Comment    Test to confirm the SRC->DEST Port 82 is routed through SF
+    Stop Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}
+    Start Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}    args=--do forward --interface ens2 --output ens3 --verbose off --block 82
+    Start Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}    args=--do forward --interface ens3 --output ens2 --verbose off
+    Wait Until Keyword Succeeds    8x    20s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} --local-port 2000 -m 60 http://@{NET1_VM_IPS}[1]:82    ${HTTP_FAILURE}
+    ...    cmd_timeout=80s
+    BuiltIn.Comment    Test to confirm DEST->SRC Port 2000 path SFC traversal
+    Stop Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}
+    Start Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}    args=--do forward --interface ens2 --output ens3 --verbose off
+    Start Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}    args=--do forward --interface ens3 --output ens2 --verbose off --block 2000
+    Wait Until Keyword Succeeds    8x    20s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} --local-port 2000 -m 60 http://@{NET1_VM_IPS}[1]:82    ${HTTP_FAILURE}
+    ...    cmd_timeout=80s
+    BuiltIn.Comment    Test to confirm the Normalcy restored
+    Stop Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}
+    Start Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}    args=--do forward --interface ens2 --output ens3 --verbose off
+    Start Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}    args=--do forward --interface ens3 --output ens2 --verbose off
+    Wait Until Keyword Succeeds    8x    20s    Access Http And Check Status    @{NETWORKS}[0]    ${CURL_COMMAND} --local-port 2000 -m 60 http://@{NET1_VM_IPS}[1]:82    ${HTTP_SUCCESS}
+    ...    cmd_timeout=80s
+    Stop Vxlan Tool in SF    @{NETWORKS}[0]    ${SF1_IP}
+    [Teardown]    BuiltIn.Run Keywords    OpenStackOperations.Get Test Teardown Debugs
+    ...    AND    OpenStackOperations.Get Test Teardown Debugs For SFC
+    ...    AND    OpenStackOperations.Exit From Vm Console
 
 Delete Configurations
     [Documentation]    Delete all elements that were created in the test case section. These are done
@@ -72,13 +157,12 @@ Delete Configurations
     ...    to leave the test environment as clean as possible upon completion of this suite.
     : FOR    ${vm}    IN    @{NET_1_VMS}
     \    OpenStackOperations.Delete Vm Instance    ${vm}
-    OpenStackOperations.Delete SFC Port Chain    PC1
-    OpenStackOperations.Delete SFC Port Pair Group    PG1
-    OpenStackOperations.Delete SFC Port Pair Group    PG2
-    OpenStackOperations.Delete SFC Port Pair    PP1
-    OpenStackOperations.Delete SFC Port Pair    PP2
-    OpenStackOperations.Delete SFC Port Pair    PP3
-    OpenStackOperations.Delete SFC Flow Classifier    FC_http
+    OpenStackOperations.Delete SFC Port Chain    SFPSYM
+    OpenStackOperations.Delete SFC Port Pair Group    SFPPG1
+    OpenStackOperations.Delete SFC Port Pair    SFPP1
+    OpenStackOperations.Delete SFC Flow Classifier    FC_80
+    OpenStackOperations.Delete SFC Flow Classifier    FC_81
+    OpenStackOperations.Delete SFC Flow Classifier    FC_SYM
     : FOR    ${port}    IN    @{PORTS}
     \    OpenStackOperations.Delete Port    ${port}
     OpenStackOperations.Delete SubNet    l2_subnet_1
@@ -89,19 +173,89 @@ Delete Configurations
 *** Keywords ***
 Suite Setup
     OpenStackOperations.OpenStack Suite Setup
+    Create Basic Networks
+    Create Ports For Testing
+    Create Instances For Testing
+    Check Vm Instances Have Ip Address And Ready For Test
+    Start Applications on VM Instances For Test
+
+Create Basic Networks
+    BuiltIn.Comment    Create Network For Testing
     OpenStackOperations.Create Network    @{NETWORKS}[0]
+    BuiltIn.Comment    Create Subnet For Testing
     OpenStackOperations.Create SubNet    @{NETWORKS}[0]    @{SUBNETS}[0]    @{SUBNET_CIDRS}[0]
     OpenStackOperations.Create Allow All SecurityGroup    ${SECURITY_GROUP}
+    BuiltIn.Comment    Create Neutron Ports with no port security for SFC Tests
+    OpenStackOperations.Get Suite Debugs
+
+Create Ports For Testing
     : FOR    ${port}    IN    @{PORTS}
     \    OpenStackOperations.Create Port    @{NETWORKS}[0]    ${port}    sg=${SECURITY_GROUP}
-    Create Vm Instance With Ports    p1in    p1out    sf1    sg=${SECURITY_GROUP}
-    Create Vm Instance With Ports    p2in    p2out    sf2    sg=${SECURITY_GROUP}
-    Create Vm Instance With Ports    p3in    p3out    sf3    sg=${SECURITY_GROUP}
-    Create Vm Instance With Port    source_vm_port    source_vm    sg=${SECURITY_GROUP}
-    Create Vm Instance With Port    dest_vm_port    dest_vm    sg=${SECURITY_GROUP}
-    @{NET1_VM_IPS}    ${NET1_DHCP_IP} =    OpenStackOperations.Get VM IPs    @{NET_1_VMS}
+    OpenStackOperations.Update Port    p1in    additional_args=--no-security-group
+    OpenStackOperations.Update Port    p1in    additional_args=--disable-port-security
+    OpenStackOperations.Update Port    p1out    additional_args=--no-security-group
+    OpenStackOperations.Update Port    p1out    additional_args=--disable-port-security
+    OpenStackOperations.Get Suite Debugs
+
+Create Instances For Testing
+    BuiltIn.Comment    Create one ubuntu instances and two cirros instances
+    OpenStackOperations.Add New Image From Url    ${CLOUD_IMAGE}    ${CLOUD_IMAGE_NAME}
+    OpenStackOperations.Create Flavor    ${CLOUD_FLAVOR_NAME}    2048    4
+    OpenStackOperations.Generate And Add Keypair    sfctest    odlsfctest
+    OpenStackOperations.Create Vm Instance With Ports And Key On Compute Node    p1in    p1out    sf1    ${OS_CMP1_HOSTNAME}    image=${CLOUD_IMAGE_NAME}    flavor=${CLOUD_FLAVOR_NAME}
+    ...    sg=${SECURITY_GROUP}    keyname=sfctest
+    OpenStackOperations.Create Vm Instance With Port On Compute Node    source_vm_port    sourcevm    ${OS_CMP1_HOSTNAME}    sg=${SECURITY_GROUP}    flavor=cirros256
+    OpenStackOperations.Create Vm Instance With Port On Compute Node    dest_vm_port    destvm    ${OS_CMP1_HOSTNAME}    sg=${SECURITY_GROUP}    flavor=cirros256
+    OpenStackOperations.Show Debugs    @{NET_1_VMS}
+    OpenStackOperations.Get Suite Debugs
+
+Check Vm Instances Have Ip Address And Ready For Test
+    OpenStackOperations.Poll VM Is ACTIVE    sf1
+    OpenStackOperations.Poll VM Is ACTIVE    sourcevm
+    OpenStackOperations.Poll VM Is ACTIVE    destvm
+    ${sfc1_mac}    OpenStackOperations.Get Port Mac    p1in
+    ${SF1_IP}    OpenStackOperations.Get Port Ip    p1in
+    BuiltIn.Wait Until Keyword Succeeds    500s    60s    OpenStackOperations.Verify If Instance Is Arpingable From Dhcp Namespace    @{NETWORKS}[0]    ${sfc1_mac}    ${SF1_IP}
+    ${src_mac}    OpenStackOperations.Get Port Mac    source_vm_port
+    ${src_ip}    OpenStackOperations.Get Port Ip    source_vm_port
+    BuiltIn.Wait Until Keyword Succeeds    500s    60s    OpenStackOperations.Verify If Instance Is Arpingable From Dhcp Namespace    @{NETWORKS}[0]    ${src_mac}    ${src_ip}
+    ${dest_mac}    OpenStackOperations.Get Port Mac    dest_vm_port
+    ${dest_ip}    OpenStackOperations.Get Port Ip    dest_vm_port
+    BuiltIn.Wait Until Keyword Succeeds    500s    60s    OpenStackOperations.Verify If Instance Is Arpingable From Dhcp Namespace    @{NETWORKS}[0]    ${dest_mac}    ${dest_ip}
+    BuiltIn.Comment    If the Tests reach this point, all the Instances are reachable.
+    ${NET1_VM_IPS}    BuiltIn.Create List    ${src_ip}    ${dest_ip}
     BuiltIn.Set Suite Variable    @{NET1_VM_IPS}
-    BuiltIn.Should Not Contain    ${NET1_VM_IPS}    None
-    BuiltIn.Should Not Contain    ${NET1_DHCP_IP}    None
+    BuiltIn.Set Suite Variable    ${SF1_IP}
+    BuiltIn.Wait Until Keyword Succeeds    300s    60s    OpenStackOperations.Check If Instance Is Ready For Ssh Login Using PublicKey    @{NETWORKS}[0]    ${SF1_IP}    user=ubuntu
+    ...    idfile=/tmp/odlsfctest
+    BuiltIn.Wait Until Keyword Succeeds    300s    60s    OpenStackOperations.Check If Instance Is Ready For Ssh Login Using Password    @{NETWORKS}[0]    @{NET1_VM_IPS}[0]
+    BuiltIn.Wait Until Keyword Succeeds    300s    60s    OpenStackOperations.Check If Instance Is Ready For Ssh Login Using Password    @{NETWORKS}[0]    @{NET1_VM_IPS}[1]
     OpenStackOperations.Show Debugs    @{NET_1_VMS}
     OpenStackOperations.Get Suite Debugs
+
+Start Applications on VM Instances For Test
+    BuiltIn.Comment    Run Web server Scripts on destination vm listening to 80,81 and 82 ports
+    OpenStackOperations.Execute Command on VM Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[1]    ${WEBSERVER_80} &
+    OpenStackOperations.Execute Command on VM Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[1]    ${WEBSERVER_81} &
+    OpenStackOperations.Execute Command on VM Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[1]    ${WEBSERVER_82} &
+    BuiltIn.Comment    Get vxlan_tool script
+    Utils.Download File On Openstack Node    ${OS_CNTL_CONN_ID}    vxlan_tool.py    ${VXLAN_TOOL_URL}
+    BuiltIn.Comment    Copy vxlan_tool script to SFC VM
+    OpenStackOperations.Copy File To VM Instance With PublicKey Auth    @{NETWORKS}[0]    ${SF1_IP}    /tmp/vxlan_tool.py    user=${CLOUD_USER_NAME}    idfile=/tmp/odlsfctest
+    BuiltIn.Comment    Bring up the second Interface for egress
+    Execute Command on VM Instance with PublicKey Auth    @{NETWORKS}[0]    ${SF1_IP}    sudo ifconfig ens3 up    user=${CLOUD_USER_NAME}    idfile=/tmp/odlsfctest
+
+Start Vxlan Tool in SF
+    [Arguments]    ${network}    ${sf_vm_ip}    ${args}=${EMPTY}
+    [Documentation]    Starts the tool in the SF VM's
+    Execute Command on VM Instance with PublicKey Auth    ${network}    ${sf_vm_ip}    nohup sudo python3 /tmp/vxlan_tool.py ${args} &    user=ubuntu    idfile=/tmp/odlsfctest
+
+Stop Vxlan Tool in SF
+    [Arguments]    ${network}    ${sf_vm_ip}
+    [Documentation]    Starts the tool in the SF VM's
+    Execute Command on VM Instance With PublicKey Auth    ${network}    ${sf_vm_ip}    sudo pkill python3    user=ubuntu    idfile=/tmp/odlsfctest
+
+Access Http And Check Status
+    [Arguments]    ${vm_ip}    ${curl_command}    ${ret_code}    ${cmd_timeout}=30s
+    ${curl_resp}    OpenStackOperations.Execute Command on VM Instance    @{NETWORKS}[0]    @{NET1_VM_IPS}[0]    ${curl_command}    cmd_timeout=${cmd_timeout}
+    BuiltIn.Should Contain    ${curl_resp}    ${ret_code}
index 34d0b05880408f8c6fb99d89db14bf3bed5c118f..54d1aa8cc3ece36236fb3365a54b1778d94e6576 100644 (file)
@@ -145,6 +145,7 @@ ${OPERATIONAL_NODES_API}    /restconf/operational/opendaylight-inventory:nodes
 ${OPERATIONAL_NODES_NETVIRT}    /restconf/operational/network-topology:network-topology/topology/netvirt:1    \    # FIXME: Move to a separate Resource and add description.
 ${OPERATIONAL_TOPO_API}    /restconf/operational/network-topology:network-topology    # FIXME: Move to a separate Resource and add description.
 ${OS_SYSTEM_PROMPT}    \$    # Prompt substring specific to OpenStack systems.
+${OS_SYSTEM_PROMPT_STRICT}    \]$    # Prompt substring specific to OpenStack systems.
 ${OS_CMD_SUCCESS}    Command Returns 0
 ${OSREST}         /v2.0/networks    # FIXME: Move to a separate Neutron-related Resource and add description.
 ${OVSDBPORT}      6640    # Port number ODL uses for OVSDB protocol communication. TODO: Move to OVSDB-specific Resource.