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