forked from goodboy/tractor
Ensure ctx error-state matches the MTE scenario
Namely checking that `Context._remote_error` is set to the raised MTE in the invalid started and return value cases since prior to the recent underlying changes to the `Context.result()` impl, it would not match. Further, - do asserts for non-MTE raising cases in both the parent and child. - add todos for testing ctx-outcomes for per-side-validation policies i anticipate supporting and implied msg-dialog race cases therein.runtime_to_msgspec
parent
6a4ee461f5
commit
4fa71cc01c
|
@ -148,12 +148,44 @@ async def child(
|
||||||
# propagate to parent?
|
# propagate to parent?
|
||||||
if raise_on_started_mte:
|
if raise_on_started_mte:
|
||||||
raise
|
raise
|
||||||
else:
|
|
||||||
if expect_started_mte:
|
# no-send-side-error fallthrough
|
||||||
raise RuntimeError(
|
if (
|
||||||
'Child-ctx-task SHOULD HAVE raised an MTE for\n\n'
|
validate_pld_spec
|
||||||
f'{started_value!r}\n'
|
and
|
||||||
)
|
expect_started_mte
|
||||||
|
):
|
||||||
|
raise RuntimeError(
|
||||||
|
'Child-ctx-task SHOULD HAVE raised an MTE for\n\n'
|
||||||
|
f'{started_value!r}\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
not expect_started_mte
|
||||||
|
or
|
||||||
|
not validate_pld_spec
|
||||||
|
)
|
||||||
|
|
||||||
|
# if wait_for_parent_to_cancel:
|
||||||
|
# ...
|
||||||
|
#
|
||||||
|
# ^-TODO-^ logic for diff validation policies on each side:
|
||||||
|
#
|
||||||
|
# -[ ] ensure that if we don't validate on the send
|
||||||
|
# side, that we are eventually error-cancelled by our
|
||||||
|
# parent due to the bad `Started` payload!
|
||||||
|
# -[ ] the boxed error should be srced from the parent's
|
||||||
|
# runtime NOT ours!
|
||||||
|
# -[ ] we should still error on bad `return_value`s
|
||||||
|
# despite the parent not yet error-cancelling us?
|
||||||
|
# |_ how do we want the parent side to look in that
|
||||||
|
# case?
|
||||||
|
# -[ ] maybe the equiv of "during handling of the
|
||||||
|
# above error another occurred" for the case where
|
||||||
|
# the parent sends a MTE to this child and while
|
||||||
|
# waiting for the child to terminate it gets back
|
||||||
|
# the MTE for this case?
|
||||||
|
#
|
||||||
|
|
||||||
# XXX should always fail on recv side since we can't
|
# XXX should always fail on recv side since we can't
|
||||||
# really do much else beside terminate and relay the
|
# really do much else beside terminate and relay the
|
||||||
|
@ -247,13 +279,17 @@ def test_basic_payload_spec(
|
||||||
msg_type_str: str = ''
|
msg_type_str: str = ''
|
||||||
bad_value_str: str = ''
|
bad_value_str: str = ''
|
||||||
|
|
||||||
|
maybe_mte: MsgTypeError|None = None
|
||||||
|
should_raise: Exception|None = (
|
||||||
|
MsgTypeError if (
|
||||||
|
invalid_return
|
||||||
|
or
|
||||||
|
invalid_started
|
||||||
|
) else None
|
||||||
|
)
|
||||||
async with (
|
async with (
|
||||||
maybe_expect_raises(
|
maybe_expect_raises(
|
||||||
raises=MsgTypeError if (
|
raises=should_raise,
|
||||||
invalid_return
|
|
||||||
or
|
|
||||||
invalid_started
|
|
||||||
) else None,
|
|
||||||
ensure_in_message=[
|
ensure_in_message=[
|
||||||
f"invalid `{msg_type_str}` payload",
|
f"invalid `{msg_type_str}` payload",
|
||||||
f"value: `{bad_value_str}` does not match type-spec: `{msg_type_str}.pld: PldMsg|NoneType`",
|
f"value: `{bad_value_str}` does not match type-spec: `{msg_type_str}.pld: PldMsg|NoneType`",
|
||||||
|
@ -274,18 +310,35 @@ def test_basic_payload_spec(
|
||||||
assert first.field == 'yo'
|
assert first.field == 'yo'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
assert (await ctx.result()) is None
|
res: None|PldMsg = await ctx.result(hide_tb=False)
|
||||||
|
assert res is None
|
||||||
except MsgTypeError as mte:
|
except MsgTypeError as mte:
|
||||||
|
maybe_mte = mte
|
||||||
if not invalid_return:
|
if not invalid_return:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
else: # expected this invalid `Return.pld`
|
# expected this invalid `Return.pld` so audit
|
||||||
assert mte.cid == ctx.cid
|
# the error state + meta-data
|
||||||
|
assert mte.expected_msg_type is Return
|
||||||
|
assert mte.cid == ctx.cid
|
||||||
|
|
||||||
# verify expected remote mte deats
|
# verify expected remote mte deats
|
||||||
await tractor.pause()
|
try:
|
||||||
assert ctx._remote_error is mte
|
assert ctx._local_error is None
|
||||||
assert mte.expected_msg_type is Return
|
assert (
|
||||||
|
mte is
|
||||||
|
ctx._remote_error is
|
||||||
|
ctx.maybe_error is
|
||||||
|
ctx.outcome
|
||||||
|
)
|
||||||
|
except:
|
||||||
|
# XXX should never get here..
|
||||||
|
await tractor.pause(shield=True)
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
if should_raise is None:
|
||||||
|
assert maybe_mte is None
|
||||||
|
|
||||||
await p.cancel_actor()
|
await p.cancel_actor()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue