mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 11:06:11 -10:00
Four harnesses looked the directory up with sys.argv.index('--work-dir'), which raises
ValueError for the --work-dir=PATH spelling this PR keeps. ensure_work_dir now returns the
directory argparse will pick (the last one given) and they use that.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
149 lines
8.0 KiB
Python
149 lines
8.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Damage's Codec.INT conversion through actual item commands and saved chest stacks.
|
|
|
|
Complete records are strict. Parent block tags and absolute startup clocks are
|
|
predeclared diagnostics; all saved stacks and the zero relative clock stay strict.
|
|
"""
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
import harness_args
|
|
import test_command_exec_parity as driver
|
|
|
|
# Number.intValue: float/double truncate, long narrows; validation stays upstream.
|
|
CASES = [
|
|
('plain', None, 0), ('integer', '1', 1), ('float', '1.5f', 1),
|
|
('double', '2.75d', 2), ('negative_half', '-0.5f', 0),
|
|
('long_wrap', '4294967297L', 1), ('float_max', '2147483648.0f', 2147483647),
|
|
('double_max', '1.0e20d', 2147483647),
|
|
('negative_float', '-1.5f', None), ('negative_double', '-1.5d', None),
|
|
('long_negative', '2147483648L', None), ('negative_overflow', '-1.0e20d', None),
|
|
]
|
|
|
|
|
|
def program(full=False):
|
|
ops = []
|
|
|
|
def cmd(text, label, result=None, admission=True, diagnostic=False):
|
|
op = {'op': 'cmd', 'cmd': text, 'label': label, 'admission': admission}
|
|
if result is not None:
|
|
op['expect_result'] = result
|
|
if diagnostic and not full:
|
|
op.update(record=False, trace=True)
|
|
ops.append(op)
|
|
|
|
def read(path, label, result=None, admission=False):
|
|
for holder in ['result', 'success']:
|
|
cmd(f'/scoreboard players set {holder} h087 -99', label + '-reset-' + holder, -99)
|
|
cmd(f'/execute store result score result h087 store success score success h087 '
|
|
f'run data get block 4 200 4 {path}', label + '-read', result, admission)
|
|
cmd('/scoreboard players get result h087', label + '-result', admission=admission)
|
|
cmd('/scoreboard players get success h087', label + '-success', admission=admission)
|
|
|
|
cmd('/tick freeze', 'freeze')
|
|
cmd('/gamerule spawn_mobs false', 'no-spawn')
|
|
cmd('/gamerule advance_time false', 'no-daylight')
|
|
cmd('/forceload add 0 0', 'force', 1)
|
|
ops.append({'op': 'settle', 'required_chunks': [[0, 0]]})
|
|
cmd('/fill 0 199 0 15 199 15 stone', 'floor', 256)
|
|
cmd('/setblock 4 200 4 chest[facing=north,type=single,waterlogged=false]', 'chest-place', 1)
|
|
ops.append({'op': 'settle', 'required_chunks': [[0, 0]]})
|
|
for text, label in [('loaded 4 200 4', 'chest-loaded'), ('block 4 199 4 stone', 'support'),
|
|
('block 4 200 4 chest[facing=north,type=single,waterlogged=false]', 'chest-state')]:
|
|
cmd('/execute if ' + text, label, 1)
|
|
cmd('/tp @s 8.5 200 8.5 0 0', 'owner-position', 1)
|
|
cmd('/gamemode creative @s', 'owner-mode')
|
|
cmd('/execute if entity @s[type=player,name=Player]', 'owner-type', 1)
|
|
for key, expected in [('UUID', 4), ('Health', 20), ('playerGameType', 1), ('Pos', 3)]:
|
|
cmd('/data get entity @s ' + key, 'owner-' + key, expected)
|
|
for key, expected in [('id', 15), ('x', 4), ('y', 200), ('z', 4), ('Items', 0)]:
|
|
cmd('/data get block 4 200 4 ' + key, 'initial-' + key, expected)
|
|
cmd('/scoreboard objectives add h087 dummy', 'objective')
|
|
cmd('/execute store result score start h087 run time query gametime', 'clock-start', diagnostic=True)
|
|
for slot, (case, source, expected) in enumerate(CASES):
|
|
path = f'Items[{{Slot:{slot}b}}]'
|
|
cmd(f'/execute unless data block 4 200 4 {path}', case + '-empty', 1)
|
|
if expected is None:
|
|
cmd(f'/item replace block 4 200 4 container.{slot} with stone[custom_data={{keep:87}}] 2', case + '-sentinel', 1)
|
|
for holder in ['result', 'success']:
|
|
cmd(f'/scoreboard players set {holder} h087 -99', case + '-write-reset-' + holder, -99)
|
|
parts = ['custom_data={keep:87}']
|
|
if source is not None:
|
|
parts.append('damage=' + source)
|
|
spec = 'diamond_pickaxe[' + ','.join(parts) + ']'
|
|
cmd(f'/execute store result score result h087 store success score success h087 '
|
|
f'run item replace block 4 200 4 container.{slot} with {spec}', case + '-write',
|
|
1 if expected is not None else None, expected is not None)
|
|
cmd('/scoreboard players get result h087', case + '-write-result', admission=expected is not None)
|
|
cmd('/scoreboard players get success h087', case + '-write-success', admission=expected is not None)
|
|
for key, count in [('id', len('minecraft:stone') if expected is None else len('minecraft:diamond_pickaxe')),
|
|
('count', 2 if expected is None else 1), ('Slot', slot)]:
|
|
cmd(f'/data get block 4 200 4 {path}.{key}', case + '-' + key, count)
|
|
read(path, case + '-stack')
|
|
read(path + '.components."minecraft:damage"', case + '-damage')
|
|
read(path + '.components."minecraft:custom_data".keep', case + '-custom', 87, True)
|
|
cmd(f'/execute if data block 4 200 4 Items[{{Slot:{slot}b,components:{{"minecraft:damage":{expected}}}}}]'
|
|
if expected else f'/execute unless data block 4 200 4 {path}.components."minecraft:damage"',
|
|
case + '-typed-damage', 1, admission=False)
|
|
cmd('/data get block 4 200 4 Items', 'final-stacks', len(CASES), admission=False)
|
|
cmd('/data get block 4 200 4', 'parent-block', diagnostic=True)
|
|
cmd('/execute store result score end h087 run time query gametime', 'clock-end', diagnostic=True)
|
|
cmd('/scoreboard players operation end h087 -= start h087', 'clock-delta-operation', 0)
|
|
cmd('/scoreboard players get end h087', 'clock-delta', 0)
|
|
return ops
|
|
|
|
|
|
def main():
|
|
full = '--full-diagnostic' in sys.argv
|
|
if full:
|
|
sys.argv.remove('--full-diagnostic')
|
|
reference = None
|
|
if '--reference' in sys.argv:
|
|
i = sys.argv.index('--reference')
|
|
reference = Path(sys.argv[i + 1]).resolve()
|
|
del sys.argv[i:i + 2]
|
|
build = harness_args.ensure_work_dir(driver.lab.LOCAL / 'numeric-damage-component-parity').resolve()
|
|
reference_bytes = reference.read_bytes() if reference else None
|
|
assert reference is None or reference != build / 'vanilla.jsonl'
|
|
ops = program(full)
|
|
driver.corpus_module.groups = lambda: [('numeric damage component', ops)]
|
|
sys.argv.append('--allow-gaps')
|
|
driver.main()
|
|
recorded = [op for op in ops if op['op'] == 'cmd' and op.get('record', True)]
|
|
java = [json.loads(s) for s in (build / 'vanilla.jsonl').read_text().splitlines()]
|
|
assert len(recorded) == len(java)
|
|
rows = {op['label']: row for op, row in zip(recorded, java)}
|
|
for case, _, expected in CASES:
|
|
if expected is None:
|
|
assert rows[case + '-write']['results'] == [], rows[case + '-write']
|
|
else:
|
|
callbacks = [[True, expected]] if expected else [[False, 0]]
|
|
assert rows[case + '-damage-read']['results'] == callbacks, rows[case + '-damage-read']
|
|
if '--reference-only' in sys.argv:
|
|
return
|
|
comparison = reference_bytes or (build / 'vanilla.jsonl').read_bytes()
|
|
if reference_bytes and not full:
|
|
assert reference_bytes == (build / 'vanilla.jsonl').read_bytes(), 'fresh reference changed'
|
|
(build / 'comparison-reference.jsonl').write_bytes(comparison)
|
|
java = [json.loads(s) for s in comparison.decode().splitlines()]
|
|
native = [json.loads(s) for s in (build / 'rust.jsonl').read_text().splitlines()]
|
|
assert len(recorded) == len(java) == len(native)
|
|
differences = [{'label': op['label'], 'expected': a, 'actual': b}
|
|
for op, a, b in zip(recorded, java, native) if a != b]
|
|
report = {'records': len(native), 'passed': len(native) - len(differences), 'differences': differences,
|
|
'comparison': 'complete raw records, no masks/tolerances',
|
|
'reference_sha256': hashlib.sha256(comparison).hexdigest()}
|
|
(build / 'strict-report.json').write_text(json.dumps(report, indent=2) + '\n')
|
|
for op, a, b in zip(recorded, java, native):
|
|
if op['admission'] and op['label'] not in {'clock-start', 'parent-block', 'clock-end'}:
|
|
assert a == b, ('admission', op, a, b)
|
|
print(f'Strict raw records: {report["passed"]}/{report["records"]}')
|
|
if differences:
|
|
raise SystemExit(1)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|