mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 18:25:35 -04:00
aot: persist exact candidate coverage gaps
This commit is contained in:
@@ -473,6 +473,27 @@ def group_by_region(addrs):
|
||||
for a in addrs: g[region_of(a)].append(a)
|
||||
return {r: sorted(v) for r, v in sorted(g.items())}
|
||||
|
||||
|
||||
def candidate_miss_records(misses):
|
||||
"""Stable JSON records for strict content-variant coverage gaps."""
|
||||
return [
|
||||
{'entry': f'0x{entry | 0x80000000:08X}',
|
||||
'code_crc': f'{crc:08X}'}
|
||||
for entry, crc in sorted(
|
||||
(norm(entry), crc & 0xFFFFFFFF) for entry, crc in misses)
|
||||
]
|
||||
|
||||
|
||||
def group_candidate_misses_by_region(misses):
|
||||
"""Group strict ``(entry, code_crc)`` gaps without losing variants."""
|
||||
grouped = defaultdict(list)
|
||||
for entry, crc in sorted(misses):
|
||||
grouped[region_of(entry)].append((entry, crc))
|
||||
return {
|
||||
f'0x{region | 0x80000000:08X}': candidate_miss_records(values)
|
||||
for region, values in sorted(grouped.items())
|
||||
}
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument('--static', required=True, help='static shard cache dir (.ranges)')
|
||||
@@ -548,6 +569,10 @@ def main():
|
||||
f'0x{x|0x80000000:08X}' for x in r['range_misses']]
|
||||
report['vault_interval_potential_misses'] = list(
|
||||
report['vault_range_misses'])
|
||||
report['vault_entry_crc_misses'] = candidate_miss_records(
|
||||
r['entry_crc_misses'])
|
||||
report['vault_entry_crc_misses_by_region'] = \
|
||||
group_candidate_misses_by_region(r['entry_crc_misses'])
|
||||
combined = None
|
||||
if a.bios_dispatch:
|
||||
combined = recall(set(vault_ent), combined_ent, combined_ranges)
|
||||
@@ -575,13 +600,23 @@ def main():
|
||||
f'{r.get("needed_entry_crc",0)}** '
|
||||
f'(**{r.get("recall_entry_crc",0)*100:.1f}%**) '
|
||||
f'_(cg-version differences can lower this vs address-level recall)_')
|
||||
if r['entry_crc_misses']:
|
||||
md.append('#### Exact manifest-candidate gaps by region\n')
|
||||
for region, records in group_candidate_misses_by_region(
|
||||
r['entry_crc_misses']).items():
|
||||
unique_addresses = len({record['entry'] for record in records})
|
||||
md.append(f'- `{region}`: **{len(records)}** missing '
|
||||
f'candidate variant(s) at **{unique_addresses}** '
|
||||
'entry address(es)')
|
||||
md.append('')
|
||||
md.append(f'- **MISSED exact entries: {r["missed"]}**')
|
||||
md.append(f'- **OUTSIDE ALL STATIC INTERVALS: '
|
||||
f'{r["missed_interval_potential"]}** played entry PCs '
|
||||
'(potential gaps; interval membership is not dispatch proof)\n')
|
||||
if combined:
|
||||
md.append('### Combined with base recompiled BIOS\n')
|
||||
md.append(f'- Exact native dispatch entries: **{combined["covered_here"]}** '
|
||||
md.append(f'- Exact entry addresses present in overlay/BIOS static '
|
||||
f'dispatch sets: **{combined["covered_here"]}** '
|
||||
f'(**{combined["recall_entry"]*100:.1f}%**)')
|
||||
md.append(f'- Contained in an overlay/BIOS static interval '
|
||||
f'(unverified potential): '
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import json
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
import zlib
|
||||
@@ -59,6 +60,58 @@ const PsxNativeStub psx_bios_native_stubs[1] = {
|
||||
self.assertEqual(result['recall_entry_crc'], 0.5)
|
||||
self.assertEqual(result['entry_crc_misses'], [(0x100, 0xAAAA)])
|
||||
|
||||
def test_exact_candidate_misses_persist_variants_grouped_by_region(self):
|
||||
misses = [(0xA0001234, 0x1AAAAAAAA), (0x1234, 0xBBBBBBBB),
|
||||
(0x2450, 0xCCCCCCCC)]
|
||||
self.assertEqual(coverage_report.candidate_miss_records(misses), [
|
||||
{'entry': '0x80001234', 'code_crc': 'AAAAAAAA'},
|
||||
{'entry': '0x80001234', 'code_crc': 'BBBBBBBB'},
|
||||
{'entry': '0x80002450', 'code_crc': 'CCCCCCCC'},
|
||||
])
|
||||
self.assertEqual(
|
||||
coverage_report.group_candidate_misses_by_region(misses), {
|
||||
'0x80001000': [
|
||||
{'entry': '0x80001234', 'code_crc': 'AAAAAAAA'},
|
||||
{'entry': '0x80001234', 'code_crc': 'BBBBBBBB'},
|
||||
],
|
||||
'0x80002000': [
|
||||
{'entry': '0x80002450', 'code_crc': 'CCCCCCCC'},
|
||||
],
|
||||
})
|
||||
|
||||
def test_main_persists_and_summarizes_exact_candidate_gaps(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
static = os.path.join(tmp, 'static')
|
||||
vault = os.path.join(tmp, 'vault')
|
||||
os.makedirs(static)
|
||||
os.makedirs(vault)
|
||||
with open(os.path.join(static, 'static.ranges'), 'w',
|
||||
encoding='utf-8') as out:
|
||||
out.write('F 80001234 BBBBBBBB\nR 80001234 8\n')
|
||||
with open(os.path.join(vault, 'vault.ranges'), 'w',
|
||||
encoding='utf-8') as out:
|
||||
out.write('F 80001234 AAAAAAAA\nR 80001234 8\n')
|
||||
out.write('F 80001234 BBBBBBBB\nR 80001234 8\n')
|
||||
out_md = os.path.join(tmp, 'gaps.md')
|
||||
out_json = os.path.join(tmp, 'gaps.json')
|
||||
argv = [
|
||||
'coverage_report.py', '--static', static, '--vault', vault,
|
||||
'--game', 'TEST', '--out-md', out_md, '--out-json', out_json,
|
||||
]
|
||||
with mock.patch.object(sys, 'argv', argv):
|
||||
coverage_report.main()
|
||||
with open(out_json, encoding='utf-8') as source:
|
||||
report = json.load(source)
|
||||
with open(out_md, encoding='utf-8') as source:
|
||||
markdown = source.read()
|
||||
expected = [{'entry': '0x80001234', 'code_crc': 'AAAAAAAA'}]
|
||||
self.assertEqual(report['vault_entry_crc_misses'], expected)
|
||||
self.assertEqual(report['vault_entry_crc_misses_by_region'], {
|
||||
'0x80001000': expected,
|
||||
})
|
||||
self.assertIn('`0x80001000`: **1** missing candidate variant(s)',
|
||||
markdown)
|
||||
|
||||
def test_interval_containment_does_not_count_as_crc_candidate(self):
|
||||
result = coverage_report.recall(
|
||||
{0x100}, {0x100: {0xBBBB}}, [(0x100, 0x108)],
|
||||
|
||||
Reference in New Issue
Block a user