38 lines
2.6 KiB
Python
38 lines
2.6 KiB
Python
"""Explicit reproducibility exercise with authored synthetic input; no targets needed."""
|
|
from __future__ import annotations
|
|
import argparse,concurrent.futures,contextlib,copy,json,multiprocessing,tempfile
|
|
from pathlib import Path
|
|
from generator import production,vocabulary
|
|
from tests.test_solo import song
|
|
|
|
def main():
|
|
p=argparse.ArgumentParser(description=__doc__);p.add_argument('--output',type=Path,required=True);a=p.parse_args();a.output.mkdir(parents=True,exist_ok=True)
|
|
data=Path('data').resolve();source=production.SourceAnalysis.read(song(count=1,chords=('C7',)))
|
|
results={};evidence={'scope':'One-bar independently authored source, real production catalogs, all six roles; not a whole-song musical quality test.','canonical_source':source.musical_key,'cases':{}}
|
|
def collect(label,values):
|
|
hashes={role:vocabulary.fingerprint(value['document']) for role,value in values.items()}
|
|
evidence['cases'][label]=hashes
|
|
evidence.setdefault('reads',{})[label]={r:v.get('observed_reads',[]) for r,v in values.items()}
|
|
if results:assert hashes==results['base'],label
|
|
else:results['base']=hashes
|
|
with tempfile.TemporaryDirectory() as temp:
|
|
cache=Path(temp)/'cache'
|
|
collect('alone_cold',{r:production.generate_role(source,r,data,cache_dir=cache) for r in production.ROLES})
|
|
collect('reverse_warm',{r:production.generate_role(source,r,data,cache_dir=cache) for r in reversed(production.ROLES)})
|
|
with concurrent.futures.ProcessPoolExecutor(max_workers=2,mp_context=multiprocessing.get_context('spawn')) as pool:
|
|
futures={r:pool.submit(production._job,(source,r,data,{},None)) for r in reversed(production.ROLES)}
|
|
collect('parallel_cold',{r:f.result() for r,f in futures.items()})
|
|
with contextlib.chdir(temp):
|
|
refs=Path('build');refs.mkdir()
|
|
for name in ('all-of-me','autumn-leaves'):
|
|
for i in (1,2):(refs/f'{name}-solo-{i}.xml').write_text('invalid optional content')
|
|
collect('targets_present_cold',{r:production.generate_role(source,r,data) for r in production.ROLES})
|
|
for path in refs.glob('*.xml'):path.unlink()
|
|
collect('targets_absent_cold',{r:production.generate_role(source,r,data) for r in production.ROLES})
|
|
production.generate_role(source,'electric_solo',data,{'choice_seed':'different electric only'})
|
|
collect('after_electric_setting',{r:production.generate_role(source,r,data,cache_dir=cache) for r in production.ROLES})
|
|
evidence['passed']=True
|
|
(a.output/'dependency.json').write_text(json.dumps(evidence,indent=2))
|
|
print(json.dumps({'passed':True,'hashes':results['base']},indent=2))
|
|
if __name__=='__main__':main()
|