| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 1 | *** Settings *** | 
| Steven Sombar | 43d6ba3 | 2018-02-16 11:25:09 -0600 | [diff] [blame] | 2 | Documentation  Utilities for fan tests. | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 3 |  | 
| Steven Sombar | 43d6ba3 | 2018-02-16 11:25:09 -0600 | [diff] [blame] | 4 | Library        ../lib/bmc_ssh_utils.py | 
|  | 5 | Resource       ../lib/openbmc_ffdc_utils.robot | 
|  | 6 | Variables      ../data/variables.py | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 7 |  | 
|  | 8 | *** Keywords *** | 
|  | 9 |  | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 10 | Is Water Cooled | 
|  | 11 | [Documentation]  Return 1 if system is water cooled, 0 othersise. | 
|  | 12 |  | 
|  | 13 | ${water_cooled}=  Read Attribute | 
|  | 14 | ...  ${HOST_INVENTORY_URI}/system/chassis  WaterCooled | 
|  | 15 | [Return]  ${water_cooled} | 
|  | 16 |  | 
|  | 17 |  | 
| Steven Sombar | 43d6ba3 | 2018-02-16 11:25:09 -0600 | [diff] [blame] | 18 | Get Fan Names | 
|  | 19 | [Documentation]  Get the names of fans marked present in inventory. | 
|  | 20 | [Arguments]  ${fan_names} | 
|  | 21 | # This keyword populates the fan_names list with the names of | 
|  | 22 | # fans present in inventory e.g. fan0, fan2, fan3. | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 23 |  | 
| Steven Sombar | 43d6ba3 | 2018-02-16 11:25:09 -0600 | [diff] [blame] | 24 | # Description of Argument(s): | 
|  | 25 | # fan_names   The list of fan names to which new fan names are to be | 
|  | 26 | #             added to.  This list is returned to the caller. | 
|  | 27 |  | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 28 | ${fan_uris}=  Get Endpoint Paths  ${HOST_INVENTORY_URI}/system  fan | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 29 | : FOR  ${fan_uri}  IN  @{fan_uris} | 
| Steven Sombar | 43d6ba3 | 2018-02-16 11:25:09 -0600 | [diff] [blame] | 30 | \  ${fan_properties}=  Read Properties  ${fan_uri} | 
|  | 31 | \  Continue For Loop If  ${fan_properties['Present']} != 1 | 
|  | 32 | \  ${remaining_uri}  ${fan_name}=  Split Path  ${fan_uri} | 
|  | 33 | \  Append To List  ${fan_names}  ${fan_name} | 
|  | 34 |  | 
|  | 35 | [Return]  ${fan_names} | 
|  | 36 |  | 
|  | 37 |  | 
|  | 38 | Verify System Error Indication Due To Fans | 
|  | 39 | [Documentation]  Verify enclosure LEDs are on and there's an error log. | 
|  | 40 |  | 
|  | 41 | # Both enclosure LEDs should now be On. | 
|  | 42 | Verify Front And Rear LED State  On | 
|  | 43 |  | 
|  | 44 | # An error log should now exist. | 
|  | 45 | Error Logs Should Exist | 
|  | 46 |  | 
|  | 47 |  | 
|  | 48 | Verify Front And Rear LED State | 
|  | 49 | [Documentation]  Check state of the front and rear enclsure fault LEDs. | 
|  | 50 | [Arguments]  ${state} | 
|  | 51 | # Both LEDs should be in the specified state.  If not fail the test case. | 
|  | 52 |  | 
|  | 53 | # Description of Argument(s): | 
|  | 54 | # state    The state to check for, either 'Off' or 'On'. | 
|  | 55 |  | 
|  | 56 | ${front_fault}=  Get System LED State  front_fault | 
|  | 57 | ${rear_fault}=  Get System LED State  rear_fault | 
| Steven Sombar | 1508aff | 2018-04-06 12:53:42 -0500 | [diff] [blame] | 58 |  | 
| Steven Sombar | 43d6ba3 | 2018-02-16 11:25:09 -0600 | [diff] [blame] | 59 | Run Keyword If | 
|  | 60 | ...  '${front_fault}' != '${state}' or '${rear_fault}' != '${state}' | 
|  | 61 | ...  Fail  msg=Expecting both enclosure LEDs to be ${state}. | 
|  | 62 |  | 
|  | 63 |  | 
|  | 64 | Set Fan State | 
|  | 65 | [Documentation]  Set the fan state, either functional or non-functional. | 
|  | 66 | [Arguments]  ${fan_name}  ${fan_state} | 
|  | 67 |  | 
|  | 68 | # Description of Argument(s): | 
|  | 69 | # fan_name     The name of the fan, e.g. "fan2". | 
|  | 70 | # fan_state    The state to set, 1 for functional, 2 for non-functional. | 
|  | 71 |  | 
|  | 72 | ${valueDict}=  Create Dictionary  data=${fan_state} | 
|  | 73 | Write Attribute | 
|  | 74 | ...  ${HOST_INVENTORY_URI}system/chassis/motherboard/${fan_name} | 
|  | 75 | ...  Functional  data=${valueDict} | 
|  | 76 |  | 
|  | 77 |  | 
| Steven Sombar | 1508aff | 2018-04-06 12:53:42 -0500 | [diff] [blame] | 78 | Set Fan Target Speed | 
|  | 79 | [Documentation]  Set the target speed of a fan. | 
|  | 80 | [Arguments]  ${fan_name}  ${fan_speed} | 
|  | 81 |  | 
|  | 82 | # Description of argument(s): | 
|  | 83 | # fan_name    The name of the fan (e.g. "fan0"). | 
|  | 84 | # fan_speed   The target speed to set (e.g. "9000"). | 
|  | 85 |  | 
|  | 86 | ${valueDict}=  Create Dictionary  data=${fan_speed} | 
|  | 87 | Write Attribute  ${SENSORS_URI}fan_tach/${fan_name}_0 | 
|  | 88 | ...  Target  data=${valueDict} | 
|  | 89 |  | 
|  | 90 |  | 
| Steven Sombar | 43d6ba3 | 2018-02-16 11:25:09 -0600 | [diff] [blame] | 91 | Get Target Speed Of Fans | 
| Steven Sombar | 1508aff | 2018-04-06 12:53:42 -0500 | [diff] [blame] | 92 | [Documentation]  Return the maximum target speed of the system fans. | 
| Steven Sombar | 43d6ba3 | 2018-02-16 11:25:09 -0600 | [diff] [blame] | 93 |  | 
|  | 94 | ${max_target}=  Set Variable  0 | 
|  | 95 | ${paths}=  Get Endpoint Paths  ${SENSORS_URI}fan_tach/  0 | 
|  | 96 | :FOR  ${path}  IN  @{paths} | 
|  | 97 | \  ${response}=  OpenBMC Get Request  ${path} | 
|  | 98 | \  ${json}=  To JSON  ${response.content} | 
|  | 99 | \  ${target_speed}=  Set Variable  ${json["data"]["Target"]} | 
|  | 100 | \  ${max_target}=  Run Keyword If  ${target_speed} > ${max_target} | 
|  | 101 | ...  Set Variable  ${target_speed}  ELSE  Set Variable  ${max_target} | 
|  | 102 | [Return]  ${max_target} | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 103 |  | 
|  | 104 |  | 
| Steven Sombar | 1508aff | 2018-04-06 12:53:42 -0500 | [diff] [blame] | 105 | Get Target And Blade Speeds | 
|  | 106 | [Documentation]  Return the fan target speed setting, the speed of the | 
|  | 107 | ...  fan's clockwise blade, and the speed of the counter-clockwise blade. | 
|  | 108 | # Each fan unit has two counter-rotating fan blades | 
|  | 109 | # One blade is expected to be moving but the other blade may not be | 
|  | 110 | # moving whenever the fan unit is transitioning to a new target speed. | 
|  | 111 | [Arguments]  ${fan_name} | 
|  | 112 |  | 
|  | 113 | # Description of argument(s): | 
|  | 114 | # fan_name       The name of a fan (e.g. "fan0") | 
|  | 115 |  | 
|  | 116 | # Get the fan target speed and the clockwise blade speed. | 
|  | 117 | ${path}=  Catenate  ${SENSORS_URI}fan_tach/${fan_name}_0 | 
|  | 118 | ${response}=  OpenBMC Get Request  ${path} | 
|  | 119 | ${json}=  To JSON  ${response.content} | 
|  | 120 | ${fan_clockwise_speed}=  Set Variable  ${json["data"]["Value"]} | 
|  | 121 | ${target_speed}=  Set Variable  ${json["data"]["Target"]} | 
|  | 122 |  | 
|  | 123 | # Get the counter-clockwise blade speed. | 
|  | 124 | ${path}=  Catenate  ${SENSORS_URI}fan_tach/${fan_name}_1 | 
|  | 125 | ${response}=  OpenBMC Get Request  ${path} | 
|  | 126 | ${json}=  To JSON  ${response.content} | 
|  | 127 | ${fan_counterclockwise_speed}=  Set Variable  ${json["data"]["Value"]} | 
|  | 128 |  | 
|  | 129 | [Return]  ${target_speed}  ${fan_clockwise_speed} | 
|  | 130 | ...  ${fan_counterclockwise_speed} | 
|  | 131 |  | 
|  | 132 |  | 
|  | 133 | Get Fan Target And Speed | 
|  | 134 | [Documentation]  Return the fan target speed setting and the | 
|  | 135 | ...  speed of the fastest blade. | 
|  | 136 | [Arguments]  ${fan_name} | 
|  | 137 |  | 
|  | 138 | # Description of argument(s): | 
|  | 139 | # fan_name       The name of a fan (e.g. "fan0") | 
|  | 140 |  | 
|  | 141 | ${target_speed}  ${clockwise_speed}  ${counterclockwise_speed}= | 
|  | 142 | ...  Get Target And Blade Speeds  ${fan_name} | 
|  | 143 | ${blade_speed}=  Run Keyword If | 
|  | 144 | ...  ${clockwise_speed} > ${counterclockwise_speed} | 
|  | 145 | ...  Set Variable  ${clockwise_speed}  ELSE | 
|  | 146 | ...  Set Variable  ${counterclockwise_speed} | 
|  | 147 | [Return]  ${target_speed}  ${blade_speed} | 
|  | 148 |  | 
|  | 149 |  | 
|  | 150 | Set Fan Daemon State | 
|  | 151 | [Documentation]  Set the state of the fan control service. | 
|  | 152 | [Arguments]  ${state} | 
|  | 153 |  | 
|  | 154 | # Description of argument(s): | 
|  | 155 | # state     The desired state of the service, usually | 
|  | 156 | #           "start", "stop", or "restart". | 
|  | 157 |  | 
|  | 158 | ${cmd}=  Catenate  systemctl  ${state}  phosphor-fan-control@0.service | 
|  | 159 | ${stdout}  ${stderr}  ${rc}=  BMC Execute Command  ${cmd} | 
|  | 160 |  | 
|  | 161 |  | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 162 | Verify Minimum Number Of Fans With Cooling Type | 
|  | 163 | [Documentation]  Verify minimum number of fans. | 
| Steven Sombar | 43d6ba3 | 2018-02-16 11:25:09 -0600 | [diff] [blame] | 164 | [Arguments]  ${num_fans}  ${water_cooled} | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 165 |  | 
|  | 166 | # Description of argument(s): | 
| Steven Sombar | 43d6ba3 | 2018-02-16 11:25:09 -0600 | [diff] [blame] | 167 | # num_fans       The number of fans present in the system. | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 168 | # water_cooled   The value 1 if the system is water cooled, | 
| Steven Sombar | 43d6ba3 | 2018-02-16 11:25:09 -0600 | [diff] [blame] | 169 | #                0 if air cooled. | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 170 |  | 
|  | 171 | # For a water cooled system. | 
|  | 172 | ${min_fans_water}=  Set Variable  2 | 
|  | 173 |  | 
|  | 174 | # For an air cooled system. | 
|  | 175 | ${min_fans_air}=  Set Variable  3 | 
|  | 176 |  | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 177 | Rprintn | 
| Steven Sombar | 43d6ba3 | 2018-02-16 11:25:09 -0600 | [diff] [blame] | 178 | Rpvars  num_fans  water_cooled | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 179 |  | 
|  | 180 | # If water cooled must have at least min_fans_water fans, otherwise | 
|  | 181 | # issue Fatal Error and terminate testing. | 
|  | 182 | Run Keyword If  ${water_cooled} == 1 and ${num_fans} < ${min_fans_water} | 
|  | 183 | ...  Fatal Error | 
|  | 184 | ...  msg=Water cooled but less than ${min_fans_water} fans present. | 
|  | 185 |  | 
|  | 186 | # If air cooled must have at least min_fans_air fans. | 
|  | 187 | Run Keyword If  ${water_cooled} == 0 and ${num_fans} < ${min_fans_air} | 
|  | 188 | ...  Fatal Error | 
|  | 189 | ...  msg=Air cooled but less than ${min_fans_air} fans present. | 
|  | 190 |  | 
|  | 191 |  | 
|  | 192 | Verify Fan Monitors With State | 
|  | 193 | [Documentation]  Verify fan monitor daemons in the system state. | 
| Steven Sombar | 43d6ba3 | 2018-02-16 11:25:09 -0600 | [diff] [blame] | 194 | [Arguments]  ${power_state} | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 195 | # The number of monitoring daemons is dependent upon the system | 
|  | 196 | # power state.  If power is off there should be 0, if power | 
|  | 197 | # is on there should be several. | 
| Steven Sombar | 6b28014 | 2018-02-12 10:45:13 -0600 | [diff] [blame] | 198 |  | 
|  | 199 | # Description of argument(s): | 
|  | 200 | # power_state   Power staet of the system, either "On" or "Off" | 
|  | 201 |  | 
|  | 202 | ${cmd}=  Catenate  systemctl list-units | grep phosphor-fan | wc -l | 
|  | 203 | ${num_fan_daemons}  ${stderr}  ${rc}=  BMC Execute Command  ${cmd} | 
|  | 204 |  | 
|  | 205 | Rpvars  power_state  num_fan_daemons | 
|  | 206 |  | 
|  | 207 | # Fail if system is On and there are no fan monitors. | 
|  | 208 | Run Keyword If  '${power_state}' == 'On' and ${num_fan_daemons} == 0 | 
|  | 209 | ...  Fail  msg=No phosphor-fan monitors found at power on. | 
|  | 210 |  | 
|  | 211 | # Fail if system is Off and the fan monitors are present. | 
|  | 212 | Run Keyword If  '${power_state}' == 'Off' and ${num_fan_daemons} != 0 | 
|  | 213 | ...  Fail  msg=Phosphor-fan monitors found at power off. |