| 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 |