mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-09-09 21:49:37 +00:00
fix(tests): preload sandbox leaf modules before mocking their parent package (#5215)
TestBashExecutionHarvest's shell-persistence tests report
shell_persistent=None whenever deerflow.sandbox.overwrite is not already
cached in sys.modules. _setup_executor_classes replaces the
"deerflow.sandbox" parent package with a MagicMock, so a later
`from deerflow.sandbox.overwrite import unwrap_sandbox` inside
_harvest_shell_persistence can no longer locate the submodule through
the mocked parent ("'deerflow.sandbox' is not a package") when the leaf
module is not already in sys.modules. The helper's
`except Exception: return None` silently converts that ImportError into
an UNKNOWN provenance stamp.
Whether the leaf module was cached depended on which tests ran earlier
in the session, making the outcome order-dependent: green in CI by
collection-order luck, red when the module runs alone or first.
Fix it the same way the fixture already handles audit_context and
tool_search: preload the real leaf modules (deerflow.sandbox.sandbox_provider
and deerflow.sandbox.overwrite) before installing the mocked parent
package, pin them in sys.modules for the duration of the test, and
restore the previous state afterwards.
This commit is contained in:
parent
090c92a4e3
commit
18b34298cc
@ -85,12 +85,16 @@ def _setup_executor_classes():
|
||||
original_executor = sys.modules.get("deerflow.subagents.executor")
|
||||
original_audit_context = sys.modules.get("deerflow.agents.middlewares.audit_context")
|
||||
original_tool_search = sys.modules.get("deerflow.tools.builtins.tool_search")
|
||||
original_sandbox_provider = sys.modules.get("deerflow.sandbox.sandbox_provider")
|
||||
original_sandbox_overwrite = sys.modules.get("deerflow.sandbox.overwrite")
|
||||
|
||||
# Preload real executor dependencies before replacing their parent packages
|
||||
# with cycle-breaking test doubles. Keeping the concrete leaf modules in
|
||||
# sys.modules makes this fixture independent of test collection order.
|
||||
audit_context_module = importlib.import_module("deerflow.agents.middlewares.audit_context")
|
||||
tool_search_module = importlib.import_module("deerflow.tools.builtins.tool_search")
|
||||
sandbox_provider_module = importlib.import_module("deerflow.sandbox.sandbox_provider")
|
||||
sandbox_overwrite_module = importlib.import_module("deerflow.sandbox.overwrite")
|
||||
|
||||
# Remove mocked executor if exists (from conftest.py)
|
||||
if "deerflow.subagents.executor" in sys.modules:
|
||||
@ -106,6 +110,8 @@ def _setup_executor_classes():
|
||||
sys.modules["deerflow.skills.storage"] = storage_module
|
||||
sys.modules["deerflow.agents.middlewares.audit_context"] = audit_context_module
|
||||
sys.modules["deerflow.tools.builtins.tool_search"] = tool_search_module
|
||||
sys.modules["deerflow.sandbox.sandbox_provider"] = sandbox_provider_module
|
||||
sys.modules["deerflow.sandbox.overwrite"] = sandbox_overwrite_module
|
||||
|
||||
# Import real classes inside fixture
|
||||
from langchain_core.messages import AIMessage, HumanMessage, ToolMessage
|
||||
@ -158,6 +164,14 @@ def _setup_executor_classes():
|
||||
sys.modules["deerflow.tools.builtins.tool_search"] = original_tool_search
|
||||
else:
|
||||
sys.modules.pop("deerflow.tools.builtins.tool_search", None)
|
||||
if original_sandbox_provider is not None:
|
||||
sys.modules["deerflow.sandbox.sandbox_provider"] = original_sandbox_provider
|
||||
else:
|
||||
sys.modules.pop("deerflow.sandbox.sandbox_provider", None)
|
||||
if original_sandbox_overwrite is not None:
|
||||
sys.modules["deerflow.sandbox.overwrite"] = original_sandbox_overwrite
|
||||
else:
|
||||
sys.modules.pop("deerflow.sandbox.overwrite", None)
|
||||
|
||||
|
||||
# Helper classes that wrap real classes for testing
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user