Soft sensor progress state test

Added:
   - System boot states mapping.
   - Validate boot count "AttemptsLeft".
   - Validate boot states when power if off.
   - Validate boot states when BMC reset to standby.
   - Validate boot states when host is booting in progress.
   - Validate boot states when host is booted.
   - Validate boot states when BMC reset reload to runtime.

Resolves  openbmc/openbmc-test-automation#930

Change-Id: I1d0c89865fa14361fc1fedc30fcdb46bca342dc5
Signed-off-by: George Keishing <gkeishin@in.ibm.com>
diff --git a/data/variables.py b/data/variables.py
index 0c2a11e..342c5ee 100644
--- a/data/variables.py
+++ b/data/variables.py
@@ -39,6 +39,7 @@
 CHASSIS_POWERON_STATE = 'xyz.openbmc_project.State.Chassis.PowerState.On'
 
 # State Manager URI variables.
+SYSTEM_STATE_URI = '/xyz/openbmc_project/state/'
 BMC_STATE_URI = '/xyz/openbmc_project/state/bmc0/'
 HOST_STATE_URI = '/xyz/openbmc_project/state/host0/'
 CHASSIS_STATE_URI = '/xyz/openbmc_project/state/chassis0/'
diff --git a/lib/state_map.py b/lib/state_map.py
index e0f30a1..4ca309e 100644
--- a/lib/state_map.py
+++ b/lib/state_map.py
@@ -6,50 +6,132 @@
    - Defines Valid states of the system
 
 """
+import os
+import re
+import sys
+
 from robot.libraries.BuiltIn import BuiltIn
 
+robot_pgm_dir_path = os.path.dirname(__file__) + os.sep
+repo_data_dir_path = re.sub('/lib', '/data', robot_pgm_dir_path)
+sys.path.append(repo_data_dir_path)
+
+import gen_robot_keyword as keyword
+import variables as var
+
 BuiltIn().import_resource("state_manager.robot")
+BuiltIn().import_resource("rest_client.robot")
 
 # We will build eventually the mapping for warm, cold reset as well.
 VALID_STATES = {
     'reboot':
     {
-         # (Power Policy, BMC state, Chassis State, Host State)
-         ('LEAVE_OFF','Ready','Off','Off'),
-         ('ALWAYS_POWER_ON','Ready','On','Running'),
-         ('ALWAYS_POWER_ON','Ready','On','Off'),
-         ('RESTORE_LAST_STATE','Ready','On','Running'),
-         ('RESTORE_LAST_STATE','Ready','On','Off'),
-         ('RESTORE_LAST_STATE','Ready','Off','Off'),
+        # (Power Policy, BMC state, Chassis State, Host State)
+        ('LEAVE_OFF', 'Ready', 'Off', 'Off'),
+        ('ALWAYS_POWER_ON', 'Ready', 'On', 'Running'),
+        ('ALWAYS_POWER_ON', 'Ready', 'On', 'Off'),
+        ('RESTORE_LAST_STATE', 'Ready', 'On', 'Running'),
+        ('RESTORE_LAST_STATE', 'Ready', 'On', 'Off'),
+        ('RESTORE_LAST_STATE', 'Ready', 'Off', 'Off'),
+    },
+}
+
+VALID_BOOT_STATES = {
+    'Off':  # Valid states when Host is Off.
+    {
+        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
+        (
+            "xyz.openbmc_project.State.BMC.BMCState.Ready",
+            "xyz.openbmc_project.State.Chassis.PowerState.Off",
+            "xyz.openbmc_project.State.Host.HostState.Off",
+            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified",
+            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive"
+        ),
+    },
+    'Reboot':  # Valid states when BMC reset to standby.
+    {
+        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
+        (
+            "xyz.openbmc_project.State.BMC.BMCState.Ready",
+            "xyz.openbmc_project.State.Chassis.PowerState.Off",
+            "xyz.openbmc_project.State.Host.HostState.Off",
+            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified",
+            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive"
+        ),
+    },
+    'Running':  # Valid states when Host is powering on.
+    {
+        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
+        (
+            "xyz.openbmc_project.State.BMC.BMCState.Ready",
+            "xyz.openbmc_project.State.Chassis.PowerState.On",
+            "xyz.openbmc_project.State.Host.HostState.Running",
+            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.MotherboardInit",
+            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive"
+        ),
+    },
+    'Booted':  # Valid state when Host is booted.
+    {
+        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
+        (
+            "xyz.openbmc_project.State.BMC.BMCState.Ready",
+            "xyz.openbmc_project.State.Chassis.PowerState.On",
+            "xyz.openbmc_project.State.Host.HostState.Running",
+            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart",
+            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.BootComplete"
+        ),
+    },
+    'ResetReload':  # Valid state BMC reset reload when host is booted.
+    {
+        # (BMC , Chassis , Host , BootProgress, OperatingSystemState)
+        (
+            "xyz.openbmc_project.State.BMC.BMCState.Ready",
+            "xyz.openbmc_project.State.Chassis.PowerState.On",
+            "xyz.openbmc_project.State.Host.HostState.Running",
+            "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart",
+            "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.BootComplete"
+        ),
     },
 }
 
 
+###############################################################################
 class state_map():
 
-    def get_system_state(self):
+    def get_boot_state(self):
         r"""
