Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a mock virtual object manager to support unit tests outside SwingSet #2543

Merged
merged 2 commits into from
Mar 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,80 +1,13 @@
import '@agoric/install-ses';
import test from 'ava';
import { makeMarshal, Far } from '@agoric/marshal';
import { assert } from '@agoric/assert';
import { parseVatSlot } from '../../src/parseVatSlots';
import { makeVirtualObjectManager } from '../../src/kernel/virtualObjectManager';
import { Far } from '@agoric/marshal';
import { makeFakeVirtualObjectManager } from '../../tools/fakeVirtualObjectManager';

function capdata(body, slots = []) {
return harden({ body, slots });
}
const s = JSON.stringify;

function makeAllTheStuff(cacheSize) {
const fakeStore = new Map();

function dumpStore() {
const result = [];
for (const entry of fakeStore.entries()) {
result.push(entry);
}
result.sort((e1, e2) => e1[0].localeCompare(e2[0]));
return result;
}

const fakeSyscall = {
vatstoreGet: key => fakeStore.get(key),
vatstoreSet: (key, value) => fakeStore.set(key, value),
vatstoreDelete: key => fakeStore.delete(key),
};

let nextExportID = 1;
function fakeAllocateExportID() {
const exportID = nextExportID;
nextExportID += 1;
return exportID;
}

const valToSlot = new WeakMap();

// eslint-disable-next-line no-use-before-define
const fakeMarshal = makeMarshal(fakeConvertValToSlot, fakeConvertSlotToVal);

const {
makeVirtualObjectRepresentative,
makeWeakStore,
makeKind,
flushCache,
} = makeVirtualObjectManager(
fakeSyscall,
fakeAllocateExportID,
valToSlot,
fakeMarshal,
cacheSize,
);

function fakeConvertValToSlot(val) {
return valToSlot.get(val);
}

function fakeConvertSlotToVal(slot) {
const { type, virtual } = parseVatSlot(slot);
assert(
virtual,
'fakeConvertSlotToVal only works with virtual object references',
);
assert.equal(type, 'object');
return makeVirtualObjectRepresentative(slot);
}

return {
makeWeakStore,
makeKind,
flushCache,
dumpStore,
};
}

function makeThingInstance(state) {
return {
init(label = 'thing', counter = 0) {
Expand Down Expand Up @@ -132,7 +65,7 @@ function makeZotInstance(state) {
}

test('virtual object operations', t => {
const { makeKind, flushCache, dumpStore } = makeAllTheStuff(3);
const { makeKind, flushCache, dumpStore } = makeFakeVirtualObjectManager(3);

const thingMaker = makeKind(makeThingInstance);
const zotMaker = makeKind(makeZotInstance);
Expand Down Expand Up @@ -231,7 +164,7 @@ test('virtual object operations', t => {
});

test('weak store operations', t => {
const { makeWeakStore, makeKind } = makeAllTheStuff(3);
const { makeWeakStore, makeKind } = makeFakeVirtualObjectManager(3);

const thingMaker = makeKind(makeThingInstance);
const zotMaker = makeKind(makeZotInstance);
Expand Down
77 changes: 77 additions & 0 deletions packages/SwingSet/tools/fakeVirtualObjectManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { makeMarshal } from '@agoric/marshal';
import { assert } from '@agoric/assert';
import { parseVatSlot } from '../src/parseVatSlots';

import { makeVirtualObjectManager } from '../src/kernel/virtualObjectManager';

export function makeFakeVirtualObjectManager(cacheSize = 100) {
const fakeStore = new Map();

function dumpStore() {
const result = [];
for (const entry of fakeStore.entries()) {
result.push(entry);
}
result.sort((e1, e2) => e1[0].localeCompare(e2[0]));
return result;
}

const fakeSyscall = {
vatstoreGet: key => fakeStore.get(key),
vatstoreSet: (key, value) => fakeStore.set(key, value),
vatstoreDelete: key => fakeStore.delete(key),
};

let nextExportID = 1;
function fakeAllocateExportID() {
const exportID = nextExportID;
nextExportID += 1;
return exportID;
}

const valToSlot = new WeakMap();
const slotToVal = new Map();

function fakeConvertValToSlot(val) {
if (!valToSlot.has(val)) {
const slot = `o+${fakeAllocateExportID()}`;
valToSlot.set(val, slot);
slotToVal.set(slot, val);
}
return valToSlot.get(val);
}

function fakeConvertSlotToVal(slot) {
const { type, virtual } = parseVatSlot(slot);
assert.equal(type, 'object');
if (virtual) {
// eslint-disable-next-line no-use-before-define
return makeVirtualObjectRepresentative(slot);
} else {
return slotToVal.get(slot);
}
}

// eslint-disable-next-line no-use-before-define
const fakeMarshal = makeMarshal(fakeConvertValToSlot, fakeConvertSlotToVal);

const {
makeVirtualObjectRepresentative,
makeWeakStore,
makeKind,
flushCache,
} = makeVirtualObjectManager(
fakeSyscall,
fakeAllocateExportID,
valToSlot,
fakeMarshal,
cacheSize,
);

return {
makeKind,
makeWeakStore,
flushCache,
dumpStore,
};
}