Caps-msging test tweaks to get correct failures

These are likely temporary changes but still needed to actually see the
desired/correct failures (of which 5 of 6 tests are supposed to fail rn)
mostly to do with `Start` and `Return` msgs which are invalid under each
test's applied msg-spec.

Tweak set here:
- bit more `print()`s in root and sub for grokin test flow.
- never use `pytes.fail()` in subactor.. should know this by now XD
- comment out some bits that can't ever pass rn and make the underlying
  expected failues harder to grok:
  - the sub's child-side-of-ctx task doing sends should only fail
    for certain msg types like `Started` + `Return`, `Yield`s are
    processed receiver/parent side.
  - don't expect `sent` list to match predicate set for the same reason
    as last bullet.

The outstanding msg-type-semantic validation questions are:
- how to handle `.open_context()` with an input `kwargs` set that
  doesn't adhere to the currently applied msg-spec?
  - should the initial `@acm` entry fail before sending to the child
    side?
- where should received `MsgTypeError`s be raised, at the `MsgStream`
  `.receive()` or lower in the stack?
  - i'm thinking we should mk `MsgTypeError` derive from
    `RemoteActorError` and then have it be delivered as an error to the
    `Context`/`MsgStream` for per-ctx-task handling; would lead to more
    flexible/modular policy overrides in user code outside any defaults
    we provide.
runtime_to_msgspec
Tyler Goodlet 2024-04-08 10:13:14 -04:00
parent 8e83455a78
commit 2f451ab9a3
1 changed files with 56 additions and 29 deletions

View File

