fix(tester): use remote artifact path for installs
This commit is contained in:
@@ -219,6 +219,28 @@ def validate_preflight_matrix(root: Path, config_path: Path, bindings: dict[str,
|
|||||||
raise EnvironmentFailure(f"{platform} 绑定到 {expected_node},必须使用 contract runner;禁止在协调节点执行")
|
raise EnvironmentFailure(f"{platform} 绑定到 {expected_node},必须使用 contract runner;禁止在协调节点执行")
|
||||||
|
|
||||||
|
|
||||||
|
def preflight_remote_artifacts(config_path: Path, requested: list[str]) -> dict[str, str]:
|
||||||
|
"""Return caller-declared artifact paths readable by remote tester nodes."""
|
||||||
|
try:
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
raw = yaml.safe_load(config_path.read_text(encoding="utf-8")) or {}
|
||||||
|
except (OSError, ValueError, ImportError) as exc:
|
||||||
|
raise EnvironmentFailure(f"无法读取 preflight matrix: {config_path}: {exc}") from exc
|
||||||
|
rows = raw.get("matrix") if isinstance(raw, dict) else None
|
||||||
|
if not isinstance(rows, list):
|
||||||
|
raise EnvironmentFailure("preflight matrix 缺少 matrix;不能解析远程产物路径")
|
||||||
|
by_platform = {str(row.get("platform", "")).lower(): row for row in rows if isinstance(row, dict)}
|
||||||
|
paths: dict[str, str] = {}
|
||||||
|
for platform in requested:
|
||||||
|
row = by_platform.get(platform) or {}
|
||||||
|
artifact = row.get("artifact") if isinstance(row, dict) else None
|
||||||
|
remote_path = artifact.get("remote_path") if isinstance(artifact, dict) else None
|
||||||
|
if isinstance(remote_path, str) and remote_path.strip():
|
||||||
|
paths[platform] = remote_path.strip()
|
||||||
|
return paths
|
||||||
|
|
||||||
|
|
||||||
def local_path(locator: str) -> Path | None:
|
def local_path(locator: str) -> Path | None:
|
||||||
parsed = urllib.parse.urlsplit(locator)
|
parsed = urllib.parse.urlsplit(locator)
|
||||||
if parsed.scheme in ("http", "https"):
|
if parsed.scheme in ("http", "https"):
|
||||||
@@ -551,6 +573,7 @@ def execute(args: argparse.Namespace) -> int:
|
|||||||
"product_test": {"status": "not-run", "failure_class": "automatic-repair-failed", "note": "准备完成后由 tester catalog 驱动真实移动 session;本工具不以 API 替代移动测试"},
|
"product_test": {"status": "not-run", "failure_class": "automatic-repair-failed", "note": "准备完成后由 tester catalog 驱动真实移动 session;本工具不以 API 替代移动测试"},
|
||||||
"platforms": {},
|
"platforms": {},
|
||||||
}
|
}
|
||||||
|
remote_artifacts: dict[str, str] = {}
|
||||||
try:
|
try:
|
||||||
locators = parse_artifacts(args.artifacts)
|
locators = parse_artifacts(args.artifacts)
|
||||||
missing = [platform for platform in requested if platform not in locators]
|
missing = [platform for platform in requested if platform not in locators]
|
||||||
@@ -596,6 +619,7 @@ def execute(args: argparse.Namespace) -> int:
|
|||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
validate_preflight_matrix(context.root, preflight_config, bindings, requested)
|
validate_preflight_matrix(context.root, preflight_config, bindings, requested)
|
||||||
|
remote_artifacts = preflight_remote_artifacts(preflight_config, requested)
|
||||||
preflight_result = run_test_preflight(
|
preflight_result = run_test_preflight(
|
||||||
preflight_config,
|
preflight_config,
|
||||||
mode=args.preflight_mode,
|
mode=args.preflight_mode,
|
||||||
@@ -676,15 +700,17 @@ def execute(args: argparse.Namespace) -> int:
|
|||||||
})
|
})
|
||||||
if network.get("status") != "ready":
|
if network.get("status") != "ready":
|
||||||
raise EnvironmentFailure(str(network.get("observed") or network))
|
raise EnvironmentFailure(str(network.get("observed") or network))
|
||||||
artifact_path = Path(result["artifact"]["path"])
|
artifact_path = result["artifact"]["path"]
|
||||||
if platform == "ios" and node_name != "local":
|
if node_name != "local":
|
||||||
raise EnvironmentFailure("远程 iOS 安装必须在 matrix.artifact.remote_path 声明 Mac 可读产物;不能把协调机路径当成 Mac 路径")
|
artifact_path = remote_artifacts.get(platform, "")
|
||||||
|
if not artifact_path:
|
||||||
|
raise EnvironmentFailure(f"远程 {platform} 安装必须在 matrix.artifact.remote_path 声明节点可读产物")
|
||||||
installed = agent_runner(context.root, {
|
installed = agent_runner(context.root, {
|
||||||
"operation": "install",
|
"operation": "install",
|
||||||
"platform": platform,
|
"platform": platform,
|
||||||
"node": node_name,
|
"node": node_name,
|
||||||
"binding": binding_id,
|
"binding": binding_id,
|
||||||
"artifact": str(artifact_path),
|
"artifact": artifact_path,
|
||||||
"identity": identity,
|
"identity": identity,
|
||||||
})
|
})
|
||||||
if installed.get("status") != "ready":
|
if installed.get("status") != "ready":
|
||||||
|
|||||||
@@ -116,6 +116,18 @@ matrix:
|
|||||||
["android", "ios"],
|
["android", "ios"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_remote_artifact_path_comes_from_preflight_matrix(self):
|
||||||
|
with tempfile.TemporaryDirectory() as temp:
|
||||||
|
config = Path(temp) / "matrix.yaml"
|
||||||
|
config.write_text(
|
||||||
|
"matrix:\n - platform: ios\n artifact:\n remote_path: /Users/tester/app.ipa\n",
|
||||||
|
encoding="utf-8",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
bundle.preflight_remote_artifacts(config, ["ios"]),
|
||||||
|
{"ios": "/Users/tester/app.ipa"},
|
||||||
|
)
|
||||||
|
|
||||||
def test_new_worktree_each_run(self):
|
def test_new_worktree_each_run(self):
|
||||||
with tempfile.TemporaryDirectory() as temp:
|
with tempfile.TemporaryDirectory() as temp:
|
||||||
repo, worktrees = Path(temp) / "repo", Path(temp) / "worktrees"
|
repo, worktrees = Path(temp) / "repo", Path(temp) / "worktrees"
|
||||||
|
|||||||
Reference in New Issue
Block a user