Run code update in loop

changes:
   - Default loop count value is set to 20, but can be passed as argument.
   - Added test case "Redfish Firmware Update Loop"
   - Added keyword "Redfish Firmware Update In Loop"
   - Added keyword "Get BMC Functional Firmware"
   - Added keyword "Get Functional Firmware"
   - Added keyword "Get Non Fucntional Firmware"
   - Added keyword "Delete BMC Image"

Change-Id: I1ba7fff156ba2e8c85baa01f0f4b3267e2b5c4cd
Signed-off-by: Sushil Singh <susilsi7@in.ibm.com>
diff --git a/lib/code_update_utils.py b/lib/code_update_utils.py
index ac1efc9..35f9e85 100644
--- a/lib/code_update_utils.py
+++ b/lib/code_update_utils.py
@@ -9,6 +9,7 @@
 import sys
 import tarfile
 import time
+import collections
 from robot.libraries.BuiltIn import BuiltIn
 
 robot_pgm_dir_path = os.path.dirname(__file__) + os.sep
@@ -22,6 +23,24 @@
 from robot.libraries.BuiltIn import BuiltIn
 
 
+def get_bmc_firmware(image_type, sw_dict):
+    r"""
+    Get the dictionary of image based on image type like either BMC or Host.
+
+    Description of argument(s):
+    image_type                     This value is either BMC update or Host update type.
+    sw_dict                        This contain dictionay of firmware inventory properties.
+    """
+
+    temp_dict = collections.OrderedDict()
+    for key, value in sw_dict.items():
+        if value['image_type'] == image_type:
+            temp_dict[key] = value
+        else:
+            pass
+    return temp_dict
+
+
 def verify_no_duplicate_image_priorities(image_purpose):
     r"""
     Check that there are no active images with the same purpose and priority.
diff --git a/lib/redfish_code_update_utils.robot b/lib/redfish_code_update_utils.robot
index a97b06e..ba5fb60 100644
--- a/lib/redfish_code_update_utils.robot
+++ b/lib/redfish_code_update_utils.robot
@@ -18,7 +18,8 @@
 
     ${image_info}=  Redfish.Get Properties  /redfish/v1/UpdateService/FirmwareInventory/${image_id}
 
-    ${sw_functional}=  Run Keyword If  '${image_info["Description"]}' == 'BMC image'
+    ${sw_functional}=  Run Keyword If
+    ...   '${image_info["Description"]}' == 'BMC image' or '${image_info["Description"]}' == 'BMC update'
     ...    Redfish.Get Attribute  /redfish/v1/Managers/bmc  FirmwareVersion
     ...  ELSE
     ...    Redfish.Get Attribute  /redfish/v1/Systems/system  BiosVersion
@@ -114,10 +115,12 @@
     ${manifest}  ${stderr}  ${rc}=  BMC Execute Command  cat /tmp/images/${image_id}/MANIFEST
     Rprint Vars  manifest
 
-    Check Image Update Progress State
-    ...  match_state='Disabled', 'Updating'  image_id=${image_id}
+    Wait Until Keyword Succeeds  1 min  05 sec
+    ...  Check Image Update Progress State  match_state='Disabled', 'Updating'  image_id=${image_id}
+
     # Wait a few seconds to check if the update progress started.
     Sleep  5s
+
     Check Image Update Progress State
     ...  match_state='Updating'  image_id=${image_id}
 
diff --git a/redfish/extended/redfish_bmc_code_update.robot b/redfish/extended/redfish_bmc_code_update.robot
index ebec8a7..5362200 100644
--- a/redfish/extended/redfish_bmc_code_update.robot
+++ b/redfish/extended/redfish_bmc_code_update.robot
@@ -19,6 +19,7 @@
 Library                  ../../lib/gen_robot_valid.py
 Library                  ../../lib/var_funcs.py
 Library                  ../../lib/gen_robot_keyword.py
+Library                  ../../lib/code_update_utils.py
 
 Suite Setup              Suite Setup Execution
 Suite Teardown           Redfish.Logout
@@ -30,7 +31,7 @@
 *** Variables ***
 
 ${FORCE_UPDATE}          ${0}
-
+${LOOP_COUNT}            20
 
 *** Test Cases ***
 
@@ -53,6 +54,15 @@
     ...  Activate Existing Firmware  ${image_version}
     Redfish Update Firmware
 
+
+Redfish Firmware Update Loop
+    [Documentation]  Update the firmware image in loop.
+    [Tags]  Redfish_Firmware_Update_Loop
+    [Template]  Redfish Firmware Update In Loop
+
+    ${LOOP_COUNT}
+
+
 *** Keywords ***
 
 Suite Setup Execution
@@ -65,6 +75,78 @@
     # Checking for file existence.
     Valid File Path  IMAGE_FILE_PATH
 
+
+Redfish Firmware Update In Loop
+    [Documentation]  Update the firmware in loop.
+    [Arguments]  ${update_loop_count}
+
+    # Description of argument(s):
+    # update_loop_count    This value is used to run the firmware update in loop.
+
+    ${before_image_state}=  Get BMC Functional Firmware
+
+    FOR  ${count}  IN RANGE  ${update_loop_count}
+      Print Timen  **************************************
+      Print Timen  * The Current Loop Count is ${count} of ${update_loop_count} *
+      Print Timen  **************************************
+      Redfish Update Firmware
+      ${sw_inv}=  Get Functional Firmware  BMC update
+      ${nonfunctional_sw_inv}=  Get Non Fucntional Firmware  ${sw_inv}  False
+      Run Keyword If  ${nonfunctional_sw_inv['functional']} == False
+      ...  Set BMC Image Priority To Least  ${nonfunctional_sw_inv['version']}  ${nonfunctional_sw_inv}
+      Redfish.Login
+      ${sw_inv}=  Get Functional Firmware  BMC update
+      ${nonfunctional_sw_inv}=  Get Non Fucntional Firmware  ${sw_inv}  False
+      Delete BMC Image
+    END
+
+    ${after_image_state}=  Get BMC Functional Firmware
+    Valid Value  before_image_state["version"]  ['${after_image_state["version"]}']
+
+
+Get BMC Functional Firmware
+    [Documentation]  Get BMC functional firmware details.
+
+    ${sw_inv}=  Get Functional Firmware  BMC update
+    ${sw_inv}=  Get Non Fucntional 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 Fucntional Firmware
+    [Documentation]  Get BMC non functional fimware details.
+    [Arguments]  ${sw_inv}  ${functional_sate}
+
+    # Description of argument(s):
+    # sw_inv           This dictionay contains all the BMC fimware details.
+    # functional_sate  Functional state can be either True or False.
+
+    ${resp}=  Filter Struct  ${sw_inv}  [('functional', ${functional_sate})]
+    ${list_inv_dict}=  Get Dictionary Values  ${resp}
+
+    [Return]  ${list_inv_dict}[0]
+
+
+Delete BMC Image
+    [Documentation]  Delete a BMC image from the BMC flash chip.
+
+    ${software_object}=  Get Non Running BMC Software Object
+    Delete Image And Verify  ${software_object}  ${VERSION_PURPOSE_BMC}
+
+
 Activate Existing Firmware
     [Documentation]  Set fimware image to lower priority.
     [Arguments]  ${image_version}