Added new testcase for Get SDR info and Reserve SDR IPMI Commands

Modified Get SDR info testcase to verify supported commands dynamically,
rather than harcoded values.

Testcase Added:
    - Test Reserve SDR repository.
    - Verify Reserve SDR repository cmd functionality using get SDR cmd.
    - Test Invalid reservation ID using Get SDR command.
    - Verify Reserve SDR cmd after BMC reboot.

Tested  Run robot ipmi/test_ipmi_sdr.robot

Signed-off-by: Nagarjun B   <nagarjunb@ami.com>
Change-Id: I7ac3d23133c42c9823c6cbc4f14d968ecd89b78c
diff --git a/data/ipmi_raw_cmd_table.py b/data/ipmi_raw_cmd_table.py
index 690fba0..7a5cbea 100644
--- a/data/ipmi_raw_cmd_table.py
+++ b/data/ipmi_raw_cmd_table.py
@@ -606,4 +606,43 @@
             # 81 - aes_cbc_128
         ]
     },
+    'SDR':
+    {
+        'Get':
+        [
+            # Get SDR raw command without Reservation ID.
+            "0x0a 0x23 0x00 0x00 0x00 0x00 0x00 0xff",
+            # Netfunction and command.
+            "0x0a 0x23",
+            # Record ID offset and bytes to read.
+            "0x00 0x00 0x01 0x0f",
+            #  Raw command To Get SDR Partial without reservation ID.
+            "0x0a 0x23 0x00 0x00 0x00 0x00 0x01 0x0f"
+        ],
+        'Reserve SDR Repository':
+        [
+            # raw command, expected output(s), comment
+            "0x0a 0x22",
+        ],
+        'SDR Repository Info':
+        [
+            # raw command.
+            "0x0a 0x20",
+        ],
+        'Get SDR allocation Info':
+        [
+            # raw command.
+            "0x0a 0x21"
+        ],
+        'Delete SDR':
+        [
+            # raw command.
+            "0x0a 0x26"
+        ],
+        'Partially Add SDR':
+        [
+            # raw command.
+            "0x0a 0x25"
+        ]
+    },
 }
diff --git a/ipmi/test_ipmi_sdr.robot b/ipmi/test_ipmi_sdr.robot
index 34f357e..6e6d776 100755
--- a/ipmi/test_ipmi_sdr.robot
+++ b/ipmi/test_ipmi_sdr.robot
@@ -7,6 +7,8 @@
 Resource               ../lib/boot_utils.robot
 Resource               ../lib/bmc_redfish_resource.robot
 Library                ../lib/ipmi_utils.py
+Library                ../lib/utilities.py
+Variables              ../data/ipmi_raw_cmd_table.py
 
 Suite setup             Suite Setup Execution
 Suite Teardown          Redfish.Logout
@@ -33,6 +35,16 @@
     # Reserve SDR repository supported    : no
     # SDR Repository Alloc info supported : no
 
+    # Check if delete, partially add, reserve SDR and get SDR alloc info command are supported or not.
+    ${support_delete_sdr}=  Fetch IPMI Command Support Status
+    ...  ${IPMI_RAW_CMD['SDR']['Delete SDR'][0]}
+    ${support_partial_add}=  Fetch IPMI Command Support Status
+    ...  ${IPMI_RAW_CMD['SDR']['Partially Add SDR'][0]}
+    ${support_reserve_sdr_repository}=  Fetch IPMI Command Support Status
+    ...  ${IPMI_RAW_CMD['SDR']['Reserve SDR Repository'][0]}
+    ${support_sdr_repository_alloc_info}=  Fetch IPMI Command Support Status
+    ...  ${IPMI_RAW_CMD['SDR']['Get SDR allocation Info'][0]}
+
     ${sdr_info}=  Get SDR Info
     Should Be Equal  ${sdr_info['sdr_version']}  0x51
 
@@ -42,14 +54,14 @@
     ...  ${sdr_info['record_count']}  ${sensor_count}
 
     Should Be Equal  ${sdr_info['free_space']}  unspecified
