174 lines
7.2 KiB
Bash
Executable File
174 lines
7.2 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Current first-cycle audit. This is intentionally separate from the historical
|
|
# DEV-5 candidate suite: the latter bundled a pre-reconstruction Market test
|
|
# that treated the read-only MarketTitle label as a Button.
|
|
|
|
ROOT=$(cd "$(dirname "$0")/.." && pwd)
|
|
RUNTIME="$ROOT/runtime"
|
|
EVIDENCE=${ABG_EVIDENCE_DIR:?ABG_EVIDENCE_DIR is required}
|
|
SOURCE_REVISION=${ABG_SOURCE_REVISION:?ABG_SOURCE_REVISION is required}
|
|
GODOT=${GODOT_BIN:-/Applications/Godot.app/Contents/MacOS/Godot}
|
|
|
|
if [[ ! "$SOURCE_REVISION" =~ ^[0-9a-f]{40}$ ]]; then
|
|
echo "MVP first-cycle audit requires a source-bound 40-character revision" >&2
|
|
exit 85
|
|
fi
|
|
|
|
mkdir -p "$EVIDENCE/logs/headless" "$EVIDENCE/logs/normal" "$EVIDENCE/captures"
|
|
|
|
strict_scan() {
|
|
local log=$1
|
|
if grep -En 'SCRIPT ERROR:|Parse Error:|ERROR:|ObjectDB instances leaked|resources still in use at exit|RID allocations of type|RID of type' "$log"; then
|
|
echo "strict diagnostics in $log" >&2
|
|
return 86
|
|
fi
|
|
}
|
|
|
|
require_marker() {
|
|
local log=$1
|
|
local marker=$2
|
|
local count
|
|
count=$(grep -Ec "^${marker}( |$)" "$log" || true)
|
|
if [ "$count" -ne 1 ]; then
|
|
echo "marker $marker count=$count in $log" >&2
|
|
return 87
|
|
fi
|
|
}
|
|
|
|
run_headless() {
|
|
local id=$1
|
|
local folder=$2
|
|
local script=$3
|
|
local markers=$4
|
|
local log="$EVIDENCE/logs/headless/${id}.log"
|
|
"$GODOT" --headless --audio-driver Dummy --path "$RUNTIME" \
|
|
--script "res://tests/$folder/$script" >"$log" 2>&1
|
|
strict_scan "$log"
|
|
IFS=',' read -r -a expected_markers <<< "$markers"
|
|
for marker in "${expected_markers[@]}"; do
|
|
require_marker "$log" "$marker"
|
|
done
|
|
tail -n 1 "$log"
|
|
}
|
|
|
|
run_normal() {
|
|
local id=$1
|
|
local folder=$2
|
|
local script=$3
|
|
local markers=$4
|
|
local evidence_subdir="$EVIDENCE/captures/$id"
|
|
local log="$EVIDENCE/logs/normal/${id}.log"
|
|
mkdir -p "$evidence_subdir"
|
|
ABG_EVIDENCE_DIR="$evidence_subdir" \
|
|
"$GODOT" --audio-driver Dummy --fixed-fps 60 --disable-vsync \
|
|
--path "$RUNTIME" --script "res://tests/$folder/$script" >"$log" 2>&1
|
|
strict_scan "$log"
|
|
IFS=',' read -r -a expected_markers <<< "$markers"
|
|
for marker in "${expected_markers[@]}"; do
|
|
require_marker "$log" "$marker"
|
|
done
|
|
tail -n 1 "$log"
|
|
}
|
|
|
|
run_fixture_capture() {
|
|
local id=$1
|
|
local folder=$2
|
|
local script=$3
|
|
local marker=$4
|
|
local fixture=$5
|
|
shift 5
|
|
local evidence_subdir="$EVIDENCE/captures/$id"
|
|
local log="$EVIDENCE/logs/normal/${id}.log"
|
|
mkdir -p "$evidence_subdir"
|
|
ABG_EVIDENCE_DIR="$evidence_subdir" \
|
|
ABG_CAPTURE_FIXTURE_INDEX="$fixture" \
|
|
"$@" \
|
|
"$GODOT" --audio-driver Dummy --fixed-fps 60 --disable-vsync \
|
|
--path "$RUNTIME" --script "res://tests/$folder/$script" >"$log" 2>&1
|
|
strict_scan "$log"
|
|
require_marker "$log" "$marker"
|
|
tail -n 1 "$log"
|
|
}
|
|
|
|
assert_capture_count() {
|
|
local id=$1
|
|
local expected=$2
|
|
local actual
|
|
actual=$(find "$EVIDENCE/captures/$id" -type f -name '*.png' | wc -l | tr -d ' ')
|
|
if [ "$actual" -ne "$expected" ]; then
|
|
echo "$id capture count=$actual; expected $expected" >&2
|
|
return 89
|
|
fi
|
|
}
|
|
|
|
import_log="$EVIDENCE/logs/import.log"
|
|
"$GODOT" --headless --editor --audio-driver Dummy --path "$RUNTIME" --import >"$import_log" 2>&1
|
|
strict_scan "$import_log"
|
|
|
|
# Entry, Company and first Contract semantics.
|
|
while IFS='|' read -r id folder script markers; do
|
|
[ -n "$id" ] || continue
|
|
run_headless "$id" "$folder" "$script" "$markers"
|
|
done <<'TESTS'
|
|
dev1_boot_service|dev1|boot_service_test.gd|ABG_DEV1_BOOT_OK
|
|
dev1_boot_runtime|dev1|boot_runtime_test.gd|ABG_DEV1_BOOT_RUNTIME_OK
|
|
dev1_first_launch|dev1|first_launch_test.gd|ABG_DEV1_FIRST_LAUNCH_OK
|
|
dev1_title|dev1|title_state_test.gd|ABG_DEV1_TITLE_OK
|
|
dev1_settings|dev1|settings_credits_test.gd|ABG_DEV1_SETTINGS_OK
|
|
dev1_touch|dev1|entry_flow_touch_test.gd|ABG_DEV1_ENTRY_TOUCH_OK
|
|
dev2_draft|dev2|initial_company_draft_test.gd|ABG_DEV2_DRAFT_OK
|
|
dev2_choice|dev2|initial_company_choice_test.gd|ABG_DEV2_CHOICE_OK
|
|
dev2_choice_touch|dev2|initial_company_touch_test.gd|ABG_DEV2_CHOICE_TOUCH_OK
|
|
dev2_commit|dev2|initial_company_commit_test.gd|ABG_DEV2_COMMIT_OK
|
|
dev2_commit_touch|dev2|initial_company_commit_touch_test.gd|ABG_DEV2_COMMIT_TOUCH_OK
|
|
dev2_full_flow_touch|dev2|initial_company_full_flow_touch_test.gd|ABG_DEV2_FULL_FLOW_TOUCH_OK
|
|
dev3_contract|dev3|contract_foundation_test.gd|ABG_DEV3_CONTRACT_OK
|
|
dev3_guild_contract|dev3|guild_contract_choice_test.gd|ABG_DEV3_GUILD_OK
|
|
dev3_market_behavior|dev3|market_recruit_review_test.gd|ABG_DEV3_MARKET_OK
|
|
dev3_hire|dev3|hire_transaction_test.gd|ABG_DEV3_HIRE_OK
|
|
m09_market_runtime|dev3|market_runtime_reconstruction_test.gd|ABG_M09_MARKET_RUNTIME_OK
|
|
m10_recruit_runtime|dev3|shp002_recruit_review_runtime_test.gd|ABG_M10_RECRUIT_REVIEW_OK
|
|
dev4_foundation|dev4|formation_risk_foundation_test.gd|ABG_DEV4_FOUNDATION_OK
|
|
dev4_party|dev4|party_line_test.gd|ABG_DEV4_PARTY_OK
|
|
dev4_readiness|dev4|readiness_review_test.gd|ABG_DEV4_READY_OK
|
|
dev4_risk|dev4|risk_selection_test.gd|ABG_DEV4_RISK_OK
|
|
rsk002_commitment|rsk002|risk_commitment_runtime_test.gd|ABG_RSK002_COMMITMENT_OK
|
|
bat001_foundation|dev5|battle_foundation_test.gd|ABG_DEV5_BATTLE_OK
|
|
bat001_opening|dev5|battle_opening_test.gd|ABG_DEV5_BATTLE_OPENING_OK
|
|
bat002_runtime|dev5|battle_runtime_test.gd|ABG_DEV5_BATTLE_UI_OK
|
|
bat002_observation|dev5|battle_observation_service_test.gd|ABG_DEV5_BATTLE_OBSERVATION_SERVICE_OK
|
|
bat002_field|dev5|battle_live_field_test.gd|ABG_DEV5_BATTLE_LIVE_FIELD_OK
|
|
bat002_timeline|dev5|battle_live_timeline_test.gd|ABG_DEV5_BATTLE_TIMELINE_OK
|
|
bat003_004_runtime|dev5|bat003_bat004_runtime_test.gd|ABG_BAT003_BAT004_RUNTIME_OK
|
|
m12_domain|dev5|outcome_recovery_test.gd|ABG_M12_OUTCOME_RECOVERY_DOMAIN_OK
|
|
m12_runtime|dev5|m12_runtime_test.gd|ABG_M12_RUNTIME_OK
|
|
TESTS
|
|
|
|
# Current normal 100% page/battle evidence. No 130% fixture is part of this
|
|
# MVP gate; the explicit override keeps the older Party/Risk capture helper
|
|
# from selecting its historical 130% English fixture.
|
|
run_normal m09_market_capture dev3 market_runtime_capture_test.gd ABG_M09_MARKET_CAPTURE_OK
|
|
assert_capture_count m09_market_capture 16
|
|
run_normal m10_recruit_capture dev3 shp002_recruit_review_capture_test.gd ABG_M10_RECRUIT_REVIEW_CAPTURE_OK
|
|
assert_capture_count m10_recruit_capture 4
|
|
for fixture in 0 1 2 3; do
|
|
run_fixture_capture "dev4_capture_${fixture}" dev4 formation_risk_capture_test.gd ABG_DEV4_CAPTURE_OK "$fixture" env ABG_CAPTURE_TEXT_SCALE=1.0
|
|
done
|
|
for fixture in 0 1 2 3; do
|
|
run_fixture_capture "bat001_capture_${fixture}" dev5 battle_opening_capture_test.gd ABG_DEV5_BATTLE_OPENING_CAPTURE_OK "$fixture"
|
|
done
|
|
for fixture in 0 1 2 3; do
|
|
run_fixture_capture "bat002_capture_${fixture}" dev5 battle_live_capture_test.gd ABG_DEV5_BATTLE_LIVE_CAPTURE_OK "$fixture"
|
|
done
|
|
for fixture in 0 1 2 3; do
|
|
run_fixture_capture "bat003_004_capture_${fixture}" dev5 bat003_bat004_capture_test.gd ABG_BAT003_BAT004_CAPTURE_OK "$fixture"
|
|
done
|
|
run_normal m12_capture dev5 m12_capture_test.gd ABG_M12_CAPTURE_OK
|
|
assert_capture_count m12_capture 32
|
|
|
|
capture_count=$(find "$EVIDENCE/captures" -type f -name '*.png' | wc -l | tr -d ' ')
|
|
printf 'ABG_MVP_FIRST_CYCLE_AUDIT_OK source=%s focused=34 capture_families=8 captures=%s normal_100=true locales=zh_CN,en viewports=760x360,844x390,1280x720 strict=0 parsed_touch=true restart=market stale_market_title_test=fixed non_mvp=second_cycle,regions,endgame,device,package,store,human_comprehension\n' \
|
|
"$SOURCE_REVISION" "$capture_count"
|