Skip to content

Commit 23b4c0f

Browse files
authored
fix(gb-test-runner): mark pages reports requiring real boot (#259)
1 parent 39640b4 commit 23b4c0f

3 files changed

Lines changed: 98 additions & 2 deletions

File tree

crates/gb-test-runner/data/rom-reports-pages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[
2-
{ "name": "gb-emulator-shootout" },
2+
{ "name": "gb-emulator-shootout", "boot_roms": true },
33
{ "name": "blargg" },
44
{ "name": "mooneye" },
55
{ "name": "wilbertpol" },

crates/gb-test-runner/src/suite/test/manifest.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,6 +1730,31 @@ fn real_remaining_gb_emulator_shootout_suite_manifests_load_framebuffer_oracles(
17301730
fs::remove_dir_all(workspace).expect("workspace should be removable");
17311731
}
17321732

1733+
#[test]
1734+
fn real_rom_reports_pages_marks_real_boot_reports_with_boot_roms() {
1735+
let workspace = crate::default_workspace_root();
1736+
let pages = read_rom_reports_pages_for_test(&workspace);
1737+
let reports = load_reports(&workspace).expect("reports should load");
1738+
let mut missing_boot_roms = Vec::new();
1739+
1740+
for page in pages {
1741+
let report = reports
1742+
.iter()
1743+
.find(|report| report.id == page.name)
1744+
.unwrap_or_else(|| panic!("report {:?} should exist", page.name));
1745+
let real_boot_suites = real_boot_suite_names_for_report(report);
1746+
if !real_boot_suites.is_empty() && !page.boot_roms {
1747+
missing_boot_roms.push(format!("{} ({})", page.name, real_boot_suites.join(", ")));
1748+
}
1749+
}
1750+
1751+
assert!(
1752+
missing_boot_roms.is_empty(),
1753+
"rom-reports-pages.json entries with RealBoot suite manifests must set boot_roms = true: {}",
1754+
missing_boot_roms.join("; ")
1755+
);
1756+
}
1757+
17331758
#[test]
17341759
fn real_standalone_extra_report_manifests_load_new_runner_oracles() {
17351760
let report_specs = [
@@ -2302,6 +2327,77 @@ fn read_gbemu_suite_manifest(suite_name: &str) -> String {
23022327
.expect("suite manifest should be readable")
23032328
}
23042329

2330+
const ROM_REPORTS_PAGES_PATH_FOR_TEST: &str = "crates/gb-test-runner/data/rom-reports-pages.json";
2331+
2332+
#[derive(Debug, Deserialize)]
2333+
struct RomReportsPageEntryForTest {
2334+
name: String,
2335+
#[serde(default)]
2336+
boot_roms: bool,
2337+
}
2338+
2339+
fn read_rom_reports_pages_for_test(workspace_root: &Path) -> Vec<RomReportsPageEntryForTest> {
2340+
let path = workspace_root.join(ROM_REPORTS_PAGES_PATH_FOR_TEST);
2341+
let text = fs::read_to_string(&path).expect("ROM reports Pages metadata should be readable");
2342+
serde_json::from_str(&text).expect("ROM reports Pages metadata should parse")
2343+
}
2344+
2345+
fn real_boot_suite_names_for_report(report: &super::super::model::Report) -> Vec<String> {
2346+
let report_root = Path::new(env!("CARGO_MANIFEST_DIR"))
2347+
.join("data")
2348+
.join(&report.store_dir);
2349+
let mut suite_names = Vec::new();
2350+
for entry in fs::read_dir(&report_root).unwrap_or_else(|error| {
2351+
panic!(
2352+
"report manifest directory {} should be readable: {error}",
2353+
report_root.display()
2354+
)
2355+
}) {
2356+
let path = entry
2357+
.expect("suite manifest entry should be readable")
2358+
.path();
2359+
let Some(file_name) = path.file_name().and_then(|file_name| file_name.to_str()) else {
2360+
continue;
2361+
};
2362+
if !file_name.ends_with(".suite.toml") || file_name.ends_with(".link.suite.toml") {
2363+
continue;
2364+
}
2365+
if suite_manifest_declares_real_boot(&path) {
2366+
suite_names.push(
2367+
file_name
2368+
.strip_suffix(".suite.toml")
2369+
.expect("suite manifest suffix should be present")
2370+
.to_string(),
2371+
);
2372+
}
2373+
}
2374+
suite_names.sort();
2375+
suite_names
2376+
}
2377+
2378+
fn suite_manifest_declares_real_boot(path: &Path) -> bool {
2379+
let text = fs::read_to_string(path).unwrap_or_else(|error| {
2380+
panic!(
2381+
"suite manifest {} should be readable: {error}",
2382+
path.display()
2383+
)
2384+
});
2385+
let manifest: toml::Value = toml::from_str(&text)
2386+
.unwrap_or_else(|error| panic!("suite manifest {} should parse: {error}", path.display()));
2387+
let top_level_real_boot =
2388+
manifest.get("startup").and_then(toml::Value::as_str) == Some("real-boot");
2389+
let case_real_boot = manifest
2390+
.get("case")
2391+
.and_then(toml::Value::as_array)
2392+
.map(|cases| {
2393+
cases
2394+
.iter()
2395+
.any(|case| case.get("startup").and_then(toml::Value::as_str) == Some("real-boot"))
2396+
})
2397+
.unwrap_or(false);
2398+
top_level_real_boot || case_real_boot
2399+
}
2400+
23052401
fn read_docboy_suite_manifest(suite_name: &str) -> String {
23062402
fs::read_to_string(
23072403
Path::new(env!("CARGO_MANIFEST_DIR"))

docs/info/ROM-SUITES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ Same-ROM model variants are ordered DMG before MGB before GBC before AGB before
171171
- GitHub `ci` mirrors Rust checks and coverage.
172172
- GitHub `test-roms` runs the promoted `gb-emulator-shootout` matrix with `cargo rom-suite gb-emulator-shootout --suite <suite>`; rows that intentionally depend on manifest-declared RealBoot, currently `ashiepaws` and `mealybug-tearoom-tests`, first run `cargo rom-fetch --boot-rom <dir>` into runner-local temporary storage and then pass `--boot-rom-dir <dir>`.
173173
- GitHub `test-roms-extra` runs explicitly promoted standalone report lanes with `cargo rom-suite <report>`; rows that intentionally depend on manifest-declared RealBoot, currently `gbmicrotest`, first run `cargo rom-fetch --boot-rom <dir>` into runner-local temporary storage and then pass `--boot-rom-dir <dir>`. `rtc3test` now replaces the removed standalone `ax6` report lane, while `little-things-gb` is temporarily commented out during the c-sp v7 Telling LYs joypad IRQ entropy investigation, `nitro2k01` stays local while placeholder framebuffer fixtures are replaced with manual fixtures, and standalone `mealybug-tearoom-tests` plus `samesuite` are temporarily commented out while their c-sp v7 inventories are validated manually.
174-
- GitHub `rom-reports-pages` reads its curated report metadata from `crates/gb-test-runner/data/rom-reports-pages.json`; a row with `boot_roms: true` fetches pinned boot ROM assets into runner-local temporary storage and passes `--boot-rom-dir <dir>` to `cargo rom-report <report> --html`, preserving manifest-declared RealBoot without forcing unrelated cases. Render jobs upload each report's `.status/` directory as an intermediate artifact, and the assemble job reconstructs `test/<report>/.status/` before running `cargo rom-report --index _site`; the published index follows the JSON metadata order, includes non-failing/total counts and a green check only when all executed rows are non-failing, and does not publish `summary.json`.
174+
- GitHub `rom-reports-pages` reads its curated report metadata from `crates/gb-test-runner/data/rom-reports-pages.json`; RealBoot-backed rows, currently `gb-emulator-shootout`, `gbmicrotest`, and `nitro2k01`, set `boot_roms: true` so the workflow fetches pinned boot ROM assets into runner-local temporary storage and passes `--boot-rom-dir <dir>` to `cargo rom-report <report> --html`, preserving manifest-declared RealBoot without forcing unrelated cases. Render jobs upload each report's `.status/` directory as an intermediate artifact, and the assemble job reconstructs `test/<report>/.status/` before running `cargo rom-report --index _site`; the published index follows the JSON metadata order, includes non-failing/total counts and a green check only when all executed rows are non-failing, and does not publish `summary.json`.
175175
- RealBoot, commercial, red, linked, and local-only lanes stay outside GitHub ROM workflows unless promoted intentionally; any promoted RealBoot lane must fetch pinned boot ROM assets into runner-local temporary storage and pass `--boot-rom-dir <dir>` explicitly.
176176

177177
## Private and commercial ROMs

0 commit comments

Comments
 (0)