From 5b35519562823175b73243cc5b0eb6b01a541a30 Mon Sep 17 00:00:00 2001 From: Codex Bot Date: Mon, 9 Nov 2026 14:04:54 +0800 Subject: [PATCH] Exercise live scoped imports and deep copies before an unread model tail --- tests/headless/foundry.integration.mjs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/tests/headless/foundry.integration.mjs b/tests/headless/foundry.integration.mjs index a60de7d..5fbb9be 100644 --- a/tests/headless/foundry.integration.mjs +++ b/tests/headless/foundry.integration.mjs @@ -37,19 +37,27 @@ try{ const copiedId=await engine.imports.duplicate([{id:frame.id,incarnation:1},{id:member.id,incarnation:1}],{viewCanvasId:rootId});await engine.settle();const copied=engine.imports.getJobs().get(copiedId);assert.equal(copied.status,'completed');const copiedFrame=copied.stableIds['element:'+frame.id],copiedMember=copied.stableIds['element:'+member.id];assert.ok(copiedFrame&&copiedMember); live=await loadFoundryModel(transport,workspaceId,rootId,registry);assert.ok(live.document.elements.has(copiedMember));assert.ok([...live.document.elements.values()].some(element=>element.structure==='connection'&&element.source.elementId===anchor.id&&element.target.elementId===copiedFrame));assert.equal(engine.editor.history.undo().status,'applied');await engine.settle();assert.equal(engine.editor.history.redo().status,'applied');await engine.settle();assert.equal(engine.getSnapshot().document.elements.get(copiedFrame).incarnation,2); const importId=engine.imports.startNdjson(new Blob([JSON.stringify({kind:'element',key:'native',record:node('native','$target')})+'\n'+JSON.stringify({kind:'unsupported'})+'\n']),rootId);await engine.settle();const imported=engine.imports.getJobs().get(importId);assert.equal(imported.status,'partial');assert.equal(imported.committedSourceKeys.length,1); + // Put a deterministic sorted tail in a different owner. Every original ID is + // lower than these records, so the first real 64-record frame certifies the + // root/new child while the original child is provably still incomplete. + const namespace=[...engine.getSnapshot().document.elements.keys(),...engine.getSnapshot().document.canvases.keys(),...engine.getSnapshot().document.tombstones.keys()]; + const maximum=namespace.reduce((max,id)=>{const value=BigInt('0x'+id.replaceAll('-',''));return value>max?value:max;},0n);assert.ok(maximum+70n<(1n<<128n)); + const tail=Array.from({length:70},(_,i)=>{const hex=(maximum+BigInt(i+1)).toString(16).padStart(32,'0');return node(`${hex.slice(0,8)}-${hex.slice(8,12)}-${hex.slice(12,16)}-${hex.slice(16,20)}-${hex.slice(20)}`,sourceMember.ownerCanvasId);}); + assert.equal(engine.editor.transaction(tx=>{for(const element of tail)tx.dispatch({type:'element.create',element});}).status,'applied');await engine.settle(); // Consume the real negotiated stream through the production decoder, pausing - // before terminal publication. ACKs advance while the immutable read is retained. + // after the first nonempty frame. HTTP/DB ACKs may advance before its old tail. await engine.close();image=null;initial=await loadFoundryModel(transport,workspaceId,rootId,registry); const streamed=await transport({method:'GET',path:path+'/model',responseFormat:'model-stream-v1'});assert.ok(streamed.stream);const controller=new AbortController(),preview=createModelPreview(registry);let capture,sourceToken,sourceVersions; const stream=decodeModelStream(streamed.stream,rootId,registry,controller.signal); while(true){const next=await stream.next();assert.equal(next.done,false);const chunk=next.value; - const value=preview.update(chunk.value);if(chunk.value.status==='receiving'){capture=value;sourceToken=chunk.snapshotToken;sourceVersions=chunk.versions;if(chunk.value.receivedElements===chunk.value.totalElements)break;} + const value=preview.update(chunk.value);if(chunk.value.status==='receiving'){capture=value;sourceToken=chunk.snapshotToken;sourceVersions=chunk.versions;if(chunk.value.receivedElements>0)break;} } - assert.ok(capture.sourceCanvases&&capture.elementOwners);assert.equal(capture.document.elements.size,initial.document.elements.size); + assert.ok(capture.sourceCanvases&&capture.elementOwners);assert.ok(capture.document.elements.sizecanvas.id),receivedElements:capture.receivedElements,totalElements:capture.totalElements}; - engine=await open({document:capture.document,versions:sourceVersions,loading});const partialId=engine.imports.startNdjson(new Blob([JSON.stringify({kind:'element',key:'partial-native',record:node('partial-native','$target')})+'\n']),childId);await engine.settle();assert.equal(engine.imports.getJobs().get(partialId).status,'completed');assert.equal(engine.loading.getState().version,5); + engine=await open({document:capture.document,versions:sourceVersions,loading});assert.equal(engine.editor.getQueries().membersResult(sourceMember.ownerCanvasId).complete,false);assert.equal(engine.imports.canStart(childId).enabled,true);const partialId=engine.imports.startNdjson(new Blob([JSON.stringify({kind:'element',key:'partial-native',record:node('partial-native','$target')})+'\n']),childId);await engine.settle();assert.equal(engine.imports.getJobs().get(partialId).status,'completed');assert.equal(engine.loading.getState().version,5); + const partialCopyId=await engine.imports.duplicate([{id:frame.id,incarnation:1}],{viewCanvasId:rootId});await engine.settle();const partialCopy=engine.imports.getJobs().get(partialCopyId);assert.equal(partialCopy.status,'completed');assert.equal(engine.getSnapshot().document.elements.has(tail.at(-1).id),false);const partialFrame=partialCopy.stableIds['element:'+frame.id];assert.ok(partialFrame); let terminal;for await(const chunk of stream){preview.update(chunk.value);if(chunk.value.status==='ready')terminal=chunk.value;}assert.ok(terminal,'real source never reached terminal and EOF'); - assert.equal((await engine.loading.complete(terminal.document,sourceVersions,{sourceToken})).status,'applied');await engine.settle();live=await loadFoundryModel(transport,workspaceId,rootId,registry);assert.ok(live.document.elements.has(engine.imports.getJobs().get(partialId).stableIds['element:partial-native'])); + assert.equal((await engine.loading.complete(terminal.document,sourceVersions,{sourceToken})).status,'applied');await engine.settle();live=await loadFoundryModel(transport,workspaceId,rootId,registry);assert.ok(live.document.elements.has(engine.imports.getJobs().get(partialId).stableIds['element:partial-native']));assert.ok(live.document.elements.has(partialFrame));assert.ok(live.document.elements.has(tail.at(-1).id));assert.ok([...live.document.elements.values()].some(element=>element.structure==='connection'&&element.source.elementId===anchor.id&&element.target.elementId===partialFrame)); assert.ok(errors.every(error=>String(error).includes('injected response loss')),'unexpected engine error: '+errors.map(String).join(',')); - console.log(JSON.stringify({status:'ok',migrationRetry:true,realHttp:true,lostAckRecovered:true,atomicPartition:true,deepCopyUpperEdge:true,nativePartialReport:true,loadingImportOldCapture:true,requests:calls.length})); + console.log(JSON.stringify({status:'ok',migrationRetry:true,realHttp:true,lostAckRecovered:true,atomicPartition:true,deepCopyUpperEdge:true,nativePartialReport:true,loadingImportOldCapture:true,unloadedTailDuringCopy:true,requests:calls.length})); }finally{await engine.close();}