mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-10-26 21:26:39 +00:00
* test: fix five Windows-host failures across sandbox, read_file, lark shim, and extension checks Windows dev hosts currently fail five backend test cases that CI (ubuntu) never exercises: - test_local_sandbox_command_timeout: the fixture forces a bare /bin/sh shell and the Windows dispatch spawns it directly (WinError 2), and make(1) is not a given on Windows. Stub both runners; the contract under test is the timeout marker assembly, not the runner. - test_local_sandbox_provider_mounts: the Popen-capture mock delegated to the real spawn, which cannot execute a POSIX shell path on Windows. Capture at the runner seam instead and assert the rewritten path shape-agnostically (the Windows runners pass the command string, not a [shell, -c, command] list). - test_read_file_tool_binary: text-mode write_text leaks CRLF into the fixture on Windows; write the mount fixture as bytes (#6042 follow-up). - test_lark_shim_atomic: skip the exact 0o755/0o644 assertions on Windows hosts, whose stat mode approximates POSIX bits (#6257 pattern). - test_extension_check_script: zipfile normalizes os.sep in entry names on Windows reads, so a writestr-built fixture can never carry a verbatim backslash entry there. Inject the hostile name into namelist unless the archive already stores it, pinning the guard contract identically. On a Windows 11 host these five files go from five failed cases to green (102 passed, ruff check/format clean). Two more Windows-host failures (skill-review NUL probe, jina shared-deadline classification) need deeper root-causing and are left for follow-ups. * test(skill-review): review the committed skill tree, not local residue The video-generation review test scans the live directory, so untracked build residue inside skills/public/video-generation fails it: once bytecode caching drops a scripts/__pycache__ directory into the tree (importing the skill script writes one), skillscan's package-undecodable-script finding is correct and the test can never pass again until the residue is deleted by hand. Reproduced on Windows: a planted scripts/__pycache__ pyc fails the test; deleting it makes it pass. - Materialize the tracked skill tree (git ls-files) into a temp dir and review that, so the test reviews exactly the committed package. - tests/skills/skill_loader.py disables bytecode caching around exec_module, so the root skill suite stops polluting the committed tree. Follows up on #6786 (item 6). * docs(test): state the argv-list contract on both sandbox runners The Windows dispatch also passes the resolved command as an argv list, so the string fallback was unreachable on every platform. --------- Co-authored-by: xiaodu55 <xiaodu55@users.noreply.github.com>
50 lines
1.7 KiB
Python
50 lines
1.7 KiB
Python
"""Load a skill's scripts/generate.py as an importable module, by file path.
|
|
|
|
Skills live in skills/public/<name>/scripts/generate.py and are NOT a package,
|
|
so tests load them via importlib. Tests then mock the module's `requests`.
|
|
"""
|
|
|
|
import importlib.util
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import requests
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
|
|
def load(skill_name: str):
|
|
"""Return the generate.py module for skills/public/<skill_name>."""
|
|
path = REPO_ROOT / "skills" / "public" / skill_name / "scripts" / "generate.py"
|
|
mod_name = skill_name.replace("-", "_") + "_generate"
|
|
spec = importlib.util.spec_from_file_location(mod_name, path)
|
|
module = importlib.util.module_from_spec(spec)
|
|
sys.modules[mod_name] = module # standard pattern; lets the module resolve itself
|
|
# Bytecode caching would drop a scripts/__pycache__ directory into the
|
|
# committed skill tree, and the skill review scans the live directory, so
|
|
# local runs would permanently fail the package review with a
|
|
# package-undecodable-script finding on the .pyc.
|
|
previous_dont_write_bytecode = sys.dont_write_bytecode
|
|
sys.dont_write_bytecode = True
|
|
try:
|
|
spec.loader.exec_module(module)
|
|
finally:
|
|
sys.dont_write_bytecode = previous_dont_write_bytecode
|
|
return module
|
|
|
|
|
|
class FakeResp:
|
|
"""Minimal stand-in for requests.Response."""
|
|
|
|
def __init__(self, json_data=None, content=b"", status_code=200):
|
|
self._json = json_data if json_data is not None else {}
|
|
self.content = content
|
|
self.status_code = status_code
|
|
|
|
def raise_for_status(self):
|
|
if self.status_code >= 400:
|
|
raise requests.HTTPError(f"HTTP {self.status_code}")
|
|
|
|
def json(self):
|
|
return self._json
|