152 lines
12 KiB
GDScript
152 lines
12 KiB
GDScript
extends SceneTree
|
|
const PAIR_ROOT := "/Users/korizatou114/Projects/とりにく工房ゲーム制作部/artifacts/original-completion-2026-10-02/p03-current1299-logistics-dimension-native-r02/migration-pair"
|
|
const MODE := "write"
|
|
var checks:=0
|
|
var failures:=0
|
|
var runtime: Variant
|
|
var clock: Variant
|
|
var state: Variant
|
|
var job_id: StringName
|
|
var serial:=0
|
|
var journal: Array[Dictionary]=[]
|
|
func _initialize() -> void:call_deferred("run")
|
|
func expect(ok: bool,label: String) -> void:
|
|
checks+=1
|
|
print(("PASS " if ok else "FAIL ")+label)
|
|
if not ok:failures+=1;push_error("P03_INFLIGHT "+label)
|
|
func write_proof(name: String,value: Variant) -> void:
|
|
var path:=PAIR_ROOT.path_join(name)
|
|
expect(not FileAccess.file_exists(path),"fresh proof "+name)
|
|
var file:=FileAccess.open(path,FileAccess.WRITE)
|
|
expect(file!=null,"open proof "+name)
|
|
if file!=null:file.store_buffer(var_to_bytes(value));file.close()
|
|
func read_proof(name: String) -> Variant:
|
|
var data:=FileAccess.get_file_as_bytes(PAIR_ROOT.path_join(name))
|
|
expect(not data.is_empty(),"read whole proof "+name)
|
|
return bytes_to_var(data)
|
|
func command(kind: StringName,payload: Dictionary) -> CommandResult:
|
|
serial+=1
|
|
var result: CommandResult=runtime.submit_command(kind,payload,&"player",&"",0,-1,StringName("p03.inflight.%d"%serial))
|
|
expect(result.is_success(),"public paid command "+String(kind)+": "+result.message)
|
|
if not result.is_success():runtime.free();clock.free();state.free();quit(1)
|
|
return result
|
|
func copy_package(source: String,destination: String) -> void:
|
|
expect(DirAccess.make_dir_recursive_absolute(destination)==OK,"package destination "+destination)
|
|
for name: String in [SaveService.WORLD_FILE,SaveService.MANIFEST_FILE,SaveService.THUMBNAIL_FILE,SaveService.JOURNAL_FILE]:
|
|
var original:=FileAccess.get_file_as_bytes(source.path_join(name))
|
|
expect(not original.is_empty() and not FileAccess.file_exists(destination.path_join(name)),"fresh formal member "+name)
|
|
var file:=FileAccess.open(destination.path_join(name),FileAccess.WRITE)
|
|
expect(file!=null,"open formal member "+name)
|
|
if file!=null:file.store_buffer(original);file.close()
|
|
expect(original==FileAccess.get_file_as_bytes(destination.path_join(name)),"complete formal member "+name)
|
|
func observe(event: SimulationDomainEvent) -> void:journal.append(event.to_dictionary())
|
|
func capture(label: String) -> void:
|
|
var snapshot: Dictionary=runtime.create_snapshot()
|
|
write_proof(MODE+"-"+label+".var",snapshot)
|
|
if MODE=="read":expect(var_to_bytes(snapshot)==var_to_bytes(read_proof("write-"+label+".var")),"entire separate-PID snapshot "+label)
|
|
func run() -> void:
|
|
root.get_node("GameClock").set_paused(true);root.get_node("GameClock").set_process(false)
|
|
root.get_node("SimulationRuntime").configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false})
|
|
runtime=load("res://autoload/simulation_runtime.gd").new()
|
|
clock=load("res://autoload/game_clock.gd").new();state=load("res://autoload/game_state.gd").new()
|
|
clock.reset(1,6,0);state.reset();expect(runtime.initialize(clock,state,42586)[&"valid"],"current canonical initialization")
|
|
clock.set_paused(true);runtime.configure_save_policy({&"enabled":false,&"daily_checkpoint_enabled":false,&"auto_migrate":false})
|
|
var paths: Array[String]=FacilityCatalog.FACILITY_PATHS+FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS+FacilityCatalog.RESCUE_FACILITY_PATHS
|
|
var slot: String="user://p03-inflight-dimension/manual"
|
|
if MODE=="write":
|
|
expect(DirAccess.make_dir_recursive_absolute(PAIR_ROOT)==OK,"fresh external proof directory")
|
|
paths.append("res://tests/fixtures/legacy_premium_room.tres")
|
|
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"explicit archived dimension fixture")
|
|
for row: Array in [[&"warehouse",Vector3i(-8,0,1)],[&"kitchen",Vector3i(2,0,1)],[&"staff_door",Vector3i(0,0,1)]]:
|
|
command(&"build_facility",{&"definition_id":row[0],&"origin":row[1]})
|
|
clock.advance_minutes(180)
|
|
for y: int in [1,2,3]:
|
|
command(&"build_facility",{&"definition_id":&"guest_stairs",&"origin":Vector3i(4,y,0)})
|
|
clock.advance_minutes(runtime.definition_registry.get_facility(&"guest_stairs").build_minutes)
|
|
command(&"build_facility",{&"definition_id":&"reception",&"origin":Vector3i(-6,0,0)})
|
|
clock.advance_minutes(runtime.definition_registry.get_facility(&"reception").build_minutes)
|
|
command(&"build_facility",{&"definition_id":&"premium_room",&"origin":Vector3i(-6,2,0)})
|
|
clock.advance_minutes(7)
|
|
for job: ConstructionJob in runtime.construction_service.get_jobs():
|
|
if job.definition_id==&"premium_room" and not job.is_terminal():job_id=job.job_id
|
|
expect(not job_id.is_empty(),"real paid old-size construction is in flight")
|
|
if job_id.is_empty():runtime.free();clock.free();state.free();quit(1);return
|
|
var warehouse: FacilityInstance
|
|
var kitchen: FacilityInstance
|
|
for room: FacilityInstance in runtime.facility_service.get_instances():
|
|
if room.definition_id==&"warehouse":warehouse=room
|
|
if room.definition_id==&"kitchen":kitchen=room
|
|
expect(warehouse!=null and kitchen!=null,"real paid supply endpoints completed")
|
|
if warehouse==null or kitchen==null:runtime.free();clock.free();state.free();quit(1);return
|
|
command(&"hire_staff_candidate",{&"candidate_id":&"staff_gina"})
|
|
command(&"set_staff_work_assignment",{&"staff_id":&"staff_gina",&"facility_id":warehouse.instance_id,&"template_id":&"DAY"})
|
|
command(&"purchase_supplies",{&"warehouse_id":warehouse.instance_id,&"item_id":SupplyCatalog.RAW_FOOD,&"quantity":8})
|
|
command(&"set_kitchen_production",{&"facility_id":kitchen.instance_id,&"enabled":true,&"target_stock":4})
|
|
var loaded:=false
|
|
for minute: int in range(60):
|
|
clock.advance_minutes(1)
|
|
var worker: StaffRuntime=runtime.staff_service.get_staff(&"staff_gina")
|
|
if not worker.carried_inventory_id.is_empty():loaded=true;break
|
|
expect(loaded,"normally hired porter actually picks up purchased cargo")
|
|
if not loaded:runtime.free();clock.free();state.free();quit(1);return
|
|
var porter: StaffRuntime=runtime.staff_service.get_staff(&"staff_gina")
|
|
expect(runtime.inventory_service.total_quantity(porter.carried_inventory_id,SupplyCatalog.RAW_FOOD)==4,"actual cargo contains four paid food units from an eight-unit purchase")
|
|
var legacy: Dictionary=runtime.create_snapshot()
|
|
var original_job: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
|
expect(original_job[&"progress"]>0 and original_job[&"reserved_cells"].size()==6,"old-size job is partly paid and reserved")
|
|
expect(SaveService.save_snapshot(slot,legacy)[&"ok"],"write actual formal source")
|
|
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("legacy/formal"))
|
|
write_proof("legacy.var",legacy);write_proof("original-job.var",original_job)
|
|
paths.erase("res://tests/fixtures/legacy_premium_room.tres");paths.append("res://data/facilities/expansion/premium_room.tres")
|
|
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"switch to current dimensions without fake graph changes")
|
|
var preview: Dictionary=runtime.preview_facility_dimensions_at_path(slot)
|
|
expect(preview.get(&"ok",false) and var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration preview preserves entire moving live world")
|
|
var migrated: Dictionary=runtime.migrate_facility_dimensions_at_path(slot,&"",String(preview.get(&"source_digest","")))
|
|
expect(migrated.get(&"ok",false) and migrated.get(&"backup_created",false),"formal migration makes verified original backup")
|
|
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(legacy),"migration never advances live guest or job")
|
|
var backup:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
|
expect(backup.get(&"ok",false) and var_to_bytes(backup.get(&"snapshot",{}))==var_to_bytes(legacy),"backup contains entire old moving state")
|
|
copy_package(ProjectSettings.globalize_path(slot),PAIR_ROOT.path_join("migrated/formal"))
|
|
copy_package(ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX),PAIR_ROOT.path_join("backup/formal"))
|
|
write_proof("identity.var",{&"job_id":job_id,&"serial":serial})
|
|
else:
|
|
paths.append("res://data/facilities/expansion/premium_room.tres")
|
|
expect(runtime.definition_registry.rebuild_from_paths(paths)[&"valid"],"reader current dimension registry")
|
|
var identity: Dictionary=read_proof("identity.var");job_id=identity[&"job_id"];serial=identity[&"serial"]
|
|
copy_package(PAIR_ROOT.path_join("backup/formal"),ProjectSettings.globalize_path(slot+SaveService.MIGRATION_BACKUP_SUFFIX))
|
|
copy_package(PAIR_ROOT.path_join("migrated/formal"),ProjectSettings.globalize_path(slot))
|
|
var old:=SaveService.load_snapshot(slot+SaveService.MIGRATION_BACKUP_SUFFIX)
|
|
expect(old.get(&"ok",false) and runtime.restore_snapshot(old.get(&"snapshot",{})),"separate PID restores actual original backup")
|
|
expect(var_to_bytes(runtime.create_snapshot())==var_to_bytes(read_proof("legacy.var")),"whole old guest/job backup replay is exact")
|
|
var loaded:=SaveService.load_snapshot(slot)
|
|
expect(loaded.get(&"ok",false) and runtime.restore_snapshot(loaded.get(&"snapshot",{})),"actual migrated formal package restores")
|
|
var original: Dictionary=read_proof("original-job.var")
|
|
var actual: Dictionary=runtime.construction_service.get_job(job_id).create_snapshot()
|
|
expect(actual[&"reserved_cells"].size()==4 and actual[&"progress"]==original[&"progress"] and actual[&"construction_cost"]==original[&"construction_cost"] and actual[&"started_at"]==original[&"started_at"],"migration preserves actual paid work and changes footprint only")
|
|
expect(not runtime.get_operations_report().get(&"enabled",false),"scope remains controlled Operations OFF")
|
|
expect(runtime.domain_events.subscribe(&"*",&"p03.inflight.uncapped",Callable(self,"observe")),"subscribe whole uncapped continuation journal")
|
|
capture("checkpoint")
|
|
clock.advance_minutes(1);capture("next1")
|
|
expect(SupplyLogisticsBridge.validate_crosslinks(runtime.logistics_requests,runtime.staff_service,runtime.inventory_service,runtime.facility_service),"actual cargo crosslinks after first continued minute")
|
|
clock.advance_minutes(1);capture("next2")
|
|
clock.advance_minutes(8);capture("next10")
|
|
clock.advance_minutes(150);capture("final160")
|
|
var porter: StaffRuntime=runtime.staff_service.get_staff(&"staff_gina")
|
|
var delivered:=0
|
|
for request: LogisticsRequest in runtime.logistics_requests.values():
|
|
if request.state==LogisticsRequest.State.COMPLETED and request.item_requirements.has(SupplyCatalog.RAW_FOOD):delivered+=1
|
|
expect(delivered==2 and porter.carried_inventory_id.is_empty(),"two real four-unit shipments complete and releases porter cargo")
|
|
var kitchen: FacilityInstance
|
|
for room: FacilityInstance in runtime.facility_service.get_instances():
|
|
if room.definition_id==&"kitchen":kitchen=room
|
|
expect(kitchen!=null and runtime.inventory_service.total_quantity(kitchen.local_inventory_id,SupplyCatalog.RAW_FOOD)==8,"all eight purchased units actually arrive at kitchen")
|
|
expect(SupplyLogisticsBridge.validate_crosslinks(runtime.logistics_requests,runtime.staff_service,runtime.inventory_service,runtime.facility_service),"all final physical cargo ownership crosslinks valid")
|
|
var completed: ConstructionJob=runtime.construction_service.get_job(job_id)
|
|
expect(completed.state==ConstructionJob.State.COMPLETED and runtime.facility_service.get_instance(completed.facility_instance_id).occupied_cells.size()==4,"resized paid job completes exactly once in actual Runtime")
|
|
expect(runtime.restore_snapshot(runtime.create_snapshot()),"final moving and construction world remains canonical")
|
|
write_proof(MODE+"-events.var",journal)
|
|
if MODE=="read":expect(var_to_bytes(journal)==var_to_bytes(read_proof("write-events.var")),"all uncapped continuation events match without deletion or remapping")
|
|
write_proof(MODE+"-result.var",{&"pid":OS.get_process_id(),&"checks":checks,&"failures":failures,&"job_id":job_id,&"events":journal.size()})
|
|
runtime.free();clock.free();state.free()
|
|
print("Logistics dimension formal "+MODE+": %d checks, %d failures"%[checks,failures]);quit(failures)
|