Skip to content

Commit

Permalink
WIP: test(daemon): Add cancellation context tests
Browse files Browse the repository at this point in the history
Deletes some unused args and fixes some type issues discovered
in the course of work.
  • Loading branch information
rekmarks committed Feb 15, 2024
1 parent e17cecc commit 58dbd3a
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 11 deletions.
2 changes: 1 addition & 1 deletion packages/daemon/src/daemon-node-powers.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ export const makeSocketPowers = ({ net }) => {
);

/** @type {import('./types.js').SocketPowers['connectPort']} */
const connectPort = ({ port, host, cancelled }) =>
const connectPort = ({ port, host }) =>
new Promise((resolve, reject) => {
const conn = net.connect(port, host, err => {
if (err) {
Expand Down
8 changes: 5 additions & 3 deletions packages/daemon/src/daemon.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ const makeInspector = (type, number, record) =>
list: () => Object.keys(record),
});

/**
* @param {import('./types.js').Context} context - The context to make far.
* @returns {import('./types.js').FarContext} The far context.
*/
const makeFarContext = context =>
Far('Context', {
cancel: context.cancel,
Expand All @@ -65,15 +69,14 @@ const makeFarContext = context =>
* @param {import('./types.js').DaemonicPowers} powers
* @param {Promise<number>} webletPortP
* @param {object} args
* @param {Promise<never>} args.cancelled
* @param {(error: Error) => void} args.cancel
* @param {number} args.gracePeriodMs
* @param {Promise<never>} args.gracePeriodElapsed
*/
const makeEndoBootstrap = async (
powers,
webletPortP,
{ cancelled, cancel, gracePeriodMs, gracePeriodElapsed },
{ cancel, gracePeriodMs, gracePeriodElapsed },
) => {
const {
crypto: cryptoPowers,
Expand Down Expand Up @@ -862,7 +865,6 @@ export const makeDaemon = async (powers, daemonLabel, cancel, cancelled) => {
);

const endoBootstrap = makeEndoBootstrap(powers, assignedWebletPortP, {
cancelled,
cancel,
gracePeriodMs,
gracePeriodElapsed,
Expand Down
1 change: 1 addition & 0 deletions packages/daemon/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ export interface FarContext {
cancel: (reason: string) => Promise<never>;
whenCancelled: () => Promise<never>;
whenDisposed: () => Promise<void>;
addDisposalHook: Context['onCancel'];
}

export interface InternalExternal<External = unknown, Internal = unknown> {
Expand Down
12 changes: 12 additions & 0 deletions packages/daemon/test/context-consumer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { E, Far } from '@endo/far';

export const make = async (_powers, context) => {
return Far('Context consumer', {
async awaitCancellation() {
await E(context).whenCancelled();
// await E(context).whenDisposed();
// await new Promise(r => E(context).addDisposalHook(r));
return 'cancelled';
},
});
};
50 changes: 43 additions & 7 deletions packages/daemon/test/test-endo.js
Original file line number Diff line number Diff line change
Expand Up @@ -566,11 +566,11 @@ test('guest facet receives a message for host', async t => {
await stop(locator);
});

test('direct termination', async t => {
test('direct cancellation', async t => {
const { promise: cancelled, reject: cancel } = makePromiseKit();
t.teardown(() => cancel(Error('teardown')));

const locator = makeLocator('tmp', 'termination-direct');
const locator = makeLocator('tmp', 'cancellation-direct');

await start(locator);
t.teardown(() => stop(locator));
Expand Down Expand Up @@ -643,15 +643,13 @@ test('direct termination', async t => {
['counter'],
),
);

t.pass();
});

test('indirect termination', async t => {
test('indirect cancellation', async t => {
const { promise: cancelled, reject: cancel } = makePromiseKit();
t.teardown(() => cancel(Error('teardown')));

const locator = makeLocator('tmp', 'termination-indirect');
const locator = makeLocator('tmp', 'cancellation-indirect');

await start(locator);
t.teardown(() => stop(locator));
Expand Down Expand Up @@ -731,7 +729,7 @@ test('cancel because of requested capability', async t => {
const { promise: cancelled, reject: cancel } = makePromiseKit();
t.teardown(() => cancel(Error('teardown')));

const locator = makeLocator('tmp', 'termination-via-request');
const locator = makeLocator('tmp', 'cancellation-via-request');

await start(locator);
t.teardown(() => stop(locator));
Expand Down Expand Up @@ -815,6 +813,44 @@ test('cancel because of requested capability', async t => {
);
});

test('unconfined service can respond to cancellation', async t => {
const { promise: cancelled, reject: cancel } = makePromiseKit();
t.teardown(() => cancel(Error('teardown')));

const locator = makeLocator('tmp', 'cancellation-unconfined-response');

await start(locator);
t.teardown(() => stop(locator));

const { getBootstrap } = await makeEndoClient(
'client',
locator.sockPath,
cancelled,
);
const bootstrap = getBootstrap();
const host = E(bootstrap).host();
await E(host).provideWorker('worker');

const capletPath = path.join(dirname, 'test', 'context-consumer.js');
const capletLocation = url.pathToFileURL(capletPath).href;
await E(host).makeUnconfined(
'worker',
capletLocation,
'NONE',
'context-consumer',
);

const result = E(host).evaluate(
'worker',
'E(caplet).awaitCancellation()',
['caplet'],
['context-consumer'],
);
// await E(host).cancel('context-consumer');
await E(host).cancel('worker');
t.is(await result, 'cancelled');
});

test('make a host', async t => {
const { promise: cancelled, reject: cancel } = makePromiseKit();
t.teardown(() => cancel(Error('teardown')));
Expand Down

0 comments on commit 58dbd3a

Please sign in to comment.