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".
8 Library RequestsLibrary
11 Library XmlComparator.py
13 Variables ../variables/Variables.py
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}
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}"
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}
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}
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
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}
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}
54 [Documentation] Check number of links in the topolgy.
55 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
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}
62 [Arguments] ${switches}
63 [Documentation] Check Linear topology.
64 ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
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"
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}
86 [Documentation] Check number of flows in the inventory.
87 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
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}
93 Check Number Of Groups
95 [Documentation] Check number of groups in the inventory.
96 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
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}
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
108 Should Be Equal As Strings ${resp.status_code} 200
109 Should Contain X Times ${resp.content} priority ${flows}
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
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
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.
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}
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
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
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
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
193 [Documentation] Will clean out any existing flow actions in the given ${flow} object
194 Remove Flow XML Element ${flow} instructions/instruction
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}
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}
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}
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}
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}
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}
247 Should Be Equal As Strings ${resp.status_code} 200
248 Compare Xml ${group_body} ${resp.content}
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}
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}
258 Should Be Equal As Strings ${resp.status_code} 200
259 Compare Xml ${flow_body} ${resp.content}
261 Verify Flow On Mininet Switch
262 [Arguments] ${flow_elements}
263 [Documentation] Checking flow on switch
265 Write dpctl dump-flows -O OpenFlow13
266 ${switchoutput} Read Until >
267 : FOR ${flowElement} IN @{flow_elements}
268 \ Should Contain ${switchoutput} ${flowElement}
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}
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}
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}
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}
292 Verify Flow Does Not Exist On Mininet Switch
293 [Arguments] ${flow_elements}
294 [Documentation] Checking flow on switch is removed
296 Write dpctl dump-flows -O OpenFlow13
297 ${switchoutput} Read Until >
298 : FOR ${flowElement} IN @{flow_elements}
299 \ Should Not Contain ${switchoutput} ${flowElement}
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}
317 Should Be Equal As Strings ${resp.status_code} 200
318 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
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}
324 Create Flow Variables For Suite From XML 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}
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}
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}
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}
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}
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}
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}
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}
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}
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
413 ${strxml}= Element To String ${req}
414 ${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:add-flow data=${strxml}
416 Should Be Equal As Strings ${resp.status_code} 200
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
422 ${resp}= RequestsLibrary.Post Request session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id} data=${flow_body}
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}
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>
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
449 ${strxml}= Element To String ${xml}
450 ${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:update-flow data=${strxml}
452 Should Be Equal As Strings ${resp.status_code} 200
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
458 ${resp}= RequestsLibrary.Put Request session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id} data=${flow_body}
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}
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
475 ${strxml}= Element To String ${req}
476 ${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:remove-flow data=${strxml}
478 Should Be Equal As Strings ${resp.status_code} 200
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}
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}