diff --git a/lib/cylc/task_pool.py b/lib/cylc/task_pool.py index b4d170779c5..d6676be5b99 100644 --- a/lib/cylc/task_pool.py +++ b/lib/cylc/task_pool.py @@ -797,15 +797,21 @@ def warn_stop_orphans(self): def pool_is_stalled(self): """Return True if no active, queued or clock trigger awaiting tasks""" + can_be_stalled = False for itask in self.get_tasks(): if itask.point > self.stop_point: # Don't consider task beyond stop point continue + if itask.state.status in [ + TASK_STATUS_SUCCEEDED, TASK_STATUS_EXPIRED]: + # Succeeded and expired tasks don't stall the suite + continue if itask.state.status in TASK_STATUSES_NOT_STALLED or ( not itask.start_time_reached() and itask.state.status not in TASK_STATUSES_FINAL): return False - return True + can_be_stalled = True + return can_be_stalled def report_stalled_task_deps(self): """Return a set of unmet dependencies""" diff --git a/tests/events/31-dont-stall-succeeded.t b/tests/events/31-dont-stall-succeeded.t new file mode 100755 index 00000000000..e93a76bc89f --- /dev/null +++ b/tests/events/31-dont-stall-succeeded.t @@ -0,0 +1,38 @@ +#!/bin/bash +# THIS FILE IS PART OF THE CYLC SUITE ENGINE. +# Copyright (C) 2008-2017 NIWA +# +# 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 . +#------------------------------------------------------------------------------- +# Test no stall when task pool has succeeded tasks only. +. "$(dirname "$0")/test_header" +set_test_number 4 + +install_suite "${TEST_NAME_BASE}" "${TEST_NAME_BASE}" +run_ok "${TEST_NAME_BASE}-validate" cylc validate "${SUITE_NAME}" +run_ok "${TEST_NAME_BASE}-run" cylc run "${SUITE_NAME}" +TIMEOUT=$(($(date +%s) + 60)) +while (($(date +%s) < TIMEOUT)) && \ + ! grep -q '\[t1\.1\] .* succeeded' "${SUITE_RUN_DIR}/log/suite/log" +do + sleep 1 +done +grep_ok '\[t1\.1\] .* succeeded' "${SUITE_RUN_DIR}/log/suite/log" + +sleep 5 +cylc stop --max-polls=10 --interval=2 "${SUITE_NAME}" 1>'/dev/null' 2>&1 +run_fail "${TEST_NAME_BASE}-stall" \ + grep -q -F 'WARNING - suite stalled' "${SUITE_RUN_DIR}/log/suite/log" +purge_suite "${SUITE_NAME}" +exit diff --git a/tests/events/31-dont-stall-succeeded/suite.rc b/tests/events/31-dont-stall-succeeded/suite.rc new file mode 100644 index 00000000000..976b46372b9 --- /dev/null +++ b/tests/events/31-dont-stall-succeeded/suite.rc @@ -0,0 +1,13 @@ +#!jinja2 +[cylc] + disable automatic shutdown = True + [[events]] + abort on stalled = True + abort on inactivity = True + inactivity = PT1M +[scheduling] + [[dependencies]] + graph=t1 +[runtime] + [[t1]] + script = true