383178a189228098ca61bc58c0ad6f598258ba2f
[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 ${controller_index}    -1
14
15 *** Keywords ***
16 Start Suite
17     [Arguments]    ${system}=${MININET}    ${user}=${MININET_USER}    ${password}=${MININET_PASSWORD}    ${prompt}=${DEFAULT_LINUX_PROMPT}    ${timeout}=30s
18     [Documentation]    Basic setup/cleanup work that can be done safely before any system
19     ...    is run.
20     Log    Start the test on the base edition
21     Clean Mininet System
22     ${mininet_conn_id}=    Open Connection    ${system}    prompt=${DEFAULT_LINUX_PROMPT}    timeout=${timeout}
23     Set Suite Variable    ${mininet_conn_id}
24     Flexible Mininet Login    user=${user}    password=${password}
25     Execute Command    sudo ovs-vsctl set-manager ptcp:6644
26     Write    ${start}
27     Read Until    mininet>
28
29 Start Mininet
30     [Arguments]    ${system}=${MININET}    ${cmd}=${start}    ${custom}=    ${user}=${MININET_USER}    ${password}=${MININET_PASSWORD}    ${prompt}=${DEFAULT_LINUX_PROMPT}
31     ...    ${prompt_timeout}=30s
32     [Documentation]    Basic setup to start mininet with custom topology
33     Log    Start the test on the base edition
34     Clean Mininet System
35     ${mininet_conn_id}=    Open Connection    ${system}    prompt=${prompt}    timeout=${prompt_timeout}
36     Set Suite Variable    ${mininet_conn_id}
37     Flexible Mininet Login    user=${user}    password=${password}
38     Put File    ${custom}
39     Write    ${cmd}
40     Read Until    mininet>
41     [Return]    ${mininet_conn_id}
42
43 Connect To Controller Karaf
44     [Documentation]    Connect to the controller's karaf console.
45     ${esc}=    BuiltIn.Evaluate    chr(int(27))
46     ${prompt}=    Builtin.Set Variable    @${esc}[0m${esc}[34mroot${esc}[0m>
47     ${connection}=    SSHLibrary.Open_Connection    ${CONTROLLER}    port=${KARAF_SHELL_PORT}    prompt=${prompt}
48     Set Suite Variable    ${controller_index}    ${connection}
49     SSHLibrary.Login    ${KARAF_USER}    ${KARAF_PASSWORD}
50
51 Log Message To Controller Karaf
52     [Arguments]    ${message}
53     [Documentation]    Send a message into the controller's karaf log file.
54     # Background info: If there was no previous SSH connection, the "Get
55     # Connection" returns an information structure whose "index" field
56     # resolves to "None", and the "Switch Connection" below does not
57     # complain.
58     ${current}=    Get_Connection
59     ${connection}=    Set Variable    ${current.index}
60     BuiltIn.Run Keyword If    ${controller_index} <> -1    Switch Connection    ${controller_index}
61     BuiltIn.Run Keyword If    ${controller_index} == -1    Connect to Controller Karaf
62     SSHLibrary.Write    log:log "ROBOT MESSAGE: ${message}"
63     SSHLibrary.Read_Until_Prompt
64     Switch Connection    ${connection}
65
66 Stop Mininet
67     [Arguments]    ${mininet_conn_id}    ${prompt}=${DEFAULT_LINUX_PROMPT}
68     [Documentation]    Basic setup to stop/clean mininet
69     Switch Connection    ${mininet_conn_id}
70     SSHLibrary.Write    exit
71     Read Until    ${prompt}
72     Close Connection
73
74 Stop Suite
75     [Arguments]    ${prompt}=${DEFAULT_LINUX_PROMPT}
76     [Documentation]    Cleanup/Shutdown work that should be done at the completion of all
77     ...    tests
78     Log    Stop the test on the base edition
79     Switch Connection    ${mininet_conn_id}
80     Read
81     Write    exit
82     Read Until    ${prompt}
83     Close Connection
84
85 Ensure All Nodes Are In Response
86     [Arguments]    ${URI}    ${node_list}
87     [Documentation]    A GET is made to the supplied ${URI} and every item in the ${node_list}
88     ...    is verified to exist in the repsonse. This keyword currently implies that it's node
89     ...    specific but any list of strings can be given in ${node_list}. Refactoring of this
90     ...    to make it more generic should be done. (see keyword "Check For Elements At URI")
91     : FOR    ${node}    IN    @{node_list}
92     \    ${resp}    RequestsLibrary.Get    session    ${URI}
93     \    Should Be Equal As Strings    ${resp.status_code}    200
94     \    Should Contain    ${resp.content}    ${node}
95
96 Check Nodes Stats
97     [Arguments]    ${node}
98     [Documentation]    A GET on the /node/${node} API is made and specific flow stat
99     ...    strings are checked for existence.
100     ${resp}    RequestsLibrary.Get    session    ${OPERATIONAL_NODES_API}/node/${node}
101     Should Be Equal As Strings    ${resp.status_code}    200
102     Should Contain    ${resp.content}    flow-capable-node-connector-statistics
103     Should Contain    ${resp.content}    flow-table-statistics
104
105 Check That Port Count Is Ok
106     [Arguments]    ${node}    ${count}
107     [Documentation]    A GET on the /port API is made and the specified port ${count} is
108     ...    verified. A more generic Keyword "Check For Specific Number Of Elements At URI"
109     ...    also does this work and further consolidation should be done.
110     ${resp}    RequestsLibrary.Get    session    ${REST_CONTEXT}/${CONTAINER}/port
111     Log    ${resp.content}
112     Should Be Equal As Strings    ${resp.status_code}    200
113     Should Contain X Times    ${resp.content}    ${node}    ${count}
114
115 Check For Specific Number Of Elements At URI
116     [Arguments]    ${uri}    ${element}    ${expected_count}
117     [Documentation]    A GET is made to the specified ${URI} and the specific count of a
118     ...    given element is done (as supplied by ${element} and ${expected_count})
119     ${resp}    RequestsLibrary.Get    session    ${uri}
120     Log    ${resp.content}
121     Should Be Equal As Strings    ${resp.status_code}    200
122     Should Contain X Times    ${resp.content}    ${element}    ${expected_count}
123
124 Check For Elements At URI
125     [Arguments]    ${uri}    ${elements}
126     [Documentation]    A GET is made at the supplied ${URI} and every item in the list of
127     ...    ${elements} is verified to exist in the response
128     ${resp}    RequestsLibrary.Get    session    ${uri}
129     Log    ${resp.content}
130     Should Be Equal As Strings    ${resp.status_code}    200
131     : FOR    ${i}    IN    @{elements}
132     \    Should Contain    ${resp.content}    ${i}
133
134 Check For Elements Not At URI
135     [Arguments]    ${uri}    ${elements}
136     [Documentation]    A GET is made at the supplied ${URI} and every item in the list of
137     ...    ${elements} is verified to NOT exist in the response
138     ${resp}    RequestsLibrary.Get    session    ${uri}
139     Log    ${resp.content}
140     Should Be Equal As Strings    ${resp.status_code}    200
141     : FOR    ${i}    IN    @{elements}
142     \    Should Not Contain    ${resp.content}    ${i}
143
144 Clean Mininet System
145     [Arguments]    ${system}=${MININET}
146     Run Command On Mininet    ${system}    sudo mn -c
147     Run Command On Mininet    ${system}    sudo ps -elf | egrep 'usr/local/bin/mn' | egrep python | awk '{print "sudo kill -9",$4}' | sh
148
149 Clean Up Ovs
150     [Arguments]    ${system}=${MININET}
151     [Documentation]    Cleans up the OVS instance and remove any existing common known bridges.
152     ${output}=    Run Command On Mininet    ${system}    sudo ovs-vsctl list-br
153     Log    ${output}
154     : FOR    ${i}    IN    ${output}
155     \    Run Command On Mininet    ${system}    sudo ovs-vsctl --if-exists del-br ${i}
156     Run Command On Mininet    ${system}    sudo ovs-vsctl del-manager
157
158 Extract Value From Content
159     [Arguments]    ${content}    ${index}    ${strip}=nostrip
160     [Documentation]    Will take the given response content and return the value at the given index as a string
161     ${value}=    Get Json Value    ${content}    ${index}
162     ${value}=    Convert To String    ${value}
163     ${value}=    Run Keyword If    '${strip}' == 'strip'    Strip Quotes    ${value}
164     [Return]    ${value}
165
166 Get Process ID Based On Regex On Remote System
167     [Arguments]    ${system}    ${regex_string_to_match_on}    ${user}=${MININET_USER}    ${password}=${EMPTY}    ${prompt}=${DEFAULT_LINUX_PROMPT}    ${prompt_timeout}=30s
168     [Documentation]    Uses ps to find a process that matches the supplied regex. Returns the PID of that process
169     ...    The ${regex_string_to_match_on} should produce a unique process otherwise the PID returned may not be
170     ...    the expected PID
171     # doing the extra -v grep in this command to exclude the grep process itself from the output
172     ${cmd}=    Set Variable    ps -elf | grep -v grep | grep ${regex_string_to_match_on} | awk '{print $4}'
173     ${output}=    Run Command On Remote System    ${system}    ${cmd}    user=${user}    password=${password}    prompt=${prompt}
174     ...    prompt_timeout=${prompt_timeout}
175     # ${output} contains the system prompt and all we want is the value of the number
176     ${pid}=    Fetch From Left    ${output}    \r
177     # TODO: Get Process * keywords have perhaps non-standard default credentials.
178     # ...    Should there be * On Mininet and * On Controller specializations?
179     [Return]    ${pid}
180
181 Get Process Thread Count On Remote System
182     [Arguments]    ${system}    ${pid}    ${user}=${MININET_USER}    ${password}=${EMPTY}    ${prompt}=${DEFAULT_LINUX_PROMPT}    ${prompt_timeout}=30s
183     [Documentation]    Executes the ps command to retrieve the lightweight process (aka thread) count.
184     ${cmd}=    Set Variable    ps --no-headers -o nlwp ${pid}
185     ${output}=    Run Command On Remote System    ${system}    ${cmd}    user=${user}    password=${password}    prompt=${prompt}
186     ...    prompt_timeout=${prompt_timeout}
187     # ${output} contains the system prompt and all we want is the value of the number
188     ${thread_count}=    Fetch From Left    ${output}    \r
189     [Return]    ${thread_count}
190
191 Strip Quotes
192     [Arguments]    ${string_to_strip}
193     [Documentation]    Will strip ALL quotes from given string and return the new string
194     ${string_to_return}=    Replace String    ${string_to_strip}    "    \    count=-1
195     [Return]    ${string_to_return}
196
197 Flexible SSH Login
198     [Arguments]    ${user}    ${password}=${EMPTY}    ${delay}=0.5s
199     [Documentation]    On active SSH session: if given non-empty password, do Login, else do Login With Public Key.
200     ${pwd_length} =    BuiltIn.Get Length    ${password}
201     # ${pwd_length} is guaranteed to be an integer, so we are safe to evaluate it as Python expression.
202     BuiltIn.Run Keyword And Return If    ${pwd_length} > 0    SSHLibrary.Login    ${user}    ${password}    delay=${delay}
203     BuiltIn.Run Keyword And Return    SSHLibrary.Login With Public Key    ${user}    ${USER_HOME}/.ssh/${SSH_KEY}    ${KEYFILE_PASS}    delay=${delay}
204
205 Flexible Mininet Login
206     [Arguments]    ${user}=${MININET_USER}    ${password}=${MININET_PASSWORD}    ${delay}=0.5s
207     [Documentation]    Call Flexible SSH Login, but with default values suitable for Mininet machine.
208     BuiltIn.Run Keyword And Return    Flexible SSH Login    user=${user}    password=${password}    delay=${delay}
209
210 Flexible Controller Login
211     [Arguments]    ${user}=${CONTROLLER_USER}    ${password}=${CONTROLLER_PASSWORD}    ${delay}=0.5s
212     [Documentation]    Call Flexible SSH Login, but with default values suitable for Controller machine.
213     BuiltIn.Run Keyword And Return    Flexible SSH Login    user=${user}    password=${password}    delay=${delay}
214
215 Run Command On Remote System
216     [Arguments]    ${system}    ${cmd}    ${user}=${MININET_USER}    ${password}=${EMPTY}    ${prompt}=${DEFAULT_LINUX_PROMPT}    ${prompt_timeout}=30s
217     [Documentation]    Reduces the common work of running a command on a remote system to a single higher level
218     ...    robot keyword, taking care to log in with a public key and. The command given is written
219     ...    and the output returned. No test conditions are checked.
220     Log    Attempting to execute ${cmd} on ${system} by ${user} with ${keyfile_pass} and ${prompt}
221     ${conn_id}=    SSHLibrary.Open Connection    ${system}    prompt=${prompt}    timeout=${prompt_timeout}
222     Flexible SSH Login    ${user}    ${password}
223     SSHLibrary.Write    ${cmd}
224     ${output}=    SSHLibrary.Read Until    ${prompt}
225     SSHLibrary.Close Connection
226     Log    ${output}
227     [Return]    ${output}
228
229 Write_Bare_Ctrl_C
230     [Documentation]    Construct ctrl+c character and SSH-write it (without endline) to the current SSH connection.
231     ...    Do not read anything yet.
232     ${ctrl_c}=    BuiltIn.Evaluate    chr(int(3))
233     SSHLibrary.Write_Bare    ${ctrl_c}
234
235 Run Command On Mininet
236     [Arguments]    ${system}=${MININET}    ${cmd}=echo    ${user}=${MININET_USER}    ${password}=${MININET_PASSWORD}    ${prompt}=${DEFAULT_LINUX_PROMPT}    ${prompt_timeout}=30s
237     [Documentation]    Call Run Comand On Remote System, but with default values suitable for Mininet machine.
238     BuiltIn.Run Keyword And Return    Run Command On Remote System    ${system}    ${cmd}    user=${user}    password=${password}    prompt=${prompt}
239     ...    prompt_timeout=${prompt_timeout}
240
241 Run Command On Controller
242     [Arguments]    ${system}=${CONTROLLER}    ${cmd}=echo    ${user}=${CONTROLLER_USER}    ${password}=${CONTROLLER_PASSWORD}    ${prompt}=${DEFAULT_LINUX_PROMPT}    ${prompt_timeout}=30s
243     [Documentation]    Call Run Comand On Remote System, but with default values suitable for Controller machine.
244     BuiltIn.Run Keyword And Return    Run Command On Remote System    ${system}    ${cmd}    user=${user}    password=${password}    prompt=${prompt}
245     ...    prompt_timeout=${prompt_timeout}
246
247 Verify File Exists On Remote System
248     [Arguments]    ${system}    ${file}    ${user}=${MININET_USER}    ${password}=${MININET_PASSWORD}    ${prompt}=${DEFAULT_LINUX_PROMPT}    ${prompt_timeout}=5s
249     [Documentation]    Will create connection with public key and will PASS if the given ${file} exists,
250     ...    otherwise will FAIL
251     ${conn_id}=    Open Connection    ${system}    prompt=${prompt}    timeout=${prompt_timeout}
252     Flexible SSH Login    ${user}    ${password}
253     SSHLibrary.File Should Exist    ${file}
254     Close Connection
255
256 Verify Controller Is Not Dead
257     [Arguments]    ${controller_ip}=${CONTROLLER}
258     [Documentation]    Will execute any tests to verify the controller is not dead. Some checks are
259     ...    Out Of Memory Execptions.
260     Check Karaf Log File Does Not Have Messages    ${controller_ip}    java.lang.OutOfMemoryError
261     # TODO: Should Verify Controller * keywords also accept user, password, prompt and karaf_log arguments?
262
263 Verify Controller Has No Null Pointer Exceptions
264     [Arguments]    ${controller_ip}=${CONTROLLER}
265     [Documentation]    Will execute any tests to verify the controller is not having any null pointer eceptions.
266     Check Karaf Log File Does Not Have Messages    ${controller_ip}    java.lang.NullPointerException
267
268 Get Epoch Time
269     [Arguments]    ${time}
270     [Documentation]    Get the Epoc time from MM/DD/YYYY HH:MM:SS
271     ${epoch_time}=    Convert Date    ${time}    epoch    exclude_milles=True    date_format=%m/%d/%Y %H:%M:%S
272     ${epoch_time}=    Convert To Integer    ${epoch_time}
273     [Return]    ${epoch_time}
274
275 Remove Space on String
276     [Arguments]    ${str}    ${count}=-1
277     [Documentation]    Remove the empty space from given string.count is optional,if its given
278     ...    that many occurence of space will be removed from left
279     ${x}=    Convert To String    ${str}
280     ${x}=    Replace String    ${str}    ${SPACE}    ${EMPTY}    count=${count}
281     [Return]    ${x}
282
283 Split Value from String
284     [Arguments]    ${str}    ${splitter}
285     [Documentation]    Split the String based on given splitter and return as list
286     @{x}=    Split String    ${str}    ${splitter}
287     [Return]    @{x}
288
289 Concatenate the String
290     [Arguments]    ${str1}    ${str2}
291     [Documentation]    Catenate the two non-string objects and return as String
292     ${str1}=    Convert to String    ${str1}
293     ${str2}=    Convert to String    ${str2}
294     ${output}=    Catenate    ${str1}    ${str2}
295     [Return]    ${output}
296
297 Remove All Elements At URI
298     [Arguments]    ${uri}
299     ${resp}    RequestsLibrary.Delete    session    ${uri}
300     Should Be Equal As Strings    ${resp.status_code}    200
301
302 Add Elements To URI From File
303     [Arguments]    ${dest_uri}    ${data_file}
304     ${body}    OperatingSystem.Get File    ${data_file}
305     ${resp}    RequestsLibrary.Put    session    ${dest_uri}    data=${body}    headers=${headers}
306     Should Be Equal As Strings    ${resp.status_code}    200
307
308 Post Elements To URI From File
309     [Arguments]    ${dest_uri}    ${data_file}
310     ${body}    OperatingSystem.Get File    ${data_file}
311     ${resp}    RequestsLibrary.Post    session    ${dest_uri}    data=${body}    headers=${headers}
312     Should Be Equal As Strings    ${resp.status_code}    200
313
314 Run Process With Logging And Status Check
315     [Arguments]    @{proc_args}
316     [Documentation]    Execute an OS command, log STDOUT and STDERR output and check exit code to be 0
317     ${result}=    Run Process    @{proc_args}
318     Log    ${result.stdout}
319     Log    ${result.stderr}
320     Should Be Equal As Integers    ${result.rc}    0
321     [Return]    ${result}