diff --git a/cylc/flow/main_loop/auto_restart.py b/cylc/flow/main_loop/auto_restart.py index 1751e6b4a05..66aa0ebbb46 100644 --- a/cylc/flow/main_loop/auto_restart.py +++ b/cylc/flow/main_loop/auto_restart.py @@ -54,11 +54,12 @@ Suites that are started up in no-detach mode cannot auto stop-restart on a different host - as it will still end up attached to the condemned host. -Therefore, a suite in no-detach mode running on a condemned host will abort with -a non-zero return code. The parent process should manually handle the restart of -the suite if desired. +Therefore, a suite in no-detach mode running on a condemned host will abort +with a non-zero return code. The parent process should manually handle the +restart of the suite if desired. See the ``[suite servers]`` configuration section + (:ref:`global-suite-servers`) for more details. """ @@ -199,7 +200,7 @@ def _set_auto_restart( if restart_delay > 0: # Delay shutdown by a random interval to avoid many # suites restarting simultaneously. - shutdown_delay = int(random() * restart_delay) + shutdown_delay = int(random() * restart_delay) # nosec else: # Un-documented feature, schedule exact restart interval for # testing purposes. diff --git a/cylc/flow/main_loop/health_check.py b/cylc/flow/main_loop/health_check.py index 57f739cb69f..1bbf9472548 100644 --- a/cylc/flow/main_loop/health_check.py +++ b/cylc/flow/main_loop/health_check.py @@ -12,6 +12,7 @@ from cylc.flow import suite_files from cylc.flow.exceptions import CylcError, SuiteServiceFileError + async def during(scheduler, _): """Perform suite health checks.""" # 1. check if suite run dir still present - if not shutdown. @@ -32,8 +33,7 @@ def _check_contact_file(scheduler): scheduler.suite) if contact_data != scheduler.contact_data: raise AssertionError('contact file modified') - except (AssertionError, IOError, ValueError, - SuiteServiceFileError) as exc: + except (AssertionError, IOError, ValueError, SuiteServiceFileError): raise CylcError( '%s: contact file corrupted/modified and may be left' % suite_files.get_contact_file(scheduler.suite) diff --git a/cylc/flow/main_loop/log_memory.py b/cylc/flow/main_loop/log_memory.py index 44d479ce959..e499ce2307f 100644 --- a/cylc/flow/main_loop/log_memory.py +++ b/cylc/flow/main_loop/log_memory.py @@ -1,5 +1,4 @@ import json -import math from pathlib import Path from time import time @@ -72,7 +71,7 @@ def _transpose(data): all_keys = list(all_keys) all_keys.sort(key=lambda x: data[-1][1].get(x, 0), reverse=True) - # extract data for each field, if not present + # extract data for each field, if not present fields = {} for key in all_keys: fields[key] = [ diff --git a/cylc/flow/scheduler.py b/cylc/flow/scheduler.py index 84756f6bc2b..4720705a931 100644 --- a/cylc/flow/scheduler.py +++ b/cylc/flow/scheduler.py @@ -537,7 +537,7 @@ def configure(self): self.config.cfg['cylc']['events'][key] = DurationFloat(180) if self._get_events_conf(key): self.set_suite_inactivity_timer() - + # Main loop plugins self.main_loop_plugins = main_loop.load_plugins( self._get_cylc_conf('main loop', {}), @@ -1462,7 +1462,6 @@ def suite_auto_restart(self, max_retries=3): 'manual restart required.', max_retries) return False - def update_profiler_logs(self, tinit): """Update info for profiler.""" now = time() diff --git a/cylc/flow/tests/main_loop.py b/cylc/flow/tests/main_loop.py index 333b7e1a51e..9e05963f261 100644 --- a/cylc/flow/tests/main_loop.py +++ b/cylc/flow/tests/main_loop.py @@ -59,11 +59,13 @@ def test_load_plugins(): def test_wrapper_calls_function(): """Ensure the wrapper calls coroutines.""" flag = False + async def test_coro(arg1, arg2): assert arg1 == 'arg1' assert arg2 == 'arg2' nonlocal flag flag = True + coro = _wrapper( test_coro, ('arg1', 'arg2') @@ -132,9 +134,11 @@ async def test_coro(): def test_before(): """Ensure the before function calls all before coros.""" calls = [] + def capture(*stuff): nonlocal calls calls.append(stuff) + plugins = { 'before': { 'foo': capture, @@ -154,6 +158,7 @@ def capture(*stuff): (42, {'c': 3}), ] + @pytest.fixture def test_plugins(): return { @@ -191,14 +196,17 @@ def test_plugins(): def test_during(test_plugins): """Ensure the during function calls all during and on_change coros.""" calls = [] + def capture_during(_, state): nonlocal calls state['calls'].append(f'during_{state["name"]}') calls.append(list(state['calls'])) + def capture_on_change(_, state): nonlocal calls state['calls'].append(f'on_change_{state["name"]}') calls.append(list(state['calls'])) + test_plugins.update({ 'during': { 'foo': capture_during, @@ -221,10 +229,13 @@ def capture_on_change(_, state): def test_during_interval(test_plugins): + def capture_during(_, state): state['calls'].append(f'during_{state["name"]}') + def capture_on_change(_, state): state['calls'].append(f'on_change_{state["name"]}') + test_plugins.update({ 'during': { 'foo': capture_during, @@ -278,9 +289,11 @@ def capture_on_change(_, state): def test_after(): """Ensure the after function calls all after coros.""" calls = [] + def capture(*stuff): nonlocal calls calls.append(stuff) + plugins = { 'after': { 'foo': capture, diff --git a/cylc/flow/tests/main_loop/auto_restart.py b/cylc/flow/tests/main_loop/auto_restart.py index 8934d11e575..982d3d0e60a 100644 --- a/cylc/flow/tests/main_loop/auto_restart.py +++ b/cylc/flow/tests/main_loop/auto_restart.py @@ -179,10 +179,12 @@ def test_set_auto_restart_no_detach(caplog): def test_set_auto_restart_unable_to_restart(monkeypatch): """Ensure returns False if suite is unable to restart""" called = False + def suite_select_fail(**_): nonlocal called called = True # prevent this becoming a placebo return False + monkeypatch.setattr( 'cylc.flow.main_loop.auto_restart._can_auto_restart', suite_select_fail @@ -201,10 +203,12 @@ def suite_select_fail(**_): def test_set_auto_restart_with_delay(monkeypatch, caplog): """Ensure suites wait for a period before auto-restarting.""" called = False + def suite_select_pass(**_): nonlocal called called = True # prevent this becoming a placebo return True + monkeypatch.setattr( 'cylc.flow.main_loop.auto_restart._can_auto_restart', suite_select_pass @@ -233,10 +237,12 @@ def suite_select_pass(**_): def test_set_auto_restart_without_delay(monkeypatch, caplog): """Ensure suites auto-restart when no delay is provided.""" called = False + def suite_select_pass(**_): nonlocal called called = True # prevent this becoming a placebo return True + monkeypatch.setattr( 'cylc.flow.main_loop.auto_restart._can_auto_restart', suite_select_pass