- tests/s2/test_new_pid_pairs.gd runs each writer/reader save-restart pair as two real child processes and keeps their complete output in the private profile, since the script-level roster runs suites without arguments. - Commit the Godot UIDs of scripts added this session (and the pre-existing peeping-room scripts that lacked tracked UIDs) plus the legacy fixture's thumbnail import, so a private import generates nothing undeclared. - Repin suite-policy source SHAs for test_main_dashboard (A06 HUD, palette 25) and test_runtime_transport (sustained outage helper); flags unchanged. - Register the pair suite's completion marker. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
69 lines
2.9 KiB
GDScript
69 lines
2.9 KiB
GDScript
extends SceneTree
|
|
|
|
## Runs every writer/reader save-restart pair as two real child Godot processes
|
|
## (distinct PIDs) from this one suite, so a script-level regression roster also
|
|
## proves the new-PID halves. Each child's complete stdout+stderr and exit code
|
|
## are kept under user://pair-evidence/ (inside the run's private profile);
|
|
## summaries printed here avoid completion-marker wording on purpose.
|
|
const PAIRS: Array[String] = [
|
|
"res://tests/s2/test_mana_reserve_new_pid.gd",
|
|
"res://tests/s2/test_mana_recovery_new_pid.gd",
|
|
"res://tests/transport/test_runtime_warp.gd",
|
|
"res://tests/mvp/test_whole_tower_outage.gd",
|
|
"res://tests/transport/test_route_wait_choice.gd",
|
|
]
|
|
const EVIDENCE_DIR := "user://pair-evidence"
|
|
var _checks := 0
|
|
var _failures := 0
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("_run")
|
|
|
|
|
|
func _run() -> void:
|
|
var engine := OS.get_executable_path()
|
|
var project := ProjectSettings.globalize_path("res://")
|
|
DirAccess.make_dir_recursive_absolute(ProjectSettings.globalize_path(EVIDENCE_DIR))
|
|
print("New-PID pairs: parent pid %d engine %s" % [OS.get_process_id(), engine])
|
|
for script: String in PAIRS:
|
|
var pids := {}
|
|
for mode: String in ["writer", "reader"]:
|
|
var output: Array = []
|
|
var code := OS.execute(engine, ["--headless", "--path", project, "--script", script, "--", mode], output, true)
|
|
var text := "".join(output)
|
|
var name := "%s.%s" % [script.get_file().get_basename(), mode]
|
|
var file := FileAccess.open(EVIDENCE_DIR.path_join(name + ".log"), FileAccess.WRITE)
|
|
file.store_string(text)
|
|
file.close()
|
|
var pid := _child_pid(text)
|
|
pids[mode] = pid
|
|
var passed := code == 0 and _child_marker_passed(text)
|
|
print(" pair %s %s exit=%d child_pid=%d bytes=%d sha256=%s" % [script.get_file(), mode, code, pid, text.to_utf8_buffer().size(), text.sha256_text()])
|
|
_expect(passed, "%s %s child completes with zero failures" % [script.get_file(), mode])
|
|
_expect(int(pids["writer"]) > 0 and int(pids["reader"]) > 0 and pids["writer"] != pids["reader"] and pids["reader"] != OS.get_process_id(), "%s writer and reader ran in distinct processes" % script.get_file())
|
|
print("%s: %d checks" % ["PASS" if _failures == 0 else "FAIL", _checks])
|
|
quit(_failures)
|
|
|
|
|
|
## Each pair script prints its own pid on its first line ("... pid N" or "(pid N)").
|
|
static func _child_pid(text: String) -> int:
|
|
var regex := RegEx.new()
|
|
regex.compile("pid (\\d+)")
|
|
var found := regex.search(text)
|
|
return int(found.get_string(1)) if found != null else -1
|
|
|
|
|
|
static func _child_marker_passed(text: String) -> bool:
|
|
var regex := RegEx.new()
|
|
regex.compile("(?m)^PASS: (\\d+) checks$")
|
|
var found := regex.search(text)
|
|
return found != null and int(found.get_string(1)) > 0 and not text.contains("FAIL:") and not text.contains("SCRIPT ERROR")
|
|
|
|
|
|
func _expect(condition: bool, label: String) -> void:
|
|
_checks += 1
|
|
if not condition:
|
|
_failures += 1
|
|
push_error(" ✗ %s" % label)
|