-        Return the system state as a tuple of power policy, bmc, chassis and
-        host states.
+        Return the system state as a tuple of bmc, chassis, host state,
+        BootProgress and OperatingSystemState.
         """
-        power_policy = BuiltIn().run_keyword('Get System Power Policy')
-        bmc_state = BuiltIn().run_keyword('Get BMC State')
-        chassis_state = BuiltIn().run_keyword('Get Chassis Power State')
-        host_state = BuiltIn().run_keyword('Get Host State')
-        return (str(power_policy),
-                str(bmc_state),
+
+        status, state = keyword.run_key("Read Properties  " +
+                                        var.SYSTEM_STATE_URI + "enumerate")
+        bmc_state = state[var.SYSTEM_STATE_URI + 'bmc0']['CurrentBMCState']
+        chassis_state = \
+            state[var.SYSTEM_STATE_URI + 'chassis0']['CurrentPowerState']
+        host_state = state[var.SYSTEM_STATE_URI + 'host0']['CurrentHostState']
+        boot_state = state[var.SYSTEM_STATE_URI + 'host0']['BootProgress']
+        os_state = \
+            state[var.SYSTEM_STATE_URI + 'host0']['OperatingSystemState']
+
+        return (str(bmc_state),
                 str(chassis_state),
-                str(host_state))
+                str(host_state),
+                str(boot_state),
+                str(os_state))
 
     def valid_boot_state(self, boot_type, state_set):
         r"""
         Validate a given set of states is valid.
 
