xref: /openbmc/openbmc-test-automation/lib/code_update_utils.robot (revision e43fb2f773a76a1083c47ceac20f0a638e5be567)
1*** Settings ***
2Documentation  BMC and PNOR update utilities keywords.
3
4Library     code_update_utils.py
5Library     OperatingSystem
6Library     String
7Variables   ../data/variables.py
8Resource    rest_client.robot
9Resource    openbmc_ffdc.robot
10
11*** Keywords ***
12
13Get Software Objects
14    [Documentation]  Get the host software objects and return as a list.
15    [Arguments]  ${version_type}=${VERSION_PURPOSE_HOST}
16
17    # Description of argument(s):
18    # version_type  Either BMC or host version purpose.
19    #               By default host version purpose string.
20    #  (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"
21    #        "xyz.openbmc_project.Software.Version.VersionPurpose.Host").
22
23    # Example:
24    # "data": [
25    #      "/xyz/openbmc_project/software/f3b29aa8",
26    #      "/xyz/openbmc_project/software/e49bc78e",
27    # ],
28    # Iterate the list and return the host object name path list.
29
30    ${host_list}=  Create List
31    ${sw_list}=  Read Properties  ${SOFTWARE_VERSION_URI}
32
33    :FOR  ${index}  IN  @{sw_list}
34    \  ${attr_purpose}=  Read Software Attribute  ${index}  Purpose
35    \  Continue For Loop If  '${attr_purpose}' != '${version_type}'
36    \  Append To List  ${host_list}  ${index}
37
38    [Return]  ${host_list}
39
40
41Read Software Attribute
42    [Documentation]  Return software attribute data.
43    [Arguments]  ${software_object}  ${attribute_name}
44
45    # Description of argument(s):
46    # software_object   Software object path.
47    #                   (e.g. "/xyz/openbmc_project/software/f3b29aa8").
48    # attribute_name    Software object attribute name.
49
50    ${resp}=  OpenBMC Get Request  ${software_object}/attr/${attribute_name}
51    ...  quiet=${1}
52    Return From Keyword If  ${resp.status_code} != ${HTTP_OK}
53    ${content}=  To JSON  ${resp.content}
54    [Return]  ${content["data"]}
55
56
57Get Software Objects Id
58    [Documentation]  Get the software objects id and return as a list.
59    [Arguments]  ${version_type}=${VERSION_PURPOSE_HOST}
60
61    # Description of argument(s):
62    # version_type  Either BMC or host version purpose.
63    #               By default host version purpose string.
64    #              (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"
65    #               "xyz.openbmc_project.Software.Version.VersionPurpose.Host").
66
67    ${sw_id_list}=  Create List
68    ${sw_list}=  Get Software Objects  ${version_type}
69
70    :FOR  ${index}  IN  @{sw_list}
71    \  Append To List  ${sw_id_list}  ${index.rsplit('/', 1)[1]}
72
73    [Return]  ${sw_id_list}
74
75
76Get Host Software Property
77    [Documentation]  Return a dictionary of host software properties.
78    [Arguments]  ${host_object}
79
80    # Description of argument(s):
81    # host_object  Host software object path.
82    #             (e.g. "/xyz/openbmc_project/software/f3b29aa8").
83
84    ${sw_attributes}=  Read Properties  ${host_object}
85    [return]  ${sw_attributes}
86
87Get Host Software Objects Details
88    [Documentation]  Return software object details as a list of dictionaries.
89    [Arguments]  ${quiet}=${QUIET}
90
91    ${software}=  Create List
92
93    ${pnor_details}=  Get Software Objects  ${VERSION_PURPOSE_HOST}
94    :FOR  ${pnor}  IN  @{pnor_details}
95    \  ${resp}=  OpenBMC Get Request  ${pnor}  quiet=${1}
96    \  ${json}=  To JSON  ${resp.content}
97    \  Append To List  ${software}  ${json["data"]}
98
99    [Return]  ${software}
100
101Set Host Software Property
102    [Documentation]  Set the host software properties of a given object.
103    [Arguments]  ${host_object}  ${sw_attribute}  ${data}
104
105    # Description of argument(s):
106    # host_object   Host software object name.
107    # sw_attribute  Host software attribute name.
108    #               (e.g. "Activation", "Priority", "RequestedActivation" etc).
109    # data          Value to be written.
110
111    ${args}=  Create Dictionary  data=${data}
112    Write Attribute  ${host_object}  ${sw_attribute}  data=${args}
113
114
115Set Property To Invalid Value And Verify No Change
116    [Documentation]  Attempt to set a property and check that the value didn't
117    ...              change.
118    [Arguments]  ${property}  ${version_type}
119
120    # Description of argument(s):
121    # property      The property to attempt to set.
122    # version_type  Either BMC or host version purpose.
123    #               By default host version purpose string.
124    #  (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"
125    #        "xyz.openbmc_project.Software.Version.VersionPurpose.Host").
126
127    ${software_objects}=  Get Software Objects  version_type=${version_type}
128    ${prev_properties}=  Get Host Software Property  @{software_objects}[0]
129    Run Keyword And Expect Error  500 != 200
130    ...  Set Host Software Property  @{software_objects}[0]  ${property}  foo
131    ${cur_properties}=  Get Host Software Property  @{software_objects}[0]
132    Should Be Equal As Strings  &{prev_properties}[${property}]
133    ...  &{cur_properties}[${property}]
134
135
136Set Priority To Invalid Value And Expect Error
137    [Documentation]  Set the priority of an image to an invalid value and
138    ...              check that an error was returned.
139    [Arguments]  ${version_type}  ${priority}
140
141    # Description of argument(s):
142    # version_type  Either BMC or host version purpose.
143    #               (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"
144    #                     "xyz.openbmc_project.Software.Version.VersionPurpose.Host").
145    # priority      The priority value to set. Should be an integer outside of
146    #               the range of 0 through 255.
147
148    ${images}=  Get Software Objects  version_type=${version_type}
149    ${num_images}=  Get Length  ${images}
150    Should Be True  0 < ${num_images}
151
152    Run Keyword And Expect Error  403 != 200
153    ...  Set Host Software Property  @{images}[0]  Priority  ${priority}
154
155
156Upload And Activate Image
157    [Documentation]  Upload an image to the BMC and activate it with REST.
158    [Arguments]  ${image_file_path}  ${wait}=${1}  ${skip_if_active}=false
159
160    # Description of argument(s):
161    # image_file_path     The path to the image tarball to upload and activate.
162    # wait                Indicates that this keyword should wait for host or
163    #                     BMC activation is completed.
164    # skip_if_active      If set to true, will skip the code update if this
165    #                     image is already on the BMC.
166
167    OperatingSystem.File Should Exist  ${image_file_path}
168    ${image_version}=  Get Version Tar  ${image_file_path}
169
170    ${image_data}=  OperatingSystem.Get Binary File  ${image_file_path}
171    Upload Image To BMC  /upload/image  data=${image_data}
172    ${ret}  ${version_id}=  Verify Image Upload  ${image_version}
173    Should Be True  ${ret}
174
175    # Verify the image is 'READY' to be activated or if it's already active,
176    # set priority to 0 and reboot the BMC.
177    ${software_state}=  Read Properties  ${SOFTWARE_VERSION_URI}${version_id}
178    ${activation}=  Set Variable  &{software_state}[Activation]
179    Run Keyword If
180    ...  '${skip_if_active}' == 'true' and '${activation}' == '${ACTIVE}'
181    ...  Switch To Active Image And Pass  ${SOFTWARE_VERSION_URI}${version_id}
182    Should Be Equal As Strings  &{software_state}[Activation]  ${READY}
183
184    # Request the image to be activated.
185    ${args}=  Create Dictionary  data=${REQUESTED_ACTIVE}
186    Write Attribute  ${SOFTWARE_VERSION_URI}${version_id}
187    ...  RequestedActivation  data=${args}
188    ${software_state}=  Read Properties  ${SOFTWARE_VERSION_URI}${version_id}
189    Should Be Equal As Strings  &{software_state}[RequestedActivation]
190    ...  ${REQUESTED_ACTIVE}
191
192    # Does caller want to wait for activation to complete?
193    Run Keyword If  '${wait}' == '${0}'  Return From Keyword
194
195    # Verify code update was successful and Activation state is Active.
196    Wait For Activation State Change  ${version_id}  ${ACTIVATING}
197    ${software_state}=  Read Properties  ${SOFTWARE_VERSION_URI}${version_id}
198    Should Be Equal As Strings  &{software_state}[Activation]  ${ACTIVE}
199
200
201Switch To Active Image And Pass
202    [Documentation]  Make the given active image the image running on the BMC
203    ...              and pass the test.
204    [Arguments]  ${software_object}
205
206    # Description of argument(s):
207    # software_object  Software object path.
208    #                  (e.g. "/xyz/openbmc_project/software/f3b29aa8").
209
210    Set Host Software Property  ${software_object}  Priority  ${0}
211    OBMC Reboot (off)
212    Pass Execution  ${software_object} was already on the BMC.
213
214
215Activate Image And Verify No Duplicate Priorities
216    [Documentation]  Upload an image, and then check that no images have the
217    ...              same priority.
218    [Arguments]  ${image_file_path}  ${image_purpose}
219
220    # Description of argument(s):
221    # image_file_path  The path to the image to upload.
222    # image_purpose    The purpose in the image's MANIFEST file.
223
224    Upload And Activate Image  ${image_file_path}
225    Verify No Duplicate Image Priorities  ${image_purpose}
226
227
228Set Same Priority For Multiple Images
229    [Documentation]  Find two images, set the priorities to be the same, and
230    ...              verify that the priorities are not the same.
231    [Arguments]  ${version_purpose}
232
233    # Description of argument(s):
234    # version_purpose  Either BMC or host version purpose.
235    #                  (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"
236    #                        "xyz.openbmc_project.Software.Version.VersionPurpose.Host").
237
238    # Make sure we have more than two images.
239    ${software_objects}=  Get Software Objects  version_type=${version_purpose}
240    ${num_images}=  Get Length  ${software_objects}
241    Should Be True  1 < ${num_images}
242    ...  msg=Only found one image on the BMC with purpose ${version_purpose}.
243
244    # Set the priority of the second image to the priority of the first.
245    ${properties}=  Get Host Software Property  @{software_objects}[0]
246    Set Host Software Property  @{software_objects}[1]  Priority
247    ...  &{properties}[Priority]
248    Verify No Duplicate Image Priorities  ${version_purpose}
249
250    # Set the priority of the first image back to what it was before
251    Set Host Software Property  @{software_objects}[0]  Priority
252    ...  &{properties}[Priority]
253
254
255Delete Software Object
256    [Documentation]  Deletes an image from the BMC.
257    [Arguments]  ${software_object}
258
259    # Description of argument(s):
260    # software_object  The URI to the software image to delete.
261
262    ${arglist}=  Create List
263    ${args}=  Create Dictionary  data=${arglist}
264    ${resp}=  OpenBMC Post Request  ${software_object}/action/delete
265    ...  data=${args}
266    Should Be Equal As Strings  ${resp.status_code}  ${HTTP_OK}
267
268
269Delete Image And Verify
270    [Documentation]  Delete an image from the BMC and verify that it was
271    ...              removed from software and the /tmp/images directory.
272    [Arguments]  ${software_object}  ${version_type}
273
274    # Description of argument(s):
275    # software_object        The URI of the software object to delete.
276    # version_type  The type of the software object, e.g.
277    #               xyz.openbmc_project.Software.Version.VersionPurpose.Host
278    #               or xyz.openbmc_project.Software.Version.VersionPurpose.BMC.
279
280    Log To Console  Deleteing ${software_object}
281
282    # Delete the image.
283    Delete Software Object  ${software_object}
284    # TODO: If/when we don't have to delete twice anymore, take this out
285    Run Keyword And Ignore Error  Delete Software Object  ${software_object}
286
287    # Verify that it's gone from software.
288    ${software_objects}=  Get Software Objects  version_type=${version_type}
289    Should Not Contain  ${software_objects}  ${software_object}
290
291    # Check that there is no file in the /tmp/images directory.
292    ${image_id}=  Fetch From Right  ${software_object}  /
293    BMC Execute Command
294    ...  [ ! -d "/tmp/images/${image_id}" ]
295
296
297Check Error And Collect FFDC
298    [Documentation]  Collect FFDC if error log exists.
299
300    ${status}=  Run Keyword And Return Status  Error Logs Should Not Exist
301    Run Keyword If  '${status}' == 'False'  FFDC
302    Delete Error Logs
303
304
305Verify Running BMC Image
306    [Documentation]  Verify that the version on the BMC is the same as the
307    ...              version in the given image.
308    [Arguments]  ${image_file_path}
309
310    # Description of argument(s):
311    # image_file_path   Path to the BMC image tarball.
312
313    ${tar_version}=  Get Version Tar  ${image_file_path}
314    ${bmc_version}=  Get BMC Version
315    ${bmc_version}=  Remove String  ${bmc_version}  "
316    Should Be Equal  ${tar_version}  ${bmc_version}
317
318
319Verify Running Host Image
320    [Documentation]  Verify that the version of the PNOR image that is on the
321    ...              BMC is the same as the one in the given image.
322    [Arguments]  ${image_file_path}
323
324    # Description of argument(s):
325    # image_file_path   Path to the PNOR image tarball.
326
327    ${tar_version}=  Get Version Tar  ${image_file_path}
328    ${pnor_version}=  Get PNOR Version
329    Should Be Equal  ${tar_version}  ${pnor_version}
330