Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions .github/actions/rust-build-release/src/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

import json
import os
import shutil
import subprocess
import typing as typ
Expand All @@ -15,6 +16,7 @@

CROSS_CONTAINER_ERROR_CODES = {125, 126, 127}
DEFAULT_HOST_TARGET = "x86_64-unknown-linux-gnu"
PROBE_TIMEOUT = int(os.environ.get("RUNTIME_PROBE_TIMEOUT", "10"))


def runtime_available(name: str, *, cwd: str | Path | None = None) -> bool:
Expand All @@ -33,7 +35,7 @@ def runtime_available(name: str, *, cwd: str | Path | None = None) -> bool:
allowed_names=(name, f"{name}.exe"),
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
timeout=10,
timeout=PROBE_TIMEOUT,
cwd=cwd,
)
except (OSError, subprocess.TimeoutExpired):
Expand All @@ -51,7 +53,7 @@ def runtime_available(name: str, *, cwd: str | Path | None = None) -> bool:
capture_output=True,
text=True,
check=True,
timeout=10,
timeout=PROBE_TIMEOUT,
cwd=cwd,
)
except (OSError, subprocess.CalledProcessError, subprocess.TimeoutExpired):
Expand Down Expand Up @@ -102,8 +104,13 @@ def detect_host_target(
capture_output=True,
text=True,
check=True,
timeout=PROBE_TIMEOUT,
)
except (FileNotFoundError, subprocess.CalledProcessError, OSError):
except (
subprocess.CalledProcessError,
subprocess.TimeoutExpired,
Comment thread
leynos marked this conversation as resolved.
OSError,
):
return default

triple = next(
Expand Down
70 changes: 68 additions & 2 deletions .github/actions/rust-build-release/tests/test_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def fake_run(
) -> subprocess.CompletedProcess[str]:
_ = allowed_names
cmd = [executable, *args]
raise subprocess.TimeoutExpired(cmd, 10)
raise subprocess.TimeoutExpired(cmd, runtime_module.PROBE_TIMEOUT)

harness.monkeypatch.setattr(runtime_module, "run_validated", fake_run)

Expand Down Expand Up @@ -146,7 +146,7 @@ def fake_run(
_ = (allowed_names, capture_output, check, text)
cmd = [executable, *args]
if "--format" in args:
raise subprocess.TimeoutExpired(cmd, 10)
raise subprocess.TimeoutExpired(cmd, runtime_module.PROBE_TIMEOUT)
return subprocess.CompletedProcess(cmd, 0, stdout="")

harness.monkeypatch.setattr(runtime_module, "run_validated", fake_run)
Expand Down Expand Up @@ -189,3 +189,69 @@ def fake_run(

harness.monkeypatch.setattr(runtime_module, "run_validated", fake_run)
assert runtime_module.detect_host_target() == "custom-triple"


def test_detect_host_target_returns_default_on_timeout(
runtime_module: ModuleType, module_harness: HarnessFactory
) -> None:
"""Falls back to the default triple when rustc probing times out."""
harness = module_harness(runtime_module)
harness.patch_shutil_which(
lambda name: "/usr/bin/rustc" if name == "rustc" else None
)
harness.patch_attr("ensure_allowed_executable", lambda path, allowed: path)

def fake_run(
executable: str,
args: list[str],
*,
allowed_names: tuple[str, ...],
**_: object,
) -> subprocess.CompletedProcess[str]:
_ = (executable, args, allowed_names)
raise subprocess.TimeoutExpired(
[executable, *args], runtime_module.PROBE_TIMEOUT
)

harness.monkeypatch.setattr(runtime_module, "run_validated", fake_run)

assert (
runtime_module.detect_host_target(default="fallback-triple")
== "fallback-triple"
)


def test_detect_host_target_passes_timeout_to_run_validated(
runtime_module: ModuleType, module_harness: HarnessFactory
) -> None:
"""Ensures rustc probing is bounded via the timeout parameter."""
harness = module_harness(runtime_module)
harness.patch_shutil_which(
lambda name: "/usr/bin/rustc" if name == "rustc" else None
)
harness.patch_attr("ensure_allowed_executable", lambda path, allowed: path)

call_kwargs: dict[str, object] = {}

def fake_run(
executable: str,
args: list[str],
*,
allowed_names: tuple[str, ...],
**kwargs: object,
) -> subprocess.CompletedProcess[str]:
_ = (executable, args)
call_kwargs.update(kwargs)
call_kwargs["allowed_names"] = allowed_names
return subprocess.CompletedProcess(
[executable, *args], 0, stdout="host: bounded\n"
)

harness.monkeypatch.setattr(runtime_module, "run_validated", fake_run)

assert runtime_module.detect_host_target() == "bounded"
assert call_kwargs.get("timeout") == runtime_module.PROBE_TIMEOUT
assert call_kwargs.get("capture_output") is True
assert call_kwargs.get("text") is True
assert call_kwargs.get("check") is True
assert call_kwargs.get("allowed_names") == ("rustc", "rustc.exe")
3 changes: 2 additions & 1 deletion .github/actions/setup-windows-gnu/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ runs:
Remove-Item $destination -Recurse -Force
}
Expand-Archive $archive -DestinationPath $destination -Force
$binPath = Join-Path $destination "llvm-mingw-$version-ucrt-x86_64\bin"
$toolRoot = Join-Path $destination "llvm-mingw-$version-ucrt-x86_64"
$binPath = Join-Path $toolRoot "bin"
if (-not (Test-Path $binPath)) {
throw "llvm-mingw bin directory not found at $binPath"
}
Expand Down
Loading