mirror of
https://github.com/logos-messaging/logos-delivery.git
synced 2026-08-10 22:03:19 +00:00
* test(e2e): port remaining wrapper tests from the interop repo The wrapper suite that moved into tests-e2e (#4027) was a reworked subset of the one still living in logos-delivery-interop-tests. Comparing both sides showed 21 tests here against 46 there, with no overlap in the delta: the 25 missing tests cover scenarios the reworked set never included. Ports those 25 tests, bringing the in-repo suite to the full 46: - 12 send scenarios: s01 (nil/destroyed handle), s03, s04, s05, s11, s13, s16, s18 (both orderings), s25, s29 - 7 channel lifecycle tests (rc01-rc04) - 6 wrapper corner cases: auto port allocation, MyBoundPorts, ENR Supporting changes the ported tests need: - wrapper_helpers: get_node_tcp_port, get_node_bound_ports, enr_udp_port - WrapperManager: channel_create/send/close, destroy_keep_ctx - vendored binding refreshed to the revision exposing the channel API (additive only; cffi resolves symbols lazily, so nothing existing moves) Two Edge senders were fixed while porting. build_node_config defaults relay and store to True, and the flat-JSON config path applies mode=Edge before explicit fields, so those defaults win: the Edge nodes in s11/s16/s25 came up as relay and store servers and exercised the relay path instead of lightpush. They now set relay=False and store=False, matching test_send_e2e_part2. s16 also dropped lightpush=True, which mounts the lightpush server and fails node start once relay is off; the lightpush client mounts unconditionally. Suite goes from 21 to 46 functions (53 collected). The docker subset grows from 3 to 5 as s11 and s25 need a store peer. Local run against a freshly built library: 45 passed, 2 skipped, 1 xfailed. * test(e2e): enable autosharding in the channel lifecycle tests channel_create subscribes to the channel's content topic since #4081, and resolving that topic to a shard needs autosharding. build_node_config leaves numShardsInNetwork at 0 and cluster 198 has no preset, so these nodes came up with static sharding and every channel_create failed with "autosharding is not configured; pass an explicit shard". Adds numShardsInNetwork=1 to the six tests that create a channel, matching what every other wrapper test that touches the send or channel API already does. rc02 is left alone: channel_send rejects on the id lookup before any shard is resolved. Verified locally against a fresh build: the five tests that complete now pass and the error string is gone from the run.
149 lines
4.4 KiB
Python
149 lines
4.4 KiB
Python
"""S01 helpers: invoke send() against an invalid handle in an isolated process.
|
|
|
|
Run via:
|
|
python -m tests.wrappers_tests.helpers.send_invalid_handle nil <marker>
|
|
python -m tests.wrappers_tests.helpers.send_invalid_handle destroyed <marker>
|
|
|
|
Prints a single line to stdout starting with <marker>, followed by a JSON
|
|
payload describing the outcome. Runs in its own process so that a missing
|
|
C-ABI guard (which can SIGSEGV) fails the parent test cleanly instead of
|
|
taking the pytest runner down.
|
|
|
|
Cases:
|
|
- nil: send() on a wrapper built with ctx=ffi.NULL.
|
|
- destroyed: send() after destroy_keep_ctx() — self.ctx stays non-nil so the
|
|
call reaches the C side with the original (now-stale) pointer.
|
|
"""
|
|
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def _ensure_bindings_on_path() -> None:
|
|
# The wrapper module lives outside the project tree, under vendor/.
|
|
# Helper file is at <root>/tests/wrappers_tests/helpers/<this>.py.
|
|
project_root = Path(__file__).resolve().parents[3]
|
|
bindings_path = project_root / "vendor" / "logos-delivery-python-bindings" / "waku"
|
|
if str(bindings_path) not in sys.path:
|
|
sys.path.insert(0, str(bindings_path))
|
|
if str(project_root) not in sys.path:
|
|
sys.path.insert(0, str(project_root))
|
|
|
|
|
|
def _emit(marker: str, payload: dict) -> None:
|
|
print(marker + json.dumps(payload))
|
|
|
|
|
|
def _run_nil_handle(marker: str) -> None:
|
|
from wrapper import NodeWrapper, ffi # type: ignore[import-not-found]
|
|
from src.node.wrappers_manager import WrapperManager
|
|
from src.node.wrapper_helpers import create_message_bindings
|
|
|
|
sender = WrapperManager(NodeWrapper(ctx=ffi.NULL, config_buffer=None, event_cb_handler=None))
|
|
send_result = sender.send_message(message=create_message_bindings())
|
|
|
|
_emit(
|
|
marker,
|
|
{
|
|
"is_ok": send_result.is_ok(),
|
|
"ok": send_result.ok_value if send_result.is_ok() else None,
|
|
"err": send_result.err() if send_result.is_err() else None,
|
|
},
|
|
)
|
|
|
|
|
|
def _run_destroyed_handle(marker: str) -> None:
|
|
from src.node.wrappers_manager import WrapperManager
|
|
from src.node.wrapper_helpers import EventCollector, create_message_bindings
|
|
from tests.wrappers_tests.conftest import build_node_config
|
|
|
|
collector = EventCollector()
|
|
|
|
create_result = WrapperManager.create_and_start(
|
|
config=build_node_config(),
|
|
event_cb=collector.event_callback,
|
|
)
|
|
if create_result.is_err():
|
|
_emit(
|
|
marker,
|
|
{
|
|
"stage": "create_and_start",
|
|
"is_ok": False,
|
|
"ok": None,
|
|
"err": create_result.err(),
|
|
"events_after_send": [],
|
|
},
|
|
)
|
|
return
|
|
|
|
sender = create_result.ok_value
|
|
|
|
stop_result = sender.stop_node()
|
|
if stop_result.is_err():
|
|
_emit(
|
|
marker,
|
|
{
|
|
"stage": "stop_node",
|
|
"is_ok": False,
|
|
"ok": None,
|
|
"err": stop_result.err(),
|
|
"events_after_send": [],
|
|
},
|
|
)
|
|
return
|
|
|
|
destroy_result = sender.destroy_keep_ctx()
|
|
if destroy_result.is_err():
|
|
_emit(
|
|
marker,
|
|
{
|
|
"stage": "destroy_keep_ctx",
|
|
"is_ok": False,
|
|
"ok": None,
|
|
"err": destroy_result.err(),
|
|
"events_after_send": [],
|
|
},
|
|
)
|
|
return
|
|
|
|
events_before_send = len(collector.events)
|
|
|
|
send_result = sender.send_message(message=create_message_bindings())
|
|
|
|
new_events = collector.events[events_before_send:]
|
|
|
|
_emit(
|
|
marker,
|
|
{
|
|
"stage": "send_message",
|
|
"is_ok": send_result.is_ok(),
|
|
"ok": send_result.ok_value if send_result.is_ok() else None,
|
|
"err": send_result.err() if send_result.is_err() else None,
|
|
"events_after_send": [str(e) for e in new_events],
|
|
},
|
|
)
|
|
|
|
|
|
CASES = {
|
|
"nil": _run_nil_handle,
|
|
"destroyed": _run_destroyed_handle,
|
|
}
|
|
|
|
|
|
def main() -> int:
|
|
if len(sys.argv) != 3 or sys.argv[1] not in CASES:
|
|
cases = "|".join(CASES)
|
|
print(f"usage: send_invalid_handle <{cases}> <result_marker>", file=sys.stderr)
|
|
return 2
|
|
|
|
case, marker = sys.argv[1], sys.argv[2]
|
|
|
|
_ensure_bindings_on_path()
|
|
CASES[case](marker)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|