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