refactor(test): dynamic ports with fixture injection#1153
refactor(test): dynamic ports with fixture injection#1153
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors the Python test HTTP server and related tests to use OS-assigned dynamic ports and pytest fixture injection, enabling parallel test execution and removing reliance on hardcoded localhost:8000 URLs / global state.
Changes:
- Replace hardcoded server URLs with a
ServerUrlsdataclass provided via a session-scopedserverfixture. - Update test pages (HTML/JS) to use root-relative paths instead of
http://localhost:8000/.... - Fix test path assumptions by removing
os.chdir()usage and switching to absolute paths / handlerdirectory=.
Reviewed changes
Copilot reviewed 30 out of 30 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| test/utilities.py | Introduces ServerUrls, binds server to port 0, removes os.chdir(), adds caching header behavior. |
| test/conftest.py | Updates server fixture to yield ServerUrls and threads it through task_manager_creator. |
| test/openwpmtest.py | Injects ServerUrls into OpenWPMTest instances and uses it to build absolute URLs. |
| test/manual_test.py | Adapts manual helpers to new start_server() return signature and dynamic base URL. |
| test/test_xvfb_browser.py | Switches test URL construction to server.base. |
| test/test_timer.py | Switches test URL construction to server.base. |
| test/test_task_manager.py | Switches test URL construction to server.base. |
| test/test_storage_vectors.py | Uses ServerUrls for page URL; keeps host expectation based on BASE_TEST_URL_DOMAIN. |
| test/test_simple_commands.py | Removes global URL constants, builds URLs from server.base, fixes expected-source path handling. |
| test/test_profile.py | Switches profile-related navigation from global base URL to server.base. |
| test/test_js_instrument.py | Removes global TOP_URL constants; computes URLs from self.server.base at runtime. |
| test/test_http_instrumentation.py | Converts expected HTTP record sets into functions parameterized by ServerUrls; updates test URLs. |
| test/test_extension.py | Refactors expected URL-dependent call sets into helper functions parameterized by server.base. |
| test/test_dns_instrument.py | Uses dynamic port for test.localhost. |
| test/test_custom_function_command.py | Builds expected link set from dynamic server.base. |
| test/test_callstack_instrument.py | Builds expected stack traces from dynamic server.base and fixes row handling. |
| test/test_callback.py | Switches callback test URL construction to server.base. |
| test/test_pages/simple_a.html | Replaces absolute link to localhost:8000 with root-relative /test_pages/.... |
| test/test_pages/expected_source.html | Updates expected HTML to match new root-relative link form. |
| test/test_pages/shared/worker.js | Replaces absolute fetch URL with root-relative /test_pages/.... |
| test/test_pages/shared/service_worker.js | Replaces absolute resource URL with root-relative /test_pages/.... |
| test/test_pages/http_service_worker_page.html | Replaces absolute fetch URL with root-relative /test_pages/.... |
| test/test_pages/recursive_iframes/parent.html | Replaces absolute iframe src URLs with root-relative /test_pages/.... |
| test/test_pages/recursive_iframes/child1a.html | Replaces absolute iframe src URLs with root-relative /test_pages/.... |
| test/test_pages/recursive_iframes/child1c.html | Replaces absolute iframe src URL with root-relative /test_pages/.... |
| test/test_pages/recursive_iframes/child2a.html | Replaces absolute iframe src URL with root-relative /test_pages/.... |
| test/test_pages/recursive_iframes/child2c.html | Replaces absolute iframe src URLs with root-relative /test_pages/.... |
| test/test_pages/recursive_iframes/child3a.html | Replaces absolute iframe src URL with root-relative /test_pages/.... |
| test/test_pages/recursive_iframes/child4a.html | Replaces absolute iframe src URL with root-relative /test_pages/.... |
| test/test_pages/recursive_iframes/child5a.html | Replaces absolute iframe src URL with root-relative /test_pages/.... |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| handler = lambda *args, **kwargs: MyHandler(*args, directory=test_dir, **kwargs) | ||
| server = MyTCPServer(("0.0.0.0", 0), handler) |
There was a problem hiding this comment.
socketserver.TCPServer is typed to take a RequestHandlerClass (a handler type), but start_server passes a lambda factory. This is likely to fail mypy (incompatible type) and also makes the handler less introspectable. Prefer defining an inner MyHandler subclass (or a small wrapper class) that hard-binds directory=test_dir and pass that class to MyTCPServer.
| handler = lambda *args, **kwargs: MyHandler(*args, directory=test_dir, **kwargs) | |
| server = MyTCPServer(("0.0.0.0", 0), handler) | |
| class BoundMyHandler(MyHandler): | |
| def __init__(self, *args, **kwargs): | |
| super().__init__(*args, directory=test_dir, **kwargs) | |
| server = MyTCPServer(("0.0.0.0", 0), BoundMyHandler) |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1153 +/- ##
==========================================
- Coverage 62.18% 62.14% -0.04%
==========================================
Files 40 40
Lines 3898 3902 +4
==========================================
+ Hits 2424 2425 +1
- Misses 1474 1477 +3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
- CRITICAL: add missing server: ServerUrls fixture to test_get_with_popup_blocking and construct url_a/url_b dynamically instead of using undefined module-level vars - MAJOR: replace os.chdir() in start_server() with SimpleHTTPRequestHandler directory= parameter to avoid mutating global process state - Remove dead code: ServerUrls.url() and ServerUrls.base_noscheme (never used)
Run black on test_http_instrumentation.py and test_custom_function_command.py to satisfy pre-commit checks.
9a71702 to
939c7e2
Compare
- test_dns_instrument: replace hardcoded port 8000 with server.port fixture in assertion and connection abort test - test_profile: use Path(__file__).parent for profile.tar.gz to avoid dependency on CWD being set to test/
Summary
port=0) instead of hardcodedlocalhost:8000to enable parallel test executionServerUrlsfixture via pytest, removing global state from test infrastructuretest_get_with_popup_blockingNameError (missingserverfixture)os.chdir()withSimpleHTTPRequestHandler(directory=)parameterFileNotFoundErrorindump_page_sourcetests by using absolute pathsSupersedes #1136. Incorporates all fixes identified through adversarial review (VDD methodology).
VDD Review History
os.chdir()hazardFileNotFoundErrorfrom incompleteos.chdir()removal → fixed with absolute pathsTest plan
test_simple_commands.pytests pass includingtest_dump_page_source_validandtest_recursive_dump_page_source_validtest_get_with_popup_blockingno longer raisesNameErrorpre-commit run --all-filespasses