2 Variables ../variables/Variables.py
3 Variables ../variables/topoprocessing/Topologies.py
4 Variables ../variables/topoprocessing/TopologyRequests.py
5 Library RequestsLibrary
8 Resource KarafKeywords.robot
12 ${CONFIGURATION_XML} ${CURDIR}/../suites/topoprocessing/configuration.xml
13 ${OPERATIONAL_XML} ${CURDIR}/../suites/topoprocessing/operational.xml
14 ${REMOTE_FILE} ${WORKSPACE}/${BUNDLEFOLDER}/etc/opendaylight/karaf/80-topoprocessing-config.xml
15 ${OUTPUT_TOPO_NAME} topo:1
16 ${OVERLAY_TOPO_URL} ${TOPOLOGY_URL}/${OUTPUT_TOPO_NAME}
20 [Arguments] ${request} ${overlay_topology_url}
21 [Documentation] Send a simple HTTP PUT request to Configurational datastore
22 ${resp} Put Request session ${CONFIG_API}/${overlay_topology_url} data=${request}
23 Log ${CONFIG_API}/${overlay_topology_url}
24 Should Be Equal As Strings ${resp.status_code} 200
25 Wait For Karaf Log Correlation configuration successfully read
26 Wait For Karaf Log Transaction successfully written
29 [Arguments] ${overlay_topology_url}
30 [Documentation] Send a simple HTTP GET request to a given URL
31 ${resp} Get Request session ${OPERATIONAL_API}/${overlay_topology_url}
32 Should Be Equal As Strings ${resp.status_code} 200
35 Send Basic Delete Request
37 [Documentation] Sends a HTTP/DELETE request to a given URL
38 ${resp} Delete Request session ${CONFIG_API}/${url}
39 Log Deleting ${CONFIG_API}/${url}
43 [Arguments] ${topology-id} ${node-id}
44 [Documentation] Deletes a node from an underlay topology
45 ${resp} Send Basic Delete Request ${TOPOLOGY_URL}/${topology-id}/node/${node-id}
49 [Documentation] Setup karaf enviroment for following tests
50 Log ---- Setup Environment ----
51 Open Connection ${ODL_SYSTEM_IP}
52 Flexible Controller Login
53 Put File ${CONFIGURATION_XML} ${REMOTE_FILE}
55 Issue Command On Karaf Console log:set DEBUG org.opendaylight.topoprocessing
56 Install a Feature odl-restconf-noauth timeout=30
57 Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${SEND_ACCEPT_XML_HEADERS}
58 ${features} Issue Command On Karaf Console feature:list -i
59 ${lines} Get Lines Containing String ${features} odl-topoprocessing-framework
60 ${length} Get Length ${lines}
61 Install a Feature odl-openflowplugin-nsf-model odl-topoprocessing-framework odl-topoprocessing-network-topology odl-topoprocessing-inventory odl-mdsal-models odl-ovsdb-southbound-impl timeout=120
62 Run Keyword If ${length} == 0 Wait For Karaf Log Registering Topology Request Listener 60
63 Prepare New Feature Installation
64 Insert Underlay topologies
67 [Documentation] Revert startup changes
68 Log ---- Clean Environment ----
69 Open Connection ${ODL_SYSTEM_IP}
70 Flexible Controller Login
71 Put File ${OPERATIONAL_XML} ${REMOTE_FILE}
75 Delete Overlay Topology
76 [Documentation] Delete overlay topologies from datastore
77 Run Keyword If Test Failed Print Output Topo
78 Log ---- Test Teardown ----
79 Log Deleting overlay topology from ${CONFIG_API}/${OVERLAY_TOPO_URL}
80 ${resp} Delete Request session ${CONFIG_API}/${OVERLAY_TOPO_URL}
81 Should Be Equal As Strings ${resp.status_code} 200
84 [Documentation] Waits a while to allow any hanging transactions to finnish and then logs the output topology
85 Log ---- Output Topo Dump After Cooldown----
87 ${resp} Wait Until Keyword Succeeds 5x 250ms Basic Request Get ${OVERLAY_TOPO_URL}
90 Refresh Underlay Topologies And Delete Overlay Topology
91 [Documentation] Deletes given overlay topology from datastore and overwrites the underlaying ones with initial topologies
92 Delete Overlay Topology
93 Insert Underlay Topologies
95 Prepare New Feature Installation
96 [Documentation] Clears karaf logs and CONFIGURATION datastore
97 ${resp} Delete Request session ${CONFIG_API}/network-topology:network-topology
98 ${resp} Delete Request session ${CONFIG_API}/opendaylight-inventory:nodes
99 Issue Command On Karaf Console log:clear
101 Insert Underlay Topologies
102 [Documentation] Insert underlay topologies used by following tests
103 Log Inserting underlay topologies
104 # Network underlay topologies
105 : FOR ${index} IN RANGE 1 7
106 \ ${resp} Put Request session ${CONFIG_API}/${TOPOLOGY_URL}/network-topo:${index} data=${NETWORK_UNDERLAY_TOPOLOGY_${index}}
107 \ Log ${resp.content}
108 \ Should Be Equal As Strings ${resp.status_code} 200
109 # Openflow underlay nodes
110 ${resp} Put Request session ${CONFIG_API}/opendaylight-inventory:nodes data=${OPENFLOW_UNDERLAY_NODES}
112 Should Be Equal As Strings ${resp.status_code} 200
113 # Openflow underlay topologies
114 : FOR ${index} IN RANGE 1 7
115 \ ${resp} Put Request session ${CONFIG_API}/${TOPOLOGY_URL}/openflow-topo:${index} data=${OPENFLOW_UNDERLAY_TOPOLOGY_${index}}
116 \ Log ${resp.content}
117 \ Should Be Equal As Strings ${resp.status_code} 200
118 Issue Command On Karaf Console log:clear
121 Prepare Unification Inside Topology Request
122 [Arguments] ${request_template} ${model} ${correlation_item} ${underlay_topo1}
123 [Documentation] Prepare topology request for unification inside from template
124 ${request_template} Set Element Text ${request_template} ${model} xpath=.//correlations/output-model
125 ${request_template} Set Element Text ${request_template} aggregation-only xpath=.//correlations/correlation/type
126 ${request_template} Set Element Text ${request_template} ${correlation_item} xpath=.//correlation/correlation-item
127 ${request_template} Set Element Text ${request_template} unification xpath=.//correlation/aggregation/aggregation-type
128 ${request_template} Set Element Text ${request_template} ${model} xpath=.//correlation/aggregation/mapping[1]/input-model
129 ${request_template} Set Element Text ${request_template} ${underlay_topo1} xpath=.//correlation/aggregation/mapping[1]/underlay-topology
130 ${request_template} Element to String ${request_template}
131 [Return] ${request_template}
133 Prepare Unification Topology Request
134 [Arguments] ${request_template} ${model} ${correlation_item} ${underlay_topo1} ${underlay_topo2}
135 [Documentation] Prepare topology request for unification on two topologies from template
136 ${request_template} Prepare Unification Inside Topology Request ${request_template} ${model} ${correlation_item} ${underlay_topo1}
137 ${request_template} Set Element Text ${request_template} ${underlay_topo2} xpath=.//correlation/aggregation/mapping[2]/underlay-topology
138 ${request_template} Set Element Text ${request_template} ${model} xpath=.//correlation/aggregation/mapping[2]/input-model
139 ${request_template} Element to String ${request_template}
140 [Return] ${request_template}
142 Prepare Unification Filtration Topology Request
143 [Arguments] ${request_template} ${model} ${correlation_item} ${target_field1} ${underlay_topo1} ${target_field2}
144 ... ${underlay_topo2}
145 [Documentation] Prepare topology request for unification on two topologies from template
146 ${request_template} Prepare Unification Filtration Inside Topology Request ${request_template} ${model} ${correlation_item} ${target_field1} ${underlay_topo1}
147 ${request_template} Set Element Text ${request_template} ${underlay_topo2} xpath=.//correlation/aggregation/mapping[2]/underlay-topology
148 Insert Target Field ${request_template} 2 ${target_field2} 1
149 ${request_template} Set Element Text ${request_template} ${model} xpath=.//correlation/aggregation/mapping[2]/input-model
150 ${request_template} Element to String ${request_template}
151 [Return] ${request_template}
153 Prepare Unification Filtration Inside Topology Request
154 [Arguments] ${request_template} ${model} ${correlation_item} ${target-field} ${underlay_topo}
155 [Documentation] Prepare topology request for unification filtration inside from template
156 ${request_template} Set Element Text ${request_template} ${model} xpath=.//correlations/output-model
157 ${request_template} Set Element Text ${request_template} filtration-aggregation xpath=.//correlations/correlation/type
158 ${request_template} Set Element Text ${request_template} ${correlation_item} xpath=.//correlation/correlation-item
159 ${request_template} Set Element Text ${request_template} unification xpath=.//correlation/aggregation/aggregation-type
160 ${request_template} Set Element Text ${request_template} ${model} xpath=.//correlation/aggregation/mapping[1]/input-model
161 ${request_template} Set Element Text ${request_template} ${underlay_topo} xpath=.//correlation/aggregation/mapping[1]/underlay-topology
162 Insert Target Field ${request_template} 1 ${target-field} 1
163 ${request_template} Set Element Text ${request_template} ${underlay_topo} xpath=.//correlation/filtration/underlay-topology
164 ${request_template} Element to String ${request_template}
165 [Return] ${request_template}
168 [Arguments] ${request_template} ${mapping} ${filter_id}
169 ${request_template} Add Element ${request_template} ${APPLY_FILTERS} xpath=.//correlation/aggregation/mapping[${mapping}]
170 ${request_template} Set Element Text ${request_template} ${filter_id} xpath=.//correlation/aggregation/mapping[${mapping}]/apply-filters
171 [Return] ${request_template}
173 Prepare Filtration Topology Request
174 [Arguments] ${request_template} ${model} ${correlation_item} ${underlay_topo}
175 [Documentation] Prepare topology request for filtration from template
176 ${request_template} Set Element Text ${request_template} ${model} xpath=.//correlations/output-model
177 ${request_template} Set Element Text ${request_template} ${correlation_item} xpath=.//correlation/correlation-item
178 ${request_template} Set Element Text ${request_template} ${underlay_topo} xpath=.//correlation/filtration/underlay-topology
179 [Return] ${request_template}
182 [Arguments] ${request_template} ${mapping_index} ${target_field_path} ${matching_key}
183 [Documentation] Add target field to request
184 ${target_field_template} Set Element Text ${TARGET_FIELD} ${target_field_path} xpath=.//target-field-path
185 ${target_field_template} Set Element Text ${target_field_template} ${matching_key} xpath=.//matching-key
186 ${request_template} Add Element ${request_template} ${target_field_template} xpath=.//correlation/aggregation/mapping[${mapping_index}]
187 ${request_template} Element to String ${request_template}
188 [Return] ${request_template}
191 [Arguments] ${request_template} ${filter_template} ${target_field}
192 [Documentation] Add filter to filtration
193 ${request_template} Add Element ${request_template} ${filter_template} xpath=.//correlation/filtration
194 ${model} Get Element Text ${request_template} xpath=.//correlations/output-model
195 ${request_template} Set Element Text ${request_template} ${model} xpath=.//correlation/filtration/filter/input-model
196 ${request_template} Set Element Text ${request_template} ${target_field} xpath=.//correlation/filtration/filter/target-field
197 [Return] ${request_template}
199 Insert Filter With ID
200 [Arguments] ${request_template} ${filter_template} ${target_field} ${filter_id}
201 [Documentation] Add filter to filtration with specified id
202 ${request_template} Insert Filter ${request_template} ${filter_template} ${target_field}
203 ${request_template} Set Element Text ${request_template} ${filter_id} xpath=.//correlation/filtration/filter/filter-id
204 [Return] ${request_template}
207 [Arguments] ${request_template} ${ip_address}
208 [Documentation] Set filter ipv4 address
209 ${request_template} Set Element Text ${request_template} ${ip_address} xpath=.//correlation/filtration/filter/ipv4-address-filter/ipv4-address
210 ${request_template} Element to String ${request_template}
211 [Return] ${request_template}
213 Set Range Number Filter
214 [Arguments] ${request_template} ${min_number} ${max_number}
215 [Documentation] Set filter minimum and maximum number values
216 ${request_template} Set Element Text ${request_template} ${min_number} xpath=.//correlation/filtration/filter/range-number-filter/min-number-value
217 ${request_template} Set Element Text ${request_template} ${max_number} xpath=.//correlation/filtration/filter/range-number-filter/max-number-value
218 ${request_template} Element to String ${request_template}
219 [Return] ${request_template}
221 Set Range String Filter
222 [Arguments] ${request_template} ${min_value} ${max_value}
223 [Documentation] Set filter minimum and maximum string values
224 ${request_template} Set Element Text ${request_template} ${min_value} xpath=.//correlation/filtration/filter/range-string-filter/min-string-value
225 ${request_template} Set Element Text ${request_template} ${max_value} xpath=.//correlation/filtration/filter/range-string-filter/max-string-value
226 ${request_template} Element to String ${request_template}
227 [Return] ${request_template}
229 Set Specific Number Filter
230 [Arguments] ${request_template} ${number}
231 [Documentation] Set filter number value
232 ${request_template} Set Element Text ${request_template} ${number} xpath=.//correlation/filtration/filter/specific-number-filter/specific-number
233 ${request_template} Element to String ${request_template}
234 [Return] ${request_template}
236 Set Specific String Filter
237 [Arguments] ${request_template} ${string_value}
238 [Documentation] Set filter string value
239 ${request_template} Set Element Text ${request_template} ${string_value} xpath=.//correlation/filtration/filter/specific-string-filter/specific-string
240 ${request_template} Element to String ${request_template}
241 [Return] ${request_template}
244 [Arguments] ${request_template} ${ip_address}
245 [Documentation] Set filter ipv6 address
246 ${request_template} Set Element Text ${request_template} ${ip_address} xpath=.//correlation/filtration/filter/ipv6-address-filter/ipv6-address
247 ${request_template} Element to String ${request_template}
248 [Return] ${request_template}
251 [Arguments] ${request_template} ${script_language} ${script}
252 [Documentation] Set filter script
253 ${request_template} Set Element Text ${request_template} ${script_language} xpath=.//correlation/filtration/filter/script-filter/scripting/language
254 ${request_template} Set Element Text ${request_template} ${script} xpath=.//correlation/filtration/filter/script-filter/scripting/script
255 ${request_template} Element to String ${request_template}
256 [Return] ${request_template}
258 Insert Link Computation Inside
259 [Arguments] ${request_template} ${link_computation_template} ${input_model} ${underlay_topology}
260 [Documentation] Add link computation to request
261 ${request_template} Add Element ${request_template} ${link_computation_template} xpath=.
262 ${request_template} Set Element Text ${request_template} ${input_model} xpath=.//link-computation/node-info/input-model
263 ${request_template} Set Element Text ${request_template} ${input_model} xpath=.//link-computation/link-info/input-model
264 ${request_template} Set Element Text ${request_template} ${input_model} xpath=.//link-computation/output-model
265 ${request_template} Set Element Text ${request_template} ${underlay_topology} xpath=.//link-computation/link-info/link-topology
266 ${request_template} Set Element Attribute ${request_template} xmlns:n urn:opendaylight:topology:correlation xpath=./link-computation
267 ${request_template} Element to String ${request_template}
268 [Return] ${request_template}
270 Insert Link Computation
271 [Arguments] ${request_template} ${link_computation_template} ${input_model} ${underlay_topology_1} ${underlay_topology_2}
272 [Documentation] Add link computation to request
273 ${request_template} Add Element ${request_template} ${link_computation_template} xpath=.
274 ${request_template} Set Element Text ${request_template} ${input_model} xpath=.//link-computation/node-info/input-model
275 ${request_template} Set Element Text ${request_template} ${input_model} xpath=.//link-computation/link-info[1]/input-model
276 ${request_template} Set Element Text ${request_template} ${input_model} xpath=.//link-computation/link-info[2]/input-model
277 ${request_template} Set Element Text ${request_template} ${input_model} xpath=.//link-computation/output-model
278 ${request_template} Set Element Text ${request_template} ${underlay_topology_1} xpath=.//link-computation/link-info[1]/link-topology
279 ${request_template} Set Element Text ${request_template} ${underlay_topology_2} xpath=.//link-computation/link-info[2]/link-topology
280 ${request_template} Set Element Attribute ${request_template} xmlns:n urn:opendaylight:topology:correlation xpath=./link-computation
281 ${request_template} Element to String ${request_template}
282 [Return] ${request_template}
284 Insert Scripting into Request
285 [Arguments] ${request} ${language} ${script}
286 [Documentation] Insert Scripting into Request under aggregation node
287 ${request} Add Element ${request} ${SCRIPTING} xpath=.//correlation/aggregation
288 ${request} Set Element Text ${request} ${script} xpath=.//correlation/aggregation/scripting/script
289 ${request} Set Element Text ${request} ${language} xpath=.//correlation/aggregation/scripting/language
290 ${request} Element to String ${request}
294 [Arguments] ${node-id} ${ovs-version}=23 ${router-id-ipv4}=10.0.0.1
295 [Documentation] Create an isis node element with id and ip
296 ${request} Set Element Text ${NODE_ISIS} ${node-id} xpath=.//node-id
297 ${request} Set Element Text ${request} ${ovs-version} xpath=.//ovs-version
298 ${request} Set Element Text ${request} ${router-id-ipv4} xpath=.//igp-node-attributes/isis-node-attributes/ted/te-router-id-ipv4
299 ${request} Element to String ${request}
303 [Arguments] ${node-id} ${ip-address}=10.0.0.1 ${serial-number}=27
304 [Documentation] Create an Openflow node element with id and ip
305 ${request} Set Element Text ${NODE_OPENFLOW} ${node-id} xpath=.//id
306 ${request} Set Element Text ${request} ${ip-address} xpath=.//ip-address
307 ${request} Set Element Text ${request} ${serial-number} xpath=.//serial-number
308 ${request} Element to String ${request}
311 Create OVSDB Termination Point
312 [Arguments] ${tp-id} ${ofport}
313 [Documentation] Create an OVSDB termination point element with id and port
314 ${request} Set Element Text ${TERMINATION_POINT_OVSDB} ${tp-id} xpath=.//tp-id
315 ${request} Set Element Text ${request} ${ofport} xpath=.//ofport
316 ${request} Element to String ${request}
319 Create Openflow Node Connector
320 [Arguments] ${nc-id} ${port-number}
321 [Documentation] Create an Openflow node connector element with id and port number
322 ${request} Set Element Text ${NODE_CONNECTOR_OPENFLOW} ${nc-id} xpath=.//id
323 ${request} Set Element Text ${request} ${port-number} xpath=.//port-number
324 ${request} Element to String ${request}
328 [Arguments] ${link-id} ${source-node} ${dest-node} ${name} ${metric}
329 ${request} Set Element Text ${LINK} ${link-id} xpath=.//link-id
330 ${request} Set Element Text ${request} ${source-node} xpath=.//source/source-node
331 ${request} Set Element Text ${request} ${dest-node} xpath=.//destination/dest-node
332 ${request} Set Element Text ${request} ${name} xpath=.//igp-link-attributes/name
333 ${request} Set Element Text ${request} ${metric} xpath=.//igp-link-attributes/metric
334 ${request} Element to String ${request}
337 Extract Node from Topology
338 [Arguments] ${topology} ${supp_node_id}
339 [Documentation] Returns node that contains supporting node with ID specified in argument supp_node_id
340 ${xpath} Set Variable .//node/supporting-node[node-ref='${supp_node_id}']/..
341 ${node} Get Element ${topology} xpath=${xpath}
342 ${node} Element to String ${node}
345 Extract Termination Point from Topology
346 [Arguments] ${model} ${topology} ${topo_id} ${node_id} ${tp_id}
347 [Documentation] Returns termination point that contains supporting termination point from specified topology, node and with specified id
348 Check Supported Model ${model}
349 ${xpath} Set Variable If '${model}' == 'network-topology-model' or '${model}' == 'opendaylight-inventory-model' .//termination-point[tp-ref='/network-topology:network-topology/topology/${topo_id}/node/${node_id}/termination-point/${tp_id}'] .//termination-point/supporting-termination-point[tp-ref='${tp_id}']/..
350 ${tp} Get Element ${topology} xpath=${xpath}
351 ${tp} Element to String ${tp}
354 Extract Link from Topology
355 [Arguments] ${model} ${topology} ${topo_id} ${link_id}
356 [Documentation] Returns link that contains supporting link
357 Check Supported Model ${model}
358 ${xpath} Set Variable If '${model}' == 'network-topology-model' or '${model}' == 'opendaylight-inventory-model' .//link/supporting-link[link-ref='/network-topology/topology/${topo_id}/link/${link_id}']/.. .//link/supporting-link[tp-ref='${tp_id}']/..
359 ${link} Get Element ${topology} xpath=${xpath}
360 ${link} Element to String ${link}
363 Check Supported Model
365 [Documentation] Checks if model is supported.
366 Run Keyword If '${model}' != 'network-topology-model' and '${model}' != 'i2rs-model' and '${model}' != 'opendaylight-inventory-model' Fail Not supported model
368 Check Aggregated Node in Topology
369 [Arguments] ${model} ${topology} ${tp_count} @{supp_node_ids}
370 [Documentation] Checks number of termination points and concrete supporting nodes in aggregated node and returns overlay node id. Model should be 'network-topology-model', 'opendaylight-inventory-model' or 'i2rs-model'.
371 Check Supported Model ${model}
372 ${node_id} Get From List ${supp_node_ids} 0
373 ${aggregated_node} Extract Node from Topology ${topology} ${node_id}
374 ${supp_node_count} Get Length ${supp_node_ids}
375 Should Contain X Times ${aggregated_node} <supporting-node> ${supp_node_count}
376 Should Contain X Times ${aggregated_node} <termination-point> ${tp_count}
377 Should Contain X Times ${aggregated_node} <tp-ref> ${tp_count}
378 : FOR ${supp_node_id} IN @{supp_node_ids}
379 \ Element Text Should Be ${aggregated_node} ${supp_node_id} xpath=.//supporting-node[node-ref='${supp_node_id}']/node-ref
380 ${overlay_node_id} Get Element Text ${aggregated_node} xpath=./node-id
381 [Return] ${overlay_node_id}
383 Check Aggregated Termination Point in Node
384 [Arguments] ${model} ${topology} ${topology_id} ${node_id} ${tp_id} @{supp_tp_ids}
385 [Documentation] Checks supporting termination points in aggregated termination point. Model should be 'network-topology-model', 'opendaylight-inventory-model' or 'i2rs-model'.
386 Check Supported Model ${model}
387 ${tp} Extract Termination Point from Topology ${model} ${topology} ${topology_id} ${node_id} ${tp_id}
388 ${supp_tp_count} Get Length ${supp_tp_ids}
389 Should Contain X Times ${tp} <tp-ref> ${supp_tp_count}
390 : FOR ${supp_tp_id} IN @{supp_tp_ids}
391 \ Should Contain X Times ${tp} ${supp_tp_id}</tp-ref> 1
393 Check Filtered Nodes in Topology
394 [Arguments] ${topology} ${tp_count} @{node_ids}
395 [Documentation] Checks nodes in filtered topology
396 : FOR ${node_id} IN @{node_ids}
397 \ Element Text Should Be ${topology} ${node_id} xpath=.//node/supporting-node[node-ref='${node_id}']/node-ref
399 Check Filtered Termination Points in Node
400 [Arguments] ${topology} ${supp_node_id} @{supp_tp_ids}
401 [Documentation] Checks termination points in filtered topology
402 ${node} Extract Node from Topology ${topology} ${supp_node_id}
403 ${supp_tp_count} Get Length ${supp_tp_ids}
404 Should Contain X Times ${node} <supporting-node> 1
405 Should Contain X Times ${node} <termination-point> ${supp_tp_count}
406 Should Contain X Times ${node} <tp-ref> ${supp_tp_count}
407 : FOR ${supp_tp_id} IN @{supp_tp_ids}
408 \ Should Contain X Times ${node} ${supp_tp_id} 1
410 Check Filtered Links In Topology
411 [Arguments] ${topology} @{supp_link_ids}
412 [Documentation] Checks links in filtered topology
413 : FOR ${supp_link_id} IN @{supp_link_ids}
414 \ Should Contain X Times ${topology} ${supp_link_id}</link-ref> 1
416 Check Overlay Link Source And Destination
417 [Arguments] ${model} ${topology} ${topo_id} ${link_id} ${expected_source} ${expected_destination}
418 [Documentation] Checks if the overlay link's source and destination specified by a supporting link ref matches given source and destination
419 ${link} Extract Link from Topology ${model} ${topology} ${topo_id} ${link_id}
420 ${link_source} Get Element Text ${link} xpath=.//source-node
421 ${link_destination} Get Element Text ${link} xpath=.//dest-node
422 Should Be Equal As Strings ${link_source} ${expected_source}
423 Should Be Equal As Strings ${link_destination} ${expected_destination}
425 Output Topo Should Be Complete
426 [Documentation] Verifies that the output topology contains the expected amount of essential elements
427 [Arguments] ${node_count}=-1 ${supporting-node_count}=-1 ${node-ref_count}=-1 ${tp_count}=-1 ${tp-ref_count}=-1 ${link_count}=-1 ${link-ref_count}=-1
428 ${resp} Wait Until Keyword Succeeds 5x 250ms Basic Request Get ${OVERLAY_TOPO_URL}
429 Should Contain ${resp.content} <topology-id>${OUTPUT_TOPO_NAME}</topology-id>
430 Run Keyword If ${node_count}>-1 Should Contain X Times ${resp.content} <node> ${node_count}
431 Run Keyword If ${supporting-node_count}>-1 Should Contain X Times ${resp.content} <supporting-node> ${supporting-node_count}
432 Run Keyword If ${node-ref_count}>-1 Should Contain X Times ${resp.content} <node-ref> ${node-ref_count}
433 Run Keyword If ${link_count}>-1 Should Contain X Times ${resp.content} <link> ${link_count}
434 Run Keyword If ${link-ref_count}>-1 Should Contain X Times ${resp.content} <link-ref> ${link-ref_count}
435 Run Keyword If ${tp_count}>-1 Should Contain X Times ${resp.content} <termination-point> ${tp_count}
436 Run Keyword If ${tp-ref_count}>-1 Should Contain X Times ${resp.content} <tp-ref> ${tp-ref_count}
437 Log ---- Output Topo ----