mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-09-16 17:46:20 +00:00
test(mounts): compare host paths separator-agnostically in provisioner and mount suites (#5413)
* test(mounts): compare host paths separator-agnostically in provisioner and mount suites The provisioner deliberately preserves host filesystem style (join_host_path keeps native separators and os.path.normpath re-spells POSIX inputs on Windows), and the docker --mount args and review-CLI PYTHONPATH inherit that spelling. Six assertions across test_provisioner_pvc_volumes, test_three_way_skills_mount_e2e and test_review_changed_public_skills compared those strings against POSIX-style literals, so they fail on Windows hosts while passing on Linux CI. Normalize the host-native side before comparing; the replace is a no-op on POSIX, so CI expectations are unchanged. * test(mounts): share the host-path normalization helper Both review suggestions: define posix_path once in backend/tests/_host_path_helpers.py (matching the existing _xxx_helpers convention) instead of three spellings across suites, and wrap the last raw hostPath assertion (test_hostpath_userdata_includes_thread_id) so the whole provisioner class stays separator-agnostic.
This commit is contained in:
parent
9861c296d4
commit
daf32cd246
14
backend/tests/_host_path_helpers.py
Normal file
14
backend/tests/_host_path_helpers.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
"""Helpers for asserting on paths the codebase spells in host-native style.
|
||||||
|
|
||||||
|
The provisioner's ``join_host_path`` deliberately preserves the host
|
||||||
|
filesystem style (explicit ``PureWindowsPath`` branch), and
|
||||||
|
``os.path.normpath`` re-spells POSIX inputs with backslashes on Windows, so
|
||||||
|
hostPath volume strings, docker ``--mount`` args and ``PYTHONPATH`` entries
|
||||||
|
carry ``\\`` on a Windows host where POSIX CI sees ``/``. Tests that match
|
||||||
|
segments inside such strings normalize with :func:`posix_path` instead of
|
||||||
|
hard-coding one separator; the replace is a no-op on POSIX inputs.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def posix_path(path: str) -> str:
|
||||||
|
return path.replace("\\", "/")
|
||||||
@ -1,6 +1,7 @@
|
|||||||
"""Regression tests for provisioner three-way skills + PVC volume support."""
|
"""Regression tests for provisioner three-way skills + PVC volume support."""
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from _host_path_helpers import posix_path
|
||||||
|
|
||||||
|
|
||||||
def _thread_skill_mounts(
|
def _thread_skill_mounts(
|
||||||
@ -39,7 +40,7 @@ class TestBuildVolumes:
|
|||||||
pub = volumes[0]
|
pub = volumes[0]
|
||||||
assert pub.name == "skills-public"
|
assert pub.name == "skills-public"
|
||||||
assert pub.host_path is not None
|
assert pub.host_path is not None
|
||||||
assert pub.host_path.path.endswith("/skills_view/public")
|
assert posix_path(pub.host_path.path).endswith("/skills_view/public")
|
||||||
assert pub.host_path.type == "Directory"
|
assert pub.host_path.type == "Directory"
|
||||||
assert pub.persistent_volume_claim is None
|
assert pub.persistent_volume_claim is None
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ class TestBuildVolumes:
|
|||||||
custom = volumes[1]
|
custom = volumes[1]
|
||||||
assert custom.name == "skills-custom"
|
assert custom.name == "skills-custom"
|
||||||
assert custom.host_path is not None
|
assert custom.host_path is not None
|
||||||
assert "users/user-7/skills_view/custom" in custom.host_path.path
|
assert "users/user-7/skills_view/custom" in posix_path(custom.host_path.path)
|
||||||
assert custom.host_path.type == "Directory"
|
assert custom.host_path.type == "Directory"
|
||||||
|
|
||||||
def test_hostpath_skills_legacy_volume(self, provisioner_module):
|
def test_hostpath_skills_legacy_volume(self, provisioner_module):
|
||||||
@ -63,7 +64,7 @@ class TestBuildVolumes:
|
|||||||
legacy = volumes[2]
|
legacy = volumes[2]
|
||||||
assert legacy.name == "skills-legacy"
|
assert legacy.name == "skills-legacy"
|
||||||
assert legacy.host_path is not None
|
assert legacy.host_path is not None
|
||||||
assert "users/default/skills_view/legacy" in legacy.host_path.path
|
assert "users/default/skills_view/legacy" in posix_path(legacy.host_path.path)
|
||||||
assert legacy.host_path.type == "Directory"
|
assert legacy.host_path.type == "Directory"
|
||||||
|
|
||||||
def test_hostpath_without_legacy_flag_still_has_empty_capable_mount(self, provisioner_module):
|
def test_hostpath_without_legacy_flag_still_has_empty_capable_mount(self, provisioner_module):
|
||||||
@ -82,7 +83,7 @@ class TestBuildVolumes:
|
|||||||
provisioner_module.USERDATA_PVC_NAME = ""
|
provisioner_module.USERDATA_PVC_NAME = ""
|
||||||
volumes = provisioner_module._build_volumes("my-thread-42")
|
volumes = provisioner_module._build_volumes("my-thread-42")
|
||||||
userdata_vol = volumes[-1]
|
userdata_vol = volumes[-1]
|
||||||
path = userdata_vol.host_path.path
|
path = posix_path(userdata_vol.host_path.path)
|
||||||
assert "my-thread-42" in path
|
assert "my-thread-42" in path
|
||||||
assert path.endswith("user-data")
|
assert path.endswith("user-data")
|
||||||
assert userdata_vol.host_path.type == "DirectoryOrCreate"
|
assert userdata_vol.host_path.type == "DirectoryOrCreate"
|
||||||
@ -149,7 +150,7 @@ class TestBuildVolumes:
|
|||||||
assert len(volumes) == 5
|
assert len(volumes) == 5
|
||||||
extra_vol = volumes[-1]
|
extra_vol = volumes[-1]
|
||||||
assert extra_vol.name == "extra-0"
|
assert extra_vol.name == "extra-0"
|
||||||
assert extra_vol.host_path.path == "/state/users/alice/integrations/lark-cli/config"
|
assert posix_path(extra_vol.host_path.path) == "/state/users/alice/integrations/lark-cli/config"
|
||||||
assert extra_vol.host_path.type == "DirectoryOrCreate"
|
assert extra_vol.host_path.type == "DirectoryOrCreate"
|
||||||
|
|
||||||
def test_extra_mount_uses_userdata_pvc_when_configured(self, provisioner_module):
|
def test_extra_mount_uses_userdata_pvc_when_configured(self, provisioner_module):
|
||||||
|
|||||||
@ -5,6 +5,7 @@ from pathlib import Path, PurePosixPath
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import review_changed_public_skills as runner
|
import review_changed_public_skills as runner
|
||||||
|
from _host_path_helpers import posix_path
|
||||||
from skill_review_waivers import EMPTY_MANIFEST, WaiverManifest
|
from skill_review_waivers import EMPTY_MANIFEST, WaiverManifest
|
||||||
|
|
||||||
|
|
||||||
@ -302,7 +303,7 @@ def test_main_exits_nonzero_when_review_cli_reports_error(tmp_path: Path, monkey
|
|||||||
"never",
|
"never",
|
||||||
]
|
]
|
||||||
assert kwargs["cwd"] == tmp_path
|
assert kwargs["cwd"] == tmp_path
|
||||||
assert "backend/packages/harness" in kwargs["env"]["PYTHONPATH"]
|
assert "backend/packages/harness" in posix_path(kwargs["env"]["PYTHONPATH"])
|
||||||
assert kwargs["capture_output"] is True
|
assert kwargs["capture_output"] is True
|
||||||
assert kwargs["text"] is True
|
assert kwargs["text"] is True
|
||||||
assert kwargs["check"] is False
|
assert kwargs["check"] is False
|
||||||
|
|||||||
@ -15,6 +15,7 @@ from types import SimpleNamespace
|
|||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from _host_path_helpers import posix_path
|
||||||
|
|
||||||
from deerflow.config.extensions_config import ExtensionsConfig, SkillStateConfig
|
from deerflow.config.extensions_config import ExtensionsConfig, SkillStateConfig
|
||||||
from deerflow.config.paths import Paths
|
from deerflow.config.paths import Paths
|
||||||
@ -602,11 +603,11 @@ class TestThreeWayMountEndToEnd:
|
|||||||
|
|
||||||
assert "/mnt/skills/custom" in mount_entries
|
assert "/mnt/skills/custom" in mount_entries
|
||||||
assert "dst=/mnt/skills/custom" in mount_entries["/mnt/skills/custom"]
|
assert "dst=/mnt/skills/custom" in mount_entries["/mnt/skills/custom"]
|
||||||
assert "users/noob/skills_view/custom" in mount_entries["/mnt/skills/custom"]
|
assert "users/noob/skills_view/custom" in posix_path(mount_entries["/mnt/skills/custom"])
|
||||||
|
|
||||||
assert "/mnt/skills/integrations" in mount_entries
|
assert "/mnt/skills/integrations" in mount_entries
|
||||||
assert "dst=/mnt/skills/integrations" in mount_entries["/mnt/skills/integrations"]
|
assert "dst=/mnt/skills/integrations" in mount_entries["/mnt/skills/integrations"]
|
||||||
assert "users/noob/skills_view/integrations" in mount_entries["/mnt/skills/integrations"]
|
assert "users/noob/skills_view/integrations" in posix_path(mount_entries["/mnt/skills/integrations"])
|
||||||
|
|
||||||
# noob has no per-user custom → legacy is mounted
|
# noob has no per-user custom → legacy is mounted
|
||||||
assert "/mnt/skills/legacy" in mount_entries
|
assert "/mnt/skills/legacy" in mount_entries
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user