implements PLN-0038
This commit is contained in:
parent
6bd4c13d24
commit
77351a8813
@ -175,6 +175,24 @@ mod tests {
|
||||
use prometeu_hal::syscalls::caps;
|
||||
use prometeu_system::CrashReport;
|
||||
|
||||
fn halting_program() -> Vec<u8> {
|
||||
let code = assemble("HALT").expect("assemble");
|
||||
BytecodeModule {
|
||||
version: 0,
|
||||
const_pool: vec![],
|
||||
functions: vec![FunctionMeta {
|
||||
code_offset: 0,
|
||||
code_len: code.len() as u32,
|
||||
..Default::default()
|
||||
}],
|
||||
code,
|
||||
debug_info: None,
|
||||
exports: vec![],
|
||||
syscalls: vec![],
|
||||
}
|
||||
.serialize()
|
||||
}
|
||||
|
||||
fn invalid_game_cartridge() -> Cartridge {
|
||||
Cartridge {
|
||||
app_id: 7,
|
||||
@ -225,6 +243,20 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn valid_cartridge(app_mode: AppMode) -> Cartridge {
|
||||
Cartridge {
|
||||
app_id: 9,
|
||||
title: "Valid Cart".into(),
|
||||
app_version: "1.0.0".into(),
|
||||
app_mode,
|
||||
capabilities: caps::NONE,
|
||||
program: halting_program(),
|
||||
assets: AssetsPayloadSource::empty(),
|
||||
asset_table: vec![],
|
||||
preload: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_cartridge_transitions_to_app_crashes_when_vm_init_fails() {
|
||||
let mut firmware = Firmware::new(None);
|
||||
@ -268,4 +300,56 @@ mod tests {
|
||||
other => panic!("expected AppCrashes state, got {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reset_routes_hub_boot_target_to_splash_screen() {
|
||||
let mut firmware = Firmware::new(None);
|
||||
let mut hardware = Hardware::new();
|
||||
let signals = InputSignals::default();
|
||||
|
||||
firmware.boot_target = BootTarget::Hub;
|
||||
firmware.tick(&signals, &mut hardware);
|
||||
|
||||
assert!(matches!(firmware.state, FirmwareState::SplashScreen(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reset_routes_cartridge_boot_target_to_launch_hub() {
|
||||
let mut firmware = Firmware::new(None);
|
||||
let mut hardware = Hardware::new();
|
||||
let signals = InputSignals::default();
|
||||
|
||||
firmware.boot_target = BootTarget::Cartridge {
|
||||
path: "missing-cart".into(),
|
||||
debug: false,
|
||||
debug_port: 7777,
|
||||
};
|
||||
firmware.tick(&signals, &mut hardware);
|
||||
|
||||
assert!(matches!(firmware.state, FirmwareState::LaunchHub(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_cartridge_routes_system_apps_back_to_hub_home() {
|
||||
let mut firmware = Firmware::new(None);
|
||||
let mut hardware = Hardware::new();
|
||||
let signals = InputSignals::default();
|
||||
|
||||
firmware.load_cartridge(valid_cartridge(AppMode::System));
|
||||
firmware.tick(&signals, &mut hardware);
|
||||
|
||||
assert!(matches!(firmware.state, FirmwareState::HubHome(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn load_cartridge_routes_game_apps_to_game_running() {
|
||||
let mut firmware = Firmware::new(None);
|
||||
let mut hardware = Hardware::new();
|
||||
let signals = InputSignals::default();
|
||||
|
||||
firmware.load_cartridge(valid_cartridge(AppMode::Game));
|
||||
firmware.tick(&signals, &mut hardware);
|
||||
|
||||
assert!(matches!(firmware.state, FirmwareState::GameRunning(_)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -368,3 +368,63 @@ impl HostDebugger {
|
||||
self.last_fault_summary = Some(summary);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use prometeu_drivers::hardware::Hardware;
|
||||
use prometeu_hal::debugger_protocol::DebugCommand;
|
||||
|
||||
#[test]
|
||||
fn setup_boot_target_ignores_hub_and_non_debug_cartridges() {
|
||||
let mut debugger = HostDebugger::new();
|
||||
let mut firmware = Firmware::new(None);
|
||||
|
||||
debugger.setup_boot_target(&BootTarget::Hub, &mut firmware);
|
||||
assert!(!debugger.waiting_for_start);
|
||||
assert!(debugger.listener.is_none());
|
||||
|
||||
debugger.setup_boot_target(
|
||||
&BootTarget::Cartridge {
|
||||
path: "dummy".into(),
|
||||
debug: false,
|
||||
debug_port: 7777,
|
||||
},
|
||||
&mut firmware,
|
||||
);
|
||||
assert!(!debugger.waiting_for_start);
|
||||
assert!(debugger.listener.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn handle_command_updates_pause_and_step_flags_without_host_io() {
|
||||
let mut debugger = HostDebugger::new();
|
||||
let mut firmware = Firmware::new(None);
|
||||
let mut hardware = Hardware::new();
|
||||
|
||||
debugger.handle_command(DebugCommand::Pause, &mut firmware, &mut hardware);
|
||||
assert!(firmware.os.paused);
|
||||
|
||||
debugger.handle_command(DebugCommand::Resume, &mut firmware, &mut hardware);
|
||||
assert!(!firmware.os.paused);
|
||||
|
||||
debugger.handle_command(DebugCommand::StepFrame, &mut firmware, &mut hardware);
|
||||
assert!(!firmware.os.paused);
|
||||
assert!(firmware.os.debug_step_request);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn handle_command_start_leaves_waiting_for_start_mode() {
|
||||
let mut debugger = HostDebugger::new();
|
||||
let mut firmware = Firmware::new(None);
|
||||
let mut hardware = Hardware::new();
|
||||
|
||||
debugger.waiting_for_start = true;
|
||||
firmware.os.paused = true;
|
||||
|
||||
debugger.handle_command(DebugCommand::Start, &mut firmware, &mut hardware);
|
||||
|
||||
assert!(!debugger.waiting_for_start);
|
||||
assert!(!firmware.os.paused);
|
||||
}
|
||||
}
|
||||
|
||||
@ -604,6 +604,9 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
// These ignored tests intentionally cover host-dependent behavior that requires
|
||||
// real socket bind/connect coordination. Deterministic debugger state changes
|
||||
// are covered below the host layer in `debugger.rs`.
|
||||
#[test]
|
||||
#[ignore = "requires localhost TCP bind/connect; run via `cargo test -p prometeu-host-desktop-winit --lib -- --ignored`"]
|
||||
fn test_debug_port_opens() {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
{"type":"discussion","id":"DSC-0021","status":"done","ticket":"asset-entry-codec-enum-with-metadata","title":"Asset Entry Codec Enum Contract","created_at":"2026-04-09","updated_at":"2026-04-09","tags":["asset","runtime","codec","metadata"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0024","file":"lessons/DSC-0021-asset-entry-codec-enum-contract/LSN-0024-string-on-the-wire-enum-in-runtime.md","status":"done","created_at":"2026-04-09","updated_at":"2026-04-09"}]}
|
||||
{"type":"discussion","id":"DSC-0022","status":"done","ticket":"tile-bank-vs-glyph-bank-domain-naming","title":"Glyph Bank Domain Naming Contract","created_at":"2026-04-09","updated_at":"2026-04-10","tags":["gfx","runtime","naming","domain-model"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0025","file":"lessons/DSC-0022-glyph-bank-domain-naming/LSN-0025-rename-artifact-by-meaning-not-by-token.md","status":"done","created_at":"2026-04-10","updated_at":"2026-04-10"}]}
|
||||
{"type":"discussion","id":"DSC-0001","status":"done","ticket":"legacy-runtime-learn-import","title":"Import legacy runtime learn into discussion lessons","created_at":"2026-03-27","updated_at":"2026-03-27","tags":["migration","tech-debt"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0001","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0001-prometeu-learn-index.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0002","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0002-historical-asset-status-first-fault-and-return-contract.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0003","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0003-historical-audio-status-first-fault-and-return-contract.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0004","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0004-historical-cartridge-boot-protocol-and-manifest-authority.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0005","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0005-historical-game-memcard-slots-surface-and-semantics.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0006","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0006-historical-gfx-status-first-fault-and-return-contract.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0007","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0007-historical-retired-fault-and-input-decisions.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0008","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0008-historical-vm-core-and-assets.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0009","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0009-mental-model-asset-management.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0010","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0010-mental-model-audio.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0011","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0011-mental-model-gfx.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0012","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0012-mental-model-input.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0013","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0013-mental-model-observability-and-debugging.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0014","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0014-mental-model-portability-and-cross-platform.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0015","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0015-mental-model-save-memory-and-memcard.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0016","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0016-mental-model-status-first-and-fault-thinking.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0017","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0017-mental-model-time-and-cycles.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"},{"id":"LSN-0018","file":"lessons/DSC-0001-runtime-learn-legacy-import/LSN-0018-mental-model-touch.md","status":"done","created_at":"2026-03-27","updated_at":"2026-03-27"}]}
|
||||
{"type":"discussion","id":"DSC-0002","status":"open","ticket":"runtime-edge-test-plan","title":"Agenda - Runtime Edge Test Plan","created_at":"2026-03-27","updated_at":"2026-04-20","tags":[],"agendas":[{"id":"AGD-0001","file":"workflow/agendas/AGD-0001-runtime-edge-test-plan.md","status":"done","created_at":"2026-03-27","updated_at":"2026-04-20"}],"decisions":[{"id":"DEC-0020","file":"workflow/decisions/DEC-0020-runtime-edge-coverage-governance-by-domain.md","status":"in_progress","created_at":"2026-04-20","updated_at":"2026-04-20","ref_agenda":"AGD-0001"}],"plans":[{"id":"PLN-0037","file":"workflow/plans/PLN-0037-runtime-edge-coverage-governance-foundation.md","status":"done","created_at":"2026-04-20","updated_at":"2026-04-20","ref_decisions":["DEC-0020"]},{"id":"PLN-0038","file":"workflow/plans/PLN-0038-firmware-and-host-dependent-domain-coverage-expansion.md","status":"open","created_at":"2026-04-20","updated_at":"2026-04-20","ref_decisions":["DEC-0020"]},{"id":"PLN-0039","file":"workflow/plans/PLN-0039-incremental-runtime-domain-suite-split-and-baselines.md","status":"open","created_at":"2026-04-20","updated_at":"2026-04-20","ref_decisions":["DEC-0020"]}],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0002","status":"open","ticket":"runtime-edge-test-plan","title":"Agenda - Runtime Edge Test Plan","created_at":"2026-03-27","updated_at":"2026-04-20","tags":[],"agendas":[{"id":"AGD-0001","file":"workflow/agendas/AGD-0001-runtime-edge-test-plan.md","status":"done","created_at":"2026-03-27","updated_at":"2026-04-20"}],"decisions":[{"id":"DEC-0020","file":"workflow/decisions/DEC-0020-runtime-edge-coverage-governance-by-domain.md","status":"in_progress","created_at":"2026-04-20","updated_at":"2026-04-20","ref_agenda":"AGD-0001"}],"plans":[{"id":"PLN-0037","file":"workflow/plans/PLN-0037-runtime-edge-coverage-governance-foundation.md","status":"done","created_at":"2026-04-20","updated_at":"2026-04-20","ref_decisions":["DEC-0020"]},{"id":"PLN-0038","file":"workflow/plans/PLN-0038-firmware-and-host-dependent-domain-coverage-expansion.md","status":"done","created_at":"2026-04-20","updated_at":"2026-04-20","ref_decisions":["DEC-0020"]},{"id":"PLN-0039","file":"workflow/plans/PLN-0039-incremental-runtime-domain-suite-split-and-baselines.md","status":"open","created_at":"2026-04-20","updated_at":"2026-04-20","ref_decisions":["DEC-0020"]}],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0003","status":"open","ticket":"packed-cartridge-loader-pmc","title":"Agenda - Packed Cartridge Loader PMC","created_at":"2026-03-27","updated_at":"2026-03-27","tags":[],"agendas":[{"id":"AGD-0002","file":"workflow/agendas/AGD-0002-packed-cartridge-loader-pmc.md","status":"open","created_at":"2026-03-27","updated_at":"2026-03-27"}],"decisions":[],"plans":[],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0004","status":"open","ticket":"system-run-cart","title":"Agenda - System Run Cart","created_at":"2026-03-27","updated_at":"2026-03-27","tags":[],"agendas":[{"id":"AGD-0003","file":"workflow/agendas/AGD-0003-system-run-cart.md","status":"open","created_at":"2026-03-27","updated_at":"2026-03-27"}],"decisions":[],"plans":[],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0005","status":"open","ticket":"system-fault-semantics-and-control-surface","title":"Agenda - System Fault Semantics and Control Surface","created_at":"2026-03-27","updated_at":"2026-03-27","tags":[],"agendas":[{"id":"AGD-0004","file":"workflow/agendas/AGD-0004-system-fault-semantics-and-control-surface.md","status":"open","created_at":"2026-03-27","updated_at":"2026-03-27"}],"decisions":[],"plans":[],"lessons":[]}
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
id: PLN-0038
|
||||
ticket: runtime-edge-test-plan
|
||||
title: Plan - Firmware and Host-Dependent Domain Coverage Expansion
|
||||
status: open
|
||||
status: done
|
||||
created: 2026-04-20
|
||||
completed:
|
||||
completed: 2026-04-20
|
||||
tags: [tests, firmware, host, coverage]
|
||||
---
|
||||
|
||||
@ -133,4 +133,3 @@ Use the governance helpers from `PLN-0037` if available, or temporary documented
|
||||
- Adding host-only tests for behavior that belongs below the host boundary.
|
||||
- Expanding firmware tests without aligning them to the state machine contract in the specs.
|
||||
- Overfitting ignored integration tests to desktop timing details.
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user