1*** Settings ***
2
3Documentation    Module to test IPMI SEL functionality.
4Resource         ../lib/ipmi_client.robot
5Resource         ../lib/openbmc_ffdc.robot
6Resource         ../../../lib/logging_utils.robot
7
8Library          ../lib/ipmi_utils.py
9Library          ../../../lib/logging_utils.py
10
11Variables        ../data/ipmi_raw_cmd_table.py
12
13Test Setup       Test Setup Execution
14Test Teardown    FFDC On Test Case Fail
15
16Force Tags       IPMI_SEL
17
18*** Variables ***
19
20# Based on 13th byte of add SEL entry command as per IPMI spec
21# event_dir and event_type variable value needs to be given.
22${sel_no_entry_msg}  SEL has no entries
23${event_type}        Lower Non-critical going low
24${event_dir}         Asserted
25
26*** Test Cases ***
27
28Verify IPMI SEL Version
29    [Documentation]  Verify IPMI SEL's version info.
30    [Tags]  Verify_IPMI_SEL_Version
31    ${version_info}=  Get IPMI SEL Setting  Version
32    ${setting_status}=  Fetch From Left  ${version_info}  (
33    ${setting_status}=  Evaluate  $setting_status.replace(' ','')
34
35    Should Be True  ${setting_status} >= 1.5
36    Should Contain  ${version_info}  v2 compliant  case_insensitive=True
37
38
39Verify Empty SEL
40    [Documentation]  Verify IPMI sel clear command clears the SEL entry.
41    [Tags]  Verify_Empty_SEL
42
43    Redfish Power Off  stack_mode=skip
44
45    # Generate an error log and verify there is one at least.
46    Create Test PEL Log
47    ${resp}=  Run IPMI Standard Command  sel elist last 1
48    Log To Console  ${resp}
49
50    Should Contain Any  ${resp}  system hardware failure   Asserted
51    ...  msg=Add SEL Entry failed.
52
53    # Send SEL clear command and verify if it really clears up the SEL entry.
54    Run IPMI Standard Command  sel clear
55    Sleep  5s
56
57    ${resp}=  Run IPMI Standard Command  sel list
58    Should Contain  ${resp}  SEL has no entries  case_insensitive=True
59
60
61Verify Add SEL Entry
62    [Documentation]  Verify add SEL entry.
63    [Tags]  Verify_Add_SEL_Entry
64    [Teardown]  Run Keywords  FFDC On Test Case Fail  AND  Run IPMI Standard Command  sel clear
65
66    # The IPMI raw command to generate Temp sensor  error is no longer working.
67    # Our aim is to check if the SEL command is listed in IPMI or not.
68    # Original keyword "Create User Defined SEL" for reference
69    Create Test PEL Log
70
71    # Get last SEL entry.
72    ${resp}=  Run IPMI Standard Command  sel elist last 1
73    #  output:
74    #  1 | 11/17/2021 | 07:49:20 | System Event #0x01 | Undetermined system hardware failure | Asserted
75    Run Keywords  Should Contain  ${resp}  system hardware failure  AND
76    ...  Should Contain  ${resp}  Asserted  msg=Add SEL Entry failed.
77
78
79Verify Add SEL Entry For Any Random Sensor
80    [Documentation]  Create SEL entry and verify for any given random sensor.
81    [Tags]  Verify_Add_SEL_Entry_For_Any_Random_Sensor
82    [Teardown]  Run Keywords  FFDC On Test Case Fail  AND  Run IPMI Standard Command  sel clear
83
84    # Get any sensor available from sensor list.
85    ${sensor_name}=  Fetch One Threshold Sensor From Sensor List
86
87    # Get Sensor ID from SDR get "sensor".
88    ${sensor_data1}=  Fetch Sensor Details From SDR  ${sensor_name}  Sensor ID
89    ${sensor_number}=  Get Bytes From SDR Sensor  ${sensor_data1}
90
91    # Get Sensor Type from SDR get "sensor".
92    ${sensor_data2}=  Fetch Sensor Details From SDR  ${sensor_name}  Sensor Type (Threshold)
93    ${sensor_type_id}=  Get Bytes From SDR Sensor  ${sensor_data2}
94
95    # Add SEL Entry.
96    # ${sel_entry_id} is the Record ID for added record (LSB First).
97    ${sel_create_resp}=  Create SEL  ${sensor_type_id}  ${sensor_number}
98    ${sel_entry_id}=  Split String  ${sel_create_resp}
99
100    # Get last SEL entry.
101    ${resp}=  Run IPMI Standard Command  sel elist
102    Should Not Contain  ${resp}  ${sel_no_entry_msg}
103
104    # Output of the Sel elist.
105    # Below example is a continuous line statement.
106    #    N | MM/DD/YYYY | HH:MM:SS | Sensor_Type Sensor_Name |
107    #    Lower Non-critical going low  | Asserted | Reading 0.
108
109    ${get_sel_entry}=  Get Lines Containing String  ${resp}  ${sensor_name}
110    ${sel_entry}=  Get Lines Containing String  ${get_sel_entry}  ${event_type}
111    Should Contain  ${sel_entry}  ${event_dir}  msg=Add SEL Entry failed.
112
113    # Get SEL Entry IPMI Raw Command.
114    ${entry}=  Get SEL Entry Via IPMI  ${sel_entry_id[0]}  ${sel_entry_id[1]}
115
116    # Compare SEL Record ID.
117    ${sel_record_id}=  Set Variable  ${entry[2:4]}
118    Should Be Equal  ${sel_record_id}  ${sel_entry_id}
119
120    # Sensor type compare.
121    Should Be Equal  ${sensor_type_id}  ${entry[12]}
122
123    # Sensor number compare.
124    Should Be Equal  ${sensor_number}  ${entry[13]}
125
126
127Verify Reserve SEL
128    [Documentation]  Verify reserve SEL.
129    [Tags]  Verify_Reserve_SEL
130
131    ${resp}=  Run IPMI Command
132    ...  ${IPMI_RAW_CMD['SEL_entry']['Reserve'][0]}
133    ${reserve_id}=  Split String  ${resp}
134
135    # Execute clear SEL raw command with Reservation ID.
136    # Command will not execute unless the correct Reservation ID value is provided.
137    Run IPMI Command
138    ...  0x0a 0x47 0x${reserve_id[0]} 0x${reserve_id[1]} 0x43 0x4c 0x52 0xaa
139
140    # Check SEL list.
141    ${resp}=  Run IPMI Standard Command  sel list
142    Should Contain  ${resp}  SEL has no entries  case_insensitive=True
143
144
145Verify IPMI SEL Most Recent Addition Timestamp
146    [Documentation]  Verify most recent addition timestamp in SEL info.
147    [Tags]  Verify_IPMI_SEL_Most_Recent_Addition_Timestamp
148
149    # Get Most Recent Addition Timestamp from SEL Info.
150    ${addition_timestamp}=  Get Most Recent Addition Timestamp From SEL Info
151
152    IF  '${addition_timestamp}' != 'ffffffff'
153        # Convert to epoch timestamp.
154        ${epoch_addition}=  Convert To Integer  ${addition_timestamp}  16
155
156        # Get SEL List last 1 entry date and time and convert to epoch timestamp.
157        ${sel_epoch_time}=  Get SEL Elist Last Entry Date In Epoch
158
159        # Compare epoch of sel entry timestamp and last addition timestamp.
160        ${diff}=  Evaluate  int(${sel_epoch_time}) - int(${epoch_addition})
161        Should Be True  ${diff}<=600
162
163    ELSE
164        # Get any Sensor available from Sensor list
165        ${sensor_name}=  Fetch One Threshold Sensor From Sensor List
166
167        # Get Sensor ID from SDR Get "sensor" and Identify Sensor ID.
168        ${sensor_data1}=  Fetch Sensor Details From SDR  ${sensor_name}  Sensor ID
169        ${sensor_number}=  Get Bytes From SDR Sensor  ${sensor_data1}
170
171        # Get Sensor Type from SDR Get "sensor" and Identify Sensor Type.
172        ${sensor_data2}=  Fetch Sensor Details From SDR  ${sensor_name}  Sensor Type (Threshold)
173        ${sensor_type_id}=  Get Bytes From SDR Sensor  ${sensor_data2}
174
175        # Add SEL Entry.
176        ${sel_create_resp}=  Create SEL  ${sensor_type_id}  ${sensor_number}
177
178        # Get SEL List last 1 entry date and time and convert to epoch timestamp.
179        ${sel_epoch_time}=  Get SEL Elist Last Entry Date In Epoch
180
181        # Get Most Recent Addition Timestamp from SEL Info.
182        ${addition}=  Get Most Recent Addition Timestamp From SEL Info
183        ${epoch_addition}=  Convert To Integer  ${addition}  16
184
185        # Compare epoch of sel entry timestamp and last addition timestamp.
186        ${diff}=  Evaluate  int(${epoch_addition}) - int(${sel_epoch_time})
187        Should Be True  ${diff}<=5
188    END
189
190
191Verify IPMI SEL Most Recent Erase Timestamp
192    [Documentation]  Verify Most Recent Erase Timestamp In SEL Info with current
193    ...              BMC epoch timestamp.
194    [Tags]  Verify_IPMI_SEL_Most_Recent_Erase_Timestamp
195
196    # Get BMC Current Time.
197    ${bmc_epoch_time}=  Get BMC Time In Epoch
198
199    # Get Most Recent Addition Timestamp from SEL Info.
200    ${addition_timestamp}=  Get Most Recent Addition Timestamp From SEL Info
201    Should Be Equal  ${addition_timestamp}  ffffffff
202
203    # Get Most Recent Erase Timestamp from SEL Info.
204    ${erase_timestamp}=  Get Most Recent Erase Timestamp From SEL Info
205    ${epoch_erase}=  Convert To Integer  ${erase_timestamp}  16
206
207    # Compare epoch of erase timestamp and current bmc timestamp.
208    ${diff}=  Evaluate  int(${epoch_erase}) - int(${bmc_epoch_time})
209    Should Be True  ${diff}<=5
210
211
212Verify Clear SEL With Invalid Reservation ID
213    [Documentation]  Verify clear SEL After generating another reserve ID.
214    [Tags]  Verify_Clear_SEL_With_Invalid_Reservation_ID
215
216    # Reserve Sel command - 1.
217    ${resp}=  Run IPMI Command
218    ...  ${IPMI_RAW_CMD['SEL_entry']['Reserve'][0]}
219    ${reserve_id}=  Split String  ${resp}
220
221    # Reserve Sel command - 2.
222    ${resp}=  Run IPMI Command
223    ...  ${IPMI_RAW_CMD['SEL_entry']['Reserve'][0]}
224
225    ${cmd}=  Catenate  ${IPMI_RAW_CMD['SEL_entry']['Clear_SEL'][0]} 0x${reserve_id[0]}
226    ...  0x${reserve_id[1]} ${IPMI_RAW_CMD['SEL_entry']['Clear_SEL'][1]}
227
228    # Clear SEL command.
229    ${clear_resp}=  Run Keyword and Expect Error  *${IPMI_RAW_CMD['SEL_entry']['Clear_SEL'][4]}*
230    ...  Run IPMI Command  ${cmd}
231    Should Contain  ${clear_resp}  ${IPMI_RAW_CMD['SEL_entry']['Clear_SEL'][5]}
232
233
234Verify Reservation ID Erasure Status
235    [Documentation]  Verify Erasure status by clearing SEL with Reserve ID and verify the response byte,
236    ...  whether erasure status is updated in clear sel command response data using new Reserve ID.
237    [Tags]  Verify_Reservation_ID_Erasure_Status
238
239    # Generate Reserve ID 1.
240    ${resp}=  Run IPMI Command
241    ...  ${IPMI_RAW_CMD['SEL_entry']['Reserve'][0]}
242    ${reserve_id}=  Split String  ${resp}
243
244    ${cmd1}=  Catenate  ${IPMI_RAW_CMD['SEL_entry']['Clear_SEL'][0]} 0x${reserve_id[0]}
245    ...  0x${reserve_id[1]} ${IPMI_RAW_CMD['SEL_entry']['Clear_SEL'][1]}
246
247    # Execute clear SEL raw command with Reservation ID.
248    # Command will not execute unless the correct Reservation ID value is provided.
249    Run IPMI Command  ${cmd1}
250
251    # Generate Reserver ID 2.
252    ${resp}=  Run IPMI Command
253    ...  ${IPMI_RAW_CMD['SEL_entry']['Reserve'][0]}
254    ${reserve_id}=  Split String  ${resp}
255
256    ${cmd2}=  Catenate  ${IPMI_RAW_CMD['SEL_entry']['Clear_SEL'][0]} 0x${reserve_id[0]}
257    ...  0x${reserve_id[1]} ${IPMI_RAW_CMD['SEL_entry']['Clear_SEL'][6]}
258
259    # Check the Erasure status of Clear SEL.
260    ${data}=  Run IPMI Command  ${cmd2}
261
262    # 00 - Erasure in Progress , 01 - Erasure Complete.
263    Should Contain Any  ${data}  00  01
264
265
266Verify Clear SEL After Cold Reset
267    [Documentation]  Verify Clear SEL for a reserve SEL ID after Cold Reset.
268    [Tags]  Verify_Clear_SEL_After_Cold_Reset
269
270    # Reserve Sel command.
271    ${resp}=  Run IPMI Command
272    ...  ${IPMI_RAW_CMD['SEL_entry']['Reserve'][0]}
273    ${reserve_id}=  Split String  ${resp}
274
275    # Run Cold Reset.
276    IPMI MC Reset Cold (off)
277
278    ${cmd}=  Catenate  ${IPMI_RAW_CMD['SEL_entry']['Clear_SEL'][0]} 0x${reserve_id[0]}
279    ...  0x${reserve_id[1]} ${IPMI_RAW_CMD['SEL_entry']['Clear_SEL'][1]}
280
281    # Clear SEL command.
282    ${clear_resp}=  Run Keyword and Expect Error  *${IPMI_RAW_CMD['SEL_entry']['Clear_SEL'][5]}*
283    ...  Run IPMI Command  ${cmd}
284
285    Should Contain  ${clear_resp}  ${IPMI_RAW_CMD['SEL_entry']['Clear_SEL'][4]}
286
287
288Delete Non Existing SEL Event Entry
289    [Documentation]  Delete non existing SEL event entry.
290    [Tags]  Delete_Non_Existing_SEL_Event_Entry
291
292    ${sel_delete}=  Run Keyword And Expect Error  *
293    ...  Run IPMI Standard Command  sel delete 100
294    Should Contain  ${sel_delete}  Unable to delete entry
295    ...  case_insensitive=True
296
297
298Delete Invalid SEL Event Entry
299    [Documentation]  Delete invalid SEL event entry.
300    [Tags]  Delete_Invalid_SEL_Event_Entry
301
302    ${sel_delete}=  Run Keyword And Expect Error  *
303    ...  Run IPMI Standard Command  sel delete abc
304    Should Contain  ${sel_delete}  Given SEL ID 'abc' is invalid
305    ...  case_insensitive=True
306
307
308Verify IPMI SEL Event Last Add Time
309    [Documentation]  Verify IPMI SEL's last added timestamp.
310    [Tags]  Verify_IPMI_SEL_Event_Last_Add_Time
311    [Setup]  Install Tarball For Error Creation
312
313    Create Test Error Log
314    ${sel_time}=  Run IPMI Standard Command  sel time get
315    ${sel_time}=  Convert Date  ${sel_time}
316    ...  date_format=%m/%d/%Y %H:%M:%S  exclude_millis=True
317
318    ${sel_last_add_time}=  Get IPMI SEL Setting  Last Add Time
319    ${sel_last_add_time}=  Convert Date  ${sel_last_add_time}
320    ...  date_format=%m/%d/%Y %H:%M:%S  exclude_millis=True
321
322    ${time_diff}=
323    ...  Subtract Date From Date  ${sel_last_add_time}  ${sel_time}
324
325    # Verify if the delay in current time check and last add SEL time
326    # is less or equals to 2 seconds.
327    Should Be True  ${time_diff} <= 2
328
329
330Verify IPMI SEL Event Entries
331    [Documentation]  Verify IPMI SEL's entries info.
332    [Tags]  Verify_IPMI_SEL_Event_Entries
333    [Setup]  Install Tarball For Error Creation
334
335    # Clear all SEL entries using IPMI command.
336    Run IPMI Standard Command  sel clear
337
338    # Added a delay for IPMI SEL to clear completely.
339    Sleep  5s
340
341    # Generate error logs of random count.
342    ${count}=  Evaluate  random.randint(1, 5)  modules=random
343    Repeat Keyword  ${count}  Create Test Error Log
344
345    ${sel_entries_count}=  Get IPMI SEL Setting  Entries
346
347    # After issuing the IPMI SEL clear command.
348    # There will be one informational SEL entry in the IPMI SEL.
349    # So comparing the IPMI SEL count with this additional single entry.
350    Should Be Equal As Strings  ${sel_entries_count}  ${count + 1}
351
352
353*** Keywords ***
354
355Create User Defined SEL
356    [Documentation]  Create a user defined tempearature sensor SEL.
357
358    # Create a SEL.
359    # Example:
360    # a | 02/14/2020 | 01:16:58 | Temperature #0x17 |  | Asserted
361    Run IPMI Command
362    ...  0x0a 0x44 0x00 0x00 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x04 0x01 ${sensor_number} 0x00 0xa0 0x04 0x07
363
364
365Get SEL Entry Via IPMI
366    [Documentation]  Get SEL Entry Via IPMI raw command.
367    [Arguments]  ${record1}  ${record2}
368
369    # Description of Argument(s):
370    # ${record1}    Record ID for added record, LS Byte
371    # ${record2}    Record ID for added record, MS Byte
372
373    # For example, when a first sel entry is added with IPMI raw command, the response will be "01 00".
374    # Here, ${record1} is 01, and ${record2} is 00.
375
376    ${cmd}=  Catenate  ${IPMI_RAW_CMD['SEL_entry']['Get_SEL_Entry'][0]} 0x${record1}
377    ...  0x${record2} ${IPMI_RAW_CMD['SEL_entry']['Get_SEL_Entry'][1]}
378
379    # Get SEL Entry Raw command.
380    ${resp}=  Run IPMI Command  ${cmd}
381    ${resp}=  Split String  ${resp}
382
383    [Return]  ${resp}
384
385
386Get Most Recent Addition Timestamp From SEL Info
387    [Documentation]  Get Most recent addition timestamp From SEL Info.
388
389    # Get SEL Info raw command.
390    ${sel_info}=  Get SEL Info Via IPMI
391
392    # Get Most Recent Addition timestamp in hex.
393    ${addition_timestamp}=  Set Variable  ${sel_info[5:9]}
394    Reverse List  ${addition_timestamp}
395    ${addition_timestamp}=  Evaluate  "".join(${addition_timestamp})
396
397    [Return]  ${addition_timestamp}
398
399
400Get Most Recent Erase Timestamp From SEL Info
401    [Documentation]  Get Most recent erase timestamp From SEL Info.
402
403    # Get SEL Info Raw command.
404    ${sel_info}=  Get SEL Info Via IPMI
405
406    # Get Most Recent Erase timestamp in hex.
407    ${erase_timestamp}=  Set Variable  ${sel_info[9:13]}
408    Reverse List  ${erase_timestamp}
409    ${erase_timestamp}=  Evaluate  "".join(${erase_timestamp})
410
411    [Return]  ${erase_timestamp}
412
413
414Get SEL Elist Last Entry Date In Epoch
415    [Documentation]  Get the time from SEL elist last entry and returns epoch time.
416
417    # Get SEL list last entry.
418    ${resp}=  Run IPMI Standard Command  sel elist last 1
419
420    # Get date from the sel entry and convert to epoch timestamp.
421    ${sel_entry_date}=  Fetch Added SEL Date  ${resp}
422    ${epoch_date}=  Convert Date  ${sel_entry_date}  epoch  exclude_millis=yes  date_format=%m/%d/%Y %H:%M:%S
423
424    [Return]  ${epoch_date}
425
426
427Get BMC Time In Epoch
428    [Documentation]  Get the current time from BMC and returns epoch time.
429
430    # Get the bmc native bmc date command response.
431    ${date}=  Get Current Date from BMC
432
433    ${epoch_date}=  Convert Date  ${date}  epoch  exclude_millis=yes  date_format=%m/%d/%Y %H:%M:%S
434
435    [Return]   ${epoch_date}
436
437
438Install Tarball For Error Creation
439    [Documentation]  Install tarball for error log creation.
440
441    ${status}=  Run Keyword And Return Status  Logging Test Binary Exist
442    Run Keyword If  ${status} == ${False}  Install Tarball
443
444
445Test Setup Execution
446    [Documentation]  Do test setup tasks.
447
448    Run IPMI Standard Command  sel clear
449    Sleep  5s
450