Add oem folder for verify special sensor name

Changes:
        -Add "data/oem/ieisystem/sensors_resource.json".
        -Add "oem/ieisystem/test_sensor_monitoring.robot".

Tested:
        -Ran and Tested on ieisystem bmc Environment.

Change-Id: I7a9c6e8c1cfd5afbbd0f6da0a69aef2b1db7c02e
Signed-off-by: Guowei Zheng <zhengguowei@ieisystem.com>
Signed-off-by: Chicago Duan <duanzhijia01@ieisystem.com>
diff --git a/data/oem/ieisystem/sensors_resource.json b/data/oem/ieisystem/sensors_resource.json
new file mode 100644
index 0000000..a9d316f
--- /dev/null
+++ b/data/oem/ieisystem/sensors_resource.json
@@ -0,0 +1,176 @@
+{
+    "Voltages": [
+        "P12V_CPU0_DIMM",
+        "P1V05_PCH_STBY",
+        "PSU1_VOUT",
+        "PVCCD_HV_CPU0",
+        "PVCCD_HV_CPU1",
+        "PVCCINFAON_CPU0",
+        "PVCCINFAON_CPU1",
+        "PVCCIN_CPU0",
+        "PVCCIN_CPU1",
+        "PVNN_MAIN_CPU0",
+        "PVNN_PCH_STBY",
+        "RTC_Battery",
+        "SYS_12V",
+        "SYS_3V3",
+        "SYS_5V"
+    ],
+    "Temperatures": [
+        "CPU0_DTS_Margin",
+        "CPU0_Temp",
+        "GPU_Temp",
+        "Inlet_Temp",
+        "NVMe_MAX_Temp",
+        "OCP_NIC_TEMP",
+        "OCP_SFP_TEMP",
+        "Outlet_Temp",
+        "PCH_Temp",
+        "PCIE_NIC_TEMP",
+        "PCIE_SFP_TEMP",
+        "PSU1_Inlet_Temp",
+        "PSU1_Temp"
+    ],
+    "Fans": [
+        "fan0_0",
+        "fan0_1",
+        "fan1_0",
+        "fan1_1",
+        "fan2_0",
+        "fan2_1",
+        "fan3_1",
+        "fan4_0",
+        "fan4_1",
+        "fan5_0",
+        "fan5_1"
+    ],
+    "DiscreteSensors": [
+        "Nvme0",
+        "Nvme1",
+        "Drive10",
+        "Drive11",
+        "Drive2",
+        "Drive3",
+        "Drive4",
+        "Drive5",
+        "Drive6",
+        "Drive7",
+        "Drive8",
+        "Drive9",
+        "Power_Button",
+        "bmc_boot_up",
+        "POST_Status",
+        "SEL_Status",
+        "TPM_Verify",
+        "Watchdog2",
+        "PWR_Drop",
+        "PWR_On_TMOUT",
+        "Sys_Health",
+        "ACPI_PWR",
+        "CPU0_C0D0",
+        "CPU0_C0D1",
+        "CPU0_C1D0",
+        "CPU0_C1D1",
+        "CPU0_C2D0",
+        "CPU0_C2D1",
+        "CPU0_C3D0",
+        "CPU0_C3D1",
+        "CPU0_C4D0",
+        "CPU0_C4D1",
+        "CPU0_C5D0",
+        "CPU0_C5D1",
+        "CPU0_C6D0",
+        "CPU0_C6D1",
+        "CPU0_C7D0",
+        "CPU0_C7D1",
+        "CPU0_MEM_Hot",
+        "CPU0_Status",
+        "CPU1_C0D0",
+        "CPU1_C0D1",
+        "CPU1_C1D0",
+        "CPU1_C1D1",
+        "CPU1_C2D0",
+        "CPU1_C2D1",
+        "CPU1_C3D0",
+        "CPU1_C3D1",
+        "CPU1_C4D0",
+        "CPU1_C4D1",
+        "CPU1_C5D0",
+        "CPU1_C5D1",
+        "CPU1_C6D0",
+        "CPU1_C6D1",
+        "CPU1_C7D0",
+        "CPU1_C7D1",
+        "CPU1_MEM_Hot",
+        "CPU1_Status",
+        "CPU_Config",
+        "PSU0_Status",
+        "PSU1_Status",
+        "SysShutdown",
+        "System_Error",
+        "Fan_Redundant",
+        "PSU_Mismatch",
+        "PSU_Redundant",
+        "PWR_CAP_Fail",
+        "BMC_I2C",
+        "System_Restart",
+        "UID_Button",
+        "PCIE_Status"
+    ],
+    "ThresholdSensors": [
+        "SYS_12V",
+        "SYS_3V3",
+        "SYS_5V",
+        "RTC_Battery",
+        "fan5_0",
+        "fan2_1",
+        "fan1_0",
+        "fan2_0",
+        "fan4_1",
+        "fan0_1",
+        "fan4_0",
+        "fan0_0",
+        "fan5_1",
+        "fan1_1",
+        "fan3_1",
+        "fan3_0",
+        "NVMe_MAX_Temp",
+        "PCIE_SFP_TEMP",
+        "GPU_Temp",
+        "OCP_SFP_TEMP",
+        "OCP_NIC_TEMP",
+        "Total_Power",
+        "PCIE_NIC_TEMP",
+        "MEM_ResourceRate",
+        "IO_ResourceRate",
+        "CPU_ResourceRate",
+        "PCH_Temp",
+        "Inlet_Temp",
+        "Outlet_Temp",
+        "PSU1_POUT",
+        "PSU1_Inlet_Temp",
+        "PSU0_POUT",
+        "PVCCINFAON_CPU0",
+        "PVNN_MAIN_CPU0",
+        "PSU1_VOUT",
+        "FAN_Power",
+        "PSU0_VIN",
+        "PVCCINFAON_CPU1",
+        "PSU1_Temp",
+        "PSU1_VIN",
+        "PSU0_VOUT",
+        "PSU0_PIN",
+        "PVCCIN_CPU0",
+        "PVCCD_HV_CPU1",
+        "PSU0_Temp",
+        "P12V_CPU1_DIMM",
+        "P1V05_PCH_STBY",
+        "PVCCD_HV_CPU0",
+        "PSU0_Inlet_Temp",
+        "PVNN_PCH_STBY",
+        "PSU1_PIN",
+        "PVCCIN_CPU1",
+        "P12V_CPU0_DIMM",
+        "PVNN_MAIN_CPU1"
+    ]
+}
diff --git a/oem/ieisystem/test_sensor_monitoring.robot b/oem/ieisystem/test_sensor_monitoring.robot
new file mode 100644
index 0000000..a55258e
--- /dev/null
+++ b/oem/ieisystem/test_sensor_monitoring.robot
@@ -0,0 +1,247 @@
+*** Settings ***
+Documentation    Test Redfish sensor monitoring.
+
+Resource         ../../lib/resource.robot
+Resource         ../../lib/bmc_redfish_resource.robot
+Resource         ../../lib/bmc_redfish_utils.robot
+Library          ../../lib/gen_robot_print.py
+Library          ../../lib/utils.py
+
+Test Setup       Test Setup Execution
+Test Teardown    Test Teardown Execution
+Test Tags        Test_Sensor_Monitoring
+
+*** Variables ***
+
+@{INVALID_SENSORS}
+${OPENBMC_CONN_METHOD}  ssh
+${IPMI_COMMAND}         Inband
+
+** Test Cases **
+
+Verify Sensor Monitoring
+    [Documentation]  Verify the redfish sensor monitoring according to the BMC
+    ...              expected SDR table.
+    [Tags]  Verify_Sensor_Monitoring
+
+    # Check whether the expected sensors are present in the Redfish request.
+    # Check whether the sensors's 'Health' is 'OK' and the 'State' is 'Enabled'.
+    # Check sensor reading is not equal to null.
+
+    ${resp}=  Redfish.Get  /redfish/v1/Chassis/${CHASSIS_ID}
+    ...  valid_status_codes=[${HTTP_OK}]
+
+   Should Be Equal As Strings  ${resp.dict['Oem']['Public']['DiscreteSensors']['@odata.id']}
+   ...  /redfish/v1/Chassis/${CHASSIS_ID}/DiscreteSensors
+   Should Be Equal As Strings  ${resp.dict['Oem']['Public']['ThresholdSensors']['@odata.id']}
+   ...  /redfish/v1/Chassis/${CHASSIS_ID}/ThresholdSensors
+   Should Be Equal As Strings  ${resp.dict['Thermal']['@odata.id']}
+   ...  /redfish/v1/Chassis/${CHASSIS_ID}/Thermal
+   Should Be Equal As Strings  ${resp.dict['Power']['@odata.id']}
+   ...  /redfish/v1/Chassis/${CHASSIS_ID}/Power
+
+    # Check sensors in /redfish/v1/Chassis/{ChassisId}/Power
+    ${resp}=  Redfish.Get  /redfish/v1/Chassis/${CHASSIS_ID}/Power
+    ...  valid_status_codes=[${HTTP_OK}]
+
+    Check If Expected Sensors Are Present  ${resp.dict['Voltages']}  Voltages
+    Check Sensor Status And Reading Via Sensor Info
+    ...  ${resp.dict['Voltages']}  ReadingVolts
+
+    # Check sensors in /redfish/v1/Chassis/{ChassisId}/Thermal
+    ${resp}=  Redfish.Get  /redfish/v1/Chassis/${CHASSIS_ID}/Thermal
+    ...  valid_status_codes=[${HTTP_OK}]
+
+    Check If Expected Sensors Are Present  ${resp.dict['Temperatures']}  Temperatures
+    Check If Expected Sensors Are Present  ${resp.dict['Fans']}  Fans
+
+    Check Sensor Status And Reading Via Sensor Info
+    ...  ${resp.dict['Temperatures']}  ReadingCelsius
+    Check Sensor Status And Reading Via Sensor Info
+    ...  ${resp.dict['Fans']}  Reading
+
+    # Check sensors in
+    # /redfish/v1/Chassis/{ChassisId}/DiscreteSensors
+    ${resp}=  Redfish.Get  /redfish/v1/Chassis/${CHASSIS_ID}/DiscreteSensors
+    ...  valid_status_codes=[${HTTP_OK}]
+
+    Check If Expected Sensors Are Present  ${resp.dict['Sensors']}  DiscreteSensors
+    Check Sensor Status And Reading Via Sensor Info
+    ...  ${resp.dict['Sensors']}  Status
+
+    # Check sensors in
+    # /redfish/v1/Chassis/{ChassisId}/ThresholdSensors
+    ${resp}=  Redfish.Get  /redfish/v1/Chassis/${CHASSIS_ID}/ThresholdSensors
+    ...  valid_status_codes=[${HTTP_OK}]
+
+    Check If Expected Sensors Are Present  ${resp.dict['Sensors']}  ThresholdSensors
+    Check Sensor Status And Reading Via Sensor Info
+    ...  ${resp.dict['Sensors']}  Reading
+
+    Rprint Vars  INVALID_SENSORS
+
+    ${error_msg}=   Evaluate  ", ".join(${INVALID_SENSORS})
+    Should Be Empty  ${INVALID_SENSORS}
+    ...  msg=Test fail, invalid sensors are ${error_msg}.
+
+
+*** Keywords ***
+
+Test Teardown Execution
+    [Documentation]  Do the post test teardown.
+
+    Run Keyword And Ignore Error  Redfish.Logout
+
+
+Test Setup Execution
+    [Documentation]  Do the test setup.
+
+    Check For Required Parameters For Sensor Monitoring
+    Redfish.Login
+
+
+Check For Required Parameters For Sensor Monitoring
+    [Documentation]  Check if required parameters are provided via command line.
+
+    Should Not Be Empty   ${OS_HOST}
+    Should Not Be Empty   ${OS_USERNAME}
+    Should Not Be Empty   ${OS_PASSWORD}
+    IF  '${OPENBMC_CONN_METHOD}' == 'ssh'
+        Should Not Be Empty   ${OPENBMC_HOST}
+    ELSE IF  '${OPENBMC_CONN_METHOD}' == 'telnet'
+        Should Not Be Empty   ${OPENBMC_SERIAL_HOST}
+    ELSE
+        Fail  Invalid connection method: ${OPENBMC_CONN_METHOD}
+    END
+
+
+Get Sensors Name List From Redfish
+    [Documentation]  Get sensors name list from redfish.
+    [Arguments]  ${sensor_info_list}
+    # Description of arguments:
+    # sensor_info_list    A list of a specified sensor info return by a redfish
+    #                     request.
+
+    # An example of a sensor redfish request:
+    # /redfish/v1/Chassis/${CHASSIS_ID}/Power
+    # {
+    #     ...
+    #   "Voltages": [
+    #     {
+    #     "@odata.id": "/redfish/v1/Chassis/1/Power#/Voltages/0",
+    #     "@odata.type": "#Power.v1_7_1.Voltage",
+    #     "LowerThresholdCritical": 10.8,
+    #     "LowerThresholdFatal": 10.44,
+    #     "LowerThresholdNonCritical": 11.16,
+    #     "MaxReadingRange": 255.0,
+    #     "MemberId": "0",
+    #     "MinReadingRange": 0.0,
+    #     "Name": "P12V_CPU0_DIMM",
+    #     "ReadingVolts": null,
+    #     "Status": {
+    #         "Health": "OK",
+    #         "State": "Enabled"
+    #     },
+    #     "UpperThresholdCritical": 13.2,
+    #     "UpperThresholdFatal": 13.786,
+    #     "UpperThresholdNonCritical": 12.84
+    #     },
+
+    #     ..
+    # }
+
+    @{sensor_name_list}=  Create List
+    FOR  ${sensor_info}  IN  @{sensor_info_list}
+        Append To List  ${sensor_name_list}  ${sensor_info['Name']}
+    END
+
+    RETURN  ${sensor_name_list}
+
+
+Check Sensor Status And Reading Via Sensor Name
+    [Documentation]  Verify the sensor status and reading by sensor name,
+    ...              optionally checking if the reading is within a given range.
+    [Arguments]  ${sensor_name}
+    # Description of arguments:
+    # sensor_name    Sensor that should be present.
+
+    ${resp}=  Redfish.Get
+    ...  /redfish/v1/Chassis/${CHASSIS_ID}/Sensors/${sensor_name}
+    ...  valid_status_codes=[${HTTP_OK}, ${HTTP_NOT_FOUND}]
+
+    Run Keyword And Return If  '${resp.status}' == '${HTTP_NOT_FOUND}'
+    ...  Append To List  ${INVALID_SENSORS}  ${sensor_name}
+
+    ${condition_str}=  Catenate
+        ...  '${resp.dict['Status']['Health']}' != 'OK'
+        ...  or '${resp.dict['Status']['State']}' != 'Enabled'
+        ...  or ${resp.dict['Reading']} == ${null}
+
+    IF  ${condition_str}
+        Append To List  ${INVALID_SENSORS}  ${sensor_name}
+    END
+
+
+Check Sensor Status And Reading Via Sensor Info
+    [Documentation]  Check if each sensor's health is ok, state is enabled,
+    ...              and reading value (by unit) is not null from a redfish sensor info list.
+    [Arguments]  ${sensor_info_list}  ${reading_unit}
+    # Description of arguments:
+    # sensor_info_list  A list of a specified sensor info return by a redfish
+    #                   request.
+    # reading_unit      A string represents the reading value in sensor info
+    #                   return by a redfish request. It different between
+    #                   different sensor unit of sensor info.
+
+    FOR  ${sensor_info}  IN  @{sensor_info_list}
+        ${condition_str}=  Catenate
+        ...  '${sensor_info['Status']['Health']}' != 'OK'
+        ...  or '${sensor_info['Status']['State']}' != 'Enabled'
+        ...  or ${sensor_info['${reading_unit}']} == ${null}
+
+         IF  ${condition_str}
+             Append To List  ${INVALID_SENSORS}  ${sensor_info['Name']}
+         END
+    END
+
+
+Check If Expected Sensors Are Present
+    [Documentation]  Check that sensors are present as expected.
+    [Arguments]  ${sensor_info_list}  ${sensor_type}
+    # Description of arguments:
+    # sensor_info_list  A list of a specified sensor info return by a redfish
+    #                   request.
+    # sensor_type       A string represents the sensor category to be verified.
+
+    # An example table of expected sensors:
+    # redfish_sensor_info_map = {
+    #       "Voltages":{
+    #           "Voltage0",
+    #           ...
+    #       },
+    #       "Temperatures":{
+    #           "DIMM0",
+    #           ...
+    #       }
+    #       "Fans":{
+    #           "Fan0",
+    #           ...
+    #       }...
+    #}
+
+    ${curr_sensor_name_list}=  Get Sensors Name List From Redfish
+    ...  ${sensor_info_list}
+
+    ${code_base_dir_path}=  Get Code Base Dir Path
+    ${redfish_sensor_info_map}=  Evaluate
+    ...  json.load(open('${code_base_dir_path}data/oem/ieisystem/sensors_resource.json'))  modules=json
+
+    ${expected_sensor_name_list}=  Set Variable
+    ...  ${redfish_sensor_info_map['${sensor_type}']}
+
+    FOR  ${sensor_name}  IN  @{expected_sensor_name_list}
+        ${exist}=  Evaluate  '${sensor_name}' in ${curr_sensor_name_list}
+        IF  '${exist}' == '${False}'
+            Append To List  ${INVALID_SENSORS}  ${sensor_name}
+        END
+    END