Skip to content

Commit ba1f244

Browse files
committed
fix(swingset): test-comms.js: fix retireImports test
This unit test was exercising `dispatch.retireImports`, just to ensure that it didn't cause a crash. But the invocation was not semantically valid: it was retiring an object without first dropping it. That didn't matter when the implementation was a no-op, but now that it actually behaves correctly, this invocation is invalid, and causes an assertion failure. The new test exercises this correctly, at least in one direction.
1 parent c901eb6 commit ba1f244

File tree

1 file changed

+54
-18
lines changed

1 file changed

+54
-18
lines changed

packages/SwingSet/test/test-comms.js

+54-18
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,7 @@ import { flipRemoteSlot } from '../src/vats/comms/parseRemoteSlot.js';
55
import { makeState } from '../src/vats/comms/state.js';
66
import { makeCListKit } from '../src/vats/comms/clist.js';
77
import { debugState } from '../src/vats/comms/dispatch.js';
8-
import {
9-
makeMessage,
10-
makeDropExports,
11-
makeRetireExports,
12-
makeRetireImports,
13-
} from './util.js';
8+
import { makeMessage, makeDropExports, makeRetireExports } from './util.js';
149
import { commsVatDriver } from './commsVatDriver.js';
1510

1611
test('provideRemoteForLocal', t => {
@@ -46,6 +41,7 @@ test('provideRemoteForLocal', t => {
4641

4742
function mockSyscall() {
4843
const sends = [];
44+
const gcs = [];
4945
const fakestore = new Map();
5046
const syscall = harden({
5147
send(targetSlot, method, args) {
@@ -62,8 +58,17 @@ function mockSyscall() {
6258
vatstoreDelete(key) {
6359
fakestore.delete(key);
6460
},
61+
dropImports(vrefs) {
62+
gcs.push(['dropImports', vrefs]);
63+
},
64+
retireImports(vrefs) {
65+
gcs.push(['retireImports', vrefs]);
66+
},
67+
retireExports(vrefs) {
68+
gcs.push(['retireExports', vrefs]);
69+
},
6570
});
66-
return { syscall, sends };
71+
return { syscall, sends, gcs };
6772
}
6873

6974
function capdata(body, slots = []) {
@@ -152,7 +157,7 @@ test('transmit', t => {
152157
test('receive', t => {
153158
// look at machine B, which is receiving remote messages aimed at a local
154159
// vat's object 'bob'
155-
const { syscall, sends } = mockSyscall();
160+
const { syscall, sends, gcs } = mockSyscall();
156161
const dispatch = buildCommsDispatch(syscall, 'fakestate', 'fakehelpers');
157162
const { state, clistKit } = debugState.get(dispatch);
158163
state.initialize();
@@ -252,18 +257,49 @@ test('receive', t => {
252257
// { message: /unexpected recv seqNum .*/ },
253258
// );
254259

255-
// make sure comms can tolerate GC operations, even if they're a no-op
260+
// bob!cat(alice, bob, agrippa)
261+
const expectedAgrippaKernel = 'o+33';
262+
dispatch(
263+
makeMessage(
264+
receiverID,
265+
'receive',
266+
encodeArgs(
267+
`5:0:deliver:${bobRemote}:cat::ro-20:${bobRemote}:ro-22;argsbytes`,
268+
),
269+
),
270+
);
271+
t.deepEqual(sends.shift(), [
272+
bobKernel,
273+
'cat',
274+
capdata('argsbytes', [
275+
expectedAliceKernel,
276+
bobKernel,
277+
expectedAgrippaKernel,
278+
]),
279+
]);
280+
281+
// upstream GC operations should work
256282
dispatch(makeDropExports(expectedAliceKernel, expectedAyanaKernel));
283+
const gc1 = `1:5:gc:dropExport:ro+20\ngc:dropExport:ro+21`;
284+
t.deepEqual(sends.shift(), [transmitterID, 'transmit', encodeArgs(gc1)]);
285+
257286
dispatch(makeRetireExports(expectedAliceKernel, expectedAyanaKernel));
258-
// Sending retireImport into a vat that hasn't yet emitted dropImport is
259-
// rude, and would only happen if the exporter unilaterally revoked the
260-
// object's identity. Normally the kernel would only send retireImport
261-
// after receiving dropImport (and sending a dropExport into the exporter,
262-
// and getting a retireExport from the exporter, gracefully terminating the
263-
// object's identity). We do it the rude way because it's good enough to
264-
// test the comms vat can tolerate it, but we may have to update this when
265-
// we implement retireImport for real.
266-
dispatch(makeRetireImports(bobKernel));
287+
const gc2 = `2:5:gc:retireExport:ro+20\ngc:retireExport:ro+21`;
288+
t.deepEqual(sends.shift(), [transmitterID, 'transmit', encodeArgs(gc2)]);
289+
t.deepEqual(sends, []);
290+
291+
// sending an upstream drop makes it legal to expect a downstream retire
292+
dispatch(makeDropExports(expectedAgrippaKernel));
293+
const gc3 = `3:5:gc:dropExport:ro+22`;
294+
t.deepEqual(sends.shift(), [transmitterID, 'transmit', encodeArgs(gc3)]);
295+
t.deepEqual(sends, []);
296+
297+
dispatch(
298+
makeMessage(receiverID, 'receive', encodeArgs(`6:3:gc:retireImport:ro-22`)),
299+
);
300+
301+
t.deepEqual(gcs.shift(), ['retireExports', [expectedAgrippaKernel]]);
302+
t.deepEqual(gcs, []);
267303
});
268304

269305
// This tests the various pathways through the comms vat driver. This has the

0 commit comments

Comments
 (0)