extends SceneTree const ManaOutage = preload("res://tests/helpers/mana_outage.gd") ## Real construction, hired porter and purchased stock; failure injection is ## limited to route closures, capacity pressure and expired cargo. var _checks := 0 var _failures := 0 var _runtime: Variant var _clock: Variant var _state: Variant var _source: StringName var _destination: StringName var _loaded: Dictionary var _reserved: Dictionary const REQUEST := &"supply.bridge_test" const PORTER := &"staff_gina" class LateFailInventory extends InventoryService: var fail_delivery := true func transfer_available(source_inventory_id: StringName, destination_inventory_id: StringName, item_id: StringName, quantity: int, operation_id: StringName = &"", absolute_minute: int = -1) -> Dictionary: var result := super.transfer_available(source_inventory_id, destination_inventory_id, item_id, quantity, operation_id, absolute_minute) if fail_delivery and String(source_inventory_id).begins_with("cargo:") and result[&"ok"]: return {&"ok": false, &"code": &"INJECTED_LATE_FAILURE"} return result func _initialize() -> void: call_deferred("_run") func _run() -> void: print("Supply bridge: real movement, cargo conservation and recovery") _runtime = root.get_node("SimulationRuntime") _clock = root.get_node("GameClock") _state = root.get_node("GameState") _clock.reset(1, 6, 0) _state.reset() _expect(_runtime.initialize(_clock, _state, 653322)[&"valid"], "Runtime initializes") _clock.set_paused(true) _runtime.configure_save_policy({&"enabled": false, &"daily_checkpoint_enabled": false}) for row: Array in [[&"warehouse", Vector3i(-8, 0, 1)], [&"kitchen", Vector3i(2, 0, 1)], [&"staff_door", Vector3i(0, 0, 1)]]: _expect(_command(&"build_facility", {&"definition_id": row[0], &"origin": row[1]}), "build %s" % row[0]) _clock.advance_minutes(180) for facility: FacilityInstance in _runtime.facility_service.get_instances(): if facility.definition_id == &"warehouse": _source = facility.instance_id if facility.definition_id == &"kitchen": _destination = facility.instance_id if _source.is_empty() or _destination.is_empty(): _expect(false, "normal construction completes") _finish() return _expect(_command(&"hire_staff_candidate", {&"candidate_id": PORTER}), "hire the catalogue porter") _expect(_command(&"set_staff_work_assignment", {&"staff_id": PORTER, &"facility_id": _source, &"template_id": &"DAY"}), "assign porter to a repeating real shift") _expect(_worker().state == StaffRuntime.State.COMMUTING, "porter assignment begins a real warehouse commute") for minute in range(40): if _worker().state == StaffRuntime.State.AVAILABLE: break _clock.advance_minutes(1) _expect(_worker().state == StaffRuntime.State.AVAILABLE and StaffCommuteService.is_at_facility(_worker(), _runtime.facility_service.get_instance(_source)), "porter checks in physically before taking a supply job") _expect(_command(&"purchase_supplies", {&"warehouse_id": _source, &"item_id": SupplyCatalog.RAW_FOOD, &"quantity": 8}), "purchase the source stock through the ledger") _expect(_command(&"create_logistics_request", {&"request_id": REQUEST, &"source_inventory_id": _inventory(_source), &"destination_inventory_id": _inventory(_destination), &"item_requirements": {SupplyCatalog.RAW_FOOD: 8}}), "create the reserved supply request") _expect(_quantity(_inventory(_destination)) == 0, "request creation does not deliver anything") _test_manual_dispatch_boundary() _reserved = _runtime.create_snapshot() var check_in_cell := _worker().current_cell _clock.advance_minutes(1) _expect(_request().assigned_carrier_id == PORTER and _worker().current_cell.distance_to(check_in_cell) <= 1.0, "dispatcher selects the checked-in employee without teleporting") _wait_for(LogisticsRequest.State.DELIVERING, 40) _expect(_request().state == LogisticsRequest.State.DELIVERING and _worker().current_cell.distance_to(check_in_cell) <= 1.0, "physical pickup starts delivery from the checked-in warehouse access without teleporting") if _request().state != LogisticsRequest.State.DELIVERING: _finish() return _expect(_quantity(_inventory(_source)) == 0 and _quantity(_cargo()) == 8 and _quantity(_inventory(_destination)) == 0, "pickup moves all eight units into owned cargo only") _expect(_crosslinks(), "loaded Request, Task, reservations and cargo agree") _loaded = _runtime.create_snapshot() _expect(_runtime.restore_snapshot(_loaded), "mid-delivery Runtime snapshot restores") _test_reserve_outage() _test_kitchen_reserve_outage() _test_same_floor_access() _test_ownership_and_replay() _test_capacity_wait() _test_route_recovery() _test_unavailable_and_expiry() _test_restore_guards() _test_pickup_retry() _test_source_closes_after_assignment() _test_source_closes_after_loading() _test_unavailable_before_pickup() _test_partial_expiry_return() _test_shift_boundary() _test_late_delivery_failure() _finish() func _test_same_floor_access() -> void: var upper := FacilityInstance.new().configure(&"upper", &"warehouse", {&"origin": Vector3i(2, 1, 1), &"occupied_cells": [Vector3i(2, 1, 1)]}) _expect(not SupplyLogisticsBridge._cell_touches_facility(Vector3i(2, 0, 1), upper), "goods cannot be picked up from the floor below a warehouse") _expect(SupplyLogisticsBridge._cell_touches_facility(Vector3i(1, 1, 1), upper), "same-floor doorway remains a valid transfer boundary") _expect(not _runtime.supply_logistics.find_facility_access_path(Vector3i(2, 0, 1), upper).get(&"reachable", false), "source access routing cannot substitute a corridor below the destination floor") func _test_ownership_and_replay() -> void: var owned := _owned_snapshot() var manual: CommandResult = _runtime.submit_command(&"advance_logistics_request", {&"request_id": REQUEST}) _expect(not manual.is_success() and manual.details.get(&"reason") == &"SUPPLY_DRIVER_REQUIRED", "external advance cannot bypass real arrival") _expect(_owned_snapshot() == owned, "rejected manual advance leaves inventory, Task and carrier ownership unchanged") _expect(_runtime.restore_snapshot(_loaded), "rewind the rejected command audit before deterministic replay") var task_id := _worker().current_task_id _expect(not _runtime.staff_service.cancel_task(task_id).is_success(), "ordinary cancellation cannot orphan loaded cargo") _expect(not _runtime.staff_service.remove_staff(PORTER).is_success(), "loaded porter cannot be removed") _expect(not _runtime.staff_service.retire_staff(PORTER).is_success() and not _worker().is_retiring, "retirement rejects atomically while hauling") _expect(not _runtime.staff_service.progress_task(task_id, 1, _clock.absolute_minute + 2).is_success(), "generic Task progress cannot bypass delivery") _wait_for(LogisticsRequest.State.COMPLETED, 40) _expect(_request().state == LogisticsRequest.State.COMPLETED and _quantity(_inventory(_destination)) == 8, "arrival transfers the purchased stock into kitchen storage") _expect(_quantity(_cargo()) == 0 and _worker().current_task_id.is_empty() and _worker().carried_inventory_id.is_empty(), "completion clears cargo and employee ownership together") _expect(_runtime.logistics_dispatcher.get_reserved_load(PORTER) == 0 and _crosslinks(), "completion releases exact dispatcher weight") var completed: Dictionary = _runtime.create_snapshot() var end_minute: int = _clock.absolute_minute _expect(_runtime.restore_snapshot(_loaded), "rewind to a loaded employee") _clock.advance_minutes(end_minute - _clock.absolute_minute) _expect(_runtime.create_snapshot() == completed, "loaded save replay produces identical inventory, Tasks, positions and accounts") func _test_manual_dispatch_boundary() -> void: var owned := _owned_snapshot() var manual: CommandResult = _runtime.submit_command(&"dispatch_logistics", {&"carriers": {&"synthetic_porter": {&"capacity": 100, &"current_load": 0, &"path_minutes": 0, &"role": &"logistics"}}}) _expect(manual.is_success() and manual.details[&"assignments"].is_empty(), "external synthetic carrier cannot claim a managed supply request") _expect(_owned_snapshot() == owned, "manual dispatch does not change reserved stock, Staff Task or request ownership") func _owned_snapshot() -> Dictionary: return {&"inventory": _runtime.inventory_service.create_snapshot(), &"staff": _runtime.staff_service.create_snapshot(), &"dispatcher": _runtime.logistics_dispatcher.create_snapshot(), &"request": _request().create_snapshot()} func _test_capacity_wait() -> void: _expect(_runtime.restore_snapshot(_loaded), "restore capacity scenario") _runtime.inventory_service.add_stack(_inventory(_destination), SupplyCatalog.BASIC_MEAL, 40, 100, -1, _clock.absolute_minute) _clock.advance_minutes(30) _expect(_request().state == LogisticsRequest.State.DELIVERING and _request().state_reason == "DESTINATION_FULL", "capacity becoming full after pickup pauses delivery") _expect(_quantity(_cargo()) == 8 and _runtime.logistics_dispatcher.get_reserved_load(PORTER) == 8, "full destination retains all cargo and weight ownership") _expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "waiting loaded cargo is restorable") _runtime.inventory_service.transfer_available(_inventory(_destination), &"test.capacity_sink", SupplyCatalog.BASIC_MEAL, 40, &"", _clock.absolute_minute) _wait_for(LogisticsRequest.State.COMPLETED, 10) _expect(_quantity(_inventory(_destination)) == 8 and _quantity(_cargo()) == 0, "freeing storage resumes once without losing or duplicating stock") func _test_route_recovery() -> void: _expect(_runtime.restore_snapshot(_loaded), "restore route scenario") var target := _task().target_cell _runtime.path_service.set_cell_temporary_block(target, true) _clock.advance_minutes(40) _expect(_request().state == LogisticsRequest.State.DELIVERING and _quantity(_cargo()) == 8, "blocked delivery route never releases carried stock") _expect(_worker().current_task_id == _task().task_id and _crosslinks(), "stuck recovery keeps employee and Task linked") _expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "route-blocked cargo saves and restores") _runtime.path_service.set_cell_temporary_block(target, false) _wait_for(LogisticsRequest.State.COMPLETED, 40) _expect(_request().state == LogisticsRequest.State.COMPLETED and _quantity(_inventory(_destination)) == 8, "restoring the real route resumes delivery") func _test_unavailable_and_expiry() -> void: _expect(_runtime.restore_snapshot(_loaded), "restore unavailable scenario") _worker().health = 0 _worker().transition_to(StaffRuntime.State.INCAPACITATED, &"TEST", _clock.absolute_minute) var cell := _worker().current_cell _clock.advance_minutes(3) _expect(_worker().current_cell == cell and _quantity(_cargo()) == 8, "incapacitated porter does not move or lose cargo") _expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "incapacitated cargo owner is restorable") _worker().health = 100 _worker().transition_to(StaffRuntime.State.MOVING_TO_TASK, &"TEST_RECOVERED", _clock.absolute_minute) _wait_for(LogisticsRequest.State.COMPLETED, 40) _expect(_request().state == LogisticsRequest.State.COMPLETED, "employee recovery resumes the retained delivery") _expect(_runtime.restore_snapshot(_loaded), "restore spoilage scenario") _worker().health = 0 _worker().transition_to(StaffRuntime.State.INCAPACITATED, &"TEST", _clock.absolute_minute) var inventory_snapshot: Dictionary = _runtime.inventory_service.create_snapshot() for owner: Dictionary in inventory_snapshot[&"inventories"]: if owner[&"owner_inventory_id"] == String(_cargo()): for stack: Dictionary in owner[&"stacks"]: stack[&"expires_at"] = _clock.absolute_minute + 1 _expect(_runtime.inventory_service.restore_snapshot(inventory_snapshot), "inject a cargo expiry boundary") _clock.advance_minutes(1) _expect(_request().state == LogisticsRequest.State.CANCELLED and _quantity(_cargo()) == 0, "expired cargo enters inventory waste and closes the impossible delivery") _expect(_worker().state == StaffRuntime.State.INCAPACITATED and _worker().current_task_id.is_empty(), "spoilage cleanup preserves incapacitation while releasing the Task") _expect(_runtime.logistics_dispatcher.get_reserved_load(PORTER) == 0 and _crosslinks(), "spoilage releases weight without a ghost assignment") func _test_restore_guards() -> void: _expect(_runtime.restore_snapshot(_loaded), "restore crosslink scenario") var stable: Dictionary = _runtime.create_snapshot() var bad := stable.duplicate(true) for task: Dictionary in bad[&"systems"][&"runtime"][&"staff"][&"tasks"]: if task[&"task_type"] == String(SupplyLogisticsBridge.DELIVERY_TYPE): task[&"target_cell"] = [99, 99, 1] _expect(not _runtime.restore_snapshot(bad) and _runtime.create_snapshot() == stable, "restore rejects a remote delivery target atomically") var worker := _worker() worker.carried_inventory_id = &"cargo:somebody_else" _expect(not _crosslinks(), "crosslink validator rejects stolen cargo ownership") worker.carried_inventory_id = _cargo() var task := _task() var saved_type := task.task_type task.task_type = SupplyLogisticsBridge.PICKUP_TYPE _expect(not _crosslinks(), "crosslink validator rejects pickup Task paired with loaded request") task.task_type = saved_type _expect(_crosslinks(), "valid ownership survives rejected candidates") func _test_pickup_retry() -> void: _expect(_runtime.restore_snapshot(_reserved), "restore before pickup dispatch") _clock.advance_minutes(1) var old_task := _worker().current_task_id var stopped: Dictionary = _runtime.supply_logistics.handle_path_stuck(old_task, _clock.absolute_minute) _expect(stopped[&"ok"] and _request().state == LogisticsRequest.State.BLOCKED, "unloaded route failure blocks the request and cancels the approach") _expect(_runtime.inventory_service.available_quantity(_inventory(_source), SupplyCatalog.RAW_FOOD) == 8 and _worker().current_task_id.is_empty(), "failed approach releases source reservation and employee together") _expect(_runtime.logistics_dispatcher.get_reserved_load(PORTER) == 0 and _crosslinks(), "failed approach retains no dispatcher load") _expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "blocked unloaded request restores") _wait_for(LogisticsRequest.State.DELIVERING, 40) _expect(_request().state == LogisticsRequest.State.DELIVERING and _worker().current_task_id != old_task, "retries reserve stock again and create a fresh attempt Task") _wait_for(LogisticsRequest.State.COMPLETED, 40) _expect(_quantity(_inventory(_destination)) == 8 and _quantity(_cargo()) == 0, "retry delivers the same stock exactly once") func _test_source_closes_after_assignment() -> void: _expect(_runtime.restore_snapshot(_reserved), "restore source-closure approach scenario") _clock.advance_minutes(1) var old_task := _worker().current_task_id _expect(_request().state == LogisticsRequest.State.ASSIGNED and not old_task.is_empty(), "source closure begins after assigning the real pickup Task") _expect(_command(&"set_facility_policy", {&"facility_id": _source, &"patch": {&"business_open": false}}), "close the source while its porter approaches") _wait_for(LogisticsRequest.State.BLOCKED, 40) _expect(_request().state == LogisticsRequest.State.BLOCKED and _request().state_reason == "SOURCE_CLOSED", "arrival at a newly closed source blocks before loading") _expect(_quantity(_inventory(_source)) == 8 and _quantity(_cargo()) == 0 and _quantity(_inventory(_destination)) == 0, "closed source retains every purchased unit without transfer") _expect(_runtime.inventory_service.available_quantity(_inventory(_source), SupplyCatalog.RAW_FOOD) == 8 and _worker().current_task_id.is_empty(), "blocked pickup releases both source stock and employee reservations") _expect(_runtime.logistics_dispatcher.get_reserved_load(PORTER) == 0 and _crosslinks(), "closed-source cleanup retains no dispatcher or Task ghost") _expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "blocked closed-source state passes strict Runtime restore") _expect(_command(&"set_facility_policy", {&"facility_id": _source, &"patch": {&"business_open": true}}), "reopen the source for a retry") _wait_for(LogisticsRequest.State.DELIVERING, 40) _expect(_request().state == LogisticsRequest.State.DELIVERING and _worker().current_task_id != old_task and _quantity(_cargo()) == 8, "reopening retries with a fresh Task and physical pickup") var loaded_cell := _worker().current_cell _wait_for(LogisticsRequest.State.COMPLETED, 40) _expect(_request().state == LogisticsRequest.State.COMPLETED and _worker().current_cell != loaded_cell and _quantity(_inventory(_destination)) == 8, "reopened source stock reaches the kitchen by actual porter movement") _expect(_quantity(_inventory(_source)) == 0 and _quantity(_cargo()) == 0 and _runtime.logistics_dispatcher.get_reserved_load(PORTER) == 0 and _crosslinks(), "reopened source delivery consumes and releases ownership exactly once") func _test_source_closes_after_loading() -> void: _expect(_runtime.restore_snapshot(_loaded), "restore loaded source-closure scenario") _expect(_command(&"set_facility_policy", {&"facility_id": _source, &"patch": {&"business_open": false}}), "close the source after loading") var cell := _worker().current_cell _wait_for(LogisticsRequest.State.COMPLETED, 40) _expect(_request().state == LogisticsRequest.State.COMPLETED and _worker().current_cell != cell and _quantity(_inventory(_destination)) == 8, "already-loaded porter can finish delivery to an open destination") _expect(_quantity(_cargo()) == 0 and _runtime.logistics_dispatcher.get_reserved_load(PORTER) == 0 and _crosslinks(), "delivery after source closure clears cargo and carrier ownership") func _test_unavailable_before_pickup() -> void: _expect(_runtime.restore_snapshot(_reserved), "restore unloaded health failure") _clock.advance_minutes(1) _worker().health = 0 _worker().transition_to(StaffRuntime.State.INCAPACITATED, &"TEST", _clock.absolute_minute) _clock.advance_minutes(1) _expect(_request().state == LogisticsRequest.State.BLOCKED and _worker().current_task_id.is_empty(), "incapacitation before pickup releases approach ownership") _expect(_worker().state == StaffRuntime.State.INCAPACITATED and _runtime.inventory_service.available_quantity(_inventory(_source), SupplyCatalog.RAW_FOOD) == 8, "unloaded health failure preserves health state and releases reserved food") _expect(_runtime.restore_snapshot(_runtime.create_snapshot()) and _crosslinks(), "unloaded health failure saves without expired reservation links") func _test_partial_expiry_return() -> void: _expect(_runtime.restore_snapshot(_loaded), "restore partial-spoilage scenario") var inventory: Dictionary = _runtime.inventory_service.create_snapshot() for owner: Dictionary in inventory[&"inventories"]: if owner[&"owner_inventory_id"] == String(_cargo()): owner[&"stacks"][0][&"quantity"] = 4 _expect(_runtime.inventory_service.restore_snapshot(inventory), "split loaded cargo into two expiry lots") _runtime.inventory_service.add_stack(_cargo(), SupplyCatalog.RAW_FOOD, 4, 100, _clock.absolute_minute + 1, _clock.absolute_minute) _clock.advance_minutes(1) _expect(_request().state == LogisticsRequest.State.DELIVERING and _task().task_type == SupplyLogisticsBridge.RETURN_TYPE and _quantity(_cargo()) == 4, "partial expiry retargets the surviving cargo to its source") _expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "returning cargo saves its destination in the existing Task") _worker().health = 0 _worker().transition_to(StaffRuntime.State.INCAPACITATED, &"TEST", _clock.absolute_minute) _clock.advance_minutes(1) _expect(_crosslinks(), "unavailability reason cannot erase return destination") _worker().health = 100 _worker().transition_to(StaffRuntime.State.MOVING_TO_TASK, &"RECOVERED", _clock.absolute_minute) _wait_for(LogisticsRequest.State.CANCELLED, 40) _expect(_request().state_reason == "CARGO_EXPIRED_RETURNED" and _quantity(_inventory(_source)) == 4 and _quantity(_inventory(_destination)) == 0, "return unloads only unspoiled stock at the original warehouse") _expect(_quantity(_cargo()) == 0 and _runtime.logistics_dispatcher.get_reserved_load(PORTER) == 0 and _crosslinks(), "partial-expiry return releases all cargo ownership") func _test_shift_boundary() -> void: _expect(_runtime.restore_snapshot(_loaded), "restore end-of-shift scenario") var target := _task().target_cell _runtime.path_service.set_cell_temporary_block(target, true) _clock.advance_minutes(1081 - _clock.absolute_minute) _expect(_worker().is_overtime and not _worker().current_task_id.is_empty() and _quantity(_cargo()) == 8, "18:00 shift end retains loaded non-interruptible work") _expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "overtime delivery is restorable") _runtime.path_service.set_cell_temporary_block(target, false) _wait_for(LogisticsRequest.State.COMPLETED, 40) _clock.advance_minutes(1) _expect(_worker().state == StaffRuntime.State.OFF_DUTY and _worker().current_task_id.is_empty() and _quantity(_inventory(_destination)) == 8, "employee ends the shift after safe unloading") func _test_late_delivery_failure() -> void: _expect(_runtime.restore_snapshot(_loaded), "restore delivery transaction failure") var fault := LateFailInventory.new() _expect(fault.restore_snapshot(_runtime.inventory_service.create_snapshot()), "install failure after inventory transfer has already mutated") _runtime.inventory_service = fault _clock.advance_minutes(30) _expect(_request().state == LogisticsRequest.State.DELIVERING and _request().state_reason == "DELIVERY_RETRY", "late inventory failure rolls the request back to owned delivery") _expect(_quantity(_cargo()) == 8 and _quantity(_inventory(_destination)) == 0 and _runtime.logistics_dispatcher.get_reserved_load(PORTER) == 8, "failed delivery reverses all physical transfer and dispatcher changes") _expect(_crosslinks() and not _worker().current_task_id.is_empty(), "failed delivery preserves the employee and Task pair") fault.fail_delivery = false _wait_for(LogisticsRequest.State.COMPLETED, 10) _expect(_request().state == LogisticsRequest.State.COMPLETED and _quantity(_inventory(_destination)) == 8 and _quantity(_cargo()) == 0, "clearing transient failure retries the same operation exactly once") _expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "transaction retry leaves a restorable Runtime") func _wait_for(state: int, minutes: int) -> void: for index: int in minutes: if _request().state == state: return _clock.advance_minutes(1) func _command(type: StringName, payload: Dictionary) -> bool: var result: CommandResult = _runtime.submit_command(type, payload) if not result.is_success(): print(result.message, result.details) return result.is_success() func _inventory(id: StringName) -> StringName: return _runtime.facility_service.get_instance(id).local_inventory_id func _request() -> LogisticsRequest: return _runtime.logistics_requests[REQUEST] func _worker() -> StaffRuntime: return _runtime.staff_service.get_staff(PORTER) func _task() -> StaffTask: return _runtime.staff_service.get_task(_worker().current_task_id) func _cargo() -> StringName: return StringName("cargo:%s" % PORTER) func _quantity(inventory_id: StringName) -> int: return _runtime.inventory_service.total_quantity(inventory_id, SupplyCatalog.RAW_FOOD) func _crosslinks() -> bool: return SupplyLogisticsBridge.validate_crosslinks(_runtime.logistics_requests, _runtime.staff_service, _runtime.inventory_service, _runtime.facility_service) func _expect(condition: bool, message: String) -> void: _checks += 1 if not condition: _failures += 1 push_error(message) func _finish() -> void: print("%s: %d checks / %d failures" % ["PASS" if _failures == 0 else "FAIL", _checks, _failures]) quit(_failures) func _test_reserve_outage() -> void: _expect(_runtime.restore_snapshot(_loaded), "restore physically loaded cargo for reserve outage") ManaOutage.hold(_runtime, _state) _clock.advance_minutes(30) _expect(_request().state == LogisticsRequest.State.DELIVERING and _quantity(_cargo()) == 8 and _quantity(_inventory(_destination)) == 0, "outage retains loaded cargo without delivering into stopped facility") _expect(_crosslinks(), "outage preserves Request Task inventory ownership") _expect(_runtime.restore_snapshot(_runtime.create_snapshot()), "cargo waiting through outage restores") ManaOutage.release(_runtime, _state) _wait_for(LogisticsRequest.State.COMPLETED, 60) _expect(_request().state == LogisticsRequest.State.COMPLETED and _quantity(_cargo()) == 0 and _quantity(_inventory(_destination)) == 8, "recovered power delivers cargo exactly once") _expect(_crosslinks(), "recovered delivery ownership reconciles") _expect(_runtime.restore_snapshot(_loaded), "rewind outage drill for remaining logistics scenarios") func _test_kitchen_reserve_outage() -> void: _expect(_runtime.restore_snapshot(_loaded), "restore real supply for cooking outage") _wait_for(LogisticsRequest.State.COMPLETED, 60) _expect(_command(&"hire_staff_candidate", {&"candidate_id": &"staff_chika"}), "hire kitchen employee") _expect(_command(&"set_staff_work_assignment", {&"staff_id": &"staff_chika", &"facility_id": _destination, &"template_id": &"DAY"}), "assign kitchen employee through production command") _expect(_command(&"set_kitchen_production", {&"facility_id": _destination, &"enabled": true, &"target_stock": 4}), "enable one real production batch") for minute in range(60): _clock.advance_minutes(1) if int(_runtime.kitchen_production.get_report(_destination)[&"progress_minutes"]) >= 3: break var before: Dictionary = _runtime.kitchen_production.get_report(_destination) _expect(int(before[&"progress_minutes"]) == 3 and not before[&"active_batch"].is_empty(), "physical employee starts and advances actual cooking") if before[&"active_batch"].is_empty(): _runtime.restore_snapshot(_loaded) return ManaOutage.hold(_runtime, _state) _clock.advance_minutes(30) var stopped: Dictionary = _runtime.kitchen_production.get_report(_destination) _expect(stopped[&"state"] == &"NO_POWER" and stopped[&"active_batch"] == before[&"active_batch"], "thirty stopped minutes preserve batch identity reservations and progress") _expect(_quantity(_inventory(_destination)) == 8 and _runtime.inventory_service.total_quantity(_inventory(_destination), SupplyCatalog.BASIC_MEAL) == 0, "outage neither consumes input nor creates meals") _expect(_runtime.kitchen_production.validate_crosslinks(), "stopped kitchen reservations remain owned") var saved: Dictionary = _runtime.create_snapshot() _expect(_runtime.restore_snapshot(saved) and _runtime.create_snapshot() == saved, "active cooking outage round trips through complete Runtime save") ManaOutage.release(_runtime, _state) _clock.advance_minutes(30) _expect(_quantity(_inventory(_destination)) == 4 and _runtime.inventory_service.total_quantity(_inventory(_destination), SupplyCatalog.BASIC_MEAL) == 4, "recovery consumes exactly four raw food and produces exactly four meals") _expect(_runtime.kitchen_production.get_report(_destination)[&"state"] == &"TARGET_REACHED" and _runtime.kitchen_production.validate_crosslinks(), "recovered batch releases reservations and stops at target") _expect(_runtime.restore_snapshot(_loaded), "rewind cooking outage scenario")