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