Teardown of GBP components from ODL controller
[integration/test.git] / csit / libraries / Utils.robot
1 *** Settings ***
2 Library           SSHLibrary
3 Library           String
4 Library           DateTime
5 Library           Process
6 Library           ./UtilLibrary.py
7 Resource          KarafKeywords.robot
8 Variables         ../variables/Variables.py
9
10 *** Variables ***
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
13
14 *** Keywords ***
15 Start Suite
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
18     ...    is run.
19     Log    Start the test on the base edition
20     Clean Mininet System
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
25     Write    ${start}
26     Read Until    mininet>
27
28 Start Mininet
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
33     Clean Mininet System
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}
37     Put File    ${custom}
38     Write    ${cmd}
39     Read Until    mininet>
40     [Return]    ${mininet_conn_id}
41
42 Stop Mininet
43     [Arguments]    ${mininet_conn_id}    ${prompt}=${DEFAULT_LINUX_PROMPT}
44     [Documentation]    Basic setup to stop/clean mininet
45     Switch Connection    ${mininet_conn_id}
46     SSHLibrary.Write    exit
47     Read Until    ${prompt}
48     Close Connection
49
50 Stop Suite
51     [Arguments]    ${prompt}=${DEFAULT_LINUX_PROMPT}
52     [Documentation]    Cleanup/Shutdown work that should be done at the completion of all
53     ...    tests
54     Log    Stop the test on the base edition
55     Switch Connection    ${mininet_conn_id}
56     Read
57     Write    exit
58     Read Until    ${prompt}
59     Close Connection
60
61 Report_Failure_Due_To_Bug
62     [Arguments]    ${number}
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}
73
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}
84
85 Check Nodes Stats
86     [Arguments]    ${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
93
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
100     Log    ${resp.content}
101     Should Be Equal As Strings    ${resp.status_code}    200
102     Should Contain X Times    ${resp.content}    ${node}    ${count}
103
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}
109     Log    ${resp.content}
110     Should Be Equal As Strings    ${resp.status_code}    200
111     Should Contain X Times    ${resp.content}    ${element}    ${expected_count}
112
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}
118     Log    ${resp.content}
119     Should Be Equal As Strings    ${resp.status_code}    200
120     : FOR    ${i}    IN    @{elements}
121     \    Should Contain    ${resp.content}    ${i}
122
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}
128     Log    ${resp.content}
129     Should Be Equal As Strings    ${resp.status_code}    200
130     : FOR    ${i}    IN    @{elements}
131     \    Should Not Contain    ${resp.content}    ${i}
132
133 Clean Mininet System
134     [Arguments]    ${system}=${MININET}
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
137
138 Clean Up Ovs
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
142     Log    ${output}
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
146
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}
153     [Return]    ${value}
154
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
159     ...    the expected PID
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?
168     [Return]    ${pid}
169
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}
179
180 Strip Quotes
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}
185
186 Flexible SSH Login
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}
193
194 Flexible Mininet Login
195     [Arguments]    ${user}=${MININET_USER}    ${password}=${MININET_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}
198
199 Flexible Controller Login
200     [Arguments]    ${user}=${CONTROLLER_USER}    ${password}=${CONTROLLER_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}
203
204 Run Command On Remote System
205     [Arguments]    ${system}    ${cmd}    ${user}=${MININET_USER}    ${password}=${EMPTY}    ${prompt}=${DEFAULT_LINUX_PROMPT}    ${prompt_timeout}=30s
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     SSHLibrary.Write    ${cmd}
213     ${output}=    SSHLibrary.Read Until    ${prompt}
214     SSHLibrary.Close Connection
215     Log    ${output}
216     [Return]    ${output}
217
218 Write_Bare_Ctrl_C
219     [Documentation]    Construct ctrl+c character and SSH-write it (without endline) to the current SSH connection.
220     ...    Do not read anything yet.
221     ${ctrl_c}=    BuiltIn.Evaluate    chr(int(3))
222     SSHLibrary.Write_Bare    ${ctrl_c}
223
224 Write Bare Ctrl D
225     [Documentation]    Construct ctrl+d character and SSH-write it (without endline) to the current SSH connection.
226     ...    Do not read anything yet.
227     ${ctrl_d}=    BuiltIn.Evaluate    chr(int(4))
228     SSHLibrary.Write Bare    ${ctrl_d}
229
230 Run Command On Mininet
231     [Arguments]    ${system}=${MININET}    ${cmd}=echo    ${user}=${MININET_USER}    ${password}=${MININET_PASSWORD}    ${prompt}=${DEFAULT_LINUX_PROMPT}    ${prompt_timeout}=30s
232     [Documentation]    Call Run Comand On Remote System, but with default values suitable for Mininet machine.
233     BuiltIn.Run Keyword And Return    Run Command On Remote System    ${system}    ${cmd}    user=${user}    password=${password}    prompt=${prompt}
234     ...    prompt_timeout=${prompt_timeout}
235
236 Run Command On Controller
237     [Arguments]    ${system}=${CONTROLLER}    ${cmd}=echo    ${user}=${CONTROLLER_USER}    ${password}=${CONTROLLER_PASSWORD}    ${prompt}=${DEFAULT_LINUX_PROMPT}    ${prompt_timeout}=30s
238     [Documentation]    Call Run Comand On Remote System, but with default values suitable for Controller machine.
239     BuiltIn.Run Keyword And Return    Run Command On Remote System    ${system}    ${cmd}    user=${user}    password=${password}    prompt=${prompt}
240     ...    prompt_timeout=${prompt_timeout}
241
242 Verify File Exists On Remote System
243     [Arguments]    ${system}    ${file}    ${user}=${MININET_USER}    ${password}=${MININET_PASSWORD}    ${prompt}=${DEFAULT_LINUX_PROMPT}    ${prompt_timeout}=5s
244     [Documentation]    Will create connection with public key and will PASS if the given ${file} exists,
245     ...    otherwise will FAIL
246     ${conn_id}=    Open Connection    ${system}    prompt=${prompt}    timeout=${prompt_timeout}
247     Flexible SSH Login    ${user}    ${password}
248     SSHLibrary.File Should Exist    ${file}
249     Close Connection
250
251 Verify Controller Is Not Dead
252     [Arguments]    ${controller_ip}=${CONTROLLER}
253     [Documentation]    Will execute any tests to verify the controller is not dead. Some checks are
254     ...    Out Of Memory Execptions.
255     Check Karaf Log File Does Not Have Messages    ${controller_ip}    java.lang.OutOfMemoryError
256     # TODO: Should Verify Controller * keywords also accept user, password, prompt and karaf_log arguments?
257
258 Verify Controller Has No Null Pointer Exceptions
259     [Arguments]    ${controller_ip}=${CONTROLLER}
260     [Documentation]    Will execute any tests to verify the controller is not having any null pointer eceptions.
261     Check Karaf Log File Does Not Have Messages    ${controller_ip}    java.lang.NullPointerException
262
263 Get Epoch Time
264     [Arguments]    ${time}
265     [Documentation]    Get the Epoc time from MM/DD/YYYY HH:MM:SS
266     ${epoch_time}=    Convert Date    ${time}    epoch    exclude_milles=True    date_format=%m/%d/%Y %H:%M:%S
267     ${epoch_time}=    Convert To Integer    ${epoch_time}
268     [Return]    ${epoch_time}
269
270 Remove Space on String
271     [Arguments]    ${str}    ${count}=-1
272     [Documentation]    Remove the empty space from given string.count is optional,if its given
273     ...    that many occurence of space will be removed from left
274     ${x}=    Convert To String    ${str}
275     ${x}=    Replace String    ${str}    ${SPACE}    ${EMPTY}    count=${count}
276     [Return]    ${x}
277
278 Split Value from String
279     [Arguments]    ${str}    ${splitter}
280     [Documentation]    Split the String based on given splitter and return as list
281     @{x}=    Split String    ${str}    ${splitter}
282     [Return]    @{x}
283
284 Concatenate the String
285     [Arguments]    ${str1}    ${str2}
286     [Documentation]    Catenate the two non-string objects and return as String
287     ${str1}=    Convert to String    ${str1}
288     ${str2}=    Convert to String    ${str2}
289     ${output}=    Catenate    ${str1}    ${str2}
290     [Return]    ${output}
291
292 Post Elements To URI
293     [Arguments]    ${rest_uri}    ${data}
294     [Documentation]    Perform a POST rest operation, using the URL and data provided
295     ${resp} =    RequestsLibrary.Post Request    session    ${rest_uri}    data=${data}    headers=${headers}
296     Should Be Equal As Strings    ${resp.status_code}    200
297
298 Remove All Elements At URI
299     [Arguments]    ${uri}
300     ${resp}    RequestsLibrary.Delete Request    session    ${uri}
301     Should Be Equal As Strings    ${resp.status_code}    200
302
303 Remove All Elements At URI And Verify
304     [Arguments]    ${uri}
305     ${resp}    RequestsLibrary.Delete Request    session    ${uri}
306     Should Be Equal As Strings    ${resp.status_code}    200
307     ${resp}    RequestsLibrary.Get    session    ${uri}
308     Should Be Equal As Strings    ${resp.status_code}    404
309
310 Add Elements To URI From File
311     [Arguments]    ${dest_uri}    ${data_file}
312     ${body}    OperatingSystem.Get File    ${data_file}
313     ${resp}    RequestsLibrary.Put Request    session    ${dest_uri}    data=${body}    headers=${headers}
314     Should Be Equal As Strings    ${resp.status_code}    200
315
316 Post Elements To URI From File
317     [Arguments]    ${dest_uri}    ${data_file}
318     ${body}    OperatingSystem.Get File    ${data_file}
319     ${resp}    RequestsLibrary.Post Request    session    ${dest_uri}    data=${body}    headers=${headers}
320     Should Be Equal As Strings    ${resp.status_code}    200
321
322 Run Process With Logging And Status Check
323     [Arguments]    @{proc_args}
324     [Documentation]    Execute an OS command, log STDOUT and STDERR output and check exit code to be 0
325     ${result}=    Run Process    @{proc_args}
326     Log    ${result.stdout}
327     Log    ${result.stderr}
328     Should Be Equal As Integers    ${result.rc}    0
329     [Return]    ${result}
330
331 Get Data From URI
332     [Arguments]    ${session}    ${uri}    ${headers}=${NONE}
333     [Documentation]    Issue a GET request and return the data obtained or on error log the error and fail.
334     ...    Issues a GET request for ${uri} in ${session} using headers from
335     ...    ${headers}. If the request returns a HTTP error, fails. Otherwise
336     ...    returns the data obtained by the request.
337     ${response}=    RequestsLibrary.Get Request    ${session}    ${uri}    ${headers}
338     Builtin.Return_From_Keyword_If    ${response.status_code} == 200    ${response.text}
339     Builtin.Log    ${response.text}
340     Builtin.Fail    The request failed with code ${response.status_code}