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}            20
38
39${ACTIVATION_WAIT_TIMEOUT}     8 min
40
41*** Test Cases ***
42
43Redfish BMC Code Update
44    [Documentation]  Update the firmware image.
45    [Tags]  Redfish_BMC_Code_Update
46
47    # Python module:  get_version_tar(tar_file_path)
48    ${image_version}=  code_update_utils.Get Version Tar  ${IMAGE_FILE_PATH}
49    Rprint Vars  image_version
50
51    # Python module: get_bmc_release_info()
52    ${bmc_release_info}=  utils.Get BMC Release Info
53    ${functional_version}=  Set Variable  ${bmc_release_info['version_id']}
54    Rprint Vars  functional_version
55
56    ${post_code_update_actions}=  Get Post Boot Action
57    ${state}=  Get Pre Reboot State
58    Rprint Vars  state
59
60    # Check if the existing firmware is functional.
61    Pass Execution If  '${functional_version}' == '${image_version}'
62    ...  The existing ${image_version} firmware is already functional.
63
64    ${sw_inv}=  Get Functional Firmware  BMC image
65    ${nonfunctional_sw_inv}=  Get Non Functional Firmware  ${sw_inv}  False
66
67    # Redfish active software image API.
68    Run Keyword If  ${num_records} > 0
69    ...  Run Keyword If  '${nonfunctional_sw_inv['version']}' == '${image_version}'
70    ...  Set Backup Firmware To Functional  ${image_version}  ${state}
71
72    Print Timen  Performing firmware update ${image_version}.
73
74    Redfish Update Firmware
75
76
77Redfish Firmware Update Loop
78    [Documentation]  Update the firmware image in loop.
79    [Tags]  Redfish_Firmware_Update_Loop
80    [Template]  Redfish Firmware Update In Loop
81
82    ${LOOP_COUNT}
83
84
85*** Keywords ***
86
87Suite Setup Execution
88    [Documentation]  Do the suite setup.
89
90    Redfish.Login
91    # Delete BMC dump and Error logs.
92    Run Keyword And Ignore Error  Redfish Delete All BMC Dumps
93    Run Keyword And Ignore Error  Redfish Purge Event Log
94    # Checking for file existence.
95    Valid File Path  IMAGE_FILE_PATH
96
97    Redfish Power Off  stack_mode=skip
98
99
100Redfish Firmware Update In Loop
101    [Documentation]  Update the firmware in loop.
102    [Arguments]  ${update_loop_count}
103
104    # Description of argument(s):
105    # update_loop_count    This value is used to run the firmware update in loop.
106
107    ${before_image_state}=  Get BMC Functional Firmware
108    ${temp_update_loop_count}=  Evaluate  ${update_loop_count} + 1
109
110    FOR  ${count}  IN RANGE  1  ${temp_update_loop_count}
111      Print Timen  **************************************
112      Print Timen  * The Current Loop Count is ${count} of ${update_loop_count} *
113      Print Timen  **************************************
114      Redfish Update Firmware
115      ${sw_inv}=  Get Functional Firmware  BMC update
116      ${nonfunctional_sw_inv}=  Get Non Functional Firmware  ${sw_inv}  False
117      Run Keyword If  ${nonfunctional_sw_inv['functional']} == False
118      ...  Set BMC Image Priority To Least  ${nonfunctional_sw_inv['version']}  ${nonfunctional_sw_inv}
119      Redfish.Login
120      ${sw_inv}=  Get Functional Firmware  BMC update
121      ${nonfunctional_sw_inv}=  Get Non Functional Firmware  ${sw_inv}  False
122      Delete BMC Image
123    END
124
125    ${after_image_state}=  Get BMC Functional Firmware
126    Valid Value  before_image_state["version"]  ['${after_image_state["version"]}']
127
128
129Delete BMC Image
130    [Documentation]  Delete a BMC image from the BMC flash chip.
131
132    ${software_object}=  Get Non Running BMC Software Object
133    Delete Image And Verify  ${software_object}  ${VERSION_PURPOSE_BMC}
134
135
136Activate Existing Firmware
137    [Documentation]  Set firmware image to lower priority.
138    [Arguments]  ${image_version}
139
140    # Description of argument(s):
141    # image_version     Version of image.
142
143    ${software_inventory_record}=  Get Software Inventory State By Version
144    ...  ${image_version}
145    ${num_keys}=  Get Length  ${software_inventory_record}
146
147    Rprint Vars  software_inventory_record
148
149    # If no software inventory record was found, there is no existing
150    # firmware for the given version and therefore no action to be taken.
151    Return From Keyword If  not ${num_keys}
152
153    # Check if the existing firmware is functional.
154    Pass Execution If  ${software_inventory_record['functional']}
155    ...  The existing ${image_version} firmware is already functional.
156
157    # If existing firmware is not functional, then set the priority to least.
158    Print Timen  The existing ${image_version} firmware is not yet functional.
159    Set BMC Image Priority To Least  ${image_version}  ${software_inventory_record}
160
161    Pass Execution  The existing ${image_version} firmware is now functional.
162
163
164Get Image Priority
165    [Documentation]  Get Current Image Priority.
166    [Arguments]  ${image_version}
167
168    # Description of argument(s):
169    # image_version       The Firmware image version (e.g. 2.8.0-dev-1107-g512028d95).
170
171    ${software_info}=  Read Properties
172    ...  ${SOFTWARE_VERSION_URI}/enumerate  quiet=1
173    # Get only the record associated with our image_version.
174
175    ${software_info}=  Filter Struct
176    ...  ${software_info}  [('Version', '${image_version}')]
177    # Convert from dict to list.
178    ${software_info}=  Get Dictionary Values  ${software_info}
179
180    [Return]  ${software_info[0]['Priority']}
181
182
183Set BMC Image Priority To Least
184    [Documentation]  Set BMC image priority to least value.
185    [Arguments]  ${image_version}  ${software_inventory}
186
187    # Description of argument(s):
188    # image_version       The Firmware image version (e.g. 2.8.0-dev-1107-g512028d95).
189    # software_inventory  Software inventory details.
190
191    ${least_priority}=  Get Least Value Priority Image  ${VERSION_PURPOSE_BMC}
192    ${cur_priority}=  Get Image Priority  ${image_version}
193    Rprint Vars  least_priority  cur_priority
194
195    Return From Keyword If  '${least_priority}' == ${cur_priority}
196    Set Host Software Property
197    ...  ${SOFTWARE_VERSION_URI}${software_inventory['image_id']}
198    ...  Priority  ${least_priority}
199
200    Redfish OBMC Reboot (off)
201
202
203Set Backup Firmware To Functional
204    [Documentation]  Set the backup firmware to functional.
205    [Arguments]  ${image_version}  ${state}
206
207    # Description of argument(s):
208    # image_version     Version of image.
209    # state             Pre reboot state.
210
211    Print Timen  Switch to back up and rebooting.
212    Switch Backup Firmware Image To Functional
213    Wait For Reboot  start_boot_seconds=${state['epoch_seconds']}
214    Redfish Verify BMC Version  ${IMAGE_FILE_PATH}
215    Pass Execution  The backup firmware image ${image_version} is now functional.
216
217
218Redfish Update Firmware
219    [Documentation]  Update the BMC firmware via redfish interface.
220
221    ${post_code_update_actions}=  Get Post Boot Action
222    ${state}=  Get Pre Reboot State
223    Rprint Vars  state
224    Run Keyword And Ignore Error  Set ApplyTime  policy=OnReset
225
226    # Python module:  get_member_list(resource_path)
227    ${before_inv_list}=  redfish_utils.Get Member List  /redfish/v1/UpdateService/FirmwareInventory
228    Log To Console   Current images on the BMC before upload: ${before_inv_list}
229
230    Log To Console   Start uploading image to BMC.
231    Redfish Upload Image  /redfish/v1/UpdateService  ${IMAGE_FILE_PATH}
232    Log To Console   Completed image upload to BMC.
233
234    # Python module:  get_member_list(resource_path)
235    ${after_inv_list}=  redfish_utils.Get Member List  /redfish/v1/UpdateService/FirmwareInventory
236    Log To Console  Current images on the BMC after upload: ${after_inv_list}
237
238    ${image_id}=  Evaluate  set(${after_inv_list}) - set(${before_inv_list})
239    Should Not Be Empty    ${image_id}
240    ${image_id}=  Evaluate  list(${image_id})[0].split('/')[-1]
241    Log To Console  Firmware installation in progress with image id:: ${image_id}
242
243    Wait Until Keyword Succeeds  ${ACTIVATION_WAIT_TIMEOUT}  10 sec
244    ...  Check Image Update Progress State  match_state='Enabled'  image_id=${image_id}
245
246    # Python module:  get_version_tar(tar_file_path)
247    ${tar_version}=  code_update_utils.Get Version Tar  ${IMAGE_FILE_PATH}
248    ${image_info}=  Get Software Inventory State By Version  ${tar_version}
249
250    Run Key  ${post_code_update_actions['${image_info["image_type"]}']['OnReset']}
251    Redfish.Login
252    Redfish Verify BMC Version  ${IMAGE_FILE_PATH}
253
254