diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e930ff5e35..b9a7117688 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -55,6 +55,13 @@ the full dev/release/dist taxonomy and the slim `--features dev-cli` CLI (#5422) The full README [Development](README.md#development) section has more `cargo run` recipes (HIR dumps, per-crate rebuilds). +For fixture-only parity reruns, `PERRY_SKIP_BUILD=1 ./run_parity_tests.sh` +reuses `PERRY_BIN` and the matching runtime/stdlib archives from +`PERRY_RUNTIME_DIR` (or the binary's directory) with auto-optimization disabled. +Rebuild instead whenever Rust or Cargo inputs, or compiler, runtime, stdlib, or +required extension sources differ; reuse does not prove that prebuilt artifacts +match the checkout. + ## Making changes ### What goes in a PR diff --git a/run_parity_tests.sh b/run_parity_tests.sh index 5546921045..8dd7b536be 100755 --- a/run_parity_tests.sh +++ b/run_parity_tests.sh @@ -417,8 +417,37 @@ echo "" # release binary the prior step had just produced, and (b) adds cargo's own # per-invocation overhead × ~150 tests. TARGET_DIR="${CARGO_TARGET_DIR:-$SCRIPT_DIR/target}" -PERRY_BIN="$TARGET_DIR/release/perry" -echo "Building compiler (release)..." +PERRY_SKIP_BUILD="${PERRY_SKIP_BUILD:-0}" +case "$PERRY_SKIP_BUILD" in + 0|1) ;; + *) + echo -e "${RED}Invalid PERRY_SKIP_BUILD '$PERRY_SKIP_BUILD' (want 0 or 1)${NC}" >&2 + exit 1 + ;; +esac + +if [[ "$PERRY_SKIP_BUILD" == "1" ]]; then + PERRY_BIN="${PERRY_BIN:-$TARGET_DIR/release/perry}" + if [[ ! -x "$PERRY_BIN" ]]; then + echo -e "${RED}PERRY_BIN is not executable: $PERRY_BIN${NC}" >&2 + exit 1 + fi + PERRY_RUNTIME_DIR="${PERRY_RUNTIME_DIR:-$(cd "$(dirname "$PERRY_BIN")" && pwd)}" + case "$(uname -s)" in + MINGW*|MSYS*|CYGWIN*) runtime_lib=perry_runtime.lib; stdlib_lib=perry_stdlib.lib ;; + *) runtime_lib=libperry_runtime.a; stdlib_lib=libperry_stdlib.a ;; + esac + if [[ ! -f "$PERRY_RUNTIME_DIR/$runtime_lib" || ! -f "$PERRY_RUNTIME_DIR/$stdlib_lib" ]]; then + echo -e "${RED}PERRY_RUNTIME_DIR must contain $runtime_lib and $stdlib_lib: $PERRY_RUNTIME_DIR${NC}" >&2 + exit 1 + fi + export PERRY_RUNTIME_DIR PERRY_NO_AUTO_OPTIMIZE=1 + echo "Using prebuilt compiler: $PERRY_BIN" + echo "Using prebuilt runtime archives: $PERRY_RUNTIME_DIR" +else + PERRY_BIN="$TARGET_DIR/release/perry" + echo "Building compiler (release)..." +fi BUILD_PACKAGES=(-p perry -p perry-runtime -p perry-stdlib -p perry-runtime-static -p perry-stdlib-static) BUILD_FEATURES=() needs_wasm_host=0 @@ -498,11 +527,11 @@ if [[ "${#BUILD_FEATURES[@]}" -gt 0 ]]; then feature_csv=$(IFS=,; echo "${BUILD_FEATURES[*]}") BUILD_FEATURE_ARGS=(--features "$feature_csv") fi -if ! cargo build --release --quiet "${BUILD_PACKAGES[@]}" "${BUILD_FEATURE_ARGS[@]}" 2>/dev/null; then +if [[ "$PERRY_SKIP_BUILD" == "0" ]] && ! cargo build --release --quiet "${BUILD_PACKAGES[@]}" "${BUILD_FEATURE_ARGS[@]}" 2>/dev/null; then echo -e "${RED}Failed to build compiler/runtime archives${NC}" exit 1 fi -if [[ "$needs_wasm_host" -eq 1 ]]; then +if [[ "$PERRY_SKIP_BUILD" == "0" && "$needs_wasm_host" -eq 1 ]]; then # WebAssembly metadata fixtures exercise the real host shims. Build the # wasm-enabled runtime staticlib after the CLI build above; enabling this # feature while building the `perry` binary would make the CLI link against @@ -513,7 +542,7 @@ if [[ "$needs_wasm_host" -eq 1 ]]; then exit 1 fi fi -if [[ "$needs_ext_net" -eq 1 ]]; then +if [[ "$PERRY_SKIP_BUILD" == "0" && "$needs_ext_net" -eq 1 ]]; then echo "Building net extension (release)..." ext_net_jobs="${CARGO_BUILD_JOBS:-1}" if ! cargo build --release --quiet -p perry-ext-net -j "$ext_net_jobs" 2>/dev/null; then @@ -526,7 +555,11 @@ if [[ ! -x "$PERRY_BIN" ]]; then exit 1 fi -echo -e "${GREEN}Compiler and runtime archives built successfully${NC}" +if [[ "$PERRY_SKIP_BUILD" == "0" ]]; then + echo -e "${GREEN}Compiler and runtime archives built successfully${NC}" +else + echo -e "${GREEN}Prebuilt compiler and runtime archives verified${NC}" +fi echo "" echo "Running parity tests (backend: $BACKEND_LABEL, suite: $TEST_SUITE${MODULE_FILTER:+, module: $MODULE_FILTER})..." echo "" diff --git a/tests/test_parity_build_reuse.sh b/tests/test_parity_build_reuse.sh new file mode 100755 index 0000000000..5d9a28c5d1 --- /dev/null +++ b/tests/test_parity_build_reuse.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +WORK="$(mktemp -d)" +trap 'rm -rf "$WORK"' EXIT + +cp "$ROOT/run_parity_tests.sh" "$WORK/run_parity_tests.sh" +mkdir -p "$WORK/bin" "$WORK/test-files" "$WORK/test-parity/node-suite/reuse" \ + "$WORK/test-parity/output/node" "$WORK/test-parity/output/perry" "$WORK/test-parity/reports" +cat > "$WORK/bin/cargo" <<'EOF' +#!/bin/sh +echo invoked >> "$CARGO_LOG" +exit 99 +EOF +cat > "$WORK/perry" <<'EOF' +#!/bin/sh +echo "$0|$PERRY_RUNTIME_DIR|$PERRY_NO_AUTO_OPTIMIZE" >> "$PERRY_LOG" +while [ "$#" -gt 0 ]; do + if [ "$1" = "-o" ]; then + cat > "$2" <<'BIN' +#!/bin/sh +echo reuse-ok +BIN + chmod +x "$2" + exit 0 + fi + shift +done +exit 0 +EOF +cat > "$WORK/bin/node" <<'EOF' +#!/bin/sh +echo reuse-ok +EOF +cat > "$WORK/bin/ps" <<'EOF' +#!/bin/sh +echo 1 +EOF +touch "$WORK/test-parity/node-suite/reuse/basic.ts" +chmod +x "$WORK/bin/cargo" "$WORK/bin/node" "$WORK/bin/ps" "$WORK/perry" +export PATH="$WORK/bin:$PATH" CARGO_LOG="$WORK/cargo.log" PERRY_LOG="$WORK/perry.log" + +run_failure() { + local expected=$1 + shift + if "$@" >"$WORK/output" 2>&1; then + echo "expected failure: $expected" >&2 + exit 1 + fi + grep -F "$expected" "$WORK/output" >/dev/null +} + +run_failure "Invalid PERRY_SKIP_BUILD 'yes'" env PERRY_SKIP_BUILD=yes "$WORK/run_parity_tests.sh" +run_failure "PERRY_BIN is not executable" env PERRY_SKIP_BUILD=1 PERRY_BIN="$WORK/missing" "$WORK/run_parity_tests.sh" +mkdir -p "$WORK/empty" +case "$(uname -s)" in + MINGW*|MSYS*|CYGWIN*) touch "$WORK/empty/perry_runtime.lib" ;; + *) touch "$WORK/empty/libperry_runtime.a" ;; +esac +run_failure "PERRY_RUNTIME_DIR must contain" env PERRY_SKIP_BUILD=1 PERRY_BIN="$WORK/perry" PERRY_RUNTIME_DIR="$WORK/empty" "$WORK/run_parity_tests.sh" + +case "$(uname -s)" in + MINGW*|MSYS*|CYGWIN*) touch "$WORK/perry_runtime.lib" "$WORK/perry_stdlib.lib" ;; + *) touch "$WORK/libperry_runtime.a" "$WORK/libperry_stdlib.a" ;; +esac +: > "$CARGO_LOG" +set +e +PERRY_SKIP_BUILD=1 PERRY_BIN="$WORK/perry" "$WORK/run_parity_tests.sh" --suite node-suite --module reuse >"$WORK/output" 2>&1 +status=$? +set -e +[[ "$status" -eq 0 ]] +grep -F "Using prebuilt compiler: $WORK/perry" "$WORK/output" >/dev/null +grep -F "Using prebuilt runtime archives: $WORK" "$WORK/output" >/dev/null +grep -F "$WORK/perry|$WORK|1" "$PERRY_LOG" >/dev/null +[[ ! -s "$CARGO_LOG" ]] + +echo "PASS"