blob: 96dd2656e4e8d98d01a3335a6854e4dd7104982f [file] [log] [blame]
*** Settings ***
Documentation Redfish BMC and PNOR software utilities keywords.
Library code_update_utils.py
Library gen_robot_valid.py
Library tftp_update_utils.py
Resource bmc_redfish_utils.robot
Resource boot_utils.robot
*** Keywords ***
Get Software Functional State
[Documentation] Return functional or active state of the software (i.e. True/False).
[Arguments] ${image_id}
# Description of argument(s):
# image_id The image ID (e.g. "acc9e073").
${resp}= Redfish.Get /redfish/v1/UpdateService/FirmwareInventory/${image_id}
... valid_status_codes=[${HTTP_OK}, ${HTTP_INTERNAL_SERVER_ERROR}]
${image_info} Set Variable ${resp.dict}
${sw_functional}= Run Keyword If
... '${image_info["Description"]}' == 'BMC image' or '${image_info["Description"]}' == 'BMC update'
... Redfish.Get Attribute /redfish/v1/Managers/${MANAGER_ID} FirmwareVersion
... ELSE
... Redfish.Get Attribute /redfish/v1/Systems/${SYSTEM_ID} BiosVersion
${functional}= Run Keyword And Return Status
... Should Be Equal ${sw_functional} ${image_info["Version"]}
# If they are not same, return from here.
Return From Keyword If '${functional}' == 'False' ${functional}
# WHen the functional and backup firmware versions are same, this ensure, we rightly set the
# test inventory dictionary for the firmware functional status.
Run Keyword If
... '${image_info["Description"]}' == 'BMC image' or '${image_info["Description"]}' == 'BMC update'
... Run Keyword And Return Find Active Software Image ${image_id}
[Return] ${functional}
Find Active Software Image
[Documentation] Match the firmware id of ActiveSoftwareImage attribute with the input id.
... The ActiveSoftwareImage id is the current functional BMC firmware.
[Arguments] ${image_id}
# Description of argument(s):
# image_id The image ID (e.g. "acc9e073").
# This attribute tells which is the firmware version currently functional.
# "ActiveSoftwareImage": {
# "@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/5ca9fec0"
# },
${active_sw_img}= Redfish.Get Attribute /redfish/v1/Managers/${MANAGER_ID} Links
${active_id}= Set Variable ${active_sw_img["ActiveSoftwareImage"]["@odata.id"].split("/")[-1]}
${matched_functional}= Run Keyword And Return Status
... Should Be Equal As Strings ${image_id} ${active_id}
# Returns True if matched else False.
[Return] ${matched_functional}
Get Software Inventory State
[Documentation] Return dictionary of the image type, version and functional state
... of the software objects active on the system.
# User defined state for software objects.
# Note: "Functional" term refers to firmware which system is currently booted with.
# sw_inv_dict:
# [ace821ef]:
# [image_type]: Host update
# [image_id]: ace821ef
# [functional]: True
# [version]: witherspoon-xx.xx.xx.xx
# [b9101858]:
# [image_type]: BMC update
# [image_id]: b9101858
# [functional]: True
# [version]: 2.8.0-dev-150-g04508dc9f
# [c45eafa5]:
# [image_type]: BMC update
# [image_id]: c45eafa5
# [functional]: False
# [version]: 2.8.0-dev-149-g1a8df5077
${sw_member_list}= Redfish_Utils.Get Member List /redfish/v1/UpdateService/FirmwareInventory
&{sw_inv_dict}= Create Dictionary
# sw_member_list:
# [0]: /redfish/v1/UpdateService/FirmwareInventory/98744d76
# [1]: /redfish/v1/UpdateService/FirmwareInventory/9a8028ec
# [2]: /redfish/v1/UpdateService/FirmwareInventory/acc9e073
FOR ${uri_path} IN @{sw_member_list}
&{tmp_dict}= Create Dictionary
${resp}= Redfish.Get ${uri_path} valid_status_codes=[${HTTP_OK}, ${HTTP_INTERNAL_SERVER_ERROR}]
${image_info} Set Variable ${resp.dict}
Set To Dictionary ${tmp_dict} image_type ${image_info["Description"]}
Set To Dictionary ${tmp_dict} image_id ${uri_path.split("/")[-1]}
${functional}= Get Software Functional State ${uri_path.split("/")[-1]}
Set To Dictionary ${tmp_dict} functional ${functional}
Set To Dictionary ${tmp_dict} version ${image_info["Version"]}
Set To Dictionary ${sw_inv_dict} ${uri_path.split("/")[-1]} ${tmp_dict}
END
[Return] &{sw_inv_dict}
Get Software Inventory State By Version
[Documentation] Return the software inventory record that matches the given software version.
[Arguments] ${software_version}
# If no matchine record can be found, return ${EMPTY}.
# Example of returned data:
# software_inventory_record:
# [image_type]: BMC update
# [image_id]: 1e662ba8
# [functional]: True
# [version]: 2.8.0-dev-150-g04508dc9f
# Description of argument(s):
# software_version A BMC or Host version (e.g "2.8.0-dev-150-g04508dc9f").
${software_inventory}= Get Software Inventory State
# Filter out entries that don't match the criterion..
${software_inventory}= Filter Struct ${software_inventory} [('version', '${software_version}')]
# Convert from dictionary to list.
${software_inventory}= Get Dictionary Values ${software_inventory}
${num_records}= Get Length ${software_inventory}
Return From Keyword If ${num_records} == ${0} ${EMPTY}
# Return the first list entry.
[Return] ${software_inventory}[0]
Get BMC Functional Firmware
[Documentation] Get BMC functional firmware details.
${sw_inv}= Get Functional Firmware BMC update
${sw_inv}= Get Non Functional Firmware ${sw_inv} True
[Return] ${sw_inv}
Get Functional Firmware
[Documentation] Get all the BMC firmware details.
[Arguments] ${image_type}
# Description of argument(s):
# image_type Image value can be either BMC update or Host update.
${software_inventory}= Get Software Inventory State
${bmc_inv}= Get BMC Firmware ${image_type} ${software_inventory}
[Return] ${bmc_inv}
Get Non Functional Firmware
[Documentation] Get BMC non functional firmware details.
[Arguments] ${sw_inv} ${functional_state}
# Description of argument(s):
# sw_inv This dictionary contains all the BMC firmware details.
# functional_state Functional state can be either True or False.
${resp}= Filter Struct ${sw_inv} [('functional', ${functional_state})]
${num_records}= Get Length ${resp}
Set Global Variable ${num_records}
Return From Keyword If ${num_records} == ${0} ${EMPTY}
${list_inv_dict}= Get Dictionary Values ${resp}
[Return] ${list_inv_dict}[0]
Get Non Functional Firmware List
[Documentation] Get BMC non functional firmware details.
[Arguments] ${sw_inv} ${functional_state}
# Description of argument(s):
# sw_inv This dictionary contains all the BMC firmware details.
# functional_state Functional state can be either True or False.
${list_inv}= Create List
FOR ${key} IN @{sw_inv.keys()}
Run Keyword If '${sw_inv['${key}']['functional']}' == '${functional_state}'
... Append To List ${list_inv} ${sw_inv['${key}']}
END
[Return] ${list_inv}
Get Redfish Update Service URI
[Documentation] Get Redfish firmware update URI.
${update_url}= Redfish.Get Attribute ${REDFISH_BASE_URI}UpdateService HttpPushUri
Log To Console Firmware update URI: ${update_url}
[Return] ${update_url}
Redfish Upload Image And Check Progress State
[Documentation] Code update with ApplyTime.
Log To Console Start uploading image to BMC.
# URI : /redfish/v1/UpdateService
# "HttpPushUri": "/redfish/v1/UpdateService/update",
${redfish_update_uri}= Get Redfish Update Service URI
Redfish Upload Image ${redfish_update_uri} ${IMAGE_FILE_PATH}
Log To Console Completed image upload to BMC.
${image_id}= Get Latest Image ID
Rprint Vars image_id
# We have noticed firmware inventory state Enabled quickly as soon the image
# is uploaded via redfish.
Wait Until Keyword Succeeds 2 min 05 sec
... Check Image Update Progress State match_state='Disabled', 'Updating', 'Enabled' image_id=${image_id}
Wait Until Keyword Succeeds 8 min 10 sec
... Check Image Update Progress State
... match_state='Enabled' image_id=${image_id}
Get Host Power State
[Documentation] Get host power state.
[Arguments] ${quiet}=0
# Description of arguments:
# quiet Indicates whether results should be printed.
${state}= Redfish.Get Attribute
... ${REDFISH_BASE_URI}Systems/${SYSTEM_ID} PowerState
Rqprint Vars state
[Return] ${state}
Check Host Power State
[Documentation] Check that the machine's host state matches
... the caller's required host state.
[Arguments] ${match_state}
# Description of argument(s):
# match_state The expected state. This may be one or more
# comma-separated values (e.g. "On", "Off").
# If the actual state matches any of the
# states named in this argument,
# this keyword passes.
${state}= Get Host Power State
Rvalid Value state valid_values=[${match_state}]
Get System Firmware Details
[Documentation] Return dictionary of system firmware details.
# {
# FirmwareVersion: 2.8.0-dev-1067-gdc66ce1c5,
# BiosVersion: witherspoon-XXX-XX.X-X
# }
${firmware_version}= Redfish Get BMC Version
${bios_version}= Redfish Get Host Version
&{sys_firmware_dict}= Create Dictionary
Set To Dictionary
... ${sys_firmware_dict} FirmwareVersion ${firmware_version} BiosVersion ${bios_version}
Rprint Vars sys_firmware_dict
[Return] &{sys_firmware_dict}
Switch Backup Firmware Image To Functional
[Documentation] Switch the backup firmware image to make functional.
${sw_inv}= Get Functional Firmware BMC image
${nonfunctional_sw_inv}= Get Non Functional Firmware ${sw_inv} False
${firmware_inv_path}=
... Set Variable /redfish/v1/UpdateService/FirmwareInventory/${nonfunctional_sw_inv['image_id']}
# Below URI, change to backup image and reset the BMC.
Redfish.Patch /redfish/v1/Managers/${MANAGER_ID}
... body={'Links': {'ActiveSoftwareImage': {'@odata.id': '${firmware_inv_path}'}}}
Create List Of Task
[Documentation] Return list of task id(s) from provided list of dictionary.
[Arguments] ${task_dict_list}
# Description of argument(s):
# task_dict_list Task id dictionary list.
# '@odata.id': '/redfish/v1/TaskService/Tasks/0'
${task_list}= Create List
FOR ${task_dict} IN @{task_dict_list}
Append To List ${task_list} ${task_dict['@odata.id']}
END
[Return] ${task_list}
Create Initiated Task State Dict
[Documentation] Create active task inventory dictionary as certain URI create task
... to serve the user request.
[Arguments] ${task_obj}
# Description of argument(s):
# task_obj Task dictionary.
# task_inv
# TargetUri /redfish/v1/UpdateService
# TaskIdURI /redfish/v1/TaskService/Tasks/0
# TaskState Starting
# TaskStatus OK
${task_inv}= Create Dictionary
Set To Dictionary ${task_inv} TargetUri ${task_obj['Payload']['TargetUri']}
Set To Dictionary ${task_inv} TaskIdURI ${task_obj['@odata.id']}
Set To Dictionary ${task_inv} TaskState ${task_obj['TaskState']}
Set To Dictionary ${task_inv} TaskStatus ${task_obj['TaskStatus']}
[Return] ${task_inv}
Get Task Inventory
[Documentation] Return task inventory.
[Arguments] ${task_info}
# Description of argument(s):
# task_info Task information.
# Task information.
# @odata.id: /redfish/v1/TaskService/Tasks/1
# Id: 1
# TaskState: Starting
# TaskStatus: OK
${task_payload}= Redfish.Get Properties ${task_info['@odata.id']}
${task_inv}= Create Initiated Task State Dict ${task_payload}
[Return] ${task_inv}
Match Target URI
[Documentation] Match target uri from task list.
[Arguments] ${task_list} ${target_uri}
# Description of argument(s):
# task_list Task id list.
# target_uri Task created for target URI.
# target_uri /redfish/v1/UpdateService
FOR ${task_id} IN @{task_list}
${task_payload}= Redfish.Get Properties ${task_id}
Run Keyword And Return If '${task_payload['Payload']['TargetUri']}' == '${target_uri}' Create Initiated Task State Dict ${task_payload}
END
Check Task With Match TargetUri
[Documentation] Create task state dictionary.
[Arguments] ${target_uri}=/redfish/v1/TaskService/Tasks
# Description of argument(s):
# target_uri Target URI for which task is initiated.
${task_dict_list}= Redfish.Get Attribute /redfish/v1/TaskService/Tasks Members
${task_list}= Create List Of Task ${task_dict_list}
${task_inv}= Match Target URI ${task_list} ${target_uri}
[Return] ${task_inv}
Verify Task Progress State
[Documentation] Verify task progress matches the user expected task state.
[Arguments] ${task_inv} ${task_state}
# Description of argument(s):
# task_inv Initiated task inventory dict information.
# task_state Expected task state, user reference from data/task_state.json.
# task_inv
# TaskIdURI /redfish/v1/TaskService/Tasks/0
# TaskState Starting
# TaskStatus OK
${task_payload}= Redfish.Get Properties ${task_inv['TaskIdURI']}
${temp_task_inv}= Create Dictionary
Set To Dictionary ${temp_task_inv} TaskState ${task_payload['TaskState']}
Set To Dictionary ${temp_task_inv} TaskStatus ${task_payload['TaskStatus']}
Rprint Vars temp_task_inv
Should Be Equal As Strings ${task_state['TaskState']} ${task_payload['TaskState']}
Should Be Equal As Strings ${task_state['TaskStatus']} ${task_payload['TaskStatus']}