Merge "o introducing FlowLib robot/python library. Gives ability to dynamically...
authorChristopher O'Shea <christopher.o.shea@ericsson.com>
Fri, 5 Sep 2014 07:48:26 +0000 (07:48 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Fri, 5 Sep 2014 07:48:26 +0000 (07:48 +0000)
test/csit/libraries/FlowLib.py [new file with mode: 0644]
test/csit/libraries/FlowLib.txt [new file with mode: 0644]
test/csit/suites/base-of13/070__Flows_OF13/305__ttl.txt

diff --git a/test/csit/libraries/FlowLib.py b/test/csit/libraries/FlowLib.py
new file mode 100644 (file)
index 0000000..2e42328
--- /dev/null
@@ -0,0 +1,81 @@
+"""
+Library for dynamic flow construction.
+Authors: james.luhrsen@hp.com
+Updated: 2014-08-29
+"""
+'''
+xmltodict and json libs not needed at this point, but may be useful in
+the future.
+'''
+##import xmltodict
+##import json
+import string
+import robot
+from robot.libraries.BuiltIn import BuiltIn
+
+##bare bones xml for building a flow
+xml_skeleton = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' +      \
+               '<flow xmlns="urn:opendaylight:flow:inventory">'         +      \
+                    '<instructions></instructions>'                     +      \
+                    '<match></match>'                                   +      \
+               '</flow>'
+
+class Flow:
+    '''
+    Flow class for creating and interacting with OpenFlow flows
+    '''
+
+    strict = "false"
+    instruction_xmls = ""
+    match_xmls = ""
+    cookie = 0
+    cookie_mask = 0
+    table_id = 0
+    id = 1
+    hard_timeout = 60
+    idle_timeout = 30
+    flow_name = "No Name"
+    priority = 0
+    barrier = "false"
+
+    xml = xml_skeleton
+
+    json = ""
+
+    def set_field(self, field, value):
+        '''
+           allows for generically setting any attribute in this
+           class based on the 'field' passed in.  In the future,
+           adding a new attribute only requires that single line
+           addition.  no need for additional setter.
+        '''
+        setattr(self, field, value)
+
+def Make_Flow_Object():
+    '''
+        Robot Keyword to create and return an instance of the Flow
+        class.
+    '''
+    flow = Flow()
+    return flow
+
+def Set_Flow_Field(flow, field, value):
+    '''
+        Robot Keyword to allow the modification (setting) of the 
+        flow object attributes
+    '''
+    flow.set_field(field,value)
+    return flow
+
+
+#def Convert_Flow_XML_To_Json(flow):
+#    '''
+#       There may be a need in the future to use json to push
+#       flows, as opposed to xml format that is prevalent in 
+#       test code at this point.  This function will give a 
+#       conversion, but unsure if it's proper.  Also, unsure
+#       if the xmltodict library is viable in the CSIT environment
+#    '''
+#    flowXmlDict = xmltodict.parse(flow.xml)
+#    flow.json = json.dumps(flowXmlDict)
+#    return flow
diff --git a/test/csit/libraries/FlowLib.txt b/test/csit/libraries/FlowLib.txt
new file mode 100644 (file)
index 0000000..8e7b405
--- /dev/null
@@ -0,0 +1,119 @@
+*** Settings ***
+Documentation     Keywords used to create/modify flow objects. The object is defined in the
+...               corresponding FlowLib.py library and contains pertinent fields and methods (e.g.,
+...               cookie and barrier fields, string formatted xml that can be used to push to
+...               controller)
+Library           ./FlowLib.py
+Library           XML
+
+*** Variables ***
+##default flow attributes ...
+@{default_flow_fields}    strict    table_id    id    hard_timeout    idle_timeout    flow_name    priority
+...               barrier    cookie    cookie_mask
+
+*** Keywords ***
+Create Flow
+    [Documentation]    Calls FlowLib.Make_Flow_Object() function and initializes and sanitizes
+    ...    the basic flow elements.
+    ${flow}=    Make Flow Object
+    : FOR    ${field}    IN    @{default_flow_fields}
+    \    Set "${flow}" "${field}" With "${flow.${field}}"
+    [Return]    ${flow}
+
+Set "${flow}" "${property}" With "${property_val}"
+    [Documentation]    Embedded variables to make higher level keywords more readable.
+    ...    There are some cases where the python attribute uses an underscore,
+    ...    but a hyphen needs to be used. This seems inconsistent, and may need
+    ...    to be looked at from the openflow plugin perspective.
+    ...
+    ...    At this point, this library will remove the element ${property} from the
+    ...    xml representation of the flow and reset with the given value. \ It's not
+    ...    possible, yet, to have multiple elements with the same name. \ That will
+    ...    likely be needed in the future.
+    ${property}    Run Keyword If    "table_id" != "${property}" and "cookie_mask" != "${property}"    Replace String    ${property}    _    -
+    ...    ELSE    Set Variable    ${property}
+    Remove Flow XML Element    ${flow}    ${property}
+    Add Flow XML Element    ${flow}    ${property}    ${property_val}
+    Set Flow Field    ${flow}    ${property}    ${property_val}
+    [Return]    ${flow}
+
+Set Flow Action
+    [Arguments]    ${flow}    ${instruction_order}    ${action_order}    ${action}    ${action_val}=${EMPTY}
+    [Documentation]    Will remove the instruction element first, then add the proper xml structure
+    ...    to implement the action as given in the arguments
+    ##For the case that any of the instruction/apply-actions/action elements are not there we need to add them'
+    Remove Flow XML Element    ${flow}    instruction
+    Add Flow XML Element    ${flow}    instruction    ${EMPTY}    instructions
+    Add Flow XML Element    ${flow}    order    ${instruction_order}    instructions/instruction
+    Add Flow XML Element    ${flow}    apply-actions    ${EMPTY}    instructions/instruction
+    Add Flow XML Element    ${flow}    action    ${EMPTY}    instructions/instruction/apply-actions
+    Add Flow XML Element    ${flow}    order    ${action_order}    instructions/instruction/apply-actions/action
+    Add Flow XML Element    ${flow}    ${action}    ${action_val}    instructions/instruction/apply-actions/action
+    [Return]    ${flow}
+
+Set Flow Ethernet Match
+    [Arguments]    ${flow}    ${match_value_dict}
+    [Documentation]    Specific keyword for adding an ethernet match rules where the elements are given
+    ...    in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
+    ...    existing ethernet-match elements from the flow before adding
+    Clear Flow Matches    ${flow}    match/ethernet-match
+    Add Flow XML Element    ${flow}    ethernet-match    ${EMPTY}    match
+    ${type}=    Get From Dictionary    ${match_value_dict}    type
+    Add Flow XML Element    ${flow}    ethernet-type    ${EMPTY}    match/ethernet-match
+    Add Flow XML Element    ${flow}    type    ${type}    match/ethernet-match/ethernet-type
+    ${src}=    Get From Dictionary    ${match_value_dict}    source
+    Add Flow XML Element    ${flow}    ethernet-source    ${EMPTY}    match/ethernet-match
+    Add Flow XML Element    ${flow}    address    ${src}    match/ethernet-match/ethernet-source
+    ${dst}=    Get From Dictionary    ${match_value_dict}    destination
+    Add Flow XML Element    ${flow}    ethernet-destination    ${EMPTY}    match/ethernet-match
+    Add Flow XML Element    ${flow}    address    ${dst}    match/ethernet-match/ethernet-destination
+    [Return]    ${flow}
+
+Set Flow IPv4 Match
+    [Arguments]    ${flow}    ${match_value_dict}
+    [Documentation]    Specific keyword for adding an ipv4 match rules where the elements are given
+    ...    in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
+    ...    existing ipv4 match elements from the flow before adding
+    Clear Flow Matches    ${flow}    match/ipv4-source
+    Clear Flow Matches    ${flow}    match/ipv4-destination
+    ${src}=    Get From Dictionary    ${match_value_dict}    source
+    Add Flow XML Element    ${flow}    ipv4-source    ${src}    match
+    ${dst}=    Get From Dictionary    ${match_value_dict}    destination
+    Add Flow XML Element    ${flow}    ipv4-destination    ${dst}    match
+    [Return]    ${flow}
+
+Clear Flow Actions
+    [Arguments]    ${flow}
+    [Documentation]    Will clean out any existing flow actions in the given ${flow} object
+    Remove Flow XML Element    ${flow}    instructions/instruction
+    [Return]    ${flow}
+
+Clear Flow Matches
+    [Arguments]    ${flow}    ${match_element}
+    [Documentation]    Will clean out any existing flow matches in the given ${flow} object
+    Remove Flow XML Element    ${flow}    match/${match_element}
+    [Return]    ${flow}
+
+Add Flow XML Element
+    [Arguments]    ${flow}    ${element}    ${element_val}=${EMPTY}    ${xpath}=.
+    [Documentation]    Will modify the current xml representation of the ${flow} object to contain
+    ...    the given ${element} at the given ${xpath}. If the ${element} uses a value, that can be
+    ...    passed eith the ${element_val} which defaults to ${EMPTY} if not used. NOTE: since there
+    ...    are two default parameters to this keyword, if you have an ${xpath} to use, but no ${element_val}
+    ...    you will still need to pass ${EMPTY} when invoking so that ${xpath} will end up at the right
+    ...    location in the parameter list
+    ${flow_xml}=    Parse XML    ${flow.xml}
+    Add Element    ${flow_xml}    <${element}>${element_val}</${element}>    xpath=${xpath}
+    ${xml_string}=    Element To String    ${flow_xml}
+    Set Flow Field    ${flow}    xml    ${xml_string}
+    [Return]    ${flow}
+
+Remove Flow XML Element
+    [Arguments]    ${flow}    ${element_xpath}
+    [Documentation]    Removes the element at the given ${element_xpath} within the given ${flow}
+    ...    object. The ${flow} object's xml representation will be updated to reflect this removal.
+    ${flow_xml}=    Parse XML    ${flow.xml}
+    Run Keyword And Ignore Error    Remove Elements    ${flow_xml}    xpath=${element_xpath}
+    ${xml_string}=    Element To String    ${flow_xml}
+    Set Flow Field    ${flow}    xml    ${xml_string}
+    [Return]    ${flow}
index 25cd14eb27bb6f9d23dffbd5ff7b926f52229157..5b05b6c5470d0642e45df7e0ae1d792af77df344 100644 (file)
@@ -16,6 +16,7 @@ Library           Collections
 Library           OperatingSystem
 Library           String
 Library           XML
+Resource          ../../../libraries/FlowLib.txt
 Library           ../../../libraries/RequestsLibrary.py
 Library           ../../../libraries/Common.py
 Variables         ../../../variables/Variables.py
@@ -25,41 +26,60 @@ ${REST_CON}       /restconf/config/opendaylight-inventory:nodes
 ${REST_OPR}       /restconf/operational/opendaylight-inventory:nodes
 ${GENERIC_ACTION_FLOW_FILE}    ${CURDIR}/../../../variables/xmls/genericActionFlow.xml
 ${MININET_CMD}    sudo mn --controller=remote,ip=${CONTROLLER} --topo tree,1 --switch ovsk,protocols=OpenFlow13
+${ipv4_src}       10.1.2.0/24
+${ipv4_dst}       40.4.0.0/16
+${eth_type}       0x800
+${eth_src}        00:00:00:01:23:ae
+${eth_dst}        ff:ff:ff:ff:ff:ff
 
-*** Test Cases ***    ODL flow action        action XML                tableID    flowID    verify OVS?    OVS specific string?
-Set_IP_TTL            set-nw-ttl-action      <nw-ttl>1</nw-ttl>        2          101       no             set_ttl
+*** Test Cases ***    ODL flow action        action key                                                                                                                      action value    tableID    flowID    verify OVS?    OVS specific string?
+Set_IP_TTL            [Documentation]        OF1.3: \ OFPAT_SET_NW_TTL = 23, /* IP TTL. */\n(currently not supported on OVS)\n
+                      [Tags]                 ttl                                                                                                                             set
+                      set-nw-ttl-action      nw-ttl                                                                                                                          1               2          101       no             set_ttl
 
-Dec_TTL               dec-nw-ttl             none                      3          305       yes            dec_ttl
+Dec_TTL               [Documentation]        OF1.3: \ OFPAT_DEC_NW_TTL = 24, /* Decrement IP TTL. */\n
+                      [Tags]                 ttl                                                                                                                             dec
+                      dec-nw-ttl             none                                                                                                                            none            3          305       yes            dec_ttl
 
-Copy_TTL_In           copy-ttl-in            none                      9          202       no             copy_ttl_in
+Copy_TTL_In           [Documentation]        OFPAT_COPY_TTL_IN = 12, /* Copy TTL "inwards" -- from outermost to\nnext-to-outermost */\n(currently NOT supported in OVS)\n
+                      [Tags]                 ttl                                                                                                                             copyin
+                      copy-ttl-in            none                                                                                                                            none            9          202       no             copy_ttl_in
 
-Copy_TTL_Out          copy-ttl-out           none                      8          909       no             copy_ttl_out
+Copy_TTL_Out          [Documentation]        OFPAT_COPY_TTL_OUT = 11, /* Copy TTL "outwards" -- from next-to-outermost\nto outermost */\n(currently NOT suported in OVS)
+                      [Tags]                 ttl                                                                                                                             copyout
+                      copy-ttl-out           none                                                                                                                            none            8          909       no             copy_ttl_out
 
-Set_MPLS_TTL          set-mpls-ttl-action    <mpls-ttl>1</mpls-ttl>    4          505       yes            set_mpls_ttl
+Set_MPLS_TTL          [Documentation]        OFPAT_SET_MPLS_TTL = 15, /* MPLS TTL */
+                      [Tags]                 ttl                                                                                                                             setmpls
+                      set-mpls-ttl-action    mpls-ttl                                                                                                                        1               4          505       yes            set_mpls_ttl
 
-Dec_MPLS_TTL          dec-mpls-ttl           none                      2          1001      yes            dec_mpls_ttl
+Dec_MPLS_TTL          [Documentation]        OFPAT_DEC_MPLS_TTL = 16, /* Decrement MPLS TTL */
+                      [Tags]                 ttl                                                                                                                             decmpls
+                      dec-mpls-ttl           none                                                                                                                            none            2          1001      yes            dec_mpls_ttl
 
 *** Keywords ***
 Create And Remove Flow
-    [Arguments]    ${flow_action}    ${action_xml}    ${table_id}    ${flow_id}    ${verify_switch_flag}    ${additional_ovs_flowelements}
-    ${flow_body}=    OperatingSystem.Get File    ${GENERIC_ACTION_FLOW_FILE}
-    ${flow_body}=    Replace String    ${flow_body}    FLOW_ACTION    ${flow_action}
-    ${flow_body}=    Replace String    ${flow_body}    FLOW_ID    ${flow_id}
-    ${flow_body}=    Replace String    ${flow_body}    TABLE_ID    ${table_id}
-    Log    ${flow_body}
-    ${flow_root}=    Parse XML    ${flow_body}
-    Run Keyword If    "set" in "${flow_action}"    Add Element    ${flow_root}    ${action_xml}    xpath=instructions/instruction/apply-actions/action/${flow_action}
-    ${nw_src}=    Get Element    ${flow_root}    match/ipv4-source
-    ${nw_dst}=    Get Element    ${flow_root}    match/ipv4-destination
-    ${eth_src}=    Get Element    ${flow_root}    match/ethernet-match/ethernet-source/address
-    ${eth_dst}=    Get Element    ${flow_root}    match/ethernet-match/ethernet-destination/address
-    @{OVS_FLOWELEMENTS}    Create List    dl_dst=${eth_dst.text}    table=${table_id}    dl_src=${eth_src.text}    nw_src=${nw_src.text}    nw_dst=${nw_dst.text}
+    [Arguments]    ${flow_action}    ${action_key}    ${action_value}    ${table_id}    ${flow_id}    ${verify_switch_flag}
     ...    ${additional_ovs_flowelements}
-    ${flow_data}=    Element To String    ${flow_root}
-    Log    ${flow_data}
-    Add Flow To Controller And Verify    ${flow_data}    ${table_id}    ${flow_id}
+    @{OVS_FLOWELEMENTS}    Create List    dl_dst=${eth_dst}    table=${table_id}    dl_src=${eth_src}    nw_src=${ipv4_src}    nw_dst=${ipv4_dst}
+    ...    ${additional_ovs_flowelements}
+    ##The dictionaries here will be used to populate the match and action elements of the flow mod
+    ${ethernet_match_dict}=    Create Dictionary    type=${eth_type}    destination=${eth_dst}    source=${eth_src}
+    ${ipv4_match_dict}=    Create Dictionary    source=${ipv4_src}    destination=${ipv4_dst}
+    ##flow is a python Object to build flow details, including the xml format to send to controller
+    ${flow}=    Create Flow
+    Set "${flow}" "table_id" With "${table_id}"
+    Set "${flow}" "id" With "${flow_id}"
+    Clear Flow Actions    ${flow}
+    Set Flow Action    ${flow}    0    0    ${flow_action}
+    Set Flow Ethernet Match    ${flow}    ${ethernet_match_dict}
+    Set Flow IPv4 Match    ${flow}    ${ipv4_match_dict}
+    ##If the ${flow_action} contains the string "set" we need to include a deeper action detail (e.g. set-ttl needs a element to indicate the value to set it to)
+    Run Keyword If    "set" in "${flow_action}"    Add Flow XML Element    ${flow}    ${action_key}    ${action_value}    instructions/instruction/apply-actions/action/${flow_action}
+    Log    Flow XML is ${flow.xml}
+    Add Flow To Controller And Verify    ${flow.xml}    ${flow.table_id}    ${flow.id}
     Run Keyword If    "${verify_switch_flag}" == "yes"    Verify Flow On Switch    ${OVS_FLOWELEMENTS}
-    Remove Flow From Controller And Verify    ${flow_body}    ${table_id}    ${flow_id}
+    Remove Flow From Controller And Verify    ${flow.xml}    ${flow.table_id}    ${flow.id}
     Run Keyword If    "${verify_switch_flag}" == "yes"    Verify Flow Does Not Exist On Switch    ${OVS_FLOWELEMENTS}
 
 Add Flow To Controller And Verify