1*** Settings ***
2Documentation  Validate IPMI sensor IDs using Redfish.
3
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        Redfish.Login
10Test Teardown     Run Keywords  FFDC On Test Case Fail  AND
11...  Redfish.Logout
12
13
14*** Variables ***
15${allowed_temp_diff}    ${2}
16${allowed_power_diff}   ${10}
17
18
19*** Test Cases ***
20
21Verify IPMI Temperature Readings using Redfish
22    [Documentation]  Verify temperatures from IPMI sensor reading command using Redfish.
23    [Tags]  Verify_IPMI_Temperature_Readings_using_Redfish
24    [Template]  Get Temperature Reading And Verify In Redfish
25
26    # command_type  sensor_id  member_id
27    IPMI            pcie       pcie
28    IPMI            ambient    ambient
29
30
31Verify DCMI Temperature Readings using Redfish
32    [Documentation]  Verify temperatures from DCMI sensor reading command using Redfish.
33    [Tags]  Verify_DCMI_Temperature_Readings_using_Redfish
34    [Template]  Get Temperature Reading And Verify In Redfish
35
36    # command_type  sensor_id  member_id
37    DCMI            pcie       pcie
38    DCMI            ambient    ambient
39
40
41Test Ambient Temperature Via IPMI
42    [Documentation]  Test ambient temperature via IPMI and verify using Redfish.
43    [Tags]  Test_Ambient_Temperature_Via_IPMI
44
45    # Example of IPMI dcmi get_temp_reading output:
46    #        Entity ID                       Entity Instance    Temp. Readings
47    # Inlet air temperature(40h)                      1               +19 C
48    # CPU temperature sensors(41h)                    5               +51 C
49    # CPU temperature sensors(41h)                    6               +50 C
50    # CPU temperature sensors(41h)                    7               +50 C
51    # CPU temperature sensors(41h)                    8               +50 C
52    # CPU temperature sensors(41h)                    9               +50 C
53    # CPU temperature sensors(41h)                    10              +48 C
54    # CPU temperature sensors(41h)                    11              +49 C
55    # CPU temperature sensors(41h)                    12              +47 C
56    # CPU temperature sensors(41h)                    8               +50 C
57    # CPU temperature sensors(41h)                    16              +51 C
58    # CPU temperature sensors(41h)                    24              +50 C
59    # CPU temperature sensors(41h)                    32              +43 C
60    # CPU temperature sensors(41h)                    40              +43 C
61    # Baseboard temperature sensors(42h)              1               +35 C
62
63    ${temp_reading}=  Run IPMI Standard Command  dcmi get_temp_reading -N 10
64    Should Contain  ${temp_reading}  Inlet air temperature
65    ...  msg="Unable to get inlet temperature via DCMI".
66
67    ${ambient_temp_line}=
68    ...  Get Lines Containing String  ${temp_reading}
69    ...  Inlet air temperature  case-insensitive
70
71    ${ambient_temp_ipmi}=  Set Variable  ${ambient_temp_line.split('+')[1].strip(' C')}
72
73    # Example of ambient temperature via Redfish
74
75    #"@odata.id": "/redfish/v1/Chassis/chassis/Thermal#/Temperatures/0",
76    #"@odata.type": "#Thermal.v1_3_0.Temperature",
77    #"LowerThresholdCritical": 0.0,
78    #"LowerThresholdNonCritical": 0.0,
79    #"MaxReadingRangeTemp": 0.0,
80    #"MemberId": "ambient",
81    #"MinReadingRangeTemp": 0.0,
82    #"Name": "ambient",
83    #"ReadingCelsius": 24.987000000000002,
84    #"Status": {
85          #"Health": "OK",
86          #"State": "Enabled"
87    #},
88    #"UpperThresholdCritical": 35.0,
89    #"UpperThresholdNonCritical": 25.0
90
91    ${ambient_temp_redfish}=  Get Temperature Reading From Redfish  ambient
92
93    ${ipmi_redfish_temp_diff}=
94    ...  Evaluate  abs(${ambient_temp_redfish} - ${ambient_temp_ipmi})
95
96    Should Be True  ${ipmi_redfish_temp_diff} <= ${allowed_temp_diff}
97    ...  msg=Ambient temperature above allowed threshold ${allowed_temp_diff}.
98
99
100Test Power Reading Via IPMI With Host Off
101    [Documentation]  Verify power reading via IPMI with host in off state
102    [Tags]  Test_Power_Reading_Via_IPMI_With_Host_Off
103
104    Redfish Power Off  stack_mode=skip
105
106    ${ipmi_reading}=  Get IPMI Power Reading
107
108    Should Be Equal  ${ipmi_reading['instantaneous_power_reading']}  0
109    ...  msg=Power reading not zero when power is off.
110
111
112Test Power Reading Via IPMI With Host Booted
113    [Documentation]  Test power reading via IPMI with host in booted state and
114    ...  verify using Redfish.
115    [Tags]  Test_Power_Reading_Via_IPMI_With_Host_Booted
116
117    IPMI Power On  stack_mode=skip
118
119    Wait Until Keyword Succeeds  2 min  30 sec  Verify Power Reading Using IPMI And Redfish
120
121
122Test Baseboard Temperature Via IPMI
123    [Documentation]  Test baseboard temperature via IPMI and verify using Redfish.
124    [Tags]  Test_Baseboard_Temperature_Via_IPMI
125
126    # Example of IPMI dcmi get_temp_reading output:
127    #        Entity ID                       Entity Instance    Temp. Readings
128    # Inlet air temperature(40h)                      1               +19 C
129    # CPU temperature sensors(41h)                    5               +51 C
130    # CPU temperature sensors(41h)                    6               +50 C
131    # CPU temperature sensors(41h)                    7               +50 C
132    # CPU temperature sensors(41h)                    8               +50 C
133    # CPU temperature sensors(41h)                    9               +50 C
134    # CPU temperature sensors(41h)                    10              +48 C
135    # CPU temperature sensors(41h)                    11              +49 C
136    # CPU temperature sensors(41h)                    12              +47 C
137    # CPU temperature sensors(41h)                    8               +50 C
138    # CPU temperature sensors(41h)                    16              +51 C
139    # CPU temperature sensors(41h)                    24              +50 C
140    # CPU temperature sensors(41h)                    32              +43 C
141    # CPU temperature sensors(41h)                    40              +43 C
142    # Baseboard temperature sensors(42h)              1               +35 C
143
144    ${temp_reading}=  Run IPMI Standard Command  dcmi get_temp_reading -N 10
145    Should Contain  ${temp_reading}  Baseboard temperature sensors
146    ...  msg="Unable to get baseboard temperature via DCMI".
147    ${baseboard_temp_line}=
148    ...  Get Lines Containing String  ${temp_reading}
149    ...  Baseboard temperature  case-insensitive=True
150
151    ${baseboard_temp_ipmi}=  Set Variable  ${baseboard_temp_line.split('+')[1].strip(' C')}
152
153    # Example of Baseboard temperature via Redfish
154
155    #"@odata.id": "/redfish/v1/Chassis/chassis/Thermal#/Temperatures/9",
156    #"@odata.type": "#Thermal.v1_3_0.Temperature",
157    #"LowerThresholdCritical": 0.0,
158    #"LowerThresholdNonCritical": 0.0,
159    #"MaxReadingRangeTemp": 0.0,
160    #"MemberId": "pcie",
161    #"MinReadingRangeTemp": 0.0,
162    #"Name": "pcie",
163    #"ReadingCelsius": 28.687,
164    #"Status": {
165          #"Health": "OK",
166          #"State": "Enabled"
167    #},
168    #"UpperThresholdCritical": 70.0,
169    #"UpperThresholdNonCritical": 60.0
170
171    ${baseboard_temp_redfish}=  Get Temperature Reading From Redfish  pcie
172
173    Should Be True
174    ...  ${baseboard_temp_redfish} - ${baseboard_temp_ipmi} <= ${allowed_temp_diff}
175    ...  msg=Baseboard temperature above allowed threshold ${allowed_temp_diff}.
176
177
178Test Power Reading Via IPMI Raw Command
179    [Documentation]  Test power reading via IPMI raw command and verify
180    ...  using Redfish.
181    [Tags]  Test_Power_Reading_Via_IPMI_Raw_Command
182
183    IPMI Power On  stack_mode=skip
184
185    Wait Until Keyword Succeeds  2 min  30 sec  Verify Power Reading Via Raw Command
186
187
188Verify CPU Present
189    [Documentation]  Verify the IPMI sensor for CPU present using Redfish.
190    [Tags]  Verify_CPU_Present
191    [Template]  Enable Present Bit Via IPMI and Verify Using Redfish
192
193    # sensor_id  component
194    0x5a         cpu0
195
196
197Verify CPU Not Present
198    [Documentation]  Verify the IPMI sensor for CPU not present using Redfish.
199    [Tags]  Verify_CPU_Not_Present
200    [Template]  Disable Present Bit Via IPMI and Verify Using Redfish
201
202    # sensor_id  component
203    0x5a         cpu0
204
205
206Verify GPU Present
207    [Documentation]  Verify the IPMI sensor for GPU present using Redfish.
208    [Tags]  Verify_GPU_Present
209    [Template]  Enable Present Bit Via IPMI and Verify Using Redfish
210
211    # sensor_id  component
212    0xC5         gv100card0
213
214
215Verify GPU Not Present
216    [Documentation]  Verify the IPMI sensor for GPU not present using Redfish.
217    [Tags]  Verify_GPU_Not_Present
218    [Template]  Disable Present Bit Via IPMI and Verify Using Redfish
219
220    # sensor_id  component
221    0xC5         gv100card0
222
223
224Test Sensor Threshold Via IPMI
225    [Documentation]  Test sensor threshold via IPMI and verify using Redfish.
226    [Tags]  Test_Sensor_Threshold_Via_IPMI
227    [Template]  Verify Power Supply Sensor Threshold
228
229    # threshold_id             component
230    Upper Non-Critical         UpperThresholdNonCritical
231    Upper Critical             UpperThresholdCritical
232    Lower Non-Critical         LowerThresholdNonCritical
233    Lower Critical             LowerThresholdCritical
234
235
236*** Keywords ***
237
238Get Temperature Reading And Verify In Redfish
239    [Documentation]  Get IPMI or DCMI sensor reading and verify in Redfish.
240    [Arguments]  ${command_type}  ${sensor_id}  ${member_id}
241
242    # Description of argument(s):
243    # command_type  Type of command used to get sensor data (eg. IPMI, DCMI).
244    # sensor_id     Sensor id used to get reading in IPMI or DCMI.
245    # member_id     Member id of sensor data in Redfish.
246
247    ${ipmi_value}=  Run Keyword If  '${command_type}' == 'IPMI'  Get IPMI Sensor Reading  ${sensor_id}
248    ...  ELSE  Get DCMI Sensor Reading  ${sensor_id}
249
250    ${redfish_value}=  Get Temperature Reading From Redfish  ${member_id}
251
252    Valid Range  ${ipmi_value}  ${redfish_value-1.000}  ${redfish_value+1.000}
253
254
255Get IPMI Sensor Reading
256    [Documentation]  Get reading from IPMI sensor reading command.
257    [Arguments]  ${sensor_id}
258
259    # Description of argument(s):
260    # sensor_id     Sensor id used to get reading in IPMI.
261
262    ${data}=  Run IPMI Standard Command  sensor reading ${sensor_id}
263
264    # Example reading:
265    # pcie             | 28.500
266
267    ${sensor_value}=  Set Variable  ${data.split('| ')[1].strip()}
268    [Return]  ${sensor_value}
269
270
271Get DCMI Sensor Reading
272    [Documentation]  Get reading from DCMI sensors command.
273    [Arguments]  ${sensor_id}
274
275    # Description of argument(s):
276    # sensor_id     Sensor id used to get reading in DCMI.
277
278    ${data}=  Run IPMI Standard Command  dcmi sensors
279    ${sensor_data}=  Get Lines Containing String  ${data}  ${sensor_id}
280
281    # Example reading:
282    # Record ID 0x00fd: pcie             | 28.50 degrees C   | ok
283
284    ${sensor_value}=  Set Variable  ${sensor_data.split(' | ')[1].strip('degrees C').strip()}
285    [Return]  ${sensor_value}
286
287
288Get Temperature Reading From Redfish
289    [Documentation]  Get temperature reading from Redfish.
290    [Arguments]  ${member_id}
291
292    # Description of argument(s):
293    # member_id    Member id of temperature.
294
295    @{redfish_readings}=  Redfish.Get Attribute  /redfish/v1/Chassis/chassis/Thermal  Temperatures
296    FOR  ${data}  IN  @{redfish_readings}
297        ${redfish_value}=  Set Variable If  '${data}[MemberId]' == '${member_id}'
298        ...  &{data}[ReadingCelsius]
299        Exit For Loop If  '${data}[MemberId]' == '${member_id}'
300    END
301    [Return]  ${redfish_value}
302
303
304Verify Power Reading Using IPMI And Redfish
305    [Documentation]  Verify power reading using IPMI and Redfish.
306
307    # Example of power reading command output via IPMI.
308    # Instantaneous power reading:                   235 Watts
309    # Minimum during sampling period:                235 Watts
310    # Maximum during sampling period:                235 Watts
311    # Average power reading over sample period:      235 Watts
312    # IPMI timestamp:                                Thu Jan  1 00:00:00 1970
313    # Sampling period:                               00000000 Seconds.
314    # Power reading state is:                        deactivated
315
316    ${ipmi_reading}=  Get IPMI Power Reading
317
318    ${power_uri_list}=  redfish_utils.Get Members URI  /redfish/v1/Chassis/  PowerControl
319    Log List  ${power_uri_list}
320
321    # Power entries could be seen across different redfish path, remove the URI
322    # where the attribute is non-existent.
323    # Example:
324    #     ['/redfish/v1/Chassis/chassis/Power',
325    #      '/redfish/v1/Chassis/motherboard/Power']
326    FOR  ${idx}  IN  @{power_uri_list}
327        ${power}=  redfish_utils.Get Attribute  ${idx}  PowerControl
328        Log Dictionary  ${power[0]}
329
330        # Ensure the path does have the attribute else set to EMPTY as default to skip.
331        ${value}=  Get Variable Value  ${power[0]['PowerConsumedWatts']}  ${EMPTY}
332        Run Keyword If  "${value}" == "${EMPTY}"
333        ...  Remove Values From List  ${power_uri_list}  ${idx}
334
335        # Check the next available element in the list.
336        Continue For Loop If  "${value}" == "${EMPTY}"
337
338        ${ipmi_redfish_power_diff}=
339        ...  Evaluate  abs(${${power[0]['PowerConsumedWatts']}} - ${ipmi_reading['instantaneous_power_reading']})
340        Should Be True  ${ipmi_redfish_power_diff} <= ${allowed_power_diff}
341        ...  msg=Power reading above allowed threshold ${allowed_power_diff}.
342    END
343
344    # Double check, the validation has at least one valid path.
345    Should Not Be Empty  ${power_uri_list}
346    ...  msg=Should contain at least one element in the list.
347
348
349Verify Power Reading Via Raw Command
350    [Documentation]  Get dcmi power reading via IPMI raw command.
351
352    ${ipmi_raw_output}=  Run IPMI Standard Command
353    ...  raw ${IPMI_RAW_CMD['power_reading']['Get'][0]}
354
355    ${power_reading_ipmi}=  Set Variable  ${ipmi_raw_output.split()[1]}
356    ${power_reading_ipmi}=
357    ...  Convert To Integer  0x${power_reading_ipmi}
358
359    #  Example of power reading via Redfish
360    #  "@odata.id": "/redfish/v1/Chassis/chassis/Power#/PowerControl/0",
361    #  "@odata.type": "#Power.v1_0_0.PowerControl",
362    #  "MemberId": "0",
363    #  "Name": "Chassis Power Control",
364    #  "PowerConsumedWatts": 145.0,
365
366    ${power}=  Redfish.Get Properties  /redfish/v1/Chassis/chassis/Power
367    ${redfish_reading}=  Set Variable  ${power['PowerControl'][0]['PowerConsumedWatts']}
368
369    ${ipmi_redfish_power_diff}=
370    ...  Evaluate  abs(${redfish_reading} - ${power_reading_ipmi})
371
372    Should Be True  ${ipmi_redfish_power_diff} <= ${allowed_power_diff}
373    ...  msg=Power reading above allowed threshold ${allowed_power_diff}.
374
375
376Enable Present Bit Via IPMI and Verify Using Redfish
377    [Documentation]  Enable present bit of sensor via IPMI and verify using Redfish.
378    [Arguments]  ${sensor_id}  ${component}
379
380    # Description of argument(s):
381    # sensor_id    The sensor id of IPMI sensor.
382    # component    The Redfish component of IPMI sensor.
383
384    Run IPMI Command
385    ...  0x04 0x30 ${sensor_id} 0xa9 0x00 0x80 0x00 0x00 0x00 0x00 0x20 0x00
386
387    #  Example of CPU state via Redfish
388
389    #"Name": "Processor",
390    #"ProcessorArchitecture": "Power",
391    #"ProcessorType": "CPU",
392    #"Status": {
393    #    "Health": "OK",
394    #    "State": "Enabled"
395    #}
396
397    ${redfish_value}=  Redfish.Get Properties  /redfish/v1/Systems/system/Processors/${component}
398    Should Be True  '${redfish_value['Status']['State']}' == 'Enabled'
399
400
401Disable Present Bit Via IPMI and Verify Using Redfish
402    [Documentation]  Disable present bit of sensor via IPMI and verify using Redfish.
403    [Arguments]  ${sensor_id}  ${component}
404
405    # Description of argument(s):
406    # sensor_id    The sensor id of IPMI sensor.
407    # component    The Redfish component of IPMI sensor.
408
409    Run IPMI Command
410    ...  0x04 0x30 ${sensor_id} 0xa9 0x00 0x00 0x00 0x80 0x00 0x00 0x20 0x00
411
412    #  Example of CPU state via Redfish
413
414    #"Name": "Processor",
415    #"ProcessorArchitecture": "Power",
416    #"ProcessorType": "CPU",
417    #"Status": {
418    #    "Health": "OK",
419    #    "State": "Absent"
420    #}
421
422    ${redfish_value}=  Redfish.Get Properties  /redfish/v1/Systems/system/Processors/${component}
423    Should Be True  '${redfish_value['Status']['State']}' == 'Absent'
424
425
426Verify Power Supply Sensor Threshold
427    [Documentation]  Get power supply sensor threshold value via IPMI and verify using Redfish.
428    [Arguments]  ${ipmi_threshold_id}  ${redfish_threshold_id}
429
430    # Description of argument(s):
431    # ipmi_threshold_id       The sensor threshold component of IPMI sensor.
432    # redfish_threshold_id    The sensor threshold component of Redfish sensor.
433
434
435    #  Example of ipmi sensor output
436    # Locating sensor record...
437    # Sensor ID              : ps0_input_voltag (0xf7)
438    # Entity ID             : 10.19
439    # Sensor Type (Threshold)  : Voltage
440    # Sensor Reading        : 208 (+/- 0) Volts
441    # Status                : ok
442    # Lower Non-Recoverable : na
443    # Lower Critical        : 180.000
444    # Lower Non-Critical    : 200.000
445    # Upper Non-Critical    : 290.000
446    # Upper Critical        : 300.000
447    # Upper Non-Recoverable : na
448    # Positive Hysteresis   : Unspecified
449    # Negative Hysteresis   : Unspecified
450
451
452    ${ipmi_sensor_output}=  Run External IPMI Standard Command  sensor get ps0_input_voltag
453    ${ipmi_threshold_output}=  Get Lines Containing String  ${ipmi_sensor_output}  ${ipmi_threshold_id}
454    ${ipmi_threshold_reading}=  Fetch From Right  ${ipmi_threshold_output}  :${SPACE}
455
456    ${ipmi_threshold_reading}=  Set Variable If  '${ipmi_threshold_reading}' == 'na'
457    ...  ${0}  ${ipmi_threshold_reading}
458
459    #  Example of redfish sensor output
460    # "@odata.id": "/redfish/v1/Chassis/chassis/Power#/Voltages/0",
461    # "@odata.type": "#Power.v1_0_0.Voltage",
462    # "LowerThresholdCritical": 180.0,
463    # "LowerThresholdNonCritical": 200.0,
464    # "MaxReadingRange": 0.0,
465    # "MemberId": "ps0_input_voltage",
466    # "MinReadingRange": 0.0,
467    # "Name": "ps0 input voltage",
468    # "ReadingVolts": 209.5,
469    # "Status": {
470    # "Health": "OK",
471    # "State": "Enabled"
472    # },
473    # "UpperThresholdCritical": 300.0,
474    # "UpperThresholdNonCritical": 290.0
475
476    @{redfish_readings}=  Redfish.Get Attribute  /redfish/v1/Chassis/chassis/Power  Voltages
477    FOR  ${data}  IN  @{redfish_readings}
478        Run keyword if  '${data}[MemberId]' == 'ps0_input_voltage'
479        ...  Should Be Equal As Numbers  ${data['${redfish_threshold_id}']}  ${ipmi_threshold_reading}
480    END
481