diff --git a/tools/smokes/v2/lib/llvm_exe_runner.sh b/tools/smokes/v2/lib/llvm_exe_runner.sh index bae66359..de341816 100644 --- a/tools/smokes/v2/lib/llvm_exe_runner.sh +++ b/tools/smokes/v2/lib/llvm_exe_runner.sh @@ -11,6 +11,98 @@ set -uo pipefail +# Source centralized environment configuration (SSOT) +LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +if [ -f "$LIB_DIR/env.sh" ]; then + source "$LIB_DIR/env.sh" +fi + +# ============================================================================ +# Helper: require_joinir_dev +# ============================================================================ +# Sets dev-only environment variables for JoinIR normalized shadow testing. +# Must be called BEFORE build/run operations if the fixture requires dev-only features. +# +# Usage: +# require_joinir_dev +# +# NOTE: This now validates that env.sh has been sourced correctly. +# +require_joinir_dev() { + # Verify env.sh provided the defaults + if [ "${NYASH_JOINIR_DEV:-0}" != "1" ]; then + export NYASH_JOINIR_DEV=1 + fi + if [ "${HAKO_JOINIR_STRICT:-0}" != "1" ]; then + export HAKO_JOINIR_STRICT=1 + fi + echo "[INFO] JoinIR dev mode enabled (NYASH_JOINIR_DEV=1, HAKO_JOINIR_STRICT=1)" +} + +# ============================================================================ +# Helper: check_output_contract +# ============================================================================ +# Unified output validation interface for exit_code, numeric, and substring checks. +# +# Args: +# $1: contract_type - "exit_code" / "numeric" / "substring" +# $2: expected - Expected value (string/number) +# $3: actual - Actual value to compare +# $4: context - (optional) Context description for error messages +# +# Returns: +# 0 if contract satisfied, 1 otherwise +# +check_output_contract() { + local contract_type="${1:-}" + local expected="${2:-}" + local actual="${3:-}" + local context="${4:-output}" + + if [ -z "$contract_type" ] || [ -z "$expected" ]; then + echo "[FAIL] check_output_contract: missing contract_type or expected value" + return 1 + fi + + case "$contract_type" in + exit_code) + if [ "$actual" -ne "$expected" ] 2>/dev/null; then + echo "[FAIL] OutputContract(exit_code): got $actual, expected $expected" + return 1 + fi + echo "[PASS] OutputContract(exit_code): $actual == $expected" + return 0 + ;; + + numeric) + if [ "$actual" != "$expected" ]; then + echo "[FAIL] OutputContract(numeric): got '$actual', expected '$expected'" + echo "[INFO] Context: $context" + return 1 + fi + echo "[PASS] OutputContract(numeric): $actual == $expected" + return 0 + ;; + + substring) + if ! printf "%s" "$actual" | grep -qF "$expected"; then + echo "[FAIL] OutputContract(substring): '$expected' not found in $context" + echo "[INFO] Actual output (first 200 chars):" + printf "%s" "$actual" | head -c 200 + echo "" + return 1 + fi + echo "[PASS] OutputContract(substring): '$expected' found in $context" + return 0 + ;; + + *) + echo "[FAIL] check_output_contract: unknown contract_type '$contract_type'" + return 1 + ;; + esac +} + llvm_exe_cargo_target_dir() { # Use the workspace target dir by default so `NYASH_BIN` and plugin artifacts match local dev expectations. local target_dir="${LLVM_EXE_CARGO_TARGET_DIR:-$NYASH_ROOT/target}" @@ -180,15 +272,12 @@ llvm_exe_build_and_run_numeric_smoke() { echo "[INFO] CLEAN output:" echo "$clean" - if [ "$clean" = "$EXPECTED" ]; then + if check_output_contract "numeric" "$EXPECTED" "$clean" "numeric stdout (first $EXPECTED_LINES lines)"; then return 0 fi - echo "[FAIL] Output mismatch" echo "[INFO] Raw output (tail):" echo "$output" | tail -n 80 - echo "[INFO] Expected:" - printf "%s\n" "$EXPECTED" return 1 } @@ -241,12 +330,11 @@ llvm_exe_build_and_run_expect_exit_code() { local exit_code=$? set -e - if [ "$exit_code" -ne "$EXPECTED_EXIT_CODE" ]; then - echo "[FAIL] Execution exit code mismatch: got $exit_code, expected $EXPECTED_EXIT_CODE" - echo "[INFO] Raw output (tail):" - echo "$output" | tail -n 80 - return 1 + if check_output_contract "exit_code" "$EXPECTED_EXIT_CODE" "$exit_code" "executable exit code"; then + return 0 fi - return 0 + echo "[INFO] Raw output (tail):" + echo "$output" | tail -n 80 + return 1 } diff --git a/tools/smokes/v2/lib/test_runner.sh b/tools/smokes/v2/lib/test_runner.sh index aee87465..5733b947 100644 --- a/tools/smokes/v2/lib/test_runner.sh +++ b/tools/smokes/v2/lib/test_runner.sh @@ -9,6 +9,12 @@ set -uo pipefail if [ -z "${NYASH_ROOT:-}" ]; then export NYASH_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)" fi + +# Source centralized environment configuration (SSOT) +LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +if [ -f "$LIB_DIR/env.sh" ]; then + source "$LIB_DIR/env.sh" +fi # Prefer hakorune binary if exists; fallback to nyash for compatibility if [ -z "${NYASH_BIN:-}" ]; then if [ -x "$NYASH_ROOT/target/release/hakorune" ]; then @@ -842,6 +848,27 @@ verify_v1_inline_file() { fi return 1 } +# ============================================================================ +# Helper: require_joinir_dev +# ============================================================================ +# Sets dev-only environment variables for JoinIR normalized shadow testing. +# Must be called BEFORE build/run operations if the fixture requires dev-only features. +# +# Usage: +# require_joinir_dev +# +require_joinir_dev() { + # JoinIR dev mode now controlled by env.sh (SSOT) + # Verify it's enabled (should be default=1 from env.sh) + if [ "${NYASH_JOINIR_DEV:-0}" != "1" ]; then + export NYASH_JOINIR_DEV=1 + fi + if [ "${HAKO_JOINIR_STRICT:-0}" != "1" ]; then + export HAKO_JOINIR_STRICT=1 + fi + echo "[INFO] JoinIR dev mode enabled (NYASH_JOINIR_DEV=1, HAKO_JOINIR_STRICT=1)" +} + # Dev profile helpers (centralize bring-up toggles for MirBuilder) # Usage: call enable_mirbuilder_dev_env in canaries that need it. enable_mirbuilder_dev_env() { @@ -849,12 +876,12 @@ enable_mirbuilder_dev_env() { export NYASH_USE_NY_COMPILER=0 # Allow FileBox provider fallback (dev only) export NYASH_FAIL_FAST=${NYASH_FAIL_FAST:-0} - # Enable using resolution in VM - export NYASH_ENABLE_USING=1 - export HAKO_ENABLE_USING=1 - # Allow file-based using in dev (e.g., using "hako.mir.builder") - export NYASH_ALLOW_USING_FILE=1 - export HAKO_ALLOW_USING_FILE=1 + # Using system already configured by env.sh (SSOT), but ensure enabled + export NYASH_ENABLE_USING="${NYASH_ENABLE_USING:-1}" + export HAKO_ENABLE_USING="${HAKO_ENABLE_USING:-1}" + # File-based using also from env.sh, but ensure enabled for dev + export NYASH_ALLOW_USING_FILE="${NYASH_ALLOW_USING_FILE:-1}" + export HAKO_ALLOW_USING_FILE="${HAKO_ALLOW_USING_FILE:-1}" # Optional: preinclude heavy using segments for legacy/prelude-heavy paths (default OFF) if [ "${SMOKES_DEV_PREINCLUDE:-0}" = "1" ]; then export HAKO_PREINCLUDE=1 @@ -875,13 +902,13 @@ enable_mirbuilder_dev_env() { # Sets environment defaults for LLVM crate backend and EXE link paths. # Usage: call enable_exe_dev_env in EXE canaries. enable_exe_dev_env() { - # Prefer crate backend when available - export NYASH_LLVM_BACKEND=${NYASH_LLVM_BACKEND:-crate} + # LLVM backend already configured by env.sh (SSOT), fallback to crate + export NYASH_LLVM_BACKEND="${NYASH_LLVM_BACKEND:-crate}" # Tool locations (override when cross) - export NYASH_NY_LLVM_COMPILER=${NYASH_NY_LLVM_COMPILER:-"$NYASH_ROOT/target/release/ny-llvmc"} + export NYASH_NY_LLVM_COMPILER="${NYASH_NY_LLVM_COMPILER:-$NYASH_ROOT/target/release/ny-llvmc}" # NyRT (kernel) lib search path for linking EXEs - export NYASH_EMIT_EXE_NYRT=${NYASH_EMIT_EXE_NYRT:-"$NYASH_ROOT/target/release"} - # Optional verification toggles (kept ON by default only for canaries that opt-in) - export NYASH_LLVM_VERIFY=${NYASH_LLVM_VERIFY:-0} - export NYASH_LLVM_VERIFY_IR=${NYASH_LLVM_VERIFY_IR:-0} + export NYASH_EMIT_EXE_NYRT="${NYASH_EMIT_EXE_NYRT:-$NYASH_ROOT/target/release}" + # Verification toggles from env.sh (SSOT) + export NYASH_LLVM_VERIFY="${NYASH_LLVM_VERIFY:-0}" + export NYASH_LLVM_VERIFY_IR="${NYASH_LLVM_VERIFY_IR:-0}" } diff --git a/tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_llvm_exe.sh b/tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_llvm_exe.sh index 965dd67d..113f4d54 100644 --- a/tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_llvm_exe.sh +++ b/tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_llvm_exe.sh @@ -11,8 +11,7 @@ llvm_exe_preflight_or_skip || exit 0 # Phase 131 is a dev-only Normalized shadow loop case. # LLVM EXE emission must run with JoinIR dev/strict enabled, otherwise it will freeze. -export NYASH_JOINIR_DEV=1 -export HAKO_JOINIR_STRICT=1 +require_joinir_dev # Phase 131: minimal plugin set (StringBox, ConsoleBox, IntegerBox only) STRINGBOX_SO="$NYASH_ROOT/plugins/nyash-string-plugin/libnyash_string_plugin.so" diff --git a/tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_vm.sh b/tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_vm.sh index c52f0f98..9e5909d7 100644 --- a/tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_vm.sh +++ b/tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_vm.sh @@ -9,6 +9,9 @@ source "$(dirname "$0")/../../../lib/test_runner.sh" export SMOKES_USE_PYVM=0 require_env || exit 2 +# Phase 131 is a dev-only Normalized shadow loop case. +require_joinir_dev + PASS_COUNT=0 FAIL_COUNT=0 RUN_TIMEOUT_SECS=${RUN_TIMEOUT_SECS:-10} @@ -22,8 +25,6 @@ INPUT="$NYASH_ROOT/apps/tests/phase131_loop_true_break_once_min.hako" set +e OUTPUT=$(timeout "$RUN_TIMEOUT_SECS" env \ NYASH_DISABLE_PLUGINS=1 \ - HAKO_JOINIR_STRICT=1 \ - NYASH_JOINIR_DEV=1 \ "$NYASH_BIN" --backend vm "$INPUT" 2>&1) EXIT_CODE=$? set -e