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