blob: a16c09378d1df40e82025be77f101987f547c886 [file] [log] [blame]
Steven Sombar6b280142018-02-12 10:45:13 -06001*** Settings ***
Steven Sombar43d6ba32018-02-16 11:25:09 -06002Documentation Utilities for fan tests.
Steven Sombar6b280142018-02-12 10:45:13 -06003
Steven Sombar43d6ba32018-02-16 11:25:09 -06004Library ../lib/bmc_ssh_utils.py
Steven Sombar741e99d2019-05-07 07:20:51 -05005Resource ../lib/state_manager.robot
Steven Sombar43d6ba32018-02-16 11:25:09 -06006Resource ../lib/openbmc_ffdc_utils.robot
7Variables ../data/variables.py
Steven Sombar6b280142018-02-12 10:45:13 -06008
Steven Sombar47ac2f42019-04-17 21:13:43 -05009*** Variables ***
10
11# Fan state values.
12${fan_functional} ${1}
13${fan_nonfunctional} ${0}
14
15# Criteria for a fan at maximum speed.
16${max_speed}= ${10400}
17
18
Steven Sombar6b280142018-02-12 10:45:13 -060019*** Keywords ***
20
Steven Sombar6b280142018-02-12 10:45:13 -060021Is Water Cooled
22 [Documentation] Return 1 if system is water cooled, 0 othersise.
23
24 ${water_cooled}= Read Attribute
Steven Sombaraaaab222018-12-19 13:16:23 -060025 ... ${HOST_INVENTORY_URI}system/chassis WaterCooled
George Keishing409df052024-01-17 22:36:14 +053026 RETURN ${water_cooled}
Steven Sombar6b280142018-02-12 10:45:13 -060027
28
Steven Sombar43d6ba32018-02-16 11:25:09 -060029Get Fan Names
Steven Sombar1e656462018-07-13 14:04:27 -050030 [Documentation] Get the names of the fans marked present in inventory.
Steven Sombar43d6ba32018-02-16 11:25:09 -060031 [Arguments] ${fan_names}
32 # This keyword populates the fan_names list with the names of
33 # fans present in inventory e.g. fan0, fan2, fan3.
Steven Sombar6b280142018-02-12 10:45:13 -060034
Steven Sombar43d6ba32018-02-16 11:25:09 -060035 # Description of Argument(s):
36 # fan_names The list of fan names to which new fan names are to be
37 # added to. This list is returned to the caller.
38
Steven Sombaraaaab222018-12-19 13:16:23 -060039 ${fan_uris}= Get Endpoint Paths ${HOST_INVENTORY_URI}system fan
Marissa Garza9778eb22020-06-30 13:21:07 -050040 FOR ${fan_uri} IN @{fan_uris}
41 ${fan_properties}= Read Properties ${fan_uri}
42 ${fan_present}= Get Variable Value ${fan_properties['Present']} 0
43 ${fan_functional}= Get Variable Value
44 ... ${fan_properties['Functional']} 0
45 Continue For Loop If ${fan_present} == 0 or ${fan_functional} == 0
46 ${remaining_uri} ${fan_name}= Split Path ${fan_uri}
47 Append To List ${fan_names} ${fan_name}
48 END
Steven Sombar43d6ba32018-02-16 11:25:09 -060049
George Keishing409df052024-01-17 22:36:14 +053050 RETURN ${fan_names}
Steven Sombar43d6ba32018-02-16 11:25:09 -060051
52
53Verify System Error Indication Due To Fans
54 [Documentation] Verify enclosure LEDs are on and there's an error log.
55
56 # Both enclosure LEDs should now be On.
57 Verify Front And Rear LED State On
58
59 # An error log should now exist.
60 Error Logs Should Exist
61
62
63Verify Front And Rear LED State
64 [Documentation] Check state of the front and rear enclsure fault LEDs.
65 [Arguments] ${state}
66 # Both LEDs should be in the specified state. If not fail the test case.
67
68 # Description of Argument(s):
69 # state The state to check for, either 'Off' or 'On'.
70
71 ${front_fault}= Get System LED State front_fault
72 ${rear_fault}= Get System LED State rear_fault
Steven Sombar1508aff2018-04-06 12:53:42 -050073
Sridevi Rameshe40d8f82025-11-05 03:20:32 -060074 IF '${front_fault}' != '${state}' or '${rear_fault}' != '${state}'
Steven Sombar43d6ba32018-02-16 11:25:09 -060075 ... Fail msg=Expecting both enclosure LEDs to be ${state}.
76
Steven Sombar43d6ba32018-02-16 11:25:09 -060077Set Fan State
78 [Documentation] Set the fan state, either functional or non-functional.
79 [Arguments] ${fan_name} ${fan_state}
80
81 # Description of Argument(s):
82 # fan_name The name of the fan, e.g. "fan2".
83 # fan_state The state to set, 1 for functional, 2 for non-functional.
84
85 ${valueDict}= Create Dictionary data=${fan_state}
86 Write Attribute
87 ... ${HOST_INVENTORY_URI}system/chassis/motherboard/${fan_name}
88 ... Functional data=${valueDict}
89
90
Steven Sombar1508aff2018-04-06 12:53:42 -050091Set Fan Target Speed
92 [Documentation] Set the target speed of a fan.
93 [Arguments] ${fan_name} ${fan_speed}
94
95 # Description of argument(s):
96 # fan_name The name of the fan (e.g. "fan0").
97 # fan_speed The target speed to set (e.g. "9000").
98
99 ${valueDict}= Create Dictionary data=${fan_speed}
100 Write Attribute ${SENSORS_URI}fan_tach/${fan_name}_0
101 ... Target data=${valueDict}
102
103
Steven Sombar43d6ba32018-02-16 11:25:09 -0600104Get Target Speed Of Fans
Steven Sombar1508aff2018-04-06 12:53:42 -0500105 [Documentation] Return the maximum target speed of the system fans.
Steven Sombar43d6ba32018-02-16 11:25:09 -0600106
107 ${max_target}= Set Variable 0
108 ${paths}= Get Endpoint Paths ${SENSORS_URI}fan_tach/ 0
Marissa Garza20ccfc72020-06-19 12:51:10 -0500109 FOR ${path} IN @{paths}
110 ${response}= OpenBMC Get Request ${path}
George Keishingfbd67002022-08-01 11:24:03 -0500111 ${target_speed}= Set Variable ${response.json()["data"]["Target"]}
Sridevi Rameshe40d8f82025-11-05 03:20:32 -0600112 ${max_target}= Set Variable If ${target_speed} > ${max_target}
113 ... ${target_speed} ${max_target}
Marissa Garza20ccfc72020-06-19 12:51:10 -0500114 END
George Keishing409df052024-01-17 22:36:14 +0530115 RETURN ${max_target}
Steven Sombar6b280142018-02-12 10:45:13 -0600116
117
Steven Sombar1508aff2018-04-06 12:53:42 -0500118Get Target And Blade Speeds
119 [Documentation] Return the fan target speed setting, the speed of the
120 ... fan's clockwise blade, and the speed of the counter-clockwise blade.
121 # Each fan unit has two counter-rotating fan blades
122 # One blade is expected to be moving but the other blade may not be
123 # moving whenever the fan unit is transitioning to a new target speed.
124 [Arguments] ${fan_name}
125
126 # Description of argument(s):
127 # fan_name The name of a fan (e.g. "fan0")
128
129 # Get the fan target speed and the clockwise blade speed.
130 ${path}= Catenate ${SENSORS_URI}fan_tach/${fan_name}_0
131 ${response}= OpenBMC Get Request ${path}
George Keishingfbd67002022-08-01 11:24:03 -0500132 ${fan_clockwise_speed}= Set Variable ${response.json()["data"]["Value"]}
133 ${target_speed}= Set Variable ${response.json["data"]["Target"]}
Steven Sombar1508aff2018-04-06 12:53:42 -0500134
135 # Get the counter-clockwise blade speed.
136 ${path}= Catenate ${SENSORS_URI}fan_tach/${fan_name}_1
137 ${response}= OpenBMC Get Request ${path}
George Keishingfbd67002022-08-01 11:24:03 -0500138 ${fan_counterclockwise_speed}= Set Variable ${response.json()["data"]["Value"]}
Steven Sombar1508aff2018-04-06 12:53:42 -0500139
George Keishing409df052024-01-17 22:36:14 +0530140 RETURN ${target_speed} ${fan_clockwise_speed}
Steven Sombar1508aff2018-04-06 12:53:42 -0500141 ... ${fan_counterclockwise_speed}
142
143
144Get Fan Target And Speed
145 [Documentation] Return the fan target speed setting and the
146 ... speed of the fastest blade.
147 [Arguments] ${fan_name}
148
149 # Description of argument(s):
150 # fan_name The name of a fan (e.g. "fan0")
151
152 ${target_speed} ${clockwise_speed} ${counterclockwise_speed}=
153 ... Get Target And Blade Speeds ${fan_name}
Sridevi Rameshe40d8f82025-11-05 03:20:32 -0600154 ${blade_speed}= Set Variable If ${clockwise_speed} > ${counterclockwise_speed}
155 ... ${clockwise_speed} ${counterclockwise_speed}
George Keishing409df052024-01-17 22:36:14 +0530156 RETURN ${target_speed} ${blade_speed}
Steven Sombar1508aff2018-04-06 12:53:42 -0500157
158
159Set Fan Daemon State
160 [Documentation] Set the state of the fan control service.
161 [Arguments] ${state}
162
163 # Description of argument(s):
164 # state The desired state of the service, usually
165 # "start", "stop", or "restart".
166
167 ${cmd}= Catenate systemctl ${state} phosphor-fan-control@0.service
168 ${stdout} ${stderr} ${rc}= BMC Execute Command ${cmd}
169
170
Steven Sombar6b280142018-02-12 10:45:13 -0600171Verify Minimum Number Of Fans With Cooling Type
172 [Documentation] Verify minimum number of fans.
Steven Sombar43d6ba32018-02-16 11:25:09 -0600173 [Arguments] ${num_fans} ${water_cooled}
Steven Sombar6b280142018-02-12 10:45:13 -0600174
175 # Description of argument(s):
Steven Sombar43d6ba32018-02-16 11:25:09 -0600176 # num_fans The number of fans present in the system.
Steven Sombar6b280142018-02-12 10:45:13 -0600177 # water_cooled The value 1 if the system is water cooled,
Steven Sombar43d6ba32018-02-16 11:25:09 -0600178 # 0 if air cooled.
Steven Sombar6b280142018-02-12 10:45:13 -0600179
180 # For a water cooled system.
181 ${min_fans_water}= Set Variable 2
182
183 # For an air cooled system.
184 ${min_fans_air}= Set Variable 3
185
Michael Walshc108e422019-03-28 12:27:18 -0500186 Printn
Steven Sombar43d6ba32018-02-16 11:25:09 -0600187 Rpvars num_fans water_cooled
Steven Sombar6b280142018-02-12 10:45:13 -0600188
189 # If water cooled must have at least min_fans_water fans, otherwise
190 # issue Fatal Error and terminate testing.
Sridevi Rameshe40d8f82025-11-05 03:20:32 -0600191 IF ${water_cooled} == 1 and ${num_fans} < ${min_fans_water}
192 ... Fatal Error msg=Water cooled but less than ${min_fans_water} fans present.
Steven Sombar6b280142018-02-12 10:45:13 -0600193
194 # If air cooled must have at least min_fans_air fans.
Sridevi Rameshe40d8f82025-11-05 03:20:32 -0600195 IF ${water_cooled} == 0 and ${num_fans} < ${min_fans_air}
196 ... Fatal Error msg=Air cooled but less than ${min_fans_air} fans present.
Steven Sombar6b280142018-02-12 10:45:13 -0600197
198
199Verify Fan Monitors With State
200 [Documentation] Verify fan monitor daemons in the system state.
Steven Sombar43d6ba32018-02-16 11:25:09 -0600201 [Arguments] ${power_state}
Steven Sombar6b280142018-02-12 10:45:13 -0600202 # The number of monitoring daemons is dependent upon the system
203 # power state. If power is off there should be 0, if power
204 # is on there should be several.
Steven Sombar6b280142018-02-12 10:45:13 -0600205
206 # Description of argument(s):
207 # power_state Power staet of the system, either "On" or "Off"
208
209 ${cmd}= Catenate systemctl list-units | grep phosphor-fan | wc -l
210 ${num_fan_daemons} ${stderr} ${rc}= BMC Execute Command ${cmd}
211
212 Rpvars power_state num_fan_daemons
213
214 # Fail if system is On and there are no fan monitors.
Sridevi Rameshe40d8f82025-11-05 03:20:32 -0600215 IF '${power_state}' == 'On' and ${num_fan_daemons} == 0
Steven Sombar6b280142018-02-12 10:45:13 -0600216 ... Fail msg=No phosphor-fan monitors found at power on.
217
218 # Fail if system is Off and the fan monitors are present.
Sridevi Rameshe40d8f82025-11-05 03:20:32 -0600219 IF '${power_state}' == 'Off' and ${num_fan_daemons} != 0
Steven Sombar6b280142018-02-12 10:45:13 -0600220 ... Fail msg=Phosphor-fan monitors found at power off.
Steven Sombar47ac2f42019-04-17 21:13:43 -0500221
Steven Sombar47ac2f42019-04-17 21:13:43 -0500222Get Fan Count And Names
223 [Documentation] Return the number of fans and the fan names.
224
225 # The @{fan_names} list holds the names of the fans in the system.
226 @{fan_names} Create List
227 ${fan_names}= Get Fan Names ${fan_names}
228
229 ${number_of_fans}= Get Length ${fan_names}
230
George Keishing409df052024-01-17 22:36:14 +0530231 RETURN ${number_of_fans} ${fan_names}
Steven Sombar47ac2f42019-04-17 21:13:43 -0500232
233
Steven Sombar741e99d2019-05-07 07:20:51 -0500234
Steven Sombar47ac2f42019-04-17 21:13:43 -0500235Reset Fans
236 [Documentation] Set the fans to functional state.
237 # Set state of fans to functional by writing 1 to the Functional
238 # attribute of each fan in the @{fan_names} list. If @{fan_names}
239 # is empty nothing is done.
240 [Arguments] ${fan_names}
241
242 # Description of Argument(s):
243 # fan_names A list containing the names of the fans (e.g. fan0
244 # fan2 fan3).
245
Marissa Garza20ccfc72020-06-19 12:51:10 -0500246 FOR ${fan_name} IN @{fan_names}
247 Set Fan State ${fan_name} ${fan_functional}
248 END
Steven Sombar47ac2f42019-04-17 21:13:43 -0500249
250Verify Fan Speed
251 [Documentation] Verify fans are running at or near target speed.
252 [Arguments] ${tolerance} ${fan_names}
253
254 # Description of argument(s):
255 # tolerance The speed tolerance criteria.
256 # A tolerance value of .15 means that the fan's speed
257 # should be within 15% of its set target speed.
258 # Fans may be accelerating to meet a new target, so
259 # allow .10 extra.
260 # fan_names A list containing the names of the fans (e.g. fan0 fan1).
261
262 # Compare the fan's speed with its target speed.
Marissa Garza20ccfc72020-06-19 12:51:10 -0500263 FOR ${fan_name} IN @{fan_names}
264 ${target_speed} ${fan_speed}= Get Fan Target And Speed ${fan_name}
265 Rpvars fan_name target_speed fan_speed
266 # Calculate tolerance, which is a % of the target speed.
267 ${tolerance_value}= Evaluate ${tolerance}*${target_speed}
268 # Calculate upper and lower speed limits.
269 ${max_limit}= Evaluate ${target_speed}+${tolerance_value}
270 ${min_limit}= Evaluate ${target_speed}-${tolerance_value}
Sridevi Rameshe40d8f82025-11-05 03:20:32 -0600271 IF ${fan_speed} < ${min_limit} or ${fan_speed} > ${max_limit}
Marissa Garza20ccfc72020-06-19 12:51:10 -0500272 ... Fail msg=${fan_name} speed of ${fan_speed} is out of range.
273 END
Steven Sombar47ac2f42019-04-17 21:13:43 -0500274
275Verify Direct Fan Control
276 [Documentation] Verify direct control of fans.
Steven Sombar741e99d2019-05-07 07:20:51 -0500277 [Arguments] ${max_speed} ${min_speed}
Steven Sombar47ac2f42019-04-17 21:13:43 -0500278 ... ${minutes_to_stabilize} ${number_of_fans} ${fan_names}
279
280 # Overview:
281 # Turn off BMC's fan control daemon, then test to confirm
282 # that fans can be controlled manually.
283 # The app that takes data from sysfs and updates dbus is named hwmon.
284 # Verify hwmon functionality by comparing with what's on dbus
285 # (/xyz/openbmc_project/sensors/fan_tach/fan0_0, fan0_1, etc.)
286 # with what's in the BMC's file system at
287 # /sys/class/hwmon/hwmon9/fan*_input.
288
289 # Description of argument(s):
Steven Sombar741e99d2019-05-07 07:20:51 -0500290 # max_speed Integer value of maximum fan speed.
Steven Sombar47ac2f42019-04-17 21:13:43 -0500291 # min_speed Integer value of minimum speed.
292 # minutes_to_stabilize Time to wait for fan daemons to
293 # stabilize fan operation after
294 # tests (e.g. "4").
295 # number_of_fans The number of fans in the system.
296 # fan_names A list containing the names of the
297 # fans (e.g. fan0 fan1).
298
299 # Login to BMC and disable the fan daemon. Disabling the daemon sets
300 # manual mode.
301 Open Connection And Log In
302 Set Fan Daemon State stop
303
304 # For each fan, set a new target speed and wait for the fan to
305 # accelerate. Then check that the fan is running near that speed.
Marissa Garza20ccfc72020-06-19 12:51:10 -0500306 FOR ${fan_name} IN @{fan_names}
307 Set Fan Target Speed ${fan_name} ${max_speed}
308 Run Key U Sleep \ 60s
309 ${target_speed} ${cw_speed} ${ccw_speed}=
310 ... Get Target And Blade Speeds ${fan_name}
311 Rpvars fan_name target_speed cw_speed ccw_speed
Sridevi Rameshe40d8f82025-11-05 03:20:32 -0600312 IF ${cw_speed} < ${min_speed} or ${ccw_speed} < ${min_speed}
Marissa Garza20ccfc72020-06-19 12:51:10 -0500313 ... Fail msg=${fan_name} failed manual speed test.
314 END
Steven Sombar47ac2f42019-04-17 21:13:43 -0500315
316 # Check the fan speeds in the BMC file system.
317
318 # Get the location of the fan hwmon.
319 ${controller_path} ${stderr} ${rc}= BMC Execute Command
320 ... grep -ir max31785a /sys/class/hwmon/hwmon* | grep name
321 # E.g., controller_path=/sys/class/hwmon/hwmon10/name:max31785a.
322
323 ${hwmon_path} ${file_name}= Split Path ${controller_path}
324 # E.g., /sys/class/hwmon/hwmon10 or /sys/class/hwmon/hwmon9.
325
326 Rpvars controller_path hwmon_path
327
328 # Run the BMC command which gets fan speeds from the file system.
329 ${cmd}= Catenate cat ${hwmon_path}/fan*_input
330 ${stdout} ${stderr} ${rc}=
331 ... BMC Execute Command ${cmd}
332
333 # Convert output to integer values.
334 ${speeds}= Evaluate map(int, $stdout.split(${\n}))
335 Rpvars speeds
336 # Count the number of speeds > ${min_speed}.
337 ${count}= Set Variable ${0}
Marissa Garza20ccfc72020-06-19 12:51:10 -0500338 FOR ${speed} IN @{speeds}
Sridevi Rameshe40d8f82025-11-05 03:20:32 -0600339 ${count}= Set Variable If ${speed} > ${min_speed}
Marissa Garza20ccfc72020-06-19 12:51:10 -0500340 ... Evaluate ${count}+1 ELSE Set Variable ${count}
341 # Because each fan has two rotating fan blades, the count should be
342 # equual to 2*${number_of_fans}. On water-cooled systems some
343 # speeds may be reported by hwmon as 0. That is expected,
344 # and the number_of_fans reported in the system will be less.
345 END
Steven Sombar47ac2f42019-04-17 21:13:43 -0500346 ${fail_test}= Evaluate (2*${number_of_fans})-${count}
347
348 # Re-enable the fan daemon
349 Set Fan Daemon State restart
350
Sridevi Rameshe40d8f82025-11-05 03:20:32 -0600351 IF ${fail_test} > ${0} Fail msg=hwmon did not properly report fan speeds.
Steven Sombar47ac2f42019-04-17 21:13:43 -0500352
353 # Wait for the daemon to take control and gracefully set fan speeds
354 # back to normal.
355 ${msg}= Catenate Waiting ${minutes_to_stabilize} minutes
356 ... for fan daemon to stabilize fans.
357 Print Timen ${msg}
358 Run Key U Sleep \ ${minutes_to_stabilize}m
359
360
361Verify Fan Speed Increase
362 [Documentation] Verify that the speed of working fans increase when
363 ... one fan is marked as disabled.
364 # A non-functional fan should cause an error log and
365 # an enclosure LED will light. The other fans should speed up.
366 [Arguments] ${fan_names}
367
368 # Description of argument(s):
369 # fan_names A list containing the names of the fans (e.g. fan0 fan1).
370
371 # Allow system_response_time before checking if there was a
372 # response by the system to an applied fault.
373 ${system_response_time}= Set Variable 60s
374
375 # Choose a fan to test with, e.g., fan0.
376 ${test_fan_name}= Get From List ${fan_names} 0
377
378 ${initial_speed}= Get Target Speed Of Fans
379 Rpvars test_fan_name initial_speed
380
381 # If initial speed is not already at maximum, set expect_increase.
382 # This flag is used later to determine if speed checking is
383 # to be done or not.
Sridevi Rameshe40d8f82025-11-05 03:20:32 -0600384 ${expect_increase}= Set Variable If ${initial_speed} < ${max_speed} 1 0
Steven Sombar47ac2f42019-04-17 21:13:43 -0500385
386 Set Fan State ${test_fan_name} ${fan_nonfunctional}
387
Steven Sombar47ac2f42019-04-17 21:13:43 -0500388 Run Key U Sleep \ ${system_response_time}
389
390 # A heavily loaded system may have powered-off.
391 ${host_state}= Get Host State
392 Rpvars host_state
Sridevi Rameshe40d8f82025-11-05 03:20:32 -0600393 IF 'Running' != '${host_state}' Pass Execution
Steven Sombar47ac2f42019-04-17 21:13:43 -0500394 ... msg=System shutdown so skipping remainder of test.
395
396 ${new_fan_speed}= Get Target Speed Of Fans
397 Rpvars expect_increase initial_speed new_fan_speed
398
399 # Fail if current fan speed did not increase past the initial
400 # speed, but do this check only if not at maximum speed to begin with.
Steven Sombar47ac2f42019-04-17 21:13:43 -0500401
Sridevi Rameshe40d8f82025-11-05 03:20:32 -0600402 IF ${expect_increase} == 1 and ${new_fan_speed} < ${initial_speed}
403 ... Fail msg=Remaining fans did not increase speed with loss of one fan.
Steven Sombar47ac2f42019-04-17 21:13:43 -0500404
405
406Verify System Shutdown Due To Fans
407 [Documentation] Shut down when not enough fans.
408 [Arguments] ${fan_names}
409
410 # Description of argument(s):
411 # fan_names A list containing the names of the fans (e.g. fan0 fan1).
412
413 ${wait_after_poweroff}= Set Variable 15s
414
Steven Sombar47ac2f42019-04-17 21:13:43 -0500415 # Set fans to be non-functional.
Marissa Garza20ccfc72020-06-19 12:51:10 -0500416 FOR ${fan_name} IN @{fan_names}
417 Set Fan State ${fan_name} ${fan_nonfunctional}
418 END
Steven Sombar47ac2f42019-04-17 21:13:43 -0500419
420 # System should notice the non-functional fans and power-off.
421 # The Wait For PowerOff keyword will time-out and report
422 # an error if power off does not happen within a reasonable time.
423 Wait For PowerOff