Refactored and added test case for BMC code update

- Split code update tests into files for BMC and Host
- Added a test case for BMC code update

Resolves openbmc/openbmc-test-automation#872

Change-Id: I4247fc2da512e01aea9790141dd5884e534982a8
Signed-off-by: Charles Paul Hofer <Charles.Hofer@ibm.com>
diff --git a/data/variables.py b/data/variables.py
index a80bff1..96058b6 100644
--- a/data/variables.py
+++ b/data/variables.py
@@ -61,6 +61,9 @@
 VERSION_PURPOSE_BMC = SOFTWARE_PURPOSE + '.BMC'
 VERSION_PURPOSE_SYSTEM = SOFTWARE_PURPOSE + '.System'
 
+# Image Upload Directory Path
+IMAGE_UPLOAD_DIR_PATH = '/tmp/images/'
+
 # Inventory URI
 HOST_INVENTORY_URI = '/xyz/openbmc_project/inventory/'
 
diff --git a/extended/code_update/bmc_code_update.robot b/extended/code_update/bmc_code_update.robot
new file mode 100644
index 0000000..1fd6479
--- /dev/null
+++ b/extended/code_update/bmc_code_update.robot
@@ -0,0 +1,36 @@
+*** Settings ***
+Documentation     Update the BMC code on a target BMC.
+...               Execution Method:
+...               python -m robot -v OPENBMC_HOST:<hostname>
+...               -v IMAGE_FILE_PATH:<path/*.tar>  bmc_code_update.robot
+
+Library           ../../lib/code_update_utils.py
+Variables         ../../data/variables.py
+Resource          ../../lib/boot_utils.robot
+Resource          code_update_utils.robot
+Resource          ../../lib/code_update_utils.robot
+Resource          ../lib/openbmc_ffdc.robot
+
+Test Teardown     FFDC On Test Case Fail
+
+*** Variables ***
+
+${QUIET}                          ${1}
+${IMAGE_FILE_PATH}                ${EMPTY}
+
+*** Test Cases ***
+
+REST BMC Code Update
+    [Documentation]  Do a BMC code update by uploading image on BMC via REST.
+    [Tags]  REST_BMC_Code_Update
+
+    Upload And Activate Image  ${IMAGE_FILE_PATH}
+    OBMC Reboot (off)
+
+
+Delete BMC Image
+    [Documentation]  Delete a BMC image from the BMC flash chip.
+    [Tags]  Delete_BMC_Image
+
+    ${software_object}=  Get Non Running BMC Software Object
+    Delete Image And Verify  ${software_object}  ${VERSION_PURPOSE_BMC}
diff --git a/extended/code_update/code_update.robot b/extended/code_update/code_update.robot
deleted file mode 100644
index 6b6f058..0000000
--- a/extended/code_update/code_update.robot
+++ /dev/null
@@ -1,164 +0,0 @@
-*** Settings ***
-Documentation     Code update to a target BMC.
-...               Execution Method:
-...               python -m robot -v OPENBMC_HOST:<hostname>
-...               -v DELETE_OLD_PNOR_IMAGES:<"true" or "false">
-...               -v IMAGE_FILE_PATH:<path/*.tar>  code_update.robot
-...
-...               Code update method BMC
-...               Update work flow sequence:
-...                 - Upload image via REST
-...                 - Verify that the file exists on the BMC
-...                 - Check software "Activation" status to be "Ready"
-...                 - Set "Requested Activation" to "Active"
-...                 - Wait for code update to complete
-...                 - Verify the new version
-
-Library           ../../lib/code_update_utils.py
-Variables         ../../data/variables.py
-Resource          ../lib/openbmc_ffdc.robot
-Resource          ../../lib/code_update_utils.robot
-Resource          ../../lib/boot_utils.robot
-Resource          ../../lib/utils.robot
-Resource          code_update_utils.robot
-Resource          ../../lib/state_manager.robot
-
-Test Teardown     FFDC On Test Case Fail
-
-*** Variables ***
-
-${QUIET}                          ${1}
-${upload_dir_path}                /tmp/images/
-${IMAGE_FILE_PATH}                ${EMPTY}
-${DELETE_OLD_PNOR_IMAGES}         false
-
-*** Test Cases ***
-
-REST Host Code Update
-    [Documentation]  Do a PNOR code update by uploading image on BMC via REST.
-    [Tags]  REST_Host_Code_Update
-    [Setup]  Code Update Setup
-
-    Upload And Activate Image  ${IMAGE_FILE_PATH}
-
-    OBMC Reboot (off)
-
-
-Post Update Boot To OS
-    [Documentation]  Boot the host OS
-    [Tags]  Post_Update_Boot_To_OS
-    [Teardown]  Stop SOL Console Logging
-
-    Run Keyword Unless  '${PREV_TEST_STATUS}' == 'PASS'
-    ...  Fail  Code update failed. No need to boot to OS.
-    Start SOL Console Logging
-    REST Power On
-
-
-Host Image Priority Attribute Test
-    [Documentation]  Set "Priority" attribute.
-    [Tags]  Host_Image_Priority_Attribute_Test
-    [Template]  Set PNOR Attribute
-
-    # Property        Value
-    Priority          ${0}
-    Priority          ${1}
-    Priority          ${127}
-
-
-Set RequestedActivation To None
-    [Documentation]  Set the RequestedActivation of the image to None and
-    ...              verify that it is in fact set to None.
-    [Tags]  Set_RequestedActivation_To_None
-
-    ${sw_objs}=  Get Software Objects
-    Set Host Software Property  @{sw_objs}[0]  RequestedActivation
-    ...  ${REQUESTED_NONE}
-    ${sw_props}=  Get Host Software Property  @{sw_objs}[0]
-    Should Be Equal As Strings  &{sw_props}[RequestedActivation]
-    ...  ${REQUESTED_NONE}
-
-
-Set RequestedActivation To Invalid Value
-    [Documentation]  Set the RequestedActivation proprety of the image to an
-    ...              invalid value and verify that it was not changed.
-    [Template]  Set Property To Invalid Value And Verify No Change
-    [Tags]  Set_RequestedActivation_To_Invalid_Value
-
-    # Property
-    RequestedActivation
-
-
-Set Activation To Invalid Value
-    [Documentation]  Set the Activation proprety of the image to an invalid
-    ...              value and verify that it was not changed.
-    [Template]  Set Property To Invalid Value And Verify No Change
-    [Tags]  Set_Activation_To_Invalid_Value
-
-    # Property
-    Activation
-
-
-Delete Host Image
-    [Documentation]  Delete a PNOR image from the BMC and PNOR flash chip.
-    [Tags]  Delete_Host_Image
-    [Setup]  Initiate Host PowerOff
-
-    ${software_objects}=  Get Software Objects
-    ...  version_type=${VERSION_PURPOSE_HOST}
-    ${num_images}=  Get Length  ${software_objects}
-    Should Be True  0 < ${num_images}
-    ...  msg=There are no PNOR images on the BMC to delete.
-    Delete Image And Verify  @{software_objects}[0]  ${VERSION_PURPOSE_HOST}
-
-
-Delete BMC Image
-    [Documentation]  Delete a BMC image from the BMC flash chip.
-    [Tags]  Delete_BMC_Image
-
-    ${software_object}=  Get Non Running BMC Software Object
-    Delete Image And Verify  ${software_object}  ${VERSION_PURPOSE_BMC}
-
-
-*** Keywords ***
-
-Set PNOR Attribute
-    [Documentation]  Update the attribute value.
-    [Arguments]  ${attribute_name}  ${value}
-
-    # Description of argument(s):
-    # attribute_name   Host software attribute name (e.g. "Priority").
-    # value            Value to be written.
-
-    ${image_ids}=  Get Software Objects
-    ${resp}=  Get Host Software Property  ${image_ids[0]}
-    ${initial_value}=  Set Variable  ${resp["Priority"]}
-
-    Set Host Software Property  ${image_ids[0]}  ${attribute_name}  ${value}
-
-    ${resp}=  Get Host Software Property  ${image_ids[0]}
-    Should Be Equal As Integers  ${resp["Priority"]}  ${value}
-
-    # Revert to to initial value.
-    Set Host Software Property
-    ...  ${image_ids[0]}  ${attribute_name}  ${initial_value}
-
-
-Code Update Setup
-    [Documentation]  Do code update test case setup.
-
-    Run Keyword If  'true' == '${DELETE_OLD_PNOR_IMAGES}'
-    ...  Delete All PNOR Images
-
-
-Get PNOR Extended Version
-    [Documentation]  Return the PNOR extended version.
-    [Arguments]  ${path}
-
-    # Description of argument(s):
-    # path  Path of the MANIFEST file.
-
-    Open Connection And Log In
-    ${version}= Execute Command On BMC
-    ...  "grep \"extended_version=\" " + ${path}
-    [return] ${version.split(",")}
diff --git a/extended/code_update/host_code_update.robot b/extended/code_update/host_code_update.robot
new file mode 100644
index 0000000..eec0ddc
--- /dev/null
+++ b/extended/code_update/host_code_update.robot
@@ -0,0 +1,148 @@
+*** Settings ***
+Documentation     Update the PNOR code on a target BMC.
+...               Execution Method:
+...               python -m robot -v OPENBMC_HOST:<hostname>
+...               -v DELETE_OLD_PNOR_IMAGES:<"true" or "false">
+...               -v IMAGE_FILE_PATH:<path/*.tar>  host_code_update.robot
+...
+...               Code update method BMC
+...               Update work flow sequence:
+...                 - Upload image via REST
+...                 - Verify that the file exists on the BMC
+...                 - Check that software "Activation" is set to "Ready"
+...                 - Set "Requested Activation" to "Active"
+...                 - Wait for code update to complete
+...                 - Verify the new version
+
+Library           ../../lib/bmc_ssh_utils.py
+Library           ../../lib/code_update_utils.py
+Variables         ../../data/variables.py
+Resource          ../../lib/boot_utils.robot
+Resource          code_update_utils.robot
+Resource          ../../lib/code_update_utils.robot
+Resource          ../lib/openbmc_ffdc.robot
+Resource          ../../lib/state_manager.robot
+
+Test Teardown     FFDC On Test Case Fail
+
+*** Variables ***
+
+${QUIET}                          ${1}
+${IMAGE_FILE_PATH}                ${EMPTY}
+${DELETE_OLD_PNOR_IMAGES}         false
+
+*** Test Cases ***
+
+REST Host Code Update
+    [Documentation]  Do a PNOR code update by uploading image on BMC via REST.
+    [Tags]  REST_Host_Code_Update
+    [Setup]  Code Update Setup
+
+    Upload And Activate Image  ${IMAGE_FILE_PATH}
+    OBMC Reboot (off)
+
+
+Post Update Boot To OS
+    [Documentation]  Boot the host OS
+    [Tags]  Post_Update_Boot_To_OS
+    [Teardown]  Stop SOL Console Logging
+
+    Run Keyword If  '${PREV_TEST_STATUS}' == 'FAIL'
+    ...  Fail  Code update failed. No need to boot to OS.
+    Start SOL Console Logging
+    REST Power On
+
+
+Host Image Priority Attribute Test
+    [Documentation]  Set "Priority" attribute.
+    [Tags]  Host_Image_Priority_Attribute_Test
+    [Template]  Temporarily Set PNOR Attribute
+
+    # Property        Value
+    Priority          ${0}
+    Priority          ${1}
+    Priority          ${127}
+
+
+Set RequestedActivation To None
+    [Documentation]  Set the RequestedActivation of the image to None and
+    ...              verify that it is in fact set to None.
+    [Tags]  Set_RequestedActivation_To_None
+
+    ${software_objects}=  Get Software Objects
+    Set Host Software Property  @{software_objects}[0]  RequestedActivation
+    ...  ${REQUESTED_NONE}
+    ${software_properties}=  Get Host Software Property  @{software_objects}[0]
+    Should Be Equal As Strings  &{software_properties}[RequestedActivation]
+    ...  ${REQUESTED_NONE}
+
+
+Set RequestedActivation And Activation To Invalid Value
+    [Documentation]  Set the RequestedActivation and Activation propreties of
+    ...              the image to an invalid value and verify that it was not
+    ...              changed.
+    [Template]  Set Property To Invalid Value And Verify No Change
+    [Tags]  Set_RequestedActivation_And_Activation_To_Invalid_Value
+
+    # Property              Version Type
+    RequestedActivation     ${VERSION_PURPOSE_HOST}
+    Activation              ${VERSION_PURPOSE_HOST}
+
+
+Delete Host Image
+    [Documentation]  Delete a PNOR image from the BMC and PNOR flash chip.
+    [Tags]  Delete_Host_Image
+    [Setup]  Initiate Host PowerOff
+
+    ${software_objects}=  Get Software Objects
+    ...  version_type=${VERSION_PURPOSE_HOST}
+    ${num_images}=  Get Length  ${software_objects}
+    Should Be True  0 < ${num_images}
+    ...  msg=There are no PNOR images on the BMC to delete.
+    Delete Image And Verify  @{software_objects}[0]  ${VERSION_PURPOSE_HOST}
+
+
+*** Keywords ***
+
+Temporarily Set PNOR Attribute
+    [Documentation]  Update the PNOR attribute value.
+    [Arguments]  ${attribute_name}  ${attribute_value}
+
+    # Description of argument(s):
+    # attribute_name    Host software attribute name (e.g. "Priority").
+    # attribute_value   Value to be written.
+
+    ${image_ids}=  Get Software Objects
+    ${init_host_properties}=  Get Host Software Property  ${image_ids[0]}
+    ${initial_priority}=  Set Variable  ${init_host_properties["Priority"]}
+
+    Set Host Software Property  ${image_ids[0]}  ${attribute_name}
+    ...  ${attribute_value}
+
+    ${cur_host_properties}=  Get Host Software Property  ${image_ids[0]}
+    Should Be Equal As Integers  ${cur_host_properties["Priority"]}
+    ...  ${attribute_value}
+
+    # Revert to to initial value.
+    Set Host Software Property
+    ...  ${image_ids[0]}  ${attribute_name}  ${initial_priority}
+
+
+Code Update Setup
+    [Documentation]  Do code update test case setup.
+
+    Run Keyword If  'true' == '${DELETE_OLD_PNOR_IMAGES}'
+    ...  Delete All PNOR Images
+
+
+Get PNOR Extended Version
+    [Documentation]  Return the PNOR extended version.
+    [Arguments]  ${manifest_path}
+
+    # Description of argument(s):
+    # manifest_path  Path of the MANIFEST file
+    #                (e.g. "/tmp/images/abc123/MANIFEST").
+
+    ${version}= BMC Execute Command
+    ...  grep extended_version= ${manifest_path}
+    [return] ${version.split(",")}
diff --git a/extended/test_uploadimage.robot b/extended/test_uploadimage.robot
index ade0b0b..17a83f0 100644
--- a/extended/test_uploadimage.robot
+++ b/extended/test_uploadimage.robot
@@ -27,7 +27,6 @@
 
 *** Variables ***
 ${timeout}            10
-${upload_dir_path}    /tmp/images/
 ${QUIET}              ${1}
 
 *** Test Cases ***
diff --git a/lib/code_update_utils.py b/lib/code_update_utils.py
index c33d360..5026878 100644
--- a/lib/code_update_utils.py
+++ b/lib/code_update_utils.py
@@ -37,7 +37,8 @@
     for image_name in images:
         _, image_properties = keyword.run_key(
                 "Get Host Software Property  " + image_name)
-        if image_properties['Version'] != cur_img_version:
+        if image_properties['Purpose'] != var.VERSION_PURPOSE_HOST \
+                and image_properties['Version'] != cur_img_version:
             return image_name
     BuiltIn().fail("Did not find any non-running BMC images.")
 
@@ -193,11 +194,10 @@
                      of the images in the upload dir.
     """
 
-    upload_dir = BuiltIn().get_variable_value("${upload_dir_path}")
     keyword.run_key_u("Open Connection And Log In")
     status, image_list =\
-            keyword.run_key("Execute Command On BMC  ls -d " + upload_dir
-            + "*/")
+            keyword.run_key("Execute Command On BMC  ls -d "
+                            + var.IMAGE_UPLOAD_DIR_PATH + "*/")
 
     image_list = image_list.split("\n")
     retry = 0
