Files
agentic-mobile-control/tests/test_workspace_packaging.py
T
q792602257 8f74eac50c
Tests / Test passed: 545
Jenkins
2026-07-13 16:11:40 +08:00

69 lines
2.2 KiB
Python

from __future__ import annotations
import ast
import re
import tomllib
from importlib.metadata import packages_distributions
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parent.parent
RUNTIME_PACKAGE_DIRS = (
"agents",
"api",
"core",
"device",
"driver",
"perception",
"runtime",
"semantic",
"skills_learning",
"storage",
"tools",
"workflow",
"world",
)
def test_workspace_distributions_own_expected_import_packages() -> None:
distributions = packages_distributions()
assert set(distributions.get("cloud", ())) == {"device-cloud-platform"}
assert set(distributions.get("core", ())) == {"device-agent-runtime"}
assert set(distributions.get("runtime", ())) == {"device-agent-runtime"}
def test_runtime_project_does_not_declare_cloud_distribution() -> None:
project = tomllib.loads((PROJECT_ROOT / "pyproject.toml").read_text("utf-8"))
dependencies = {
_requirement_name(requirement)
for requirement in project["project"].get("dependencies", [])
}
package_patterns = project["tool"]["setuptools"]["packages"]["find"]["include"]
assert "device-cloud-platform" not in dependencies
assert "cloud*" not in package_patterns
def test_runtime_source_does_not_import_cloud() -> None:
offenders: list[str] = []
for package_dir in RUNTIME_PACKAGE_DIRS:
for path in (PROJECT_ROOT / package_dir).rglob("*.py"):
tree = ast.parse(path.read_text("utf-8"), filename=str(path))
for node in ast.walk(tree):
if isinstance(node, ast.Import):
names = [alias.name for alias in node.names]
elif isinstance(node, ast.ImportFrom) and node.module:
names = [node.module]
else:
continue
if any(name == "cloud" or name.startswith("cloud.") for name in names):
offenders.append(str(path.relative_to(PROJECT_ROOT)))
assert not offenders, f"runtime distribution imports cloud: {sorted(set(offenders))}"
def _requirement_name(requirement: str) -> str:
name = re.split(r"[\s<>=!~\[]", requirement, maxsplit=1)[0]
return name.lower().replace("_", "-")