Skip to content

Commit

Permalink
Test what happens to workflow run_mode upon restart.
Browse files Browse the repository at this point in the history
Raise an exception if the user tries to change mode.
  • Loading branch information
wxtim committed Oct 25, 2023
1 parent e5d9ba8 commit 06ef772
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 18 deletions.
13 changes: 13 additions & 0 deletions cylc/flow/rundb.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,19 @@ def select_workflow_params_restart_count(self):
result = self.connect().execute(stmt).fetchone()
return int(result[0]) if result else 0

def select_workflow_params_run_mode(self):
"""Return original run_mode for workflow_params."""
stmt = rf"""
SELECT
value
FROM
{self.TABLE_WORKFLOW_PARAMS}
WHERE
key == 'run_mode'
""" # nosec (table name is code constant)
result = self.connect().execute(stmt).fetchone()
return result[0] if result else None

def select_workflow_template_vars(self, callback):
"""Select from workflow_template_vars.
Expand Down
12 changes: 12 additions & 0 deletions cylc/flow/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,18 @@ async def configure(self, params):
# Mark this exc as expected (see docstring for .schd_expected):
exc.schd_expected = True
raise exc

# Prevent changing mode on restart.
if self.is_restart:
# check run mode against db
og_run_mode = self.workflow_db_mgr.get_pri_dao(
).select_workflow_params_run_mode()
run_mode = self.config.run_mode()
if run_mode != og_run_mode:
raise InputError(
f'This workflow was originally run in {og_run_mode} mode:'
f' Will not restart in {run_mode} mode.')

self.profiler.log_memory("scheduler.py: after load_flow_file")

self.workflow_db_mgr.on_workflow_start(self.is_restart)
Expand Down
43 changes: 25 additions & 18 deletions tests/integration/test_mode_on_restart.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,41 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""What happens to the mode on restart?
+--------------------+--------+-------+-------+
| ↓restart \ start → | live | sim | dummy |
+====================+========+=======+=======+
| live | live | sim * | ??? |
| sim | live * | sim | ??? |
| dummy | ??? | ??? | dummy |
+--------------------+--------+-------+-------+
* A warning ought to be emitted, since the user doesn't otherwise know
what's happening.
"""

import pytest

from cylc.flow.exceptions import InputError


MODES = (('live'), ('simulation'), ('dummy'))


@pytest.mark.parametrize('mode_before', (('live'), ('simulation')))
@pytest.mark.parametrize('mode_after', (('live'), ('simulation')))
@pytest.mark.parametrize('mode_before', MODES)
@pytest.mark.parametrize('mode_after', MODES)
async def test_restart_mode(
flow, scheduler, start, one_conf, mode_before, mode_after
flow, run, scheduler, start, one_conf,
mode_before, mode_after
):
"""Restarting a workflow in live mode leads to workflow in live mode
"""Restarting a workflow in live mode leads to workflow in live mode.
N.B - we need use run becuase the check in question only happens
on start.
"""
id_ = flow(one_conf)
schd = scheduler(id_, run_mode=mode_before)
async with start(schd):
assert schd.config.run_mode() == mode_before

schd.options.run_mode = mode_after
async with start(schd):
assert schd.config.run_mode() == mode_before
schd = scheduler(id_, run_mode=mode_after)

if mode_before == mode_after:
# Restarting in the same mode is fine.
async with run(schd):
assert schd.config.run_mode() == mode_before
else:
# Restarting in a new mode is not:
errormsg = f'^This.*{mode_before} mode: Will.*{mode_after} mode.$'
with pytest.raises(InputError, match=errormsg):
async with run(schd):
pass

0 comments on commit 06ef772

Please sign in to comment.