-    Should Be Equal  ${sdr_info['most_recent_addition']}  ${EMPTY}
-    Should Be Equal  ${sdr_info['most_recent_erase']}  ${EMPTY}
-    Should Be Equal  ${sdr_info['sdr_overflow']}  no
+    Should Not Be Equal  ${sdr_info['most_recent_addition']}  ${EMPTY}
+    Should Not Be Equal  ${sdr_info['most_recent_erase']}  ${EMPTY}
+    Should Be Equal  ${sdr_info['sdr_overflow']}  yes
     Should Be Equal  ${sdr_info['sdr_repository_update_support']}  unspecified
-    Should Be Equal  ${sdr_info['delete_sdr_supported']}  no
-    Should Be Equal  ${sdr_info['partial_add_sdr_supported']}  no
-    Should Be Equal  ${sdr_info['reserve_sdr_repository_supported']}  no
-    Should Be Equal  ${sdr_info['sdr_repository_alloc_info_supported']}  no
+    Should Be Equal  ${sdr_info['delete_sdr_supported']}  ${support_delete_sdr}
+    Should Be Equal  ${sdr_info['partial_add_sdr_supported']}  ${support_partial_add}
+    Should Be Equal  ${sdr_info['reserve_sdr_repository_supported']}  ${support_reserve_sdr_repository}
+    Should Be Equal  ${sdr_info['sdr_repository_alloc_info_supported']}  ${support_sdr_repository_alloc_info}
 
 
 Test CPU Core SDR Info At Power On
@@ -146,9 +158,101 @@
     ...  ELSE IF  '${state_ipmi}' == 'State Asserted'
     ...    Should Be True  ${state_rest} == ${1}
 
+Test Reserve SDR Repository
+    [Documentation]  Verify Reserve SDR Repository IPMI command.
+    [Tags]  Test_Reserve_SDR_Repository
+
+    ${reservation_id}=  Get Reservation ID  convert_lsb_to_msb=True
+
+    # Getting another Reservation ID and verify it is different from previous Reservation ID.
+    ${new_reservation_id}=  Get Reservation ID  convert_lsb_to_msb=True
+
+    Should Not Be Equal  ${reservation_id}  ${new_reservation_id}
+    ...  msg=Getting same reseravtion ID for second time, reservation ID must be different.
+
+Test Get SDR Using Reservation ID
+   [Documentation]  Verify get SDR command using reservation ID obtained from Reserve SDR repository.
+   [Tags]  Test_Get_SDR_Using_Reservation_ID
+
+   ${reservation_id}=  Get Reservation ID  add_prefix=True
+
+   # Get SDR full without using Reservation ID.
+   Run External IPMI Raw Command  ${IPMI_RAW_CMD['SDR']['Get'][0]}
+
+   # Get SDR Partially using Reservation ID.
+   ${get_sdr_raw_cmd}=  Catenate
+   ...  ${IPMI_RAW_CMD['SDR']['Get'][1]} ${reservation_id} ${IPMI_RAW_CMD['SDR']['Get'][2]}
+   Run External IPMI Raw Command  ${get_sdr_raw_cmd}
+
+   # Get SDR partially without using reservation ID and expect error.
+   Verify Invalid IPMI Command  ${IPMI_RAW_CMD['SDR']['Get'][3]}  0xc5
+
+
+Test Get SDR Using Invalid Reservation ID
+    [Documentation]  Verify get SDR command using invalid reservation ID.
+    [Tags]  Test_Get_SDR_Using_Invalid_Reservation_ID
+
+    # Generate two reservation ID and verify get SDR partial using old reservation ID.
+    ${first_reservation_id}=  Get Reservation ID  add_prefix=True
+    ${second_reservation_id}=  Get Reservation ID  add_prefix=True
+
+    # Creating raw command with First reservation ID.
+    ${get_sdr_raw_cmd}=  Catenate
+    ...  ${IPMI_RAW_CMD['SDR']['Get'][1]} ${first_reservation_id} ${IPMI_RAW_CMD['SDR']['Get'][2]}
+
+    Verify Invalid IPMI Command  ${get_sdr_raw_cmd}  0xc5
+
+Test Reserve SDR Repository After BMC Reboot
+    [Documentation]  Verify reserve SDR repository reservation ID after BMC Reboot.
+    [Tags]  Test_Reserve_SDR_Repository_After_BMC_Reboot
+
+    #  Get Reservation ID before reboot.
+    ${reservation_id_before_reboot}=  Get Reservation ID  add_prefix=True
+
+    # Cold reset BMC
+    IPMI MC Reset Cold (run)
+
+    # Create Get SDR Partially command using reservation ID which got before reboot.
+    ${get_sdr_raw_cmd}=  Catenate
+    ...  ${IPMI_RAW_CMD['SDR']['Get'][1]} ${reservation_id_before_reboot} ${IPMI_RAW_CMD['SDR']['Get'][2]}
+
+    Verify Invalid IPMI Command  ${get_sdr_raw_cmd}  0xc5
+
+    #  Verify get SDR partially with new reservation ID after reboot.
+    ${reservation_id_after_reboot}=  Get Reservation ID  add_prefix=True
+    ${get_sdr_raw_cmd}=  Catenate
+    ...  ${IPMI_RAW_CMD['SDR']['Get'][1]} ${reservation_id_after_reboot} ${IPMI_RAW_CMD['SDR']['Get'][2]}
+    Run External IPMI Raw Command  ${get_sdr_raw_cmd}
+
 
 *** Keywords ***
 
