Port service+tests to latest `tractor` APIs
Continue the `repair_tests`-branch mission (already merged in this stack's ancestry, seedatad_servicef4c4f1e2which ported `conftest.py`) by fixing the remaining drift breakage vs. `tractor` git `main`; without these NOTHING boots since the `tractor.Address` port in604e5fcf. Deats, - normalize reg addrs via `wrap_address()` in `open_pikerd()` before `.unwrap()`-ing; entries may be raw `tuple`s when passed in from (test) client code. - port `check_for_service()` to `query_actor(regaddr=)` (was `arbiter_sockaddr=`) incl. its 2-tuple yield and the now-required `open_registry(addrs=)` arg. - `wait_for_actor(registry_addr=)` + `.chan.raddr.unwrap()` raw-tuple compares in `test_runtime_boot` and `ensure_service()`. - update `run_test_w_cancel_method()` for modern `tractor` cancel semantics: self-requested sub-service cancels are absorbed (no `ContextCancelled` raised to the opener) and single-exc groups collapse to a bare KBI. - `RemoteActorError.boxed_type` (was `.type`) and `Position.cumsize` (was `.size`) renames in tests. - bump the paper-EMS startup budget 9 -> 19s; it includes a live (kraken) symbology fetch so needs net headroom. - woops, add the missing comma in `.deribit.api`'s `tractor.trionics` import tuple.. (this patch was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-code Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
parent
06c0a4856e
commit
47a7cf5502
|
|
@ -37,7 +37,7 @@ from rapidfuzz import process as fuzzy
|
|||
import numpy as np
|
||||
from tractor.trionics import (
|
||||
broadcast_receiver,
|
||||
maybe_open_context
|
||||
maybe_open_context,
|
||||
collapse_eg,
|
||||
)
|
||||
from tractor import to_asyncio
|
||||
|
|
|
|||
|
|
@ -214,7 +214,13 @@ async def open_pikerd(
|
|||
trio.open_nursery() as service_tn,
|
||||
):
|
||||
for addr in reg_addrs:
|
||||
uaddr: tuple = addr.unwrap()
|
||||
# normalize to a wrapped `tractor` addr-type;
|
||||
# entries may be raw `tuple`s when passed in
|
||||
# from (test) client code.
|
||||
wladdr = tractor.discovery._addr.wrap_address(
|
||||
addr,
|
||||
)
|
||||
uaddr: tuple = wladdr.unwrap()
|
||||
if (
|
||||
uaddr not in root_actor.accept_addrs
|
||||
):
|
||||
|
|
|
|||
|
|
@ -225,10 +225,13 @@ async def check_for_service(
|
|||
|
||||
'''
|
||||
async with (
|
||||
open_registry(ensure_exists=False) as reg_addr,
|
||||
open_registry(
|
||||
addrs=Registry.addrs,
|
||||
ensure_exists=False,
|
||||
) as reg_addrs,
|
||||
tractor.query_actor(
|
||||
service_name,
|
||||
arbiter_sockaddr=reg_addr,
|
||||
) as sockaddr,
|
||||
regaddr=reg_addrs[0],
|
||||
) as (sockaddr, _),
|
||||
):
|
||||
return sockaddr
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ def load_and_check_pos(
|
|||
# is the same the fqme.
|
||||
pp: Position = table.pps[ppmsg.symbol]
|
||||
|
||||
assert ppmsg.size == pp.size
|
||||
assert ppmsg.size == pp.cumsize
|
||||
assert ppmsg.avg_price == pp.ppu
|
||||
|
||||
yield pp
|
||||
|
|
@ -179,7 +179,7 @@ def test_ems_err_on_bad_broker(
|
|||
# NOTE: emsd should error on the actor's enabled modules
|
||||
# import phase, when looking for a backend named `doggy`.
|
||||
except tractor.RemoteActorError as re:
|
||||
assert re.type is ModuleNotFoundError
|
||||
assert re.boxed_type is ModuleNotFoundError
|
||||
|
||||
run_and_tollerate_cancels(load_bad_fqme)
|
||||
|
||||
|
|
|
|||
|
|
@ -53,11 +53,12 @@ def test_runtime_boot(
|
|||
|
||||
tractor.wait_for_actor(
|
||||
'pikerd',
|
||||
arbiter_sockaddr=daemon_addr,
|
||||
registry_addr=daemon_addr,
|
||||
) as portal,
|
||||
):
|
||||
assert pikerd_portal.channel.raddr == daemon_addr
|
||||
assert pikerd_portal.channel.raddr == portal.channel.raddr
|
||||
uw_raddr: tuple = pikerd_portal.chan.raddr.unwrap()
|
||||
assert uw_raddr == daemon_addr
|
||||
assert uw_raddr == portal.chan.raddr.unwrap()
|
||||
|
||||
# no service tasks should be started
|
||||
assert not services.service_tasks
|
||||
|
|
@ -108,7 +109,7 @@ async def ensure_service(
|
|||
sockaddr: tuple[str, int] | None = None,
|
||||
) -> None:
|
||||
async with find_service(name) as portal:
|
||||
remote_sockaddr = portal.channel.raddr
|
||||
remote_sockaddr: tuple = portal.chan.raddr.unwrap()
|
||||
print(f'FOUND `{name}` @ {remote_sockaddr}')
|
||||
|
||||
if sockaddr:
|
||||
|
|
@ -131,41 +132,50 @@ def run_test_w_cancel_method(
|
|||
"was remotely cancelled by remote actor (\'pikerd\'")
|
||||
|
||||
if cancel_method == 'sigint':
|
||||
with pytest.raises(
|
||||
# XXX: with modern `tractor` the (single-exc)
|
||||
# group is collapsed so a bare KBI normally
|
||||
# propagates; tolerate either form.
|
||||
with pytest.raises((
|
||||
KeyboardInterrupt,
|
||||
BaseExceptionGroup,
|
||||
) as exc_info:
|
||||
)) as exc_info:
|
||||
trio.run(main)
|
||||
|
||||
multi = exc_info.value
|
||||
|
||||
for suberr in multi.exceptions:
|
||||
err = exc_info.value
|
||||
match err:
|
||||
case BaseExceptionGroup():
|
||||
for suberr in err.exceptions:
|
||||
match suberr:
|
||||
# ensure we receive a remote cancellation error caused
|
||||
# by the pikerd root actor since we used the
|
||||
# `.cancel_service()` API above B)
|
||||
# ensure we receive a remote
|
||||
# cancellation error caused by the
|
||||
# pikerd root actor.
|
||||
case tractor.ContextCancelled():
|
||||
assert cancelled_msg in suberr.args[0]
|
||||
assert (
|
||||
cancelled_msg
|
||||
in
|
||||
suberr.args[0]
|
||||
)
|
||||
|
||||
case KeyboardInterrupt():
|
||||
pass
|
||||
|
||||
case _:
|
||||
pytest.fail(f'Unexpected error {suberr}')
|
||||
pytest.fail(
|
||||
f'Unexpected error {suberr}'
|
||||
)
|
||||
|
||||
case KeyboardInterrupt():
|
||||
pass
|
||||
|
||||
elif cancel_method == 'services':
|
||||
|
||||
# XXX NOTE: oddly, when you pass --pdb to pytest, i think since
|
||||
# we also use that to enable the underlying tractor debug mode,
|
||||
# it causes this to not raise for some reason? So if you see
|
||||
# that while changing this test.. it's prolly that.
|
||||
|
||||
with pytest.raises(
|
||||
tractor.ContextCancelled
|
||||
) as exc_info:
|
||||
# XXX: cancelling our own sub-service via
|
||||
# `Services.cancel_service()` is a *self*
|
||||
# requested cancel: modern `tractor` absorbs the
|
||||
# resulting `ContextCancelled` (canceller is our
|
||||
# own actor) so the runtime tears down gracefully
|
||||
# with NO error raised to the opener.
|
||||
trio.run(main)
|
||||
|
||||
assert cancelled_msg in exc_info.value.args[0]
|
||||
|
||||
else:
|
||||
pytest.fail(f'Test is broken due to {cancel_method}')
|
||||
|
||||
|
|
@ -197,7 +207,9 @@ def test_ensure_ems_in_paper_actors(
|
|||
# ensure we timeout after is startup is too slow.
|
||||
# TODO: something like this should be our start point for
|
||||
# benchmarking end-to-end startup B)
|
||||
with trio.fail_after(9):
|
||||
# NOTE: includes a live (kraken) symbology fetch so
|
||||
# the budget needs some headroom for net latency..
|
||||
with trio.fail_after(19):
|
||||
async with (
|
||||
open_test_pikerd() as (_, _, _, services),
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue