Skip to content

Commit

Permalink
test(SwingSet): Improve vat-direct.js
Browse files Browse the repository at this point in the history
  • Loading branch information
gibson042 committed Mar 19, 2023
1 parent 78de461 commit 530b23b
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 25 deletions.
22 changes: 15 additions & 7 deletions packages/SwingSet/test/upgrade/test-upgrade.js
Original file line number Diff line number Diff line change
Expand Up @@ -546,12 +546,12 @@ test('non-durable exports are abandoned by upgrade of non-liveslots vat', async
});
config.vats.exporter = {
sourceSpec: bfile('../vat-direct.js'),
parameters: { role: 'exporter' },
parameters: { vatName: 'exporter' },
creationOptions: { enableSetup: true },
};
config.vats.observer = {
sourceSpec: bfile('../vat-direct.js'),
parameters: { role: 'observer' },
parameters: { vatName: 'observer' },
creationOptions: { enableSetup: true },
};
const { controller, kvStore, run } = await initKernelForTest(
Expand All @@ -568,10 +568,18 @@ test('non-durable exports are abandoned by upgrade of non-liveslots vat', async
const observer = await run('awaitVatObject', [
{ presence: observerPresence, rawOutput: true },
]);
const strongObj = await run('makeObject', [], 'exporter');
await run('sendOnly', [observer, 'holdThis', [strongObj]], 'exporter');
const weakObj = await run('makeObject', [], 'exporter');
await run('sendOnly', [observer, 'recognizeThis', [weakObj]], 'exporter');
const strongObj = await run('exportFakeObject', [], 'exporter');
await run(
'syscall-send',
[observer, 'acceptImports', [strongObj]],
'exporter',
);
const weakObj = await run('exportFakeObject', [], 'exporter');
await run(
'syscall-send',
[observer, 'acceptWeakImports', [weakObj]],
'exporter',
);

// Verify kernel tracking of the objects.
const getKrefReachableAndRecognizable = kref =>
Expand Down Expand Up @@ -607,7 +615,7 @@ test('non-durable exports are abandoned by upgrade of non-liveslots vat', async

// TODO: Verify observer receipt of dispatch.retireExports
// https://github.com/Agoric/agoric-sdk/issues/6696#issuecomment-1431881255
const observerLog = await run('getLog', [], 'observer');
const observerLog = await run('getDispatchLog', [], 'observer');
t.deepEqual(observerLog, [], 'TODO');
});

Expand Down
80 changes: 62 additions & 18 deletions packages/SwingSet/test/vat-direct.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,102 @@
import { extractMessage } from './vat-util.js';
import { kser, kslot, kunser } from '../src/lib/kmarshal.js';
import { krefOf, kser, kslot, kunser } from '../src/lib/kmarshal.js';

const promiseFulfillment = (vpid, value) => [[vpid, false, kser(value)]];
const promiseRejection = (vpid, reason) => [[vpid, true, kser(reason)]];
/**
* A testing vat that generically exposes kernel interactions
* which are normally handled by liveslots.
*/

/**
* @param {string} vpid - vat-centric promise ID p+NN
* @param {boolean} isRejection
* @param {unknown} value - fulfillment or rejection value
* @returns {VatOneResolution[]}
*/
const promiseSettlement = (vpid, isRejection, value) => [
[vpid, isRejection, kser(value)],
];
const promiseFulfillment = (vpid, value) =>
promiseSettlement(vpid, false, value);
const promiseRejection = (vpid, reason) =>
promiseSettlement(vpid, true, reason);

export default function setup(syscall, _state, _helpers, vatPowers) {
// eslint-disable-next-line no-unused-vars
const { testLog } = vatPowers;

// eslint-disable-next-line no-unused-vars
let role;
let vatName;
let lastExportID = 99;
const incExportID = () => {
lastExportID += 1;
return lastExportID;
};
let log = [];
/** @type {KernelDeliveryObject[]} */
let dispatchLog = [];

/**
* Process an inbound message.
*
* @param {KernelDeliveryObject} vatDeliverObject
* @returns {void}
*/
function dispatch(vatDeliverObject) {
log = [...log, vatDeliverObject];
if (vatDeliverObject[0] === 'startVat') {
({ role } = kunser(vatDeliverObject[1]) || {});
// Append to the log by copying (since exporting the log in getDispatchLog
// automatically hardens it).
dispatchLog = [...dispatchLog, vatDeliverObject];

// Capture initial configuration.
const deliveryType = vatDeliverObject[0];
if (deliveryType === 'startVat') {
const vatParameters = kunser(vatDeliverObject[1]) || {};
const newVatName = vatParameters.vatName;
if (newVatName !== undefined) {
vatName = newVatName;
}
}
if (vatDeliverObject[0] !== 'message') {

// React only to message deliveries.
if (deliveryType !== 'message') {
return;
}

const {
method,
args: argsCapdata,
result,
} = extractMessage(vatDeliverObject);
// Default to resolving a result promise with `undefined`.
/** @type {VatOneResolution[]} */
let resolutions = promiseFulfillment(result, undefined);
try {
// Supported methods should have names that indicate what they
// cause this vat to do but (for greppability) should not
// duplicate names that appear in actual kernel/liveslots code.
switch (method) {
case 'getLog':
resolutions = promiseFulfillment(result, log);
case 'getDispatchLog':
resolutions = promiseFulfillment(result, dispatchLog);
break;

case 'holdThis':
case 'acceptImports':
break;
case 'recognizeThis':
case 'acceptWeakImports':
syscall.dropImports(argsCapdata.slots);
break;

case 'makeObject':
case 'exportFakeObject': {
// Currently limited to ephemeral objects
// (i.e., non-virtual and non-durable).
const vref = `o+${incExportID()}`;
resolutions = promiseFulfillment(
result,
kslot(`o+${incExportID()}`, 'Fake Object'),
kslot(vref, `Fake Remoteable ${vatName} ${vref}`),
);
break;
}

case 'sendOnly': {
case 'syscall-send': {
const [sendTarget, sendMethod, sendArgs] = kunser(argsCapdata);
const sendTargetVref = kser(sendTarget).slots[0];
const sendTargetVref = krefOf(sendTarget);
// Currently limited to send-only (i.e., no resultVPID).
syscall.send(sendTargetVref, kser([sendMethod, sendArgs]));
break;
}
Expand Down

0 comments on commit 530b23b

Please sign in to comment.