1*** Settings *** 2Documentation Open power domain keywords. 3 4Variables ../data/variables.py 5Resource ../lib/utils.robot 6Resource ../lib/connection_client.robot 7 8*** Variables *** 9${functional_cpu_count} ${0} 10${active_occ_count} ${0} 11${OCC_WAIT_TIMEOUT} 4 min 12 13*** Keywords *** 14 15Get OCC Objects 16 [Documentation] Get the OCC objects and return as a list. 17 18 # Example: 19 # { 20 # "/org/open_power/control/occ0": { 21 # "OccActive": 0 22 # }, 23 # "/org/open_power/control/occ1": { 24 # "OccActive": 1 25 # } 26 27 ${occ_list}= Get Endpoint Paths ${OPENPOWER_CONTROL} occ* 28 29 [Return] ${occ_list} 30 31 32Get OCC Active State 33 [Documentation] Get the OCC "OccActive" and return the attribute value. 34 [Arguments] ${value} 35 36 # Description of argument(s): 37 # value CPU position (e.g. "0, 1, 2"). 38 39 ${cmd}= Catenate busctl get-property org.open_power.OCC.Control 40 ... /org/open_power/control/occ${value} org.open_power.OCC.Status OccActive 41 42 ${cmd_output} ${stderr} ${rc} = BMC Execute Command ${cmd} 43 ... print_out=1 print_err=1 ignore_err=1 44 45 # The command returns format 'b true' 46 Return From Keyword If '${cmd_output.split(' ')[-1]}' == 'true' ${1} 47 48 [Return] ${0} 49 50 51Count Object Entries 52 [Documentation] Count the occurrence number of a given object. 53 [Arguments] ${object_base_uri_path} ${object_name} 54 55 # Description of argument(s): 56 # object_base_uri_path Object base path 57 # (e.g. "/org/open_power/control/"). 58 # object_name Object name (e.g. "occ", "cpu" etc). 59 60 ${object_list}= Get Endpoint Paths 61 ... ${object_base_uri_path} ${object_name} 62 ${list_count}= Get Length ${object_list} 63 [Return] ${list_count} 64 65 66Read Object Attribute 67 [Documentation] Return object attribute data. 68 [Arguments] ${object_base_uri_path} ${attribute_name} 69 70 # Description of argument(s): 71 # object_base_uri_path Object path. 72 # (e.g. "/org/open_power/control/occ0"). 73 # attribute_name Object attribute name. 74 75 ${resp}= OpenBMC Get Request 76 ... ${object_base_uri_path}/attr/${attribute_name} quiet=${1} 77 Return From Keyword If ${resp.status_code} != ${HTTP_OK} 78 [Return] ${resp.json()["data"]} 79 80 81Get Functional Processor Count 82 [Documentation] Get functional processor count. 83 84 ${cpu_list}= Redfish.Get Members List /redfish/v1/Systems/system/Processors/ *cpu* 85 86 FOR ${endpoint_path} IN @{cpu_list} 87 # {'Health': 'OK', 'State': 'Enabled'} get only matching status good. 88 ${cpu_status}= Redfish.Get Attribute ${endpoint_path} Status 89 Continue For Loop If '${cpu_status['Health']}' != 'OK' or '${cpu_status['State']}' != 'Enabled' 90 ${functional_cpu_count} = Evaluate ${functional_cpu_count} + 1 91 END 92 93 [Return] ${functional_cpu_count} 94 95 96Get Active OCC State Count 97 [Documentation] Get active OCC state count. 98 99 ${cpu_list}= Redfish.Get Members List /redfish/v1/Systems/system/Processors/ *cpu* 100 101 FOR ${endpoint_path} IN @{cpu_list} 102 ${num}= Set Variable ${endpoint_path[-1]} 103 ${cmd}= Catenate busctl get-property org.open_power.OCC.Control 104 ... /org/open_power/control/occ${num} org.open_power.OCC.Status OccActive 105 106 ${cmd_output} ${stderr} ${rc} = BMC Execute Command ${cmd} 107 ... print_out=1 print_err=1 ignore_err=1 108 109 # The command returns format 'b true' 110 Continue For Loop If '${cmd_output.split(' ')[-1]}' != 'true' 111 ${active_occ_count} = Evaluate ${active_occ_count} + 1 112 END 113 114 [Return] ${active_occ_count} 115 116 117Match OCC And CPU State Count 118 [Documentation] Get CPU functional count and verify OCC count active matches. 119 120 ${cpu_count}= Get Functional Processor Count 121 Log To Console Functional Processor count: ${cpu_count} 122 123 FOR ${num} IN RANGE ${0} ${cpu_count} 124 ${cmd}= Catenate busctl get-property org.open_power.OCC.Control 125 ... /org/open_power/control/occ${num} org.open_power.OCC.Status OccActive 126 127 ${cmd_output} ${stderr} ${rc} = BMC Execute Command ${cmd} 128 ... print_out=1 print_err=1 ignore_err=1 129 130 # The command returns format 'b true' 131 Continue For Loop If '${cmd_output.split(' ')[-1]}' != 'true' 132 ${active_occ_count} = Evaluate ${active_occ_count} + 1 133 END 134 135 Log To Console OCC Active count: ${active_occ_count} 136 137 Should Be Equal ${active_occ_count} ${cpu_count} 138 ... msg=OCC count ${active_occ_count} and CPU Count ${cpu_count} mismatched. 139 140 141Verify OCC State 142 [Documentation] Check OCC active state. 143 [Arguments] ${expected_occ_active}=${1} 144 # Description of Argument(s): 145 # expected_occ_active The expected occ_active value (i.e. 1/0). 146 147 # Example cpu_list data output: 148 # /redfish/v1/Systems/system/Processors/cpu0 149 # /redfish/v1/Systems/system/Processors/cpu1 150 151 ${cpu_list}= Redfish.Get Members List /redfish/v1/Systems/system/Processors/ cpu* 152 153 FOR ${endpoint_path} IN @{cpu_list} 154 # {'Health': 'OK', 'State': 'Enabled'} get only matching status good. 155 ${cpu_status}= Redfish.Get Attribute ${endpoint_path} Status 156 Continue For Loop If '${cpu_status['Health']}' != 'OK' or '${cpu_status['State']}' != 'Enabled' 157 Log To Console ${cpu_status} 158 ${num}= Set Variable ${endpoint_path[-1]} 159 ${occ_active}= Get OCC Active State ${num} 160 Should Be Equal ${occ_active} ${expected_occ_active} 161 ... msg=OCC not in right state 162 END 163 164 165Get Sensors Aggregation Data 166 [Documentation] Return open power sensors aggregation value list. 167 [Arguments] ${object_base_uri_path} 168 169 # Description of argument(s): 170 # object_base_uri_path An object path such as one of the elements 171 # returned by 'Get Sensors Aggregation URL List' 172 # (e.g. "/org/open_power/sensors/aggregation/per_30s/ps0_input_power/average"). 173 174 # Example of aggregation [epoch,time] data: 175 # "Values": [ 176 # [ 177 # 1517815708479, <-- EPOCH 178 # 282 <-- Power value in watts 179 # ], 180 # [ 181 # 1517815678238, 182 # 282 183 # ], 184 # [ 185 # 1517815648102, 186 # 282 187 # ], 188 # ], 189 190 ${resp}= Read Attribute ${object_base_uri_path} Values quiet=${1} 191 ${power_sensors_value_list}= Create List 192 FOR ${entry} IN @{resp} 193 Append To List ${power_sensors_value_list} ${entry[1]} 194 END 195 [Return] ${power_sensors_value_list} 196 197 198Get Sensors Aggregation URL List 199 [Documentation] Return the open power aggregation maximum list and the 200 ... average list URIs. 201 [Arguments] ${object_base_uri_path} 202 203 # Example of the 2 lists returned by this keyword: 204 # avgs: 205 # avgs[0]: /org/open_power/sensors/aggregation/per_30s/ps0_input_power/average 206 # avgs[1]: /org/open_power/sensors/aggregation/per_30s/ps1_input_power/average 207 # maxs: 208 # maxs[0]: /org/open_power/sensors/aggregation/per_30s/ps1_input_power/maximum 209 # maxs[1]: /org/open_power/sensors/aggregation/per_30s/ps0_input_power/maximum 210 211 # Description of argument(s): 212 # object_base_uri_path Object path. 213 # base path "/org/open_power/sensors/" 214 # (e.g. "base path + aggregation/per_30s/ps0_input_power/average") 215 216 # Example of open power sensor aggregation data as returned by the get 217 # request: 218 # /org/open_power/sensors/list 219 # [ 220 # "/org/open_power/sensors/aggregation/per_30s/ps0_input_power/average", 221 # "/org/open_power/sensors/aggregation/per_30s/ps1_input_power/maximum", 222 # "/org/open_power/sensors/aggregation/per_30s/ps0_input_power/maximum", 223 # "/org/open_power/sensors/aggregation/per_30s/ps1_input_power/average" 224 # ] 225 226 ${resp}= OpenBMC Get Request ${object_base_uri_path}list quiet=${1} 227 228 ${power_supply_avg_list}= Create List 229 ${power_supply_max_list}= Create List 230 231 FOR ${entry} IN @{resp.json()["data"]} 232 Run Keyword If 'average' in '${entry}' Append To List ${power_supply_avg_list} ${entry} 233 Run Keyword If 'maximum' in '${entry}' Append To List ${power_supply_max_list} ${entry} 234 END 235 236 [Return] ${power_supply_avg_list} ${power_supply_max_list} 237 238 239REST Verify No Gard Records 240 [Documentation] Verify no gard records are present. 241 242 ${resp}= Read Properties ${OPENPOWER_CONTROL}gard/enumerate 243 Log Dictionary ${resp} 244 Should Be Empty ${resp} msg=Found gard records. 245 246 247Inject OPAL TI 248 [Documentation] OPAL terminate immediate procedure. 249 [Arguments] ${stable_branch}=master 250 ... ${repo_dir_path}=/tmp/repository 251 ... ${repo_github_url}=https://github.com/open-power/op-test 252 253 # Description of arguments: 254 # stable_branch Git branch to clone. (default: master) 255 # repo_dir_path Directory path for repo tool (e.g. "op-test"). 256 # repo_github_url Github URL link (e.g. "https://github.com/open-power/op-test"). 257 258 ${value}= Generate Random String 4 [NUMBERS] 259 260 ${cmd_buf}= Catenate git clone --branch ${stable_branch} ${repo_github_url} ${repo_dir_path}/${value} 261 Shell Cmd ${cmd_buf} 262 263 Open Connection for SCP 264 scp.Put File ${repo_dir_path}/${value}/test_binaries/deadbeef /tmp 265 Pdbg -a putmem 0x300000f8 < /tmp/deadbeef 266 267 # Clean up the repo once done. 268 ${cmd_buf}= Catenate rm -rf ${repo_dir_path}${/}${value} 269 Shell Cmd ${cmd_buf} 270 271 272Trigger OCC Reset 273 [Documentation] Trigger OCC reset request on an active OCC. 274 [Arguments] ${occ_target}=${0} 275 276 # Description of Argument(s): 277 # occ_target Target a valid given OCC number 0,1, etc. 278 279 Log To Console OCC Reset Triggered on OCC ${occ_target} 280 281 ${cmd}= Catenate busctl call org.open_power.OCC.Control 282 ... /org/open_power/control/occ${occ_target} org.open_power.OCC.PassThrough 283 ... Send ai 8 64 0 5 20 82 83 84 0 284 285 ${cmd_output} ${stderr} ${rc} = BMC Execute Command ${cmd} print_out=1 print_err=1 286 287 Log To Console OCC wait check for disabled state. 288 Wait Until Keyword Succeeds 30 sec 5 sec Verify OCC Target State ${occ_target} 289 290 291Verify OCC Target State 292 [Documentation] Verify that the user given state matches th current OCC state. 293 [Arguments] ${occ_target}=${0} ${expected_state}=${0} 294 295 # Description of Argument(s): 296 # occ_target Target a valid given OCC number 0,1, etc. 297 # expected_state For OCC either 0 or 1. Default is 0. 298 299 ${occ_active}= Get OCC Active State ${occ_target} 300 Should Be Equal ${occ_active} ${expected_state} 301 Log To Console Target OCC ${occ_target} state is ${occ_active}. 302 303 304Trigger OCC Reset And Wait For OCC Active State 305 [Documentation] Trigger OCC reset request and wait for OCC to reset back to active state. 306 307 Trigger OCC Reset 308 309 Log To Console OCC wait check for active state. 310 Wait Until Keyword Succeeds ${OCC_WAIT_TIMEOUT} 20 sec Match OCC And CPU State Count 311 312 313Get Sensors Dbus Tree List 314 [Documentation] Get the list dbus path of the given sensor object and 315 ... return the populatedlist. 316 317 ${dbus_obj_var}= Set Variable 318 ... xyz.openbmc_project.HwmonTempSensor 319 ... xyz.openbmc_project.ADCSensor 320 ... xyz.openbmc_project.VirtualSensor 321 322 # Filter only the dbus paths service by the sensor obj. 323 ${sensors_dbus_tree_dict}= Create Dictionary 324 FOR ${dbus_obj} IN @{dbus_obj_var} 325 ${cmd}= Catenate busctl tree ${dbus_obj} --list | grep /sensors/ 326 ${cmd_output} ${stderr} ${rc} = BMC Execute Command ${cmd} 327 ... print_out=0 print_err=0 ignore_err=1 328 Set To Dictionary ${sensors_dbus_tree_dict} ${dbus_obj} ${cmd_output.splitlines()} 329 END 330 331 Rprint Vars sensors_dbus_tree_dict 332 # Key Pair: 'sensor obj":[list of obj URI] 333 # Example: 334 # sensors_dbus_tree_dict: 335 # [xyz.openbmc_project.HwmonTempSensor]: 336 # [0]: /xyz/openbmc_project/sensors/temperature/Ambient_0_Temp 337 # [1]: /xyz/openbmc_project/sensors/temperature/PCIE_0_Temp 338 # [xyz.openbmc_project.ADCSensor]: 339 # [0]: /xyz/openbmc_project/sensors/voltage/Battery_Voltage 340 # [xyz.openbmc_project.VirtualSensor]: 341 # [0]: /xyz/openbmc_project/sensors/temperature/Ambient_Virtual_Temp 342 343 [Return] ${sensors_dbus_tree_dict} 344 345 346Get Populated Sensors Dbus List 347 [Documentation] Perform GET operation on the attribute list and confirm it is 348 ... populated and does not error out during GET request.. 349 350 ${sensor_dict}= Get Sensors Dbus Tree List 351 352 # Loop through the dictionary and iterate item entries. 353 ${valid_dbus_list}= Create List 354 FOR ${key} IN @{sensor_dict.keys()} 355 FOR ${val} IN @{sensor_dict["${key}"]} 356 ${cmd}= Catenate 357 ... busctl get-property ${key} ${val} xyz.openbmc_project.Sensor.Value Value 358 ${cmd_output} ${stderr} ${rc} = BMC Execute Command ${cmd} 359 ... print_out=0 print_err=0 ignore_err=1 360 # Skip failed to get property command on Dbus object. 361 Run Keyword If ${rc} == 0 Append To List ${valid_dbus_list} ${val} 362 END 363 END 364 365 [Return] ${valid_dbus_list} 366 367 368Verify Runtime Sensors Dbus List 369 [Documentation] Load pre-defined sensor JSON Dbus data and validate against 370 ... runtime sensor list generated. 371 372 # Default path data/sensor_dbus.json else takes 373 # user CLI input -v SENSOR_DBUS_JSON_FILE_PATH:<path> 374 ${SENSOR_DBUS_JSON_FILE_PATH}= 375 ... Get Variable Value ${SENSOR_DBUS_JSON_FILE_PATH} data/sensor_dbus.json 376 377 ${json_data}= OperatingSystem.Get File ${SENSOR_DBUS_JSON_FILE_PATH} 378 ${json_sensor_data}= Evaluate json.loads('''${json_data}''') json 379 380 ${runtime_sensor_list}= Get Populated Sensors Dbus List 381 382 ${system_model}= Get BMC System Model 383 Rprint Vars system_model 384 Rprint Vars runtime_sensor_list 385 386 ${status}= Run Keyword And Return Status 387 ... Dictionary Should Contain Value ${json_sensor_data} ${runtime_sensor_list} 388 389 Run Keyword If ${status} == ${False} Log And Fail ${json_sensor_data} 390 391 Log To Console Runtime Dbus sensor list matches. 392 393 394Log And Fail 395 [Documentation] Log detailed failure log on the console. 396 [Arguments] ${json_sensor_data} 397 398 # Description of Argument(s): 399 # json_sensor_data Sensor JSON data from data/sensor_dbus.json. 400 401 Rprint Vars json_sensor_data 402 Fail Runtime generated Dbus sensors does not match 403 404