@@ -213,7 +213,8 @@
 
 
 ###############################################################################
-def verify_image_upload(image_version, timeout=3):
+def verify_image_upload(image_version,
+                        timeout=3):
 
     r"""
     Verify the image was uploaded correctly and that it created
@@ -221,9 +222,10 @@
     fails, try again until we reach the timeout.
 
     Description of argument(s):
-    image_version  The version from the image's manifest file.
-    timeout  How long, in minutes, to keep trying to find the
-             image on the BMC. Default is 3 minutes.
+    image_version  The version from the image's manifest file
+                   (e.g. "IBM-witherspoon-redbud-ibm-OP9_v1.17_1.68").
+    timeout        How long, in minutes, to keep trying to find the
+                   image on the BMC. Default is 3 minutes.
     """
 
     image_path = get_image_path(image_version)
@@ -271,10 +273,9 @@
     """
 
     keyword.run_key('Open Connection And Log In')
-    upload_dir_path = BuiltIn().get_variable_value("${upload_dir_path}")
     for i in range(timeout * 2):
         stat, grep_res = keyword.run_key('Execute Command On BMC  '
-                + 'ls ' + upload_dir_path + '*/MANIFEST 2>/dev/null '
+                + 'ls ' + var.IMAGE_UPLOAD_DIR_PATH + '*/MANIFEST 2>/dev/null '
                 + '| xargs grep -rl "version=' + image_version + '"')
         image_dir = os.path.dirname(grep_res.split('\n')[0])
         if '' != image_dir:
diff --git a/lib/code_update_utils.robot b/lib/code_update_utils.robot
index d336888..a73a6a9 100644
--- a/lib/code_update_utils.robot
+++ b/lib/code_update_utils.robot
@@ -66,22 +66,26 @@
 Set Property To Invalid Value And Verify No Change
     [Documentation]  Attempt to set a property and check that the value didn't
     ...              change.
-    [Arguments]  ${property}
+    [Arguments]  ${property}  ${version_type}
 
     # Description of argument(s):
-    # property  The property to attempt to set.
+    # property      The property to attempt to set.
+    # version_type  Either BMC or host version purpose.
+    #               By default host version purpose string.
+    #  (e.g. "xyz.openbmc_project.Software.Version.VersionPurpose.BMC"
+    #        "xyz.openbmc_project.Software.Version.VersionPurpose.Host").
 
-    ${sw_objs}=  Get Software Objects
-    ${prev_props}=  Get Host Software Property  @{sw_objs}[0]
+    ${software_objects}=  Get Software Objects  version_type=${version_type}
+    ${prev_properties}=  Get Host Software Property  @{software_objects}[0]
     Run Keyword And Expect Error  500 != 200
-    ...  Set Host Software Property  @{sw_objs}[0]  ${property}  foo
-    ${cur_props}=  Get Host Software Property  @{sw_objs}[0]
-    Should Be Equal As Strings  &{prev_props}[${property}]
-    ...  &{cur_props}[${property}]
+    ...  Set Host Software Property  @{software_objects}[0]  ${property}  foo
+    ${cur_properties}=  Get Host Software Property  @{software_objects}[0]
+    Should Be Equal As Strings  &{prev_properties}[${property}]
+    ...  &{cur_properties}[${property}]
 
 
 Upload And Activate Image
-    [Documentation]  Uploads an image to the BMC and activates it with REST.
+    [Documentation]  Upload an image to the BMC and activate it with REST.
     [Arguments]  ${image_file_path}
 
     # Description of argument(s):
@@ -138,6 +142,8 @@
     #               xyz.openbmc_project.Software.Version.VersionPurpose.Host
     #               or xyz.openbmc_project.Software.Version.VersionPurpose.BMC.
 
+    Log To Console  Deleteing ${software_object}
+
     # Delete the image.
     Delete Software Object  ${software_object}
     # TODO: If/when we don't have to delete twice anymore, take this out