Skip to content

Commit

Permalink
Sleep after state change (#530)
Browse files Browse the repository at this point in the history
* Sleep after state change

* style

* Set sleep to 0 in tests

* ds

* c
  • Loading branch information
marcin-usielski authored Jun 5, 2024
1 parent 7982abe commit 80193ac
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 14 deletions.
4 changes: 3 additions & 1 deletion moler/device/abstract_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
- be the state machine that controls which commands may run in given state
"""
__author__ = "Marcin Usielski"
__copyright__ = "Copyright (C) 2019-2020, Nokia"
__copyright__ = "Copyright (C) 2019-2024, Nokia"
__email__ = "[email protected]"

import abc
Expand Down Expand Up @@ -87,6 +87,7 @@ def goto_state(
send_enter_after_changed_state=False,
log_stacktrace_on_fail=True,
keep_state=True,
sleep_after_change=0.5
):
"""
Goes to state.
Expand All @@ -98,6 +99,7 @@ def goto_state(
:param log_stacktrace_on_fail: Set True to log exceptions if command to enter state failed.
:param keep_state: if True and state is changed without goto_state then device tries to change state to state
defined by goto_state.
:param sleep_after_change: Time in seconds to sleep after state change.
:return: None
"""

Expand Down
6 changes: 6 additions & 0 deletions moler/device/textualdevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ def __init__(
self._check_all_prompts_on_line = False
self.last_wrong_wait4_occurrence = None # Last occurrence from Wait4prompts if at least 2 prompts matched the
# same line.
self._sleep_after_state_change = 0.5

def set_all_prompts_on_line(self, value=True):
"""
Expand Down Expand Up @@ -434,6 +435,7 @@ def goto_state(
log_stacktrace_on_fail=True,
keep_state=False,
timeout_multiply=1.0,
sleep_after_changed_state=0.5,
):
"""
Go to specific state.
Expand All @@ -446,9 +448,11 @@ def goto_state(
:param keep_state: if True and state is changed without goto_state then device tries to change state to state
defined by goto_state.
:param timeout_multiply: how many times multiply passed timeout to get final timeout.
:param sleep_after_change: Time in seconds to sleep after state change.
:return: None
:raise: DeviceChangeStateFailure if cannot change the state of device.
"""
self._sleep_after_state_change = sleep_after_changed_state
self._kept_state = None
if not self.has_established_connection():
self.establish_connection()
Expand Down Expand Up @@ -610,6 +614,8 @@ def _goto_state_to_run_in_try(
next_stage_timeout = final_timeout - (time.monotonic() - start_time)
if next_stage_timeout <= 0:
is_timeout = True
if self._sleep_after_state_change is not None and self._sleep_after_state_change > 0:
time.sleep(self._sleep_after_state_change)
if keep_state:
self._kept_state = dest_state
self._warning_was_sent = False
Expand Down
16 changes: 13 additions & 3 deletions moler/util/devices_SM.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def iterate_over_device_states(
max_no_of_threads=11,
rerun=0,
timeout_multiply=3.0,
sleep_after_changed_state=0.0
):
"""
Check all states in device under test.
Expand All @@ -41,6 +42,7 @@ def iterate_over_device_states(
:param max_no_of_threads: maximum number of threads that can be started.
:param rerun: rerun for goto_state
:param timeout_multiply: timeout_multiply for goto_state
:param sleep_after_changed_state: sleep after state change
:return: None
"""
source_states = _get_all_states_from_device(device=device)
Expand All @@ -51,7 +53,7 @@ def iterate_over_device_states(
device.set_all_prompts_on_line(True)

device._goto_state_in_production_mode = False # pylint: disable=protected-access
device.goto_state(state=source_states[0], rerun=rerun)
device.goto_state(state=source_states[0], rerun=rerun, sleep_after_changed_state=sleep_after_changed_state)

random.shuffle(source_states)
random.shuffle(target_states)
Expand Down Expand Up @@ -83,6 +85,7 @@ def iterate_over_device_states(
exceptions=exceptions,
rerun=rerun,
timeout_multiply=timeout_multiply,
sleep_after_changed_state=sleep_after_changed_state
)
test_threads.append((th, new_connection))
thread_nr += 1
Expand All @@ -93,6 +96,7 @@ def iterate_over_device_states(
max_time=max_time,
rerun=rerun,
timeout_multiply=timeout_multiply,
sleep_after_changed_state=sleep_after_changed_state
)
for th, dev_connection in test_threads:
th.join()
Expand All @@ -114,6 +118,7 @@ def _perform_device_tests_start_thread(
exceptions,
rerun,
timeout_multiply,
sleep_after_changed_state,
):
try:
th = threading.Thread(
Expand All @@ -128,6 +133,7 @@ def _perform_device_tests_start_thread(
exceptions,
rerun,
timeout_multiply,
sleep_after_changed_state,
),
)
th.daemon = True
Expand All @@ -148,29 +154,31 @@ def _start_device_tests(
exceptions,
rerun,
timeout_multiply,
sleep_after_changed_state
):
try:
device = get_cloned_device(
src_device=source_device,
new_name=new_device_name,
new_connection=connection,
)
device.goto_state(state=states_to_test.queue[0][0], rerun=rerun)
device.goto_state(state=states_to_test.queue[0][0], rerun=rerun, sleep_after_changed_state=sleep_after_changed_state)
_perform_device_tests(
device=device,
tested=tested,
states_to_test=states_to_test,
max_time=max_time,
rerun=rerun,
timeout_multiply=timeout_multiply,
sleep_after_changed_state=sleep_after_changed_state
)
except Exception as ex:
exceptions.append(ex)
MolerTest.info(f"exception: '{ex}' -> '{repr(ex)}'")


def _perform_device_tests(
device, tested, states_to_test, max_time, rerun, timeout_multiply
device, tested, states_to_test, max_time, rerun, timeout_multiply, sleep_after_changed_state
):
device.set_all_prompts_on_line(True)
start_time = time.monotonic()
Expand All @@ -186,13 +194,15 @@ def _perform_device_tests(
keep_state=False,
rerun=rerun,
timeout_multiply=timeout_multiply,
sleep_after_changed_state=sleep_after_changed_state,
)
tested.add((state_before_test, source_state))
device.goto_state(
target_state,
keep_state=False,
rerun=rerun,
timeout_multiply=timeout_multiply,
sleep_after_changed_state=sleep_after_changed_state,
)
tested.add((source_state, target_state))
if device.last_wrong_wait4_occurrence is not None:
Expand Down
20 changes: 10 additions & 10 deletions test/device/test_SM_unix_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def test_unix_remote_proxy_pc_device_goto_state_bg(device_connection, unix_remot
unix_remote_proxy_pc._goto_state_in_production_mode = True
dst_state = "UNIX_REMOTE_ROOT"
src_state = "UNIX_LOCAL"
unix_remote_proxy_pc.goto_state(state=src_state)
unix_remote_proxy_pc.goto_state(state=src_state, sleep_after_changed_state=0)
assert unix_remote_proxy_pc.current_state == src_state
start_time = time.monotonic()
unix_remote_proxy_pc.goto_state_bg(state=dst_state)
Expand All @@ -66,10 +66,10 @@ def test_unix_remote_proxy_pc_device_goto_state_bg(device_connection, unix_remot
execution_time_bg = time.monotonic() - start_time
assert unix_remote_proxy_pc.current_state == dst_state

unix_remote_proxy_pc.goto_state(state=src_state)
unix_remote_proxy_pc.goto_state(state=src_state, sleep_after_changed_state=0)
assert unix_remote_proxy_pc.current_state == src_state
start_time = time.monotonic()
unix_remote_proxy_pc.goto_state(state=dst_state)
unix_remote_proxy_pc.goto_state(state=dst_state, sleep_after_changed_state=0)
execution_time_fg = time.monotonic() - start_time
assert unix_remote_proxy_pc.current_state == dst_state
time_diff = abs(execution_time_bg - execution_time_fg)
Expand All @@ -83,11 +83,11 @@ def test_unix_remote_proxy_pc_device_goto_state_bg_and_goto(device_connection, u

dst_state = "UNIX_REMOTE_ROOT"
src_state = "UNIX_LOCAL"
unix_remote_proxy_pc.goto_state(state=src_state)
unix_remote_proxy_pc.goto_state(state=src_state, sleep_after_changed_state=0)
assert unix_remote_proxy_pc.current_state == src_state
unix_remote_proxy_pc.goto_state_bg(state=dst_state)
assert unix_remote_proxy_pc.current_state != dst_state
unix_remote_proxy_pc.goto_state(state=dst_state)
unix_remote_proxy_pc.goto_state(state=dst_state, sleep_after_changed_state=0)
assert unix_remote_proxy_pc.current_state == dst_state


Expand All @@ -97,7 +97,7 @@ def test_unix_remote_proxy_pc_device_goto_state_bg_await(device_connection, unix
unix_remote_proxy_pc._goto_state_in_production_mode = True
dst_state = "UNIX_REMOTE_ROOT"
src_state = "UNIX_LOCAL"
unix_remote_proxy_pc.goto_state(state=src_state)
unix_remote_proxy_pc.goto_state(state=src_state, sleep_after_changed_state=0)
assert unix_remote_proxy_pc.current_state == src_state
unix_remote_proxy_pc.goto_state_bg(state=dst_state)
assert unix_remote_proxy_pc.current_state != dst_state
Expand All @@ -111,7 +111,7 @@ def test_unix_remote_proxy_pc_device_goto_state_bg_await_excption(device_connect
unix_remote_proxy_pc._goto_state_in_production_mode = True
dst_state = "UNIX_REMOTE_ROOT"
src_state = "UNIX_LOCAL"
unix_remote_proxy_pc.goto_state(state=src_state)
unix_remote_proxy_pc.goto_state(state=src_state, sleep_after_changed_state=0)
assert unix_remote_proxy_pc.current_state == src_state
unix_remote_proxy_pc.goto_state_bg(state=dst_state)
assert unix_remote_proxy_pc.current_state != dst_state
Expand All @@ -126,19 +126,19 @@ def test_unix_remote_device_not_connected():
dir_path = os.path.dirname(os.path.realpath(__file__))
load_config(os.path.join(dir_path, os.pardir, os.pardir, 'test', 'resources', 'device_config.yml'))
unix_remote = DeviceFactory.get_device(name="UNIX_REMOTE_REAL_IO", initial_state="UNIX_LOCAL")
unix_remote.goto_state("UNIX_LOCAL")
unix_remote.goto_state("UNIX_LOCAL", sleep_after_changed_state=0)
cmd_whoami = unix_remote.get_cmd(cmd_name="whoami")
ret1 = cmd_whoami()
execution = 0
while execution < 5:
unix_remote.goto_state("NOT_CONNECTED")
unix_remote.goto_state("NOT_CONNECTED", sleep_after_changed_state=0)
with pytest.raises(DeviceFailure) as ex:
cmd_whoami = unix_remote.get_cmd(cmd_name="whoami")
cmd_whoami()
assert "cmd is unknown for state 'NOT_CONNECTED'" in str(ex)
assert unix_remote.io_connection._terminal is None
assert unix_remote.io_connection.moler_connection.is_open() is False
unix_remote.goto_state("UNIX_LOCAL")
unix_remote.goto_state("UNIX_LOCAL", sleep_after_changed_state=0)
assert unix_remote.io_connection._terminal is not None
assert unix_remote.io_connection.moler_connection.is_open() is True
cmd_whoami = unix_remote.get_cmd(cmd_name="whoami")
Expand Down

0 comments on commit 80193ac

Please sign in to comment.