2 Documentation Karaf library. General utility keywords for interacting with the karaf environment, such as the
3 ... karaf console, karaf.log, karaf features, and karaf config files.
5 ... This library is useful to deal with controller Karaf console for ssh sessions in cluster.
6 ... Running Setup_Karaf_Keywords is necessary. If SetupUtils initialization is called, this gets initialized as well.
7 ... If this gets initialized, ClusterManagement gets initialized as well.
9 Library OperatingSystem
10 Library ${CURDIR}/netvirt/excepts.py
11 Resource ${CURDIR}/ClusterManagement.robot
12 Resource ${CURDIR}/SSHKeywords.robot
13 Variables ${CURDIR}/../variables/Variables.py
17 ${connection_index_dict} &{EMPTY}
21 [Arguments] ${http_timeout}=${DEFAULT_TIMEOUT_HTTP}
22 [Documentation] Initialize ClusterManagement. Open ssh karaf connections to each ODL.
23 ClusterManagement.ClusterManagement_Setup http_timeout=${http_timeout}
24 ClusterManagement.Run_Bash_Command_On_List_Or_All iptables -I INPUT -p tcp --dport ${KARAF_SHELL_PORT} -j ACCEPT; iptables-save
25 BuiltIn.Comment First connections to Karaf console may fail, so WUKS is used. TODO: Track as a Bug.
26 : FOR ${index} IN @{ClusterManagement__member_index_list}
27 \ BuiltIn.Run_Keyword_And_Ignore_Error BuiltIn.Wait_Until_Keyword_Succeeds 3s 1s Open_Controller_Karaf_Console_On_Background member_index=${index}
29 Verify_Feature_Is_Installed
30 [Arguments] ${feature_name} ${controller}=${ODL_SYSTEM_IP} ${karaf_port}=${KARAF_SHELL_PORT}
31 [Documentation] Will Succeed if the given ${feature_name} is found in the output of "feature:list -i"
32 ${output} = Issue_Command_On_Karaf_Console feature:list -i | grep ${feature_name} ${controller} ${karaf_port}
33 BuiltIn.Should_Contain ${output} ${feature_name}
36 Issue_Command_On_Karaf_Console
37 [Arguments] ${cmd} ${controller}=${ODL_SYSTEM_IP} ${karaf_port}=${KARAF_SHELL_PORT} ${timeout}=10 ${loglevel}=INFO
38 [Documentation] Will execute the given ${cmd} by ssh'ing to the karaf console running on ${controller}
39 ... Note that this keyword will open&close new SSH connection, without switching back to previously current session.
40 SSHLibrary.Open_Connection ${controller} port=${karaf_port} prompt=${KARAF_PROMPT_LOGIN} timeout=${timeout}
41 SSHLibrary.Login ${KARAF_USER} ${KARAF_PASSWORD} loglevel=${loglevel}
42 SSHLibrary.Write ${cmd}
43 ${output} SSHLibrary.Read_Until_Regexp ${KARAF_PROMPT}
44 SSHLibrary.Close_Connection
48 Safe_Issue_Command_On_Karaf_Console
49 [Arguments] ${cmd} ${controller}=${ODL_SYSTEM_IP} ${karaf_port}=${KARAF_SHELL_PORT} ${timeout}=10 ${loglevel}=INFO
50 [Documentation] Run Issue_Command_On_Karaf_Console but restore previous connection afterwards.
51 BuiltIn.Run_Keyword_And_Return SSHKeywords.Run_Keyword_Preserve_Connection Issue_Command_On_Karaf_Console ${cmd} ${controller} ${karaf_port} ${timeout}
54 Check For Elements On Karaf Command Output Message
55 [Arguments] ${cmd} ${elements} ${controller}=${ODL_SYSTEM_IP} ${karaf_port}=${KARAF_SHELL_PORT} ${timeout}=5
56 [Documentation] Will execute the command using Issue Command On Karaf Console then check for the given elements
57 ... in the command output message
58 ${output} Issue_Command_On_Karaf_Console ${cmd} ${controller} ${karaf_port} ${timeout}
59 : FOR ${i} IN @{elements}
60 \ BuiltIn.Should_Contain ${output} ${i}
62 Verify_Bundle_Is_Installed
63 [Arguments] ${bundle_name} ${controller}=${ODL_SYSTEM_IP} ${karaf_port}=${KARAF_SHELL_PORT}
64 [Documentation] Will succeed if the given ${bundle name} is present in the output of "bundle:list -s "
65 ${output} = Issue_Command_On_Karaf_Console bundle:list -s | grep ${bundle_name} ${controller} ${karaf_port}
66 BuiltIn.Should_Contain ${output} ${bundle_name}
69 Verify_Bundle_Is_Not_Installed
70 [Arguments] ${bundle_name} ${controller}=${ODL_SYSTEM_IP} ${karaf_port}=${KARAF_SHELL_PORT}
71 [Documentation] Will succeed if the given ${bundle_name} is NOT found in the output of "bundle:list -s"
72 ${output} = Issue_Command_On_Karaf_Console bundle:list -i | grep ${bundle_name} ${controller} ${karaf_port}
73 BuiltIn.Should_Not_Contain ${output} ${bundle_name}
76 Check_Karaf_Log_Has_Messages
77 [Arguments] ${filter_string} @{message_list}
78 [Documentation] Will succeed if the @{messages} are found in \ the output of "log:display"
79 ${output} = Issue_Command_On_Karaf_Console log:display | grep ${filter_string}
80 : FOR ${message} IN @{message_list}
81 \ BuiltIn.Should_Contain ${output} ${message}
84 Check_Karaf_Log_Message_Count
85 [Arguments] ${message} ${count} ${use_console}=False
86 [Documentation] Verifies that the ${message} exists specified number of times in
87 ... karaf console log or Karaf Log Folder based on the arg ${use_console}.
88 Run Keyword If ${use_console} == False Check_Karaf_Log_File ${message} ${count}
89 ... ELSE Check_Karaf_Log_From_Console ${message} ${count}
91 Check_Karaf_Log_From_Console
92 [Arguments] ${message} ${count}
93 [Documentation] Verifies that the ${message} exists in the Karaf Console log:display and checks
94 ... that it appears ${count} number of times
95 ${output} = Issue_Command_On_Karaf_Console log:display | grep ${message} | wc -l
96 ${line} = Get Line ${output} 0
97 ${stripped} = Strip String ${line}
98 Should Be Equal As Strings ${stripped} ${count}
101 [Arguments] ${message} ${count}
102 [Documentation] Verifies that the ${message} exists in the Karaf Log Folder and checks
103 ... that it appears ${count} number of times
104 ${output} Run Command On Controller ${ODL_SYSTEM_IP} grep -o ${message} ${WORKSPACE}/${BUNDLEFOLDER}/data/log/* | wc -l
105 Should Be Equal As Strings ${output} ${count}
108 [Arguments] ${feature_name} ${controller}=${ODL_SYSTEM_IP} ${karaf_port}=${KARAF_SHELL_PORT} ${timeout}=180
109 [Documentation] Will Install the given ${feature_name}
110 BuiltIn.Log ${timeout}
111 ${output} = Issue_Command_On_Karaf_Console feature:install ${feature_name} ${controller} ${karaf_port} ${timeout}
112 BuiltIn.Log ${output}
115 Install_A_Feature_Using_Active_Connection
116 [Arguments] ${feature_name}
117 [Documentation] Will Install the given ${feature_name} using active connection
118 ${cmd} = BuiltIn.Set_Variable feature:install ${feature_name}
119 SSHLibrary.Write ${cmd}
120 ${output} SSHLibrary.Read_Until_Regexp ${KARAF_PROMPT}
121 BuiltIn.Log ${output}
125 [Arguments] ${feature_name} ${controller}=${ODL_SYSTEM_IP} ${karaf_port}=${KARAF_SHELL_PORT} ${timeout}=180
126 [Documentation] Will UnInstall the given ${feature_name}
127 ${output} = Issue_Command_On_Karaf_Console feature:uninstall ${feature_name} ${controller} ${karaf_port} ${timeout}
128 BuiltIn.Log ${output}
131 Open_Controller_Karaf_Console_On_Background
132 [Arguments] ${member_index}=${1} ${timeout}=10 ${loglevel}=INFO
133 [Documentation] If there is a stored ssh connection index of connection to the controller's karaf console for ${member_index},
134 ... close the previous connection. In any case create a new connection
135 ... to karaf console for ${member_index}, set correct prompt set and login to karaf console.
136 ... Store connection index for ${member_index} and restore the previous active connection.
137 ${current_ssh_connection_object}= SSHLibrary.Get_Connection
138 BuiltIn.Log ${connection_index_dict}
139 BuiltIn.Log ${member_index}
140 ${status} ${old_connection_index} = BuiltIn.Run_Keyword_And_Ignore_Error Get From Dictionary ${connection_index_dict} ${member_index}
141 BuiltIn.Run_Keyword_If '${status}'=='PASS' BuiltIn.Run_Keywords SSHLibrary.Switch_Connection ${old_connection_index}
142 ... AND SSHLibrary.Close_Connection
143 ${odl_ip} = ClusterManagement.Resolve_IP_Address_For_Member ${member_index}
144 SSHLibrary.Open_Connection ${odl_ip} port=${KARAF_SHELL_PORT} prompt=${KARAF_PROMPT_LOGIN} timeout=${timeout}
145 ${karaf_connection_object} = SSHLibrary.Get_Connection
146 Collections.Set_To_Dictionary ${connection_index_dict} ${member_index} ${karaf_connection_object.index}
147 SSHLibrary.Login ${KARAF_USER} ${KARAF_PASSWORD} loglevel=${loglevel}
148 [Teardown] SSHKeywords.Restore_Current_Ssh_Connection_From_Index ${current_ssh_connection_object.index}
150 Open_Controller_Karaf_Console_With_Timeout
151 [Arguments] ${member_index}=${1} ${timeout}=3s
152 [Documentation] Open new connection to karaf console for member index with specified timeout.
153 BuiltIn.Log ${member_index}
154 ${odl_ip} = ClusterManagement.Resolve_IP_Address_For_Member ${member_index}
155 SSHLibrary.Open_Connection ${odl_ip} port=${KARAF_SHELL_PORT} prompt=${KARAF_PROMPT_LOGIN} timeout=${timeout}
156 SSHLibrary.Login ${KARAF_USER} ${KARAF_PASSWORD}
158 Configure_Timeout_For_Karaf_Console
159 [Arguments] ${timeout} ${member_index_list}=${EMPTY}
160 [Documentation] Configure a different timeout for each Karaf console.
161 ${index_list} = ClusterManagement.List_Indices_Or_All given_list=${member_index_list}
162 ${current_connection_object} = SSHLibrary.Get_Connection
163 : FOR ${member_index} IN @{index_list} # usually: 1, 2, 3
164 \ ${karaf_connection_index} = Collections.Get_From_Dictionary ${connection_index_dict} ${member_index}
165 \ SSHLibrary.Switch_Connection ${karaf_connection_index}
166 \ SSHLibrary.Set_Client_Configuration timeout=${timeout}
167 [Teardown] SSHKeywords.Restore_Current_Ssh_Connection_From_Index ${current_connection_object.index}
169 Execute_Controller_Karaf_Command_On_Background
170 [Arguments] ${command} ${member_index}=${1}
171 [Documentation] Send command to karaf without affecting current SSH connection. Read, log and return response.
172 ${karaf_connection_index} = Collections.Get_From_Dictionary ${connection_index_dict} ${member_index}
173 ${current_connection_index} = SSHLibrary.Switch_Connection ${karaf_connection_index}
174 ${status_write} ${message_write} = BuiltIn.Run_Keyword_And_Ignore_Error SSHLibrary.Write ${command}
175 ${status_wait} ${message_wait} = BuiltIn.Run_Keyword_And_Ignore_Error SSHLibrary.Read_Until_Regexp ${KARAF_PROMPT}
176 BuiltIn.Run Keyword If '${status_write}' != 'PASS' BuiltIn.Fail Failed to send the command: ${command}
177 BuiltIn.Log ${message_wait}
178 BuiltIn.Run_Keyword_If '${status_wait}' != 'PASS' BuiltIn.Fail Failed to see prompt after sending the command: ${command}
179 [Teardown] SSHKeywords.Restore_Current_Ssh_Connection_From_Index ${current_connection_index}
180 [Return] ${message_wait}
182 Execute_Controller_Karaf_Command_With_Retry_On_Background
183 [Arguments] ${command} ${member_index}=${1}
184 [Documentation] Attemp to send command to karaf for ${member_index}, if fail then open connection and try again.
185 ${status} ${message} = BuiltIn.Run_Keyword_And_Ignore_Error Execute_Controller_Karaf_Command_On_Background ${command} ${member_index}
186 BuiltIn.Return_From_Keyword_If '${status}' == 'PASS' ${message}
187 # TODO: Verify this does not leak connections indices.
188 Open_Controller_Karaf_Console_On_Background ${member_index}
189 ${message} = Execute_Controller_Karaf_Command_On_Background ${command} ${member_index}
192 Log_Message_To_Controller_Karaf
193 [Arguments] ${message} ${member_index_list}=${EMPTY} ${tolerate_failure}=True
194 [Documentation] Make sure this resource is initialized. Send a message into the controller's karaf log file on every node listed (or all).
195 ... By default, failure while processing a node is silently ignored, unless ${tolerate_failure} is False.
196 ${index_list} = ClusterManagement.List_Indices_Or_All given_list=${member_index_list}
197 : FOR ${index} IN @{index_list} # usually: 1, 2, 3.
198 \ ${status} ${output} = BuiltIn.Run_Keyword_And_Ignore_Error Execute_Controller_Karaf_Command_With_Retry_On_Background log:log "ROBOT MESSAGE: ${message}" member_index=${index}
199 \ BuiltIn.Run_Keyword_Unless ${tolerate_failure} or "${status}" == "PASS" BuiltIn.Fail ${output}
201 Log_Test_Suite_Start_To_Controller_Karaf
202 [Arguments] ${member_index_list}=${EMPTY}
203 [Documentation] Log suite name to karaf log, useful in suite setup.
204 Log_Message_To_Controller_Karaf Starting suite ${SUITE_SOURCE} ${member_index_list}
206 Log_Testcase_Start_To_Controller_Karaf
207 [Arguments] ${member_index_list}=${EMPTY}
208 [Documentation] Log test case name to karaf log, useful in test case setup.
209 Log_Message_To_Controller_Karaf Starting test ${SUITE_NAME}.${TEST_NAME} ${member_index_list}
211 Set_Bgpcep_Log_Levels
212 [Arguments] ${bgpcep_level}=${DEFAULT_BGPCEP_LOG_LEVEL} ${protocol_level}=${DEFAULT_PROTOCOL_LOG_LEVEL} ${member_index_list}=${EMPTY}
213 [Documentation] Assuming OCKCOB was used, set logging level on bgpcep and protocol loggers without affecting current SSH session.
214 # FIXME: Move to appropriate Resource
215 ${index_list} = ClusterManagement.List_Indices_Or_All given_list=${member_index_list}
216 : FOR ${index} IN @{index_list} # usually: 1, 2, 3.
217 \ Execute_Controller_Karaf_Command_On_Background log:set ${bgpcep_level} org.opendaylight.bgpcep member_index=${index}
218 \ Execute_Controller_Karaf_Command_On_Background log:set ${protocol_level} org.opendaylight.protocol member_index=${index}
220 Get and Verify Exceptions
222 [Documentation] Get a list of exceptions from the given lines from a karaf log and then verify them against a
223 ... an exception whitelist. Verify Exceptions is a python function that will return the list of unmatched
224 ... exceptions in exlist and return the matched exceptions in matchlist. Both lists will be logged to aid
225 ... with troubleshooting the exceptions.
226 ${exlist} ${matchlist} = Verify Exceptions ${lines}
227 Collections.Log List ${exlist}
228 Collections.Log List ${matchlist}
231 Get Karaf Log Lines From Test Start
232 [Arguments] ${ip} ${test_name} ${cmd} ${user}=${ODL_SYSTEM_USER} ${password}=${ODL_SYSTEM_PASSWORD} ${prompt}=${ODL_SYSTEM_PROMPT}
233 ... ${log_file}=${KARAF_LOG}
234 [Documentation] Scrapes all log messages that match regexp ${type} which fall after a point given by a log message that
235 ... contains ${test_name}. This is useful if your test cases are marking karaf.log with a message indicating when
236 ... that test case has started; such that you can easily pull out any extra log messsages to parse/log/etc in the
237 ... test logic itself. For example, you can grab all ERRORS that occur during your test case.
238 ${output} = Run Command On Controller ${ip} ${cmd} ${user} ${password} ${prompt}
239 @{log_lines} = Split String ${output} ${\n}
240 [Return] ${log_lines}
242 Fail If Exceptions Found During Test
243 [Arguments] ${test_name} ${log_file}=${KARAF_LOG}
244 [Documentation] Create a failure if an Exception is found in the karaf.log that has not been whitelisted.
245 ... Will work for single controller jobs as well as 3node cluster jobs
246 : FOR ${i} IN RANGE 1 ${NUM_ODL_SYSTEM} + 1
247 \ ${cmd} = Set Variable sed '1,/ROBOT MESSAGE: Starting test ${test_name}/d' ${log_file}
248 \ ${output} = Get Karaf Log Lines From Test Start ${ODL_SYSTEM_${i}_IP} ${test_name} ${cmd}
249 \ ${exlist} = Get and Verify Exceptions ${output}
250 \ ${listlength} = BuiltIn.Get Length ${exlist}
251 \ BuiltIn.Run Keyword If ${listlength} != 0 BuiltIn.Fail New exceptions found: ${listlength}
253 Get Karaf Log Type From Test Start
254 [Arguments] ${ip} ${test_name} ${type} ${user}=${ODL_SYSTEM_USER} ${password}=${ODL_SYSTEM_PASSWORD} ${prompt}=${ODL_SYSTEM_PROMPT}
255 ... ${log_file}=${KARAF_LOG}
256 [Documentation] Scrapes all log messages that match regexp ${type} which fall after a point given by a log message that
257 ... contains ${test_name}. This is useful if your test cases are marking karaf.log with a message indicating when
258 ... that test case has started; such that you can easily pull out any extra log messsages to parse/log/etc in the
259 ... test logic itself. For example, you can grab all ERRORS that occur during your test case.
260 ${cmd} Set Variable sed '1,/ROBOT MESSAGE: Starting test ${test_name}/d' ${log_file} | grep '${type}'
261 ${output} Run Command On Controller ${ip} ${cmd} ${user} ${password} ${prompt}
264 Get Karaf Log Types From Test Start
265 [Arguments] ${ip} ${test_name} ${types} ${user}=${ODL_SYSTEM_USER} ${password}=${ODL_SYSTEM_PASSWORD} ${prompt}=${ODL_SYSTEM_PROMPT}
266 ... ${log_file}=${KARAF_LOG}
267 [Documentation] A wrapper keyword for "Get Karaf Log Type From Test Start" so that we can parse for multiple types
268 ... of log messages. For example, we can grab all messages of type WARN and ERROR
269 : FOR ${type} IN @{types}
270 \ Get Karaf Log Type From Test Start ${ip} ${test_name} ${type} ${user} ${password}
271 \ ... ${prompt} ${log_file}
273 Get Karaf Log Events From Test Start
274 [Arguments] ${test_name} ${user}=${ODL_SYSTEM_USER} ${password}=${ODL_SYSTEM_PASSWORD} ${prompt}=${ODL_SYSTEM_PROMPT}
275 [Documentation] Wrapper for the wrapper "Get Karaf Log Types From Test Start" so that we can easily loop over
276 ... any number of controllers to analyze karaf.log for ERROR, WARN and Exception log messages
277 ${log_types} = Create List ERROR WARN Exception
278 : FOR ${i} IN RANGE 1 ${NUM_ODL_SYSTEM} + 1
279 \ Get Karaf Log Types From Test Start ${ODL_SYSTEM_${i}_IP} ${test_name} ${log_types}
281 Fail If Exceptions Found During Test Deprecated
282 [Arguments] ${test_name} ${exceptions_white_list}=${EMPTY}
283 [Documentation] Create a failure if an Exception is found in the karaf.log. Will work for single controller jobs
284 ... as well as 3node cluster jobs
285 : FOR ${i} IN RANGE 1 ${NUM_ODL_SYSTEM} + 1
286 \ Verify Exception Logging In Controller ${ODL_SYSTEM_${i}_IP} ${test_name} ${exceptions_white_list}
288 Verify Exception Logging In Controller
289 [Arguments] ${controller_ip} ${test_name} ${exceptions_white_list}
290 [Documentation] Local keyword to make it easier to loop through N controllers to pull Exceptions from the
291 ... karaf.log file and validate with "Check Against White List"
292 ${exceptions}= Get Karaf Log Type From Test Start ${controller_ip} ${test_name} Exception
293 @{log_lines}= Split String ${exceptions} ${\n}
294 ${num_log_entries} Get Length ${log_lines}
295 Return From Keyword If ${num_log_entries} == ${0} No Exceptions found.
296 : FOR ${log_message} IN @{log_lines}
297 \ Check Against White List ${log_message} ${exceptions_white_list}
299 Check Against White List
300 [Arguments] ${exception_line} ${exceptions_white_list}
301 [Documentation] As soon as the ${exceptions_line} is found in one of the elements of ${exceptions_white_list}
302 ... this keyword will exit and give a Pass to the caller. If there is no match, this keyword will end up
303 ... marking a failure. In the case that no exceptions are found, the caller could end up passing a single
304 ... empty line as that is what is returned when a grep on karaf.log has no match, so we can safely return
305 ... in that case as well.
306 Return From Keyword If "${exception_line}" == ""
307 : FOR ${exception} IN @{exceptions_white_list}
308 \ Return From Keyword If "${exception}" in "${exception_line}" Exceptions found, but whitelisted: ${\n}${exception_line}${\n}
309 Fail Exceptions Found: ${\n}${exception_line}${\n}
312 [Arguments] ${message} ${timeout}=60 ${member_index}=${1}
313 [Documentation] Read karaf logs until message appear
314 # TODO: refactor this keyword to use the new workflow to account for multiple controllers. Initial work was done
315 # in this patch https://git.opendaylight.org/gerrit/#/c/45596/
316 # however, the consumers of this keyword were breaking after that change. Initial theory is that a previous
317 # keyword used before this "Wait For Karaf Log" keyword was closing the karaf console connection, so the
318 # "Flexible SSH Login" keyword from the patch above (45596) was failing.
319 BuiltIn.Log Waiting for '${message}' in karaf log
320 SSHLibrary.Open_Connection ${ODL_SYSTEM_IP} port=${KARAF_SHELL_PORT} prompt=${KARAF_PROMPT_LOGIN} timeout=${timeout}
321 SSHLibrary.Login ${KARAF_USER} ${KARAF_PASSWORD} loglevel=${loglevel}
322 SSHLibrary.Write log:tail
323 SSHLibrary.Read_Until ${message}
324 SSHLibrary.Close_Connection
327 [Arguments] ${bundle_id}
328 [Documentation] Restarts bundle passed as argument. Note this operation is only for testing and not production environments
329 # TODO: prepare this for cluster environment and multiple controllers
330 Execute_Controller_Karaf_Command_With_Retry_On_Background bundle:restart -f $(bundle:id '${bundle_id}')
333 [Documentation] Restarts Karaf and polls log to detect when Karaf is up and running again
334 # TODO: prepare this for cluster environment and multiple controllers
335 Execute_Controller_Karaf_Command_With_Retry_On_Background log:clear
336 Execute_Controller_Karaf_Command_With_Retry_On_Background shutdown -r -f
337 BuiltIn.Run_Keyword_And_Return_Status BuiltIn.Wait_Until_Keyword_Succeeds 240s 60s Wait_For_Karaf_Log Karaf started in
340 [Documentation] Restarts jetty bundle (to reload certificates or key/truststore information)
341 Execute_Controller_Karaf_Command_With_Retry_On_Background log:clear
342 Restart_Bundle OPS4J Pax Web - Jetty
343 Wait_For_Karaf_Log Instantiated the Application class org.opendaylight.restconf.RestconfApplication
344 Wait_For_Karaf_Log Instantiated the Application class org.opendaylight.netconf.sal.rest.impl.RestconfApplication
345 Wait_For_Karaf_Log Instantiated the Application class org.opendaylight.aaa.idm.IdmLightApplication