diff --git a/tools/compress-driver-artifact.sh b/tools/compress-driver-artifact.sh index bbf2ee7..7e5c148 100755 --- a/tools/compress-driver-artifact.sh +++ b/tools/compress-driver-artifact.sh @@ -67,6 +67,56 @@ case "$goos/$goarch" in ;; esac +host_platform="$(go env GOOS)/$(go env GOARCH)" + +is_driver_agent_binary() { + local artifact_name + artifact_name="$(basename "$artifact_path")" + [[ "$artifact_name" == *"-driver-agent-"* ]] +} + +can_smoke_test_driver_agent() { + is_driver_agent_binary && [[ "$host_platform" == "$platform" ]] +} + +smoke_test_driver_agent_metadata() { + local stdout_file stderr_file + stdout_file="$(mktemp "${TMPDIR:-/tmp}/gonavi-driver-agent-stdout.XXXXXX")" + stderr_file="$(mktemp "${TMPDIR:-/tmp}/gonavi-driver-agent-stderr.XXXXXX")" + + if ! printf '%s\n' '{"id":1,"method":"metadata"}' | "$artifact_path" >"$stdout_file" 2>"$stderr_file"; then + [[ -s "$stderr_file" ]] && cat "$stderr_file" >&2 + rm -f "$stdout_file" "$stderr_file" + return 1 + fi + + if ! python3 - "$stdout_file" <<'PY' +import json +import sys +from pathlib import Path + +lines = [line.strip() for line in Path(sys.argv[1]).read_text(encoding="utf-8", errors="replace").splitlines() if line.strip()] +if not lines: + raise SystemExit(1) + +payload = json.loads(lines[0]) +if not payload.get("success"): + raise SystemExit(1) + +data = payload.get("data") or {} +if not str(data.get("agentRevision") or "").strip(): + raise SystemExit(1) +PY + then + [[ -s "$stderr_file" ]] && cat "$stderr_file" >&2 + rm -f "$stdout_file" "$stderr_file" + return 1 + fi + + rm -f "$stdout_file" "$stderr_file" + return 0 +} + if ! command -v upx >/dev/null 2>&1; then if [[ "$mode" == "required" ]]; then echo "❌ 未找到 upx,无法压缩:$label" >&2 @@ -124,6 +174,18 @@ if ! upx -t "$artifact_path" >/dev/null 2>&1; then exit 0 fi +if can_smoke_test_driver_agent; then + if ! smoke_test_driver_agent_metadata; then + cp "$backup_path" "$artifact_path" + if [[ "$mode" == "required" ]]; then + echo "❌ UPX 压缩后 driver-agent metadata 自检失败:$label" >&2 + exit 1 + fi + echo "⚠️ UPX 压缩后 driver-agent metadata 自检失败,已恢复原文件:$label" + exit 0 + fi +fi + after_bytes="$(file_size_bytes "$artifact_path")" if [[ "$after_bytes" -lt "$before_bytes" ]]; then saved_bytes=$((before_bytes - after_bytes)) diff --git a/tools/compress-driver-artifact.test.sh b/tools/compress-driver-artifact.test.sh new file mode 100755 index 0000000..99f1085 --- /dev/null +++ b/tools/compress-driver-artifact.test.sh @@ -0,0 +1,104 @@ +#!/usr/bin/env bash + +set -euo pipefail + +host_platform="$(go env GOOS)/$(go env GOARCH)" +case "$host_platform" in + linux/amd64|linux/arm64|windows/amd64) + ;; + *) + echo "skip compress-driver-artifact smoke test on unsupported host platform: $host_platform" + exit 0 + ;; +esac + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/gonavi-compress-driver-artifact.XXXXXX")" +cleanup() { + rm -rf "$tmpdir" +} +trap cleanup EXIT + +suffix="" +if [[ "$host_platform" == windows/* ]]; then + suffix=".exe" +fi + +good_src="$tmpdir/good.go" +bad_src="$tmpdir/bad.go" +good_bin="$tmpdir/good-driver-agent-${host_platform/\//-}${suffix}" +bad_bin="$tmpdir/bad-driver-agent-${host_platform/\//-}${suffix}" +recover_bin="$tmpdir/recover-driver-agent-${host_platform/\//-}${suffix}" +fakebin="$tmpdir/bin" +mkdir -p "$fakebin" + +cat >"$good_src" <<'GOEOF' +package main + +import ( + "bufio" + "fmt" + "os" + "strings" +) + +func main() { + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + if strings.TrimSpace(scanner.Text()) == "" { + continue + } + fmt.Println(`{"id":1,"success":true,"data":{"agentRevision":"src-test"}}`) + return + } +} +GOEOF + +cat >"$bad_src" <<'GOEOF' +package main + +func main() {} +GOEOF + +go build -o "$good_bin" "$good_src" +go build -o "$bad_bin" "$bad_src" +cp "$good_bin" "$recover_bin" + +cat >"$fakebin/upx" <<'SHEOF' +#!/usr/bin/env bash +set -euo pipefail + +if [[ "${1:-}" == "-t" ]]; then + exit 0 +fi + +target="${*: -1}" +if [[ -n "${FAKE_UPX_REPLACE:-}" && "$target" == *"recover-driver-agent-"* ]]; then + cp "$FAKE_UPX_REPLACE" "$target" +fi +SHEOF +chmod +x "$fakebin/upx" + +PATH="$fakebin:$PATH" bash "$repo_root/tools/compress-driver-artifact.sh" "$good_bin" "$host_platform" "good" +metadata_output="$(printf '%s\n' '{"id":1,"method":"metadata"}' | "$good_bin")" +if [[ "$metadata_output" != *'"agentRevision":"src-test"'* ]]; then + echo "expected metadata smoke test to keep good driver-agent executable" >&2 + exit 1 +fi + +warning_output="$( + FAKE_UPX_REPLACE="$bad_bin" PATH="$fakebin:$PATH" bash "$repo_root/tools/compress-driver-artifact.sh" "$recover_bin" "$host_platform" "recover" 2>&1 +)" +if [[ "$warning_output" != *"metadata 自检失败"* ]]; then + echo "expected metadata smoke-test warning when fake UPX replacement breaks the executable" >&2 + echo "$warning_output" >&2 + exit 1 +fi + +recovered_output="$(printf '%s\n' '{"id":1,"method":"metadata"}' | "$recover_bin")" +if [[ "$recovered_output" != *'"agentRevision":"src-test"'* ]]; then + echo "expected metadata smoke-test failure to restore original driver-agent binary" >&2 + exit 1 +fi + +echo "compress-driver-artifact smoke test passed"