You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
test(slm): test_health_redis_14299 fails on base — MagicMock reaches inet_pton #14535
tests/api/test_health_redis_14299.py::TestCheckRedisHealth::test_healthy_when_client_available fails on origin/Dev_new_gui.
501 passed, 1 failed
ERROR autobot_shared.redis_management.connection_manager: Error checking Redis readiness
for 'main': inet_pton() argument 2 must be str, not MagicMock
ERROR autobot_shared.retry_mechanism: create_async_pool[main] failed after 5 attempts
Verified as pre-existing by running the same suite at base in a clean worktree, not only on a feature branch.
What it looks like
The mock supplies a MagicMock where the readiness check expects a host string, so inet_pton rejects it, the pool creation retries five times and exhausts, and the "healthy when a client is available" case never reaches its assertion. So the test is exercising the retry path rather than the health path it names.
Why it matters beyond the one test
The Python suite is not a required check, so a red test here does not block a merge and can sit indefinitely. That is the same shape this umbrella keeps finding: a signal that exists, is failing, and is not surfaced anywhere that stops work.
Work
Give the mock a real host string so the readiness check reaches the branch under test
Confirm the test then fails when the health logic is broken — it currently cannot distinguish that from the mock defect
Acceptance
The test passes on base and fails when check_redis_health stops reporting healthy for an available client.
The actual failure is assert 'unhealthy' == 'healthy', with this in the captured log:
PoolConfig received non-numeric value(s) — falling back to defaults:
max_connections=<MagicMock name='mock.config.get_redis_config().get()'> ...
Error checking Redis readiness for 'main': inet_pton() argument 2 must be str, not MagicMock
So a MagicMock-derived Redis config reaches PoolConfig, readiness fails, and _check_redis_health correctly returns unhealthy. The health code and its mock are both fine — they are being handed a poisoned Redis configuration.
What I ruled out
test_auth_logout installs MagicMocks into sys.modules for its bootstrap (line 78) and does restore them afterwards (lines 126-134), so the obvious explanation is not it. Probing after importing that module:
sys.modules entries for config, autobot_shared.ssot_config, autobot_shared.redis_client and redis_management.connection_manager — all clean
ssot_config.get_config's lru_cache — holds a real config, not a mock
connection_manager._config_manager — None
a sweep of every loaded autobot_shared / services / api / config module for module-level MagicMock attributes — 0 hits
I also tried the obvious fix, adding RedisConnectionManager.reset_instance() to that module's restore block — its docstring cites exactly this scenario (#11830, "a singleton constructed under test-stubbed config caches the stub"). It does not fix the failure, so I reverted it rather than leave an ineffective change in the tree.
Where that leaves it
Nothing is poisoned at import time, so the poisoning happens while test_auth_logout's tests execute — its own per-test patching, or something constructed lazily on first use afterwards. That is the next place to look, and it is a narrower target than when this issue was filed.
Severity, restated
Lower than the original text implies. The health logic is correct and its own tests pass; this is an ordering artifact. It still matters because the Python suite is not a required check, so a red test here does not block anything and can sit indefinitely — but it is not evidence of a health-check defect.
Delivered by PR #14576, squash-merged as f1c42c7e7 and verified in origin/Dev_new_gui.
The issue was filed as a broken mock. It was test pollution, and the chain is worth recording — I verified all six links against real pytest and CPython behaviour rather than accepting the narrative:
services/token_denylist.py imports autobot_shared.redis_client transitively, pulled in by test_auth_logout.py's bootstrap.
The bootstrap's restore loop was unconditional — for _k in list(sys.modules): if _k not in _PRE_BOOTSTRAP_MODULES: del sys.modules[_k] — so it deleted a real module it never stubbed.
Deleting the sys.modules entry leaves the parent package's .redis_client attribute bound to the orphan.
_pytest/monkeypatch.py:resolve() does getattr on the parent before any import fallback, so the patch landed on that orphan.
_check_redis_health's function-local import then re-imported fresh and unpatched.
The root conftest MagicMocks config session-wide, so redis_config.get("host") returned a MagicMock — which is what reached inet_pton.
Link 4 is the non-obvious one and it checks out in the installed pytest source. Scoping the restore to _BOOTSTRAP_MANAGED_MODULES fixes the cause rather than the symptom.
A second defect surfaced in CI and is worth its own note: the auto-stub built MagicMock stubs with no __spec__. NonCallableMock.__getattr__ raises AttributeError for unconfigured dunder names, and CPython's _find_and_load_unlocked reads parent_module.__spec__unguarded — only the neighbouring __path__ read is wrapped — so it broke whenever a stub served as an import parent. It reproduces on Python 3.14 (what the shards run) and not on 3.10, which is why local runs were clean. Reproduced on 3.14 directly with a dependency-free harness rather than inferred from the traceback.
Base-verified: ModuleSpec present, 12/12 shards green, and nothing added to sys_modules_leak_baseline.txt — adding a line there to go green was the one move that would have made this worse.
Activity
mrveiss commentedon Aug 18, 2026
Correcting this issue — it is test pollution, not a broken mock
I filed this as "the mock supplies a MagicMock where a host string is expected". That is wrong, and the correction matters for whoever picks it up.
The test passes in isolation.
pytest tests/api/test_health_redis_14299.py→ 6 passed. It only fails as part of the wider directory.The interference is
tests/api/test_auth_logout.py, found by bisecting the 38 files intests/api/. The pair alone reproduces it:The actual failure is
assert 'unhealthy' == 'healthy', with this in the captured log:So a MagicMock-derived Redis config reaches
PoolConfig, readiness fails, and_check_redis_healthcorrectly returnsunhealthy. The health code and its mock are both fine — they are being handed a poisoned Redis configuration.What I ruled out
test_auth_logoutinstalls MagicMocks intosys.modulesfor its bootstrap (line 78) and does restore them afterwards (lines 126-134), so the obvious explanation is not it. Probing after importing that module:sys.modulesentries forconfig,autobot_shared.ssot_config,autobot_shared.redis_clientandredis_management.connection_manager— all cleanssot_config.get_config'slru_cache— holds a real config, not a mockconnection_manager._config_manager—Noneautobot_shared/services/api/configmodule for module-levelMagicMockattributes — 0 hitsI also tried the obvious fix, adding
RedisConnectionManager.reset_instance()to that module's restore block — its docstring cites exactly this scenario (#11830, "a singleton constructed under test-stubbed config caches the stub"). It does not fix the failure, so I reverted it rather than leave an ineffective change in the tree.Where that leaves it
Nothing is poisoned at import time, so the poisoning happens while
test_auth_logout's tests execute — its own per-test patching, or something constructed lazily on first use afterwards. That is the next place to look, and it is a narrower target than when this issue was filed.Severity, restated
Lower than the original text implies. The health logic is correct and its own tests pass; this is an ordering artifact. It still matters because the Python suite is not a required check, so a red test here does not block anything and can sit indefinitely — but it is not evidence of a health-check defect.
test(slm): fix redis health test pollution and the cross-tree stub lo…
mrveiss commentedon Aug 19, 2026
Delivered by PR #14576, squash-merged as
f1c42c7e7and verified inorigin/Dev_new_gui.The issue was filed as a broken mock. It was test pollution, and the chain is worth recording — I verified all six links against real pytest and CPython behaviour rather than accepting the narrative:
services/token_denylist.pyimportsautobot_shared.redis_clienttransitively, pulled in bytest_auth_logout.py's bootstrap.for _k in list(sys.modules): if _k not in _PRE_BOOTSTRAP_MODULES: del sys.modules[_k]— so it deleted a real module it never stubbed.sys.modulesentry leaves the parent package's.redis_clientattribute bound to the orphan._pytest/monkeypatch.py:resolve()doesgetattron the parent before any import fallback, so the patch landed on that orphan._check_redis_health's function-local import then re-imported fresh and unpatched.configsession-wide, soredis_config.get("host")returned a MagicMock — which is what reachedinet_pton.Link 4 is the non-obvious one and it checks out in the installed pytest source. Scoping the restore to
_BOOTSTRAP_MANAGED_MODULESfixes the cause rather than the symptom.A second defect surfaced in CI and is worth its own note: the auto-stub built
MagicMockstubs with no__spec__.NonCallableMock.__getattr__raisesAttributeErrorfor unconfigured dunder names, and CPython's_find_and_load_unlockedreadsparent_module.__spec__unguarded — only the neighbouring__path__read is wrapped — so it broke whenever a stub served as an import parent. It reproduces on Python 3.14 (what the shards run) and not on 3.10, which is why local runs were clean. Reproduced on 3.14 directly with a dependency-free harness rather than inferred from the traceback.Base-verified:
ModuleSpecpresent, 12/12 shards green, and nothing added tosys_modules_leak_baseline.txt— adding a line there to go green was the one move that would have made this worse.