Added test cases for uploading multiple images

Resolves openbmc/openbmc-test-automation#873

Change-Id: I2ac5b9acd6955c5d600099e39771f1feeeddc2c9
Signed-off-by: Charles Paul Hofer <Charles.Hofer@ibm.com>
diff --git a/extended/code_update/bmc_code_update.robot b/extended/code_update/bmc_code_update.robot
index 1fd6479..41751a6 100644
--- a/extended/code_update/bmc_code_update.robot
+++ b/extended/code_update/bmc_code_update.robot
@@ -17,6 +17,7 @@
 
 ${QUIET}                          ${1}
 ${IMAGE_FILE_PATH}                ${EMPTY}
+${ALTERNATE_IMAGE_FILE_PATH}      ${EMPTY}
 
 *** Test Cases ***
 
@@ -28,9 +29,28 @@
     OBMC Reboot (off)
 
 
+Upload And Activate Multiple BMC Images
+    [Documentation]  Upload another BMC image and verify that its state is
+    ...              different from all others.
+    [Tags]  Upload_And_Activate_Multiple_BMC_Images
+    [Template]  Activate Image And Verify No Duplicate Priorities
+    [Setup]  Upload And Activate Multiple BMC Images Setup
+
+    # Image File Path              Image Purpose
+    ${ALTERNATE_IMAGE_FILE_PATH}   ${VERSION_PURPOSE_BMC}
+
+
 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 ***
+
+Upload And Activate Multiple BMC Images Setup
+    [Documentation]  Check that the ALTERNATE_FILE_PATH variable is set.
+
+    Should Not Be Empty  ${ALTERNATE_IMAGE_FILE_PATH}
\ No newline at end of file
diff --git a/extended/code_update/host_code_update.robot b/extended/code_update/host_code_update.robot
index eec0ddc..12fe770 100644
--- a/extended/code_update/host_code_update.robot
+++ b/extended/code_update/host_code_update.robot
@@ -30,6 +30,7 @@
 ${QUIET}                          ${1}
 ${IMAGE_FILE_PATH}                ${EMPTY}
 ${DELETE_OLD_PNOR_IMAGES}         false
+${ALTERNATE_IMAGE_FILE_PATH}      ${EMPTY}
 
 *** Test Cases ***
 
@@ -89,6 +90,17 @@
     Activation              ${VERSION_PURPOSE_HOST}
 
 
+Upload And Activate Multiple Host Images
+    [Documentation]  Upload another PNOR image and verify that its state is
+    ...              different from all others.
+    [Tags]  Upload_And_Activate_Multiple_Host_Images
+    [Template]  Activate Image And Verify No Duplicate Priorities
+    [Setup]  Upload And Activate Multiple BMC Images Setup
+
+    # Image File Path              Image Purpose
+    ${ALTERNATE_IMAGE_FILE_PATH}   ${VERSION_PURPOSE_HOST}
+
+
 Delete Host Image
     [Documentation]  Delete a PNOR image from the BMC and PNOR flash chip.
     [Tags]  Delete_Host_Image
@@ -135,6 +147,12 @@
     ...  Delete All PNOR Images
 
 
+Upload And Activate Multiple BMC Images Setup
+    [Documentation]  Check that the ALTERNATE_FILE_PATH variable is set.
+
+    Should Not Be Empty  ${ALTERNATE_IMAGE_FILE_PATH}
+
+
 Get PNOR Extended Version
     [Documentation]  Return the PNOR extended version.
     [Arguments]  ${manifest_path}
diff --git a/lib/code_update_utils.py b/lib/code_update_utils.py
index 5026878..5dd0ca7 100644
--- a/lib/code_update_utils.py
+++ b/lib/code_update_utils.py
@@ -20,6 +20,34 @@
 from robot.libraries.BuiltIn import BuiltIn
 
 ###############################################################################
