Repository navigation
test(ci): wire 17 uncollected infra/libs tests into CI and name the second edit in the concurrency guard (#15051, #15302) - #15315
Conversation
…e dead integration step, and name the second edit in the concurrency guard (#15051, #15302) #15051 re-measured against current base: 11 of the originally-reported 28 unmarked tests gained a marker since (#14979/#15166) and already run via marker-tests.yml; the remaining 17 (13 in test_architecture_compliance.py, 4 in test_redis_db_ssot.py) ran in no workflow and no bare `pytest`. Wired both trees into pytest.ini testpaths and all four repo_tests-carrying invocations, retired ci.yml's dead `Run integration tests` step (its path was never updated after #734 moved the suite, so it warned and passed on every run since), and fixed two real bugs the newly-collected tests surfaced: get_backend_config() never set the "host"/"port" keys service_discovery.py already reads (falls back silently in every deployment), and a test imported utils.redis_helper, a module deleted years before this test ever ran. #15302: the concurrency guard's failure message told an author their omission was wrong but never that DELIBERATELY_EXEMPT is the intended second edit -- named it directly in the assertion, which is how #15300 got missed.
…ollected again (#15051) repo_tests/marker_suite_root_coverage_test.py only guards the MARKED population against running nowhere -- AC #5 asks for the unmarked case too, which is exactly how the 17 tests this PR just wired in got missed for as long as they did. Scoped to the two roots this issue actually fixed rather than a repo-wide sweep: a blind repo-wide version fails immediately against 23 pre-existing, already-deferred collection errors under autobot-infrastructure/shared/scripts (documented inline in pytest.ini) and 67 further orphans elsewhere that are unrelated to this issue's scope.
✅ SSOT Configuration Compliance: Passing🎉 No new hardcoded values of either class — Known backlog in |
CI found a real defect — in the guard, not in the wiring. Fixed in
|
…adjust them green (#15051)
|
Triage of the remaining failures.
The four |
…fixed topology (#15194) PR #15315 wired this file into CI for the first time and four tests failed by construction: each asserted a fixed six-VM topology AutoBot does not have. #15194's owner comment marked all four @pytest.mark.skip with the reason recorded instead of adjusting them to pass. This rewrites each one against an invariant that holds in every supported deployment (Docker, one VM, or any host count) and removes the skip: - test_browser_service_on_vm5 -> test_service_hosts_resolve_via_ssot_config: every role's host matches autobot_shared.ssot_config.config.vm directly (not NetworkConstants, which is itself only a ConfigRegistry proxy in front of the same SSOT) -- non-tautological because the two paths can drift (stale ConfigRegistry/Redis cache, a stray literal). - test_no_localhost_in_distributed_services -> test_distributed_service_hosts_are_resolved: loopback is now allowed (correct for Docker/single-VM per VM_ROLES.md); every role's host must still be a non-empty, syntactically valid address or hostname. - test_standard_port_assignments -> test_service_ports_match_ssot_constants: compares against autobot_shared.ssot_config.config.port instead of literals. Also fixes two latent bugs the literal comparison hid: the browser-role assertion used 3000 (Grafana's port; SSOT default is 9001, #4052) and read the config under the wrong key (`browser_service`, which get_distributed_services_config() never populates -- the key is `browser`). - test_only_one_frontend_instance: no longer requires backend and frontend to be on different hosts (fails a correct co-located/single-VM install). Asserts exactly one `frontend` entry in NetworkConstants.get_host_configs() instead, which is a real check on the canonical fleet-wide host registry. Not touched: test_redis_on_vm3_only, test_frontend_on_vm1, test_npu_worker_on_vm2, test_ai_stack_on_vm4 assert the same host-equals-a-fixed-VM-constant shape and currently pass only because both sides of the comparison trace back to the same SSOT value in this environment -- the same tautology, just not yet red. They were not in the skip list this issue scoped, so left as a follow-up finding rather than rewritten here.
…fixed topology (#15194) PR #15315 wired this file into CI for the first time and four tests failed by construction: each asserted a fixed six-VM topology AutoBot does not have. #15194's owner comment marked all four @pytest.mark.skip with the reason recorded instead of adjusting them to pass. This rewrites each one against an invariant that holds in every supported deployment (Docker, one VM, or any host count) and removes the skip: - test_browser_service_on_vm5 -> test_service_hosts_resolve_via_ssot_config: every role's host matches autobot_shared.ssot_config.config.vm directly (not NetworkConstants, which is itself only a ConfigRegistry proxy in front of the same SSOT) -- non-tautological because the two paths can drift (stale ConfigRegistry/Redis cache, a stray literal). - test_no_localhost_in_distributed_services -> test_distributed_service_hosts_are_resolved: loopback is now allowed (correct for Docker/single-VM per VM_ROLES.md); every role's host must still be a non-empty, syntactically valid address or hostname. - test_standard_port_assignments -> test_service_ports_match_ssot_constants: compares against autobot_shared.ssot_config.config.port instead of literals. Also fixes two latent bugs the literal comparison hid: the browser-role assertion used 3000 (Grafana's port; SSOT default is 9001, #4052) and read the config under the wrong key (`browser_service`, which get_distributed_services_config() never populates -- the key is `browser`). - test_only_one_frontend_instance: no longer requires backend and frontend to be on different hosts (fails a correct co-located/single-VM install). Asserts exactly one `frontend` entry in NetworkConstants.get_host_configs() instead, which is a real check on the canonical fleet-wide host registry. Not touched: test_redis_on_vm3_only, test_frontend_on_vm1, test_npu_worker_on_vm2, test_ai_stack_on_vm4 assert the same host-equals-a-fixed-VM-constant shape and currently pass only because both sides of the comparison trace back to the same SSOT value in this environment -- the same tautology, just not yet red. They were not in the skip list this issue scoped, so left as a follow-up finding rather than rewritten here.
…fixed topology (#15194) PR #15315 wired this file into CI for the first time and four tests failed by construction: each asserted a fixed six-VM topology AutoBot does not have. #15194's owner comment marked all four @pytest.mark.skip with the reason recorded instead of adjusting them to pass. This rewrites each one against an invariant that holds in every supported deployment (Docker, one VM, or any host count) and removes the skip: - test_browser_service_on_vm5 -> test_service_hosts_resolve_via_ssot_config: every role's host matches autobot_shared.ssot_config.config.vm directly (not NetworkConstants, which is itself only a ConfigRegistry proxy in front of the same SSOT) -- non-tautological because the two paths can drift (stale ConfigRegistry/Redis cache, a stray literal). - test_no_localhost_in_distributed_services -> test_distributed_service_hosts_are_resolved: loopback is now allowed (correct for Docker/single-VM per VM_ROLES.md); every role's host must still be a non-empty, syntactically valid address or hostname. - test_standard_port_assignments -> test_service_ports_match_ssot_constants: compares against autobot_shared.ssot_config.config.port instead of literals. Also fixes two latent bugs the literal comparison hid: the browser-role assertion used 3000 (Grafana's port; SSOT default is 9001, #4052) and read the config under the wrong key (`browser_service`, which get_distributed_services_config() never populates -- the key is `browser`). - test_only_one_frontend_instance: no longer requires backend and frontend to be on different hosts (fails a correct co-located/single-VM install). Asserts exactly one `frontend` entry in NetworkConstants.get_host_configs() instead, which is a real check on the canonical fleet-wide host registry. Not touched: test_redis_on_vm3_only, test_frontend_on_vm1, test_npu_worker_on_vm2, test_ai_stack_on_vm4 assert the same host-equals-a-fixed-VM-constant shape and currently pass only because both sides of the comparison trace back to the same SSOT value in this environment -- the same tautology, just not yet red. They were not in the skip list this issue scoped, so left as a follow-up finding rather than rewritten here.
Thinking Path
#15051 re-measured before touching anything, because the issue's own comment said its table predated PR #15048. Static count against current
Dev_new_gui:test_architecture_compliance.pytest_db_initialization.pytest_distributed_system_integration.pypytestmarkvia #14979/#15166, after the issue was filed)test_performance_optimization.pytest_redis_db_ssot.pylibs/.../test_integration.pyOf the original 28 unmarked, 11 (the whole
test_distributed_system_integration.pyandtest_performance_optimization.pypopulations) picked up a marker in an unrelated PR (#15166, merged after #15051 was filed and after the #15048 follow-up comment) and now run viamarker-tests.yml's third invocation. 17 remain — 13 intest_architecture_compliance.py, 4 intest_redis_db_ssot.py— and those ran in no workflow and no barepytest, ever.The dead
ci.ymlstep (Run integration tests, shard 1 only) namedinfrastructure/shared/tests/integration, a path #734 renamed toautobot-infrastructure/shared/tests/integrationwithout updating this reference. It quietly succeeds:if [ -d "$TEST_DIR" ]; then ...; else echo "::warning::..."; fihas noelse exit 1, so the step always exits 0 and has done since #734 — not an error, a silent no-op green on every shard-1 run.Both defects are fixed, not just documented:
autobot-infrastructure/shared/testsandlibsadded topytest.initestpathsand to all fourrepo_tests-carrying pytest invocations (ci.yml,coverage.yml,test-durations.yml,marker-tests.yml's first invocation), sorepo_tests/hook_suites_run_in_ci_test.py's root-set agreement stays true and the 17 unmarked tests run in the PR gate for the first time..../tests/integration(already reached by the wired-in invocation above) and put itsintegration-marked tests into the required, blocking PR gate with no-mfilter of its own — the exact "separate decision with its own blast radius"marker-tests.yml's own comment declines to make inline.Wiring in surfaced two real bugs, fixed on the implementation side per the "fix, don't adjust assertions" rule:
get_backend_config()never set a"host"/"port"key — only"server_host"/"server_port"(the bind address).utils/service_discovery.py:236's_register_backend_servicealready readsbackend_config.get("host")and logs an error on every process start when it comes backNone, silently falling back tosystem_defaults. Fixed by wiring in the existing canonicalget_host("backend")/get_port("backend")resolvers (env var →infrastructure.hosts.backend→ fallback map), the same precedence every sibling accessor here already uses.test_no_hardcoded_ips_in_redis_helperimportedfrom utils.redis_helper import REDIS_HOST—utils/redis_helper.pywas deleted from every tree years ago (confirmed viagit log --diff-filter=D), andREDIS_HOSTwas never a real export of it even historically. Repointed at the canonicalautobot_shared.redis_clientaccessor, mirroring the identical fix ci(gates): make four gates that could not fail actually fail (#13543, #13286, #13200) #15048 already made for the siblingTIMEOUT_CONFIGimport in the neighboring test.Also rewrote
test_service_discovery_has_defaults: it asserted four keys inside aservice_discovery_defaultsconfig section that two call sites (service_discovery.py,distributed_service_discovery.py) already document inline as having "no ssot equivalent". Nothing writes those keys any more post-#13286's SSOT consolidation — the test is now provably wrong, not the implementation, so it now asserts the property those two callers actually depend on: the section resolves to{}, neverNone.The VM-topology comparison tests (
test_redis_on_vm3_only,test_frontend_on_vm1, etc.) were reasoned through from source as far as static reading allows without executing code (forbidden by task constraints) — several compare a config accessor's output against the sameNetworkConstantssource it was built from, so they hold by construction.test_redis_on_vm3_onlycompares against a 5-tierConfigRegistryresolution chain that cannot be fully verified without running pytest; left as-is for CI to be the actual judge, per the task's own instruction, and will be triaged from real CI output if it turns up red.#15302: the guard's assertion at
:104-108told an author their omission was wrong but never mentionedDELIBERATELY_EXEMPT— exactly how #15300 got missed. Chose the message route over coupling the two edits: the file's own docstring already weighed this trade-off ("the coupling route is stronger but needs a way to recognise a required-context shim, which is a judgement rather than a pattern") and a judgement-based coupling risks false positives against this repo's preference for mechanical, derived checks over heuristics. The assertion now names the exemption dict, the exact filename, and cites #15300 as the precedent.What Changed
pytest.ini—testpathsgainsautobot-infrastructure/shared/testsandlibs..github/workflows/ci.yml— same two roots added to the PR-gate pytest invocation; the deadRun integration testsstep is retired with its reasoning recorded inline..github/workflows/coverage.yml,.github/workflows/test-durations.yml,.github/workflows/marker-tests.yml— same two roots added to keep the fourrepo_tests-carrying invocations in agreement.autobot-backend/config/service_config.py—get_backend_config()now sets"host"/"port"via the canonicalget_host/get_portresolvers.autobot-infrastructure/shared/tests/integration/test_architecture_compliance.py—test_no_hardcoded_ips_in_redis_helperrepointed off a deleted module;test_service_discovery_has_defaultsrewritten against the current SSOT reality.repo_tests/workflow_concurrency_guard_test.py— the concurrency-guard failure message now namesDELIBERATELY_EXEMPTas the second edit.repo_tests/infra_libs_test_wiring_guard_15051_test.py(new) — the AC Dev new gui #5 guard: a tracked test module underautobot-infrastructure/shared/testsorlibsmust be named by pytest.ini or some CI invocation, marked or not. Scoped to these two roots (not repo-wide) with a reach floor of 5 modules.Verification
Execution is off-limits for this task (do not run pytest / execute code from the codebase) — reasoning is from source, cross-checked against:
autobot-infrastructure/shared/testsandlibs, and 67 pre-existing orphans elsewhere in the repo that a repo-wide version of the same check would have wrongly reported against this PR.git log --diff-filter=Dconfirmingutils/redis_helper.py's deletion and its historical contents (noREDIS_HOSTexport ever existed).service_discovery.py:236's existing.get("host")read and itslogger.errorfallback, proving the missing key is a real, already-manifesting defect.service_discovery.py/distributed_service_discovery.pydocumentingservice_discovery_defaultsas having no SSOT equivalent.python3 -c "import ast; ast.parse(...)"on every touched.pyfile andyaml.safe_loadon every touched workflow — all parse cleanly.repo_tests/hook_suites_run_in_ci_test.pyandrepo_tests/marker_suite_root_coverage_test.pyread in full to confirm the exact root-set-agreement and floor mechanics the new roots must satisfy, and that none of the existing floors (MARKER_MIN_PASSED=34,infra=10,slm=0) are lowered or bypassed — only more roots are added to invocations that already clear those floors.Model Used
Claude Sonnet 5
Refs #15051 -- wiring, dead-step retirement, and the two implementation bugs it surfaced are complete; the VM-topology assertions in test_architecture_compliance.py could not be verified without executing pytest (out of scope for this task) and are left for CI to judge, which is why this is Refs rather than Closes.
Refs #15302 -- the message-route fix for the guard's third, previously-unmet criterion is complete; left as Refs rather than Closes per this repository's closing convention (closed by hand, with evidence, not by a merge keyword).