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