Files
2026-07-13 13:12:33 +08:00

180 lines
6.9 KiB
Python

import subprocess
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
RELEASE_PS1 = ROOT / "install.ps1"
RELEASE_SH = ROOT / "install.sh"
SOURCE_PS1 = ROOT / "scripts" / "install_source.ps1"
SOURCE_SH = ROOT / "scripts" / "install_source.sh"
CURRENT_RELEASE_TAG = "v0.5.0rc3"
def test_source_install_scripts_force_refresh_local_uv_tool_package() -> None:
ps1 = SOURCE_PS1.read_text(encoding="utf-8")
sh = SOURCE_SH.read_text(encoding="utf-8")
assert "'--force', '--reinstall-package', 'opensquilla'" in ps1
assert "--force --reinstall-package opensquilla" in sh
def test_install_scripts_do_not_run_onboarding_or_gateway() -> None:
scripts = [
RELEASE_PS1.read_text(encoding="utf-8"),
RELEASE_SH.read_text(encoding="utf-8"),
SOURCE_PS1.read_text(encoding="utf-8"),
SOURCE_SH.read_text(encoding="utf-8"),
]
for script in scripts:
assert "onboard --if-needed" not in script
assert "& opensquilla onboard" not in script
assert "& opensquilla gateway run" not in script
assert '"opensquilla onboard"' not in script
assert '"opensquilla gateway run"' not in script
def test_release_installers_install_version_pinned_wheel_with_uv() -> None:
ps1 = RELEASE_PS1.read_text(encoding="utf-8")
sh = RELEASE_SH.read_text(encoding="utf-8")
for script in (ps1, sh):
assert CURRENT_RELEASE_TAG in script
assert "opensquilla-$releaseVersion-py3-none-any.whl" in script or (
"opensquilla-${release_version}-py3-none-any.whl" in script
)
assert "opensquilla-latest-py3-none-any.whl" not in script
assert "releases/latest/download" not in script
assert "--python" in script
assert "--force" in script
assert "--reinstall-package" in script
assert "recommended" in script
assert "https://astral.sh/uv/install" in script
assert "Next steps:" in script
def test_release_installer_rejects_non_release_selectors() -> None:
ps1 = RELEASE_PS1.read_text(encoding="utf-8")
if not sys.platform.startswith("win"):
result = subprocess.run(
["bash", "install.sh", "--version", "main"],
capture_output=True,
check=False,
text=True,
)
assert result.returncode != 0
assert "only supports latest, stable, or release versions" in result.stderr
assert "scripts/install_source.sh" in result.stderr
assert "only supports latest, stable, or release versions" in ps1
assert "scripts/install_source.ps1" in ps1
def test_windows_installer_stops_when_native_install_command_fails() -> None:
ps1 = SOURCE_PS1.read_text(encoding="utf-8")
assert 'if ($LASTEXITCODE -ne 0) {' in ps1
assert "install_source.ps1: install command failed with exit code $LASTEXITCODE." in ps1
assert (
"Close any running OpenSquilla gateway or shell using the existing "
"tool environment, then retry."
in ps1
)
assert "exit $LASTEXITCODE" in ps1
def test_install_script_banners_are_ascii_for_windows_terminals() -> None:
scripts = [
RELEASE_PS1.read_text(encoding="utf-8"),
RELEASE_SH.read_text(encoding="utf-8"),
SOURCE_PS1.read_text(encoding="utf-8"),
SOURCE_SH.read_text(encoding="utf-8"),
]
for script in scripts:
assert "OpenSquilla installed" in script
assert "----" in script
assert "→" not in script
assert "─" not in script
assert "⚠" not in script
def test_install_scripts_support_optional_extras() -> None:
scripts = [
RELEASE_PS1.read_text(encoding="utf-8"),
RELEASE_SH.read_text(encoding="utf-8"),
SOURCE_PS1.read_text(encoding="utf-8"),
SOURCE_SH.read_text(encoding="utf-8"),
]
for script in scripts:
assert "OPENSQUILLA_INSTALL_EXTRAS" in script
for legacy_extra in ("feishu", "telegram", "dingtalk", "wecom", "qq"):
assert legacy_extra not in script
assert "matrix" in script
assert "matrix-e2e" in script
assert "document-extras" in script
assert "msteams" not in script
def test_windows_installer_bootstraps_vc_redist_for_router_runtime() -> None:
scripts = [
RELEASE_PS1.read_text(encoding="utf-8"),
SOURCE_PS1.read_text(encoding="utf-8"),
]
for ps1 in scripts:
assert "Install-WindowsVCRedistIfNeeded" in ps1
assert "OPENSQUILLA_SKIP_VC_REDIST" in ps1
assert "Microsoft.VCRedist.2015+.x64" in ps1
assert "https://aka.ms/vs/17/release/vc_redist.x64.exe" in ps1
assert "safe router fallback" in ps1
assert "If automatic installation fails, install it manually" in ps1
assert "After installing, reopen PowerShell and restart OpenSquilla" in ps1
def test_source_install_pins_python_312_and_refuses_below() -> None:
sh = SOURCE_SH.read_text(encoding="utf-8")
ps1 = SOURCE_PS1.read_text(encoding="utf-8")
# uv provisions a known-good 3.12, never the ambient interpreter
assert "--python 3.12" in sh
assert "'--python', '3.12'" in ps1
# the pip fallback refuses to install on python < 3.12 (no silent broken install)
assert "sys.version_info >= (3, 12)" in sh
assert "astral.sh/uv/install.sh" in sh
# Windows pip fallback also gated; self-check targets code-task, not just --version
assert "sys.version_info >= (3, 12)" in ps1
assert "code-task --help" in sh
def test_windows_installer_verifies_entry_point_is_on_path() -> None:
# Regression for #500: install_source.ps1 used to succeed silently and
# leave `opensquilla` unresolvable on a fresh Windows host, because uv
# drops entry points in ~/.local/bin (not on PATH by default). The POSIX
# installer already smoke-checks this; the PowerShell installer must
# reach parity by locating the entry point and warning when its dir is
# not on PATH.
ps1 = SOURCE_PS1.read_text(encoding="utf-8")
assert "function Resolve-EntrypointDir" in ps1
assert "function Test-DirOnUserPath" in ps1
assert "function Write-PathHint" in ps1
# Invoked after a real install (dry-run exits before this point).
assert "Write-PathHint\n" in ps1
# Same probe install_source.sh uses to locate the uv bin dir.
assert "uv tool dir --bin" in ps1
# Recommended remediation, matching troubleshooting.md and quickstart.
assert "uv tool update-shell" in ps1
# Clear failure output when the dir is missing from PATH.
assert "entry points are NOT on PATH" in ps1
def test_install_scripts_both_locate_entry_point_by_absolute_path() -> None:
# Parity: both installers probe `uv tool dir --bin` instead of trusting
# PATH, so a fresh install can be smoke-checked regardless of whether
# the user's shell has been reconfigured yet.
sh = SOURCE_SH.read_text(encoding="utf-8")
ps1 = SOURCE_PS1.read_text(encoding="utf-8")
assert "uv tool dir --bin" in sh
assert "uv tool dir --bin" in ps1