Skip to content

Commit

Permalink
fix: more tests and further refinements
Browse files Browse the repository at this point in the history
  • Loading branch information
FUDCo committed Oct 30, 2020
1 parent 2e74cc7 commit 72f9624
Show file tree
Hide file tree
Showing 5 changed files with 407 additions and 4 deletions.
29 changes: 28 additions & 1 deletion packages/SwingSet/src/kernel/virtualObjectManager.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { assert, details, q } from '@agoric/assert';
import { parseVatSlot } from '../parseVatSlots';

const initializationInProgress = Symbol('initializing');

/**
* Make a simple LRU cache of virtual object inner selves.
*
Expand All @@ -24,6 +26,16 @@ export function makeCache(size, fetch, store) {
const cache = {
makeRoom() {
while (liveTable.size > size && lruTail) {
if (lruTail.rawData[initializationInProgress]) {
let refreshCount = 1;
while (lruTail.rawData[initializationInProgress]) {
if (refreshCount > size) {
throw Error(`cache overflowed with objects being initialized`);
}
cache.refresh(lruTail);
refreshCount += 1;
}
}
liveTable.delete(lruTail.instanceKey);
store(lruTail.instanceKey, lruTail.rawData);
lruTail.rawData = null;
Expand Down Expand Up @@ -285,6 +297,10 @@ export function makeVirtualObjectManager(
}

function wrapData(target) {
assert(
!target[initializationInProgress],
`object is still being initialized`,
);
for (const prop of Object.getOwnPropertyNames(innerSelf.rawData)) {
Object.defineProperty(target, prop, {
get: () => {
Expand Down Expand Up @@ -328,9 +344,20 @@ export function makeVirtualObjectManager(
nextInstanceID += 1;

const initialData = {};
Object.defineProperty(initialData, initializationInProgress, {
configurable: true,
enumerable: false,
writeable: false,
value: true,
});
const innerSelf = { instanceKey, rawData: initialData };
const initialRepresentative = makeRepresentative(innerSelf, true);
initialRepresentative.initialize(...args);
const initialize = initialRepresentative.initialize;
if (initialize) {
delete initialRepresentative.initialize;
initialize(...args);
}
delete initialData[initializationInProgress];
const rawData = {};
for (const prop of Object.getOwnPropertyNames(initialData)) {
try {
Expand Down
151 changes: 151 additions & 0 deletions packages/SwingSet/test/virtualObjects/test-representatives.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import '@agoric/install-ses';
import path from 'path';
import test from 'ava';
import { buildVatController } from '../../src/index';
import makeNextLog from '../make-nextlog';

function capdata(body, slots = []) {
return harden({ body, slots });
}

function capargs(args, slots = []) {
return capdata(JSON.stringify(args), slots);
}

function slot0(kid) {
return {
body: '{"@qclass":"slot",index:0}',
slots: [kid],
};
}

test('virtual object representatives', async t => {
const config = {
bootstrap: 'bootstrap',
vats: {
bootstrap: {
sourceSpec: path.resolve(__dirname, 'vat-representative-bootstrap.js'),
creationOptions: {
virtualObjectCacheSize: 3,
},
},
},
};

const c = await buildVatController(config);
const nextLog = makeNextLog(c);

await c.run();
t.deepEqual(c.kpResolution(c.bootstrapResult), capargs('bootstrap done'));

async function doTestA(mode, result) {
const r = c.queueToVatExport(
'bootstrap',
'o+0',
'testA',
capargs([`thing${mode}`, mode]),
);
await c.run();
t.is(c.kpStatus(r), 'fulfilled');
t.deepEqual(nextLog(), []);
t.deepEqual(c.kpResolution(r), slot0(result));
}
await doTestA(1, 'ko25');
await doTestA(2, 'ko26');

async function doTestB(mode, result) {
const r = c.queueToVatExport(
'bootstrap',
'o+0',
'testB',
capargs([`thing${mode}`, mode]),
);
await c.run();
t.is(c.kpStatus(r), 'fulfilled');
t.deepEqual(nextLog(), [
`test${mode} thing.name before rename "thing${mode}"`,
`test${mode} initialSelf.name before rename "thing${mode}"`,
`test${mode} thing.name after rename "thing${mode} modified"`,
`test${mode} initialSelf.name after rename "thing${mode} modified"`,
]);
t.deepEqual(c.kpResolution(r), slot0(result));
}
await doTestB(3, 'ko27');
await doTestB(4, 'ko28');
await doTestB(5, 'ko29');
await doTestB(6, 'ko30');

async function doTestC(mode) {
const r = c.queueToVatExport(
'bootstrap',
'o+0',
'testC',
capargs([`thing${mode}`, mode]),
);
await c.run();
t.is(c.kpStatus(r), 'fulfilled');
t.deepEqual(nextLog(), [`test${mode} result is "47"`]);
}
await doTestC(7);
await doTestC(8);
await doTestC(9);
await doTestC(10);

async function doTestD(mode) {
const r = c.queueToVatExport(
'bootstrap',
'o+0',
'testD',
capargs([`thing${mode}`, mode]),
);
await c.run();
t.is(c.kpStatus(r), 'fulfilled');
t.deepEqual(nextLog(), [`test${mode} result is "thing${mode}"`]);
}
await doTestD(11);
await doTestD(12);

async function doTestE(mode) {
const r = c.queueToVatExport(
'bootstrap',
'o+0',
'testE',
capargs([`thing${mode}`, mode]),
);
await c.run();
t.is(c.kpStatus(r), 'fulfilled');
t.deepEqual(nextLog(), [`test${mode} result is "thing${mode} modified"`]);
}
await doTestE(13);
await doTestE(14);
await doTestE(15);
await doTestE(16);
await doTestE(17);
await doTestE(18);
await doTestE(19);
await doTestE(20);

const rz1 = c.queueToVatExport(
'bootstrap',
'o+0',
'testCacheOverflow',
capargs([`zot1`, false]),
);
await c.run();
t.is(c.kpStatus(rz1), 'fulfilled');
t.deepEqual(nextLog(), []);
t.deepEqual(c.kpResolution(rz1), slot0('ko31'));

const rz2 = c.queueToVatExport(
'bootstrap',
'o+0',
'testCacheOverflow',
capargs([`zot2`, true]),
);
await c.run();
t.is(c.kpStatus(rz2), 'fulfilled');
t.deepEqual(nextLog(), [
'testCacheOverflow catches Error: cache overflowed with objects being initialized',
]);
t.deepEqual(c.kpResolution(rz2), capdata('"overflow"'));
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import '@agoric/install-ses';
import test from 'ava';
import { makeCache } from '../src/kernel/virtualObjectManager';
import { makeCache } from '../../src/kernel/virtualObjectManager';

function makeFakeStore() {
const backing = new Map();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import '@agoric/install-ses';
import test from 'ava';
import { makeMarshal } from '@agoric/marshal';
import { assert } from '@agoric/assert';
import { parseVatSlot } from '../src/parseVatSlots';
import { makeVirtualObjectManager } from '../src/kernel/virtualObjectManager';
import { parseVatSlot } from '../../src/parseVatSlots';
import { makeVirtualObjectManager } from '../../src/kernel/virtualObjectManager';

function capdata(body, slots = []) {
return harden({ body, slots });
Expand Down
Loading

0 comments on commit 72f9624

Please sign in to comment.