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 Host Software Property
58    [Documentation]  Return a dictionary of host software properties.
59    [Arguments]  ${host_object}
60
61    # Description of argument(s):
62    # host_object  Host software object path.
63    #             (e.g. "/xyz/openbmc_project/software/f3b29aa8").
64
65    ${sw_attributes}=  Read Properties  ${host_object}
66    [return]  ${sw_attributes}
67
68Get Host Software Objects Details
69    [Documentation]  Return software object details as a list of dictionaries.
70    [Arguments]  ${quiet}=${QUIET}
71
72    ${software}=  Create List
73
74    ${pnor_details}=  Get Software Objects  ${VERSION_PURPOSE_HOST}
75    :FOR  ${pnor}  IN  @{pnor_details}
76    \  ${resp}=  OpenBMC Get Request  ${pnor}  quiet=${1}
77    \  ${json}=  To JSON  ${resp.content}
78    \  Append To List  ${software}  ${json["data"]}
79
80    [Return]  ${software}
81
82Set Host Software Property
83    [Documentation]  Set the host software properties of a given object.
84    [Arguments]  ${host_object}  ${sw_attribute}  ${data}
85
86    # Description of argument(s):
87    # host_object   Host software object name.
88    # sw_attribute  Host software attribute name.
89    #               (e.g. "Activation", "Priority", "RequestedActivation" etc).
90    # data          Value to be written.
91
92    ${args}=  Create Dictionary  data=${data}
93    Write Attribute  ${host_object}  ${sw_attribute}  data=${args}
94
95
96Set Property To Invalid Value And Verify No Change
97    [Documentation]  Attempt to set a property and check that the value didn't
98    ...              change.
99    [Arguments]  ${property}  ${version_type}
100
101    # Description of argument(s):
102    # property      The property to attempt to set.
103    # version_type  Either BMC or host version purpose.
104    #               By default host version purpose string.
105    #  (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"
106    #        "xyz.openbmc_project.Software.Version.VersionPurpose.Host").
107
108    ${software_objects}=  Get Software Objects  version_type=${version_type}
109    ${prev_properties}=  Get Host Software Property  @{software_objects}[0]
110    Run Keyword And Expect Error  500 != 200
111    ...  Set Host Software Property  @{software_objects}[0]  ${property}  foo
112    ${cur_properties}=  Get Host Software Property  @{software_objects}[0]
113    Should Be Equal As Strings  &{prev_properties}[${property}]
114    ...  &{cur_properties}[${property}]
115
116
117Set Priority To Invalid Value And Expect Error
118    [Documentation]  Set the priority of an image to an invalid value and
119    ...              check that an error was returned.
120    [Arguments]  ${version_type}  ${priority}
121
122    # Description of argument(s):
123    # version_type  Either BMC or host version purpose.
124    #               (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"
125    #                     "xyz.openbmc_project.Software.Version.VersionPurpose.Host").
126    # priority      The priority value to set. Should be an integer outside of
127    #               the range of 0 through 255.
128
129    ${images}=  Get Software Objects  version_type=${version_type}
130    ${num_images}=  Get Length  ${images}
131    Should Be True  0 < ${num_images}
132
133    Run Keyword And Expect Error  403 != 200
134    ...  Set Host Software Property  @{images}[0]  Priority  ${priority}
135
136
137Upload And Activate Image
138    [Documentation]  Upload an image to the BMC and activate it with REST.
139    [Arguments]  ${image_file_path}
140
141    # Description of argument(s):
142    # image_file_path  The path to the image tarball to upload and activate.
143
144    OperatingSystem.File Should Exist  ${image_file_path}
145    ${image_version}=  Get Version Tar  ${image_file_path}
146
147    ${image_data}=  OperatingSystem.Get Binary File  ${image_file_path}
148    Upload Image To BMC  /upload/image  data=${image_data}
149    ${ret}  ${version_id}=  Verify Image Upload  ${image_version}
150    Should Be True  ${ret}
151
152    # Verify the image is 'READY' to be activated.
153    ${software_state}=  Read Properties  ${SOFTWARE_VERSION_URI}${version_id}
154    Should Be Equal As Strings  &{software_state}[Activation]  ${READY}
155
156    # Request the image to be activated.
157    ${args}=  Create Dictionary  data=${REQUESTED_ACTIVE}
158    Write Attribute  ${SOFTWARE_VERSION_URI}${version_id}
159    ...  RequestedActivation  data=${args}
160    ${software_state}=  Read Properties  ${SOFTWARE_VERSION_URI}${version_id}
161    Should Be Equal As Strings  &{software_state}[RequestedActivation]
162    ...  ${REQUESTED_ACTIVE}
163
164    # Verify code update was successful and Activation state is Active.
165    Wait For Activation State Change  ${version_id}  ${ACTIVATING}
166    ${software_state}=  Read Properties  ${SOFTWARE_VERSION_URI}${version_id}
167    Should Be Equal As Strings  &{software_state}[Activation]  ${ACTIVE}
168
169
170Activate Image And Verify No Duplicate Priorities
171    [Documentation]  Upload an image, and then check that no images have the
172    ...              same priority.
173    [Arguments]  ${image_file_path}  ${image_purpose}
174
175    # Description of argument(s):
176    # image_file_path  The path to the image to upload.
177    # image_purpose    The purpose in the image's MANIFEST file.
178
179    Upload And Activate Image  ${image_file_path}
180    Verify No Duplicate Image Priorities  ${image_purpose}
181
182
183Set Same Priority For Multiple Images
184    [Documentation]  Find two images, set the priorities to be the same, and
185    ...              verify that the priorities are not the same.
186    [Arguments]  ${version_purpose}
187
188    # Description of argument(s):
189    # version_purpose  Either BMC or host version purpose.
190    #                  (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"
191    #                        "xyz.openbmc_project.Software.Version.VersionPurpose.Host").
192
193    # Make sure we have more than two images.
194    ${software_objects}=  Get Software Objects  version_type=${version_purpose}
195    ${num_images}=  Get Length  ${software_objects}
196    Should Be True  1 < ${num_images}
197    ...  msg=Only found one image on the BMC with purpose ${version_purpose}.
198
199    # Set the priority of the second image to the priority of the first.
200    ${properties}=  Get Host Software Property  @{software_objects}[0]
201    Set Host Software Property  @{software_objects}[1]  Priority
202    ...  &{properties}[Priority]
203    Verify No Duplicate Image Priorities  ${version_purpose}
204
205    # Set the priority of the first image back to what it was before
206    Set Host Software Property  @{software_objects}[0]  Priority
207    ...  &{properties}[Priority]
208
209
210Delete Software Object
211    [Documentation]  Deletes an image from the BMC.
212    [Arguments]  ${software_object}
213
214    # Description of argument(s):
215    # software_object  The URI to the software image to delete.
216
217    ${arglist}=  Create List
218    ${args}=  Create Dictionary  data=${arglist}
219    ${resp}=  OpenBMC Post Request  ${software_object}/action/delete
220    ...  data=${args}
221    Should Be Equal As Strings  ${resp.status_code}  ${HTTP_OK}
222
223
224Delete Image And Verify
225    [Documentation]  Delete an image from the BMC and verify that it was
226    ...              removed from software and the /tmp/images directory.
227    [Arguments]  ${software_object}  ${version_type}
228
229    # Description of argument(s):
230    # software_object        The URI of the software object to delete.
231    # version_type  The type of the software object, e.g.
232    #               xyz.openbmc_project.Software.Version.VersionPurpose.Host
233    #               or xyz.openbmc_project.Software.Version.VersionPurpose.BMC.
234
235    Log To Console  Deleteing ${software_object}
236
237    # Delete the image.
238    Delete Software Object  ${software_object}
239    # TODO: If/when we don't have to delete twice anymore, take this out
240    Run Keyword And Ignore Error  Delete Software Object  ${software_object}
241
242    # Verify that it's gone from software.
243    ${software_objects}=  Get Software Objects  version_type=${version_type}
244    Should Not Contain  ${software_objects}  ${software_object}
245
246    # Check that there is no file in the /tmp/images directory.
247    ${image_id}=  Fetch From Right  ${software_object}  /
248    BMC Execute Command
249    ...  [ ! -d "/tmp/images/${image_id}" ]
250
251
252Check Error And Collect FFDC
253    [Documentation]  Collect FFDC if error log exists.
254
255    ${status}=  Run Keyword And Return Status  Error Logs Should Not Exist
256    Run Keyword If  '${status}' == 'False'  FFDC
257    Delete Error Logs
258