Repository navigation
bug(tests): 48 mock paths target nonexistent 'src.*' package — patches silently no-op #6987
Description
Bug
48 calls to unittest.mock.patch("src.<module>.<symbol>") exist across 14 test files in autobot-backend/. The path prefix src. resolves to a package that doesn't exist — autobot-backend/src/ is not a directory and pytest.ini configures pythonpath = autobot-backend autobot_shared (no src parent).
Every one of these patch("src.…") calls fails with ModuleNotFoundError: No module named 'src' when entered. Reproduced:
$ python3 -c "
import unittest.mock
p = unittest.mock.patch('src.secure_command_executor.execute_shell_command')
p.start() # raises ModuleNotFoundError: No module named 'src'
"Net effect:
- The patched function is never replaced, so the test exercises the real implementation.
- Tests that should fail when production code regresses pass anyway, because they're not actually substituting the dependency they claim to mock.
- CI doesn't catch the breakage because the
with patch(...)context-manager error happens inside the test body and surfaces only if the surrounding code exercises the patched name. Many of these tests pass coincidentally (the real function returns a value the assertion happens to accept).
Affected sites (48 total)
autobot-backend/secure_command_executor_test.py 3
autobot-backend/worker_node_test.py 1
autobot-backend/monitoring/performance_monitor_test.py 8
autobot-backend/performance_benchmarks.performance_test.py 5
autobot-backend/enhanced_security_layer_test.py 3
autobot-backend/monitoring/redis_prometheus_metrics_test.py 2
autobot-backend/utils/redis_thread_safety_test.py 4
autobot-backend/utils/file_locking_test.py 1
autobot-backend/knowledge/code_semantic_search_test.py 6
autobot-backend/user_management/services/user_service_test.py 2
autobot-backend/security/security_edge_cases_test.py 2
autobot-backend/security/encryption_service_test.py 2
autobot-backend/security/security_integration_test.py 2
autobot-backend/security/auth_rbac_test.py 3
autobot-backend/services/rag_integration_test.py 1
autobot-backend/config/config_migration.integration_test.py 3
(Full grep output in the issue thread — grep -rn 'patch("src\.\|patch(\\'src\.' autobot-backend --include="*_test.py").
Likely cause
Older code layout had autobot-backend/src/ as a package root; a refactor flattened the tree (now autobot-backend/secure_command_executor.py etc. directly importable) but the test mock paths weren't updated.
Fix
For each site, drop the src. prefix:
# before:
with patch("src.secure_command_executor.execute_shell_command") as mock_execute:
# after:
with patch("secure_command_executor.execute_shell_command") as mock_execute:For nested cases like src.utils.redis_client.get_redis_client, target the actual import path the file uses (utils.redis_client.get_redis_client or wherever the real from utils.redis_client import get_redis_client resolves through pytest's pythonpath).
Acceptance criteria
- All 48 sites updated to working module paths
- Each affected test verified to actually mock its target — temporarily make the patched function
raise RuntimeError('not mocked')and confirm tests pass (i.e. patches apply) - Add a pre-commit lint or pytest hook that flags
patch("src.…"patterns — prevents regression - CI green; no test that was passing on stale-mock-luck now fails (if any do, those are real regressions to address)
Severity
P1: tests can't catch regressions on the patched code paths. Security-critical files affected (enhanced_security_layer, auth_rbac, secure_command_executor, encryption_service).
Activity
fix(test/perf): migrate performance_benchmarks.performance_test.py of…
fix(test/perf): migrate performance_benchmarks.performance_test.py of…
fix(test/worker): unbreak src.* mock path in worker_node_test (#6987 …
fix(test/worker): unbreak src.* mock path in worker_node_test (#6987 …
fix(test/security): unbreak 3 src.* mock paths in enhanced_security_l…
fix(test/security): unbreak 3 src.* mock paths in enhanced_security_l…
mrveiss commentedon May 7, 2026
Progress update — 7 of 48 sites cleaned across 3 PRs
secure_command_executor_test.pySecurityPolicy.dangerous_patternsAPI rot (2 tests)worker_node_test.py{status,message,data}not unwrapped (2 tests)enhanced_security_layer_test.py11 files / 41 sites still pending. Per-file PRs is the right discipline — each file surfaces its own pre-existing rot when the mocks start firing for the first time. Round 12 confirmed: 7 sites fixed → 8 pre-existing tests started failing (3 distinct rot patterns).
Pre-commit hook follow-up
Filed as #7165 — AST-based check that flags
patch("src.*")patterns. Acceptance criteria from this issue's body item 4 is now its own concrete tracker.Sites remaining (per file)
(Adjusted:
performance_benchmarks5 of original 16 already done via #7131.)fix(tests): drop nonexistent 'src.' prefix from 43 mock paths (#6987)
fix(tests): drop nonexistent 'src.' prefix from 43 mock paths (#6987)
fix(tests): drop nonexistent 'src.' prefix from 43 mock paths (#6987) (…
11 remaining items
fix(test/worker): assert on envelope-wrapped result shape (#7154) (#7230
security(P1): fix 2 regressions + 2 test rots in EnhancedSecurityLayer (
security(P1): fix 2 regressions + 2 test rots in EnhancedSecurityLayer (
fix(tests): wrap async patch return_values with AsyncMock (#7216 — 77…
fix(tests): wrap async patch return_values with AsyncMock (#7216 — 77…
fix(tests): patch get_async_redis_client at consumer namespace + Asyn…
fix(tests): patch get_async_redis_client at consumer namespace + Asyn…
feat(tools/lint): pre-commit hook flagging patch("src.*") mock paths (c…
feat(tools/lint): pre-commit hook flagging patch("src.*") mock paths (c…
fix(test/utils): patch event_manager.get_event_manager (lazy_singleto…
fix(test/notif): migrate to canonical async-redis fixture + fix wrong…
fix(test/notif): migrate to canonical async-redis fixture + fix wrong…
fix(test/skills): migrate LLMInterface patches to get_llm_service fac…
fix(test/skills): migrate LLMInterface patches to get_llm_service fac…
feat(tools/lint): broaden check_no_src_mock_path with runtime resolut…