FRU fields validation

Verifying the FRU's properties defined in YAML file for inventory.

Logic:
    1. Find the list of qualified FRU's from inventory.
    2. Iterate the FRU url and extract the fields.
    3. Compare the FRU properties set from system vs the derived
       FRU properties from YAML file (e.g. "data/inventory.py").
    4. Any mismatch would be a failure.

Resolves openbmc/openbmc-test-automation#417

Change-Id: I526c28e957fc8ff9cd46bacfd3ff108728f8550e
Signed-off-by: George Keishing <gkeishin@in.ibm.com>
diff --git a/lib/utilities.py b/lib/utilities.py
index 498348c..a68354c 100755
--- a/lib/utilities.py
+++ b/lib/utilities.py
@@ -231,3 +231,25 @@
     return row
 
 ###############################################################################
+
+
+###############################################################################
+def list_to_set(fru_list=""):
+    r"""
+    Pack the list into a set tuple and return.
+
+    It may seem that this function is rather trivial. However, it simplifies
+    the code and improves robot program readability and achieve the result
+    required.
+
+    Example result:
+
+    set(['Version', 'PartNumber', 'SerialNumber', 'FieldReplaceable',
+    'BuildDate', 'Present', 'Manufacturer', 'PrettyName', 'Cached', 'Model'])
+
+    # Description of arguments.
+    fru_list   List of FRU's elements.
+    """
+    return set(fru_list)
+
+###############################################################################
diff --git a/tests/test_inventory.robot b/tests/test_inventory.robot
index 3c4ac8b..34694c4 100644
--- a/tests/test_inventory.robot
+++ b/tests/test_inventory.robot
@@ -5,6 +5,7 @@
 Resource          ../lib/utils.robot
 Resource          ../lib/state_manager.robot
 Resource          ../lib/openbmc_ffdc.robot
+Library           ../lib/utilities.py
 
 Variables         ../data/variables.py
 Variables         ../data/inventory.py
@@ -105,6 +106,42 @@
     \  Should Be True  ${present}
 
 
+Verify FRU Properties
+    [Documentation]  Verify the FRU properties fields.
+    [Tags]  Verify_FRU_Properties
+    # Example:
+    # A FRU would have "FieldReplaceable" set to boolean 1 and should have
+    # the following entries
+    #  "fru": [
+    #    "FieldReplaceable"
+    #    "BuildDate",
+    #    "Cached"
+    #    "SerialNumber",
+    #    "Version",
+    #    "Model",
+    #    "PrettyName",
+    #    "PartNumber",
+    #    "Present",
+    #    "Manufacturer",
+    # ]
+    # and FRU which doesn't have one of this fields is an error.
+    #   "/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm0": {
+    #    "FieldReplaceable": 1,
+    #    "BuildDate": "",
+    #    "Cached": 0,
+    #    "SerialNumber": "0x0300cf4f",
+    #    "Version": "0x00",
+    #    "Model": "M393A1G40EB1-CRC    ",
+    #    "PrettyName": "0x0c",
+    #    "PartNumber": "",
+    #    "Present": 1,
+    #    "Manufacturer": "0xce80"
+    # },
+
+    ${system_list}=  Get Endpoint Paths  ${HOST_INVENTORY_URI}system  *
+    ${fru_list}=  Qualified FRU List  @{system_list}
+    Validate FRU Properties Fields  @{fru_list}
+
 *** Keywords ***
 
 Test Suite Setup
@@ -128,3 +165,56 @@
     Should Be Equal As Strings  ${resp.status_code}  ${HTTP_OK}
     ${jsondata}=  To JSON  ${resp.content}
     [Return]  ${jsondata}
+
+
+Qualified FRU List
+    [Documentation]  Build the list of valid FRUs.
+    [Arguments]  @{system_list}
+    # Description of arguments:
+    # system_list  List of system inventory URLs.
+    # Example:
+    # /xyz/openbmc_project/inventory/system/chassis/motherboard
+    # /xyz/openbmc_project/inventory/system/chassis/motherboard/cpu0
+    # /xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1
+    # /xyz/openbmc_project/inventory/system/chassis/motherboard/dimm0
+    # /xyz/openbmc_project/inventory/system/chassis/motherboard/dimm1
+    # /xyz/openbmc_project/inventory/system/chassis/motherboard/dimm2
+    # /xyz/openbmc_project/inventory/system/chassis/motherboard/dimm3
+    # /xyz/openbmc_project/inventory/system/chassis/motherboard/dimm4
+    # /xyz/openbmc_project/inventory/system/chassis/motherboard/dimm5
+    # /xyz/openbmc_project/inventory/system/chassis/motherboard/dimm6
+    # /xyz/openbmc_project/inventory/system/chassis/motherboard/dimm7
+
+    ${fru_list}=  Create List
+    :FOR  ${fru_uri}  IN  @{system_list}
+    \  ${is_fru}=  OpenBMC Get Request  ${fru_uri}/attr/FieldReplaceable
+    \  ${status}=  Run Keyword And Return Status  Should Be True  ${is_fru}
+    \  Run Keyword If  '${status}' == '${True}'
+    ...  Append To List  ${fru_list}  ${fru_uri}
+
+    [Return]  ${fru_list}
+
+
+Validate FRU Properties Fields
+    [Documentation]  Compare valid FRUs from system vs expected FRU set.
+    [Arguments]  @{fru_list}
+    # Description of arguments:
+    # fru_list  List of qualified FRU URLs.
+
+    # Build the pre-defined set list from data/inventory.py derived from
+    # a group of YAML files.
+    # Example:
+    # set(['Version', 'PartNumber', 'SerialNumber', 'FieldReplaceable',
+    # 'BuildDate', 'Present', 'Manufacturer', 'PrettyName', 'Cached', 'Model'])
+    ${fru_set}=  List To Set  ${inventory_dict['fru']}
+
+    # Iterate through the FRU's url and compare the set dictionary keys
+    # with the pre-define inventory data.
+    :FOR  ${fru_url_path}  IN  @{fru_list}
+    \  ${fru_field}=  Read Properties  ${fru_url_path}
+    # ------------------------------------------------------------
+    #  ${fru_field.viewkeys()} extracts the list of keys from the
+    #  JSON dictionary as a set.
+    # ------------------------------------------------------------
+    \  Should Be Equal  ${fru_field.viewkeys()}  ${fru_set}
+