xref: /openbmc/openbmc-test-automation/lib/utils.robot (revision aca557110becf3f4d45391b6f70d0f52f1046f4e)
1*** Settings ***
2Resource                ../lib/resource.txt
3Resource                ../lib/rest_client.robot
4Resource                ../lib/connection_client.robot
5Library                 DateTime
6Library                 Process
7Library                 OperatingSystem
8Library                 gen_print.py
9Library                 gen_robot_print.py
10
11*** Variables ***
12${SYSTEM_SHUTDOWN_TIME}       ${5}
13${dbuscmdBase}
14...  dbus-send --system --print-reply --dest=${OPENBMC_BASE_DBUS}.settings.Host
15${dbuscmdGet}
16...  ${SETTINGS_URI}host0  org.freedesktop.DBus.Properties.Get
17# Enable when ready with openbmc/openbmc-test-automation#203
18#${dbuscmdString}=  string:"xyz.openbmc_project.settings.Host" string:
19${dbuscmdString}=   string:"org.openbmc.settings.Host" string:
20
21# Assign default value to QUIET for programs which may not define it.
22${QUIET}  ${0}
23${bmc_mem_free_cmd}=   free | tr -s ' ' | sed '/^Mem/!d' | cut -d" " -f4
24${bmc_mem_total_cmd}=   free | tr -s ' ' | sed '/^Mem/!d' | cut -d" " -f2
25${bmc_cpu_usage_cmd}=   top -n 1  | grep CPU: | cut -c 7-9
26${HOST_SETTING}    ${SETTINGS_URI}host0
27# /dev/mtdblock5 filesystem  should be 100% full always
28${bmc_file_system_usage_cmd}=
29...  df -h | grep -v /dev/mtdblock5 | cut -c 52-54 | grep 100 | wc -l
30
31*** Keywords ***
32
33Wait For Host To Ping
34    [Arguments]  ${host}  ${timeout}=${OPENBMC_REBOOT_TIMEOUT}min
35    ...          ${interval}=5 sec
36
37    # host      The DNS name or IP of the host to ping.
38    # timeout   The amount of time after which attempts to ping cease.
39    # interval  The amount of time in between attempts to ping.
40
41    Wait Until Keyword Succeeds  ${timeout}  ${interval}  Ping Host  ${host}
42
43Ping Host
44    [Arguments]     ${host}
45    Should Not Be Empty    ${host}   msg=No host provided
46    ${RC}   ${output}=     Run and return RC and Output    ping -c 4 ${host}
47    Log     RC: ${RC}\nOutput:\n${output}
48    Should be equal     ${RC}   ${0}
49
50Get Boot Progress
51    [Arguments]  ${quiet}=${QUIET}
52
53    ${state}=  Read Attribute  ${OPENBMC_BASE_URI}sensors/host/BootProgress
54    ...  value  quiet=${quiet}
55    [Return]  ${state}
56
57Is Power On
58    ${state}=  Get Power State
59    Should be equal  ${state}  ${1}
60
61Is Power Off
62    ${state}=  Get Power State
63    Should be equal  ${state}  ${0}
64
65Initiate Power On
66    [Documentation]  Initiates the power on and waits until the Is Power On
67    ...  keyword returns that the power state has switched to on.
68    [Arguments]  ${wait}=${1}
69
70    @{arglist}=   Create List
71    ${args}=     Create Dictionary    data=@{arglist}
72    ${resp}=  Call Method  ${OPENBMC_BASE_URI}control/chassis0/  powerOn
73    ...  data=${args}
74    should be equal as strings      ${resp.status_code}     ${HTTP_OK}
75
76    # Does caller want to wait for power on status?
77    Run Keyword If  '${wait}' == '${0}'  Return From Keyword
78    Wait Until Keyword Succeeds  3 min  10 sec  Is Power On
79
80Initiate Power Off
81    [Documentation]  Initiates the power off and waits until the Is Power Off
82    ...  keyword returns that the power state has switched to off.
83    @{arglist}=   Create List
84    ${args}=     Create Dictionary    data=@{arglist}
85    ${resp}=  Call Method  ${OPENBMC_BASE_URI}control/chassis0/  powerOff
86    ...  data=${args}
87    should be equal as strings      ${resp.status_code}     ${HTTP_OK}
88    Wait Until Keyword Succeeds  1 min  10 sec  Is Power Off
89
90Trigger Warm Reset
91    log to console    "Triggering warm reset"
92    ${data}=   create dictionary   data=@{EMPTY}
93    ${resp}=  openbmc post request
94    ...  ${OPENBMC_BASE_URI}control/bmc0/action/warmReset  data=${data}
95    Should Be Equal As Strings      ${resp.status_code}     ${HTTP_OK}
96    ${session_active}=   Check If warmReset is Initiated
97    Run Keyword If   '${session_active}' == '${True}'
98    ...    Fail   msg=warm reset didn't occur
99
100    Sleep   ${SYSTEM_SHUTDOWN_TIME}min
101    Wait For Host To Ping   ${OPENBMC_HOST}
102
103Check OS
104    [Documentation]  Attempts to ping the host OS and then checks that the host
105    ...              OS is up by running an SSH command.
106
107    [Arguments]  ${os_host}=${OS_HOST}  ${os_username}=${OS_USERNAME}
108    ...          ${os_password}=${OS_PASSWORD}  ${quiet}=${QUIET}
109    ...          ${print_string}=${EMPTY}
110    [Teardown]  Close Connection
111
112    # os_host           The DNS name/IP of the OS host associated with our BMC.
113    # os_username       The username to be used to sign on to the OS host.
114    # os_password       The password to be used to sign on to the OS host.
115    # quiet             Indicates whether this keyword should write to console.
116    # print_string      A string to be printed before checking the OS.
117
118    rprint  ${print_string}
119
120    # Attempt to ping the OS. Store the return code to check later.
121    ${ping_rc}=  Run Keyword and Return Status  Ping Host  ${os_host}
122
123    Open connection  ${os_host}
124
125    ${status}  ${msg}=  Run Keyword And Ignore Error  Login  ${os_username}
126    ...  ${os_password}
127    ${err_msg1}=  Sprint Error  ${msg}
128    ${err_msg}=  Catenate  SEPARATOR=  \n  ${err_msg1}
129    Run Keyword If  '${status}' == 'FAIL'  Fail  msg=${err_msg}
130    ${output}  ${stderr}  ${rc}=  Execute Command  uptime  return_stderr=True
131    ...        return_rc=True
132
133    ${temp_msg}=  Catenate  Could not execute a command on the operating
134    ...  system.\n
135    ${err_msg1}=  Sprint Error  ${temp_msg}
136    ${err_msg}=  Catenate  SEPARATOR=  \n  ${err_msg1}
137
138    # If the return code returned by "Execute Command" is non-zero, this
139    # keyword will fail.
140    Should Be Equal  ${rc}  ${0}  msg=${err_msg}
141    # We will likewise fail if there is any stderr data.
142    Should Be Empty  ${stderr}
143
144    ${temp_msg}=  Set Variable  Could not ping the operating system.\n
145    ${err_msg1}=  Sprint Error  ${temp_msg}
146    ${err_msg}=  Catenate  SEPARATOR=  \n  ${err_msg1}
147    # We will likewise fail if the OS did not ping, as we could SSH but not
148    # ping
149    Should Be Equal As Strings  ${ping_rc}  ${TRUE}  msg=${err_msg}
150
151Wait for OS
152    [Documentation]  Waits for the host OS to come up via calls to "Check OS".
153    [Arguments]  ${os_host}=${OS_HOST}  ${os_username}=${OS_USERNAME}
154    ...          ${os_password}=${OS_PASSWORD}  ${timeout}=${OS_WAIT_TIMEOUT}
155    ...          ${quiet}=${0}
156    [Teardown]  rprintn
157
158    # os_host           The DNS name or IP of the OS host associated with our
159    #                   BMC.
160    # os_username       The username to be used to sign on to the OS host.
161    # os_password       The password to be used to sign on to the OS host.
162    # timeout           The timeout in seconds indicating how long you're
163    #                   willing to wait for the OS to respond.
164    # quiet             Indicates whether this keyword should write to console.
165
166    # The interval to be used between calls to "Check OS".
167    ${interval}=  Set Variable  5
168
169    ${message}=  Catenate  Checking every ${interval} seconds for up to
170    ...  ${timeout} seconds for the operating system to communicate.
171    rqprint_timen  ${message}
172
173    Wait Until Keyword Succeeds  ${timeout} sec  ${interval}  Check OS
174    ...                          ${os_host}  ${os_username}  ${os_password}
175    ...                          print_string=\#
176
177    rqprintn
178
179    rqprint_timen  The operating system is now communicating.
180
181Get BMC State
182    [Documentation]  Returns the state of the BMC as a string. (i.e: BMC_READY)
183    [Arguments]  ${quiet}=${QUIET}
184
185    @{arglist}=  Create List
186    ${args}=  Create Dictionary  data=@{arglist}
187    ${resp}=  Call Method  ${OPENBMC_BASE_URI}managers/System/  getSystemState
188    ...        data=${args}  quiet=${quiet}
189    Should be equal as strings  ${resp.status_code}  ${HTTP_OK}
190    ${content}=  to json  ${resp.content}
191    [Return]  ${content["data"]}
192
193Get Power State
194    [Documentation]  Returns the power state as an integer. Either 0 or 1.
195    [Arguments]  ${quiet}=${QUIET}
196
197    @{arglist}=  Create List
198    ${args}=  Create Dictionary  data=@{arglist}
199
200    ${resp}=  Call Method  ${OPENBMC_BASE_URI}control/chassis0/  getPowerState
201    ...        data=${args}  quiet=${quiet}
202    Should be equal as strings  ${resp.status_code}  ${HTTP_OK}
203    ${content}=  to json  ${resp.content}
204    [Return]  ${content["data"]}
205
206Clear BMC Record Log
207    [Documentation]  Clears all the event logs on the BMC. This would be
208    ...              equivalent to ipmitool sel clear.
209    @{arglist}=   Create List
210    ${args}=     Create Dictionary    data=@{arglist}
211    ${resp}=  Call Method
212    ...  ${OPENBMC_BASE_URI}records/events/  clear  data=${args}
213    should be equal as strings      ${resp.status_code}     ${HTTP_OK}
214
215Copy PNOR to BMC
216    Import Library      SCPLibrary      WITH NAME       scp
217    Open Connection for SCP
218    Log    Copying ${PNOR_IMAGE_PATH} to /tmp
219    scp.Put File    ${PNOR_IMAGE_PATH}   /tmp
220
221Flash PNOR
222    [Documentation]    Calls flash bios update method to flash PNOR image
223    [Arguments]    ${pnor_image}
224    @{arglist}=   Create List    ${pnor_image}
225    ${args}=     Create Dictionary    data=@{arglist}
226    ${resp}=  Call Method  ${OPENBMC_BASE_URI}control/flash/bios/  update
227    ...  data=${args}
228    should be equal as strings      ${resp.status_code}     ${HTTP_OK}
229    Wait Until Keyword Succeeds    2 min   10 sec    Is PNOR Flashing
230
231Get Flash BIOS Status
232    [Documentation]  Returns the status of the flash BIOS API as a string. For
233    ...              example 'Flashing', 'Flash Done', etc
234    ${data}=      Read Properties     ${OPENBMC_BASE_URI}control/flash/bios
235    [Return]    ${data['status']}
236
237Is PNOR Flashing
238    [Documentation]  Get BIOS 'Flashing' status. This indicates that PNOR
239    ...              flashing has started.
240    ${status}=    Get Flash BIOS Status
241    should be equal as strings     ${status}     Flashing
242
243Is PNOR Flash Done
244    [Documentation]  Get BIOS 'Flash Done' status.  This indicates that the
245    ...              PNOR flashing has completed.
246    ${status}=    Get Flash BIOS Status
247    should be equal as strings     ${status}     Flash Done
248
249Is System State Host Booted
250    [Documentation]  Checks whether system state is HOST_BOOTED.
251    ${state}=    Get BMC State
252    should be equal as strings     ${state}     HOST_BOOTED
253
254Verify Ping and REST Authentication
255    ${l_ping}=   Run Keyword And Return Status
256    ...    Ping Host  ${OPENBMC_HOST}
257    Run Keyword If  '${l_ping}' == '${False}'
258    ...    Fail   msg=Ping Failed
259
260    ${l_rest}=   Run Keyword And Return Status
261    ...    Initialize OpenBMC
262    Run Keyword If  '${l_rest}' == '${False}'
263    ...    Fail   msg=REST Authentication Failed
264
265    # Just to make sure the SSH is working for SCP
266    Open Connection And Log In
267    ${system}   ${stderr}=    Execute Command   hostname   return_stderr=True
268    Should Be Empty     ${stderr}
269
270Check If BMC is Up
271    [Documentation]  Wait for Host to be online. Checks every X seconds
272    ...              interval for Y minutes and fails if timed out.
273    ...              Default MAX timedout is 10 min, interval 10 seconds.
274    [Arguments]      ${max_timeout}=${OPENBMC_REBOOT_TIMEOUT} min
275    ...              ${interval}=10 sec
276
277    Wait Until Keyword Succeeds
278    ...   ${max_timeout}  ${interval}   Verify Ping and REST Authentication
279
280
281Check If warmReset is Initiated
282    [Documentation]  Ping would be still alive, so try SSH to connect
283    ...              if fails the ports are down indicating reboot
284    ...              is in progress
285
286    # Warm reset adds 3 seconds delay before forcing reboot
287    # To minimize race conditions, we wait for 7 seconds
288    Sleep  7s
289    ${alive}=   Run Keyword and Return Status
290    ...    Open Connection And Log In
291    Return From Keyword If   '${alive}' == '${False}'    ${False}
292    [Return]    ${True}
293
294Flush REST Sessions
295    [Documentation]   Removes all the active session objects
296    Delete All Sessions
297
298Initialize DBUS cmd
299    [Documentation]  Initialize dbus string with property string to extract
300    [Arguments]   ${boot_property}
301    ${cmd}=     Catenate  ${dbuscmdBase} ${dbuscmdGet} ${dbuscmdString}
302    ${cmd}=     Catenate  ${cmd}${boot_property}
303    Set Global Variable   ${dbuscmd}     ${cmd}
304
305
306Stop OBMC Console Client
307    [Documentation]   Stop any running obmc_console_client
308    ...               writing to file_path.
309    [Arguments]   ${file_path}=/tmp/obmc-console.log
310
311    ${cmd_buf}=  Catenate  SEPARATOR=${SPACE}
312    ...  ps ax | grep obmc-console-client | grep ${file_path} | grep -v grep
313    ...  | awk '{print $1}'
314
315    ${pid}=
316    ...  Execute Command  ${cmd_buf}
317
318    Run Keyword If  '${pid}' != '${EMPTY}'
319    ...  Execute Command  kill -s KILL ${pid}
320    ...  ELSE  Log  "No obmc-console-client process running"
321
322
323Start SOL Console Logging
324    [Documentation]   Start a new obmc_console_client process and direct
325    ...               output to a file.
326    [Arguments]   ${file_path}=/tmp/obmc-console.log
327
328    Open Connection And Log In
329
330    Stop OBMC Console Client  ${file_path}
331
332    Start Command
333    ...  obmc-console-client > ${file_path}
334
335
336Stop SOL Console Logging
337    [Documentation]  Stop obmc_console_client process, if any, and
338    ...              return the console output as a string.
339    [Arguments]  ${file_path}=/tmp/obmc-console.log  ${targ_file_path}=${EMPTY}
340
341    # Description of arguments:
342    # file_path       The path on the obmc system where SOL output may be
343    #                 found.
344    # targ_file_path  If specified, the file path to which SOL data should be
345    #                 written.
346
347    Open Connection And Log In
348
349    Stop OBMC Console Client  ${file_path}
350
351    ${cmd_buf}=  Set Variable  cat ${file_path}
352
353    ${console}  ${stderr}=
354    ...  Execute Command
355    ...  if [ -f ${file_path} ] ; then cat ${file_path} ; fi
356    ...  return_stderr=True
357    Should Be Empty  ${stderr}
358
359    Run Keyword If  '${targ_file_path}' != '${EMPTY}'
360    ...  Append To File  ${targ_file_path}  ${console}
361
362    [Return]  ${console}
363
364Get Time Stamp
365    [Documentation]     Get the current time stamp data
366    ${cur_time}=    Get Current Date   result_format=%Y%m%d%H%M%S%f
367    [Return]   ${cur_time}
368
369
370Verify BMC State
371    [Documentation]   Get the BMC state and verify if the current
372    ...               BMC state is as expected.
373    [Arguments]       ${expected}
374
375    ${current}=  Get BMC State
376    Should Contain  ${expected}   ${current}
377
378Start Journal Log
379    [Documentation]   Start capturing journal log to a file in /tmp using
380    ...               journalctl command. By default journal log is collected
381    ...               at /tmp/journal_log else user input location.
382    ...               The File is appended with datetime.
383    [Arguments]       ${file_path}=/tmp/journal_log
384
385    Open Connection And Log In
386
387    ${cur_time}=    Get Time Stamp
388    Set Global Variable   ${LOG_TIME}   ${cur_time}
389    Start Command
390    ...  journalctl -f > ${file_path}-${LOG_TIME}
391    Log    Journal Log Started: ${file_path}-${LOG_TIME}
392
393Stop Journal Log
394    [Documentation]   Stop journalctl process if its running.
395    ...               By default return log from /tmp/journal_log else
396    ...               user input location.
397    [Arguments]       ${file_path}=/tmp/journal_log
398
399    Open Connection And Log In
400
401    ${rc}=
402    ...  Execute Command
403    ...  ps ax | grep journalctl | grep -v grep
404    ...  return_stdout=False  return_rc=True
405
406    Return From Keyword If   '${rc}' == '${1}'
407    ...   No journal log process running
408
409    ${output}  ${stderr}=
410    ...  Execute Command   killall journalctl
411    ...  return_stderr=True
412    Should Be Empty     ${stderr}
413
414    ${journal_log}  ${stderr}=
415    ...  Execute Command
416    ...  cat ${file_path}-${LOG_TIME}
417    ...  return_stderr=True
418    Should Be Empty     ${stderr}
419
420    Log    ${journal_log}
421
422    Execute Command    rm ${file_path}-${LOG_TIME}
423
424    [Return]    ${journal_log}
425
426Mac Address To Hex String
427    [Documentation]   Converts MAC address into hex format.
428    ...               Example
429    ...               Given the following MAC: 00:01:6C:80:02:78
430    ...               This keyword will return: 0x00 0x01 0x6C 0x80 0x02 0x78
431    ...               Description of arguments:
432    ...               i_macaddress  MAC address in the following format
433    ...               00:01:6C:80:02:78
434    [Arguments]    ${i_macaddress}
435
436    ${mac_hex}=  Catenate  0x${i_macaddress.replace(':', ' 0x')}
437    [Return]    ${mac_hex}
438
439IP Address To Hex String
440    [Documentation]   Converts IP address into hex format.
441    ...               Example:
442    ...               Given the following IP: 10.3.164.100
443    ...               This keyword will return: 0xa 0x3 0xa4 0xa0
444    ...               Description of arguments:
445    ...               i_ipaddress  IP address in the following format
446    ...               10.10.10.10
447    [Arguments]    ${i_ipaddress}
448
449    @{ip}=  Split String  ${i_ipaddress}    .
450    ${index}=  Set Variable  ${0}
451
452    :FOR    ${item}     IN      @{ip}
453    \   ${hex}=  Convert To Hex    ${item}    prefix=0x    lowercase=yes
454    \   Set List Value    ${ip}    ${index}    ${hex}
455    \   ${index}=  Set Variable    ${index + 1}
456    ${ip_hex}=  Catenate    @{ip}
457    [Return]    ${ip_hex}
458
459BMC CPU Performance Check
460   [Documentation]   Minimal 10% of proc should be free in this instance
461
462    ${bmc_cpu_usage_output}  ${stderr}=  Execute Command  ${bmc_cpu_usage_cmd}
463    ...                   return_stderr=True
464    Should be empty  ${stderr}
465    ${bmc_cpu_percentage}=  Fetch From Left  ${bmc_cpu_usage_output}  %
466    Should be true  ${bmc_cpu_percentage} < 90
467
468BMC Mem Performance Check
469    [Documentation]   Minimal 10% of memory should be free in this instance
470
471    ${bmc_mem_free_output}  ${stderr}=   Execute Command  ${bmc_mem_free_cmd}
472    ...                   return_stderr=True
473    Should be empty  ${stderr}
474
475    ${bmc_mem_total_output}  ${stderr}=   Execute Command  ${bmc_mem_total_cmd}
476    ...                   return_stderr=True
477    Should be empty  ${stderr}
478
479    ${bmc_mem_percentage}=   Evaluate  ${bmc_mem_free_output}*100
480    ${bmc_mem_percentage}=  Evaluate
481    ...   ${bmc_mem_percentage}/${bmc_mem_total_output}
482    Should be true  ${bmc_mem_percentage} > 10
483
484BMC File System Usage Check
485    [Documentation]   Check the file system space. None should be 100% full
486    ...   except /dev/mtdblock5
487    ${bmc_fs_usage_output}  ${stderr}=   Execute Command
488    ...   ${bmc_file_system_usage_cmd}  return_stderr=True
489    Should Be Empty  ${stderr}
490    Should Be True  ${bmc_fs_usage_output}==0
491
492Check BMC CPU Performance
493    [Documentation]   Minimal 10% of proc should be free in 3 sample
494    :FOR  ${var}  IN Range  1  4
495    \     BMC CPU Performance check
496
497Check BMC Mem Performance
498    [Documentation]   Minimal 10% of memory should be free
499
500    :FOR  ${var}  IN Range  1  4
501    \     BMC Mem Performance check
502
503Check BMC File System Performance
504    [Documentation]  Check for file system usage for 4 times
505
506    :FOR  ${var}  IN Range  1  4
507    \     BMC File System Usage check
508
509Get Endpoint Paths
510    [Documentation]   Returns all url paths ending with given endpoint
511    ...               Example:
512    ...               Given the following endpoint: cpu
513    ...               This keyword will return: list of all urls ending with
514    ...               cpu -
515    ...               /org/openbmc/inventory/system/chassis/motherboard/cpu0,
516    ...               /org/openbmc/inventory/system/chassis/motherboard/cpu1
517    ...               Description of arguments:
518    ...               path       URL path for enumeration
519    ...               endpoint   string for which url path ending
520    [Arguments]   ${path}   ${endpoint}
521
522    ${resp}=   Read Properties   ${path}/enumerate   timeout=30
523    log Dictionary   ${resp}
524
525    ${list}=   Get Dictionary Keys   ${resp}
526    ${resp}=   Get Matches   ${list}   regexp=^.*[0-9a-z_].${endpoint}[0-9]*$
527    [Return]   ${resp}
528
529
530Check Zombie Process
531    [Documentation]    Check if any defunct process exist or not on BMC
532    ${count}  ${stderr}  ${rc}=  Execute Command  ps -o stat | grep Z | wc -l
533    ...    return_stderr=True  return_rc=True
534    Should Be True    ${count}==0
535    Should Be Empty    ${stderr}
536
537Prune Journal Log
538    [Documentation]   Prune archived journal logs.
539    [Arguments]   ${vacuum_size}=1M
540
541    # This keyword can be used to prevent the journal
542    # log from filling up the /run filesystem.
543    # This command will retain only the latest logs
544    # of the user specified size.
545
546    Open Connection And Log In
547    ${output}  ${stderr}  ${rc}=
548    ...  Execute Command
549    ...  journalctl --vacuum-size=${vacuum_size}
550    ...  return_stderr=True  return_rc=True
551
552    Should Be Equal  ${rc}  ${0}  msg=${stderr}
553    Should Contain   ${stderr}  Vacuuming done
554
555Set BMC Power Policy
556    [Documentation]   Set the given BMC power policy.
557    [arguments]   ${policy}
558
559    ${valueDict}=     create dictionary  data=${policy}
560    Write Attribute    ${HOST_SETTING}    power_policy   data=${valueDict}
561    ${currentPolicy}=  Read Attribute     ${HOST_SETTING}   power_policy
562    Should Be Equal    ${currentPolicy}   ${policy}
563