import assert from 'node:assert/strict'; import {spawnSync} from 'node:child_process'; import {mkdirSync,mkdtempSync,writeFileSync} from 'node:fs'; import {join,relative,dirname} from 'node:path'; import {hashAt,frozenSnapshot} from './boot-contract-report.mjs'; import {threadWaitInputs,threadWaitSources,threadWaitMutants,threadWaitBoundary,inspectThreadWaitHost} from './thread-wait-host-report.mjs'; const root=process.cwd();assert.equal(process.argv.length,2);const protectedBefore=frozenSnapshot(root),inputsBefore=threadWaitInputs(root),directory=mkdtempSync(join(root,'reports/os-implementation/K1061-K1079-preparation-')),runDirectory=relative(root,directory),clean=s=>s.split(root).join(''),artifact=path=>({path:relative(root,path),sha256:hashAt(root,relative(root,path))}); function source(name,mutant=null){const dest=join(directory,name,'sources');for(const[path,s]of threadWaitSources(root,mutant)){const target=join(dest,path);mkdirSync(dirname(target),{recursive:true});writeFileSync(target,s);}return dest;} const initial=source('.'),sources=[...threadWaitSources(root).keys()].map(originalPath=>({originalPath,...artifact(join(initial,originalPath))}));const version=spawnSync('rustc',['-vV'],{encoding:'utf8'});assert.equal(version.status,0);const hostTarget=version.stdout.match(/^host: (.+)$/m)[1]; function command(id,argv,executable='cargo'){console.log(`THREAD WAIT ${id}`);const env={...process.env,CARGO_TARGET_DIR:join(directory,'target')};delete env.RUSTFLAGS;delete env.CARGO_ENCODED_RUSTFLAGS;delete env.TURKOS_RELEASE_IMAGE_BYTES;delete env.TURKOS_RELEASE_IMAGE_SHA256;const r=spawnSync(executable,argv,{cwd:root,env,encoding:'utf8',timeout:120000,maxBuffer:8*1024*1024});assert.equal(r.error,undefined);const path=join(directory,`${id}.log`);writeFileSync(path,clean(`${r.stdout??''}${r.stderr??''}`));return{id,executable,argv:argv.map(clean),exitCode:r.status,targetDirectory:clean(env.CARGO_TARGET_DIR),log:artifact(path)};} const args=(dest,target,unit=false)=>['--manifest-path',join(dest,'os-thread-wait/Cargo.toml'),'--locked','--offline',...(unit?['--lib']:['--test','wait']),'--target',target]; const commands=[command('integration',['test',...args(initial,hostTarget),'--','--test-threads=1']),command('private',['test',...args(initial,hostTarget,true),'--','--test-threads=1']),command('arm64',['check','--manifest-path',join(initial,'os-thread-wait/Cargo.toml'),'--locked','--offline','--lib','--target','aarch64-unknown-none'])];commands.push(command('format',['--config','skip_children=true','--edition','2024','--check',...[...threadWaitSources(root).keys()].filter(p=>p.startsWith('os-thread-wait/')&&p.endsWith('.rs')).map(p=>join(initial,p))],'rustfmt'));commands.push(command('clippy',['clippy','--manifest-path',join(initial,'os-thread-wait/Cargo.toml'),'--locked','--offline','--all-targets','--target',hostTarget,'--','-D','warnings']));for(const c of commands)assert.equal(c.exitCode,0,c.log.path); const mutants=[];for(const spec of threadWaitMutants){const dest=source(`mutant-${spec.id}`,spec),c=command(`mutant-${spec.id}`,['test',...args(dest,hostTarget,spec.unit),spec.test,'--','--exact','--test-threads=1']);assert.equal(c.exitCode,101,c.log.path);mutants.push({...spec,...c,id:spec.id,source:artifact(join(dest,'os-thread-wait/src/thread_wait.rs')),sources:[...threadWaitSources(root,spec).keys()].map(originalPath=>({originalPath,...artifact(join(dest,originalPath))}))});} const report={schema:'turkos-thread-wait-host/v1',status:'HOST_PREPARED',guestAccepted:false,boundary:threadWaitBoundary,localMoves:Array.from({length:20},(_,i)=>1061+i).filter(n=>n%5),hostTests:29,arm64Status:'CHECK_ONLY',pendingGuests:[1065,1070,1075,1080],runDirectory,createdAt:new Date().toISOString(),hostTarget,inputsBefore,inputsAfter:threadWaitInputs(root),protectedBefore,protectedAfter:frozenSnapshot(root),sources,commands,mutants};const result=inspectThreadWaitHost(report,root),path=join(directory,'report.json');writeFileSync(path,JSON.stringify(report,null,2)+'\n');console.log(`THREAD WAIT PREPARED ${JSON.stringify(result)} ${relative(root,path)}`);