11import { makeSQLKernelDatabase } from '@metamask/kernel-store/sqlite/nodejs' ;
2+ import type { Logger } from '@metamask/logger' ;
23import { describe , it , expect , vi } from 'vitest' ;
34
45import { KernelQueue } from './KernelQueue.ts' ;
@@ -9,8 +10,7 @@ import type { EndpointHandle, KRef, RunQueueItem } from './types.ts';
910
1011/**
1112 * `KernelRouter`'s own tests mock `resolvePromises`, so nothing there can see a
12- * second resolution of one promise — which is a `Fail`, and reaches the run
13- * loop from inside the very catch meant to contain the delivery's failure.
13+ * second resolution of one promise. These run against a real store and queue.
1414 */
1515describe ( 'a result promise whose delivery fails' , ( ) => {
1616 /**
@@ -22,10 +22,12 @@ describe('a result promise whose delivery fails', () => {
2222 async function makeFixture ( deliverMessage : ( ) => Promise < never > ) : Promise < {
2323 kernelStore : ReturnType < typeof makeKernelStore > ;
2424 kernelQueue : KernelQueue ;
25+ logger : Logger ;
2526 runCrank : ( ) => Promise < void > ;
2627 } > {
2728 const kdb = await makeSQLKernelDatabase ( { dbFilename : ':memory:' } ) ;
2829 const kernelStore = makeKernelStore ( kdb ) ;
30+ kernelStore . setRefCountAuditing ( true ) ;
2931 const kernelQueue = new KernelQueue ( kernelStore , async ( ) => undefined ) ;
3032 const endpoint = {
3133 deliverMessage : vi . fn ( deliverMessage ) ,
@@ -35,11 +37,13 @@ describe('a result promise whose delivery fails', () => {
3537 deliverRetireImports : vi . fn ( ) ,
3638 deliverBringOutYourDead : vi . fn ( ) ,
3739 } as unknown as EndpointHandle ;
40+ const logger = { error : vi . fn ( ) , log : vi . fn ( ) } as unknown as Logger ;
3841 const kernelRouter = new KernelRouter (
3942 kernelStore ,
4043 kernelQueue ,
4144 ( ) => endpoint ,
4245 ( ) => undefined ,
46+ logger ,
4347 ) ;
4448
4549 // The run loop's crank, minus the run loop.
@@ -50,12 +54,13 @@ describe('a result promise whose delivery fails', () => {
5054 const item = kernelStore . dequeueRun ( ) as RunQueueItem ;
5155 await kernelRouter . deliver ( item ) ;
5256 kernelStore . collectGarbage ( ) ;
57+ kernelStore . assertRefCountsIfAuditing ( ) ;
5358 } finally {
5459 kernelStore . endCrank ( ) ;
5560 }
5661 } ;
5762
58- return { kernelStore, kernelQueue, runCrank } ;
63+ return { kernelStore, kernelQueue, logger , runCrank } ;
5964 }
6065
6166 /**
@@ -93,9 +98,6 @@ describe('a result promise whose delivery fails', () => {
9398 expect ( kernelStore . getKernelPromise ( result ) . state ) . toBe ( 'rejected' ) ;
9499 } ) ;
95100
96- // A vat that resolves the result and then loses its stream is one way in; a
97- // stream that dies mid-delivery is the other, since retiring the vat rejects
98- // every promise it was deciding and this one's decider was just set.
99101 it . each ( [
100102 { how : 'fulfilled' , rejected : false , state : 'fulfilled' } ,
101103 { how : 'rejected' , rejected : true , state : 'rejected' } ,
@@ -105,7 +107,7 @@ describe('a result promise whose delivery fails', () => {
105107 // Held in an object so the endpoint can reach it before the queue that
106108 // settles the promise exists.
107109 const endpointDoes = { settleTheResult : ( ) : void => undefined } ;
108- const { kernelStore, kernelQueue, runCrank } = await makeFixture (
110+ const { kernelStore, kernelQueue, logger , runCrank } = await makeFixture (
109111 async ( ) => {
110112 endpointDoes . settleTheResult ( ) ;
111113 throw new Error ( 'stream closed' ) ;
@@ -117,12 +119,15 @@ describe('a result promise whose delivery fails', () => {
117119 [ result , rejected , kser ( 'settled by the endpoint' ) ] ,
118120 ] ) ;
119121
120- expect ( await runCrank ( ) ) . toBeUndefined ( ) ;
122+ await runCrank ( ) ;
121123
122124 const settled = kernelStore . getKernelPromise ( result ) ;
123125 expect ( settled . state ) . toBe ( state ) ;
124126 // The endpoint's own settlement, not the delivery's `DELIVERY_FAILED`.
125127 expect ( settled . value ?. body ) . toContain ( 'settled by the endpoint' ) ;
128+ expect ( logger . error ) . toHaveBeenCalledWith (
129+ expect . stringContaining ( `already ${ state } ` ) ,
130+ ) ;
126131 } ,
127132 ) ;
128133} ) ;
0 commit comments