6 Library ./UtilLibrary.py
7 Resource KarafKeywords.robot
8 Variables ../variables/Variables.py
11 # TODO: Introduce ${tree_size} and use instead of 1 in the next line.
12 ${start} sudo mn --controller=remote,ip=${CONTROLLER} --topo tree,1 --switch ovsk,protocols=OpenFlow13
16 [Arguments] ${system}=${MININET} ${user}=${MININET_USER} ${password}=${MININET_PASSWORD} ${prompt}=${DEFAULT_LINUX_PROMPT} ${timeout}=30s
17 [Documentation] Basic setup/cleanup work that can be done safely before any system
19 Log Start the test on the base edition
21 ${mininet_conn_id}= Open Connection ${system} prompt=${DEFAULT_LINUX_PROMPT} timeout=${timeout}
22 Set Suite Variable ${mininet_conn_id}
23 Flexible Mininet Login user=${user} password=${password}
24 Execute Command sudo ovs-vsctl set-manager ptcp:6644
29 [Arguments] ${system}=${MININET} ${cmd}=${start} ${custom}= ${user}=${MININET_USER} ${password}=${MININET_PASSWORD} ${prompt}=${DEFAULT_LINUX_PROMPT}
30 ... ${prompt_timeout}=30s
31 [Documentation] Basic setup to start mininet with custom topology
32 Log Start the test on the base edition
34 ${mininet_conn_id}= Open Connection ${system} prompt=${prompt} timeout=${prompt_timeout}
35 Set Suite Variable ${mininet_conn_id}
36 Flexible Mininet Login user=${user} password=${password}
40 [Return] ${mininet_conn_id}
43 [Arguments] ${mininet_conn_id} ${prompt}=${DEFAULT_LINUX_PROMPT}
44 [Documentation] Basic setup to stop/clean mininet
45 Switch Connection ${mininet_conn_id}
51 [Arguments] ${prompt}=${DEFAULT_LINUX_PROMPT}
52 [Documentation] Cleanup/Shutdown work that should be done at the completion of all
54 Log Stop the test on the base edition
55 Switch Connection ${mininet_conn_id}
61 Report_Failure_Due_To_Bug
63 [Documentation] Report that a test failed due to a known Bugzilla bug whose
64 ... number is provided as an argument.
65 ... This must be used in the [Teardown] setting of the affected test
66 ... or as the first line of the test if FastFail module is not being
67 ... used. It reports the URL of the bug on console and also puts it
68 ... into the Robot log file.
69 ${msg}= BuiltIn.Set_Variable This test fails due to https://bugs.opendaylight.org/show_bug.cgi?id=${number}
70 ${newline}= BuiltIn.Evaluate chr(10)
71 Run Keyword If "${TEST STATUS}"=="FAIL" BuiltIn.Set Test Message ${msg}${newline}${newline}${TEST_MESSAGE}
72 Run Keyword If "${TEST STATUS}"=="FAIL" BuiltIn.Log ${msg}
74 Ensure All Nodes Are In Response
75 [Arguments] ${URI} ${node_list}
76 [Documentation] A GET is made to the supplied ${URI} and every item in the ${node_list}
77 ... is verified to exist in the repsonse. This keyword currently implies that it's node
78 ... specific but any list of strings can be given in ${node_list}. Refactoring of this
79 ... to make it more generic should be done. (see keyword "Check For Elements At URI")
80 : FOR ${node} IN @{node_list}
81 \ ${resp} RequestsLibrary.Get Request session ${URI}
82 \ Should Be Equal As Strings ${resp.status_code} 200
83 \ Should Contain ${resp.content} ${node}
87 [Documentation] A GET on the /node/${node} API is made and specific flow stat
88 ... strings are checked for existence.
89 ${resp} RequestsLibrary.Get Request session ${OPERATIONAL_NODES_API}/node/${node}
90 Should Be Equal As Strings ${resp.status_code} 200
91 Should Contain ${resp.content} flow-capable-node-connector-statistics
92 Should Contain ${resp.content} flow-table-statistics
94 Check That Port Count Is Ok
95 [Arguments] ${node} ${count}
96 [Documentation] A GET on the /port API is made and the specified port ${count} is
97 ... verified. A more generic Keyword "Check For Specific Number Of Elements At URI"
98 ... also does this work and further consolidation should be done.
99 ${resp} RequestsLibrary.Get Request session ${REST_CONTEXT}/${CONTAINER}/port
101 Should Be Equal As Strings ${resp.status_code} 200
102 Should Contain X Times ${resp.content} ${node} ${count}
104 Check For Specific Number Of Elements At URI
105 [Arguments] ${uri} ${element} ${expected_count}
106 [Documentation] A GET is made to the specified ${URI} and the specific count of a
107 ... given element is done (as supplied by ${element} and ${expected_count})
108 ${resp} RequestsLibrary.Get Request session ${uri}
110 Should Be Equal As Strings ${resp.status_code} 200
111 Should Contain X Times ${resp.content} ${element} ${expected_count}
113 Check For Elements At URI
114 [Arguments] ${uri} ${elements}
115 [Documentation] A GET is made at the supplied ${URI} and every item in the list of
116 ... ${elements} is verified to exist in the response
117 ${resp} RequestsLibrary.Get Request session ${uri}
119 Should Be Equal As Strings ${resp.status_code} 200
120 : FOR ${i} IN @{elements}
121 \ Should Contain ${resp.content} ${i}
123 Check For Elements Not At URI
124 [Arguments] ${uri} ${elements}
125 [Documentation] A GET is made at the supplied ${URI} and every item in the list of
126 ... ${elements} is verified to NOT exist in the response
127 ${resp} RequestsLibrary.Get Request session ${uri}
129 Should Be Equal As Strings ${resp.status_code} 200
130 : FOR ${i} IN @{elements}
131 \ Should Not Contain ${resp.content} ${i}
134 [Arguments] ${system}=${TOOLS_SYSTEM_IP}
135 Run Command On Mininet ${system} sudo mn -c
136 Run Command On Mininet ${system} sudo ps -elf | egrep 'usr/local/bin/mn' | egrep python | awk '{print "sudo kill -9",$4}' | sh
139 [Arguments] ${system}=${MININET}
140 [Documentation] Cleans up the OVS instance and remove any existing common known bridges.
141 ${output}= Run Command On Mininet ${system} sudo ovs-vsctl list-br
143 : FOR ${i} IN ${output}
144 \ Run Command On Mininet ${system} sudo ovs-vsctl --if-exists del-br ${i}
145 Run Command On Mininet ${system} sudo ovs-vsctl del-manager
147 Extract Value From Content
148 [Arguments] ${content} ${index} ${strip}=nostrip
149 [Documentation] Will take the given response content and return the value at the given index as a string
150 ${value}= Get Json Value ${content} ${index}
151 ${value}= Convert To String ${value}
152 ${value}= Run Keyword If '${strip}' == 'strip' Strip Quotes ${value}
155 Get Process ID Based On Regex On Remote System
156 [Arguments] ${system} ${regex_string_to_match_on} ${user}=${MININET_USER} ${password}=${EMPTY} ${prompt}=${DEFAULT_LINUX_PROMPT} ${prompt_timeout}=30s
157 [Documentation] Uses ps to find a process that matches the supplied regex. Returns the PID of that process
158 ... The ${regex_string_to_match_on} should produce a unique process otherwise the PID returned may not be
160 # doing the extra -v grep in this command to exclude the grep process itself from the output
161 ${cmd}= Set Variable ps -elf | grep -v grep | grep ${regex_string_to_match_on} | awk '{print $4}'
162 ${output}= Run Command On Remote System ${system} ${cmd} user=${user} password=${password} prompt=${prompt}
163 ... prompt_timeout=${prompt_timeout}
164 # ${output} contains the system prompt and all we want is the value of the number
165 ${pid}= Fetch From Left ${output} \r
166 # TODO: Get Process * keywords have perhaps non-standard default credentials.
167 # ... Should there be * On Mininet and * On Controller specializations?
170 Get Process Thread Count On Remote System
171 [Arguments] ${system} ${pid} ${user}=${MININET_USER} ${password}=${EMPTY} ${prompt}=${DEFAULT_LINUX_PROMPT} ${prompt_timeout}=30s
172 [Documentation] Executes the ps command to retrieve the lightweight process (aka thread) count.
173 ${cmd}= Set Variable ps --no-headers -o nlwp ${pid}
174 ${output}= Run Command On Remote System ${system} ${cmd} user=${user} password=${password} prompt=${prompt}
175 ... prompt_timeout=${prompt_timeout}
176 # ${output} contains the system prompt and all we want is the value of the number
177 ${thread_count}= Fetch From Left ${output} \r
178 [Return] ${thread_count}
181 [Arguments] ${string_to_strip}
182 [Documentation] Will strip ALL quotes from given string and return the new string
183 ${string_to_return}= Replace String ${string_to_strip} " \ count=-1
184 [Return] ${string_to_return}
187 [Arguments] ${user} ${password}=${EMPTY} ${delay}=0.5s
188 [Documentation] On active SSH session: if given non-empty password, do Login, else do Login With Public Key.
189 ${pwd_length} = BuiltIn.Get Length ${password}
190 # ${pwd_length} is guaranteed to be an integer, so we are safe to evaluate it as Python expression.
191 BuiltIn.Run Keyword And Return If ${pwd_length} > 0 SSHLibrary.Login ${user} ${password} delay=${delay}
192 BuiltIn.Run Keyword And Return SSHLibrary.Login With Public Key ${user} ${USER_HOME}/.ssh/${SSH_KEY} ${KEYFILE_PASS} delay=${delay}
194 Flexible Mininet Login
195 [Arguments] ${user}=${TOOLS_SYSTEM_USER} ${password}=${TOOLS_SYSTEM_PASSWORD} ${delay}=0.5s
196 [Documentation] Call Flexible SSH Login, but with default values suitable for Mininet machine.
197 BuiltIn.Run Keyword And Return Flexible SSH Login user=${user} password=${password} delay=${delay}
199 Flexible Controller Login
200 [Arguments] ${user}=${ODL_SYSTEM_USER} ${password}=${ODL_SYSTEM_PASSWORD} ${delay}=0.5s
201 [Documentation] Call Flexible SSH Login, but with default values suitable for Controller machine.
202 BuiltIn.Run Keyword And Return Flexible SSH Login user=${user} password=${password} delay=${delay}
204 Run Command On Remote System
205 [Arguments] ${system} ${cmd} ${user}=${DEFAULT_USER} ${password}=${EMPTY} ${prompt}=${DEFAULT_LINUX_PROMPT} ${prompt_timeout}=${DEFAULT_TIMEOUT}
206 [Documentation] Reduces the common work of running a command on a remote system to a single higher level
207 ... robot keyword, taking care to log in with a public key and. The command given is written
208 ... and the output returned. No test conditions are checked.
209 Log Attempting to execute ${cmd} on ${system} by ${user} with ${keyfile_pass} and ${prompt}
210 ${conn_id}= SSHLibrary.Open Connection ${system} prompt=${prompt} timeout=${prompt_timeout}
211 Flexible SSH Login ${user} ${password}
212 ${stdout} ${stderr} SSHLibrary.Execute Command ${cmd} return_stderr=True
213 SSHLibrary.Close Connection
218 [Documentation] Construct ctrl+c character and SSH-write it (without endline) to the current SSH connection.
219 ... Do not read anything yet.
220 ${ctrl_c}= BuiltIn.Evaluate chr(int(3))
221 SSHLibrary.Write_Bare ${ctrl_c}
224 [Documentation] Construct ctrl+d character and SSH-write it (without endline) to the current SSH connection.
225 ... Do not read anything yet.
226 ${ctrl_d}= BuiltIn.Evaluate chr(int(4))
227 SSHLibrary.Write Bare ${ctrl_d}
229 Run Command On Mininet
230 [Arguments] ${system}=${TOOLS_SYSTEM_IP} ${cmd}=echo ${user}=${TOOLS_SYSTEM_USER} ${password}=${TOOLS_SYSTEM_PASSWORD} ${prompt}=${TOOLS_SYSTEM_PROMPT}
231 [Documentation] Call Run Comand On Remote System, but with default values suitable for Mininet machine.
232 BuiltIn.Run Keyword And Return Run Command On Remote System ${system} ${cmd} ${user} ${password} prompt=${prompt}
234 Run Command On Controller
235 [Arguments] ${system}=${ODL_SYSTEM_IP} ${cmd}=echo ${user}=${ODL_SYSTEM_USER} ${password}=${ODL_SYSTEM_PASSWORD} ${prompt}=${ODL_SYSTEM_PROMPT}
236 [Documentation] Call Run Comand On Remote System, but with default values suitable for Controller machine.
237 BuiltIn.Run Keyword And Return Run Command On Remote System ${system} ${cmd} ${user} ${password} prompt=${prompt}
239 Verify File Exists On Remote System
240 [Arguments] ${system} ${file} ${user}=${MININET_USER} ${password}=${MININET_PASSWORD} ${prompt}=${DEFAULT_LINUX_PROMPT} ${prompt_timeout}=5s
241 [Documentation] Will create connection with public key and will PASS if the given ${file} exists,
242 ... otherwise will FAIL
243 ${conn_id}= Open Connection ${system} prompt=${prompt} timeout=${prompt_timeout}
244 Flexible SSH Login ${user} ${password}
245 SSHLibrary.File Should Exist ${file}
248 Verify Controller Is Not Dead
249 [Arguments] ${controller_ip}=${CONTROLLER}
250 [Documentation] Will execute any tests to verify the controller is not dead. Some checks are
251 ... Out Of Memory Execptions.
252 Check Karaf Log File Does Not Have Messages ${controller_ip} java.lang.OutOfMemoryError
253 # TODO: Should Verify Controller * keywords also accept user, password, prompt and karaf_log arguments?
255 Verify Controller Has No Null Pointer Exceptions
256 [Arguments] ${controller_ip}=${CONTROLLER}
257 [Documentation] Will execute any tests to verify the controller is not having any null pointer eceptions.
258 Check Karaf Log File Does Not Have Messages ${controller_ip} java.lang.NullPointerException
262 [Documentation] Get the Epoc time from MM/DD/YYYY HH:MM:SS
263 ${epoch_time}= Convert Date ${time} epoch exclude_milles=True date_format=%m/%d/%Y %H:%M:%S
264 ${epoch_time}= Convert To Integer ${epoch_time}
265 [Return] ${epoch_time}
267 Remove Space on String
268 [Arguments] ${str} ${count}=-1
269 [Documentation] Remove the empty space from given string.count is optional,if its given
270 ... that many occurence of space will be removed from left
271 ${x}= Convert To String ${str}
272 ${x}= Replace String ${str} ${SPACE} ${EMPTY} count=${count}
275 Split Value from String
276 [Arguments] ${str} ${splitter}
277 [Documentation] Split the String based on given splitter and return as list
278 @{x}= Split String ${str} ${splitter}
281 Concatenate the String
282 [Arguments] ${str1} ${str2}
283 [Documentation] Catenate the two non-string objects and return as String
284 ${str1}= Convert to String ${str1}
285 ${str2}= Convert to String ${str2}
286 ${output}= Catenate ${str1} ${str2}
290 [Arguments] ${rest_uri} ${data}
291 [Documentation] Perform a POST rest operation, using the URL and data provided
292 ${resp} = RequestsLibrary.Post Request session ${rest_uri} data=${data} headers=${headers}
293 Should Be Equal As Strings ${resp.status_code} 200
295 Remove All Elements At URI
297 ${resp} RequestsLibrary.Delete Request session ${uri}
298 Should Be Equal As Strings ${resp.status_code} 200
300 Remove All Elements At URI And Verify
302 ${resp} RequestsLibrary.Delete Request session ${uri}
303 Should Be Equal As Strings ${resp.status_code} 200
304 ${resp} RequestsLibrary.Get session ${uri}
305 Should Be Equal As Strings ${resp.status_code} 404
307 Add Elements To URI From File
308 [Arguments] ${dest_uri} ${data_file}
309 ${body} OperatingSystem.Get File ${data_file}
310 ${resp} RequestsLibrary.Put Request session ${dest_uri} data=${body} headers=${headers}
311 Should Be Equal As Strings ${resp.status_code} 200
313 Post Elements To URI From File
314 [Arguments] ${dest_uri} ${data_file}
315 ${body} OperatingSystem.Get File ${data_file}
316 ${resp} RequestsLibrary.Post Request session ${dest_uri} data=${body} headers=${headers}
317 Should Be Equal As Strings ${resp.status_code} 200
319 Run Process With Logging And Status Check
320 [Arguments] @{proc_args}
321 [Documentation] Execute an OS command, log STDOUT and STDERR output and check exit code to be 0
322 ${result}= Run Process @{proc_args}
325 Should Be Equal As Integers ${result.rc} 0
329 [Arguments] ${session} ${uri} ${headers}=${NONE}
330 [Documentation] Issue a GET request and return the data obtained or on error log the error and fail.
331 ... Issues a GET request for ${uri} in ${session} using headers from
332 ... ${headers}. If the request returns a HTTP error, fails. Otherwise
333 ... returns the data obtained by the request.
334 ${response}= RequestsLibrary.Get Request ${session} ${uri} ${headers}
335 Builtin.Return_From_Keyword_If ${response.status_code} == 200 ${response.text}
336 Builtin.Log ${response.text}
337 Builtin.Fail The request failed with code ${response.status_code}
340 [Arguments] ${session} ${uri} ${headers}=${NONE}
341 [Documentation] Issue a GET request and return on error 404 (No content) or will fail and log the content.
342 ... Issues a GET request for ${uri} in ${session} using headers from
343 ... ${headers}. If the request returns a HTTP error, fails. Otherwise
344 ... returns the data obtained by the request.
345 ${response}= RequestsLibrary.Get Request ${session} ${uri} ${headers}
346 Builtin.Return_From_Keyword_If ${response.status_code} == 404
347 Builtin.Log ${response.text}
348 Builtin.Fail The request failed with code ${response.status_code}
350 Get Index From List Of Dictionaries
351 [Arguments] ${dictionary_list} ${key} ${value}
352 [Documentation] Extract index for the dictionary in a list that contains a key-value pair. Returns -1 if key-value is not found.
353 ${length}= Get Length ${dictionary_list}
354 ${index}= Set Variable -1
355 : FOR ${i} IN RANGE ${length}
356 \ ${dictionary}= Get From List ${dictionary_list} ${i}
357 \ Run Keyword If '&{dictionary}[${key}]' == '${value}' Set Test Variable ${index} ${i}
360 Check Item Occurrence
361 [Arguments] ${string} ${dictionary_item_occurrence}
362 [Documentation] Check string for occurrences of items expressed in a list of dictionaries {item=occurrences}. 0 occurences means item is not present.
363 : FOR ${item} IN @{dictionary_item_occurrence}
364 \ Should Contain X Times ${string} ${item} &{dictionary_item_occurrence}[${item}]