Skip to content

Commit d0cdbc2

Browse files
authored
Test.sim mode changes on restart (#5789)
* Tests to ensure simulation mode is conserved across restarts of the scheduler. * Test what happens to workflow run_mode upon restart. Raise an exception if the user tries to change mode. * default to live if run mode is none is db * test mode = None on restart
1 parent 0a8bbfa commit d0cdbc2

File tree

4 files changed

+85
-0
lines changed

4 files changed

+85
-0
lines changed

changes.d/5789.fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Stop users changing run modes on restart.

cylc/flow/rundb.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,19 @@ def select_workflow_params_restart_count(self):
606606
result = self.connect().execute(stmt).fetchone()
607607
return int(result[0]) if result else 0
608608

609+
def select_workflow_params_run_mode(self):
610+
"""Return original run_mode for workflow_params."""
611+
stmt = rf"""
612+
SELECT
613+
value
614+
FROM
615+
{self.TABLE_WORKFLOW_PARAMS}
616+
WHERE
617+
key == 'run_mode'
618+
""" # nosec (table name is code constant)
619+
result = self.connect().execute(stmt).fetchone()
620+
return result[0] if result else None
621+
609622
def select_workflow_template_vars(self, callback):
610623
"""Select from workflow_template_vars.
611624

cylc/flow/scheduler.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,18 @@ async def configure(self, params):
434434
# Mark this exc as expected (see docstring for .schd_expected):
435435
exc.schd_expected = True
436436
raise exc
437+
438+
# Prevent changing mode on restart.
439+
if self.is_restart:
440+
# check run mode against db
441+
og_run_mode = self.workflow_db_mgr.get_pri_dao(
442+
).select_workflow_params_run_mode() or 'live'
443+
run_mode = self.config.run_mode()
444+
if run_mode != og_run_mode:
445+
raise InputError(
446+
f'This workflow was originally run in {og_run_mode} mode:'
447+
f' Will not restart in {run_mode} mode.')
448+
437449
self.profiler.log_memory("scheduler.py: after load_flow_file")
438450

439451
self.workflow_db_mgr.on_workflow_start(self.is_restart)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# THIS FILE IS PART OF THE CYLC WORKFLOW ENGINE.
2+
# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
3+
#
4+
# This program is free software: you can redistribute it and/or modify
5+
# it under the terms of the GNU General Public License as published by
6+
# the Free Software Foundation, either version 3 of the License, or
7+
# (at your option) any later version.
8+
#
9+
# This program is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
"""What happens to the mode on restart?
17+
"""
18+
19+
import pytest
20+
21+
from cylc.flow.exceptions import InputError
22+
23+
24+
MODES = [('live'), ('simulation'), ('dummy')]
25+
26+
27+
@pytest.mark.parametrize('mode_before', MODES + [None])
28+
@pytest.mark.parametrize('mode_after', MODES)
29+
async def test_restart_mode(
30+
flow, run, scheduler, start, one_conf,
31+
mode_before, mode_after
32+
):
33+
"""Restarting a workflow in live mode leads to workflow in live mode.
34+
35+
N.B - we need use run becuase the check in question only happens
36+
on start.
37+
"""
38+
id_ = flow(one_conf)
39+
schd = scheduler(id_, run_mode=mode_before)
40+
async with start(schd):
41+
if not mode_before:
42+
mode_before = 'live'
43+
assert schd.config.run_mode() == mode_before
44+
45+
schd = scheduler(id_, run_mode=mode_after)
46+
47+
if (
48+
mode_before == mode_after
49+
or not mode_before and mode_after != 'live'
50+
):
51+
# Restarting in the same mode is fine.
52+
async with run(schd):
53+
assert schd.config.run_mode() == mode_before
54+
else:
55+
# Restarting in a new mode is not:
56+
errormsg = f'^This.*{mode_before} mode: Will.*{mode_after} mode.$'
57+
with pytest.raises(InputError, match=errormsg):
58+
async with run(schd):
59+
pass

0 commit comments

Comments
 (0)