Skip to content

Commit

Permalink
Merge pull request #8618 from Agoric/8455-fakeVirtual-watchedPromises
Browse files Browse the repository at this point in the history
test: support for watchedPromises in fakeVirtualSupport
  • Loading branch information
mergify[bot] authored Dec 6, 2023
2 parents 414e88b + 8129d45 commit 241c60a
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -590,12 +590,12 @@ test('durable kind IDs can be reanimated', t => {

// Store it in the store without having used it
placeToPutIt.init('savedKindID', kindHandle);
t.is(log.shift(), 'get vc.1.ssavedKindID => undefined');
t.is(log.shift(), 'get vc.4.ssavedKindID => undefined');
t.is(log.shift(), `get vom.rc.${khid} => undefined`);
t.is(log.shift(), `set vom.rc.${khid} 1`);
t.is(log.shift(), `set vc.1.ssavedKindID ${vstr(kind)}`);
t.is(log.shift(), 'get vc.1.|entryCount => 0');
t.is(log.shift(), 'set vc.1.|entryCount 1');
t.is(log.shift(), `set vc.4.ssavedKindID ${vstr(kind)}`);
t.is(log.shift(), 'get vc.4.|entryCount => 0');
t.is(log.shift(), 'set vc.4.|entryCount 1');
t.deepEqual(log, []);

// Forget its Representative
Expand All @@ -609,7 +609,7 @@ test('durable kind IDs can be reanimated', t => {

// Fetch it from the store, which should reanimate it
const fetchedKindID = placeToPutIt.get('savedKindID');
t.is(log.shift(), `get vc.1.ssavedKindID => ${vstr(kind)}`);
t.is(log.shift(), `get vc.4.ssavedKindID => ${vstr(kind)}`);
t.is(
log.shift(),
'get vom.dkind.10.descriptor => {"kindID":"10","tag":"testkind"}',
Expand Down Expand Up @@ -658,9 +658,23 @@ test('virtual object gc', t => {
];
t.is(log.shift(), `get storeKindIDTable => undefined`);
t.is(log.shift(), `set ${skit[0]} ${skit[1]}`);
t.is(log.shift(), 'set vc.1.|nextOrdinal 1');
t.is(log.shift(), 'set vc.1.|entryCount 0');
t.is(log.shift(), 'get watcherTableID => undefined');
t.is(log.shift(), 'set vc.2.|nextOrdinal 1');
t.is(log.shift(), 'set vc.2.|entryCount 0');
t.is(log.shift(), 'set watcherTableID o+d6/2');
t.is(log.shift(), 'get vom.rc.o+d6/2 => undefined');
t.is(log.shift(), 'set vom.rc.o+d6/2 1');
t.is(log.shift(), 'get watchedPromiseTableID => undefined');
t.is(log.shift(), 'set vc.3.|nextOrdinal 1');
t.is(log.shift(), 'set vc.3.|entryCount 0');
t.is(log.shift(), 'set watchedPromiseTableID o+d6/3');
t.is(log.shift(), 'get vom.rc.o+d6/3 => undefined');
t.is(log.shift(), 'set vom.rc.o+d6/3 1');
t.is(
log.shift(),
`set vom.vkind.10.descriptor {"kindID":"10","tag":"thing"}`,
'set vom.vkind.10.descriptor {"kindID":"10","tag":"thing"}',
);
t.is(log.shift(), `set vom.vkind.11.descriptor {"kindID":"11","tag":"ref"}`);
t.deepEqual(log, []);
Expand All @@ -686,6 +700,12 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.${tbase}/1`, minThing('thing #1')],
[`vom.${tbase}/2`, minThing('thing #2')],
[`vom.${tbase}/3`, minThing('thing #3')],
Expand All @@ -695,8 +715,12 @@ test('virtual object gc', t => {
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);

// This is what the finalizer would do if the local reference was dropped and GC'd
Expand All @@ -722,6 +746,12 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.es.${tbase}/1`, 'r'],
[`vom.${tbase}/1`, minThing('thing #1')],
[`vom.${tbase}/2`, minThing('thing #2')],
Expand All @@ -732,8 +762,12 @@ test('virtual object gc', t => {
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);

// drop export -- should delete
Expand Down Expand Up @@ -763,6 +797,12 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.${tbase}/2`, minThing('thing #2')],
[`vom.${tbase}/3`, minThing('thing #3')],
[`vom.${tbase}/4`, minThing('thing #4')],
Expand All @@ -771,8 +811,12 @@ test('virtual object gc', t => {
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);

// case 2: export, drop export, drop local ref
Expand All @@ -790,6 +834,12 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.es.${tbase}/2`, 's'],
[`vom.${tbase}/2`, minThing('thing #2')],
[`vom.${tbase}/3`, minThing('thing #3')],
Expand All @@ -799,8 +849,12 @@ test('virtual object gc', t => {
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);

// drop local ref -- should delete
Expand All @@ -821,15 +875,25 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.${tbase}/3`, minThing('thing #3')],
[`vom.${tbase}/4`, minThing('thing #4')],
[`vom.${tbase}/5`, minThing('thing #5')],
[`vom.${tbase}/6`, minThing('thing #6')],
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);

// case 3: drop local ref with no prior export
Expand All @@ -851,14 +915,24 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.${tbase}/4`, minThing('thing #4')],
[`vom.${tbase}/5`, minThing('thing #5')],
[`vom.${tbase}/6`, minThing('thing #6')],
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);

// case 4: ref virtually, export, drop local ref, drop export
Expand All @@ -871,15 +945,25 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.${tbase}/4`, minThing('thing #4')],
[`vom.${tbase}/5`, minThing('thing #5')],
[`vom.${tbase}/6`, minThing('thing #6')],
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
[`vom.rc.${tbase}/4`, '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);
// export
setExportStatus(`${tbase}/4`, 'reachable');
Expand Down Expand Up @@ -913,6 +997,12 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.es.${tbase}/4`, 's'],
[`vom.es.${tbase}/5`, 'r'],
[`vom.${tbase}/4`, minThing('thing #4')],
Expand All @@ -921,10 +1011,14 @@ test('virtual object gc', t => {
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
[`vom.rc.${tbase}/4`, '1'],
[`vom.rc.${tbase}/5`, '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);
// drop local ref -- should not delete because ref'd virtually AND exported
pretendGC(`${tbase}/5`, false);
Expand All @@ -948,6 +1042,12 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.es.${tbase}/4`, 's'],
[`vom.es.${tbase}/5`, 's'],
[`vom.${tbase}/4`, minThing('thing #4')],
Expand All @@ -956,11 +1056,15 @@ test('virtual object gc', t => {
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
[`vom.rc.${tbase}/4`, '1'],
[`vom.rc.${tbase}/5`, '1'],
[`vom.rc.${tbase}/6`, '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);
// drop local ref -- should not delete because ref'd virtually
pretendGC(`${tbase}/6`, false);
Expand All @@ -970,6 +1074,12 @@ test('virtual object gc', t => {
t.deepEqual(dumpStore(), [
['kindIDID', '1'],
skit,
['vc.1.|entryCount', '0'],
['vc.1.|nextOrdinal', '1'],
['vc.2.|entryCount', '0'],
['vc.2.|nextOrdinal', '1'],
['vc.3.|entryCount', '0'],
['vc.3.|nextOrdinal', '1'],
[`vom.es.${tbase}/4`, 's'],
[`vom.es.${tbase}/5`, 's'],
[`vom.${tbase}/4`, minThing('thing #4')],
Expand All @@ -978,11 +1088,15 @@ test('virtual object gc', t => {
[`vom.${tbase}/7`, minThing('thing #7')],
[`vom.${tbase}/8`, minThing('thing #8')],
[`vom.${tbase}/9`, minThing('thing #9')],
['vom.rc.o+d6/2', '1'],
['vom.rc.o+d6/3', '1'],
[`vom.rc.${tbase}/4`, '1'],
[`vom.rc.${tbase}/5`, '1'],
[`vom.rc.${tbase}/6`, '1'],
['vom.vkind.10.descriptor', '{"kindID":"10","tag":"thing"}'],
['vom.vkind.11.descriptor', '{"kindID":"11","tag":"ref"}'],
['watchedPromiseTableID', 'o+d6/3'],
['watcherTableID', 'o+d6/2'],
]);
});

Expand Down
13 changes: 11 additions & 2 deletions packages/swingset-liveslots/tools/fakeVirtualSupport.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
/* eslint-disable max-classes-per-file */
import { makeMarshal } from '@endo/marshal';
import { assert } from '@agoric/assert';
import { parseVatSlot } from '../src/parseVatSlots.js';
import { isPromise } from '@endo/promise-kit';

import { parseVatSlot } from '../src/parseVatSlots.js';
import { makeVirtualReferenceManager } from '../src/virtualReferences.js';
import { makeWatchedPromiseManager } from '../src/watchedPromises.js';
import { makeFakeVirtualObjectManager } from './fakeVirtualObjectManager.js';
Expand Down Expand Up @@ -163,6 +164,10 @@ export function makeFakeLiveSlotsStuff(options = {}) {
return vrm.allocateNextID('exportID');
}

function allocatePromiseID() {
return vrm.allocateNextID('promiseID');
}

function allocateCollectionID() {
return vrm.allocateNextID('collectionID');
}
Expand Down Expand Up @@ -195,7 +200,9 @@ export function makeFakeLiveSlotsStuff(options = {}) {

function convertValToSlot(val) {
if (!valToSlot.has(val)) {
const slot = `o+${allocateExportID()}`;
const slot = isPromise(val)
? `p+${allocatePromiseID()}`
: `o+${allocateExportID()}`;
valToSlot.set(val, slot);
setValForSlot(slot, val);
}
Expand Down Expand Up @@ -324,6 +331,7 @@ export function makeFakeWatchedPromiseManager(
maybeExportPromise: fakeStuff.maybeExportPromise,
});
}

/**
* Configure virtual stuff with relaxed durability rules and fake liveslots
*
Expand All @@ -348,6 +356,7 @@ export function makeFakeVirtualStuff(options = {}) {
vom.initializeKindHandleKind();
const cm = makeFakeCollectionManager(vrm, fakeStuff, actualOptions);
const wpm = makeFakeWatchedPromiseManager(vrm, vom, cm, fakeStuff);
wpm.preparePromiseWatcherTables();
return { fakeStuff, vrm, vom, cm, wpm };
}

Expand Down

0 comments on commit 241c60a

Please sign in to comment.