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 : FOR ${switch} IN RANGE 1 ${switches+1}
22 \ Should Not Contain ${resp.content} "openflow:${switch}"
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}
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}
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
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}
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}
53 [Documentation] Check number of links in the topolgy.
54 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
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}
61 [Arguments] ${switches}
62 [Documentation] Check Linear topology.
63 ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
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"
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}
85 [Documentation] Check number of flows in the inventory.
86 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
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}
92 Check Number Of Groups
94 [Documentation] Check number of groups in the inventory.
95 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
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}
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
106 Should Be Equal As Strings ${resp.status_code} 200
107 Should Contain X Times ${resp.content} priority ${flows}
109 Check Number Of Hosts
111 [Documentation] Check number of hosts in topology
112 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
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}
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:
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
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
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
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
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.
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}
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
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
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
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
221 [Documentation] Will clean out any existing flow actions in the given ${flow} object
222 Remove Flow XML Element ${flow} instructions/instruction
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}
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}
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}
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}
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}
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}
275 Should Be Equal As Strings ${resp.status_code} 200
276 Compare Xml ${group_body} ${resp.content}
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}
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}
286 Should Be Equal As Strings ${resp.status_code} 200
287 Compare Xml ${flow_body} ${resp.content}
289 Verify Flow On Mininet Switch
290 [Arguments] ${flow_elements}
291 [Documentation] Checking flow on switch
293 Write dpctl dump-flows -O OpenFlow13
294 ${switchoutput} Read Until >
295 : FOR ${flowElement} IN @{flow_elements}
296 \ Should Contain ${switchoutput} ${flowElement}
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}
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}
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}
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}
320 Verify Flow Does Not Exist On Mininet Switch
321 [Arguments] ${flow_elements}
322 [Documentation] Checking flow on switch is removed
324 Write dpctl dump-flows -O OpenFlow13
325 ${switchoutput} Read Until >
326 : FOR ${flowElement} IN @{flow_elements}
327 \ Should Not Contain ${switchoutput} ${flowElement}
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}
345 Should Be Equal As Strings ${resp.status_code} 200
346 ${resp}= RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}
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}
352 Create Flow Variables For Suite From XML 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}
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}
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}
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}
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}
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}
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}
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}
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}
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
441 ${strxml}= Element To String ${req}
442 ${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:add-flow data=${strxml}
444 Should Be Equal As Strings ${resp.status_code} 200
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
450 ${resp}= RequestsLibrary.Post Request session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id} data=${flow_body}
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}
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>
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
477 ${strxml}= Element To String ${xml}
478 ${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:update-flow data=${strxml}
480 Should Be Equal As Strings ${resp.status_code} 200
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
486 ${resp}= RequestsLibrary.Put Request session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id} data=${flow_body}
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}
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
503 ${strxml}= Element To String ${req}
504 ${resp}= RequestsLibrary.Post Request session /restconf/operations/sal-flow:remove-flow data=${strxml}
506 Should Be Equal As Strings ${resp.status_code} 200
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}
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}
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]