+Get Reservation ID
+    [Documentation]  Get reservation ID using reserve SDR repository.
+    [Arguments]  ${add_prefix}=False  ${convert_lsb_to_msb}=False
+
+    # Description of argument(s):
+    # add_prefix             If True will prefix "0x" to the reservation ID.
+    #                        e.g. IPMI response for Reservation ID command will be  like 01 00
+    #                        return reservation ID will be "0x01" for above response.
+
+    # convert_lsb_to_msb     If True will convert the reservation ID from LSB first to MSB first.
+    #                        e.g. IPMI response for reservation ID command will be like  01 0a
+    #                        return reservation ID will be "a1" for above response.
+
+    ${reservation_id}=  Run External IPMI Raw Command
+    ...  ${IPMI_RAW_CMD['SDR']['Reserve SDR Repository'][0]}
+
+    ${reservation_id}=  Run Keyword If  ${add_prefix}
+    ...  Add Prefix To String  ${reservation_id}  0x
+    ...  ELSE IF  ${convert_lsb_to_msb}
+    ...  Convert LSB To MSB  ${reservation_id}
+    ...  ELSE
+    ...  Return From Keyword  ${reservation_id}
+
+    [Return]  ${reservation_id}
+
+
 Get Sensor Count
     [Documentation]  Get sensors count using "sdr elist all" command.
     # Example of "sdr elist all" command output:
@@ -282,6 +386,20 @@
       Verify SDR  ${component_name}
     END
 
+Fetch IPMI Command Support Status
+    [Documentation]  Return yes if IPMI command is supported.
+    [Arguments]  ${ipmi_cmd}
+
+    # Description of argument(s):
+    # ipmi_cmd    IPMI command.
+
+    ${resp}=  Run External IPMI Raw Command  ${ipmi_cmd}  fail_on_err=0
+    ${resp_code_match}=  Get Regexp Matches  ${resp}  rsp=0xc1
+
+    ${cmd_support}=  Set Variable If  ${resp_code_match} != []  no  yes
+
+    [Return]  ${cmd_support}
+
 
 Suite Setup Execution
     [Documentation]  Do the initial suite setup.
diff --git a/lib/utilities.py b/lib/utilities.py
index 6416aa9..1994fe7 100755
--- a/lib/utilities.py
+++ b/lib/utilities.py
@@ -250,3 +250,30 @@
     Returns the element from the list with minimum value.
     """
     return min(value_list)
+
+
+def convert_lsb_to_msb(string):
+    r"""
+    Reverse given string (From LSB first to MSB first) and converts to HEX.
+
+    Input stirng     0a 00
+    Return string    0a
+    """
+    datalist = string.split(" ")
+    new_list = datalist[::-1]
+    new_string = "".join([str(element) for element in new_list])
+    return int(new_string, 16)
+
+
+def add_prefix_to_string(string, prefix):
+    r"""
+    Add given prefix to the string and return string.
+
+    Input string      0a 01
+    Return string     0x0a 0x01
+    """
+    prefix_string = ''
+    data_list = string.strip().split(" ")
+    for item in data_list:
+        prefix_string += prefix + item + ' '
+    return prefix_string.strip()