117 lines
5.9 KiB
GDScript
117 lines
5.9 KiB
GDScript
extends SceneTree
|
|
|
|
## P16-01-DISMISS F7/F8, writer phase. Plays the ledger day script and writes
|
|
## ordinary save files before and right after the dismissal command (before the
|
|
## next minute), a minute later and around the day 2 00:00 close; and saves the
|
|
## command boundary of A6 (the medic dismissed while carrying the patient on
|
|
## foot), A7 (the patient dismissed while the medic rides the elevator alone) and
|
|
## A8 (the actor of a foreground Event with reserved cost dismissed). The reader
|
|
## suite (test_general_dismissal_restart_2_read.gd) loads them in a separate
|
|
## engine process. The handoff is the declared generated report
|
|
## res://artifacts/p16-01-dismiss/restart-handoff.json
|
|
## (tools/regression/suite-policy.json fixed_generated_report_routes).
|
|
|
|
const Scenes := preload("res://tests/helpers/p16_dismissal_fixture.gd")
|
|
const CONTINUE_MINUTES := 5
|
|
|
|
var _checks := 0
|
|
var _failures := 0
|
|
var _scenes: Scenes
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("_run")
|
|
|
|
|
|
func _run() -> void:
|
|
print("P16-01-DISMISS: restart writer")
|
|
_scenes = Scenes.new(_expect)
|
|
var straight := _scenes.new_ledger_fixture()
|
|
_scenes.play_ledger(straight, 360, Scenes.LAST_MINUTE, Callable())
|
|
var straight_runtime: Variant = straight[&"runtime"]
|
|
_expect(_scenes.count_category(straight_runtime, FinancePolicy.SEVERANCE_CATEGORY) == 1 and straight_runtime.staff_service.get_departed_unpaid_wages(Scenes.DISMISSED) == 0,
|
|
"uninterrupted script: one severance and the held wages paid at the day 2 close")
|
|
var saving := _scenes.new_ledger_fixture()
|
|
var ledger_saves: Array = []
|
|
_scenes.play_ledger(saving, 360, Scenes.LAST_MINUTE, func(minute: int, phase: String) -> void:
|
|
if [minute, phase] in Scenes.SAVE_POINTS:
|
|
var name := "ledger-%d-%s" % [minute, phase]
|
|
var path := Scenes.WRITER_SAVE % name
|
|
_expect(bool(saving[&"runtime"].save_to_path(path).get(&"ok", false)), "save file %s" % name)
|
|
ledger_saves.append(_package(name, path, {"minute": minute, "phase": phase})))
|
|
_expect(_scenes.economy_bytes(saving[&"runtime"]) == _scenes.economy_bytes(straight_runtime), "writing the save files leaves the ledger as without saving")
|
|
var boundaries: Array = []
|
|
for scene: Array in [["A6", "rescue_transport/MOVING/-/single", &"medic"], ["A7", "rescue_pickup/MOVING/BOARDED/single", &"patient"]]:
|
|
var fixture := _scenes.new_rescue_fixture()
|
|
_expect(_scenes.advance_to_rescue_phase(fixture, scene[1]), "%s: the rescue reaches %s" % [scene[0], scene[1]])
|
|
boundaries.append(_boundary(fixture, scene[0], scene[2]))
|
|
_scenes.free_fixture(fixture)
|
|
var event_fixture := _scenes.new_event_fixture(16_100)
|
|
boundaries.append(_boundary(event_fixture, "A8", &"event_actor"))
|
|
_scenes.free_fixture(event_fixture)
|
|
var handoff := {
|
|
"schema": Scenes.HANDOFF_SCHEMA,
|
|
"writer_pid": OS.get_process_id(),
|
|
"writer_source_sha256": FileAccess.get_sha256(Scenes.WRITER_SOURCE),
|
|
"ledger_seed": Scenes.LEDGER_SEED,
|
|
"last_minute": Scenes.LAST_MINUTE,
|
|
"straight_economy_sha256": Scenes.sha256(_scenes.economy_bytes(straight_runtime)),
|
|
"straight_state_base64": Marshalls.raw_to_base64(var_to_bytes(_scenes.state_value(straight_runtime, straight[&"clock"]))),
|
|
"ledger_saves": ledger_saves,
|
|
"boundaries": boundaries,
|
|
}
|
|
DirAccess.make_dir_recursive_absolute(ProjectSettings.globalize_path(Scenes.HANDOFF_PATH).get_base_dir())
|
|
var file := FileAccess.open(Scenes.HANDOFF_PATH, FileAccess.WRITE)
|
|
_expect(file != null, "handoff file opens for writing")
|
|
if file != null:
|
|
file.store_string(JSON.stringify(handoff, "\t") + "\n")
|
|
file.close()
|
|
print("P16_RESTART_WRITER pid=%d handoff_sha256=%s" % [OS.get_process_id(), FileAccess.get_sha256(Scenes.HANDOFF_PATH)])
|
|
_scenes.free_fixture(straight)
|
|
_scenes.free_fixture(saving)
|
|
await process_frame
|
|
if _failures == 0:
|
|
print("PASS: %d checks" % _checks)
|
|
else:
|
|
push_error("FAIL: %d of %d checks failed" % [_failures, _checks])
|
|
quit(_failures)
|
|
|
|
|
|
## Dismisses the employee, saves at once (the command boundary, before the next
|
|
## minute), then records the state then and CONTINUE_MINUTES later.
|
|
func _boundary(fixture: Dictionary, label: String, staff_id: StringName) -> Dictionary:
|
|
var runtime: Variant = fixture[&"runtime"]
|
|
var result := _scenes.dismiss(fixture, staff_id)
|
|
_expect(result.is_success(), "%s: the employee is dismissed (%s)" % [label, result.message])
|
|
var dangling: Array[String] = _scenes.dangling_references(runtime, staff_id)
|
|
_expect(dangling.is_empty(), "%s: no live reference remains at the command boundary %s" % [label, dangling])
|
|
var name := "boundary-%s" % label
|
|
var path := Scenes.WRITER_SAVE % name
|
|
_expect(bool(runtime.save_to_path(path).get(&"ok", false)), "%s: save right after the command" % label)
|
|
var at_command := _scenes.state_value(runtime, fixture[&"clock"])
|
|
fixture[&"clock"].advance_minutes(CONTINUE_MINUTES)
|
|
var later := _scenes.state_value(runtime, fixture[&"clock"])
|
|
return _package(name, path, {"label": label, "staff_id": String(staff_id), "continue_minutes": CONTINUE_MINUTES,
|
|
"at_command_base64": Marshalls.raw_to_base64(var_to_bytes(at_command)), "later_base64": Marshalls.raw_to_base64(var_to_bytes(later))})
|
|
|
|
|
|
func _package(name: String, path: String, extra: Dictionary) -> Dictionary:
|
|
var directory := ProjectSettings.globalize_path(path)
|
|
_expect(DirAccess.dir_exists_absolute(directory) and DirAccess.get_directories_at(directory).is_empty(), "save package %s holds only files" % name)
|
|
var files := {}
|
|
for file_name: String in DirAccess.get_files_at(directory):
|
|
var bytes := FileAccess.get_file_as_bytes(directory.path_join(file_name))
|
|
files[file_name] = {"sha256": Scenes.sha256(bytes), "bytes": bytes.size(), "base64": Marshalls.raw_to_base64(bytes)}
|
|
_expect(files.has("manifest.json") and files.has("world.bin"), "save package %s has its manifest and world" % name)
|
|
var package := extra.duplicate(true)
|
|
package["name"] = name
|
|
package["files"] = files
|
|
return package
|
|
|
|
|
|
func _expect(condition: bool, message: String) -> void:
|
|
_checks += 1
|
|
if not condition:
|
|
_failures += 1
|
|
push_error(message)
|