1*** Settings ***
2
3Documentation    Module to test IPMI asset tag functionality.
4Resource         ../lib/ipmi_client.robot
5Resource         ../lib/openbmc_ffdc.robot
6Resource         ../lib/bmc_network_utils.robot
7Resource         ../lib/energy_scale_utils.robot
8Variables        ../data/ipmi_raw_cmd_table.py
9Variables        ../data/ipmi_variable.py
10Library          ../lib/bmc_network_utils.py
11Library          ../lib/ipmi_utils.py
12
13Suite Setup      IPMI General Test Suite Setup
14Test Teardown    FFDC On Test Case Fail
15
16Test Tags       IPMI_General
17
18*** Test Cases ***
19
20Test Get Self Test Results via IPMI Raw Command
21    [Documentation]  Get self test results via IPMI raw command and verify the output.
22    [Tags]  Test_Get_Self_Test_Results_via_IPMI_Raw_Command
23
24    ${resp}=  Run IPMI Command  ${IPMI_RAW_CMD['Self_Test_Results']['Get'][0]}
25
26    # 55h = No error. All Self Tests Passed.
27    # 56h = Self Test function not implemented in this controller.
28    Should Contain Any  ${resp}  55 00  56 00
29
30
31Test Get Device GUID Via IPMI Raw Command
32    [Documentation]  Get device GUID via IPMI raw command and verify it using Redfish.
33    [Tags]  Test_Get_Device_GUID_Via_IPMI_Raw_Command
34    [Teardown]  Run Keywords  Redfish.Logout  AND  FFDC On Test Case Fail
35    # Get GUIDS via IPMI.
36    # This should match the /redfish/v1/Managers/${MANAGER_ID}'s UUID data.
37    ${guids}=  Run IPMI Command  ${IPMI_RAW_CMD['Device GUID']['Get'][0]}
38    # Reverse the order and remove space delims.
39    ${guids}=  Split String  ${guids}
40    Reverse List  ${guids}
41    ${guids}=  Evaluate  "".join(${guids})
42
43    Redfish.Login
44    ${uuid}=  Redfish.Get Attribute  /redfish/v1/Managers/${MANAGER_ID}  UUID
45    ${uuid}=  Remove String  ${uuid}  -
46
47    Rprint Vars  guids  uuid
48    Valid Value  uuid  ['${guids}']
49
50
51Verify Get Channel Info via IPMI
52    [Documentation]  Verify get channel info via IPMI.
53    [Tags]  Verify_Get_Channel_Info_via_IPMI
54
55    # Get channel info via ipmi command "ipmitool channel info [channel number]".
56    # Verify channel info with files "channel_access_volatile.json", "channel_access_nv.json"
57    # and "channel_config.json" in BMC.
58
59    # Example output from 'Get Channel Info':
60    # channel_info:
61    #   [channel_0x2_info]:
62    #     [channel_medium_type]:                        802.3 LAN
63    #     [channel_protocol_type]:                      IPMB-1.0
64    #     [session_support]:                            multi-session
65    #     [active_session_count]:                       0
66    #     [protocol_vendor_id]:                         7154
67    #   [volatile(active)_settings]:
68    #       [alerting]:                                 enabled
69    #       [per-message_auth]:                         enabled
70    #       [user_level_auth]:                          enabled
71    #       [access_mode]:                              always available
72    #   [Non-Volatile Settings]:
73    #       [alerting]:                                 enabled
74    #       [per-message_auth]:                         enabled
75    #       [user_level_auth]:                          enabled
76    #       [access_mode]:                              always available
77
78    ${channel_info_ipmi}=  Get Channel Info  ${CHANNEL_NUMBER}
79    ${active_channel_config}=  Get Active Channel Config
80    ${channel_volatile_data_config}=  Get Channel Access Config  /run/ipmi/channel_access_volatile.json
81    ${channel_nv_data_config}=  Get Channel Access Config  /var/lib/ipmi/channel_access_nv.json
82
83    Rprint Vars  channel_info_ipmi
84    Rprint Vars  active_channel_config
85    Rprint Vars  channel_volatile_data_config
86    Rprint Vars  channel_nv_data_config
87
88    Valid Value  medium_type_ipmi_conf_map['${channel_info_ipmi['channel_0x${CHANNEL_NUMBER}_info']['channel_medium_type']}']
89    ...  ['${active_channel_config['${CHANNEL_NUMBER}']['channel_info']['medium_type']}']
90
91    Valid Value  protocol_type_ipmi_conf_map['${channel_info_ipmi['channel_0x${CHANNEL_NUMBER}_info']['channel_protocol_type']}']
92    ...  ['${active_channel_config['${CHANNEL_NUMBER}']['channel_info']['protocol_type']}']
93
94    Valid Value  channel_info_ipmi['channel_0x${CHANNEL_NUMBER}_info']['session_support']
95    ...  ['${active_channel_config['${CHANNEL_NUMBER}']['channel_info']['session_supported']}']
96
97    Valid Value  channel_info_ipmi['channel_0x${CHANNEL_NUMBER}_info']['active_session_count']
98    ...  ['${active_channel_config['${CHANNEL_NUMBER}']['active_sessions']}']
99    # IPMI Spec: The IPMI Enterprise Number is: 7154 (decimal)
100    Valid Value  channel_info_ipmi['channel_0x${CHANNEL_NUMBER}_info']['protocol_vendor_id']  ['7154']
101
102    # Verify volatile(active)_settings
103    Valid Value  disabled_ipmi_conf_map['${channel_info_ipmi['volatile(active)_settings']['alerting']}']
104    ...  ['${channel_volatile_data_config['${CHANNEL_NUMBER}']['alerting_disabled']}']
105
106    Valid Value  disabled_ipmi_conf_map['${channel_info_ipmi['volatile(active)_settings']['per-message_auth']}']
107    ...  ['${channel_volatile_data_config['${CHANNEL_NUMBER}']['per_msg_auth_disabled']}']
108
109    Valid Value  disabled_ipmi_conf_map['${channel_info_ipmi['volatile(active)_settings']['user_level_auth']}']
110    ...  ['${channel_volatile_data_config['${CHANNEL_NUMBER}']['user_auth_disabled']}']
111
112    Valid Value  access_mode_ipmi_conf_map['${channel_info_ipmi['volatile(active)_settings']['access_mode']}']
113    ...  ['${channel_volatile_data_config['${CHANNEL_NUMBER}']['access_mode']}']
114
115    # Verify Non-Volatile Settings
116    Valid Value  disabled_ipmi_conf_map['${channel_info_ipmi['non-volatile_settings']['alerting']}']
117    ...  ['${channel_nv_data_config['${CHANNEL_NUMBER}']['alerting_disabled']}']
118
119    Valid Value  disabled_ipmi_conf_map['${channel_info_ipmi['non-volatile_settings']['per-message_auth']}']
120    ...  ['${channel_nv_data_config['${CHANNEL_NUMBER}']['per_msg_auth_disabled']}']
121
122    Valid Value  disabled_ipmi_conf_map['${channel_info_ipmi['non-volatile_settings']['user_level_auth']}']
123    ...  ['${channel_nv_data_config['${CHANNEL_NUMBER}']['user_auth_disabled']}']
124
125    Valid Value  access_mode_ipmi_conf_map['${channel_info_ipmi['non-volatile_settings']['access_mode']}']
126    ...  ['${channel_nv_data_config['${CHANNEL_NUMBER}']['access_mode']}']
127
128
129Test Get Channel Authentication Capabilities via IPMI
130    [Documentation]  Verify channel authentication capabilities via IPMI.
131    [Tags]  Test_Get_Channel_Authentication_Capabilities_via_IPMI
132    [Template]  Verify Channel Auth Capabilities
133
134    FOR  ${channel}  IN   @{active_channel_list}
135        FOR  ${privilege}  IN   4  3  2
136            # Input Channel     Privilege Level
137            ${channel}          ${privilege}
138        END
139    END
140
141
142Test Get Channel Authentication Capabilities IPMI Command For Invalid Channel
143    [Documentation]  Verify get channel authentication capabilities for invalid channel.
144    [Tags]  Test_Get_Channel_Authentication_Capabilities_IPMI_Command_For_Invalid_Channel
145    [Template]  Verify Channel Auth Capabilities For Invalid Channel
146
147    FOR  ${channel}  IN  @{inactive_channel_list}
148        # Input Channel
149        ${channel}
150    END
151
152
153Verify Get Channel Authentication Capabilities IPMI Raw Command With Invalid Data Length
154    [Documentation]  Verify get channel authentication capabilities IPMI raw command with invalid data length.
155    [Tags]  Verify_Get_Channel_Authentication_Capabilities_IPMI_Raw_Command_With_Invalid_Data_Length
156    [Template]  Verify Channel Auth Command For Invalid Data Length
157
158    # Bytes
159    low
160    high
161
162
163Verify Set Session Privilege Level via IPMI Raw Command
164    [Documentation]  Set session privilege with given privilege level and verify the response with
165    ...              expected level.
166    [Tags]  Verify_Set_Session_Privilege_Level_via_IPMI_Raw_Command
167    [Template]  Set Session Privilege Level And Verify
168
169    # privilege_level   expected_level
170    0x00                04
171    0x02                02
172    0x03                03
173    0x04                04
174
175
176Verify Set Invalid Session Privilege Level Via IPMI Raw Command
177    [Documentation]  Verify set invalid session privilege level via IPMI raw command.
178    [Tags]  Verify_Set_Invalid_Session_Privilege_Level_Via_IPMI_Raw_Command
179    [Template]  Set Invalid Session Privilege Level And Verify
180
181    # invalid_privilege_level
182    0x01
183    0x05
184    0x06
185    0x07
186    0x0F
187
188
189Verify Close Session Via IPMI
190    [Documentation]  Verify close session via IPMI.
191    [Tags]  Verify_Close_Session_Via_IPMI
192
193    # The "close session command" can be tested with any out-of-band IPMI command.
194    # When the session is about to close, it will execute the close session command at the end.
195
196    ${cmd}=  Catenate  mc info -vvv 2>&1 | grep "Closed Session"
197    ${cmd_output}=  Run External IPMI Standard Command  ${cmd}
198
199    Should Contain  ${cmd_output}  Closed Session
200
201
202Verify Chassis Identify via IPMI
203    [Documentation]  Set chassis identify using IPMI and verify.
204    [Tags]  Verify_Chassis_Identify_via_IPMI
205    [Setup]  Redfish.Login
206    [Teardown]  Redfish.logout
207
208    # Set to default "chassis identify" and verify that LED blinks for 15s.
209    Run IPMI Standard Command  chassis identify
210    Verify Identify LED State Via Redfish  True
211
212    Sleep  18s
213    Verify Identify LED State Via Redfish  False
214
215    # Set "chassis identify" to 10s and verify that the LED blinks for 10s.
216    Run IPMI Standard Command  chassis identify 10
217    Verify Identify LED State Via Redfish  True
218
219    Sleep  12s
220    Verify Identify LED State Via Redfish  False
221
222
223Verify Chassis Identify Off And Force Identify On via IPMI
224    [Documentation]  Set chassis identify to "off" and "force" using IPMI and verify.
225    [Tags]  Verify_Chassis_Identify_Off_And_Force_Identify_On_via_IPMI
226    [Setup]  Redfish.Login
227    [Teardown]  Redfish.logout
228
229    # Set the LED to "Force Identify On".
230    Run IPMI Standard Command  chassis identify force
231    Verify Identify LED State Via Redfish  True
232
233    # Set "chassis identify" to 0 and verify that the LED turns off.
234    Run IPMI Standard Command  chassis identify 0
235    Verify Identify LED State Via Redfish  False
236
237
238Set Power Cap Value Via IPMI And Verify Using Redfish
239    [Documentation]  Set power cap value via IPMI and verify using Redfish.
240    [Setup]  Redfish.Login
241    [Teardown]  Run Keywords  Set Power Cap Value Via Redfish  ${initial_power_value}  AND  Redfish.Logout
242    [Tags]  Set_Power_Cap_Value_Via_IPMI_And_Verify_Using_Redfish
243
244    # Get initial power cap value via Redfish.
245    ${power_limit_watts}=  Get System Power Cap Limit
246    ${initial_power_value}=  Set Variable  ${power_limit_watts['SetPoint']}
247
248    # Get the allowable min and max power cap value via Redfish.
249    ${min_power_value}=  Set Variable  ${power_limit_watts['AllowableMin']}
250    ${max_power_value}=  Set Variable  ${power_limit_watts['AllowableMax']}
251
252    # Generate a random power cap value within the allowable range.
253    ${random_power_cap}=  Evaluate  random.randint(${min_power_value}, ${max_power_value})  modules=random
254
255    # Set power cap value via IPMI.
256    Run Keyword  Run IPMI Standard Command  dcmi power set_limit limit ${random_power_cap}
257
258    # Verify the power cap value with the Redfish value.
259    ${updated_power_limits}=  Get System Power Cap Limit
260    Should Be Equal  ${updated_power_limits['SetPoint']}  ${random_power_cap}
261
262
263Verify Power Cap Value Via IPMI
264    [Documentation]  Verify the power cap value via IPMI, set to non-zero using Redfish
265    ...              if initial power cap value is zero.
266    [Tags]  Verify_Power_Cap_Value_Via_IPMI
267    [Setup]  Redfish.Login
268    [Teardown]  Run Keywords  Set Power Cap Value Via Redfish  ${redfish_power_value}  AND  Redfish.Logout
269
270    # Get power cap value via Redfish.
271    ${power_cap_limit}=  Get System Power Cap Limit
272
273    # Get initial power cap value.
274    ${redfish_power_value}=  Set Variable  ${power_cap_limit['SetPoint']}
275
276    # Update power cap value via Redfish if the initial power cap value is zero.
277    IF  ${redfish_power_value} == 0
278        # Get the allowable min and max power cap value via Redfish.
279        ${min_power_value}=  Set Variable  ${power_cap_limit['AllowableMin']}
280        ${max_power_value}=  Set Variable  ${power_cap_limit['AllowableMax']}
281
282        # Generate a random power cap value within the allowable range.
283        ${random_power_cap}=  Evaluate  random.randint(${min_power_value}, ${max_power_value})  modules=random
284
285        # Set power value via Redfish.
286        Set Power Cap Value Via Redfish  ${random_power_cap}
287        ${redfish_power_value}=  Set Variable  ${random_power_cap}
288    END
289
290    # Get power cap value via IPMI.
291    ${cmd}=  Catenate  dcmi power get_limit | grep "Power Limit:"
292    ${resp}=  Run IPMI Standard Command  ${cmd}
293
294    # The output will be as below.
295    # Power Limit:         1472 Watts
296
297    # Truncate power limit: and watts from output.
298    ${output_limit}=  Strip String  ${resp}  mode=left  characters=Power Limit:
299    ${ipmi_power_cap_value}=  Strip String  ${output_limit}  mode=both  characters= Watts
300
301    # Perform a comparison of power cap values obtained from both IPMI and Redfish.
302    ${redfish_power_cap_value}=  Convert To String  ${redfish_power_value}
303    Should Be Equal  ${ipmi_power_cap_value}  ${redfish_power_cap_value}
304
305
306*** Keywords ***
307
308IPMI General Test Suite Setup
309    [Documentation]  Get active and inactive/invalid channels from channel_config.json file
310    ...              in list type and set it as suite variable.
311
312    # Get active channel list and set as suite variable.
313    @{active_channel_list}=  Get Active Ethernet Channel List
314    Set Suite Variable  @{active_channel_list}
315
316    # Get Inactive/Invalid channel list and set as suite variable.
317    @{inactive_channel_list}=  Get Invalid Channel Number List
318    Set Suite Variable  @{inactive_channel_list}
319
320
321Set Session Privilege Level And Verify
322    [Documentation]   Set session privilege with given privilege level and verify the response with
323    ...               expected level.
324    [Arguments]  ${privilege_level}  ${expected_level}
325    # Description of argument(s):
326    # privilege_level    Requested Privilege Level.
327    # expected_level     New Privilege Level (or present level if ‘return present privilege level’
328    #                    was selected).
329
330    ${resp}=  Run External IPMI Raw Command
331    ...  0x06 0x3b ${privilege_level}
332    Should Contain  ${resp}  ${expected_level}
333
334
335Set Invalid Session Privilege Level And Verify
336    [Documentation]   Set invalid session privilege level and verify the response.
337    [Arguments]  ${privilege_level}
338    # Description of argument(s):
339    # privilege_level    Requested Privilege Level.
340
341    # Verify requested level exceeds Channel and/or User Privilege Limit.
342    ${msg}=  Run Keyword And Expect Error  *  Run External IPMI Raw Command
343    ...  0x06 0x3b ${privilege_level}
344
345    # 0x05 is OEM proprietary level.
346    IF  ${privilege_level} == 0x05
347        Should Contain  ${msg}  Unknown  rsp=0x81
348    ELSE
349        # According to IPMI spec privilege level except 0x00-0x05, others are
350        # reserved. So if we try to set those privilege we will get rsp as
351        # 0xcc(Invalid data filed in request)
352        Should Contain  ${msg}  Invalid data field in request  rsp=0xcc
353    END
354
355
356Verify Identify LED State Via Redfish
357    [Documentation]  Verify that Redfish identify LED system with given state.
358    [Arguments]  ${expected_state}
359    # Description of argument(s):
360    # expected_led_status  Expected value of Identify LED.
361
362    # Get the following URI(s) and iterate to find the attribute IndicatorLED.
363    # Example:
364    # /redfish/v1/Systems/system
365    # /redfish/v1/Systems/hypervisor
366
367    # Python module:  get_member_list(resource_path)
368    ${systems}=  Redfish_Utils.Get Member List  /redfish/v1/Systems
369    FOR  ${system}  IN  @{systems}
370        ${led_value}=  Redfish.Get Attribute  ${system}  LocationIndicatorActive
371        # Get attribute return None if IndicatorLED does not exist in the URI.
372        Continue For Loop If  '${led_value}' == 'None'
373        Should Be True  '${led_value}' == '${expected_state}'
374    END
375
376
377Verify Channel Auth Capabilities
378    [Documentation]  Verify authentication capabilities for given channel and privilege.
379    [Arguments]  ${channel}  ${privilege_level}
380
381    # Description of argument(s):
382    # channel           Interface channel number.
383    # privilege_level   User Privilege level (e.g. 4-Administator, 3-Operator, 2-Readonly).
384
385    # Python module:  get_channel_auth_capabilities(channel_number, privilege_level)
386    ${channel_auth_cap}=  Get Channel Auth Capabilities  ${channel}  ${privilege_level}
387    Rprint Vars  channel_auth_cap
388
389    Valid Value  channel_auth_cap['channel_number']  ['${channel}']
390    Valid Value  channel_auth_cap['kg_status']  ['default (all zeroes)']
391    Valid Value  channel_auth_cap['per_message_authentication']  ['enabled']
392    Valid Value  channel_auth_cap['user_level_authentication']  ['enabled']
393    Valid Value  channel_auth_cap['non-null_user_names_exist']  ['yes']
394    Valid Value  channel_auth_cap['null_user_names_exist']  ['no']
395    Valid Value  channel_auth_cap['anonymous_login_enabled']  ['no']
396    Valid Value  channel_auth_cap['channel_supports_ipmi_v1.5']  ['no']
397    Valid Value  channel_auth_cap['channel_supports_ipmi_v2.0']  ['yes']
398
399
400Verify Channel Auth Capabilities For Invalid Channel
401    [Documentation]  Verify authentication capabilities of invalid channels.
402    [Arguments]  ${channel}
403
404    # Description of argument(s):
405    # channel   Interface channel number.
406
407    ${channel_in_hex}=  Convert To Hex  ${channel}  prefix=0x
408    ${cmd}=  Catenate  ${IPMI_RAW_CMD['Get Channel Auth Cap']['get'][0]} ${channel_in_hex} 0x04
409
410    Verify Invalid IPMI Command  ${cmd}  0xcc
411
412
413Verify Channel Auth Command For Invalid Data Length
414   [Documentation]  Verify channel authentication command for invalid data length.
415   [Arguments]  ${byte_length}
416
417   # Description of argument(s):
418   # byte_length   high or low.
419   #               e.g. high - add extra byte to request data like "0x06 0x38 0x01 0x04 0x01".
420   #               low - reduce bytes in actual request data like "0x06 0x38".
421
422   ${req_cmd}=  Run Keyword If  '${byte_length}' == 'low'
423   ...  Catenate  ${IPMI_RAW_CMD['Get Channel Auth Cap']['get'][0]}  ${CHANNEL_NUMBER}
424   ...  ELSE
425   ...  Catenate  ${IPMI_RAW_CMD['Get Channel Auth Cap']['get'][0]}  ${CHANNEL_NUMBER} 0x04 0x01
426
427   Verify Invalid IPMI Command  ${req_cmd}  0xc7
428
429
430Set Power Cap Value Via Redfish
431    [Documentation]  Set power cap value via Redfish.
432    [Arguments]   ${power_cap_value}
433
434    # Description of argument(s):
435    # power_cap_value    Power cap value which need to be set.
436
437    # Set power cap value based on argument.
438    Redfish.Patch  /redfish/v1/Chassis/${CHASSIS_ID}/EnvironmentMetrics
439    ...  body={"PowerLimitWatts":{"SetPoint": ${power_cap_value}}}
440    ...  valid_status_codes=[${HTTP_OK}, ${HTTP_NO_CONTENT}]
441