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