Increase WUKS timeout due to change of behavior
[integration/test.git] / 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). TODO: Remove hard dependency on controller HTTP "session".
6 Library           XML
7 Library           String
8 Library           RequestsLibrary
9 Library           ScaleClient.py
10 Library           FlowLib.py
11 Library           XmlComparator.py
12 Library           Common.py
13 Variables         ../variables/Variables.py
14
15 *** Keywords ***
16 Check No Switches In Inventory
17     [Arguments]    ${switches}
18     [Documentation]    Check no switch is in inventory
19     ${resp}    RequestsLibrary.Get Request    session    ${OPERATIONAL_NODES_API}
20     Log    ${resp.content}
21     : FOR    ${switch}    IN RANGE    1    ${switches+1}
22     \    Should Not Contain    ${resp.content}    "openflow:${switch}"
23
24 Check No Switches In Topology
25     [Arguments]    ${switches}
26     [Documentation]    Check no switch is in topology
27     ${resp}    RequestsLibrary.Get Request    session    ${OPERATIONAL_TOPO_API}
28     Log    ${resp.content}
29     Should Be Equal As Strings    ${resp.status_code}    200
30     : FOR    ${switch}    IN RANGE    1    ${switches+1}
31     \    Should Not Contain    ${resp.content}    openflow:${switch}
32
33 Check Switches In Inventory
34     [Arguments]    ${switches}
35     [Documentation]    Check all switches and stats in operational inventory
36     : FOR    ${switch}    IN RANGE    1    ${switches+1}
37     \    ${resp}    RequestsLibrary.Get Request    session    ${OPERATIONAL_NODES_API}/node/openflow:${switch}
38     \    Log    ${resp.content}
39     \    Should Be Equal As Strings    ${resp.status_code}    200
40     \    Should Contain    ${resp.content}    flow-capable-node-connector-statistics
41     \    Should Contain    ${resp.content}    flow-table-statistics
42
43 Check Switches In Topology
44     [Arguments]    ${switches}
45     [Documentation]    Check switches are in the topology.
46     ${resp}=    RequestsLibrary.Get Request    session    ${OPERATIONAL_TOPO_API}
47     Log    ${resp.content}
48     Should Be Equal As Strings    ${resp.status_code}    200
49     ${count}=    Get Count    ${resp.content}    "node-id":"openflow:
50     BuiltIn.Should Be Equal As Numbers    ${count}    ${switches}
51
52 Check Number Of Links
53     [Arguments]    ${links}
54     [Documentation]    Check number of links in the topolgy.
55     ${resp}=    RequestsLibrary.Get Request    session    ${OPERATIONAL_TOPO_API}
56     Log    ${resp.content}
57     Should Be Equal As Strings    ${resp.status_code}    200
58     ${count}=    Get Count    ${resp.content}    "link-id":"openflow:
59     Should Be Equal As Integers    ${count}    ${links}
60
61 Check Linear Topology
62     [Arguments]    ${switches}
63     [Documentation]    Check Linear topology.
64     ${resp}    RequestsLibrary.Get Request    session    ${OPERATIONAL_TOPO_API}
65     Log    ${resp.content}
66     Should Be Equal As Strings    ${resp.status_code}    200
67     : FOR    ${switch}    IN RANGE    1    ${switches+1}
68     \    Should Contain    ${resp.content}    "node-id":"openflow:${switch}"
69     \    Should Contain    ${resp.content}    "tp-id":"openflow:${switch}:1"
70     \    Should Contain    ${resp.content}    "tp-id":"openflow:${switch}:2"
71     \    Should Contain    ${resp.content}    "source-tp":"openflow:${switch}:2"
72     \    Should Contain    ${resp.content}    "dest-tp":"openflow:${switch}:2"
73     \    ${edge}    Evaluate    ${switch}==1 or ${switch}==${switches}
74     \    Run Keyword Unless    ${edge}    Should Contain    ${resp.content}    "tp-id":"openflow:${switch}:3"
75     \    Run Keyword Unless    ${edge}    Should Contain    ${resp.content}    "source-tp":"openflow:${switch}:3"
76     \    Run Keyword Unless    ${edge}    Should Contain    ${resp.content}    "dest-tp":"openflow:${switch}:3"
77
78 Check Flows Operational Datastore
79     [Arguments]    ${flow_count}    ${controller_ip}=${ODL_SYSTEM_IP}
80     [Documentation]    Check if number of Operational Flows on member of given index is equal to ${flow_count}.
81     ${sw}    ${reported_flow}    ${found_flow}=    ScaleClient.Flow Stats Collected    controller=${controller_ip}
82     Should_Be_Equal_As_Numbers    ${flow_count}    ${found_flow}
83
84 Check Number Of Flows
85     [Arguments]    ${flows}
86     [Documentation]    Check number of flows in the inventory.
87     ${resp}=    RequestsLibrary.Get Request    session    ${OPERATIONAL_NODES_API}
88     Log    ${resp.content}
89     Should Be Equal As Strings    ${resp.status_code}    200
90     ${count}=    Get Count    ${resp.content}    "priority"
91     Should Be Equal As Integers    ${count}    ${flows}
92
93 Check Number Of Groups
94     [Arguments]    ${groups}
95     [Documentation]    Check number of groups in the inventory.
96     ${resp}=    RequestsLibrary.Get Request    session    ${OPERATIONAL_NODES_API}
97     Log    ${resp.content}
98     Should Be Equal As Strings    ${resp.status_code}    200
99     ${group_count}=    Get Count    ${resp.content}    "group-type"
100     Should Be Equal As Integers    ${group_count}    ${groups}
101
102 Check Flow Stats Are Available
103     [Arguments]    ${node_id}    ${flows}
104     [Documentation]    A GET on the /node/${node_id} inventory API is made and flow stats string is checked for existence.
105     ${resp}    RequestsLibrary.Get Request    session    ${OPERATIONAL_NODES_API}/node/${node_id}/table/2
106     Log    ${resp.content}
107     Should Be Equal As Strings    ${resp.status_code}    200
108     Should Contain X Times    ${resp.content}    priority    ${flows}
109
110 Check Number Of Hosts
111     [Arguments]    ${hosts}
112     [Documentation]    Check number of hosts in topology
113     ${resp}=    RequestsLibrary.Get Request    session    ${OPERATIONAL_TOPO_API}
114     Log    ${resp.content}
115     Should Be Equal As Strings    ${resp.status_code}    200
116     ${count}=    Get Count    ${resp.content}    "node-id":"host:
117     Should Be Equal As Integers    ${count}    ${hosts}
118
119 Check No Hosts
120     [Documentation]    Check if all hosts are deleted from inventory
121     ${resp}=    RequestsLibrary.Get Request    session    ${OPERATIONAL_TOPO_API}
122     Should Be Equal As Strings    ${resp.status_code}    200
123     Should Not Contain    ${resp.content}    "node-id":"host:
124
125 Add Table Miss Flows
126     [Arguments]    ${switches}
127     [Documentation]    Add table miss flows to switches.
128     ${switches}=    Convert To Integer    ${switches}
129     ${data}=    OperatingSystem.Get File    ${CURDIR}/../variables/openflowplugin/table_miss_flow.json
130     : FOR    ${switch}    IN RANGE    1    ${switches+1}
131     \    TemplatedRequests.Put As Json To Uri    ${CONFIG_NODES_API}/node/openflow:${switch}/table/0/flow/default    ${data}    session
132
133 Check Table Miss Flows
134     [Arguments]    ${switches}
135     [Documentation]    Check table miss flows in switches.
136     ${switches}=    Convert To Integer    ${switches}
137     : FOR    ${switch}    IN RANGE    1    ${switches+1}
138     \    TemplatedRequests.Get As Json From Uri    ${OPERATIONAL_NODES_API}/node/openflow:${switch}/table/0/flow/default    session
139
140 Create Inventory Flow
141     [Documentation]    Calls FlowLib.Make_Inventory_Flow function and initializes and sanitizes
142     ...    the basic flow elements that can be given to flow:inventory
143     ${flow}=    Make Inventory Flow
144     [Return]    ${flow}
145
146 Create Service Flow
147     [Documentation]    Used for creating an object that will use an XML format that
148     ...    can be given to flow:service.
149     ${flow}=    Make Service Flow
150     [Return]    ${flow}
151
152 Set "${flow}" "${property}" With "${property_val}"
153     [Documentation]    Embedded variables to make higher level keywords more readable.
154     ...    There are some cases where the python attribute uses an underscore,
155     ...    but a hyphen needs to be used. This seems inconsistent, and may need
156     ...    to be looked at from the openflow plugin perspective.
157     ...
158     ...    At this point, this library will remove the element ${property} from the
159     ...    xml representation of the flow and reset with the given value. \ It's not
160     ...    possible, yet, to have multiple elements with the same name. \ That will
161     ...    likely be needed in the future.
162     ${property}    Run Keyword If    "table_id" != "${property}" and "cookie_mask" != "${property}"    Replace String    ${property}    _    -
163     ...    ELSE    Set Variable    ${property}
164     Remove Flow XML Element    ${flow}    ${property}
165     Add Flow XML Element    ${flow}    ${property}    ${property_val}
166     Set Flow Field    ${flow}    ${property}    ${property_val}
167     [Return]    ${flow}
168
169 Set Flow Action
170     [Arguments]    ${flow}    ${instruction_order}    ${action_order}    ${action}    ${action_val}=${EMPTY}
171     [Documentation]    Will remove the instruction element first, then add the proper xml structure
172     ...    to implement the action as given in the arguments
173     ##For the case that any of the instruction/apply-actions/action elements are not there we need to add them'
174     Remove Flow XML Element    ${flow}    instruction
175     Add Flow XML Element    ${flow}    instruction    ${EMPTY}    instructions
176     Add Flow XML Element    ${flow}    order    ${instruction_order}    instructions/instruction
177     Add Flow XML Element    ${flow}    apply-actions    ${EMPTY}    instructions/instruction
178     Add Flow XML Element    ${flow}    action    ${EMPTY}    instructions/instruction/apply-actions
179     Add Flow XML Element    ${flow}    order    ${action_order}    instructions/instruction/apply-actions/action
180     Add Flow XML Element    ${flow}    ${action}    ${action_val}    instructions/instruction/apply-actions/action
181     [Return]    ${flow}
182
183 Set Flow Output Action
184     [Arguments]    ${flow}    ${instruction_order}    ${action_order}    ${output_port}
185     Set Flow Action    ${flow}    ${instruction_order}    ${action_order}    output-action
186     Add Flow XML Element    ${flow}    output-node-connector    ${output_port}    instructions/instruction/apply-actions/action/output-action
187     [Return]    ${flow}
188
189 Set Flow Ethernet Match
190     [Arguments]    ${flow}    ${match_value_dict}
191     [Documentation]    Specific keyword for adding an ethernet match rules where the elements are given
192     ...    in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
193     ...    existing ethernet-match elements from the flow before adding
194     Clear Flow Matches    ${flow}    match/ethernet-match
195     Add Flow XML Element    ${flow}    ethernet-match    ${EMPTY}    match
196     ${type}=    Get From Dictionary    ${match_value_dict}    type
197     Add Flow XML Element    ${flow}    ethernet-type    ${EMPTY}    match/ethernet-match
198     Add Flow XML Element    ${flow}    type    ${type}    match/ethernet-match/ethernet-type
199     ${src}=    Get From Dictionary    ${match_value_dict}    source
200     Add Flow XML Element    ${flow}    ethernet-source    ${EMPTY}    match/ethernet-match
201     Add Flow XML Element    ${flow}    address    ${src}    match/ethernet-match/ethernet-source
202     ${dst}=    Get From Dictionary    ${match_value_dict}    destination
203     Add Flow XML Element    ${flow}    ethernet-destination    ${EMPTY}    match/ethernet-match
204     Add Flow XML Element    ${flow}    address    ${dst}    match/ethernet-match/ethernet-destination
205     [Return]    ${flow}
206
207 Set Flow IPv4 Match
208     [Arguments]    ${flow}    ${match_value_dict}
209     [Documentation]    Specific keyword for adding an ipv4 match rules where the elements are given
210     ...    in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
211     ...    existing ipv4 match elements from the flow before adding
212     Clear Flow Matches    ${flow}    match/ipv4-source
213     Clear Flow Matches    ${flow}    match/ipv4-destination
214     ${src}=    Get From Dictionary    ${match_value_dict}    source
215     Add Flow XML Element    ${flow}    ipv4-source    ${src}    match
216     ${dst}=    Get From Dictionary    ${match_value_dict}    destination
217     Add Flow XML Element    ${flow}    ipv4-destination    ${dst}    match
218     [Return]    ${flow}
219
220 Clear Flow Actions
221     [Arguments]    ${flow}
222     [Documentation]    Will clean out any existing flow actions in the given ${flow} object
223     Remove Flow XML Element    ${flow}    instructions/instruction
224     [Return]    ${flow}
225
226 Clear Flow Matches
227     [Arguments]    ${flow}    ${match_element}
228     [Documentation]    Will clean out any existing flow matches in the given ${flow} object
229     Remove Flow XML Element    ${flow}    match/${match_element}
230     [Return]    ${flow}
231
232 Set Flow XML Element Attribute
233     [Arguments]    ${flow}    ${element}    ${id}    ${value}
234     [Documentation]    Will set the given id/value pair to the given to the element provided
235     ...    and make the proper changes to the ${flow} object also provided.
236     ${flow_xml}=    Parse XML    ${flow.xml}
237     Set Element Attribute    ${flow_xml}    ${id}    ${value}    xpath=${element}
238     ${xml_string}=    Element To String    ${flow_xml}
239     Set Flow Field    ${flow}    xml    ${xml_string}
240     Log    ${flow.xml}
241     [Return]    ${flow}
242
243 Add Flow XML Element
244     [Arguments]    ${flow}    ${element}    ${element_val}=${EMPTY}    ${xpath}=.
245     [Documentation]    Will modify the current xml representation of the ${flow} object to contain
246     ...    the given ${element} at the given ${xpath}. If the ${element} uses a value, that can be
247     ...    passed eith the ${element_val} which defaults to ${EMPTY} if not used. NOTE: since there
248     ...    are two default parameters to this keyword, if you have an ${xpath} to use, but no ${element_val}
249     ...    you will still need to pass ${EMPTY} when invoking so that ${xpath} will end up at the right
250     ...    location in the parameter list
251     ${flow_xml}=    Parse XML    ${flow.xml}
252     Add Element    ${flow_xml}    <${element}>${element_val}</${element}>    xpath=${xpath}
253     ${xml_string}=    Element To String    ${flow_xml}
254     Set Flow Field    ${flow}    xml    ${xml_string}
255     Log    ${flow.xml}
256     [Return]    ${flow}
257
258 Remove Flow XML Element
259     [Arguments]    ${flow}    ${element_xpath}
260     [Documentation]    Removes the element at the given ${element_xpath} within the given ${flow}
261     ...    object. The ${flow} object's xml representation will be updated to reflect this removal.
262     ${flow_xml}=    Parse XML    ${flow.xml}
263     Run Keyword And Ignore Error    Remove Elements    ${flow_xml}    xpath=${element_xpath}
264     ${xml_string}=    Element To String    ${flow_xml}
265     Set Flow Field    ${flow}    xml    ${xml_string}
266     [Return]    ${flow}
267
268 Add Group To Controller And Verify
269     [Arguments]    ${group_body}    ${node_id}    ${group_id}
270     [Documentation]    Push group through REST-API and verify in data-store
271     ${resp}    RequestsLibrary.Put Request    session    ${CONFIG_NODES_API}/node/${node_id}/group/${group_id}    headers=${HEADERS_XML}    data=${group_body}
272     Log    ${resp.content}
273     BuiltIn.Should_Match    "${resp.status_code}"    "20?"
274     ${resp}    RequestsLibrary.Get Request    session    ${CONFIG_NODES_API}/node/${node_id}/group/${group_id}    headers=${ACCEPT_XML}
275     Log    ${resp.content}
276     Should Be Equal As Strings    ${resp.status_code}    200
277     Compare Xml    ${group_body}    ${resp.content}
278
279 Add Flow To Controller And Verify
280     [Arguments]    ${flow_body}    ${node_id}    ${table_id}    ${flow_id}
281     [Documentation]    Push flow through REST-API and verify in data-store
282     ${resp}    RequestsLibrary.Put Request    session    ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id}    headers=${HEADERS_XML}    data=${flow_body}
283     Log    ${resp.content}
284     BuiltIn.Should_Match    "${resp.status_code}"    "20?"
285     ${resp}    RequestsLibrary.Get Request    session    ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id}    headers=${ACCEPT_XML}
286     Log    ${resp.content}
287     Should Be Equal As Strings    ${resp.status_code}    200
288     Compare Xml    ${flow_body}    ${resp.content}
289
290 Verify Flow On Mininet Switch
291     [Arguments]    ${flow_elements}
292     [Documentation]    Checking flow on switch
293     Sleep    1
294     Write    dpctl dump-flows -O OpenFlow13
295     ${switchoutput}    Read Until    >
296     : FOR    ${flowElement}    IN    @{flow_elements}
297     \    Should Contain    ${switchoutput}    ${flowElement}
298
299 Remove Group From Controller And Verify
300     [Arguments]    ${node_id}    ${group_id}
301     [Documentation]    Remove group and verify
302     ${resp}    RequestsLibrary.Delete Request    session    ${CONFIG_NODES_API}/node/${node_id}/group/${group_id}
303     Log    ${resp.content}
304     Should Be Equal As Strings    ${resp.status_code}    200
305     ${resp}    RequestsLibrary.Get Request    session    ${CONFIG_NODES_API}/node/${node_id}/group/${group_id}
306     Builtin.Return_From_Keyword_If    ${resp.status_code} == 404
307     Builtin.Log    ${resp.text}
308     Builtin.Fail    The request failed with code ${resp.status_code}
309
310 Remove Flow From Controller And Verify
311     [Arguments]    ${node_id}    ${table_id}    ${flow_id}
312     [Documentation]    Remove flow and verify
313     ${resp}    RequestsLibrary.Delete Request    session    ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id}
314     Log    ${resp.content}
315     Should Be Equal As Strings    ${resp.status_code}    200
316     ${resp}    RequestsLibrary.Get Request    session    ${CONFIG_NODES_API}/node/${node_id}/table/${table_id}/flow/${flow_id}
317     Builtin.Return_From_Keyword_If    ${resp.status_code} == 404
318     Builtin.Log    ${resp.text}
319     Builtin.Fail    The request failed with code ${resp.status_code}
320
321 Verify Flow Does Not Exist On Mininet Switch
322     [Arguments]    ${flow_elements}
323     [Documentation]    Checking flow on switch is removed
324     Sleep    1
325     Write    dpctl dump-flows -O OpenFlow13
326     ${switchoutput}    Read Until    >
327     : FOR    ${flowElement}    IN    @{flow_elements}
328     \    Should Not Contain    ${switchoutput}    ${flowElement}
329
330 Remove Default Flows
331     [Arguments]    ${node_id}
332     [Documentation]    Removes any flows considered "default". one such flow is
333     ...    to forward all traffic to the CONTROLLER with priority 0 at flow-table 0
334     ...    If/When others are implemented this keyword can be updated to include those.
335     ${flow}=    Make Service Flow
336     Set "${flow}" "priority" With "0"
337     Set "${flow}" "flow-table" With "0"
338     Add Flow XML Element    ${flow}    node    /inv:nodes/inv:node[inv:id="${node_id}"]
339     Set Flow XML Element Attribute    ${flow}    node    xmlns:inv    urn:opendaylight:inventory
340     Log    Flow XML is ${flow.xml}
341     write    dpctl dump-flows -O OpenFlow13
342     ${switchoutput}    Read Until    >
343     ${headers}=    Create Dictionary    Content-Type=application/yang.data+xml
344     ${resp}    RequestsLibrary.Post Request    session    restconf/operations/sal-flow:remove-flow    data=${flow.xml}    headers=${headers}
345     Log    ${resp.content}
346     Should Be Equal As Strings    ${resp.status_code}    200
347     ${resp}=    RequestsLibrary.Get Request    session    ${OPERATIONAL_NODES_API}
348     Log    ${resp.content}
349     Should Not Contain    ${resp.content}    "output-node-connector": "CONTROLLER",
350     ${strings_to_check_for}=    Create List    CONTROLLER
351     Verify Flow Does Not Exist On Mininet Switch    ${strings_to_check_for}
352
353 Create Flow Variables For Suite From XML File
354     [Arguments]    ${file}
355     [Documentation]    Given the flow XML ${file}, it will create several suite wide variables
356     ${data}=    OperatingSystem.Get File    ${file}
357     ${xmlroot}=    Parse Xml    ${file}
358     ${table_id}=    Get Element Text    ${xmlroot}    table_id
359     ${flow_id}=    Get Element Text    ${xmlroot}    id
360     ${flow_priority}=    Get Element Text    ${xmlroot}    priority
361     ${upddata}=    Get Data For Flow Put Update    ${data}
362     Set Suite Variable    ${table_id}
363     Set Suite Variable    ${flow_id}
364     Set Suite Variable    ${flow_priority}
365     Set Suite Variable    ${data}
366     Set Suite Variable    ${upddata}
367     Set Suite Variable    ${xmlroot}
368
369 Check Datastore Presence
370     [Arguments]    ${fname}    ${reqconfpres}    ${reqoperpres}    ${upd}    ${check_id}=${False}
371     [Documentation]    Checks if flow is properly existing or not existing in the config and operational
372     ...    datastores, based on the variables ${reqconfpres} and ${reqoperpres}
373     Create Flow Variables For Suite From XML File    ${XmlsDir}/${fname}
374     # Note:    ${upddata} and ${data} are suite variables set by the keyword above.
375     ${det}=    Set Variable If    ${upd}==${True}    ${upddata}    ${data}
376     Check Config Flow    ${reqconfpres}    ${det}
377     Check Operational Flow    ${reqoperpres}    ${det}    ${check_id}
378
379 Flow Presence In Config Store
380     [Arguments]    ${expvalue}
381     [Documentation]    Checks the config store for given flow. Returns True if present, otherwise returns False
382     ...    This keyword assumes that the global/suite variables are available (${table_id}, ${flow_id} and ${switch_idx}
383     ${headers}=    Create Dictionary    Accept=application/xml
384     ${resp}=    RequestsLibrary.Get Request    session    ${CONFIG_NODES_API}/node/openflow:${switch_idx}/table/${table_id}/flow/${flow_id}    headers=${headers}
385     Log    ${resp}
386     Log    ${resp.content}
387     Return From Keyword If    ${resp.status_code}!=200    ${False}    ${EMPTY}
388     ${pres}    ${msg}=    Is Flow Configured    ${expvalue}    ${resp.content}
389     Run Keyword If    '''${msg}'''!='${EMPTY}'    Log    ${msg}
390     Return From Keyword    ${pres}    ${msg}
391
392 Flow Presence In Operational Store
393     [Arguments]    ${expvalue}    ${check_id}=${False}
394     [Documentation]    Checks the operational store for given flow. Returns True if present, otherwise returns False
395     ...    This keyword assumes that the global/suite variables are available (${table_id}, ${flow_id} and ${switch_idx}
396     ${headers}=    Create Dictionary    Accept=application/xml
397     ${resp}=    RequestsLibrary.Get Request    session    ${OPERATIONAL_NODES_API}/node/openflow:${switch_idx}/table/${table_id}    headers=${headers}
398     Log    ${resp}
399     Log    ${resp.content}
400     Return From Keyword If    ${resp.status_code}!=200    ${False}    ${EMPTY}
401     ${pres}    ${msg}=    Is Flow Operational2    ${expvalue}    ${resp.content}    ${check_id}
402     Run Keyword If    '''${msg}'''!='${EMPTY}'    Log    ${msg}
403     Return From Keyword    ${pres}    ${msg}
404
405 Get Presence Failure Message
406     [Arguments]    ${ds}    ${expected}    ${presence}    ${diffmsg}
407     [Documentation]    Utility keyword to help manipulate mesage strings that may be used later to PASS or FAIL with
408     Return From Keyword If    '''${diffmsg}'''!='${EMPTY}'    Flow found in ${ds} data store but: ${diffmsg}
409     ${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
410     ${msgp}=    Set Variable If    ${presence}==${True}    it is present.    it is not present.
411     Return From Keyword    ${msgf} ${msgp}
412
413 Check Config Flow
414     [Arguments]    ${expected}    ${expvalue}
415     [Documentation]    Wrapper keyword that calls "Flow Presence In Config Store" and "Get Presence Failure Message" from this library
416     ...    to verify that the ${expvalue} flow is or is not found in the config store, depending on whether or not it was ${expected}
417     ${presence_flow}    ${msg}=    Flow Presence In Config Store    ${expvalue}
418     ${msgf}=    Get Presence Failure Message    config    ${expected}    ${presence_flow}    ${msg}
419     Should Be Equal    ${expected}    ${presence_flow}    msg=${msgf}
420
421 Check Operational Flow
422     [Arguments]    ${expected}    ${expvalue}    ${check_id}=${False}
423     [Documentation]    Wrapper keyword that calls "Flow Presence In Operational Store" and "Get Presence Failure Message" from this library
424     ...    to verify that the ${expvalue} flow is or is not found in the operational store, depending on whether or not it was ${expected}
425     ${presence_table}    ${msg}=    Flow Presence In Operational Store    ${expvalue}    ${check_id}
426     ${msgf}=    Get Presence Failure Message    operational    ${expected}    ${presence_table}    ${msg}
427     Should Be Equal    ${expected}    ${presence_table}    msg=${msgf}
428
429 Add Flow Via RPC
430     [Arguments]    ${node_id}    ${xmlroot}
431     [Documentation]    Deploys a flow specified by given flow details (${node_id}, ${xmlroot}) using add-flow operation.
432     ...    ${xmlroot} is an xml object of parser xml flow details, usually created by Create Flow Variables For Suite From XML File
433     ...    keyword from this library.
434     ${req}=    Copy Element    ${xmlroot}
435     Remove Element    ${req}    id    clear_tail=True
436     Set Element Tag    ${req}    input
437     Set Element Attribute    ${req}    xmlns    urn:opendaylight:flow:service
438     Add Element    ${req}    <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
439     ${nodeelm}=    Get Element    ${req}    node
440     Set Element Attribute    ${nodeelm}    xmlns:inv    urn:opendaylight:inventory
441     Log Element    ${req}
442     ${strxml}=    Element To String    ${req}
443     ${resp}=    RequestsLibrary.Post Request    session    /restconf/operations/sal-flow:add-flow    data=${strxml}
444     Log    ${resp.content}
445     Should Be Equal As Strings    ${resp.status_code}    200
446
447 Add Flow Via Restconf
448     [Arguments]    ${node_id}    ${table_id}    ${flow_body}
449     [Documentation]    Configures a flow specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using POST method
450     Log    ${flow_body}
451     ${resp}=    RequestsLibrary.Post Request    session    ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}    data=${flow_body}
452     Log    ${resp.content}
453     ${msg}=    Set Variable    Adding flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id} failed, http response ${resp.status_code} received.
454     Should Be Equal As Strings    ${resp.status_code}    204    msg=${msg}
455
456 Update Flow Via RPC
457     [Arguments]    ${node_id}    ${configured_flow_body}    ${updating_flow_body}
458     [Documentation]    Updates a flow by using update-flow operation. ${xmlroot} is usually a variable created by
459     ...    Create Flow Variables For Suite From XML File keyword from this library.
460     Log    ${configured_flow_body}
461     Log    ${updating_flow_body}
462     ${xml}    Parse Xml    <input xmlns="urn:opendaylight:flow:service"></input>
463     Log Element    ${xml}
464     ${origflow}=    Parse Xml    ${configured_flow_body}
465     ${updflow}=    Parse Xml    ${updating_flow_body}
466     Remove Element    ${origflow}    id    clear_tail=True
467     Remove Element    ${updflow}    id    clear_tail=True
468     Remove Element Attribute    ${origflow}    xmlns
469     Remove Element Attribute    ${updflow}    xmlns
470     Set Element Tag    ${origflow}    original-flow
471     Set Element Tag    ${updflow}    updated-flow
472     Add Element    ${xml}    ${origflow}
473     Add Element    ${xml}    ${updflow}
474     Add Element    ${xml}    <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
475     ${nodeelm}=    Get Element    ${xml}    node
476     Set Element Attribute    ${nodeelm}    xmlns:inv    urn:opendaylight:inventory
477     Log Element    ${xml}
478     ${strxml}=    Element To String    ${xml}
479     ${resp}=    RequestsLibrary.Post Request    session    /restconf/operations/sal-flow:update-flow    data=${strxml}
480     Log    ${resp.content}
481     Should Be Equal As Strings    ${resp.status_code}    200
482
483 Update Flow Via Restconf
484     [Arguments]    ${node_id}    ${table_id}    ${flow_id}    ${flow_body}
485     [Documentation]    Updates a flow configuration by given flow details (${node_id}, ${table_id}, ${flow_body}) using PUT method
486     Log    ${flow_body}
487     ${resp}=    RequestsLibrary.Put Request    session    ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id}    data=${flow_body}
488     Log    ${resp.content}
489     ${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.
490     Should Be Equal As Strings    ${resp.status_code}    200    msg=${msg}
491
492 Delete Flow Via RPC
493     [Arguments]    ${node_id}    ${xmlroot}
494     [Documentation]    Deletes a flow by using remove-flow opearation. ${xmlroot} is usually a variable created by
495     ...    Create Flow Variables For Suite From XML File keyword from this library.
496     ${req}=    Copy Element    ${xmlroot}
497     Remove Element    ${req}    id    clear_tail=True
498     Set Element Tag    ${req}    input
499     Set Element Attribute    ${req}    xmlns    urn:opendaylight:flow:service
500     Add Element    ${req}    <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
501     ${nodeelm}=    Get Element    ${req}    node
502     Set Element Attribute    ${nodeelm}    xmlns:inv    urn:opendaylight:inventory
503     Log Element    ${req}
504     ${strxml}=    Element To String    ${req}
505     ${resp}=    RequestsLibrary.Post Request    session    /restconf/operations/sal-flow:remove-flow    data=${strxml}
506     Log    ${resp.content}
507     Should Be Equal As Strings    ${resp.status_code}    200
508
509 Delete Flow Via Restconf
510     [Arguments]    ${node_id}    ${table_id}    ${flow_id}
511     [Documentation]    Deletes a flow from configuration datastore specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using DELETE method
512     ${resp}=    RequestsLibrary.Delete Request    session    ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id}
513     Log    ${resp.content}
514     ${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.
515     Should Be Equal As Strings    ${resp.status_code}    200    msg=${msg}
516
517 Get Flow Id
518     [Arguments]    ${dpnid}    ${table_id}    ${flow_element}
519     [Documentation]    This verifies specific flow-id for particular table-id matching from the flow element
520     ${resp} =    RequestsLibrary.Get Request    session    ${CONFIG_NODES_API}/node/openflow:${dpnid}/table/${table_id}
521     BuiltIn.Log    ${resp.content}
522     @{flow_id} =    String.Get Regexp Matches    ${resp.content}    id\":\"(\\d+${flow_element})    1
523     [Return]    @{flow_id}[0]