Code update method BMC using REST

Update work flow sequence:
    - File exist check
    - Ping Test and REST authentication
    - Preserve BMC Network setting
    - SCP image to BMC
    - Activate the flash image
    - Warm Reset BMC
    - Wait for BMC to come online
    - Version check

Resolves openbmc/openbmc-test-automation#81

Change-Id: I071fcca1b58d5a4d250697efa7a1e7aec84070bb
Signed-off-by: George Keishing <gkeishin@in.ibm.com>
diff --git a/extended/code_update/code_update_utils.robot b/extended/code_update/code_update_utils.robot
new file mode 100644
index 0000000..715c8e2
--- /dev/null
+++ b/extended/code_update/code_update_utils.robot
@@ -0,0 +1,99 @@
+*** Settings ***
+Documentation    Code update utility
+
+Resource         ../../lib/rest_client.robot
+Resource         ../../lib/connection_client.robot
+Resource         ../../lib/utils.robot
+Library          OperatingSystem
+
+*** Variables ***
+
+${BMC_UPD_METHOD}   /org/openbmc/control/flash/bmc/action/update
+${BMC_UPD_ATTR}     /org/openbmc/control/flash/bmc
+
+*** Keywords ***
+
+Preserve BMC Network Setting
+    [Documentation]   Preserve Network setting
+    ${policy} =       Set Variable   ${1}
+    ${value} =    create dictionary   data=${policy}
+    Write Attribute   ${BMC_UPD_ATTR}  preserve_network_settings  data=${value}
+    ${data}=      Read Properties   ${BMC_UPD_ATTR}
+    should be equal as strings    ${data['preserve_network_settings']}   ${1}
+    ...   msg=0 indicates network is not preserved
+
+
+Activate BMC flash image
+    [Documentation]   Activate and verify the update status
+    ...               The status could be either one of these
+    ...               'Deferred for mounted filesystem. reboot BMC to apply.'
+    ...               'Image ready to apply.'
+    @{img_path} =   Create List    /tmp/flashimg
+    ${data} =   create dictionary   data=@{img_path}
+    ${resp}=    openbmc post request    ${BMC_UPD_METHOD}   data=${data}
+    should be equal as strings   ${resp.status_code}   ${HTTP_OK}
+    ${content}=     To Json    ${resp.content}
+    should be equal as strings   ${content["data"]["filename"]}   /tmp/flashimg
+
+    ${data}=      Read Properties     ${BMC_UPD_ATTR}
+    should contain    ${data['status']}   to apply
+
+
+SCP Tar Image File to BMC
+    [arguments]         ${filepath}
+    Open Connection for SCP
+    scp.Put File      ${filepath}   /tmp/flashimg
+
+
+Check If warmReset is Initiated
+    # Ping would be still alive, so try SSH to connect if fails
+    # the ports are down indicating reboot in progress
+    ${alive}=   Run Keyword and Return Status
+    ...    Open Connection And Log In
+    Return From Keyword If   '${alive}' == '${False}'    ${False}
+    [return]    ${True}
+
+
+Check If File Exist
+    [Arguments]  ${filepath}
+    Log   \n PATH: ${filepath}
+    OperatingSystem.File Should Exist  ${filepath}
+    ...    msg=${filepath} doesn't exist [ ERROR ]
+
+    Set Global Variable   ${FILE_PATH}  ${filepath}
+
+
+System Readiness Test
+    ${l_status} =   Run Keyword    Verify Ping and REST Authentication
+    Run Keyword If  '${l_status}' == '${False}'
+    ...   Fail  msg=System not in ideal state to use [ERROR]
+
+
+Wait for BMC to respond
+    # Average code update takes from 15 -20 minutes
+    # For worse case 30 minutes, check every 1 min
+    Wait For Host To Ping  ${OPENBMC_HOST}  30 min   1 min
+
+
+Validate BMC Version
+    [Arguments]   ${args}=post
+    # Check BMC installed version
+    Open Connection And Log In
+    ${version}   ${stderr}=    Execute Command   cat /etc/version
+    ...    return_stderr=True
+    Should Be Empty     ${stderr}
+    # The File name contains the version installed
+    Run Keyword If   '${args}' == 'before'
+    ...    Should not Contain  ${FILE_PATH}   ${version}
+    ...    msg=Same version already installed
+    ...    ELSE
+    ...    Should Contain      ${FILE_PATH}   ${version}
+    ...    msg=Code update Failed
+
+
+Trigger Warm Reset via Reboot
+    Open Connection And Log In
+
+    ${rc}=  SSHLibrary.Execute Command
+    ...     /sbin/reboot  return_stdout=False   return_rc=True
+    Should Be Equal As Integers   ${rc}   0
diff --git a/extended/code_update/update_bmc.robot b/extended/code_update/update_bmc.robot
new file mode 100644
index 0000000..80faf9b
--- /dev/null
+++ b/extended/code_update/update_bmc.robot
@@ -0,0 +1,46 @@
+*** Settings ***
+Documentation     Trigger code update to a target BMC.
+...               Execution Method :
+...               python -m robot -v OPENBMC_HOST:<hostname>
+...               -v FILE_PATH:<path/*all.tar>  update_bmc.robot
+...
+...               Code update method BMC using REST
+...               Update work flow sequence:
+...                 - User input BMC File existence check
+...                 - Ping Test and REST authentication
+...                 - Apply preserve BMC Network setting
+...                 - SCP image to BMC
+...                 - Activate the flash image
+...                 - Warm Reset BMC to activate code
+...                 - Wait for BMC to come online time out 30 minutes
+...                 - Version check post update
+
+Resource          code_update_utils.robot
+
+*** Variables ***
+
+${FILE_PATH}      ${EMPTY}
+
+*** Test cases ***
+
+Initiate Code update BMC
+    [Documentation]    BMC code update process initiation
+
+    Check If File Exist    ${FILE_PATH}
+    System Readiness Test
+    Validate BMC Version   before
+
+    Preserve BMC Network Setting
+    SCP Tar Image File to BMC   ${FILE_PATH}
+
+    Activate BMC flash image
+
+    Trigger Warm Reset
+    # TODO: openbmc/openbmc#519
+    ${session_active}=   Check If warmReset is Initiated
+    Run Keyword If   '${session_active}' == '${True}'
+    ...    Trigger Warm Reset via Reboot
+
+    Wait for BMC to respond
+    Sleep  1 min
+    Validate BMC Version
diff --git a/lib/utils.robot b/lib/utils.robot
index 190e4fc..c5a45ec 100644
--- a/lib/utils.robot
+++ b/lib/utils.robot
@@ -1,6 +1,7 @@
 *** Settings ***
 Resource                ../lib/resource.txt
 Resource                ../lib/rest_client.robot
+Resource                ../lib/connection_client.robot
 
 Library                 OperatingSystem
 
@@ -176,3 +177,19 @@
     [Documentation]  Checks whether system state is HOST_BOOTED.
     ${state}=    Get BMC State
     should be equal as strings     ${state}     HOST_BOOTED
+
+Verify Ping and REST Authentication
+    ${l_ping} =   Run Keyword And Return Status
+    ...    Ping Host  ${OPENBMC_HOST}
+    Return From Keyword If  '${l_ping}' == '${False}'    ${False}
+
+    ${l_rest} =   Run Keyword And Return Status
+    ...    Initialize OpenBMC
+    Return From Keyword If  '${l_rest}' == '${False}'    ${False}
+
+    # Just to make sure the SSH is working for SCP
+    Open Connection And Log In
+    ${system}   ${stderr}=    Execute Command   hostname   return_stderr=True
+    Should Be Empty     ${stderr}
+
+    [return]    ${True}