-        Description of arguments:
-        boot_type   Reset type (reboot/warm/cold)
-        state_set   State set (bmc,chassis,host)
+        Description of argument(s):
+        boot_type   Boot type (e.g. off/running/host booted etc.)
+        state_set   State set
+                    (e.g.bmc,chassis,host,BootProgress,OperatingSystemState)
         """
-        if state_set in set(VALID_STATES[boot_type]):
+
+        if state_set in set(VALID_BOOT_STATES[boot_type]):
             return True
         else:
             return False
+###############################################################################
diff --git a/tests/test_soft_boot_sensors.robot b/tests/test_soft_boot_sensors.robot
new file mode 100644
index 0000000..afe8069
--- /dev/null
+++ b/tests/test_soft_boot_sensors.robot
@@ -0,0 +1,263 @@
+*** Settings ***
+Documentation   Suite for testing non sensors.
+
+Library      ../lib/state_map.py
+Resource     ../lib/utils.robot
+Resource     ../lib/boot_utils.robot
+Resource     ../lib/state_manager.robot
+Resource     ../lib/openbmc_ffdc.robot
+
+Test Teardown     Post Test Case Execution
+
+*** Variables ***
+
+${stack_mode}   skip
+
+*** Test Cases ***
+
+Verify Boot AttemptsLeft
+    [Documentation]  Verify system boot attempts on various boot states.
+    [Tags]  Verify_Boot_AttemptsLeft
+    [Template]  Validate Boot AttemptsLeft
+
+    # Example: Expected state
+    # "data": {
+    #    "/xyz/openbmc_project/state/host0": {
+    #      "AttemptsLeft": 3,
+    #      "BootProgress": "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified",
+    #      "CurrentHostState": "xyz.openbmc_project.State.Host.HostState.Off",
+    #      "OperatingSystemState": "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive",
+    #      "RequestedHostTransition": "xyz.openbmc_project.State.Host.Transition.Off"
+    #    }
+    # }
+
+    # System at standby    AttemptsLeft
+    Reboot                 3
+    Booted                 2
+    RebootHost             1
+    Ready                  1
+
+
+Verify Boot Sensor States At Ready
+    [Documentation]  Verify system boot states at "Ready" state.
+    [Tags]  Verify_Boot_Sensor_States_At_Ready
+    [Template]  Valid Boot States
+
+    # Example: Expected state
+    # "data": {
+    #    "/xyz/openbmc_project/state/bmc0": {
+    #      "CurrentBMCState": "xyz.openbmc_project.State.BMC.BMCState.Ready",
+    #      "RequestedBMCTransition": "xyz.openbmc_project.State.BMC.Transition.None"
+    #    },
+    #    "/xyz/openbmc_project/state/chassis0": {
+    #      "CurrentPowerState": "xyz.openbmc_project.State.Chassis.PowerState.Off",
+    #      "RequestedPowerTransition": "xyz.openbmc_project.State.Chassis.Transition.Off"
+    #    },
+    #    "/xyz/openbmc_project/state/host0": {
+    #      "AttemptsLeft": 3,
+    #      "BootProgress": "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified",
+    #      "CurrentHostState": "xyz.openbmc_project.State.Host.HostState.Off",
+    #      "OperatingSystemState": "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive",
+    #      "RequestedHostTransition": "xyz.openbmc_project.State.Host.Transition.Off"
+    #    }
+    # }
+
+    # System at standby.
+    Off
+
+
+Verify Boot Sensor States On Reboot Ready
+    [Documentation]  Verify system boot states at "Ready" state.
+    [Tags]  Verify_Boot_Sensor_States_On_Reboot_Ready
+    [Template]  Valid Boot States
+
+    # Example: Expected state
+    # "data": {
+    #    "/xyz/openbmc_project/state/bmc0": {
+    #      "CurrentBMCState": "xyz.openbmc_project.State.BMC.BMCState.Ready",
+    #      "RequestedBMCTransition": "xyz.openbmc_project.State.BMC.Transition.None"
+    #    },
+    #    "/xyz/openbmc_project/state/chassis0": {
+    #      "CurrentPowerState": "xyz.openbmc_project.State.Chassis.PowerState.Off",
+    #      "RequestedPowerTransition": "xyz.openbmc_project.State.Chassis.Transition.Off"
+    #    },
+    #    "/xyz/openbmc_project/state/host0": {
+    #      "AttemptsLeft": 3,
+    #      "BootProgress": "xyz.openbmc_project.State.Boot.Progress.ProgressStages.Unspecified",
+    #      "CurrentHostState": "xyz.openbmc_project.State.Host.HostState.Off",
+    #      "OperatingSystemState": "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive",
+    #      "RequestedHostTransition": "xyz.openbmc_project.State.Host.Transition.Off"
+    #    }
+    # }
+
+    # BMC on reset to standby.
+    Reboot
+
+
+Verify Boot Sensor States At Running
+    [Documentation]  Verify system boot states at "Running" state.
+    [Tags]  Verify_Boot_Sensor_States_At_Running
+    [Template]  Valid Boot States
+
+    # Example: Expected state
+    # "data": {
+    #    "/xyz/openbmc_project/state/bmc0": {
+    #      "CurrentBMCState": "xyz.openbmc_project.State.BMC.BMCState.Ready",
+    #      "RequestedBMCTransition": "xyz.openbmc_project.State.BMC.Transition.None"
+    #   },
+    #   "/xyz/openbmc_project/state/chassis0": {
+    #      "CurrentPowerState": "xyz.openbmc_project.State.Chassis.PowerState.On",
+    #      "RequestedPowerTransition": "xyz.openbmc_project.State.Chassis.Transition.Off"
+    #   },
+    #   "/xyz/openbmc_project/state/host0": {
+    #      "AttemptsLeft": 2,
+    #      "BootProgress": "xyz.openbmc_project.State.Boot.Progress.ProgressStages.MotherboardInit",
+    #      "CurrentHostState": "xyz.openbmc_project.State.Host.HostState.Running",
+    #      "OperatingSystemState": "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Inactive",
+    #      "RequestedHostTransition": "xyz.openbmc_project.State.Host.Transition.On"
+    #   }
+    # }
+
+    # System at Running state but during initial state.
+    Running
+
+
+Verify Boot Sensor States At Host Booted
+    [Documentation]  Verify system boot states when host is booted.
+    [Tags]  Verify_Boot_Sensor_States_At_Host_Booted
+    [Template]  Valid Boot States
+
+    # Example: Expected state
+    # "data": {
+    #    "/xyz/openbmc_project/state/bmc0": {
+    #      "CurrentBMCState": "xyz.openbmc_project.State.BMC.BMCState.Ready",
+    #      "RequestedBMCTransition": "xyz.openbmc_project.State.BMC.Transition.None"
+    #   },
+    #   "/xyz/openbmc_project/state/chassis0": {
+    #      "CurrentPowerState": "xyz.openbmc_project.State.Chassis.PowerState.On",
+    #      "RequestedPowerTransition": "xyz.openbmc_project.State.Chassis.Transition.Off"
+    #   },
+    #   "/xyz/openbmc_project/state/host0": {
+    #      "AttemptsLeft": 3,
+    #      "BootProgress": "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart",
+    #      "CurrentHostState": "xyz.openbmc_project.State.Host.HostState.Running",
+    #      "OperatingSystemState": "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.BootComplete",
+    #      "RequestedHostTransition": "xyz.openbmc_project.State.Host.Transition.On"
+    #   }
+    # }
+
+    # System when host is booted.
+    Booted
+
+
+Verify Boot Sensor States RR on Host Booted
+    [Documentation]  Verify system boot states post BMC reset.
+    [Tags]  Verify_Boot_Sensor_States_RR_on_Host_Booted
+    [Template]  Valid Boot States
+
+    # Example: Expected state
+    # "data": {
+    #    "/xyz/openbmc_project/state/bmc0": {
+    #      "CurrentBMCState": "xyz.openbmc_project.State.BMC.BMCState.Ready",
+    #      "RequestedBMCTransition": "xyz.openbmc_project.State.BMC.Transition.None"
+    #   },
+    #   "/xyz/openbmc_project/state/chassis0": {
+    #      "CurrentPowerState": "xyz.openbmc_project.State.Chassis.PowerState.On",
+    #      "RequestedPowerTransition": "xyz.openbmc_project.State.Chassis.Transition.Off"
+    #   },
+    #   "/xyz/openbmc_project/state/host0": {
+    #      "AttemptsLeft": 3,
+    #      "BootProgress": "xyz.openbmc_project.State.Boot.Progress.ProgressStages.OSStart",
+    #      "CurrentHostState": "xyz.openbmc_project.State.Host.HostState.Running",
+    #      "OperatingSystemState": "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.BootComplete",
+    #      "RequestedHostTransition": "xyz.openbmc_project.State.Host.Transition.On"
+    #   }
+    # }
+
+    # System when host is booted.
+    ResetReload
+
+
+*** Keywords ***
+
+Validate Boot AttemptsLeft
+    [Documentation]  Verify boot attempts for a given system state.
+    [Arguments]  ${sys_state}  ${expected_attempts_left}
+
+    # Description of argument(s):
+    # sys_state    A user-defined boot state (e.g. "Off", "On", etc).
+    #              See VALID_BOOT_STATES in state_map.py.
+    # expected_attempts_left     Boot attempts left.
+
+    Choose Boot And Run  ${sys_state}
+    ${atempts_left}=  Read Attribute  ${HOST_STATE_URI}  AttemptsLeft
+    Should Be True  ${atempts_left} == ${expected_attempts_left}
+
+
+Valid Boot States
+    [Documentation]  Verify boot states for a given system state.
+    [Arguments]  ${sys_state}
+
+    # Description of argument(s):
+    # sys_state    A user-defined boot state (e.g. "Off", "On", etc).
+    #              See VALID_BOOT_STATES in state_map.py.
+
+    Choose Boot And Run  ${sys_state}
+    ${boot_states}=  Get Boot State
+    ${valid_state}=  Valid Boot State  ${sys_state}  ${boot_states}
+    Should Be True  ${valid_state}
+
+
+Choose Boot And Run
+    [Documentation]  Choose system boot type.
+    [Arguments]  ${option}
+
+    # Description of argument(s):
+    # option    Boot type (e.g. "Off", "On", "Reboot", etc.).
+
+    Run Keyword If  '${option}' == 'Off'
+    ...    Initiate Host PowerOff
+    ...  ELSE IF  '${option}' == 'Reboot'
+    ...    Run Keywords  Initiate Host PowerOff  AND  Initiate BMC Reboot
+    ...                  AND  Wait For BMC Ready
+    ...  ELSE IF  '${option}' == 'Running'
+    ...    Power On Till Chassis Is On
+    ...  ELSE IF  '${option}' == 'Booted'
+    ...    Initiate Host Boot
+    ...  ELSE IF  '${option}' == 'RebootHost'
+    ...    Initiate Host Reboot
+    ...  ELSE IF  '${option}' == 'ResetReload'
+    ...    Reboot Host And Expect Runtime
+
+
+Power On Till Chassis Is On
+    [Documentation]  Initiate power on and check till chassis state is just
+    ...              turned "On".
+
+    # TODO: Move to smart power off once ready.
+    Initiate Host PowerOff
+    Initiate Host Boot  wait=${0}
+    Wait Until Keyword Succeeds  2 min  10 sec  Is Chassis On
+
+    # TODO: Find better mechanism instead of wait.
+    Sleep  20 Sec
+
+
+Reboot Host And Expect Runtime
+    [Documentation]  Initiate reset reload when host is booted.
+
+    Initiate BMC Reboot
+    Wait Until Keyword Succeeds  10 min  10 sec  Is OS Booted
+
+
+Post Test Case Execution
+   [Documentation]  Do the post test teardown.
+   # - Capture FFDC on test failure.
+   # - Delete error logs.
+   # - Close all open SSH connections.
+   # - Clear all REST sessions.
+
+   FFDC On Test Case Fail
+   Delete Error Logs
+   Close All Connections
+