diff --git a/cylc/flow/scripts/validate_reinstall.py b/cylc/flow/scripts/validate_reinstall.py index 0d95bbcd6c1..2ea753820d0 100644 --- a/cylc/flow/scripts/validate_reinstall.py +++ b/cylc/flow/scripts/validate_reinstall.py @@ -92,6 +92,29 @@ def get_option_parser() -> COP: return parser +def check_tvars_and_workflow_stopped( + is_running: bool, tvars: list, tvars_file: list +) -> bool: + """are template variables set and workflow stopped? + + Template vars set by --set (options.templatevars) or --set-file + (optiions.templatevars_file) are only valid if the workflow is stopped + and vr will play it. + + args: + is_running: Is workflow running? + tvars: options.tvars, from `--set` + tvars_file: options.tvars_file, from `--set-file` + """ + if is_running and (tvars or tvars_file): + LOG.warning( + 'Template variables (from --set/--set-file) can ' + 'only be changed if the workflow is stopped.' + ) + return False + return True + + @cli_function(get_option_parser) def main(parser: COP, options: 'Values', workflow_id: str): sys.exit(vro_cli(parser, options, workflow_id)) @@ -118,6 +141,13 @@ def vro_cli(parser: COP, options: 'Values', workflow_id: str): # Workflow is definately stopped: workflow_running = False + # options.tvars and tvars_file are _only_ valid when playing a stopped + # workflow: Fail if they are set and workflow running: + if not check_tvars_and_workflow_stopped( + workflow_running, options.templatevars, options.templatevars_file + ): + return 1 + # Force on the against_source option: options.against_source = True # Make validate check against source. log_subcommand('validate --against-source', workflow_id) diff --git a/tests/unit/scripts/test_validate_reinstall_units.py b/tests/unit/scripts/test_validate_reinstall_units.py new file mode 100644 index 00000000000..e9d6b16bddf --- /dev/null +++ b/tests/unit/scripts/test_validate_reinstall_units.py @@ -0,0 +1,48 @@ +# THIS FILE IS PART OF THE CYLC WORKFLOW ENGINE. +# Copyright (C) NIWA & British Crown (Met Office) & Contributors. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +"""Tests for cylc.flow.scripts.validate_reinstall.py +""" + +import pytest + +from cylc.flow.scripts.validate_reinstall import ( + check_tvars_and_workflow_stopped) + + +@pytest.mark.parametrize( + 'is_running, tvars, tvars_file, expect', + [ + (True, [], None, True), + (True, ['FOO="Bar"'], None, False), + (True, [], ['bar.txt'], False), + (True, ['FOO="Bar"'], ['bar.txt'], False), + (False, [], None, True), + (False, ['FOO="Bar"'], ['bar.txt'], True), + (False, [], ['bar.txt'], True), + (False, ['FOO="Bar"'], ['bar.txt'], True), + ] +) +def test_check_tvars_and_workflow_stopped( + caplog, is_running, tvars, tvars_file, expect +): + """It returns true if workflow is running and tvars or tvars_file is set. + """ + result = check_tvars_and_workflow_stopped(is_running, tvars, tvars_file) + assert result == expect + if expect is False: + warn = 'can only be changed if' + assert warn in caplog.records[0].msg