@ -374,7 +374,7 @@ def enc_type_union(
@tractor.context @tractor.context
async def send_back_nsp( async def send_back_values(
ctx: Context, ctx: Context,
expect_debug: bool, expect_debug: bool,
pld_spec_type_strs: list[str], pld_spec_type_strs: list[str],
@ -388,6 +388,8 @@ async def send_back_nsp(
and ensure we can round trip a func ref with our parent. and ensure we can round trip a func ref with our parent.
''' '''
uid: tuple = tractor.current_actor().uid
# debug mode sanity check (prolly superfluous but, meh) # debug mode sanity check (prolly superfluous but, meh)
assert expect_debug == _state.debug_mode() assert expect_debug == _state.debug_mode()
@ -414,7 +416,7 @@ async def send_back_nsp(
) )
print( print(
'CHILD attempting `Started`-bytes DECODE..\n' f'{uid}: attempting `Started`-bytes DECODE..\n'
) )
try: try:
msg: Started = nsp_codec.decode(started_msg_bytes) msg: Started = nsp_codec.decode(started_msg_bytes)
@ -436,7 +438,7 @@ async def send_back_nsp(
raise raise
else: else:
print( print(
'CHILD (correctly) unable to DECODE `Started`-bytes\n' f'{uid}: (correctly) unable to DECODE `Started`-bytes\n'
f'{started_msg_bytes}\n' f'{started_msg_bytes}\n'
) )
@ -445,7 +447,7 @@ async def send_back_nsp(
for send_value, expect_send in iter_send_val_items: for send_value, expect_send in iter_send_val_items:
try: try:
print( print(
f'CHILD attempting to `.started({send_value})`\n' f'{uid}: attempting to `.started({send_value})`\n'
f'=> expect_send: {expect_send}\n' f'=> expect_send: {expect_send}\n'
f'SINCE, ipc_pld_spec: {ipc_pld_spec}\n' f'SINCE, ipc_pld_spec: {ipc_pld_spec}\n'
f'AND, codec: {codec}\n' f'AND, codec: {codec}\n'
@ -460,7 +462,6 @@ async def send_back_nsp(
# await tractor.pause() # await tractor.pause()
raise RuntimeError( raise RuntimeError(
# pytest.fail(
f'NOT-EXPECTED able to roundtrip value given spec:\n' f'NOT-EXPECTED able to roundtrip value given spec:\n'
f'ipc_pld_spec -> {ipc_pld_spec}\n' f'ipc_pld_spec -> {ipc_pld_spec}\n'
f'value -> {send_value}: {type(send_value)}\n' f'value -> {send_value}: {type(send_value)}\n'
@ -468,54 +469,77 @@ async def send_back_nsp(
break # move on to streaming block.. break # move on to streaming block..
except NotImplementedError:
print('FAILED ENCODE!')
except tractor.MsgTypeError: except tractor.MsgTypeError:
# await tractor.pause() # await tractor.pause()
if expect_send: if expect_send:
pytest.fail( raise RuntimeError(
f'EXPECTED to `.started()` value given spec:\n' f'EXPECTED to `.started()` value given spec:\n'
f'ipc_pld_spec -> {ipc_pld_spec}\n' f'ipc_pld_spec -> {ipc_pld_spec}\n'
f'value -> {send_value}: {type(send_value)}\n' f'value -> {send_value}: {type(send_value)}\n'
) )
async with ctx.open_stream() as ipc: async with ctx.open_stream() as ipc:
print(
f'{uid}: Entering streaming block to send remaining values..'
)
for send_value, expect_send in iter_send_val_items: for send_value, expect_send in iter_send_val_items:
send_type: Type = type(send_value) send_type: Type = type(send_value)
print( print(
'CHILD report on send value\n' '------ - ------\n'
f'{uid}: SENDING NEXT VALUE\n'
f'ipc_pld_spec: {ipc_pld_spec}\n' f'ipc_pld_spec: {ipc_pld_spec}\n'
f'expect_send: {expect_send}\n' f'expect_send: {expect_send}\n'
f'val: {send_value}\n' f'val: {send_value}\n'
'------ - ------\n'
) )
try: try:
await ipc.send(send_value) await ipc.send(send_value)
print(f'***\n{uid}-CHILD sent {send_value!r}\n***\n')
sent.append(send_value) sent.append(send_value)
if not expect_send:
pytest.fail( # NOTE: should only raise above on
f'NOT-EXPECTED able to roundtrip value given spec:\n' # `.started()` or a `Return`
f'ipc_pld_spec -> {ipc_pld_spec}\n' # if not expect_send:
f'value -> {send_value}: {send_type}\n' # raise RuntimeError(
) # f'NOT-EXPECTED able to roundtrip value given spec:\n'
# f'ipc_pld_spec -> {ipc_pld_spec}\n'
# f'value -> {send_value}: {send_type}\n'
# )
except ValidationError: except ValidationError:
print(f'{uid} FAILED TO SEND {send_value}!')
# await tractor.pause()
if expect_send: if expect_send:
pytest.fail( raise RuntimeError(
f'EXPECTED to roundtrip value given spec:\n' f'EXPECTED to roundtrip value given spec:\n'
f'ipc_pld_spec -> {ipc_pld_spec}\n' f'ipc_pld_spec -> {ipc_pld_spec}\n'
f'value -> {send_value}: {send_type}\n' f'value -> {send_value}: {send_type}\n'
) )
continue # continue
assert ( else:
len(sent) print(
== f'{uid}: finished sending all values\n'
len([val 'Should be exiting stream block!\n'
for val, expect in
expect_ipc_send.values()
if expect is True])
) )
print(f'{uid}: exited streaming block!')
# TODO: this won't be true bc in streaming phase we DO NOT
# msgspec check outbound msgs!
# -[ ] once we implement the receiver side `InvalidMsg`
# then we can expect it here?
# assert (
# len(sent)
# ==
# len([val
# for val, expect in
# expect_ipc_send.values()
# if expect is True])
# )
def ex_func(*args): def ex_func(*args):
print(f'ex_func({args})') print(f'ex_func({args})')
@ -635,7 +659,7 @@ def test_codec_hooks_mod(
async with ( async with (
p.open_context( p.open_context(
send_back_nsp, send_back_values,
expect_debug=debug_mode, expect_debug=debug_mode,
pld_spec_type_strs=pld_spec_type_strs, pld_spec_type_strs=pld_spec_type_strs,
add_hooks=add_codec_hooks, add_hooks=add_codec_hooks,
@ -665,10 +689,13 @@ def test_codec_hooks_mod(
async for next_sent in ipc: async for next_sent in ipc:
print( print(
'Child sent next value\n' 'Parent: child sent next value\n'
f'{next_sent}: {type(next_sent)}\n' f'{next_sent}: {type(next_sent)}\n'
) )
if expect_to_send:
expect_to_send.remove(next_sent) expect_to_send.remove(next_sent)
else:
print('PARENT should terminate stream loop + block!')
# all sent values should have arrived! # all sent values should have arrived!
assert not expect_to_send assert not expect_to_send