Skip to content

Commit f15974a

Browse files
committed
chore(swingset): comms: new addEgress refcount test
* expose state.getRefCounts() for debugging and tests
1 parent 988cb14 commit f15974a

File tree

2 files changed

+82
-1
lines changed

2 files changed

+82
-1
lines changed

packages/SwingSet/src/vats/comms/state.js

+9
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,14 @@ export function makeState(syscall, identifierBase = 0) {
319319
}
320320
}
321321

322+
function getRefCounts(lref) {
323+
const reaKey = `${lref}.reachable`;
324+
const reachable = Nat(BigInt(store.getRequired(reaKey)));
325+
const recKey = `${lref}.recognizable`;
326+
const recognizable = Nat(BigInt(store.getRequired(recKey)));
327+
return { reachable, recognizable };
328+
}
329+
322330
/**
323331
* Delete any local promises that have zero references. Return a list of
324332
* work for unreachable/unrecognizable objects.
@@ -748,6 +756,7 @@ export function makeState(syscall, identifierBase = 0) {
748756
lrefMightBeFree,
749757
incrementRefCount,
750758
decrementRefCount,
759+
getRefCounts,
751760
processMaybeFree,
752761

753762
deciderIsKernel,

packages/SwingSet/test/test-comms.js

+73-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// eslint-disable-next-line import/order
12
import { test } from '../tools/prepare-test-env-ava.js';
23

34
import buildCommsDispatch from '../src/vats/comms/index.js';
@@ -63,13 +64,19 @@ test('translation', t => {
6364

6465
function mockSyscall() {
6566
const sends = [];
67+
const resolves = [];
6668
const gcs = [];
6769
const fakestore = new Map();
6870
const syscall = harden({
6971
send(targetSlot, method, args, _result) {
7072
sends.push([targetSlot, method, args]);
7173
// return 'r-1';
7274
},
75+
resolve(resolutions) {
76+
for (const resolution of resolutions) {
77+
resolves.push(resolution);
78+
}
79+
},
7380
subscribe(_targetSlot) {},
7481
vatstoreGet(key) {
7582
return fakestore.get(key);
@@ -90,7 +97,7 @@ function mockSyscall() {
9097
gcs.push(['retireExports', vrefs]);
9198
},
9299
});
93-
return { syscall, sends, gcs, fakestore };
100+
return { syscall, sends, resolves, gcs, fakestore };
94101
}
95102

96103
/*
@@ -338,6 +345,71 @@ test('receive', t => {
338345
t.deepEqual(gcs, []);
339346
});
340347

348+
test('addEgress', t => {
349+
const { syscall } = mockSyscall();
350+
const dispatch = buildCommsDispatch(syscall, 'fakestate', 'fakehelpers');
351+
const { state, clistKit } = debugState.get(dispatch);
352+
state.initialize();
353+
const { getLocalForKernel, getRemoteForLocal } = clistKit;
354+
const transmitterID = 'o-1';
355+
const remoteName = 'remote1';
356+
const { remoteID } = state.addRemote(remoteName, transmitterID);
357+
358+
// prepare an object for the remote to access
359+
const index = 12;
360+
const kfref = 'o-2';
361+
const kfrefObj = { '@qclass': 'slot', iface: 'Alleged: export', index: 0 };
362+
const args = {
363+
body: JSON.stringify([remoteName, index, kfrefObj]),
364+
slots: [kfref],
365+
};
366+
const result = 'p-1';
367+
const vdo = ['message', 'o+0', { method: 'addEgress', args, result }];
368+
dispatch(vdo);
369+
370+
const lref = getLocalForKernel(kfref);
371+
const { reachable, recognizable } = state.getRefCounts(lref);
372+
t.is(reachable, 1n);
373+
t.is(recognizable, 1n);
374+
375+
// the outbound rref should be `ro-12`, since we're exporting it, and the
376+
// remote protocol is exceedingly polite
377+
const outboundRref = getRemoteForLocal(remoteID, lref);
378+
t.is(outboundRref, `ro-${index}`);
379+
});
380+
381+
test('addIngress', t => {
382+
const { syscall, resolves } = mockSyscall();
383+
const dispatch = buildCommsDispatch(syscall, 'fakestate', 'fakehelpers');
384+
const { state, clistKit } = debugState.get(dispatch);
385+
state.initialize();
386+
const { getLocalForKernel, getRemoteForLocal } = clistKit;
387+
const transmitterID = 'o-1';
388+
const remoteName = 'remote1';
389+
const { remoteID } = state.addRemote(remoteName, transmitterID);
390+
391+
// pretend the remote has an object for us to access
392+
const index = 12;
393+
const iface = 'iface name';
394+
const args = { body: JSON.stringify([remoteName, index, iface]), slots: [] };
395+
const result = 'p-1';
396+
const vdo = ['message', 'o+0', { method: 'addIngress', args, result }];
397+
dispatch(vdo);
398+
399+
t.is(resolves.length, 1);
400+
const kfref = resolves[0][2].slots[0];
401+
const lref = getLocalForKernel(kfref);
402+
403+
const { reachable, recognizable } = state.getRefCounts(lref);
404+
t.is(reachable, 1n);
405+
t.is(recognizable, 1n);
406+
407+
// the outbound rref should be `ro+12`, since we're importing it, and the
408+
// remote protocol is exceedingly polite
409+
const outboundRref = getRemoteForLocal(remoteID, lref);
410+
t.is(outboundRref, `ro+${index}`);
411+
});
412+
341413
test('comms gc', t => {
342414
// we exercise comms on machine A, which is communicating with machine B
343415
// about various objects that are dropped and retired

0 commit comments

Comments
 (0)