blob: 344590b7c6251ef87e57a3aa7155684453e191ad [file] [log] [blame]
George Keishingcae6e902017-09-07 13:35:59 -05001*** Settings ***
2Documentation Open power domain keywords.
3
George Keishing7e825d82019-12-13 00:38:15 -06004Variables ../data/variables.py
George Keishingcae6e902017-09-07 13:35:59 -05005Resource ../lib/utils.robot
Michael Sheposd66cd552020-08-20 16:24:21 -05006Resource ../lib/connection_client.robot
George Keishing8ef9e722023-01-18 10:21:31 +05307Library utilities.py
George Keishingcae6e902017-09-07 13:35:59 -05008
George Keishingedd01e12021-08-31 14:01:12 -05009*** Variables ***
10${functional_cpu_count} ${0}
11${active_occ_count} ${0}
George Keishing9c223092024-01-29 21:18:25 +053012${OCC_WAIT_TIMEOUT} 8 min
George Keishingc23f3872023-03-16 22:43:33 +053013${fan_json_msg} Unable to create dump on non-JSON config based system
George Keishingedd01e12021-08-31 14:01:12 -050014
George Keishingcae6e902017-09-07 13:35:59 -050015*** Keywords ***
16
17Get OCC Objects
18 [Documentation] Get the OCC objects and return as a list.
19
20 # Example:
21 # {
22 # "/org/open_power/control/occ0": {
23 # "OccActive": 0
24 # },
25 # "/org/open_power/control/occ1": {
26 # "OccActive": 1
27 # }
28
George Keishing50cd0012017-09-14 12:23:41 -050029 ${occ_list}= Get Endpoint Paths ${OPENPOWER_CONTROL} occ*
George Keishingcae6e902017-09-07 13:35:59 -050030
31 [Return] ${occ_list}
32
33
34Get OCC Active State
35 [Documentation] Get the OCC "OccActive" and return the attribute value.
George Keishing9f487012021-08-19 12:18:10 -050036 [Arguments] ${value}
George Keishingcae6e902017-09-07 13:35:59 -050037
38 # Description of argument(s):
George Keishing9f487012021-08-19 12:18:10 -050039 # value CPU position (e.g. "0, 1, 2").
George Keishingcae6e902017-09-07 13:35:59 -050040
George Keishing9f487012021-08-19 12:18:10 -050041 ${cmd}= Catenate busctl get-property org.open_power.OCC.Control
42 ... /org/open_power/control/occ${value} org.open_power.OCC.Status OccActive
43
44 ${cmd_output} ${stderr} ${rc} = BMC Execute Command ${cmd}
45 ... print_out=1 print_err=1 ignore_err=1
46
47 # The command returns format 'b true'
48 Return From Keyword If '${cmd_output.split(' ')[-1]}' == 'true' ${1}
49
50 [Return] ${0}
George Keishing50cd0012017-09-14 12:23:41 -050051
52
53Count Object Entries
Gunnar Mills28e403b2017-10-25 16:16:38 -050054 [Documentation] Count the occurrence number of a given object.
George Keishing50cd0012017-09-14 12:23:41 -050055 [Arguments] ${object_base_uri_path} ${object_name}
56
57 # Description of argument(s):
58 # object_base_uri_path Object base path
59 # (e.g. "/org/open_power/control/").
60 # object_name Object name (e.g. "occ", "cpu" etc).
61
62 ${object_list}= Get Endpoint Paths
63 ... ${object_base_uri_path} ${object_name}
64 ${list_count}= Get Length ${object_list}
65 [Return] ${list_count}
66
67
68Read Object Attribute
69 [Documentation] Return object attribute data.
70 [Arguments] ${object_base_uri_path} ${attribute_name}
71
72 # Description of argument(s):
73 # object_base_uri_path Object path.
74 # (e.g. "/org/open_power/control/occ0").
75 # attribute_name Object attribute name.
76
77 ${resp}= OpenBMC Get Request
78 ... ${object_base_uri_path}/attr/${attribute_name} quiet=${1}
79 Return From Keyword If ${resp.status_code} != ${HTTP_OK}
George Keishingfbd67002022-08-01 11:24:03 -050080 [Return] ${resp.json()["data"]}
George Keishing50cd0012017-09-14 12:23:41 -050081
George Keishing5c96d1a2018-02-02 10:59:58 -060082
George Keishingedd01e12021-08-31 14:01:12 -050083Get Functional Processor Count
84 [Documentation] Get functional processor count.
85
86 ${cpu_list}= Redfish.Get Members List /redfish/v1/Systems/system/Processors/ *cpu*
87
88 FOR ${endpoint_path} IN @{cpu_list}
89 # {'Health': 'OK', 'State': 'Enabled'} get only matching status good.
90 ${cpu_status}= Redfish.Get Attribute ${endpoint_path} Status
91 Continue For Loop If '${cpu_status['Health']}' != 'OK' or '${cpu_status['State']}' != 'Enabled'
92 ${functional_cpu_count} = Evaluate ${functional_cpu_count} + 1
93 END
94
95 [Return] ${functional_cpu_count}
96
97
98Get Active OCC State Count
99 [Documentation] Get active OCC state count.
100
101 ${cpu_list}= Redfish.Get Members List /redfish/v1/Systems/system/Processors/ *cpu*
102
103 FOR ${endpoint_path} IN @{cpu_list}
104 ${num}= Set Variable ${endpoint_path[-1]}
105 ${cmd}= Catenate busctl get-property org.open_power.OCC.Control
106 ... /org/open_power/control/occ${num} org.open_power.OCC.Status OccActive
107
108 ${cmd_output} ${stderr} ${rc} = BMC Execute Command ${cmd}
109 ... print_out=1 print_err=1 ignore_err=1
110
111 # The command returns format 'b true'
112 Continue For Loop If '${cmd_output.split(' ')[-1]}' != 'true'
113 ${active_occ_count} = Evaluate ${active_occ_count} + 1
114 END
115
116 [Return] ${active_occ_count}
117
118
119Match OCC And CPU State Count
George Keishing8b38c1a2021-12-06 22:47:18 -0600120 [Documentation] Get CPU functional count and verify OCC count active matches.
121
George Keishingedd01e12021-08-31 14:01:12 -0500122 ${cpu_count}= Get Functional Processor Count
George Keishing8b38c1a2021-12-06 22:47:18 -0600123 Log To Console Functional Processor count: ${cpu_count}
124
125 FOR ${num} IN RANGE ${0} ${cpu_count}
126 ${cmd}= Catenate busctl get-property org.open_power.OCC.Control
127 ... /org/open_power/control/occ${num} org.open_power.OCC.Status OccActive
128
129 ${cmd_output} ${stderr} ${rc} = BMC Execute Command ${cmd}
130 ... print_out=1 print_err=1 ignore_err=1
131
132 # The command returns format 'b true'
133 Continue For Loop If '${cmd_output.split(' ')[-1]}' != 'true'
134 ${active_occ_count} = Evaluate ${active_occ_count} + 1
135 END
136
137 Log To Console OCC Active count: ${active_occ_count}
138
139 Should Be Equal ${active_occ_count} ${cpu_count}
140 ... msg=OCC count ${active_occ_count} and CPU Count ${cpu_count} mismatched.
George Keishingedd01e12021-08-31 14:01:12 -0500141
142
George Keishing5c96d1a2018-02-02 10:59:58 -0600143Verify OCC State
144 [Documentation] Check OCC active state.
145 [Arguments] ${expected_occ_active}=${1}
146 # Description of Argument(s):
147 # expected_occ_active The expected occ_active value (i.e. 1/0).
148
149 # Example cpu_list data output:
George Keishing0ad13a12021-06-18 14:15:14 -0500150 # /redfish/v1/Systems/system/Processors/cpu0
151 # /redfish/v1/Systems/system/Processors/cpu1
152
153 ${cpu_list}= Redfish.Get Members List /redfish/v1/Systems/system/Processors/ cpu*
George Keishing5c96d1a2018-02-02 10:59:58 -0600154
Marissa Garza522a0c22020-02-05 12:49:29 -0600155 FOR ${endpoint_path} IN @{cpu_list}
George Keishing0ad13a12021-06-18 14:15:14 -0500156 # {'Health': 'OK', 'State': 'Enabled'} get only matching status good.
157 ${cpu_status}= Redfish.Get Attribute ${endpoint_path} Status
158 Continue For Loop If '${cpu_status['Health']}' != 'OK' or '${cpu_status['State']}' != 'Enabled'
159 Log To Console ${cpu_status}
Marissa Garza522a0c22020-02-05 12:49:29 -0600160 ${num}= Set Variable ${endpoint_path[-1]}
George Keishing9f487012021-08-19 12:18:10 -0500161 ${occ_active}= Get OCC Active State ${num}
Marissa Garza522a0c22020-02-05 12:49:29 -0600162 Should Be Equal ${occ_active} ${expected_occ_active}
163 ... msg=OCC not in right state
164 END
George Keishingac512252018-02-05 02:04:30 -0600165
166
167Get Sensors Aggregation Data
168 [Documentation] Return open power sensors aggregation value list.
169 [Arguments] ${object_base_uri_path}
170
171 # Description of argument(s):
172 # object_base_uri_path An object path such as one of the elements
173 # returned by 'Get Sensors Aggregation URL List'
174 # (e.g. "/org/open_power/sensors/aggregation/per_30s/ps0_input_power/average").
175
176 # Example of aggregation [epoch,time] data:
177 # "Values": [
178 # [
179 # 1517815708479, <-- EPOCH
180 # 282 <-- Power value in watts
181 # ],
182 # [
183 # 1517815678238,
184 # 282
185 # ],
186 # [
187 # 1517815648102,
188 # 282
189 # ],
190 # ],
191
192 ${resp}= Read Attribute ${object_base_uri_path} Values quiet=${1}
193 ${power_sensors_value_list}= Create List
Marissa Garza522a0c22020-02-05 12:49:29 -0600194 FOR ${entry} IN @{resp}
195 Append To List ${power_sensors_value_list} ${entry[1]}
196 END
George Keishingac512252018-02-05 02:04:30 -0600197 [Return] ${power_sensors_value_list}
198
199
200Get Sensors Aggregation URL List
201 [Documentation] Return the open power aggregation maximum list and the
202 ... average list URIs.
203 [Arguments] ${object_base_uri_path}
204
205 # Example of the 2 lists returned by this keyword:
206 # avgs:
207 # avgs[0]: /org/open_power/sensors/aggregation/per_30s/ps0_input_power/average
208 # avgs[1]: /org/open_power/sensors/aggregation/per_30s/ps1_input_power/average
209 # maxs:
210 # maxs[0]: /org/open_power/sensors/aggregation/per_30s/ps1_input_power/maximum
211 # maxs[1]: /org/open_power/sensors/aggregation/per_30s/ps0_input_power/maximum
212
213 # Description of argument(s):
214 # object_base_uri_path Object path.
215 # base path "/org/open_power/sensors/"
216 # (e.g. "base path + aggregation/per_30s/ps0_input_power/average")
217
218 # Example of open power sensor aggregation data as returned by the get
219 # request:
220 # /org/open_power/sensors/list
221 # [
222 # "/org/open_power/sensors/aggregation/per_30s/ps0_input_power/average",
223 # "/org/open_power/sensors/aggregation/per_30s/ps1_input_power/maximum",
224 # "/org/open_power/sensors/aggregation/per_30s/ps0_input_power/maximum",
225 # "/org/open_power/sensors/aggregation/per_30s/ps1_input_power/average"
226 # ]
227
228 ${resp}= OpenBMC Get Request ${object_base_uri_path}list quiet=${1}
George Keishingac512252018-02-05 02:04:30 -0600229
230 ${power_supply_avg_list}= Create List
231 ${power_supply_max_list}= Create List
232
George Keishingfbd67002022-08-01 11:24:03 -0500233 FOR ${entry} IN @{resp.json()["data"]}
Marissa Garza522a0c22020-02-05 12:49:29 -0600234 Run Keyword If 'average' in '${entry}' Append To List ${power_supply_avg_list} ${entry}
235 Run Keyword If 'maximum' in '${entry}' Append To List ${power_supply_max_list} ${entry}
236 END
George Keishingac512252018-02-05 02:04:30 -0600237
238 [Return] ${power_supply_avg_list} ${power_supply_max_list}
Sweta Potthuri39255032018-03-28 10:12:14 -0500239
240
241REST Verify No Gard Records
242 [Documentation] Verify no gard records are present.
243
244 ${resp}= Read Properties ${OPENPOWER_CONTROL}gard/enumerate
245 Log Dictionary ${resp}
246 Should Be Empty ${resp} msg=Found gard records.
Michael Sheposd66cd552020-08-20 16:24:21 -0500247
248
249Inject OPAL TI
250 [Documentation] OPAL terminate immediate procedure.
251 [Arguments] ${stable_branch}=master
Michael Shepos8381f732021-04-20 12:03:08 -0500252 ... ${repo_dir_path}=/tmp/repository
Michael Sheposd66cd552020-08-20 16:24:21 -0500253 ... ${repo_github_url}=https://github.com/open-power/op-test
254
255 # Description of arguments:
256 # stable_branch Git branch to clone. (default: master)
257 # repo_dir_path Directory path for repo tool (e.g. "op-test").
258 # repo_github_url Github URL link (e.g. "https://github.com/open-power/op-test").
259
260 ${value}= Generate Random String 4 [NUMBERS]
261
262 ${cmd_buf}= Catenate git clone --branch ${stable_branch} ${repo_github_url} ${repo_dir_path}/${value}
263 Shell Cmd ${cmd_buf}
264
265 Open Connection for SCP
266 scp.Put File ${repo_dir_path}/${value}/test_binaries/deadbeef /tmp
267 Pdbg -a putmem 0x300000f8 < /tmp/deadbeef
268
269 # Clean up the repo once done.
270 ${cmd_buf}= Catenate rm -rf ${repo_dir_path}${/}${value}
271 Shell Cmd ${cmd_buf}
George Keishing2d4a8102022-02-22 12:23:21 -0600272
273
274Trigger OCC Reset
275 [Documentation] Trigger OCC reset request on an active OCC.
276 [Arguments] ${occ_target}=${0}
277
278 # Description of Argument(s):
279 # occ_target Target a valid given OCC number 0,1, etc.
280
281 Log To Console OCC Reset Triggered on OCC ${occ_target}
282
283 ${cmd}= Catenate busctl call org.open_power.OCC.Control
284 ... /org/open_power/control/occ${occ_target} org.open_power.OCC.PassThrough
285 ... Send ai 8 64 0 5 20 82 83 84 0
286
287 ${cmd_output} ${stderr} ${rc} = BMC Execute Command ${cmd} print_out=1 print_err=1
288
George Keishing5dd532a2022-03-07 11:14:42 -0600289 Log To Console OCC wait check for disabled state.
290 Wait Until Keyword Succeeds 30 sec 5 sec Verify OCC Target State ${occ_target}
291
292
293Verify OCC Target State
294 [Documentation] Verify that the user given state matches th current OCC state.
295 [Arguments] ${occ_target}=${0} ${expected_state}=${0}
296
297 # Description of Argument(s):
298 # occ_target Target a valid given OCC number 0,1, etc.
299 # expected_state For OCC either 0 or 1. Default is 0.
George Keishing2d4a8102022-02-22 12:23:21 -0600300
301 ${occ_active}= Get OCC Active State ${occ_target}
George Keishing5dd532a2022-03-07 11:14:42 -0600302 Should Be Equal ${occ_active} ${expected_state}
George Keishing2d4a8102022-02-22 12:23:21 -0600303 Log To Console Target OCC ${occ_target} state is ${occ_active}.
304
305
306Trigger OCC Reset And Wait For OCC Active State
307 [Documentation] Trigger OCC reset request and wait for OCC to reset back to active state.
308
309 Trigger OCC Reset
310
311 Log To Console OCC wait check for active state.
312 Wait Until Keyword Succeeds ${OCC_WAIT_TIMEOUT} 20 sec Match OCC And CPU State Count
George Keishingd1baad62022-11-23 08:25:36 -0600313
314
315Get Sensors Dbus Tree List
316 [Documentation] Get the list dbus path of the given sensor object and
317 ... return the populatedlist.
318
319 ${dbus_obj_var}= Set Variable
320 ... xyz.openbmc_project.HwmonTempSensor
321 ... xyz.openbmc_project.ADCSensor
322 ... xyz.openbmc_project.VirtualSensor
323
324 # Filter only the dbus paths service by the sensor obj.
325 ${sensors_dbus_tree_dict}= Create Dictionary
326 FOR ${dbus_obj} IN @{dbus_obj_var}
327 ${cmd}= Catenate busctl tree ${dbus_obj} --list | grep /sensors/
328 ${cmd_output} ${stderr} ${rc} = BMC Execute Command ${cmd}
329 ... print_out=0 print_err=0 ignore_err=1
330 Set To Dictionary ${sensors_dbus_tree_dict} ${dbus_obj} ${cmd_output.splitlines()}
331 END
332
333 Rprint Vars sensors_dbus_tree_dict
334 # Key Pair: 'sensor obj":[list of obj URI]
335 # Example:
336 # sensors_dbus_tree_dict:
337 # [xyz.openbmc_project.HwmonTempSensor]:
338 # [0]: /xyz/openbmc_project/sensors/temperature/Ambient_0_Temp
339 # [1]: /xyz/openbmc_project/sensors/temperature/PCIE_0_Temp
340 # [xyz.openbmc_project.ADCSensor]:
341 # [0]: /xyz/openbmc_project/sensors/voltage/Battery_Voltage
342 # [xyz.openbmc_project.VirtualSensor]:
343 # [0]: /xyz/openbmc_project/sensors/temperature/Ambient_Virtual_Temp
344
345 [Return] ${sensors_dbus_tree_dict}
346
347
348Get Populated Sensors Dbus List
349 [Documentation] Perform GET operation on the attribute list and confirm it is
350 ... populated and does not error out during GET request..
351
352 ${sensor_dict}= Get Sensors Dbus Tree List
353
354 # Loop through the dictionary and iterate item entries.
355 ${valid_dbus_list}= Create List
356 FOR ${key} IN @{sensor_dict.keys()}
357 FOR ${val} IN @{sensor_dict["${key}"]}
358 ${cmd}= Catenate
359 ... busctl get-property ${key} ${val} xyz.openbmc_project.Sensor.Value Value
360 ${cmd_output} ${stderr} ${rc} = BMC Execute Command ${cmd}
361 ... print_out=0 print_err=0 ignore_err=1
362 # Skip failed to get property command on Dbus object.
363 Run Keyword If ${rc} == 0 Append To List ${valid_dbus_list} ${val}
364 END
365 END
366
367 [Return] ${valid_dbus_list}
368
369
370Verify Runtime Sensors Dbus List
371 [Documentation] Load pre-defined sensor JSON Dbus data and validate against
372 ... runtime sensor list generated.
373
374 # Default path data/sensor_dbus.json else takes
375 # user CLI input -v SENSOR_DBUS_JSON_FILE_PATH:<path>
376 ${SENSOR_DBUS_JSON_FILE_PATH}=
377 ... Get Variable Value ${SENSOR_DBUS_JSON_FILE_PATH} data/sensor_dbus.json
378
379 ${json_data}= OperatingSystem.Get File ${SENSOR_DBUS_JSON_FILE_PATH}
380 ${json_sensor_data}= Evaluate json.loads('''${json_data}''') json
381
382 ${runtime_sensor_list}= Get Populated Sensors Dbus List
383
384 ${system_model}= Get BMC System Model
385 Rprint Vars system_model
386 Rprint Vars runtime_sensor_list
387
388 ${status}= Run Keyword And Return Status
389 ... Dictionary Should Contain Value ${json_sensor_data} ${runtime_sensor_list}
390
391 Run Keyword If ${status} == ${False} Log And Fail ${json_sensor_data}
392
393 Log To Console Runtime Dbus sensor list matches.
394
395
396Log And Fail
397 [Documentation] Log detailed failure log on the console.
398 [Arguments] ${json_sensor_data}
399
400 # Description of Argument(s):
401 # json_sensor_data Sensor JSON data from data/sensor_dbus.json.
402
403 Rprint Vars json_sensor_data
404 Fail Runtime generated Dbus sensors does not match
405
George Keishing8ef9e722023-01-18 10:21:31 +0530406
407Dump Fan Control JSON
408 [Documentation] Execute fan control on BMC to dump config with 'fanctl dump',
409 ... which makes it write a /tmp/fan_control_dump.json file.
410
411 ${output} ${stderr} ${rc} = BMC Execute Command test -f /usr/bin/fanctl
412 ... print_err=1 ignore_err=1
413 Return From Keyword If ${rc} == 1 fanctl application doesn't exist.
414
415 # This command will force a fan_control_dump.json file in temp path and
416 # takes few seconds to complete..
417 BMC Execute Command fanctl dump
418 Sleep 10s
419
George Keishingc23f3872023-03-16 22:43:33 +0530420
421Get Fan JSON Data
422 [Documentation] Read the JSON string file from BMC and return.
423
George Keishing8ef9e722023-01-18 10:21:31 +0530424 # Check for the generated file and return the file data as JSON and fails if
425 # it doesn't find file generated.
426 ${cmd}= Catenate test -f /tmp/fan_control_dump.json; cat /tmp/fan_control_dump.json
427 ${json_string} ${stderr} ${rc} = BMC Execute Command ${cmd}
428 ... print_out=1 print_err=1 ignore_err=1
429
430 Should Be True ${rc} == 0 msg=No Fan control config JSON file is generated.
431 ${fan_json}= Evaluate json.loads('''${json_string}''') json
432
433 [return] ${fan_json}
434
435
436Get Fan Attribute Value
437 [Documentation] Return the specified value of the matched search key in
438 ... nested dictionary data.
George Keishingc23f3872023-03-16 22:43:33 +0530439 [Arguments] ${fan_dict} ${key_value}
George Keishing8ef9e722023-01-18 10:21:31 +0530440
441 # Description of Argument(s):
442 # key_value User input attribute value in the dictionary.
443
George Keishingc23f3872023-03-16 22:43:33 +0530444 ${empty_dicts}= Create Dictionary
445
446 # Check for JSON response data.
447 # {
448 # "msg": "Unable to create dump on non-JSON config based system"
449 # }
450
451 ${status}= Run Keyword And Return Status
452 ... Should Be Equal ${fan_dict["msg"]} ${fan_json_msg}
453 IF ${status}
454 Log To Console Skipping attribute ${key_value} check.
455 Return From Keyword ${empty_dicts}
456 END
George Keishing8ef9e722023-01-18 10:21:31 +0530457
458 # Python module: get_value_from_nested_dict(key,dict)
459 ${value_list}= utilities.Get Value From Nested Dict ${key_value} ${fan_dict}
460
461 Should Not Be Empty ${value_list} msg=${key_value} key attribute not found.
462
463 [Return] ${value_list[0]}