Skip to content

Commit

Permalink
Merge pull request #6184 from cylc/8.3.x-sync
Browse files Browse the repository at this point in the history
🤖 Merge 8.3.x-sync into master
  • Loading branch information
oliver-sanders committed Jul 2, 2024
2 parents 3fc8a71 + 6d31111 commit 67a6ba5
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 22 deletions.
1 change: 1 addition & 0 deletions cylc/flow/network/resolvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,7 @@ async def _mutation_mapper(
except Exception as exc:
# NOTE: keep this exception vague to prevent a bad command taking
# down the scheduler
LOG.warning(f'{log1}\n{exc.__class__.__name__}: {exc}')
if cylc.flow.flags.verbosity > 1:
LOG.exception(exc) # log full traceback in debug mode
return (False, str(exc))
Expand Down
2 changes: 1 addition & 1 deletion cylc/flow/network/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ async def get_nodes_edges(root, info: 'ResolveInfo', **args):


def resolve_state_totals(root, info, **args):
state_totals = {state: 0 for state in TASK_STATUSES_ORDERED}
state_totals = dict.fromkeys(TASK_STATUSES_ORDERED, 0)
# Update with converted protobuf map container
state_totals.update(
dict(getattr(root, to_snake_case(info.field_name), {})))
Expand Down
6 changes: 3 additions & 3 deletions cylc/flow/scripts/stop.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@
CCYYMMDDThh:mm, CCYY-MM-DDThh, etc).
Tasks that become ready after the shutdown is ordered will be submitted
immediately if the workflow is restarted. Remaining task event handlers and
job poll and kill commands, however, will be executed prior to shutdown, unless
--now is used.
immediately if the workflow is restarted. Remaining task event handlers and
job poll and kill commands will be executed prior to shutdown, unless
--now is used twice.
This command exits immediately unless --max-polls is greater than zero, in
which case it polls to wait for workflow shutdown.
Expand Down
6 changes: 1 addition & 5 deletions cylc/flow/task_outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,7 @@ def get_optional_outputs(
)
for output in used_compvars
},
# the outputs that are not used in the expression
**{
output: None
for output in all_compvars - used_compvars
},
**dict.fromkeys(all_compvars - used_compvars),
}


Expand Down
7 changes: 2 additions & 5 deletions cylc/flow/tui/updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,8 @@ def get_default_filters():
These filters show everything.
"""
return {
'tasks': {
# filtered task statuses
state: True
for state in TASK_STATUSES_ORDERED
},
# filtered task statuses
'tasks': dict.fromkeys(TASK_STATUSES_ORDERED, True),
'workflows': {
# filtered workflow statuses
**{
Expand Down
2 changes: 1 addition & 1 deletion tests/functional/lib/bash/test_header
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ contains_ok() {
local FILE_CONTROL="${2:--}"
local TEST_NAME
TEST_NAME="$(basename "${FILE_TEST}")-contains-ok"
comm -13 <(sort "${FILE_TEST}") <(sort "${FILE_CONTROL}") \
LANG=C comm -13 <(sort "${FILE_TEST}") <(sort "${FILE_CONTROL}") \
1>"${TEST_NAME}.stdout" 2>"${TEST_NAME}.stderr"
if [[ -s "${TEST_NAME}.stdout" ]]; then
mkdir -p "${TEST_LOG_DIR}"
Expand Down
6 changes: 1 addition & 5 deletions tests/functional/shutdown/08-now1.t
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# Test "cylc stop --now" will wait for event handler.
. "$(dirname "$0")/test_header"

set_test_number 6
set_test_number 5

install_workflow "${TEST_NAME_BASE}" "${TEST_NAME_BASE}"
run_ok "${TEST_NAME_BASE}-validate" cylc validate "${WORKFLOW_NAME}"
Expand All @@ -27,10 +27,6 @@ LOGD="$RUN_DIR/${WORKFLOW_NAME}/log"
grep_ok 'INFO - Workflow shutting down - REQUEST(NOW)' "${LOGD}/scheduler/log"
JLOGD="${LOGD}/job/1/t1/01"
# Check that 1/t1 event handler runs
run_ok "${TEST_NAME_BASE}-activity-log-succeeded" \
grep -q -F \
"[(('event-handler-00', 'succeeded'), 1) out] Well done 1/t1 succeeded" \
"${JLOGD}/job-activity.log"
run_ok "${TEST_NAME_BASE}-activity-log-started" \
grep -q -F \
"[(('event-handler-00', 'started'), 1) out] Hello 1/t1 started" \
Expand Down
3 changes: 1 addition & 2 deletions tests/functional/shutdown/08-now1/flow.cylc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
abort on stall timeout = True
stall timeout = PT0S
abort on inactivity timeout = True
inactivity timeout = PT3M
inactivity timeout = PT1M

[scheduling]
[[graph]]
Expand All @@ -14,6 +14,5 @@
script = cylc__job__wait_cylc_message_started; cylc stop --now "${CYLC_WORKFLOW_ID}"
[[[events]]]
started handlers = sleep 10 && echo 'Hello %(id)s %(event)s'
succeeded handlers = echo 'Well done %(id)s %(event)s'
[[t2]]
script = true
56 changes: 56 additions & 0 deletions tests/integration/test_resolvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,59 @@ async def test_command_logging(mock_flow, caplog, log_filter):
await mock_flow.resolvers._mutation_mapper("put_messages", kwargs, meta)
assert log_filter(
caplog, contains='Command "put_messages" received from Dr Spock')


async def test_command_validation_failure(
mock_flow,
caplog,
flow_args,
monkeypatch,
):
"""It should log command validation failures server side."""
caplog.set_level(logging.DEBUG, None)
flow_args['workflows'].append(
{
'user': mock_flow.owner,
'workflow': mock_flow.name,
'workflow_sel': None,
}
)

# submit a command with invalid arguments:
async def submit_invalid_command(verbosity=0):
nonlocal caplog, mock_flow, flow_args
monkeypatch.setattr('cylc.flow.flags.verbosity', verbosity)
caplog.clear()
return await mock_flow.resolvers.mutator(
None,
'stop',
flow_args,
{'task': 'cycle/task/job', 'mode': 'not-a-mode'},
{},
)

# submitting the invalid command should result in this error
msg = 'This command does not take job ids:\n * cycle/task/job'

# test submitting the command at *default* verbosity
response = await submit_invalid_command()

# the error should be sent back to the client:
assert response[0]['response'][1] == msg
# it should also be logged by the server:
assert caplog.records[-1].levelno == logging.WARNING
assert msg in caplog.records[-1].message

# test submitting the command at *debug* verbosity
response = await submit_invalid_command(verbosity=2)

# the error should be sent back to the client:
assert response[0]['response'][1] == msg
# it should be logged at the server
assert caplog.records[-2].levelno == logging.WARNING
assert msg in caplog.records[-2].message
# the traceback should also be logged
# (note traceback gets logged at the ERROR level and shows up funny in
# caplog)
assert caplog.records[-1].levelno == logging.ERROR
assert msg in caplog.records[-1].message

0 comments on commit 67a6ba5

Please sign in to comment.