Files
SGF/scripts/summarize-association-concurrency.mjs
2026-11-02 20:29:34 +02:00

46 lines
4.6 KiB
JavaScript

import fs from 'node:fs';
import path from 'node:path';
import crypto from 'node:crypto';
const sha=data=>crypto.createHash('sha256').update(data).digest('hex');
const read=file=>JSON.parse(fs.readFileSync(file,'utf8').replace(/^\uFEFF/,''));
const project=process.cwd(),runtime='C:/laragon/data/sgf-tempo/run';
const state=read(path.join(runtime,'modular-regression-current.json'));
const input=path.resolve(process.argv[2]||'');
if(!/^[a-f0-9]{12}$/.test(state.id)||path.resolve(state.root)!==path.resolve(runtime,'modular-regression-'+state.id)
||path.dirname(input)!==path.resolve(state.root)||!/^association-concurrency-\d+\.json$/.test(path.basename(input)))throw Error('Unexpected private report');
const r=read(input);
if(!/^[a-f0-9]{12}$/.test(r.run_tag)||r.identity.database!=='sgf_tempo_test'||r.identity.role!=='sgf_test_runner'||r.identity.port!==55439)throw Error('Unexpected report identity');
const manifest=read(path.join(state.root,'private','association-concurrency-'+r.run_tag,'manifest.json'));
const source=path.join(project,'app/Modules/Identity/Services/ModuleAssociationReview.php');
if(sha(fs.readFileSync(source))!==r.optimized_sha256)throw Error('Measured source changed');
const nearest=(values,p)=>values[Math.max(0,Math.ceil(values.length*p)-1)]??null;
const rows=[];let complete=0,limited=0;
for(const phase of r.phases)for(const workload of ['clients','billing_drafts'])for(const workers of [1,2,4]){
const waves=phase.waves.filter(w=>w.workload===workload&&w.configured_workers===workers);
const samples=waves.flatMap(w=>w.samples),ok=samples.filter(s=>s.status==='ok');
const times=ok.map(s=>s.elapsed_ms).sort((a,b)=>a-b),window=waves.reduce((a,w)=>a+w.measurement_window_ms,0);
complete+=ok.length;limited+=samples.length-ok.length;
rows.push({index_mode:phase.index_mode,workload,workers,complete_requests:ok.length,limited_requests:samples.length-ok.length,
p50_ms:nearest(times,.5),p95_sample_ms:nearest(times,.95),closed_loop_observed_rps:Number((ok.length/(window/1000)).toFixed(2)),
observed_max_inflight:waves.map(w=>w.observed_max_inflight),queries:[...new Set(ok.map(s=>s.queries))],
max_incremental_php_bytes:Math.max(0,...ok.map(s=>s.incremental_php_bytes)),
mean_startup_to_ready_ms:Number((waves.reduce((a,w)=>a+w.startup_to_ready_ms,0)/waves.length).toFixed(3))});
}
const xmlPath=input.replace(/\.json$/,'.xml'),xml=fs.readFileSync(xmlPath,'utf8');
const tag=xml.match(/<testsuite\b([^>]*)>/)?.[1];if(!tag)throw Error('Invalid JUnit');
const number=name=>Number(tag.match(new RegExp('\\b'+name+'="(\\d+)"'))?.[1]);
const date=r.date.replaceAll('-',''),file='module-association-concurrency-'+date+'.json';
const summary={date:r.date,source_sha256:r.optimized_sha256,test:{tests:number('tests'),assertions:number('assertions'),errors:number('errors'),failures:number('failures'),junit_sha256:sha(fs.readFileSync(xmlPath))},
method:{independent_php_workers:true,distinct_synthetic_identities:4,requests_per_worker:5,waves_per_case:3,percentiles:'Nearest rank; descriptive samples of 15/30/60 requests only',
warm_in_process_http:true,login_network_tls_browser_measured:false,read_only_reader_transactions:true,records_per_area:3000,lines_per_wide_draft:100,description_bytes:1000},
results:rows,matrix_complete_requests:complete,matrix_limited_requests:limited,mixed_read_complete_requests:r.mixed_read_wave.complete_requests,mixed_read_max_inflight:r.mixed_read_wave.observed_max_inflight,
workload_response_hashes:Object.fromEntries(Object.entries(manifest.workloads).map(([key,value])=>[key,value.response_sha256])),competing_confirmation:r.competing_confirmation,
preservation:{previous_qa_rows_and_indexes_unchanged:r.previous_rows_unchanged,new_qa_fixture_retained:true,private_manifest_kept:true,
synthetic_confirmation_rolled_back:r.synthetic_confirmation_rolled_back,test_index_removed:r.test_index_removed,protected_six_records_untouched:true,blocked_cache_untouched:true,
destination_connected:false,production_rights_changed:false,publication:false,purchasing_activation:false,checkpoint_created:false},
artifact:{path:file,sha256:sha(fs.readFileSync(input))},deployment_capacity_validated:false,visual_review_pending:true};
fs.copyFileSync(input,path.join(project,'docs/proofs',file));
fs.writeFileSync(path.join(project,'docs/proofs','module-association-concurrency-summary-'+date+'.json'),JSON.stringify(summary,null,2)+'\n');
console.log(JSON.stringify({test:summary.test,matrix:complete,mixed:summary.mixed_read_complete_requests,limited,preserved:r.previous_rows_unchanged,index_removed:r.test_index_removed},null,2));