#!/bin/bash
set -u
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEST_ALL="$SCRIPT_DIR/test-all.sh"
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
PASS=0
FAIL=0
run_scenario() {
local name="$1"
local fake_cargo_content="$2"
local expected_exit="$3"
local expected_keyword="$4"
local expected_report_keyword="$5"
local workdir="$TMPDIR/$name"
mkdir -p "$workdir"
git -C "$workdir" init -q
git -C "$workdir" config user.email "smoke@test"
git -C "$workdir" config user.name "smoke"
git -C "$workdir" commit -q --allow-empty --no-verify -m "chore: init" 2>/dev/null || true
local fake_bin="$workdir/fakebin"
mkdir -p "$fake_bin"
printf '%s\n' "$fake_cargo_content" > "$fake_bin/cargo"
chmod +x "$fake_bin/cargo"
local actual_output
actual_output=$(cd "$workdir" && PATH="$fake_bin:$PATH" bash "$TEST_ALL" 2>&1)
local actual_exit=$?
if [ "$actual_exit" -ne "$expected_exit" ]; then
echo "FAIL [$name]: expected exit $expected_exit, got $actual_exit"
echo "--- output ---"
echo "$actual_output"
echo "--- end ---"
FAIL=$((FAIL + 1))
return
fi
if ! echo "$actual_output" | grep -qF "$expected_keyword"; then
echo "FAIL [$name]: expected keyword '$expected_keyword' not found in output"
echo "--- output ---"
echo "$actual_output"
echo "--- end ---"
FAIL=$((FAIL + 1))
return
fi
if ! grep -qF "$expected_report_keyword" "$workdir/test-report.md"; then
echo "FAIL [$name]: expected keyword '$expected_report_keyword' not found in report"
echo "--- report ---"
cat "$workdir/test-report.md"
echo "--- end ---"
FAIL=$((FAIL + 1))
return
fi
echo "PASS [$name] (exit=$actual_exit)"
PASS=$((PASS + 1))
}
FAKE_COMPILE_FAIL='#!/bin/bash
if [ "$1" = "test" ]; then
echo " Compiling foo v0.1.0" >&2
echo "error[E0308]: mismatched types" >&2
echo " --> src/lib.rs:1:1" >&2
echo " |" >&2
echo " | let x: i32 = \"string\";" >&2
echo " | ^^^^^^^^ expected `i32`, found `&str`" >&2
echo "" >&2
echo "error: could not compile `foo` due to previous error" >&2
exit 101
fi
# 非 test 子命令,假装成功
exit 0
'
run_scenario "compile_failure" "$FAKE_COMPILE_FAIL" 1 \
"BUILD/RUN FAILED" "Status: FAILED (build/run error, no tests counted)"
FAKE_TEST_FAIL='#!/bin/bash
if [ "$1" = "test" ]; then
echo " Compiling foo v0.1.0" >&2
echo " Finished test [unoptimized + debuginfo] target(s) in 0.1s" >&2
echo " Running unittests src/lib.rs" >&2
echo "" >&2
echo "running 3 tests" >&2
echo "test test_a ... FAILED" >&2
echo "test test_b ... ok" >&2
echo "test test_c ... ok" >&2
echo "" >&2
echo "failures:" >&2
echo "" >&2
echo "---- test_a stdout ----" >&2
echo "thread '"'"'test_a'"'"' panicked at src/lib.rs:5:5:" >&2
echo "assertion failed: 1 == 2" >&2
echo "note: run with RUST_BACKTRACE=1 to display a backtrace" >&2
echo "" >&2
echo "failures:" >&2
echo " test_a" >&2
echo "" >&2
echo "test result: FAILED. 2 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out" >&2
exit 101
fi
exit 0
'
run_scenario "test_failure" "$FAKE_TEST_FAIL" 1 \
"test result: FAILED" "Status: FAILED"
FAKE_ALL_PASS='#!/bin/bash
if [ "$1" = "test" ]; then
echo " Compiling foo v0.1.0" >&2
echo " Finished test [unoptimized + debuginfo] target(s) in 0.1s" >&2
echo " Running unittests src/lib.rs" >&2
echo "" >&2
echo "running 5 tests" >&2
echo "test test_a ... ok" >&2
echo "test test_b ... ok" >&2
echo "test test_c ... ok" >&2
echo "test test_d ... ok" >&2
echo "test test_e ... ok" >&2
echo "" >&2
echo "test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out" >&2
exit 0
fi
exit 0
'
run_scenario "all_pass" "$FAKE_ALL_PASS" 0 \
"ALL TESTS PASSED" "Status: ALL PASSED"
FAKE_PARTIAL_FAIL='#!/bin/bash
if [ "$1" = "test" ]; then
echo " Compiling crate-a v0.1.0" >&2
echo " Running unittests src/lib.rs (crate-a)" >&2
echo "" >&2
echo "running 5 tests" >&2
echo "test a1 ... ok" >&2
echo "test a2 ... ok" >&2
echo "test a3 ... ok" >&2
echo "test a4 ... ok" >&2
echo "test a5 ... ok" >&2
echo "" >&2
echo "test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out" >&2
echo " Compiling crate-b v0.1.0" >&2
echo "error[E0432]: unresolved import \`crate_b::missing\`" >&2
echo "error: could not compile \`crate-b\` due to previous error" >&2
exit 101
fi
exit 0
'
run_scenario "partial_failure" "$FAKE_PARTIAL_FAIL" 1 \
"BUILD/RUN FAILED" "build did not fully complete"
echo ""
echo "=== Smoke Test Summary ==="
echo " Passed: $PASS"
echo " Failed: $FAIL"
if [ "$FAIL" -gt 0 ]; then
exit 1
fi
exit 0