ImageURI TFTP download and install for BMC and Host image

Changes:
    - Added test for the following use cases:
        1. TFTP update with OnReset
        2. TFTP update with Immediate
        3. ImageURI update with OnReset
        4. ImageURI update with Immediate
     - Added keyword to set ApplyTime
     - Added logic to wait for boot to standby
     - New tftp utils file

Change-Id: I02d73000e92ad190d29b8f177fae320e0254835e
Signed-off-by: George Keishing <gkeishin@in.ibm.com>
diff --git a/lib/code_update_utils.robot b/lib/code_update_utils.robot
index cea4721..d6c0be6 100644
--- a/lib/code_update_utils.robot
+++ b/lib/code_update_utils.robot
@@ -537,3 +537,16 @@
     Rprint Vars  version
 
     [Return]  ${version}
+
+
+Set ApplyTime
+    [Documentation]  Set and verify the firmware "ApplyTime" policy.
+    [Arguments]  ${policy}
+
+    # Description of argument(s):
+    # policy     ApplyTime allowed values (e.g. "OnReset", "Immediate").
+
+    Redfish.Patch  ${REDFISH_BASE_URI}UpdateService  body={'ApplyTime' : '${policy}'}
+    ${apply_time}=  Read Attribute   ${SOFTWARE_VERSION_URI}apply_time  RequestedApplyTime
+    Rvalid Value  apply_time  valid_values=["xyz.openbmc_project.Software.ApplyTime.RequestedApplyTimes.${policy}"]
+    Rprint Vars  apply_time
diff --git a/lib/tftp_update_utils.py b/lib/tftp_update_utils.py
new file mode 100644
index 0000000..2d0f7e3
--- /dev/null
+++ b/lib/tftp_update_utils.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+
+r"""
+This module contains functions for tftp update.
+"""
+
+from robot.libraries.BuiltIn import BuiltIn
+
+import state as st
+import gen_print as gp
+
+
+def get_pre_reboot_state():
+    r"""
+    Get and return a custom state which is comprised of the
+    st.default_req_states plus epoch_seconds.
+    """
+
+    global state
+
+    req_states = ['epoch_seconds'] + st.default_req_states
+
+    gp.qprint_timen("Get system state.")
+    state = st.get_state(req_states=req_states, quiet=0)
+    gp.qprint_var(state)
+    return state
+
+
+def wait_for_reboot(start_boot_seconds):
+    r"""
+    Wait for the BMC to complete a previously initiated reboot.
+
+    Description of argument(s):
+    start_boot_seconds  The time that the boot test started.  The format is the
+                        epoch time in seconds, i.e. the number of seconds since
+                        1970-01-01 00:00:00 UTC.  This value should be obtained
+                        from the BMC so that it is not dependent on any kind of
+                        synchronization between this machine and the target BMC
+                        This will allow this program to work correctly even in
+                        a simulated environment.  This value should be obtained
+                        by the caller prior to initiating a reboot.  It can be
+                        obtained as follows:
+                        state = st.get_state(req_states=['epoch_seconds'])
+
+    """
+
+    st.wait_for_comm_cycle(int(start_boot_seconds))
+
+    gp.qprintn()
+    st.wait_state(st.standby_match_state, wait_time="10 mins", interval="10 seconds")
diff --git a/redfish/update_service/test_firmware_tftp_upload_image.robot b/redfish/update_service/test_firmware_tftp_upload_image.robot
index 3a4e278..ca80115 100644
--- a/redfish/update_service/test_firmware_tftp_upload_image.robot
+++ b/redfish/update_service/test_firmware_tftp_upload_image.robot
@@ -17,10 +17,11 @@
 Resource         ../../lib/code_update_utils.robot
 Library          ../../lib/code_update_utils.py
 Library          ../../lib/gen_robot_valid.py
+Library          ../../lib/tftp_update_utils.py
 
 Suite Setup      Suite Setup Execution
 Suite Teardown   Redfish.Logout
-Test Setup       Printn
+Test Setup       Run Keywords  Redfish Power Off  stack_mode=skip  quiet=1  AND  Redfish.Login
 Test Teardown    FFDC On Test Case Fail
 
 Force Tags       tftp_update
@@ -30,12 +31,59 @@
 TFTP Download Install With ApplyTime OnReset Policy
     [Documentation]  Download image to BMC using TFTP with OnReset policy and verify installation.
     [Tags]  TFTP_Download_Install_With_ApplyTime_OnReset_Policy
+    [Template]  TFTP Download Install
 
