xref: /openbmc/openbmc-test-automation/lib/code_update_utils.robot (revision c7db60549b3a7f626809b2ac67c48f6ed5a4e89b)
1*** Settings ***
2Documentation   BMC and PNOR update utilities keywords.
3
4Library         code_update_utils.py
5Library         OperatingSystem
6Library         String
7Library         utilities.py
8Library         gen_robot_valid.py
9Variables       ../data/variables.py
10Resource        boot_utils.robot
11Resource        rest_client.robot
12Resource        openbmc_ffdc.robot
13
14*** Variables ***
15${ignore_err}    ${0}
16
17# Time in minutes.
18${IMAGE_UPLOAD_WAIT_TIMEOUT}     5
19
20*** Keywords ***
21
22Get Software Objects
23    [Documentation]  Get the host software objects and return as a list.
24    [Arguments]  ${version_type}=${VERSION_PURPOSE_HOST}
25
26    # Description of argument(s):
27    # version_type  Either BMC or host version purpose.
28    #               By default host version purpose string.
29    #  (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"
30    #        "xyz.openbmc_project.Software.Version.VersionPurpose.Host").
31
32    # Example:
33    # "data": [
34    #      "/xyz/openbmc_project/software/f3b29aa8",
35    #      "/xyz/openbmc_project/software/e49bc78e",
36    # ],
37    # Iterate the list and return the host object name path list.
38
39    ${host_list}=  Create List
40    ${sw_list}=  Read Properties  ${SOFTWARE_VERSION_URI}
41
42    FOR  ${index}  IN  @{sw_list}
43      ${attr_purpose}=  Read Software Attribute  ${index}  Purpose
44      Continue For Loop If  '${attr_purpose}' != '${version_type}'
45      Append To List  ${host_list}  ${index}
46    END
47
48    RETURN  ${host_list}
49
50
51Read Software Attribute
52    [Documentation]  Return software attribute data.
53    [Arguments]  ${software_object}  ${attribute_name}
54
55    # Description of argument(s):
56    # software_object   Software object path.
57    #                   (e.g. "/xyz/openbmc_project/software/f3b29aa8").
58    # attribute_name    Software object attribute name.
59
60    ${resp}=  OpenBMC Get Request  ${software_object}/attr/${attribute_name}
61    ...  quiet=${1}
62    Return From Keyword If  ${resp.status_code} != ${HTTP_OK}
63    RETURN  ${resp.json()["data"]}
64
65
66Get Software Objects Id
67    [Documentation]  Get the software objects id and return as a list.
68    [Arguments]  ${version_type}=${VERSION_PURPOSE_HOST}
69
70    # Description of argument(s):
71    # version_type  Either BMC or host version purpose.
72    #               By default host version purpose string.
73    #              (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"
74    #               "xyz.openbmc_project.Software.Version.VersionPurpose.Host").
75
76    ${sw_id_list}=  Create List
77    ${sw_list}=  Get Software Objects  ${version_type}
78
79    FOR  ${index}  IN  @{sw_list}
80        Append To List  ${sw_id_list}  ${index.rsplit('/', 1)[1]}
81    END
82    RETURN  ${sw_id_list}
83
84
85Get Host Software Property
86    [Documentation]  Return a dictionary of host software properties.
87    [Arguments]  ${host_object}
88
89    # Description of argument(s):
90    # host_object  Host software object path.
91    #             (e.g. "/xyz/openbmc_project/software/f3b29aa8").
92
93    ${sw_attributes}=  Read Properties  ${host_object}
94    RETURN  ${sw_attributes}
95
96Get Host Software Objects Details
97    [Documentation]  Return software object details as a list of dictionaries.
98    [Arguments]  ${quiet}=${QUIET}
99
100    ${software}=  Create List
101
102    ${pnor_details}=  Get Software Objects  ${VERSION_PURPOSE_HOST}
103    FOR  ${pnor}  IN  @{pnor_details}
104        ${resp}=  OpenBMC Get Request  ${pnor}  quiet=${1}
105        Append To List  ${software}  ${resp.json()["data"]}
106    END
107    RETURN  ${software}
108
109Set Host Software Property
110    [Documentation]  Set the host software properties of a given object.
111    [Arguments]  ${host_object}  ${sw_attribute}  ${data}
112
113    # Description of argument(s):
114    # host_object   Host software object name.
115    # sw_attribute  Host software attribute name.
116    #               (e.g. "Activation", "Priority", "RequestedActivation" etc).
117    # data          Value to be written.
118
119    ${args}=  Create Dictionary  data=${data}
120    Write Attribute  ${host_object}  ${sw_attribute}  data=${args}
121    # Sync time for software updater manager to update.
122    Sleep  10s
123
124
125Set Property To Invalid Value And Verify No Change
126    [Documentation]  Attempt to set a property and check that the value didn't
127    ...              change.
128    [Arguments]  ${property}  ${version_type}
129
130    # Description of argument(s):
131    # property      The property to attempt to set.
132    # version_type  Either BMC or host version purpose.
133    #               By default host version purpose string.
134    #  (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"
135    #        "xyz.openbmc_project.Software.Version.VersionPurpose.Host").
136
137    ${software_objects}=  Get Software Objects  version_type=${version_type}
138    ${prev_properties}=  Get Host Software Property  @{software_objects}[0]
139    Run Keyword And Expect Error  500 != 200
140    ...  Set Host Software Property  @{software_objects}[0]  ${property}  foo
141    ${cur_properties}=  Get Host Software Property  @{software_objects}[0]
142    Should Be Equal As Strings  &{prev_properties}[${property}]
143    ...  &{cur_properties}[${property}]
144
145
146Set Priority To Invalid Value And Expect Error
147    [Documentation]  Set the priority of an image to an invalid value and
148    ...              check that an error was returned.
149    [Arguments]  ${version_type}  ${priority}
150
151    # Description of argument(s):
152    # version_type  Either BMC or host version purpose.
153    #               (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"
154    #                     "xyz.openbmc_project.Software.Version.VersionPurpose.Host").
155    # priority      The priority value to set. Should be an integer outside of
156    #               the range of 0 through 255.
157
158    ${images}=  Get Software Objects  version_type=${version_type}
159    ${num_images}=  Get Length  ${images}
160    Should Be True  0 < ${num_images}
161
162    Run Keyword And Expect Error  403 != 200
163    ...  Set Host Software Property  @{images}[0]  Priority  ${priority}
164
165
166Redfish Upload Image
167    [Documentation]  Upload an image to the BMC via redfish.
168    [Arguments]  ${uri}  ${image_file_path}
169
170    # Description of argument(s):
171    # uri                 URI for uploading image via redfish.
172    # image_file_path     The path to the image tarball.
173
174    ${image_data}=  OperatingSystem.Get Binary File  ${image_file_path}
175
176    # Force time out for image file upload if failed to complete on time.
177    Wait Until Keyword Succeeds  1 times  ${IMAGE_UPLOAD_WAIT_TIMEOUT} min
178    ...  Upload Image To BMC  ${uri}  timeout=${240}  data=${image_data}
179
180
181Redfish Verify BMC Version
182    [Documentation]  Verify that the version on the BMC is the same as the
183    ...              version in the given image via Redfish.
184    [Arguments]      ${image_file_path}
185
186    # Description of argument(s):
187    # image_file_path   Path to the image tarball.
188
189    # Extract the version from the image tarball on our local system.
190    ${tar_version}=  Get Version Tar  ${image_file_path}
191    ${bmc_version}=  Redfish Get BMC Version
192
193    Valid Value  bmc_version  valid_values=['${tar_version}']
194
195
196Redfish Verify Host Version
197    [Documentation]  Verify that the version of the PNOR image that is on the
198    ...              BMC is the same as the one in the given image via Redfish.
199    [Arguments]      ${image_file_path}
200
201    # Description of argument(s):
202    # image_file_path   Path to the image tarball.
203
204    # Extract the version from the image tarball on our local system.
205    ${tar_version}=  Get Version Tar  ${image_file_path}
206    ${host_version}=  Redfish Get Host Version
207
208    Valid Value  host_version  valid_values=['${tar_version}']
209
210
211Upload And Activate Image
212    [Documentation]  Upload an image to the BMC and activate it with REST.
213    [Arguments]  ${image_file_path}  ${wait}=${1}  ${skip_if_active}=false
214
215    # Description of argument(s):
216    # image_file_path     The path to the image tarball to upload and activate.
217    # wait                Indicates that this keyword should wait for host or
218    #                     BMC activation is completed.
219    # skip_if_active      If set to true, will skip the code update if this
220    #                     image is already on the BMC.
221
222    OperatingSystem.File Should Exist  ${image_file_path}
223    ${image_version}=  Get Version Tar  ${image_file_path}
224
225    ${image_data}=  OperatingSystem.Get Binary File  ${image_file_path}
226
227    Wait Until Keyword Succeeds  3 times  120 sec
228    ...   Upload Image To BMC  /upload/image  timeout=${90}  data=${image_data}
229    ${ret}  ${version_id}=  Verify Image Upload  ${image_version}
230    Should Be True  ${ret}
231
232    # Verify the image is 'READY' to be activated or if it's already active,
233    # set priority to 0 and reboot the BMC.
234    ${software_state}=  Read Properties  ${SOFTWARE_VERSION_URI}${version_id}
235    ${activation}=  Set Variable  ${software_state}[Activation]
236
237    IF  '${skip_if_active}' == 'true' and '${activation}' == '${ACTIVE}'
238        Set Host Software Property  ${SOFTWARE_VERSION_URI}${version_id}  Priority  ${0}
239        Return From Keyword
240    END
241
242    Should Be Equal As Strings  ${software_state}[Activation]  ${READY}
243
244    # Request the image to be activated.
245    ${args}=  Create Dictionary  data=${REQUESTED_ACTIVE}
246    Write Attribute  ${SOFTWARE_VERSION_URI}${version_id}
247    ...  RequestedActivation  data=${args}
248    ${software_state}=  Read Properties  ${SOFTWARE_VERSION_URI}${version_id}
249    Should Be Equal As Strings  ${software_state}[RequestedActivation]
250    ...  ${REQUESTED_ACTIVE}
251
252    # Does caller want to wait for activation to complete?
253    Return From Keyword If  '${wait}' == '${0}'  ${version_id}
254
255    # Verify code update was successful and Activation state is Active.
256    Wait For Activation State Change  ${version_id}  ${ACTIVATING}
257    ${software_state}=  Read Properties  ${SOFTWARE_VERSION_URI}${version_id}
258    Should Be Equal As Strings  ${software_state}[Activation]  ${ACTIVE}
259
260    # Uploaded and activated image should have priority set to 0. Due to timing
261    # contention, it may take up to 10 seconds to complete updating priority.
262    Wait Until Keyword Succeeds  10 sec  5 sec
263    ...  Check Software Object Attribute  ${version_id}  Priority  ${0}
264
265    RETURN  ${version_id}
266
267
268Attempt To Reboot BMC During Image Activation
269    [Documentation]  Attempt to reboot the BMC while an image is activating and
270    ...              check that the BMC ignores the reboot command and finishes
271    ...              activation.
272    [Arguments]  ${image_file_path}
273
274    # Description of argument(s):
275    # image_file_path  Path to the image to update to.
276
277    # Attempt to reboot during activation.
278    ${version_id}=  Upload And Activate Image  ${image_file_path}
279    ...  wait=${0}
280    ${resp}=  OpenBMC Get Request  ${SOFTWARE_VERSION_URI}${version_id}
281    Should Be Equal As Strings  ${resp.status_code}  ${HTTP_OK}
282
283    OBMC Reboot (off)
284
285    ${resp}=  OpenBMC Get Request  ${SOFTWARE_VERSION_URI}${version_id}
286    Should Be Equal As Strings  ${resp.status_code}  ${HTTP_NOT_FOUND}
287
288
289Activate Image And Verify No Duplicate Priorities
290    [Documentation]  Upload an image, and then check that no images have the
291    ...              same priority.
292    [Arguments]  ${image_file_path}  ${image_purpose}
293
294    # Description of argument(s):
295    # image_file_path  The path to the image to upload.
296    # image_purpose    The purpose in the image's MANIFEST file.
297
298    Upload And Activate Image  ${image_file_path}  skip_if_active=true
299    Verify No Duplicate Image Priorities  ${image_purpose}
300
301
302Set Same Priority For Multiple Images
303    [Documentation]  Find two images, set the priorities to be the same, and
304    ...              verify that the priorities are not the same.
305    [Arguments]  ${version_purpose}
306
307    # Description of argument(s):
308    # version_purpose  Either BMC or host version purpose.
309    #                  (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"
310    #                        "xyz.openbmc_project.Software.Version.VersionPurpose.Host").
311
312    # Make sure we have more than two images.
313    ${software_objects}=  Get Software Objects  version_type=${version_purpose}
314    ${num_images}=  Get Length  ${software_objects}
315    Should Be True  1 < ${num_images}
316    ...  msg=Only found one image on the BMC with purpose ${version_purpose}.
317
318    # Set the priority of the second image to the priority of the first.
319    ${properties}=  Get Host Software Property  @{software_objects}[0]
320    Set Host Software Property  @{software_objects}[1]  Priority
321    ...  &{properties}[Priority]
322    Verify No Duplicate Image Priorities  ${version_purpose}
323
324    # Set the priority of the first image back to what it was before
325    Set Host Software Property  @{software_objects}[0]  Priority
326    ...  &{properties}[Priority]
327
328
329Delete Software Object
330    [Documentation]  Deletes an image from the BMC.
331    [Arguments]  ${software_object}
332
333    # Description of argument(s):
334    # software_object  The URI to the software image to delete.
335
336    ${args}=  Set Variable   {"data": []}
337    ${resp}=  OpenBMC Post Request  ${software_object}/action/Delete
338    ...  data=${args}
339    Should Be Equal As Strings  ${resp.status_code}  ${HTTP_OK}
340
341
342Delete Image And Verify
343    [Documentation]  Delete an image from the BMC and verify that it was
344    ...              removed from software and the /tmp/images directory.
345    [Arguments]  ${software_object}  ${version_type}
346
347    # Description of argument(s):
348    # software_object        The URI of the software object to delete.
349    # version_type  The type of the software object, e.g.
350    #               xyz.openbmc_project.Software.Version.VersionPurpose.Host
351    #               or xyz.openbmc_project.Software.Version.VersionPurpose.BMC.
352
353    Log To Console  Deleting ${software_object}
354
355    # Delete the image.
356    Delete Software Object  ${software_object}
357
358    # Verify that it's gone from software.
359    ${software_objects}=  Get Software Objects  version_type=${version_type}
360    Should Not Contain  ${software_objects}  ${software_object}
361
362    # Check that there is no file in the /tmp/images directory.
363    ${image_id}=  Fetch From Right  ${software_object}  /
364    BMC Execute Command
365    ...  [ ! -d "/tmp/images/${image_id}" ]
366
367
368Delete All Non Running BMC Images
369    [Documentation]  Delete all BMC images that are not running on the BMC.
370
371    ${args}=  Set Variable   {"data": []}
372    Call Method  ${SOFTWARE_VERSION_URI}  DeleteAll  data=${args}
373
374
375Check Error And Collect FFDC
376    [Documentation]  Collect FFDC if error log exists.
377
378    ${status}=  Run Keyword And Return Status  Error Logs Should Not Exist
379    IF  '${status}' == 'False'  FFDC
380    Delete Error Logs
381
382
383Verify Running BMC Image
384    [Documentation]  Verify that the version on the BMC is the same as the
385    ...              version in the given image.
386    [Arguments]  ${image_file_path}
387
388    # Description of argument(s):
389    # image_file_path   Path to the BMC image tarball.
390
391    ${tar_version}=  Get Version Tar  ${image_file_path}
392    ${bmc_version}=  Get BMC Version
393    ${bmc_version}=  Remove String  ${bmc_version}  "
394    Should Be Equal  ${tar_version}  ${bmc_version}
395
396
397Verify Running Host Image
398    [Documentation]  Verify that the version of the PNOR image that is on the
399    ...              BMC is the same as the one in the given image.
400    [Arguments]  ${image_file_path}
401
402    # Description of argument(s):
403    # image_file_path   Path to the PNOR image tarball.
404
405    ${tar_version}=  Get Version Tar  ${image_file_path}
406    ${pnor_version}=  Get PNOR Version
407    Should Be Equal  ${tar_version}  ${pnor_version}
408
409
410Get Least Value Priority Image
411    [Documentation]  Find the least value in "Priority" attribute and return.
412    [Arguments]  ${version_type}
413
414    # Description of argument(s):
415    # version_type  Either BMC or host version purpose.
416
417    ${priority_value_list}=  Create List
418    ${sw_list}=  Get Software Objects  version_type=${version_type}
419
420    FOR  ${index}  IN  @{sw_list}
421        ${priority_value}=
422        ...  Read Software Attribute  ${index}  Priority
423        Append To List  ${priority_value_list}  ${priority_value}
424    END
425    ${min_value}=  Min List Value  ${priority_value_list}
426
427    RETURN  ${min_value}
428
429
430Enable Field Mode And Verify Unmount
431    [Documentation]  Enable field mode and check that /usr/local is unmounted.
432
433    # After running, /xyz/openbmc_project/software should look like this:
434    # /xyz/openbmc_project/software
435    # {
436    #     "FieldModeEnabled": 1,
437    #     "associations": [
438    #         [
439    #             "active",
440    #             "software_version",
441    #             "/xyz/openbmc_project/software/fcf8e182"
442    #         ],
443    #         [
444    #             "functional",
445    #             "functional",
446    #             "/xyz/openbmc_project/software/fcf8e182"
447    #         ]
448    #     ]
449    # }
450
451    ${args}=  Create Dictionary  data=${1}
452    Write Attribute  ${SOFTWARE_VERSION_URI}  FieldModeEnabled  data=${args}
453    Sleep  5s
454    BMC Execute Command  [ ! -d "/usr/local/share" ]
455
456
457Disable Field Mode And Verify Unmount
458    [Documentation]  Disable field mode, unmask usr local mount and reboot.
459
460    BMC Execute Command  /sbin/fw_setenv fieldmode
461    BMC Execute Command  /bin/systemctl unmask usr-local.mount
462    OBMC Reboot (off)  stack_mode=normal
463    BMC Execute Command  [ -d "/usr/local/share" ]
464
465
466Field Mode Should Be Enabled
467    [Documentation]  Check that field mode is enabled.
468
469    ${value}=  Read Attribute  ${SOFTWARE_VERSION_URI}  FieldModeEnabled
470    Should Be True  ${value}  ${1}
471
472List Installed Images
473    [Documentation]  List all the installed images.
474    [Arguments]  ${image_type}
475
476    # Description of argument(s):
477    # image_type  Either "BMC" or "PNOR".
478
479    # List the installed images.
480    ${installed_images}=  Get Software Objects
481    ...  ${SOFTWARE_PURPOSE}.${image_type}
482
483    IF  ${installed_images} != []
484        Get List of Images  ${installed_images}
485    ELSE
486        Log  No ${image_type} images are present.
487    END
488
489Get List of Images
490    [Documentation]  Get List of Images
491    [Arguments]  ${installed_images}
492
493    FOR  ${uri}  IN  @{installed_images}
494      ${resp}=  OpenBMC Get Request  ${uri}
495      Log  ${resp.json()["data"]}
496    END
497
498
499Check Software Object Attribute
500    [Documentation]  Get the software property of a given object and verify.
501    [Arguments]  ${image_object}  ${sw_attribute}  ${value}
502
503    # Description of argument(s):
504    # image_object  Image software object name.
505    # sw_attribute  Software attribute name.
506    #               (e.g. "Activation", "Priority", "RequestedActivation" etc).
507    # value         Software attribute value to compare.
508
509    ${data}=  Read Attribute
510    ...  ${SOFTWARE_VERSION_URI}${image_object}  ${sw_attribute}
511
512    Should Be True  ${data} == ${value}
513    ...  msg=Given attribute value ${data} mismatch ${value}.
514
515
516Image Should Be Signed
517    [Documentation]  Fail if the image is not signed.
518
519    Directory Should Exist  ${ACTIVATION_DIR_PATH}
520    ...  msg=${ACTIVATION_DIR_PATH} does not exist. Therefore, the image is not signed.
521
522
523Get Latest Image ID
524    [Documentation]  Return the ID of the most recently extracted image.
525    # Note: This keyword will fail if there is no such file.
526
527    # Example: # ls /tmp/images/
528    #            1b714fb7
529    ${image_id}=  Get Latest File  /tmp/images/
530
531    Return From Keyword If  '${image_id}' != '${EMPTY}'  ${image_id}
532
533    ${image_id}=   Get Image Id   Updating
534    RETURN  ${image_id}
535
536
537Check Image Update Progress State
538    [Documentation]  Check that the image update progress state matches the specified state.
539    [Arguments]  ${match_state}  ${image_id}
540
541    # Description of argument(s):
542    # match_state    The expected state. This may be one or more comma-separated values
543    #                (e.g. "Disabled", "Disabled, Updating"). If the actual state matches
544    #                any of the states named in this argument, this keyword passes.
545    # image_id       The image ID (e.g. "1b714fb7").
546
547    ${state}=  Get Image Update Progress State  image_id=${image_id}
548    Valid Value  state  valid_values=[${match_state}]
549
550
551Get All Task
552    [Documentation]  Get all the active tasks.
553    [Arguments]  ${target_uri}  ${match_status}  ${match_state}
554
555    # Description of argument(s):
556    # target_uri      Target URI.
557    # match_status    The expected status. The value is (e.g. OK). If the actual state matches
558    #                 any of the states named in this argument, this keyword passes.
559    # match_state     The expected state. This may be one or more comma-separated values
560    #                 (e.g. Running, Completed). If the actual state matches
561    #                 any of the states named in this argument, this keyword passes.
562
563    ${task_list}=  Redfish.Get Members List  /redfish/v1/TaskService/Tasks
564    ${num_records}=  Get Length  ${task_list}
565    Return From Keyword If  ${num_records} == ${0}  ${EMPTY
566
567    ${task_dict}=  Get Task Objects  ${task_list}
568
569    ${task_inventory}=  Check Task Attribute  ${target_uri}  ${match_status}  ${match_state}  ${task_dict}
570
571    ${num_records}=  Get Length  ${task_inventory}
572    Return From Keyword If  ${num_records} == ${0}  ${EMPTY}
573
574    RETURN  ${task_inventory}
575
576
577Get Task Objects
578    [Documentation]  Check all the task to filter update service target URI and
579    ...  return the task attributes as dictionary.
580    [Arguments]  ${task_list}
581
582    # Description of argument(s):
583    # task_list  List of all active task.
584
585    &{task_inv_dict}=  Create Dictionary
586
587    FOR  ${task_id}  IN  @{task_list}
588      &{tmp_dict}=  Create Dictionary
589      ${task_payload}=  Redfish.Get Attribute  ${task_id}  Payload
590      Set To Dictionary  ${tmp_dict}  TargetUri  ${task_payload['TargetUri']}
591
592      ${task_state}=  Redfish.Get Attribute  ${task_id}  TaskState
593      Set To Dictionary  ${tmp_dict}  TaskState  ${task_state}
594
595      ${task_status}=  Redfish.Get Attribute  ${task_id}  TaskStatus
596      Set To Dictionary  ${tmp_dict}  TaskStatus  ${task_status}
597      Set To Dictionary  ${task_inv_dict}  ${task_id.split("/")[-1]}  ${tmp_dict}
598    END
599
600    RETURN  ${task_inv_dict}
601
602
603Check Task Attribute
604    [Documentation]  Get the active task progress state.
605    [Arguments]  ${target_uri}  ${match_status}  ${match_state}  ${task_dict}
606
607    # Description of argument(s):
608    # target_uri      Active task which has update service target URI.
609    # match_status    The expected status. The value is (e.g. OK). If the actual state matches
610    #                 any of the states named in this argument, this keyword passes.
611    # match_state     The expected state. This may be one or more comma-separated values
612    #                 (e.g. Running, Completed). If the actual state matches
613    #                 any of the states named in this argument, this keyword passes.
614    # task_dict       Task inventory.
615
616    Return From Keyword If  ${target_uri} == '' or ${target_uri} == None  ${task_dict}
617    Return From Keyword If  ${match_state} == '' or ${match_state} == None  ${task_dict}
618
619    FOR  ${task_ins}  IN  @{task_dict.items()}
620      &{tmp_dict}=  Create Dictionary
621      Set To Dictionary  ${tmp_dict}  ${task_ins[0]}  ${task_ins[1]}
622      Return From Keyword If
623      ...  ${target_uri} == '${task_ins[1]['TargetUri']}' and ${match_state} == '${task_ins[1]['TaskState']}'
624      ...  ${tmp_dict}
625    END
626
627    RETURN  ${EMPTY}
628
629
630Check Task Progress State
631    [Documentation]  Check that the task update progress state matches the specified state.
632    [Arguments]  ${task_inv_dict}  ${match_status}  ${match_state}
633
634    # Description of argument(s):
635    # task_inv_dict    Task inventory dictionary.
636    # match_status     The expected state. The value is (e.g. OK). If the actual state matches
637    #                  any of the states named in this argument, this keyword passes.
638    # match_state      The expected state. This may be one or more comma-separated values
639    #                  (e.g. Running, Completed). If the actual state matches
640    #                  any of the states named in this argument, this keyword passes.
641
642    FOR  ${task_ins}  IN  @{task_inv_dict.items()}
643      ${task_state}=  Redfish.Get Attribute  /redfish/v1/TaskService/Tasks/${task_ins}[0]  TaskState
644      ${task_status}=  Redfish.Get Attribute  /redfish/v1/TaskService/Tasks/${task_ins}[0]  TaskStatus
645      ${task_payload}=  Redfish.Get Attribute  /redfish/v1/TaskService/Tasks/${task_ins}[0]  Payload
646
647      Rprint Vars  task_state
648      Rprint Vars  task_status
649      Rprint Vars  task_payload['TargetUri']
650
651      Valid Value  task_state  valid_values=[${match_state}]
652      Valid Value  task_status  valid_values=[${match_status}]
653    END
654
655
656Get Image Id
657    [Documentation]  Get image id.
658    [Arguments]  ${match_state}
659
660    # Description of argument(s):
661    # match_state    The expected state. This may be one or more comma-separated values
662    #                (e.g. "Disabled", "Disabled, Updating"). If the actual state matches
663    #                any of the states named in this argument, this keyword passes.
664
665    ${sw_member_list}=  Redfish.Get Members List  /redfish/v1/UpdateService/FirmwareInventory
666
667    FOR  ${sw_member}  IN  @{sw_member_list}
668      ${status}=  Redfish.Get Attribute  ${sw_member}  Status
669      Return From Keyword If  '${status['State']}' == '${match_state}'
670      ...  ${sw_member.split('/')[-1]}
671    END
672
673    RETURN  None
674
675
676Get Image Update Progress State
677    [Documentation]  Return the current state of the image update.
678    [Arguments]  ${image_id}
679
680    # Description of argument(s):
681    # image_id         The image ID (e.g. "1b714fb7").
682
683    # In this example, this keyword would return the value "Enabled".
684    #  "Status": {
685    #              "Health": "OK",
686    #              "HealthRollup": "OK",
687    #              "State": "Enabled"
688    #            },
689    ${status}=  Redfish.Get Attribute  /redfish/v1/UpdateService/FirmwareInventory/${image_id}  Status
690    Rprint Vars  status
691
692    RETURN  ${status["State"]}
693
694
695Get Firmware Image Version
696    [Documentation]  Get the version of the currently installed firmware and return it.
697    [Arguments]  ${image_id}
698
699    # Description of argument(s):
700    # image_id      The image ID (e.g. "1b714fb7").
701
702    # Example of a version returned by this keyword:
703    # 2.8.0-dev-19-g6d5764b33
704    ${version}=  Redfish.Get Attribute  /redfish/v1/UpdateService/FirmwareInventory/${image_id}  Version
705    Rprint Vars  version
706
707    RETURN  ${version}
708
709
710Get ApplyTime
711    [Documentation]  Get the firmware "ApplyTime" policy.
712    [Arguments]  ${policy}
713
714    # Description of argument(s):
715    # policy     ApplyTime allowed values (e.g. "OnReset", "Immediate").
716
717    ${system_applytime}=  Redfish.Get Attribute  ${REDFISH_BASE_URI}UpdateService  HttpPushUriOptions
718
719    RETURN  ${system_applytime["HttpPushUriApplyTime"]["ApplyTime"]}
720
721
722Verify Get ApplyTime
723    [Documentation]  Get and verify the firmware "ApplyTime" policy.
724    [Arguments]  ${policy}
725
726    # Description of argument(s):
727    # policy     ApplyTime allowed values (e.g. "OnReset", "Immediate").
728
729    ${system_applytime}=  Get ApplyTime  ${policy}
730    Rprint Vars  system_applytime
731    Valid Value  system_applytime  ['${policy}']
732
733
734Set ApplyTime
735    [Documentation]  Set and verify the firmware "ApplyTime" policy.
736    [Arguments]  ${policy}
737
738    # Description of argument(s):
739    # policy     ApplyTime allowed values (e.g. "OnReset", "Immediate").
740
741    Redfish.Patch  ${REDFISH_BASE_URI}UpdateService
742    ...  body={'HttpPushUriOptions' : {'HttpPushUriApplyTime' : {'ApplyTime' : '${policy}'}}}
743    ...  valid_status_codes=[${HTTP_OK}, ${HTTP_NO_CONTENT}]
744    Verify Get ApplyTime  ${policy}
745
746
747Get Image Version From TFTP Server
748    [Documentation]  Get and return the image version
749    ...  from the TFTP server.
750    [Arguments]  ${server_host}  ${image_file_name}
751
752    # Description of argument(s):
753    # server_host   The host name or IP address of the TFTP server.
754    # image_file_name  The file name of the image.
755
756    Shell Cmd
757    ...  curl -s tftp://${server_host}/${image_file_name} > tftp_image.tar
758    ${version}=  Get Version Tar  tftp_image.tar
759    OperatingSystem.Remove File  tftp_image.tar
760
761    RETURN  ${version}
762
763
764Redfish Update Firmware
765    [Documentation]  Update the BMC firmware via redfish interface.
766    [Arguments]  ${apply_time}
767
768    # Description of argument(s):
769    # apply_time     ApplyTime allowed values (e.g. "OnReset", "Immediate").
770
771    ${post_code_update_actions}=  Get Post Boot Action
772    ${state}=  Get Pre Reboot State
773    Rprint Vars  state
774    Set ApplyTime  policy=${apply_Time}
775
776    ${task_inv_dict}=  Get Task State from File
777
778    ${file_bin_data}=  OperatingSystem.Get Binary File  ${image_file_path}
779
780
781    Log To Console   Start uploading image to BMC.
782
783    # URI : /redfish/v1/UpdateService
784    # "HttpPushUri": "/redfish/v1/UpdateService/update",
785
786    ${redfish_update_uri}=  Get Redfish Update Service URI
787
788    ${resp}=  Upload Image To BMC  ${redfish_update_uri}  timeout=${600}  data=${file_bin_data}
789
790    Log To Console   Completed image upload to BMC.
791
792    Sleep  5s
793
794    ${task_inv}=  Check Task With Match TargetUri  ${redfish_update_uri}
795
796    Rprint Vars  task_inv
797
798    Wait Until Keyword Succeeds  5 min  10 sec
799    ...  Verify Task Progress State  ${task_inv}  ${task_inv_dict['TaskCompleted']}
800
801    Run Key  ${post_code_update_actions['BMC image']['${apply_time}']}
802    Redfish.Login
803    Redfish Verify BMC Version  ${IMAGE_FILE_PATH}
804    Verify Get ApplyTime  ${apply_time}
805
806