Skip to content

Commit

Permalink
test(cosmic-swingset): Update mock-chain pushCoreEval to require sour…
Browse files Browse the repository at this point in the history
…ce text input

This reduces the risk of lexical shear between definition in a *.test.js
file and evaluation in a core-eval compartment.
  • Loading branch information
gibson042 committed Nov 9, 2024
1 parent 55b9b49 commit db8108a
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 46 deletions.
98 changes: 56 additions & 42 deletions packages/cosmic-swingset/test/run-policy.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,12 @@ test('cleanup work must be limited by vat_cleanup_budget', async t => {
};

// Launch the new vat and capture its ID.
pushCoreEval(async powers => {
const { bootstrap } = powers.vats;
await E(bootstrap).createVat('doomed', 'puppet');
});
pushCoreEval(
`${async powers => {
const { bootstrap } = powers.vats;
await E(bootstrap).createVat('doomed', 'puppet');
}}`,
);
await runNextBlock();
const vatIDs = JSON.parse(mustGet('vat.dynamicIDs'));
const vatID = vatIDs.at(-1);
Expand All @@ -117,39 +119,49 @@ test('cleanup work must be limited by vat_cleanup_budget', async t => {
t.not(initialEntries.size, 0, 'initial kvStore entries must exist');

// Give the vat a big footprint.
pushCoreEval(async powers => {
const { bootstrap } = powers.vats;
const doomed = await E(bootstrap).getVatRoot('doomed');

const makeArray = (length, makeElem) => Array.from({ length }, makeElem);

// import 20 remotables and 10 promises
const doomedRemotableImports = await Promise.all(
makeArray(20, (_, i) => E(bootstrap).makeRemotable(`doomed import ${i}`)),
);
const doomedPromiseImports = (
await Promise.all(makeArray(10, () => E(bootstrap).makePromiseKit()))
).map(kit => kit.promise);
const doomedImports = [...doomedRemotableImports, ...doomedPromiseImports];
await E(doomed).holdInHeap(doomedImports);

// export 20 remotables and 10 promises to bootstrap
const doomedRemotableExports = await Promise.all(
makeArray(20, (_, i) => E(doomed).makeRemotable(`doomed export ${i}`)),
);
const doomedPromiseExports = (
await Promise.all(makeArray(10, () => E(doomed).makePromiseKit()))
).map(kit => {
const { promise } = kit;
void promise.catch(() => {});
return promise;
});
const doomedExports = [...doomedRemotableExports, ...doomedPromiseExports];
await E(bootstrap).holdInHeap(doomedExports);

// make 20 extra vatstore entries
await E(doomed).holdInBaggage(...makeArray(20, (_, i) => i));
});
pushCoreEval(
`${async powers => {
const { bootstrap } = powers.vats;
const doomed = await E(bootstrap).getVatRoot('doomed');
const makeArray = (length, makeElem) => Array.from({ length }, makeElem);
// import 20 remotables and 10 promises
const doomedRemotableImports = await Promise.all(
makeArray(20, (_, i) =>
E(bootstrap).makeRemotable(`doomed import ${i}`),
),
);
const doomedPromiseImports = (
await Promise.all(makeArray(10, () => E(bootstrap).makePromiseKit()))
).map(kit => kit.promise);
const doomedImports = [
...doomedRemotableImports,
...doomedPromiseImports,
];
await E(doomed).holdInHeap(doomedImports);
// export 20 remotables and 10 promises to bootstrap
const doomedRemotableExports = await Promise.all(
makeArray(20, (_, i) => E(doomed).makeRemotable(`doomed export ${i}`)),
);
const doomedPromiseExports = (
await Promise.all(makeArray(10, () => E(doomed).makePromiseKit()))
).map(kit => {
const { promise } = kit;
void promise.catch(() => {});
return promise;
});
const doomedExports = [
...doomedRemotableExports,
...doomedPromiseExports,
];
await E(bootstrap).holdInHeap(doomedExports);
// make 20 extra vatstore entries
await E(doomed).holdInBaggage(...makeArray(20, (_, i) => i));
}}`,
);
await runNextBlock();
t.false(
JSON.parse(mustGet('vats.terminated')).includes(vatID),
Expand All @@ -167,11 +179,13 @@ test('cleanup work must be limited by vat_cleanup_budget', async t => {
);

// Terminate the vat and verify lack of cleanup.
pushCoreEval(async powers => {
const { bootstrap } = powers.vats;
const adminNode = await E(bootstrap).getVatAdminNode('doomed');
await E(adminNode).terminateWithFailure();
});
pushCoreEval(
`${async powers => {
const { bootstrap } = powers.vats;
const adminNode = await E(bootstrap).getVatAdminNode('doomed');
await E(adminNode).terminateWithFailure();
}}`,
);
await runNextBlock();
t.true(
JSON.parse(mustGet('vats.terminated')).includes(vatID),
Expand Down
14 changes: 10 additions & 4 deletions packages/cosmic-swingset/tools/test-kit.js
Original file line number Diff line number Diff line change
Expand Up @@ -345,22 +345,28 @@ export const makeCosmicSwingsetTestKit = async (
});
};
/**
* @param {string | ((...args: any[]) => void)} fn
* @param {string} [jsonPermits] should deserialize into a BootstrapManifestPermit
* @param {string} fnText must evaluate to a function that will be invoked in
* a core eval compartment with a "powers" argument as attenuated by
* `jsonPermits` (with no attenuation by default).
* @param {string} [jsonPermits] must deserialize into a BootstrapManifestPermit
* @param {InboundQueue} [queue]
*/
const pushCoreEval = (
fn,
fnText,
jsonPermits = 'true',
queue = highPriorityQueue,
) => {
// Fail noisily if fnText does not evaluate to a function.
// This must be refactored if there is ever a need for such input.
const fn = new Compartment().evaluate(fnText);
typeof fn === 'function' || Fail`text must evaluate to a function`;
/** @type {import('@agoric/vats/src/core/lib-boot.js').BootstrapManifestPermit} */
// eslint-disable-next-line no-unused-vars
const permit = JSON.parse(jsonPermits);
/** @type {import('@agoric/cosmic-proto/swingset/swingset.js').CoreEvalSDKType} */
const coreEvalDesc = {
json_permits: jsonPermits,
js_code: String(fn),
js_code: fnText,
};
const action = {
type: QueuedActionType.CORE_EVAL,
Expand Down

0 comments on commit db8108a

Please sign in to comment.