Skip to content

Commit

Permalink
chore(swingset): add failing test for #3264
Browse files Browse the repository at this point in the history
  • Loading branch information
warner committed Jun 8, 2021
1 parent 2061e52 commit 3a78e18
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 0 deletions.
20 changes: 20 additions & 0 deletions packages/SwingSet/test/basedir-promises-3/bootstrap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { E } from '@agoric/eventual-send';
import { makePromiseKit } from '@agoric/promise-kit';
import { Far } from '@agoric/marshal';

export function buildRootObject() {
const pk1 = makePromiseKit();
return Far('root', {
bootstrap(vats) {
const p2 = E(vats.right).one(); // p2 is kp41
E(p2).four(pk1.promise);
// that puts an unresolved promise in the arguments of the promise
// queue for p2
},
two() {
pk1.resolve(3);
// The promise is resolved and retired from our clist, the only
// remaining reference is from the p2 promise queue
},
});
}
25 changes: 25 additions & 0 deletions packages/SwingSet/test/basedir-promises-3/vat-right.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Far } from '@agoric/marshal';
import { makePromiseKit } from '@agoric/promise-kit';

export function buildRootObject() {
const pk3 = makePromiseKit();
const pk4 = makePromiseKit();
const t2 = Far('t2', {
four(arg) {
// arg should be a Promise that promptly resolves to 4
const argP = Promise.resolve(arg);
const wasP = argP === arg;
argP.then(newArg => pk4.resolve([wasP, newArg]));
},
});

return Far('root', {
one() {
return pk3.promise;
},
three() {
pk3.resolve(t2);
return pk4.promise;
},
});
}
36 changes: 36 additions & 0 deletions packages/SwingSet/test/test-promises.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
loadBasedir,
buildKernelBundles,
} from '../src/index';
import { capargs } from './util';

test.before(async t => {
const kernelBundles = await buildKernelBundles();
Expand Down Expand Up @@ -166,3 +167,38 @@ test('circular promise resolution data', async t => {
];
t.deepEqual(c.dump().promises, expectedPromises);
});

test('refcount while queued', async t => {
const config = await loadBasedir(
path.resolve(__dirname, 'basedir-promises-3'),
);
const c = await buildVatController(config, [], t.context.data);

// bootstrap() sets up an unresolved promise (p2, the result promise of
// right~.one()) with vat-right as the decider, and enqueues a message
// (p2~.four(pk)) which contains a second unresolved promise 'pk1'
await c.run();

// then we tell that vat to resolve pk1 to a value (4)
c.queueToVatExport('bootstrap', 'o+0', 'two', capargs([]), 'ignore');
await c.run();

// Now we have a resolved promise 'pk1' whose only reference is the
// arguments of a message queued to a promise. We're exercising the promise
// retirement reference counting: if it allows the 'pk1' refcount to reach
// zero, the promise will be collected, and an error will occur when 'p2'
// is resolved.

// tell vat-right to resolve p2, which should transfer the 'four' message
// from the p2 promise queue to the run-queue for vat-right. That message
// will be delivered, with a new promise that is promptly resolved to '3'.
const kpid4 = c.queueToVatExport(
'right',
'o+0',
'three',
capargs([]),
'ignore',
);
await c.run();
t.deepEqual(c.kpResolution(kpid4), capargs([true, 3]));
});

0 comments on commit 3a78e18

Please sign in to comment.