Chicago Duan | 0716635 | 2025-07-24 15:04:11 +0800 | [diff] [blame] | 1 | *** Settings *** |
| 2 | Documentation Test Redfish sensor monitoring. |
| 3 | |
| 4 | Resource ../../lib/resource.robot |
| 5 | Resource ../../lib/bmc_redfish_resource.robot |
| 6 | Resource ../../lib/bmc_redfish_utils.robot |
| 7 | Library ../../lib/gen_robot_print.py |
| 8 | Library ../../lib/utils.py |
| 9 | |
| 10 | Test Setup Test Setup Execution |
| 11 | Test Teardown Test Teardown Execution |
| 12 | Test Tags Test_Sensor_Monitoring |
| 13 | |
| 14 | *** Variables *** |
| 15 | |
| 16 | @{INVALID_SENSORS} |
| 17 | ${OPENBMC_CONN_METHOD} ssh |
| 18 | ${IPMI_COMMAND} Inband |
| 19 | |
| 20 | ** Test Cases ** |
| 21 | |
| 22 | Verify Sensor Monitoring |
| 23 | [Documentation] Verify the redfish sensor monitoring according to the BMC |
| 24 | ... expected SDR table. |
| 25 | [Tags] Verify_Sensor_Monitoring |
| 26 | |
| 27 | # Check whether the expected sensors are present in the Redfish request. |
| 28 | # Check whether the sensors's 'Health' is 'OK' and the 'State' is 'Enabled'. |
| 29 | # Check sensor reading is not equal to null. |
| 30 | |
| 31 | ${resp}= Redfish.Get /redfish/v1/Chassis/${CHASSIS_ID} |
| 32 | ... valid_status_codes=[${HTTP_OK}] |
| 33 | |
| 34 | Should Be Equal As Strings ${resp.dict['Oem']['Public']['DiscreteSensors']['@odata.id']} |
| 35 | ... /redfish/v1/Chassis/${CHASSIS_ID}/DiscreteSensors |
| 36 | Should Be Equal As Strings ${resp.dict['Oem']['Public']['ThresholdSensors']['@odata.id']} |
| 37 | ... /redfish/v1/Chassis/${CHASSIS_ID}/ThresholdSensors |
| 38 | Should Be Equal As Strings ${resp.dict['Thermal']['@odata.id']} |
| 39 | ... /redfish/v1/Chassis/${CHASSIS_ID}/Thermal |
| 40 | Should Be Equal As Strings ${resp.dict['Power']['@odata.id']} |
| 41 | ... /redfish/v1/Chassis/${CHASSIS_ID}/Power |
| 42 | |
| 43 | # Check sensors in /redfish/v1/Chassis/{ChassisId}/Power |
| 44 | ${resp}= Redfish.Get /redfish/v1/Chassis/${CHASSIS_ID}/Power |
| 45 | ... valid_status_codes=[${HTTP_OK}] |
| 46 | |
| 47 | Check If Expected Sensors Are Present ${resp.dict['Voltages']} Voltages |
| 48 | Check Sensor Status And Reading Via Sensor Info |
| 49 | ... ${resp.dict['Voltages']} ReadingVolts |
| 50 | |
| 51 | # Check sensors in /redfish/v1/Chassis/{ChassisId}/Thermal |
| 52 | ${resp}= Redfish.Get /redfish/v1/Chassis/${CHASSIS_ID}/Thermal |
| 53 | ... valid_status_codes=[${HTTP_OK}] |
| 54 | |
| 55 | Check If Expected Sensors Are Present ${resp.dict['Temperatures']} Temperatures |
| 56 | Check If Expected Sensors Are Present ${resp.dict['Fans']} Fans |
| 57 | |
| 58 | Check Sensor Status And Reading Via Sensor Info |
| 59 | ... ${resp.dict['Temperatures']} ReadingCelsius |
| 60 | Check Sensor Status And Reading Via Sensor Info |
| 61 | ... ${resp.dict['Fans']} Reading |
| 62 | |
| 63 | # Check sensors in |
| 64 | # /redfish/v1/Chassis/{ChassisId}/DiscreteSensors |
| 65 | ${resp}= Redfish.Get /redfish/v1/Chassis/${CHASSIS_ID}/DiscreteSensors |
| 66 | ... valid_status_codes=[${HTTP_OK}] |
| 67 | |
| 68 | Check If Expected Sensors Are Present ${resp.dict['Sensors']} DiscreteSensors |
| 69 | Check Sensor Status And Reading Via Sensor Info |
| 70 | ... ${resp.dict['Sensors']} Status |
| 71 | |
| 72 | # Check sensors in |
| 73 | # /redfish/v1/Chassis/{ChassisId}/ThresholdSensors |
| 74 | ${resp}= Redfish.Get /redfish/v1/Chassis/${CHASSIS_ID}/ThresholdSensors |
| 75 | ... valid_status_codes=[${HTTP_OK}] |
| 76 | |
| 77 | Check If Expected Sensors Are Present ${resp.dict['Sensors']} ThresholdSensors |
| 78 | Check Sensor Status And Reading Via Sensor Info |
| 79 | ... ${resp.dict['Sensors']} Reading |
| 80 | |
| 81 | Rprint Vars INVALID_SENSORS |
| 82 | |
| 83 | ${error_msg}= Evaluate ", ".join(${INVALID_SENSORS}) |
| 84 | Should Be Empty ${INVALID_SENSORS} |
| 85 | ... msg=Test fail, invalid sensors are ${error_msg}. |
| 86 | |
| 87 | |
| 88 | *** Keywords *** |
| 89 | |
| 90 | Test Teardown Execution |
| 91 | [Documentation] Do the post test teardown. |
| 92 | |
| 93 | Run Keyword And Ignore Error Redfish.Logout |
| 94 | |
| 95 | |
| 96 | Test Setup Execution |
| 97 | [Documentation] Do the test setup. |
| 98 | |
| 99 | Check For Required Parameters For Sensor Monitoring |
| 100 | Redfish.Login |
| 101 | |
| 102 | |
| 103 | Check For Required Parameters For Sensor Monitoring |
| 104 | [Documentation] Check if required parameters are provided via command line. |
| 105 | |
| 106 | Should Not Be Empty ${OS_HOST} |
| 107 | Should Not Be Empty ${OS_USERNAME} |
| 108 | Should Not Be Empty ${OS_PASSWORD} |
| 109 | IF '${OPENBMC_CONN_METHOD}' == 'ssh' |
| 110 | Should Not Be Empty ${OPENBMC_HOST} |
| 111 | ELSE IF '${OPENBMC_CONN_METHOD}' == 'telnet' |
| 112 | Should Not Be Empty ${OPENBMC_SERIAL_HOST} |
| 113 | ELSE |
| 114 | Fail Invalid connection method: ${OPENBMC_CONN_METHOD} |
| 115 | END |
| 116 | |
| 117 | |
| 118 | Get Sensors Name List From Redfish |
| 119 | [Documentation] Get sensors name list from redfish. |
| 120 | [Arguments] ${sensor_info_list} |
| 121 | # Description of arguments: |
| 122 | # sensor_info_list A list of a specified sensor info return by a redfish |
| 123 | # request. |
| 124 | |
| 125 | # An example of a sensor redfish request: |
| 126 | # /redfish/v1/Chassis/${CHASSIS_ID}/Power |
| 127 | # { |
| 128 | # ... |
| 129 | # "Voltages": [ |
| 130 | # { |
| 131 | # "@odata.id": "/redfish/v1/Chassis/1/Power#/Voltages/0", |
| 132 | # "@odata.type": "#Power.v1_7_1.Voltage", |
| 133 | # "LowerThresholdCritical": 10.8, |
| 134 | # "LowerThresholdFatal": 10.44, |
| 135 | # "LowerThresholdNonCritical": 11.16, |
| 136 | # "MaxReadingRange": 255.0, |
| 137 | # "MemberId": "0", |
| 138 | # "MinReadingRange": 0.0, |
| 139 | # "Name": "P12V_CPU0_DIMM", |
| 140 | # "ReadingVolts": null, |
| 141 | # "Status": { |
| 142 | # "Health": "OK", |
| 143 | # "State": "Enabled" |
| 144 | # }, |
| 145 | # "UpperThresholdCritical": 13.2, |
| 146 | # "UpperThresholdFatal": 13.786, |
| 147 | # "UpperThresholdNonCritical": 12.84 |
| 148 | # }, |
| 149 | |
| 150 | # .. |
| 151 | # } |
| 152 | |
| 153 | @{sensor_name_list}= Create List |
| 154 | FOR ${sensor_info} IN @{sensor_info_list} |
| 155 | Append To List ${sensor_name_list} ${sensor_info['Name']} |
| 156 | END |
| 157 | |
| 158 | RETURN ${sensor_name_list} |
| 159 | |
| 160 | |
| 161 | Check Sensor Status And Reading Via Sensor Name |
| 162 | [Documentation] Verify the sensor status and reading by sensor name, |
| 163 | ... optionally checking if the reading is within a given range. |
| 164 | [Arguments] ${sensor_name} |
| 165 | # Description of arguments: |
| 166 | # sensor_name Sensor that should be present. |
| 167 | |
| 168 | ${resp}= Redfish.Get |
| 169 | ... /redfish/v1/Chassis/${CHASSIS_ID}/Sensors/${sensor_name} |
| 170 | ... valid_status_codes=[${HTTP_OK}, ${HTTP_NOT_FOUND}] |
| 171 | |
| 172 | Run Keyword And Return If '${resp.status}' == '${HTTP_NOT_FOUND}' |
| 173 | ... Append To List ${INVALID_SENSORS} ${sensor_name} |
| 174 | |
| 175 | ${condition_str}= Catenate |
| 176 | ... '${resp.dict['Status']['Health']}' != 'OK' |
| 177 | ... or '${resp.dict['Status']['State']}' != 'Enabled' |
| 178 | ... or ${resp.dict['Reading']} == ${null} |
| 179 | |
| 180 | IF ${condition_str} |
| 181 | Append To List ${INVALID_SENSORS} ${sensor_name} |
| 182 | END |
| 183 | |
| 184 | |
| 185 | Check Sensor Status And Reading Via Sensor Info |
| 186 | [Documentation] Check if each sensor's health is ok, state is enabled, |
| 187 | ... and reading value (by unit) is not null from a redfish sensor info list. |
| 188 | [Arguments] ${sensor_info_list} ${reading_unit} |
| 189 | # Description of arguments: |
| 190 | # sensor_info_list A list of a specified sensor info return by a redfish |
| 191 | # request. |
| 192 | # reading_unit A string represents the reading value in sensor info |
| 193 | # return by a redfish request. It different between |
| 194 | # different sensor unit of sensor info. |
| 195 | |
| 196 | FOR ${sensor_info} IN @{sensor_info_list} |
| 197 | ${condition_str}= Catenate |
| 198 | ... '${sensor_info['Status']['Health']}' != 'OK' |
| 199 | ... or '${sensor_info['Status']['State']}' != 'Enabled' |
| 200 | ... or ${sensor_info['${reading_unit}']} == ${null} |
| 201 | |
| 202 | IF ${condition_str} |
| 203 | Append To List ${INVALID_SENSORS} ${sensor_info['Name']} |
| 204 | END |
| 205 | END |
| 206 | |
| 207 | |
| 208 | Check If Expected Sensors Are Present |
| 209 | [Documentation] Check that sensors are present as expected. |
| 210 | [Arguments] ${sensor_info_list} ${sensor_type} |
| 211 | # Description of arguments: |
| 212 | # sensor_info_list A list of a specified sensor info return by a redfish |
| 213 | # request. |
| 214 | # sensor_type A string represents the sensor category to be verified. |
| 215 | |
| 216 | # An example table of expected sensors: |
| 217 | # redfish_sensor_info_map = { |
| 218 | # "Voltages":{ |
| 219 | # "Voltage0", |
| 220 | # ... |
| 221 | # }, |
| 222 | # "Temperatures":{ |
| 223 | # "DIMM0", |
| 224 | # ... |
| 225 | # } |
| 226 | # "Fans":{ |
| 227 | # "Fan0", |
| 228 | # ... |
| 229 | # }... |
| 230 | #} |
| 231 | |
| 232 | ${curr_sensor_name_list}= Get Sensors Name List From Redfish |
| 233 | ... ${sensor_info_list} |
| 234 | |
| 235 | ${code_base_dir_path}= Get Code Base Dir Path |
| 236 | ${redfish_sensor_info_map}= Evaluate |
| 237 | ... json.load(open('${code_base_dir_path}data/oem/ieisystem/sensors_resource.json')) modules=json |
| 238 | |
| 239 | ${expected_sensor_name_list}= Set Variable |
| 240 | ... ${redfish_sensor_info_map['${sensor_type}']} |
| 241 | |
| 242 | FOR ${sensor_name} IN @{expected_sensor_name_list} |
| 243 | ${exist}= Evaluate '${sensor_name}' in ${curr_sensor_name_list} |
| 244 | IF '${exist}' == '${False}' |
| 245 | Append To List ${INVALID_SENSORS} ${sensor_name} |
| 246 | END |
| 247 | END |