"""R619:同一运行输出的缺失、截断、串用及可信备份恢复。""" from copy import deepcopy from hashlib import sha256 import json IDENTITY = {'run_id': 'S1', 'start': 0, 'end': 2} OBJECTS = { 'summary.json': {**IDENTITY, 'trade_count': 2, 'equity_count': 3, 'terminal': 102}, 'equity.json': {**IDENTITY, 'rows': [[0, 100], [1, 101], [2, 102]]}, 'trades.json': {**IDENTITY, 'rows': [['buy-1', 100], ['sell-1', 102]]}, } BACKUP = {name: json.dumps(obj, sort_keys=True).encode() for name, obj in OBJECTS.items()} EXPECTED = {name: sha256(blob).hexdigest() for name, blob in BACKUP.items()} def verify(files): issues, parsed = [], {} for name in BACKUP: if name not in files: issues.append(name + ':missing'); continue if sha256(files[name]).hexdigest() != EXPECTED[name]: issues.append(name + ':digest_mismatch') try: obj = json.loads(files[name]) except (ValueError, UnicodeError): issues.append(name + ':unparseable'); continue if any(obj.get(k) != v for k, v in IDENTITY.items()): issues.append(name + ':mixed_run_or_period') parsed[name] = obj if len(parsed) == 3: summary, eq, trades = [parsed[n] for n in ['summary.json', 'equity.json', 'trades.json']] if len(eq['rows']) != summary['equity_count'] or len(trades['rows']) != summary['trade_count']: issues.append('row_count_mismatch') if [r[0] for r in eq['rows']] != [0, 1, 2] or eq['rows'][-1][1] != summary['terminal']: issues.append('coverage_or_terminal_mismatch') return issues assert verify(BACKUP) == [] missing = dict(BACKUP); del missing['trades.json'] assert 'trades.json:missing' in verify(missing) truncated = dict(BACKUP); truncated['trades.json'] = b'{"run_id":' assert 'trades.json:unparseable' in verify(truncated) mixed_obj = deepcopy(OBJECTS['trades.json']); mixed_obj['run_id'] = 'S0' mixed = dict(BACKUP); mixed['trades.json'] = json.dumps(mixed_obj).encode() assert 'trades.json:mixed_run_or_period' in verify(mixed) restored = dict(missing); restored['trades.json'] = BACKUP['trades.json'] assert verify(restored) == [] assert OBJECTS['equity.json']['rows'][0][1] + (102 - 100) == OBJECTS['summary.json']['terminal'] print('complete_bundle=admitted missing_trades=blocked truncated_json=blocked mixed_run=blocked') print('same_run_backup_restored=True digest_verified=True terminal=102 trade_rows=2')