4 Library OperatingSystem
5 Library RequestsLibrary
8 Resource ClusterManagement.robot
10 Resource ${CURDIR}/TemplatedRequests.robot
11 Resource ../variables/Variables.robot
14 ${OVSDB_CONFIG_DIR} ${CURDIR}/../variables/ovsdb
15 ${OVSDB_NODE_PORT} 6634
16 ${SOUTHBOUND_CONFIG_API} ${CONFIG_TOPO_API}/topology/ovsdb:1/node/ovsdb:%2F%2F
17 ${SOUTHBOUND_NODE_CONFIG_API} ${CONFIG_TOPO_API}/topology/ovsdb:1/node/ovsdb:%2F%2F${TOOLS_SYSTEM_IP}:${OVSDB_NODE_PORT}
21 [Arguments] ${resp_content}
22 ${resp_json} = BuiltIn.Run Keyword If '''${resp_content}''' != '${EMPTY}' RequestsLibrary.To Json ${resp_content} pretty_print=True
23 ... ELSE BuiltIn.Set Variable ${EMPTY}
24 BuiltIn.Log ${resp_json}
28 [Arguments] ${node_ip} ${port}=${OVSDB_NODE_PORT}
29 ${body} = OperatingSystem.Get File ${OVSDB_CONFIG_DIR}/create_node.json
30 ${body} = Replace String ${body} 127.0.0.1 ${node_ip}
31 ${body} = Replace String ${body} 61644 ${port}
32 ${uri} = Builtin.Set Variable ${CONFIG_TOPO_API}/topology/ovsdb:1/
33 BuiltIn.Log URI is ${uri}
34 BuiltIn.Log data: ${body}
35 ${resp} = RequestsLibrary.Post Request session ${uri} data=${body}
36 OVSDB.Log Request ${resp.content}
37 BuiltIn.Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
40 [Arguments] ${node_ip} ${port}=${OVSDB_NODE_PORT}
41 [Documentation] This will Initiate the connection to OVSDB node from controller
42 ${body} = OperatingSystem.Get File ${OVSDB_CONFIG_DIR}/connect.json
43 ${body} = String.Replace String ${body} 127.0.0.1 ${node_ip}
44 ${body} = String.Replace String ${body} 61644 ${port}
45 ${uri} = BuiltIn.Set Variable ${SOUTHBOUND_CONFIG_API}${node_ip}:${port}
46 BuiltIn.Log URI is ${uri}
47 BuiltIn.Log data: ${body}
48 ${resp} = RequestsLibrary.Put Request session ${uri} data=${body}
49 OVSDB.Log Request ${resp.content}
50 BuiltIn.Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
52 Disconnect From Ovsdb Node
53 [Arguments] ${node_ip} ${port}=${OVSDB_NODE_PORT}
54 [Documentation] This request will disconnect the OVSDB node from the controller
55 ${resp} = RequestsLibrary.Delete Request session ${SOUTHBOUND_CONFIG_API}${node_ip}:${port}
56 BuiltIn.Should Be Equal As Strings ${resp.status_code} 200
58 Add Bridge To Ovsdb Node
59 [Arguments] ${node_id} ${node_ip} ${bridge} ${datapath_id} ${port}=${OVSDB_NODE_PORT}
60 [Documentation] This will create a bridge and add it to the OVSDB node.
61 ${body} = OperatingSystem.Get File ${OVSDB_CONFIG_DIR}/create_bridge.json
62 ${body} = String.Replace String ${body} ovsdb://127.0.0.1:61644 ovsdb://${node_id}
63 ${body} = String.Replace String ${body} tcp:127.0.0.1:6633 tcp:${ODL_SYSTEM_IP}:6633
64 ${body} = String.Replace String ${body} 127.0.0.1 ${node_ip}
65 ${body} = String.Replace String ${body} br01 ${bridge}
66 ${body} = String.Replace String ${body} 61644 ${port}
67 ${body} = String.Replace String ${body} 0000000000000001 ${datapath_id}
68 ${node_id_} = BuiltIn.Evaluate """${node_id}""".replace("/","%2F")
69 ${uri} = BuiltIn.Set Variable ${SOUTHBOUND_CONFIG_API}${node_id_}%2Fbridge%2F${bridge}
70 BuiltIn.Log URI is ${uri}
71 BuiltIn.Log data: ${body}
72 ${resp} = RequestsLibrary.Put Request session ${uri} data=${body}
73 OVSDB.Log Request ${resp.content}
74 BuiltIn.Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
76 Delete Bridge From Ovsdb Node
77 [Arguments] ${node_id} ${bridge}
78 [Documentation] This request will delete the bridge node from the OVSDB
79 ${resp} = RequestsLibrary.Delete Request session ${SOUTHBOUND_CONFIG_API}${node_id}%2Fbridge%2F${bridge}
80 BuiltIn.Should Be Equal As Strings ${resp.status_code} 200
83 [Arguments] ${node_id} ${bridge} ${tp_name} ${remote_ip}=${TOOLS_SYSTEM_IP}
84 [Documentation] Using the json data body file as a template, a REST config request is made to
85 ... create a termination-point ${tp_name} on ${bridge} for the given ${node_id}. The ports
86 ... remote-ip defaults to ${TOOLS_SYSTEM_IP}
87 ${body} = OperatingSystem.Get File ${OVSDB_CONFIG_DIR}/create_port.json
88 ${body} = String.Replace String ${body} 192.168.0.21 ${remote_ip}
89 ${body} = String.Replace String ${body} vxlanport ${tp_name}
90 ${node_id_} = BuiltIn.Evaluate """${node_id}""".replace("/","%2F")
91 ${uri} = BuiltIn.Set Variable ${SOUTHBOUND_CONFIG_API}${node_id_}%2Fbridge%2F${bridge}
92 ${resp} = RequestsLibrary.Put Request session ${uri}/termination-point/${tp_name}/ data=${body}
93 BuiltIn.Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
96 [Arguments] ${node_ip} ${bridge} ${vxlan_port} ${remote_ip} ${port}=${OVSDB_NODE_PORT}
97 [Documentation] This request will create vxlan port for vxlan tunnel and attach it to the specific bridge
98 OVSDB.Add Termination Point ${node_ip}:${port} ${bridge} ${vxlan_port} ${remote_ip}
100 Verify OVS Reports Connected
101 [Arguments] ${tools_system}=${TOOLS_SYSTEM_IP}
102 [Documentation] Uses "vsctl show" to check for string "is_connected"
103 ${output} = Verify Ovs-vsctl Output show is_connected ${tools_system}
106 Verify Ovs-vsctl Output
107 [Arguments] ${vsctl_args} ${expected_output} ${ovs_system}=${TOOLS_SYSTEM_IP} ${should_match}=True
108 [Documentation] A wrapper keyword to make it easier to validate ovs-vsctl output, and gives an easy
109 ... way to check this output in a WUKS. The argument ${should_match} can control if the match should
110 ... exist (True} or not (False) or don't care (anything but True or False). ${should_match} is True by default
111 ${output} = Utils.Run Command On Mininet ${ovs_system} sudo ovs-vsctl ${vsctl_args}
112 BuiltIn.Log ${output}
113 BuiltIn.Run Keyword If "${should_match}" == "True" BuiltIn.Should Contain ${output} ${expected_output}
114 BuiltIn.Run Keyword If "${should_match}" == "False" BuiltIn.Should Not Contain ${output} ${expected_output}
118 [Arguments] ${ovs_system_ip}=${TOOLS_SYSTEM_IP} ${controller_http_session}=session
119 [Documentation] Queries the topology in the operational datastore and searches for the node that has
120 ... the ${ovs_system_ip} argument as the "remote-ip". If found, the value returned will be the value of
121 ... node-id stripped of "ovsdb://uuid/". If not found, ${EMPTY} will be returned.
122 ${uuid} = Set Variable ${EMPTY}
123 ${resp} = RequestsLibrary.Get Request ${controller_http_session} ${OPERATIONAL_TOPO_API}/topology/ovsdb:1
124 OVSDB.Log Request ${resp.content}
125 BuiltIn.Should Be Equal As Strings ${resp.status_code} 200
126 ${resp_json} = RequestsLibrary.To Json ${resp.content}
127 ${topologies} = Collections.Get From Dictionary ${resp_json} topology
128 ${topology} = Collections.Get From List ${topologies} 0
129 ${node_list} = Collections.Get From Dictionary ${topology} node
130 BuiltIn.Log ${node_list}
131 # Since bridges are also listed as nodes, but will not have the extra "ovsdb:connection-info data,
132 # we need to use "Run Keyword And Ignore Error" below.
133 : FOR ${node} IN @{node_list}
134 \ ${node_id} = Collections.Get From Dictionary ${node} node-id
135 \ ${node_uuid} = String.Replace String ${node_id} ovsdb://uuid/ ${EMPTY}
136 \ ${status} ${connection_info} = BuiltIn.Run Keyword And Ignore Error Collections.Get From Dictionary ${node} ovsdb:connection-info
137 \ ${status} ${remote_ip} = BuiltIn.Run Keyword And Ignore Error Collections.Get From Dictionary ${connection_info} remote-ip
138 \ ${uuid} = Set Variable If '${remote_ip}' == '${ovs_system_ip}' ${node_uuid} ${uuid}
142 [Arguments] ${switch}=br-int
143 [Documentation] Used to log useful test debugs for OVSDB related system tests.
144 ${output} = Utils.Run Command On Mininet ${TOOLS_SYSTEM_IP} sudo ovs-vsctl show
145 BuiltIn.Log ${output}
146 ${output} = Utils.Run Command On Mininet ${TOOLS_SYSTEM_IP} sudo ovs-ofctl -O OpenFlow13 dump-flows ${switch} | cut -d',' -f3-
147 BuiltIn.Log ${output}
149 Clean OVSDB Test Environment
150 [Arguments] ${tools_system}=${TOOLS_SYSTEM_IP}
151 [Documentation] General Use Keyword attempting to sanitize test environment for OVSDB related
152 ... tests. Not every step will always be neccessary, but should not cause any problems for
153 ... any new ovsdb test suites.
154 Utils.Clean Mininet System ${tools_system}
155 Utils.Run Command On Mininet ${tools_system} sudo ovs-vsctl del-manager
156 Utils.Run Command On Mininet ${tools_system} sudo /usr/share/openvswitch/scripts/ovs-ctl stop
157 Utils.Run Command On Mininet ${tools_system} sudo rm -rf /etc/openvswitch/conf.db
158 Utils.Run Command On Mininet ${tools_system} sudo /usr/share/openvswitch/scripts/ovs-ctl start
161 [Arguments] ${ovs_ip}
162 [Documentation] Restart the OVS node without cleaning the current configuration.
163 ${output} = Utils.Run Command On Mininet ${ovs_ip} sudo /usr/share/openvswitch/scripts/ovs-ctl stop
164 BuiltIn.Log ${output}
165 ${output} = Utils.Run Command On Mininet ${ovs_ip} sudo /usr/share/openvswitch/scripts/ovs-ctl start
166 BuiltIn.Log ${output}
168 Set Controller In OVS Bridge
169 [Arguments] ${tools_system} ${bridge} ${controller_opt} ${ofversion}=13
170 [Documentation] Sets controller for the OVS bridge ${bridge} using ${controller_opt} and OF version ${ofversion}.
171 Utils.Run Command On Mininet ${tools_system} sudo ovs-vsctl set bridge ${bridge} protocols=OpenFlow${ofversion}
172 Utils.Run Command On Mininet ${tools_system} sudo ovs-vsctl set-controller ${bridge} ${controller_opt}
174 Check OVS OpenFlow Connections
175 [Arguments] ${tools_system} ${of_connections}
176 [Documentation] Check OVS instance with IP ${tools_system} has ${of_connections} OpenFlow connections.
177 ${output} = Utils.Run Command On Mininet ${tools_system} sudo ovs-vsctl show
178 BuiltIn.Log ${output}
179 BuiltIn.Should Contain X Times ${output} is_connected ${of_connections}
181 Add Multiple Managers to OVS
182 [Arguments] ${tools_system}=${TOOLS_SYSTEM_IP} ${controller_index_list}=${EMPTY} ${ovs_mgr_port}=6640
183 [Documentation] Connect OVS to the list of controllers in the ${controller_index_list} or all if no list is provided.
184 ${index_list} = ClusterManagement.List Indices Or All given_list=${controller_index_list}
185 Utils.Clean Mininet System ${tools_system}
186 ${ovs_opt} = BuiltIn.Set Variable
187 : FOR ${index} IN @{index_list}
188 \ ${ovs_opt} = BuiltIn.Catenate ${ovs_opt} ${SPACE}tcp:${ODL_SYSTEM_${index}_IP}:${ovs_mgr_port}
189 \ BuiltIn.Log ${ovs_opt}
190 Utils.Run Command On Mininet ${tools_system} sudo ovs-vsctl set-manager ${ovs_opt}
191 ${output} = BuiltIn.Wait Until Keyword Succeeds 5s 1s Verify OVS Reports Connected ${tools_system}
192 BuiltIn.Log ${output}
193 ${controller_index} = Collections.Get_From_List ${index_list} 0
194 ${session} = ClusterManagement.Resolve_Http_Session_For_Member member_index=${controller_index}
195 ${ovsdb_uuid} = BuiltIn.Wait Until Keyword Succeeds 30s 2s OVSDB.Get OVSDB UUID controller_http_session=${session}
196 [Return] ${ovsdb_uuid}
200 [Documentation] Returns the dpnid from the system at the given ip address using ovs-ofctl assuming br-int is present.
201 ${output} = Utils.Run Command On Remote System ${ip} sudo ovs-ofctl show -O Openflow13 br-int | head -1 | awk -F "dpid:" '{print $2}'
202 ${dpnid} = BuiltIn.Convert To Integer ${output} 16
208 [Documentation] Return the subnet from the system at the given ip address and interface
209 ${output} = Utils.Run Command On Remote System ${ip} /usr/sbin/ip addr show | grep ${ip} | cut -d' ' -f6
210 ${interface} = ipaddress.ip_interface ${output}
211 ${network} = BuiltIn.Set Variable ${interface.network.__str__()}
216 [Documentation] Returns the ethernet adapter name from the system at the given ip address using ip addr show.
217 ${adapter} = Utils.Run Command On Remote System ${ip} /usr/sbin/ip addr show | grep ${ip} | cut -d " " -f 11
218 BuiltIn.Log ${adapter}
223 [Documentation] Returns the default gateway at the given ip address using route command.
224 ${gateway} = Utils.Run Command On Remote System ${ip} /usr/sbin/route -n | grep '^0.0.0.0' | cut -d " " -f 10
225 BuiltIn.Log ${gateway}
229 [Arguments] ${subportid} ${ip_addr}
230 [Documentation] Get the port number for the given sub-port id
231 ${command} = Set Variable sudo ovs-ofctl -O OpenFlow13 show br-int | grep ${subportid} | awk '{print$1}'
232 BuiltIn.Log sudo ovs-ofctl -O OpenFlow13 show br-int | grep ${subportid} | awk '{print$1}'
233 ${output} = Utils.Run Command On Remote System ${ip_addr} ${command}
234 ${port_number} = BuiltIn.Should Match Regexp ${output} [0-9]+
235 [Return] ${port_number}
238 [Arguments] ${ip_addr} ${port}
239 [Documentation] Get the Metadata for a given port
240 ${cmd} = Set Variable sudo ovs-ofctl dump-flows -O Openflow13 br-int| grep table=0 | grep in_port=${port}
241 ${output} = Utils.Run Command On Remote System ${ip_addr} ${cmd}
242 @{list_any_matches} = String.Get_Regexp_Matches ${output} metadata:(\\w{12}) 1
243 ${metadata} = Builtin.Convert To String @{list_any_matches}
244 ${output} = String.Get Substring ${metadata} 2
247 Log Config And Operational Topology
248 [Documentation] For debugging purposes, this will log both config and operational topo data stores
249 ${resp} RequestsLibrary.Get Request session ${CONFIG_TOPO_API}
250 OVSDB.Log Request ${resp.content}
251 ${resp} = RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
252 OVSDB.Log Request ${resp.content}
254 Config and Operational Topology Should Be Empty
255 [Documentation] This will check that only the expected output is there for both operational and config
256 ... topology data stores. Empty probably means that only ovsdb:1 is there.
257 ${config_resp} RequestsLibrary.Get Request session ${CONFIG_TOPO_API}
258 ${operational_resp} RequestsLibrary.Get Request session ${OPERATIONAL_TOPO_API}
259 BuiltIn.Should Contain ${config_resp.content} {"topology-id":"ovsdb:1"}
260 BuiltIn.Should Contain ${operational_resp.content} {"topology-id":"ovsdb:1"}
262 Modify Multi Port Body
263 [Arguments] ${ovs_1_port_name} ${ovs_2_port_name} ${bridge}
264 [Documentation] Updates two port names for the given ${bridge} in config store
265 ${body} = OperatingSystem.Get File ${OVSDB_CONFIG_DIR}/bug_7414/create_multiple_ports.json
266 ${ovs_1_ovsdb_uuid} = Get OVSDB UUID ${TOOLS_SYSTEM_IP}
267 ${ovs_2_ovsdb_uuid} = Get OVSDB UUID ${TOOLS_SYSTEM_2_IP}
268 ${body} = Replace String ${body} OVS_1_UUID ${ovs_1_ovsdb_uuid}
269 ${body} = Replace String ${body} OVS_2_UUID ${ovs_2_ovsdb_uuid}
270 ${body} = Replace String ${body} OVS_1_BRIDGE_NAME ${bridge}
271 ${body} = Replace String ${body} OVS_2_BRIDGE_NAME ${bridge}
272 ${body} = Replace String ${body} OVS_1_IP ${TOOLS_SYSTEM_IP}
273 ${body} = Replace String ${body} OVS_2_IP ${TOOLS_SYSTEM_2_IP}
274 ${body} = Replace String ${body} OVS_1_PORT_NAME ${ovs_1_port_name}
275 ${body} = Replace String ${body} OVS_2_PORT_NAME ${ovs_2_port_name}
276 ${uri} = Builtin.Set Variable ${CONFIG_TOPO_API}
277 BuiltIn.Log URI is ${uri}
278 BuiltIn.Log data: ${body}
279 ${resp} = RequestsLibrary.Put Request session ${uri} data=${body}
280 OVSDB.Log Request ${resp.content}
281 BuiltIn.Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
286 ${body} = OperatingSystem.Get File ${OVSDB_CONFIG_DIR}/create_qos.json
287 ${uri} = BuiltIn.Set Variable ${CONFIG_TOPO_API}/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:qos-entries/${qos}/
288 ${body} = Replace String ${body} QOS-1 ${qos}
289 BuiltIn.Log URI is ${uri}
290 BuiltIn.Log data: ${body}
291 ${resp} = RequestsLibrary.Put Request session ${uri} data=${body}
292 OVSDB.Log Request ${resp.content}
293 BuiltIn.Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
297 ${body} = OperatingSystem.Get File ${OVSDB_CONFIG_DIR}/create_qoslinkedqueue.json
298 ${body} = Replace String ${body} QUEUE-1 ${queue}
299 ${uri} = BuiltIn.Set Variable ${CONFIG_TOPO_API}/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:queues/${queue}/
300 BuiltIn.Log URI is ${uri}
301 BuiltIn.Log data: ${body}
302 ${resp} = RequestsLibrary.Put Request session ${uri} data=${body}
303 OVSDB.Log Request ${resp.content}
304 BuiltIn.Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
308 ${body} = OperatingSystem.Get File ${OVSDB_CONFIG_DIR}/update_existingqos.json
309 ${uri} = BuiltIn.Set Variable ${CONFIG_TOPO_API}/topology/ovsdb:1/node/ovsdb:HOST1/ovsdb:qos-entries/${QOS}/
310 BuiltIn.Log URL is ${uri}
311 BuiltIn.Log data: ${body}
312 ${resp} = RequestsLibrary.Put Request session ${uri} data=${body}
313 OVSDB.Log Request ${resp.content}
314 BuiltIn.Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
316 Create Qos Linked Queue
317 ${body} OperatingSystem.Get File ${OVSDB_CONFIG_DIR}/bug_7160/create_qoslinkedqueue.json
318 ${resp} RequestsLibrary.Put Request session ${CONFIG_TOPO_API}/topology/ovsdb:1/node/ovsdb:HOST1 data=${body}
319 OVSDB.Log Request ${resp.content}
320 BuiltIn.Should Contain ${ALLOWED_STATUS_CODES} ${resp.status_code}
323 [Arguments] ${conn_id}
324 [Documentation] Add higher levels of OVS logging
325 SSHLibrary.Switch Connection ${conn_id}
326 @{modules} = BuiltIn.Create List bridge:file:dbg connmgr:file:dbg inband:file:dbg ofp_actions:file:dbg ofp_errors:file:dbg
327 ... ofp_msgs:file:dbg ovsdb_error:file:dbg rconn:file:dbg tunnel:file:dbg vconn:file:dbg
328 : FOR ${module} IN @{modules}
329 \ Utils.Write Commands Until Expected Prompt sudo ovs-appctl --target ovs-vswitchd vlog/set ${module} ${DEFAULT_LINUX_PROMPT_STRICT}
330 Utils.Write Commands Until Expected Prompt sudo ovs-appctl --target ovs-vswitchd vlog/list ${DEFAULT_LINUX_PROMPT_STRICT}
333 [Arguments] ${conn_id}
334 [Documentation] Reset the OVS logging
335 SSHLibrary.Switch Connection ${conn_id}
336 ${output} = Utils.Write Commands Until Expected Prompt sudo ovs-appctl --target ovs-vswitchd vlog/set :file:info ${DEFAULT_LINUX_PROMPT_STRICT}
339 SetupUtils.Setup_Utils_For_Setup_And_Teardown
340 KarafKeywords.Open Controller Karaf Console On Background
341 RequestsLibrary.Create Session session http://${ODL_SYSTEM_IP}:${RESTCONFPORT} auth=${AUTH} headers=${HEADERS}
342 OVSDB.Log Config And Operational Topology
345 [Arguments] ${uris}=@{EMPTY}
346 [Documentation] Cleans up test environment, close existing sessions.
347 OVSDB.Clean OVSDB Test Environment ${TOOLS_SYSTEM_IP}
348 : FOR ${uri} IN @{uris}
349 \ RequestsLibrary.Delete Request session ${uri}
350 ${resp} = RequestsLibrary.Get Request session ${CONFIG_TOPO_API}
351 OVSDB.Log Config And Operational Topology
352 RequestsLibrary.Delete All Sessions
354 Get DumpFlows And Ovsconfig
355 [Arguments] ${conn_id} ${bridge}
356 [Documentation] Get the OvsConfig and Flow entries from OVS
357 SSHLibrary.Switch Connection ${conn_id}
358 Write Commands Until Expected Prompt sudo ovs-vsctl show ${DEFAULT_LINUX_PROMPT_STRICT}
359 Write Commands Until Expected Prompt sudo ovs-vsctl list Open_vSwitch ${DEFAULT_LINUX_PROMPT_STRICT}
360 Write Commands Until Expected Prompt sudo ovs-ofctl show ${bridge} -OOpenFlow13 ${DEFAULT_LINUX_PROMPT_STRICT}
361 Write Commands Until Expected Prompt sudo ovs-ofctl dump-flows ${bridge} -OOpenFlow13 ${DEFAULT_LINUX_PROMPT_STRICT}
362 Write Commands Until Expected Prompt sudo ovs-ofctl dump-groups ${bridge} -OOpenFlow13 ${DEFAULT_LINUX_PROMPT_STRICT}
363 Write Commands Until Expected Prompt sudo ovs-ofctl dump-group-stats ${bridge} -OOpenFlow13 ${DEFAULT_LINUX_PROMPT_STRICT}
364 Write Commands Until Expected Prompt sudo ovs-vsctl list interface ${DEFAULT_LINUX_PROMPT_STRICT}
367 [Arguments] ${ovs_ip}
368 [Documentation] start the OVS node.
369 ${output} = Utils.Run Command On Mininet ${ovs_ip} sudo /usr/share/openvswitch/scripts/ovs-ctl start
370 BuiltIn.Log ${output}
373 [Arguments] ${ovs_ip}
374 [Documentation] Stop the OVS node.
375 ${output} = Utils.Run Command On Mininet ${ovs_ip} sudo /usr/share/openvswitch/scripts/ovs-ctl stop
376 BuiltIn.Log ${output}