20 lines
2.3 KiB
JavaScript
20 lines
2.3 KiB
JavaScript
/**
|
||
* 浏览器摘要适配器的协议故障测试:使用可控 Worker 替身检查请求/响应身份,以及启动和运行失败的错误区分。
|
||
* 不启动真实线程,也不验证浏览器打包;每个用例恢复 globalThis.Worker,避免污染其他测试。
|
||
*/
|
||
import {test} from 'node:test';
|
||
import assert from 'node:assert/strict';
|
||
import {createBrowserDigests} from '../../src/lib/canvas-runtime/browser-digests.ts';
|
||
|
||
// Worker 回传错误 id 即使摘要格式正确也必须拒绝;故障 worker 需 terminate,不能把别的任务结果交给当前调用者。
|
||
test('browser digest adapter rejects mismatched worker identity and terminates the worker',async()=>{
|
||
const previous=globalThis.Worker;let terminated=0;
|
||
globalThis.Worker=class{/* 模拟线程稍后回信,故意把 id 加一;其余字段合法以隔离身份校验。 */ postMessage(value){queueMicrotask(()=>this.onmessage({data:{version:1,id:value.id+1,byteLength:value.bytes.size,sha256:'a'.repeat(64)}}));}/* 计数故障后的终止动作。 */ terminate(){terminated++;}};
|
||
const pool=createBrowserDigests();try{await assert.rejects(pool.digest(new Blob(['bytes'])),/invalid_digest_response/);assert.equal(terminated,1);}finally{pool.close();if(previous===undefined)delete globalThis.Worker;else globalThis.Worker=previous;}
|
||
});
|
||
// 构造器抛错映射为 worker_unavailable,onerror 映射为 worker_failed;两个路径都不能给调用者返回伪造摘要。
|
||
test('browser digest adapter exposes worker startup and runtime failures without returning a false hash',async()=>{
|
||
const previous=globalThis.Worker;let pool;
|
||
try{globalThis.Worker=class{/* 在线程创建阶段抛错,尚未进入 postMessage。 */ constructor(){throw Error('denied');}};pool=createBrowserDigests();await assert.rejects(pool.digest(new Blob()),/digest_worker_unavailable/);pool.close();let terminated=0;globalThis.Worker=class{/* 在线程运行阶段触发 onerror,区别于构造失败。 */ postMessage(){queueMicrotask(()=>this.onerror({preventDefault(){}}));}/* 计数故障后的终止动作。 */ terminate(){terminated++;}};pool=createBrowserDigests();await assert.rejects(pool.digest(new Blob()),/digest_worker_failed/);assert.equal(terminated,1);}finally{pool?.close();if(previous===undefined)delete globalThis.Worker;else globalThis.Worker=previous;}
|
||
});
|