9f4c421a96d7340ddd00d8f3da4518d6bc996d31
[integration.git] / test / csit / libraries / FlowLib.robot
1 *** Settings ***
2 Documentation     Keywords used to create/modify flow objects. The object is defined in the
3 ...               corresponding FlowLib.py library and contains pertinent fields and methods (e.g.,
4 ...               cookie and barrier fields, string formatted xml that can be used to push to
5 ...               controller)
6 Library           ./FlowLib.py
7 Library           XML
8 Variables         ../variables/Variables.py
9
10 *** Variables ***
11
12 *** Keywords ***
13 Create Inventory Flow
14     [Documentation]    Calls FlowLib.Make_Inventory_Flow function and initializes and sanitizes
15     ...    the basic flow elements that can be given to flow:inventory
16     ${flow}=    Make Inventory Flow
17     [Return]    ${flow}
18
19 Create Service Flow
20     [Documentation]    Used for creating an object that will use an XML format that
21     ...    can be given to flow:service.
22     ${flow}=    Make Service Flow
23     [Return]    ${flow}
24
25 Set "${flow}" "${property}" With "${property_val}"
26     [Documentation]    Embedded variables to make higher level keywords more readable.
27     ...    There are some cases where the python attribute uses an underscore,
28     ...    but a hyphen needs to be used. This seems inconsistent, and may need
29     ...    to be looked at from the openflow plugin perspective.
30     ...
31     ...    At this point, this library will remove the element ${property} from the
32     ...    xml representation of the flow and reset with the given value. \ It's not
33     ...    possible, yet, to have multiple elements with the same name. \ That will
34     ...    likely be needed in the future.
35     ${property}    Run Keyword If    "table_id" != "${property}" and "cookie_mask" != "${property}"    Replace String    ${property}    _    -
36     ...    ELSE    Set Variable    ${property}
37     Remove Flow XML Element    ${flow}    ${property}
38     Add Flow XML Element    ${flow}    ${property}    ${property_val}
39     Set Flow Field    ${flow}    ${property}    ${property_val}
40     [Return]    ${flow}
41
42 Set Flow Action
43     [Arguments]    ${flow}    ${instruction_order}    ${action_order}    ${action}    ${action_val}=${EMPTY}
44     [Documentation]    Will remove the instruction element first, then add the proper xml structure
45     ...    to implement the action as given in the arguments
46     ##For the case that any of the instruction/apply-actions/action elements are not there we need to add them'
47     Remove Flow XML Element    ${flow}    instruction
48     Add Flow XML Element    ${flow}    instruction    ${EMPTY}    instructions
49     Add Flow XML Element    ${flow}    order    ${instruction_order}    instructions/instruction
50     Add Flow XML Element    ${flow}    apply-actions    ${EMPTY}    instructions/instruction
51     Add Flow XML Element    ${flow}    action    ${EMPTY}    instructions/instruction/apply-actions
52     Add Flow XML Element    ${flow}    order    ${action_order}    instructions/instruction/apply-actions/action
53     Add Flow XML Element    ${flow}    ${action}    ${action_val}    instructions/instruction/apply-actions/action
54     [Return]    ${flow}
55
56 Set Flow Output Action
57     [Arguments]    ${flow}    ${instruction_order}    ${action_order}    ${output_port}
58     Set Flow Action    ${flow}    ${instruction_order}    ${action_order}    output-action
59     Add Flow XML Element    ${flow}    output-node-connector    ${output_port}    instructions/instruction/apply-actions/action/output-action
60     [Return]    ${flow}
61
62 Set Flow Ethernet Match
63     [Arguments]    ${flow}    ${match_value_dict}
64     [Documentation]    Specific keyword for adding an ethernet match rules where the elements are given
65     ...    in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
66     ...    existing ethernet-match elements from the flow before adding
67     Clear Flow Matches    ${flow}    match/ethernet-match
68     Add Flow XML Element    ${flow}    ethernet-match    ${EMPTY}    match
69     ${type}=    Get From Dictionary    ${match_value_dict}    type
70     Add Flow XML Element    ${flow}    ethernet-type    ${EMPTY}    match/ethernet-match
71     Add Flow XML Element    ${flow}    type    ${type}    match/ethernet-match/ethernet-type
72     ${src}=    Get From Dictionary    ${match_value_dict}    source
73     Add Flow XML Element    ${flow}    ethernet-source    ${EMPTY}    match/ethernet-match
74     Add Flow XML Element    ${flow}    address    ${src}    match/ethernet-match/ethernet-source
75     ${dst}=    Get From Dictionary    ${match_value_dict}    destination
76     Add Flow XML Element    ${flow}    ethernet-destination    ${EMPTY}    match/ethernet-match
77     Add Flow XML Element    ${flow}    address    ${dst}    match/ethernet-match/ethernet-destination
78     [Return]    ${flow}
79
80 Set Flow IPv4 Match
81     [Arguments]    ${flow}    ${match_value_dict}
82     [Documentation]    Specific keyword for adding an ipv4 match rules where the elements are given
83     ...    in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
84     ...    existing ipv4 match elements from the flow before adding
85     Clear Flow Matches    ${flow}    match/ipv4-source
86     Clear Flow Matches    ${flow}    match/ipv4-destination
87     ${src}=    Get From Dictionary    ${match_value_dict}    source
88     Add Flow XML Element    ${flow}    ipv4-source    ${src}    match
89     ${dst}=    Get From Dictionary    ${match_value_dict}    destination
90     Add Flow XML Element    ${flow}    ipv4-destination    ${dst}    match
91     [Return]    ${flow}
92
93 Clear Flow Actions
94     [Arguments]    ${flow}
95     [Documentation]    Will clean out any existing flow actions in the given ${flow} object
96     Remove Flow XML Element    ${flow}    instructions/instruction
97     [Return]    ${flow}
98
99 Clear Flow Matches
100     [Arguments]    ${flow}    ${match_element}
101     [Documentation]    Will clean out any existing flow matches in the given ${flow} object
102     Remove Flow XML Element    ${flow}    match/${match_element}
103     [Return]    ${flow}
104
105 Set Flow XML Element Attribute
106     [Arguments]    ${flow}    ${element}    ${id}    ${value}
107     [Documentation]    Will set the given id/value pair to the given to the element provided
108     ...    and make the proper changes to the ${flow} object also provided.
109     ${flow_xml}=    Parse XML    ${flow.xml}
110     Set Element Attribute    ${flow_xml}    ${id}    ${value}    xpath=${element}
111     ${xml_string}=    Element To String    ${flow_xml}
112     Set Flow Field    ${flow}    xml    ${xml_string}
113     Log    ${flow.xml}
114     [Return]    ${flow}
115
116 Add Flow XML Element
117     [Arguments]    ${flow}    ${element}    ${element_val}=${EMPTY}    ${xpath}=.
118     [Documentation]    Will modify the current xml representation of the ${flow} object to contain
119     ...    the given ${element} at the given ${xpath}. If the ${element} uses a value, that can be
120     ...    passed eith the ${element_val} which defaults to ${EMPTY} if not used. NOTE: since there
121     ...    are two default parameters to this keyword, if you have an ${xpath} to use, but no ${element_val}
122     ...    you will still need to pass ${EMPTY} when invoking so that ${xpath} will end up at the right
123     ...    location in the parameter list
124     ${flow_xml}=    Parse XML    ${flow.xml}
125     Add Element    ${flow_xml}    <${element}>${element_val}</${element}>    xpath=${xpath}
126     ${xml_string}=    Element To String    ${flow_xml}
127     Set Flow Field    ${flow}    xml    ${xml_string}
128     Log    ${flow.xml}
129     [Return]    ${flow}
130
131 Remove Flow XML Element
132     [Arguments]    ${flow}    ${element_xpath}
133     [Documentation]    Removes the element at the given ${element_xpath} within the given ${flow}
134     ...    object. The ${flow} object's xml representation will be updated to reflect this removal.
135     ${flow_xml}=    Parse XML    ${flow.xml}
136     Run Keyword And Ignore Error    Remove Elements    ${flow_xml}    xpath=${element_xpath}
137     ${xml_string}=    Element To String    ${flow_xml}
138     Set Flow Field    ${flow}    xml    ${xml_string}
139     [Return]    ${flow}
140
141 Add Flow To Controller And Verify
142     [Arguments]    ${flow_body}    ${node_id}    ${table_id}    ${flow_id}
143     [Documentation]    Push flow through REST-API and verify in data-store
144     ${resp}    Put Xml    session    ${REST_CON}/node/${node_id}/table/${table_id}/flow/${flow_id}    data=${flow_body}
145     Log    ${resp.content}
146     Should Be Equal As Strings    ${resp.status_code}    200
147     ${resp}    RequestsLibrary.Get    session    ${REST_CON}/node/${node_id}/table/${table_id}/flow/${flow_id}    headers=${ACCEPT_XML}
148     Log    ${resp.content}
149     Should Be Equal As Strings    ${resp.status_code}    200
150     compare xml    ${flow_body}    ${resp.content}
151
152 Verify Flow On Mininet Switch
153     [Arguments]    ${flow_elements}
154     [Documentation]    Checking flow on switch
155     sleep    1
156     write    dpctl dump-flows -O OpenFlow13
157     ${switchoutput}    Read Until    >
158     : FOR    ${flowElement}    IN    @{flow_elements}
159     \    should Contain    ${switchoutput}    ${flowElement}
160
161 Remove Flow From Controller And Verify
162     [Arguments]    ${flow_body}    ${node_id}    ${table_id}    ${flow_id}
163     [Documentation]    Remove flow
164     ${resp}    RequestsLibrary.Delete    session    ${REST_CON}/node/${node_id}/table/${table_id}/flow/${flow_id}
165     Log    ${resp.content}
166     Should Be Equal As Strings    ${resp.status_code}    200
167     ${resp}    RequestsLibrary.Get    session    ${REST_CON}/node/${node_id}/table/${table_id}
168     Log    ${resp.content}
169     Should Not Contain    ${resp.content}    ${flow_id}
170
171 Verify Flow Does Not Exist On Mininet Switch
172     [Arguments]    ${flow_elements}
173     [Documentation]    Checking flow on switch is removed
174     sleep    1
175     write    dpctl dump-flows -O OpenFlow13
176     ${switchoutput}    Read Until    >
177     : FOR    ${flowElement}    IN    @{flow_elements}
178     \    should Not Contain    ${switchoutput}    ${flowElement}
179
180 Remove Default Flows
181     [Arguments]    ${node_id}
182     [Documentation]    Removes any flows considered "default". one such flow is
183     ...    to forward all traffic to the CONTROLLER with priority 0 at flow-table 0
184     ...    If/When others are implemented this keyword can be updated to include those.
185     ${flow}=    Make Service Flow
186     Set "${flow}" "priority" With "0"
187     Set "${flow}" "flow-table" With "0"
188     Add Flow XML Element    ${flow}    node    /inv:nodes/inv:node[inv:id="${node_id}"]
189     Set Flow XML Element Attribute    ${flow}    node    xmlns:inv    urn:opendaylight:inventory
190     Log    Flow XML is ${flow.xml}
191     write    dpctl dump-flows -O OpenFlow13
192     ${switchoutput}    Read Until    >
193     ${headers}=    Create Dictionary    Content-Type    application/yang.data+xml
194     ${resp}    RequestsLibrary.Post    session    restconf/operations/sal-flow:remove-flow    data=${flow.xml}    headers=${headers}
195     Log    ${resp.content}
196     Should Be Equal As Strings    ${resp.status_code}    200
197     ${resp}=    RequestsLibrary.Get    session    ${OPERATIONAL_NODES_API}
198     Log    ${resp.content}
199     Should Not Contain    ${resp.content}    "output-node-connector": "CONTROLLER",
200     ${strings_to_check_for}=    Create List    CONTROLLER
201     Verify Flow Does Not Exist On Mininet Switch    ${strings_to_check_for}
202
203 Create Flow Variables For Suite From XML File
204     [Arguments]    ${file}
205     [Documentation]    Given the flow XML ${file}, it will create several suite wide variables
206     ${data}=    OperatingSystem.Get File    ${file}
207     ${xmlroot}=    Parse Xml    ${file}
208     ${table_id}=    Get Element Text    ${xmlroot}    table_id
209     ${flow_id}=    Get Element Text    ${xmlroot}    id
210     ${flow_priority}=    Get Element Text    ${xmlroot}    priority
211     ${upddata}=    Get Data For Flow Put Update    ${data}
212     Set Suite Variable    ${table_id}
213     Set Suite Variable    ${flow_id}
214     Set Suite Variable    ${flow_priority}
215     Set Suite Variable    ${data}
216     Set Suite Variable    ${upddata}
217     Set Suite Variable    ${xmlroot}
218
219 Check Datastore Presence
220     [Arguments]    ${fname}    ${reqconfpres}    ${reqoperpres}    ${upd}
221     [Documentation]    Checks if flow is properly existing or not existing in the config and operational
222     ...    datastores, based on the variables ${reqconfpres} and ${reqoperpres}
223     Create Flow Variables For Suite From XML File    ${XmlsDir}/${fname}
224     # Note:    ${upddata} and ${data} are suite variables set by the keyword above.
225     ${det}=    Set Variable If    ${upd}==${True}    ${upddata}    ${data}
226     Check Config Flow    ${reqconfpres}    ${det}
227     Check Operational Flow    ${reqoperpres}    ${det}
228
229 Flow Presence In Config Store
230     [Arguments]    ${expvalue}
231     [Documentation]    Checks the config store for given flow. Returns True if present, otherwise returns False
232     ...    This keyword assumes that the global/suite variables are available (${table_id}, ${flow_id} and ${switch_idx}
233     ${headers}=    Create Dictionary    Accept    application/xml
234     ${resp}=    RequestsLibrary.Get    session    ${CONFIG_NODES_API}/node/openflow:${switch_idx}/table/${table_id}/flow/${flow_id}    headers=${headers}
235     Log    ${resp}
236     Log    ${resp.content}
237     Return From Keyword If    ${resp.status_code}!=200    ${False}    ${EMPTY}
238     ${pres}    ${msg}=    Is Flow Configured    ${expvalue}    ${resp.content}
239     Run Keyword If    '''${msg}'''!='${EMPTY}'    Log    ${msg}
240     Return From Keyword    ${pres}    ${msg}
241
242 Flow Presence In Operational Store
243     [Arguments]    ${expvalue}
244     [Documentation]    Checks the operational store for given flow. Returns True if present, otherwise returns False
245     ...    This keyword assumes that the global/suite variables are available (${table_id}, ${flow_id} and ${switch_idx}
246     ${headers}=    Create Dictionary    Accept    application/xml
247     ${resp}=    RequestsLibrary.Get    session    ${OPERATIONAL_NODES_API}/node/openflow:${switch_idx}/table/${table_id}    headers=${headers}
248     Log    ${resp}
249     Log    ${resp.content}
250     Return From Keyword If    ${resp.status_code}!=200    ${False}    ${EMPTY}
251     ${pres}    ${msg}=    Is Flow Operational2    ${expvalue}    ${resp.content}
252     Run Keyword If    '''${msg}'''!='${EMPTY}'    Log    ${msg}
253     Return From Keyword    ${pres}    ${msg}
254
255 Get Presence Failure Message
256     [Arguments]    ${ds}    ${expected}    ${presence}    ${diffmsg}
257     [Documentation]    Utility keyword to help manipulate mesage strings that may be used later to PASS or FAIL with
258     Return From Keyword If    '''${diffmsg}'''!='${EMPTY}'    Flow found in ${ds} data store but: ${diffmsg}
259     ${msgf}=    Set Variable If    ${expected}==${True}    The flow is expected in ${ds} data store, but    The flow is not expected in ${ds} data store, but
260     ${msgp}=    Set Variable If    ${presence}==${True}    it is present.    it is not present.
261     Return From Keyword    ${msgf} ${msgp}
262
263 Check Config Flow
264     [Arguments]    ${expected}    ${expvalue}
265     [Documentation]    Wrapper keyword that calls "Flow Presence In Config Store" and "Get Presence Failure Message" from this library
266     ...    to verify that the ${expvalue} flow is or is not found in the config store, depending on whether or not it was ${expected}
267     ${presence_flow}    ${msg}=    Flow Presence In Config Store    ${expvalue}
268     ${msgf}=    Get Presence Failure Message    config    ${expected}    ${presence_flow}    ${msg}
269     Should Be Equal    ${expected}    ${presence_flow}    msg=${msgf}
270
271 Check Operational Flow
272     [Arguments]    ${expected}    ${expvalue}
273     [Documentation]    Wrapper keyword that calls "Flow Presence In Operational Store" and "Get Presence Failure Message" from this library
274     ...    to verify that the ${expvalue} flow is or is not found in the config store, depending on whether or not it was ${expected}
275     ${presence_table}    ${msg}=    Flow Presence In Operational Store    ${expvalue}
276     ${msgf}=    Get Presence Failure Message    operational    ${expected}    ${presence_table}    ${msg}
277     Should Be Equal    ${expected}    ${presence_table}    msg=${msgf}
278
279 Add Flow Via RPC
280     [Arguments]    ${node_id}    ${xmlroot}
281     [Documentation]    Deploys a flow specified by given flow details (${node_id}, ${xmlroot}) using add-flow operation.
282     ...    ${xmlroot} is an xml object of parser xml flow details, usually created by Create Flow Variables For Suite From XML File
283     ...    keyword from this library.
284     ${req}=    Copy Element    ${xmlroot}
285     Remove Element    ${req}    id    clear_tail=True
286     Set Element Tag    ${req}    input
287     Set Element Attribute    ${req}    xmlns    urn:opendaylight:flow:service
288     Add Element    ${req}    <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
289     ${nodeelm}=    Get Element    ${req}    node
290     Set Element Attribute    ${nodeelm}    xmlns:inv    urn:opendaylight:inventory
291     Log Element    ${req}
292     ${strxml}=    Element To String    ${req}
293     ${resp}=    RequestsLibrary.Post    session    /restconf/operations/sal-flow:add-flow    data=${strxml}
294     Log    ${resp.content}
295     Should Be Equal As Strings    ${resp.status_code}    200
296
297 Add Flow Via Restconf
298     [Arguments]    ${node_id}    ${table_id}    ${flow_body}
299     [Documentation]    Configures a flow specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using POST method
300     Log    ${flow_body}
301     ${resp}=    RequestsLibrary.Post    session    ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}    data=${flow_body}
302     Log    ${resp.content}
303     ${msg}=    Set Variable    Adding flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id} failed, http response ${resp.status_code} received.
304     Should Be Equal As Strings    ${resp.status_code}    204    msg=${msg}
305
306 Update Flow Via RPC
307     [Arguments]    ${node_id}    ${configured_flow_body}    ${updating_flow_body}
308     [Documentation]    Updates a flow by using update-flow operation. ${xmlroot} is usually a variable created by
309     ...    Create Flow Variables For Suite From XML File keyword from this library.
310     Log    ${configured_flow_body}
311     Log    ${updating_flow_body}
312     ${xml}    Parse Xml    <input xmlns="urn:opendaylight:flow:service"></input>
313     Log Element    ${xml}
314     ${origflow}=    Parse Xml    ${configured_flow_body}
315     ${updflow}=    Parse Xml    ${updating_flow_body}
316     Remove Element    ${origflow}    id    clear_tail=True
317     Remove Element    ${updflow}    id    clear_tail=True
318     Remove Element Attribute    ${origflow}    xmlns
319     Remove Element Attribute    ${updflow}    xmlns
320     Set Element Tag    ${origflow}    original-flow
321     Set Element Tag    ${updflow}    updated-flow
322     Add Element    ${xml}    ${origflow}
323     Add Element    ${xml}    ${updflow}
324     Add Element    ${xml}    <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
325     ${nodeelm}=    Get Element    ${xml}    node
326     Set Element Attribute    ${nodeelm}    xmlns:inv    urn:opendaylight:inventory
327     Log Element    ${xml}
328     ${strxml}=    Element To String    ${xml}
329     ${resp}=    RequestsLibrary.Post    session    /restconf/operations/sal-flow:update-flow    data=${strxml}
330     Log    ${resp.content}
331     Should Be Equal As Strings    ${resp.status_code}    200
332
333 Update Flow Via Restconf
334     [Arguments]    ${node_id}    ${table_id}    ${flow_id}    ${flow_body}
335     [Documentation]    Updates a flow configuration by given flow details (${node_id}, ${table_id}, ${flow_body}) using PUT method
336     Log    ${flow_body}
337     ${resp}=    RequestsLibrary.Put    session    ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id}    data=${flow_body}
338     Log    ${resp.content}
339     ${msg}=    Set Variable    Updating flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id} failed, http response ${resp.status_code} received.
340     Should Be Equal As Strings    ${resp.status_code}    200    msg=${msg}
341
342 Delete Flow Via RPC
343     [Arguments]    ${node_id}    ${xmlroot}
344     [Documentation]    Deletes a flow by using remove-flow opearation. ${xmlroot} is usually a variable created by
345     ...    Create Flow Variables For Suite From XML File keyword from this library.
346     ${req}=    Copy Element    ${xmlroot}
347     Remove Element    ${req}    id    clear_tail=True
348     Set Element Tag    ${req}    input
349     Set Element Attribute    ${req}    xmlns    urn:opendaylight:flow:service
350     Add Element    ${req}    <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
351     ${nodeelm}=    Get Element    ${req}    node
352     Set Element Attribute    ${nodeelm}    xmlns:inv    urn:opendaylight:inventory
353     Log Element    ${req}
354     ${strxml}=    Element To String    ${req}
355     ${resp}=    RequestsLibrary.Post    session    /restconf/operations/sal-flow:remove-flow    data=${strxml}
356     Log    ${resp.content}
357     Should Be Equal As Strings    ${resp.status_code}    200
358
359 Delete Flow Via Restconf
360     [Arguments]    ${node_id}    ${table_id}    ${flow_id}
361     [Documentation]    Deletes a flow from configuration datastore specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using DELETE method
362     ${resp}=    RequestsLibrary.Delete    session    ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id}
363     Log    ${resp.content}
364     ${msg}=    Set Variable    Delete flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id} failed, http response ${resp.status_code} received.
365     Should Be Equal As Strings    ${resp.status_code}    200    msg=${msg}