50 lines
3.3 KiB
Python
50 lines
3.3 KiB
Python
from pathlib import Path
|
|
from datetime import datetime, timezone
|
|
import collections, csv, hashlib, json, zipfile
|
|
|
|
R=Path(__file__).resolve().parent.parent
|
|
P=R/'storage/app/private/investmoz-v2/portal-audit'
|
|
O=R/'outputs/investmoz-operational-onboarding-20261011'
|
|
load=lambda p:json.loads(p.read_text(encoding='utf-8-sig'))
|
|
sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest()
|
|
m=load(O/'manifesto.json');wrapper=load(O/'manifesto-disponibilizacao.json')
|
|
assert wrapper['delta_sha256']==m['delta_sha256']
|
|
assert sha(O/'manifesto.json')==wrapper['original_manifest_sha256']
|
|
assert sha(O/m['package'])==m['package_sha256']==wrapper['package_sha256']
|
|
for file,value in wrapper['documents'].items(): assert sha(O/file)==value,file
|
|
expected={x['path']:x['after_sha256'] for x in m['files']}|{x['path']:x['sha256'] for x in m['assets']}
|
|
with zipfile.ZipFile(O/m['package']) as z:
|
|
assert set(z.namelist())==set(expected) and len(z.namelist())==len(expected)
|
|
for file,value in expected.items(): assert hashlib.sha256(z.read(file)).hexdigest()==value,file
|
|
for x in m['files']:
|
|
assert (sha(R/x['path']) if (R/x['path']).is_file() else None)==x['before_sha256'],x['path']
|
|
b=load(P/'onboarding-release-target-backup.json')
|
|
assert sha(Path(b['dump_path']))==b['dump_sha256'] and sha(Path(b['files_path']))==b['files_sha256']
|
|
assert datetime.now(timezone.utc)<datetime.fromisoformat(b['valid_until'])
|
|
assert b['active_writes']==0 and len(b['tables'])==295 and b['restored_target']['port']==55441
|
|
baseline=load(P/'onboarding-release-matrix-baseline.json')
|
|
csv.field_size_limit(10_000_000)
|
|
with (R/'docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv').open(encoding='utf-8-sig',newline='') as f: rows=list(csv.reader(f))
|
|
assert len(rows)==len(baseline['rows']);changes=[]
|
|
for before,after in zip(baseline['rows'],rows):
|
|
assert len(before)==len(after)
|
|
for col,(a,v) in enumerate(zip(before,after)):
|
|
if a!=v:
|
|
header=rows[0][col]
|
|
assert header=='Evidência funcional' and baseline['updates'][before[0]][header]==v
|
|
changes.append(before[0])
|
|
assert sorted(changes)==['AUD-PROFILE-01','AUD-PROFILE-03','AUD-PROFILE-31']
|
|
proof={'at':datetime.now(timezone.utc).isoformat(),'result':'passed','delta':m['delta_sha256'][:12],
|
|
'package_sha256':m['package_sha256'],'release_manifest_sha256':sha(O/'manifesto-disponibilizacao.json'),
|
|
'source_files':len(m['files']),'compiled_assets':len(m['assets']),'active_payload_hashes_unchanged':True,
|
|
'backup_restored_verified_QA_only':True,'backup_table_count':len(b['tables']),'backup_file_count':b['file_count'],
|
|
'active_application_changes':0,'active_database_writes':0,'emails_sent':0,
|
|
'matrix_requirements':len(rows)-1,'matrix_source_occurrences':sum(int(row[rows[0].index('Quantidade de linhas de origem')]) for row in rows[1:]),
|
|
'matrix_changes':changes,'states_sources_versions_and_other_cells_preserved':True,
|
|
'matrix_states':dict(collections.Counter(row[rows[0].index('Estado')] for row in rows[1:])),
|
|
'readiness':'release_review_complete; authorization_pending; operational_enablement_separate',
|
|
'real_organization_representation_proof_upload':'pending_existing_backlog; does_not_block_validator_publisher_preparation',
|
|
'A_B_C37_preserved_not_retested':True}
|
|
(O/'verificacao-disponibilizacao.json').write_text(json.dumps(proof,indent=2,ensure_ascii=False),encoding='utf-8')
|
|
print(json.dumps(proof,ensure_ascii=False))
|