-    # Set and verify the firmware OnReset policy.
-    Redfish.Patch  ${REDFISH_BASE_URI}UpdateService  body={'ApplyTime' : 'OnReset'}
-    ${apply_time}=  Read Attribute   ${SOFTWARE_VERSION_URI}apply_time  RequestedApplyTime
-    Rvalid Value  apply_time  valid_values=['xyz.openbmc_project.Software.ApplyTime.RequestedApplyTimes.OnReset']
-    Rprint Vars  apply_time
+    # policy
+    OnReset
+
+
+TFTP Download Install With ApplyTime Immediate Policy
+    [Documentation]  Download image to BMC using TFTP with Immediate policy and verify installation.
+    [Tags]  TFTP_Download_Install_With_ApplyTime_Immediate_Policy
+    [Template]  TFTP Download Install
+
+    # policy
+    Immediate
+
+
+ImageURI Download Install With ApplyTime OnReset Policy
+    [Documentation]  Download image to BMC using ImageURI with OnReset policy and verify installation.
+    [Tags]  ImageURI_Download_Install_With_ApplyTime_OnReset_Policy
+    [Template]  ImageURI Download Install
+
+    # policy
+    OnReset
+
+
+ImageURI Download Install With ApplyTime Immediate Policy
+    [Documentation]  Download image to BMC using ImageURI with Immediate policy and verify installation.
+    [Tags]  ImageURI_Download_Install_With_ApplyTime_Immediate_Policy
+    [Template]  ImageURI Download Install
+
+    # policy
+    Immediate
+
+*** Keywords ***
+
+Suite Setup Execution
+    [Documentation]  Do the suite setup.
+
+    Redfish.Login
+    Rvalid Value  TFTP_SERVER
+    Rvalid Value  IMAGE_FILE_NAME
+
+
+TFTP Download Install
+    [Documentation]  Download image to BMC using TFTP with ApplyTime policy and verify installation.
+    [Arguments]  ${policy}
+
+    # Description of argument(s):
+    # policy     ApplyTime allowed values (e.g. "OnReset", "Immediate").
+
+    ${state}=  Get Pre Reboot State
+    Rprint Vars  state
+
+    Set ApplyTime  policy=${policy}
 
     # Download image from TFTP server to BMC.
     Redfish.Post  /redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate
@@ -56,10 +104,10 @@
     Check Image Update Progress State  match_state='Updating'  image_id=${image_id}
 
     # Wait for the image to install complete.
-    Wait Until Keyword Succeeds  5 min  15 sec
+    Wait Until Keyword Succeeds  8 min  15 sec
     ...  Check Image Update Progress State  match_state='Enabled'  image_id=${image_id}
 
-    Redfish OBMC Reboot (off)
+    Reboot And Wait For BMC Standby  policy=${policy}  start_boot_seconds=${state['epoch_seconds']}
 
     # Verify the image is installed and functional.
     ${cmd}=  Set Variable  grep ^VERSION_ID= /etc/os-release | cut -f 2 -d '=' | sed 's/"//g'
@@ -68,11 +116,57 @@
     Rprint Vars  functional_version
 
 
-*** Keywords ***
+ImageURI Download Install
+    [Documentation]  Download image to BMC using ImageURI with ApplyTime policy and verify installation.
+    [Arguments]  ${policy}
 
-Suite Setup Execution
-    [Documentation]  Do the suite setup.
+    # Description of argument(s):
+    # policy     ApplyTime allowed values (e.g. "OnReset", "Immediate").
 
-    Redfish.Login
-    Rvalid Value  TFTP_SERVER
-    Rvalid Value  IMAGE_FILE_NAME
+    ${state}=  Get Pre Reboot State
+    Rprint Vars  state
+
+    Set ApplyTime  policy=${policy}
+
+    # Download image from TFTP server via ImageURI to BMC.
+    Redfish.Post  /redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate
+    ...  body={"ImageURI": "tftp://${TFTP_SERVER}/${IMAGE_FILE_NAME}"}
+
+    # Wait for image tar file download to complete.
+    ${image_id}=  Wait Until Keyword Succeeds  60 sec  10 sec  Get Latest Image ID
+    Rprint Vars  image_id
+
+    # Let the image get extracted and it should not fail.
+    Sleep  5s
+    Check Image Update Progress State  match_state='Disabled', 'Updating'  image_id=${image_id}
+
+    ${install_version}=  Get Firmware Image Version  image_id=${image_id}
+    Rprint Vars  install_version
+
+    Check Image Update Progress State  match_state='Updating'  image_id=${image_id}
+
+    # Wait for the image to install complete.
+    Wait Until Keyword Succeeds  8 min  15 sec
+    ...  Check Image Update Progress State  match_state='Enabled'  image_id=${image_id}
+
+    Reboot And Wait For BMC Standby  policy=${policy}  start_boot_seconds=${state['epoch_seconds']}
+
+    # Verify the image is installed and functional.
+    ${cmd}=  Set Variable  grep ^VERSION_ID= /etc/os-release | cut -f 2 -d '=' | sed 's/"//g'
+    ${functional_version}  ${stderr}  ${rc}=  BMC Execute Command  ${cmd}
+    Rvalid Value  functional_version  valid_values=['${install_version}']
+    Rprint Vars  functional_version
+
+
+Reboot And Wait For BMC Standby
+    [Documentation]  Reboot or wait for BMC standby post reboot.
+    [Arguments]  ${policy}  ${start_boot_seconds}
+
+    # Description of argument(s):
+    # policy                ApplyTime allowed values (e.g. "OnReset", "Immediate").
+    # start_boot_seconds    See 'Wait For Reboot' for details.
+
+    Run Keyword If  '${policy}' == 'OnReset'
+    ...    Redfish OBMC Reboot (off)
+    ...  ELSE
+    ...    Wait For Reboot  start_boot_seconds=${start_boot_seconds}