compiler-package.test.mjs (2978B)
1 import test from 'node:test'; 2 import assert from 'node:assert/strict'; 3 import {readFile} from 'node:fs/promises'; 4 import {compilerDescriptor,COMPILER_EXPORT} from '../dist/compiler.js'; 5 import {BUNDLE_LIMIT} from '../dist/bundle.js'; 6 const descriptor=JSON.parse(await readFile(new URL('../compiler.json',import.meta.url))); 7 const bytes=await readFile(new URL('../bundles/'+descriptor.hash+'.arboricx',import.meta.url)); 8 let instance=0; 9 async function session(message,fetcher,after){ 10 const saved={fetch:globalThis.fetch,onmessage:globalThis.onmessage,postMessage:globalThis.postMessage}; 11 let timer; 12 try{ 13 globalThis.fetch=fetcher; 14 const messages=[]; 15 const reply=new Promise((resolve,reject)=>{ 16 timer=setTimeout(()=>reject(Error('worker test timeout')),5000); 17 globalThis.postMessage=data=>{messages.push(data);if(data.type==='loaded'||data.type==='error')resolve(data);}; 18 }); 19 await import('../dist/conformance/worker.js?test='+ ++instance); 20 globalThis.onmessage({data:message}); 21 const result=await reply; 22 if(after)await after(result,messages); 23 return result; 24 }finally{ 25 clearTimeout(timer); 26 for(const [key,value] of Object.entries(saved))if(value===undefined)delete globalThis[key];else globalThis[key]=value; 27 } 28 } 29 30 test('stable compiler descriptors reject arrays, wrong backends/entrypoints and malformed pins',()=>{ 31 assert.equal(compilerDescriptor(descriptor).hash,descriptor.hash); 32 for(const raw of [null,[],{...descriptor,schema:2},{...descriptor,backend:'experimental'},{...descriptor,export:'main'},{...descriptor,hash:'A'.repeat(64)}])assert.throws(()=>compilerDescriptor(raw)); 33 }); 34 35 test('the indexed compiler loads and downloads exact bytes as an ordinary package without compiling',async()=>{ 36 const requests=[]; 37 const fetcher=async url=>{requests.push(String(url));return new Response(bytes);}; 38 const loaded=await session({type:'load',hash:descriptor.hash},fetcher,async(result,messages)=>{ 39 assert.equal(result.type,'loaded');assert.ok(result.exports.some(e=>e.name===COMPILER_EXPORT)); 40 assert.equal(result.source,null);assert.ok(result.nodes<=100000); 41 globalThis.onmessage({data:{type:'download'}}); 42 const download=messages.at(-1);assert.equal(download.type,'downloaded');assert.equal(download.hash,descriptor.hash); 43 assert.deepEqual(Buffer.from(download.bytes),bytes); 44 assert.equal(messages.some(m=>m.type==='done'),false,'load/download never execute a program'); 45 }); 46 assert.equal(loaded.type,'loaded');assert.equal(requests.length,1); 47 assert.equal(requests.some(url=>url.endsWith('/compiler.json')),false); 48 }); 49 50 test('ordinary packages retain their byte ceiling and SHA-256 verification',async()=>{ 51 const wrong=await session({type:'load',hash:'0'.repeat(64)},async()=>new Response(bytes)); 52 assert.match(wrong.message,/SHA-256 mismatch/); 53 const oversized=await session({type:'load',hash:descriptor.hash},async()=>new Response(new Uint8Array(BUNDLE_LIMIT+1))); 54 assert.match(oversized.message,/download limit/); 55 });