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
16Force 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 Standard Command  raw ${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 Standard Command  raw ${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  Lit
211
212    Sleep  18s
213    Verify Identify LED State Via Redfish  Off
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  Lit
218
219    Sleep  12s
220    Verify Identify LED State Via Redfish  Off
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  Lit
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  Off
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  ${initial_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 vaule.
274    ${initial_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  ${initial_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    END
288
289    # Get power cap value via IPMI.
290    ${cmd}=  Catenate  dcmi power get_limit | grep "Power Limit:"
291    ${resp}=  Run IPMI Standard Command  ${cmd}
292
293    # The output will be as below.
294    # Power Limit:         1472 Watts
295
296    # Truncate power limit: and watts from output.
297    ${output_limit}=  Strip String  ${resp}  mode=left  characters=Power Limit:
298    ${ipmi_power_cap_value}=  Strip String  ${output_limit}  mode=both  characters= Watts
299
300    # Perform a comparison of power cap values obtained from both IPMI and Redfish.
301    ${redfish_power_cap_value}=  Convert To String  ${random_power_cap}
302    Should Be Equal  ${ipmi_power_cap_value}  ${redfish_power_cap_value}
303
304
305*** Keywords ***
306
307IPMI General Test Suite Setup
308    [Documentation]  Get active and inactive/invalid channels from channel_config.json file
309    ...              in list type and set it as suite variable.
310
311    # Get active channel list and set as suite variable.
312    @{active_channel_list}=  Get Active Ethernet Channel List
313    Set Suite Variable  @{active_channel_list}
314
315    # Get Inactive/Invalid channel list and set as suite variable.
316    @{inactive_channel_list}=  Get Invalid Channel Number List
317    Set Suite Variable  @{inactive_channel_list}
318
319
320Set Session Privilege Level And Verify
321    [Documentation]   Set session privilege with given privilege level and verify the response with
322    ...               expected level.
323    [Arguments]  ${privilege_level}  ${expected_level}
324    # Description of argument(s):
325    # privilege_level    Requested Privilege Level.
326    # expected_level     New Privilege Level (or present level if ‘return present privilege level’
327    #                    was selected).
328
329    ${resp}=  Run External IPMI Raw Command
330    ...  0x06 0x3b ${privilege_level}
331    Should Contain  ${resp}  ${expected_level}
332
333
334Set Invalid Session Privilege Level And Verify
335    [Documentation]   Set invalid session privilege level and verify the response.
336    [Arguments]  ${privilege_level}
337    # Description of argument(s):
338    # privilege_level    Requested Privilege Level.
339
340    # Verify requested level exceeds Channel and/or User Privilege Limit.
341    ${msg}=  Run Keyword And Expect Error  *  Run External IPMI Raw Command
342    ...  0x06 0x3b ${privilege_level}
343
344    # 0x05 is OEM proprietary level.
345    IF  ${privilege_level} == 0x05
346        Should Contain  ${msg}  Unknown  rsp=0x81
347    ELSE
348        # According to IPMI spec privilege level except 0x00-0x05, others are
349        # reserved. So if we try to set those privilege we will get rsp as
350        # 0xcc(Invalid data filed in request)
351        Should Contain  ${msg}  Invalid data field in request  rsp=0xcc
352    END
353
354
355Verify Identify LED State Via Redfish
356    [Documentation]  Verify that Redfish identify LED system with given state.
357    [Arguments]  ${expected_state}
358    # Description of argument(s):
359    # expected_led_status  Expected value of Identify LED.
360
361    # Get the following URI(s) and iterate to find the attribute IndicatorLED.
362    # Example:
363    # /redfish/v1/Systems/system
364    # /redfish/v1/Systems/hypervisor
365
366    # Python module:  get_member_list(resource_path)
367    ${systems}=  Redfish_Utils.Get Member List  /redfish/v1/Systems
368    FOR  ${system}  IN  @{systems}
369        ${led_value}=  Redfish.Get Attribute  ${system}  IndicatorLED
370        # Get attribute return None if IndicatorLED does not exist in the URI.
371        Continue For Loop If  '${led_value}' == 'None'
372        Should Be True  '${led_value}' == '${expected_state}'
373    END
374
375
376Verify Channel Auth Capabilities
377    [Documentation]  Verify authentication capabilities for given channel and privilege.
378    [Arguments]  ${channel}  ${privilege_level}
379
380    # Description of argument(s):
381    # channel           Interface channel number.
382    # privilege_level   User Privilege level (e.g. 4-Administator, 3-Operator, 2-Readonly).
383
384    # Python module:  get_channel_auth_capabilities(channel_number, privilege_level)
385    ${channel_auth_cap}=  Get Channel Auth Capabilities  ${channel}  ${privilege_level}
386    Rprint Vars  channel_auth_cap
387
388    Valid Value  channel_auth_cap['channel_number']  ['${channel}']
389    Valid Value  channel_auth_cap['kg_status']  ['default (all zeroes)']
390    Valid Value  channel_auth_cap['per_message_authentication']  ['enabled']
391    Valid Value  channel_auth_cap['user_level_authentication']  ['enabled']
392    Valid Value  channel_auth_cap['non-null_user_names_exist']  ['yes']
393    Valid Value  channel_auth_cap['null_user_names_exist']  ['no']
394    Valid Value  channel_auth_cap['anonymous_login_enabled']  ['no']
395    Valid Value  channel_auth_cap['channel_supports_ipmi_v1.5']  ['no']
396    Valid Value  channel_auth_cap['channel_supports_ipmi_v2.0']  ['yes']
397
398
399Verify Channel Auth Capabilities For Invalid Channel
400    [Documentation]  Verify authentication capabilities of invalid channels.
401    [Arguments]  ${channel}
402
403    # Description of argument(s):
404    # channel   Interface channel number.
405
406    ${channel_in_hex}=  Convert To Hex  ${channel}  prefix=0x
407    ${cmd}=  Catenate  ${IPMI_RAW_CMD['Get Channel Auth Cap']['get'][0]} ${channel_in_hex} 0x04
408
409    Verify Invalid IPMI Command  ${cmd}  0xcc
410
411
412Verify Channel Auth Command For Invalid Data Length
413   [Documentation]  Verify channel authentication command for invalid data length.
414   [Arguments]  ${byte_length}
415
416   # Description of argument(s):
417   # byte_length   high or low.
418   #               e.g. high - add extra byte to request data like "0x06 0x38 0x01 0x04 0x01".
419   #               low - reduce bytes in actual request data like "0x06 0x38".
420
421   ${req_cmd}=  Run Keyword If  '${byte_length}' == 'low'
422   ...  Catenate  ${IPMI_RAW_CMD['Get Channel Auth Cap']['get'][0]}  ${CHANNEL_NUMBER}
423   ...  ELSE
424   ...  Catenate  ${IPMI_RAW_CMD['Get Channel Auth Cap']['get'][0]}  ${CHANNEL_NUMBER} 0x04 0x01
425
426   Verify Invalid IPMI Command  ${req_cmd}  0xc7
427
428
429Set Power Cap Value Via Redfish
430    [Documentation]  Set power cap value via Redfish.
431    [Arguments]   ${power_cap_value}
432
433    # Description of argument(s):
434    # power_cap_value    Power cap value which need to be set.
435
436    # Set power cap value based on argument.
437    Redfish.Patch  /redfish/v1/Chassis/chassis/EnvironmentMetrics
438    ...  body={"PowerLimitWatts":{"SetPoint": ${power_cap_value}}}
439    ...  valid_status_codes=[${HTTP_OK}, ${HTTP_NO_CONTENT}]
440