1*** Settings ***
2Documentation            Update the BMC code on a target BMC via Redifsh.
3
4# Test Parameters:
5# IMAGE_FILE_PATH        The path to the BMC image file.
6#
7# Firmware update states:
8#     Enabled            Image is installed and either functional or active.
9#     Disabled           Image installation failed or ready for activation.
10#     Updating           Image installation currently in progress.
11
12Resource                 ../../lib/resource.robot
13Resource                 ../../lib/bmc_redfish_resource.robot
14Resource                 ../../lib/openbmc_ffdc.robot
15Resource                 ../../lib/common_utils.robot
16Resource                 ../../lib/code_update_utils.robot
17Resource                 ../../lib/redfish_code_update_utils.robot
18Resource                 ../../lib/utils.robot
19Library                  ../../lib/gen_robot_valid.py
20Library                  ../../lib/var_funcs.py
21Library                  ../../lib/gen_robot_keyword.py
22Library                  ../../lib/code_update_utils.py
23
24Suite Setup              Suite Setup Execution
25Suite Teardown           Redfish.Logout
26Test Setup               Printn
27Test Teardown            FFDC On Test Case Fail
28
29# Force the test to timedout to prevent test hanging.
30Test Timeout             30 minutes
31
32Force Tags               BMC_Code_Update
33
34*** Variables ***
35
36${FORCE_UPDATE}          ${0}
37${LOOP_COUNT}            ${2}
38${DELETE_ERRLOGS}        ${1}
39
40${ACTIVATION_WAIT_TIMEOUT}     8 min
41
42# New code update path.
43${REDFISH_UPDATE_URI}    /redfish/v1/UpdateService/update
44
45*** Test Cases ***
46
47Redfish BMC Code Update
48    [Documentation]  Update the firmware image.
49    [Tags]  Redfish_BMC_Code_Update
50
51    # Python module:  get_version_tar(tar_file_path)
52    ${image_version}=  code_update_utils.Get Version Tar  ${IMAGE_FILE_PATH}
53    Rprint Vars  image_version
54
55    # Python module: get_bmc_release_info()
56    ${bmc_release_info}=  utils.Get BMC Release Info
57    ${functional_version}=  Set Variable  ${bmc_release_info['version_id']}
58    Rprint Vars  functional_version
59
60    ${post_code_update_actions}=  Get Post Boot Action
61    ${state}=  Get Pre Reboot State
62    Rprint Vars  state
63
64    # Check if the existing firmware is functional.
65    Pass Execution If  '${functional_version}' == '${image_version}'
66    ...  The existing ${image_version} firmware is already functional.
67
68    ${sw_inv}=  Get Functional Firmware  BMC image
69    ${nonfunctional_sw_inv}=  Get Non Functional Firmware  ${sw_inv}  False
70
71    # Redfish active software image API.
72    Run Keyword If  ${num_records} > 0
73    ...  Run Keyword If  '${nonfunctional_sw_inv['version']}' == '${image_version}'
74    ...  Set Backup Firmware To Functional  ${image_version}  ${state}
75
76    Print Timen  Performing firmware update ${image_version}.
77
78    Redfish Update Firmware
79
80
81Redfish BMC Code Update Running And Backup Image With Same Firmware
82    [Documentation]  Perform the firmware update with same image back to back, so that
83    ...              the running (functional Image) and backup image (alternate image)
84    ...              with same firmware.
85    [Tags]  Redfish_BMC_Code_Update_Running_And_Backup_Image_With_Same_Firmware
86
87    # Python module:  get_version_tar(tar_file_path)
88    ${image_version}=  code_update_utils.Get Version Tar  ${IMAGE_FILE_PATH}
89    Rprint Vars  image_version
90
91    # Python module: get_bmc_release_info()
92    ${bmc_release_info}=  utils.Get BMC Release Info
93    ${functional_version}=  Set Variable  ${bmc_release_info['version_id']}
94    Rprint Vars  functional_version
95
96    # First update.
97    Print Timen  Performing firmware update ${image_version}.
98    Redfish Update Firmware
99
100    # Second update.
101    Print Timen  Performing firmware update ${image_version}.
102    Redfish Update Firmware
103
104
105Redfish Firmware Update Loop
106    [Documentation]  Update the same firmware image in loop.
107    [Tags]  Redfish_Firmware_Update_Loop
108    [Template]  Redfish Firmware Update In Loop
109    [Timeout]    NONE
110    # Override default 30 minutes, Disabling timeout with NONE explicitly
111    # else this test will fail for longer loop runs.
112
113    ${LOOP_COUNT}
114
115
116*** Keywords ***
117
118Suite Setup Execution
119    [Documentation]  Do the suite setup.
120
121    Redfish.Login
122    # Delete BMC dump and Error logs.
123    Run Keyword And Ignore Error  Redfish Delete All BMC Dumps
124    Run Keyword If  ${DELETE_ERRLOGS} == ${1}
125    ...   Run Keyword And Ignore Error  Redfish Purge Event Log
126    # Checking for file existence.
127    Valid File Path  IMAGE_FILE_PATH
128
129    # Check and set the update path.
130    # Old - /redfish/v1/UpdateService/
131    # New - /redfish/v1/UpdateService/update
132    ${resp}=  Redfish.Get  /redfish/v1/UpdateService/update
133    ...  valid_status_codes=[${HTTP_OK},${HTTP_NOT_FOUND},${HTTP_METHOD_NOT_ALLOWED}]
134
135    # If the method is not found, set update URI to old method.
136    Run Keyword If  ${resp.status} == ${HTTP_NOT_FOUND}
137    ...  Set Suite Variable  ${REDFISH_UPDATE_URI}  /redfish/v1/UpdateService
138
139    Log To Console  Update URI: ${REDFISH_UPDATE_URI}
140
141    Redfish Power Off  stack_mode=skip
142
143
144Redfish Firmware Update In Loop
145    [Documentation]  Update the firmware in loop.
146    [Arguments]  ${update_loop_count}
147
148    # Description of argument(s):
149    # update_loop_count    This value is used to run the firmware update in loop.
150
151    # Python module:  get_version_tar(tar_file_path)
152    ${image_version}=  code_update_utils.Get Version Tar  ${IMAGE_FILE_PATH}
153    Rprint Vars  image_version
154
155    # Python module: get_bmc_release_info()
156    ${bmc_release_info}=  utils.Get BMC Release Info
157    ${functional_version}=  Set Variable  ${bmc_release_info['version_id']}
158    Print Timen  Starting firmware information:
159    Rprint Vars  functional_version
160
161    ${temp_update_loop_count}=  Evaluate  ${update_loop_count} + 1
162
163    FOR  ${count}  IN RANGE  1  ${temp_update_loop_count}
164       Print Timen  **************************************
165       Print Timen  * The Current Loop Count is ${count} of ${update_loop_count} *
166       Print Timen  **************************************
167       Print Timen  Performing firmware update ${image_version}.
168       Redfish Update Firmware
169    END
170
171
172Delete BMC Image
173    [Documentation]  Delete a BMC image from the BMC flash chip.
174
175    ${software_object}=  Get Non Running BMC Software Object
176    Delete Image And Verify  ${software_object}  ${VERSION_PURPOSE_BMC}
177
178
179Activate Existing Firmware
180    [Documentation]  Set firmware image to lower priority.
181    [Arguments]  ${image_version}
182
183    # Description of argument(s):
184    # image_version     Version of image.
185
186    ${software_inventory_record}=  Get Software Inventory State By Version
187    ...  ${image_version}
188    ${num_keys}=  Get Length  ${software_inventory_record}
189
190    Rprint Vars  software_inventory_record
191
192    # If no software inventory record was found, there is no existing
193    # firmware for the given version and therefore no action to be taken.
194    Return From Keyword If  not ${num_keys}
195
196    # Check if the existing firmware is functional.
197    Pass Execution If  ${software_inventory_record['functional']}
198    ...  The existing ${image_version} firmware is already functional.
199
200    # If existing firmware is not functional, then set the priority to least.
201    Print Timen  The existing ${image_version} firmware is not yet functional.
202    Set BMC Image Priority To Least  ${image_version}  ${software_inventory_record}
203
204    Pass Execution  The existing ${image_version} firmware is now functional.
205
206
207Get Image Priority
208    [Documentation]  Get Current Image Priority.
209    [Arguments]  ${image_version}
210
211    # Description of argument(s):
212    # image_version       The Firmware image version (e.g. 2.8.0-dev-1107-g512028d95).
213
214    ${software_info}=  Read Properties
215    ...  ${SOFTWARE_VERSION_URI}/enumerate  quiet=1
216    # Get only the record associated with our image_version.
217
218    ${software_info}=  Filter Struct
219    ...  ${software_info}  [('Version', '${image_version}')]
220    # Convert from dict to list.
221    ${software_info}=  Get Dictionary Values  ${software_info}
222
223    [Return]  ${software_info[0]['Priority']}
224
225
226Set BMC Image Priority To Least
227    [Documentation]  Set BMC image priority to least value.
228    [Arguments]  ${image_version}  ${software_inventory}
229
230    # Description of argument(s):
231    # image_version       The Firmware image version (e.g. 2.8.0-dev-1107-g512028d95).
232    # software_inventory  Software inventory details.
233
234    ${least_priority}=  Get Least Value Priority Image  ${VERSION_PURPOSE_BMC}
235    ${cur_priority}=  Get Image Priority  ${image_version}
236    Rprint Vars  least_priority  cur_priority
237
238    Return From Keyword If  '${least_priority}' == ${cur_priority}
239    Set Host Software Property
240    ...  ${SOFTWARE_VERSION_URI}${software_inventory['image_id']}
241    ...  Priority  ${least_priority}
242
243    Redfish OBMC Reboot (off)
244
245
246Set Backup Firmware To Functional
247    [Documentation]  Set the backup firmware to functional.
248    [Arguments]  ${image_version}  ${state}
249
250    # Description of argument(s):
251    # image_version     Version of image.
252    # state             Pre reboot state.
253
254    Print Timen  Switch to back up and rebooting.
255    Switch Backup Firmware Image To Functional
256    Wait For Reboot  start_boot_seconds=${state['epoch_seconds']}
257    Redfish Verify BMC Version  ${IMAGE_FILE_PATH}
258    Pass Execution  The backup firmware image ${image_version} is now functional.
259
260
261Redfish Update Firmware
262    [Documentation]  Update the BMC firmware via redfish interface.
263
264    ${post_code_update_actions}=  Get Post Boot Action
265    ${state}=  Get Pre Reboot State
266    Rprint Vars  state
267    Run Keyword And Ignore Error  Set ApplyTime  policy=OnReset
268
269    # Python module:  get_member_list(resource_path)
270    ${before_inv_list}=  redfish_utils.Get Member List  /redfish/v1/UpdateService/FirmwareInventory
271    Log To Console   Current images on the BMC before upload: ${before_inv_list}
272
273    Print Timen  Start uploading image to BMC.
274    Redfish Upload Image  ${REDFISH_UPDATE_URI}  ${IMAGE_FILE_PATH}
275    Print Timen  Completed image upload to BMC.
276
277    # Python module:  get_member_list(resource_path)
278    ${after_inv_list}=  redfish_utils.Get Member List  /redfish/v1/UpdateService/FirmwareInventory
279    Log To Console  Current images on the BMC after upload: ${after_inv_list}
280
281    ${image_id}=  Evaluate  set(${after_inv_list}) - set(${before_inv_list})
282    Should Not Be Empty    ${image_id}
283    ${image_id}=  Evaluate  list(${image_id})[0].split('/')[-1]
284    Log To Console  Firmware installation in progress with image id:: ${image_id}
285
286    Wait Until Keyword Succeeds  ${ACTIVATION_WAIT_TIMEOUT}  10 sec
287    ...  Check Image Update Progress State  match_state='Enabled'  image_id=${image_id}
288
289    # Python module:  get_version_tar(tar_file_path)
290    ${tar_version}=  code_update_utils.Get Version Tar  ${IMAGE_FILE_PATH}
291    ${image_info}=  Get Software Inventory State By Version  ${tar_version}
292
293    Run Key  ${post_code_update_actions['${image_info["image_type"]}']['OnReset']}
294    Redfish.Login
295    Redfish Verify BMC Version  ${IMAGE_FILE_PATH}
296
297