feat(tests): add Python test harness with Docker infrastructure#76
Merged
feat(tests): add Python test harness with Docker infrastructure#76
Conversation
- Dockerfile with multi-stage build for ircu from working tree - docker-compose with hub + 2 leaves topology - Custom async IRC client with CAP negotiation support - pytest fixtures for container lifecycle management - PR #59 tests (part message suppression for banned users) - PR #61 tests (userhost-in-names capability) - IRC message parser unit tests
- tests/README.md: setup, usage, topology, API reference
- Fixed infinite loop in wait_for where stashed messages were re-read from buffer endlessly - Replaced deprecated asyncio.get_event_loop() with get_running_loop() - Simplified buffer search using enumerate
- Move dependencies from requirements.txt to pyproject.toml [project.dependencies] - Remove requirements.txt - Add uv.lock - Add .venv and uv.lock to .dockerignore
Add --force-recreate and explicit docker compose down before up to guarantee tests always run against the currently checked-out code. This is critical for TDD workflow where you switch branches between runs.
The original test_fix.py tested local part message suppression, which already worked on the base branch. The actual bug PR #59 fixes is that part messages leak across server-to-server links for banned users. Rewrote tests to use ircd_network fixture (multi-server topology): - Observer on leaf1 sees banned user's part message from hub (bug) - Fixed docker-compose to use static IPs (10.55.0.x) so ircu's built-in DNS resolver can find the other servers - Control test verifies unbanned part messages work cross-server
Add a lightweight P10 fake server (tests/p10_server.py) that connects to ircd as a U:lined service, completes the full P10 handshake, and can send S2S messages like OPMODE and ACCOUNT. This enables testing server-to-server protocol behavior from the Python test harness. Add integration tests for PR #62 (Remote +x): - test_fix.py: 3 TDD tests that verify OPMODE +x from a U:lined server sets hidden host (fail on base branch, pass with PR #62) - test_edge_cases.py: 6 adversarial tests covering remote users, unsupported modes, ACCOUNT, -o regression, and rapid sequences Infrastructure changes: - Docker configs: add Connect + UWorld blocks for services.test.net - Dockerfile: clean host-compiled binaries before Linux build to fix exec format error on cross-platform Docker builds
PR #62's OPMODE +x handler requires IsAccount(dptr) — it silently ignores +x on users without an account. Updated the test to verify this correct behavior instead of expecting a MODE notification.
Extend test_remote_opmode_x_without_account to a two-phase test: first verifies +x is ignored without an account (IsAccount guard), then sets the account and verifies +x succeeds and hides the host.
Add test_account_rejected_from_non_ulined_server which connects a second fake P10 server (notulined.test.net) that has a Connect block but no UWorld entry. Verifies that ACCOUNT from this server gets ERR_NOPRIVILEGES (481) and the user's account is not set. This covers the second half of PR #62: ms_account now requires CONF_UWORLD before accepting ACCOUNT messages.
- Remove incorrect 481 (ERR_NOPRIVILEGES) expectation from test_account_rejected_from_non_ulined_server; protocol_violation() only sends a DESYNCH wallops, not a numeric reply - Rename test_nooper_uworld_cannot_send_plus_x to _can_ and flip assertion; PR #62 intentionally only gates +o/-o behind CONF_UWORLD_OPER while +x needs only basic CONF_UWORLD - Rename test_nooper_uworld_unknown_mode_should_be_rejected to _silently_ignored; unknown modes fall through without error - Strengthen test_opmode_minus_o_still_works to verify MODE -o notification now that PR #62 adds send_umode_out() to de_oper() - Add Connect/UWorld blocks for uworldonly.test.net in hub config - Switch Dockerfile to debian:trixie-slim and use autogen.sh for reliable autotools bootstrapping in container builds
1be6217 to
81ab3bd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
Pretty big PR since it adds integration test cases retroactively for a few new features.
Summary
P10Server) for testing S2S protocol behaviorDetails
Infrastructure:
Dockerfiledebian:trixie-slim, runsautogen.shfor reliable autotools bootstrappingdocker-compose.ymltests/conftest.pytests/irc_client.pywait_for/collect_untilhelperstests/p10_server.pyTest server topology:
services.test.netnotulined.test.netuworldonly.test.netCONF_UWORLDwithoutCONF_UWORLD_OPERTest suites:
pr59_part_messages/— cross-server part message suppression for banned userspr61_uhnames/— UHNAMES (userhost-in-names) CAP negotiation and NAMES reply formatpr62_remote_x/— remote OPMODE +x, ACCOUNT U:line restriction, privilege tier checks, umode propagation orderingEach PR directory follows a consistent pattern:
test_fix.py— TDD tests that fail on the base branch and pass with the PR appliedtest_edge_cases.py— adversarial tests for boundary conditions and regressionstest_privilege_check.py,test_umode_ordering.py)Test plan