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