+def verify_no_duplicate_image_priorities(image_purpose):
+
+    r"""
+    Check that there are no active images with the same purpose and priority.
+
+    Description of argument(s):
+    image_purpose  The purpose that images must have to be checked for
+                   priority duplicates.
+    """
+
+    taken_priorities = {}
+    _, image_names = keyword.run_key("Get Software Objects  "
+                                     + "version_type=" + image_purpose)
+
+    for image_name in image_names:
+        _, image = keyword.run_key("Get Host Software Property  " + image_name)
+        if image["Activation"] != var.ACTIVE:
+            continue
+        image_priority = image["Priority"]
+        if image_priority in taken_priorities:
+            BuiltIn().fail("Found active images with the same priority.\n"
+                    + gp.sprint_vars(image, taken_priorities[image_priority]))
+            taken_priorities[image_priority] = image
+
+###############################################################################
+
+
+###############################################################################
 def get_non_running_bmc_software_object():
 
     r"""
diff --git a/lib/code_update_utils.robot b/lib/code_update_utils.robot
index a73a6a9..10e2171 100644
--- a/lib/code_update_utils.robot
+++ b/lib/code_update_utils.robot
@@ -117,6 +117,19 @@
     Should Be Equal As Strings  &{software_state}[Activation]  ${ACTIVE}
 
 
+Activate Image And Verify No Duplicate Priorities
+    [Documentation]  Upload an image, and then check that no images have the
+    ...              same priority.
+    [Arguments]  ${image_file_path}  ${image_purpose}
+
+    # Description of argument(s):
+    # image_file_path  The path to the image to upload.
+    # image_purpose    The purpose in the image's MANIFEST file.
+
+    Upload And Activate Image  ${image_file_path}
+    Verify No Duplicate Image Priorities  ${image_purpose}
+
+
 Delete Software Object
     [Documentation]  Deletes an image from the BMC.
     [Arguments]  ${software_object}
diff --git a/lib/resource.txt b/lib/resource.txt
index 74a5fcd..8f00efb 100755
--- a/lib/resource.txt
+++ b/lib/resource.txt
@@ -48,13 +48,14 @@
 ${DEBUG_TARBALL_PATH}  ${EMPTY}
 
 # Upload Image parameters
-${TFTP_SERVER}              ${EMPTY}
-${PNOR_TFTP_FILE_NAME}      ${EMPTY}
-${BMC_TFTP_FILE_NAME}       ${EMPTY}
-${IMAGE_FILE_PATH}          ${EMPTY}
-${PNOR_IMAGE_FILE_PATH}     ${EMPTY}
-${BMC_IMAGE_FILE_PATH}      ${EMPTY}
-${BAD_IMAGES_DIR_PATH}      ${EMPTY}
+${TFTP_SERVER}                  ${EMPTY}
+${PNOR_TFTP_FILE_NAME}          ${EMPTY}
+${BMC_TFTP_FILE_NAME}           ${EMPTY}
+${IMAGE_FILE_PATH}              ${EMPTY}
+${ALTERNATE_IMAGE_FILE_PATH}    ${EMPTY}
+${PNOR_IMAGE_FILE_PATH}         ${EMPTY}
+${BMC_IMAGE_FILE_PATH}          ${EMPTY}
+${BAD_IMAGES_DIR_PATH}          ${EMPTY}
 
 # The caller must set this to the string "true" in order to delete images. The
 # code is picky.
diff --git a/tools/generate_argumentfile.sh b/tools/generate_argumentfile.sh
index 4ca44f0..3316500 100755
--- a/tools/generate_argumentfile.sh
+++ b/tools/generate_argumentfile.sh
@@ -26,6 +26,7 @@
 echo "--variable PNOR_TFTP_FILE_NAME:$PNOR_TFTP_FILE_NAME" >> $ARG_FILE
 echo "--variable BMC_TFTP_FILE_NAME:$BMC_TFTP_FILE_NAME" >> $ARG_FILE
 echo "--variable IMAGE_FILE_PATH:$IMAGE_FILE_PATH" >> $ARG_FILE
+echo "--variable ALTERNATE_IMAGE_FILE_PATH:$ALTERNATE_IMAGE_FILE_PATH" >> $ARG_FILE
 echo "--variable PNOR_IMAGE_FILE_PATH:$PNOR_IMAGE_FILE_PATH" >> $ARG_FILE
 echo "--variable BMC_IMAGE_FILE_PATH:$BMC_IMAGE_FILE_PATH" >> $ARG_FILE
 echo "--variable BAD_IMAGES_DIR_PATH:$BAD_IMAGES_DIR_PATH" >> $ARG_FILE