Skip to content

Commit

Permalink
test: convert supports to .ts
Browse files Browse the repository at this point in the history
  • Loading branch information
turadg committed Sep 8, 2023
1 parent 080c9e8 commit 081f1d2
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import engineGC from '@agoric/internal/src/lib-nodejs/engine-gc.js';

import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js';
import { makeAgoricNamesRemotesFromFakeStorage } from '@agoric/vats/tools/board-utils.js';
import { makeSwingsetTestKit } from './supports.js';
import { makeSwingsetTestKit } from './supports.ts';
import { makeWalletFactoryDriver } from './drivers.ts';

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/boot/test/bootstrapTests/bench-vaults-stripped.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';

import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js';
import { makeAgoricNamesRemotesFromFakeStorage } from '@agoric/vats/tools/board-utils.js';
import { makeSwingsetTestKit } from './supports.js';
import { makeSwingsetTestKit } from './supports.ts';
import { makeWalletFactoryDriver } from './drivers.ts';

// presently all these tests use one collateral manager
Expand Down
2 changes: 1 addition & 1 deletion packages/boot/test/bootstrapTests/drivers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type { WalletFactoryStartResult } from '@agoric/vats/src/core/startWallet
import type { OfferSpec } from '@agoric/smart-wallet/src/offers.js';
import type { TimerService } from '@agoric/time/src/types.js';
import type { OfferMaker } from '@agoric/smart-wallet/src/types.js';
import type { RunUtils, SwingsetTestKit } from './supports.js';
import type { RunUtils, SwingsetTestKit } from './supports.ts';

export const makeWalletFactoryDriver = async (
runUtils: RunUtils,
Expand Down
2 changes: 1 addition & 1 deletion packages/boot/test/bootstrapTests/liquidation.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
makePriceFeedDriver,
makeWalletFactoryDriver,
} from './drivers.ts';
import { makeSwingsetTestKit } from './supports.js';
import { makeSwingsetTestKit } from './supports.ts';

export const scale6 = x => BigInt(Math.round(x * 1_000_000));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,42 @@
// @ts-check
/* eslint-disable jsdoc/require-param-type, jsdoc/require-param, @jessie.js/safe-await-separator */
/* global process */

import { promises as fsAmbientPromises } from 'fs';
import { resolve as importMetaResolve } from 'import-meta-resolve';
import { basename } from 'path';
import { inspect } from 'util';
import childProcessAmbient from 'child_process';
import childProcessAmbient, { ChildProcess } from 'child_process';

import { Fail } from '@agoric/assert';
import { Fail, NonNullish } from '@agoric/assert';
import { buildSwingset } from '@agoric/cosmic-swingset/src/launch-chain.js';
import { BridgeId, makeTracer, VBankAccount } from '@agoric/internal';
import { unmarshalFromVstorage } from '@agoric/internal/src/marshal.js';
import { makeFakeStorageKit } from '@agoric/internal/src/storage-test-utils.js';
import {
FakeStorageKit,
makeFakeStorageKit,
} from '@agoric/internal/src/storage-test-utils.js';
import { initSwingStore } from '@agoric/swing-store';
import { kunser } from '@agoric/swingset-liveslots/test/kmarshal.js';
import { loadSwingsetConfigFile } from '@agoric/swingset-vat';
import { E } from '@endo/eventual-send';
import { makeQueue } from '@endo/stream';
import { TimeMath } from '@agoric/time';
import { TimeMath, Timestamp } from '@agoric/time';
import {
boardSlottingMarshaller,
slotToBoardRemote,
} from '@agoric/vats/tools/board-utils.js';

// to retain for ESlint, used by typedef
E;
import type { ExecutionContext } from 'ava';
import type { makeBootstrap } from '@agoric/vats/src/core/lib-boot';
import type { SwingsetController } from '@agoric/swingset-vat/src/controller/controller.js';

const sink = () => {};

const trace = makeTracer('BSTSupport', false);

/**
* @typedef {Awaited<
* ReturnType<import('@agoric/vats/src/core/lib-boot').makeBootstrap>
* >} BootstrapRootObject
*/
type BootstrapRootObject = Awaited<ReturnType<typeof makeBootstrap>>;

/** @type {{ [P in keyof BootstrapRootObject]: P }} */
export const bootstrapMethods = {
export const bootstrapMethods: { [P in keyof BootstrapRootObject]: P } = {
bootstrap: 'bootstrap',
consumeItem: 'consumeItem',
produceItem: 'produceItem',
Expand All @@ -49,50 +48,41 @@ export const bootstrapMethods = {
snapshotStore: 'snapshotStore',
};

/**
* @template {PropertyKey} K
* @template V
* @param {K[]} keys
* @param {(key: K, i: number) => V} valueMaker
*/
const keysToObject = (keys, valueMaker) => {
const keysToObject = <K extends PropertyKey, V>(
keys: K[],
valueMaker: (key: K, i: number) => V,
) => {
return Object.fromEntries(keys.map((key, i) => [key, valueMaker(key, i)]));
};

/**
* AVA's default t.deepEqual() is nearly unreadable for sorted arrays of
* strings.
*
* @param {{
* deepEqual: (a: unknown, b: unknown, message?: string) => void;
* }} t
* @param {PropertyKey[]} a
* @param {PropertyKey[]} b
* @param {string} [message]
*/
export const keyArrayEqual = (t, a, b, message) => {
export const keyArrayEqual = (
t: ExecutionContext,
a: PropertyKey[],
b: PropertyKey[],
message: string,
) => {
const aobj = keysToObject(a, () => 1);
const bobj = keysToObject(b, () => 1);
return t.deepEqual(aobj, bobj, message);
};

/**
* @param {import('@agoric/swingset-vat/src/controller/controller').SwingsetController} controller
* @param {(..._: any[]) => any} log
*/
export const makeRunUtils = (controller, log = (..._) => {}) => {
export const makeRunUtils = (
controller: SwingsetController,
log = (..._) => {},
) => {
let cranksRun = 0;

const mutex = makeQueue();

mutex.put(controller.run());

/**
* @template {() => any} T
* @param {T} thunk
* @returns {Promise<ReturnType<T>>}
*/
const runThunk = async thunk => {
const runThunk = async <T extends () => any>(
thunk: T,
): Promise<ReturnType<T>> => {
try {
// this promise for the last lock may fail
await mutex.get();
Expand All @@ -111,7 +101,7 @@ export const makeRunUtils = (controller, log = (..._) => {}) => {
return result;
};

const runMethod = async (method, args = []) => {
const runMethod = async (method: string, args: object[] = []) => {
log('runMethod', method, args, 'at', cranksRun);
assert(Array.isArray(args));

Expand Down Expand Up @@ -151,6 +141,7 @@ export const makeRunUtils = (controller, log = (..._) => {}) => {
new Proxy(harden({}), {
get: (_t, methodName, _rx) =>
harden((...args) => {
assert.string(methodName);
if (name === 'meta') {
return runMethod(methodName, args);
}
Expand All @@ -159,9 +150,9 @@ export const makeRunUtils = (controller, log = (..._) => {}) => {
});
EV.rawBoot = new Proxy(harden({}), {
get: (_t, methodName, _rx) =>
// @ts-expect-error FIXME runMethod takes string but proxy allows symbol
harden((...args) => runMethod(methodName, args)),
});
// @ts-expect-error xxx
EV.sendOnly = presence =>
new Proxy(
{},
Expand All @@ -174,7 +165,6 @@ export const makeRunUtils = (controller, log = (..._) => {}) => {
]),
},
);
// @ts-expect-error xxx
EV.get = presence =>
new Proxy(harden({}), {
get: (_t, pathElement, _rx) =>
Expand All @@ -183,7 +173,7 @@ export const makeRunUtils = (controller, log = (..._) => {}) => {

return harden({ runThunk, EV });
};
/** @typedef {ReturnType<typeof makeRunUtils>} RunUtils */
export type RunUtils = ReturnType<typeof makeRunUtils>;

export const getNodeTestVaultsConfig = async (
bundleDir = 'bundles',
Expand All @@ -192,10 +182,9 @@ export const getNodeTestVaultsConfig = async (
const fullPath = await importMetaResolve(specifier, import.meta.url).then(
u => new URL(u).pathname,
);
const config = /** @type {SwingSetConfig & { coreProposals?: any[] }} */ (
await loadSwingsetConfigFile(fullPath)
const config: SwingSetConfig & { coreProposals?: any[] } = NonNullish(
await loadSwingsetConfigFile(fullPath),
);
assert(config);

// speed up (e.g. 80s vs 133s with xs-worker in production config)
config.defaultManagerType = 'local';
Expand All @@ -219,12 +208,12 @@ export const getNodeTestVaultsConfig = async (
return testConfigPath;
};

/**
* @param {object} powers
* @param {Pick<typeof import('node:child_process'), 'execFileSync'>} powers.childProcess
* @param {typeof import('node:fs/promises')} powers.fs
*/
export const makeProposalExtractor = ({ childProcess, fs }) => {
interface Powers {
childProcess: Pick<typeof import('node:child_process'), 'execFileSync'>;
fs: typeof import('node:fs/promises');
}

export const makeProposalExtractor = ({ childProcess, fs }: Powers) => {
const getPkgPath = (pkg, fileName = '') =>
new URL(`../../../${pkg}/${fileName}`, import.meta.url).pathname;

Expand All @@ -241,8 +230,7 @@ export const makeProposalExtractor = ({ childProcess, fs }) => {
harden(JSON.parse(await fs.readFile(filePath, 'utf8')));

// XXX parses the output to find the files but could write them to a path that can be traversed
/** @param {string} txt */
const parseProposalParts = txt => {
const parseProposalParts = (txt: string) => {
const evals = [
...txt.matchAll(/swingset-core-eval (?<permit>\S+) (?<script>\S+)/g),
].map(m => {
Expand All @@ -261,16 +249,14 @@ export const makeProposalExtractor = ({ childProcess, fs }) => {
return { evals, bundles };
};

/**
* @param {object} options
* @param {string} options.package
* @param {string} options.packageScriptName
* @param {Record<string, string>} [options.env]
*/
const buildAndExtract = async ({
package: packageName,
packageScriptName,
env = {},
}: {
package: string;
packageScriptName: string;
env: Record<string, string>;
}) => {
const scriptEnv = Object.assign(Object.create(process.env), env);
// XXX use '@agoric/inter-protocol'?
Expand Down Expand Up @@ -301,7 +287,7 @@ export const makeProposalExtractor = ({ childProcess, fs }) => {
const bundlesP = Promise.all(
built.bundles.map(
async bundleFile =>
/** @type {Promise<EndoZipBase64Bundle>} */ (loadJSON(bundleFile)),
loadJSON(bundleFile) as Promise<EndoZipBase64Bundle>,
),
);
return Promise.all([evalsP, bundlesP]).then(([evals, bundles]) => ({
Expand All @@ -324,16 +310,19 @@ harden(makeProposalExtractor);
* a timeout error). Use t.after.always(shutdown), because the normal t.after()
* hooks are not run if a test fails.
*
* @param {import('ava').ExecutionContext} t
* @param {string} bundleDir directory to write bundles and config to
* @param {object} [options]
* @param {string} [options.configSpecifier] bootstrap config specifier
* @param {import('@agoric/internal/src/storage-test-utils.js').FakeStorageKit} [options.storage]
* @param t
* @param bundleDir directory to write bundles and config to
* @param [options]
* @param [options.configSpecifier] bootstrap config specifier
* @param [options.storage]
*/
export const makeSwingsetTestKit = async (
t,
bundleDir = 'bundles',
{ configSpecifier, storage = makeFakeStorageKit('bootstrapTests') } = {},
t: ExecutionContext,
bundleDir: string = 'bundles',
{
configSpecifier,
storage = makeFakeStorageKit('bootstrapTests'),
}: { configSpecifier?: string; storage?: FakeStorageKit } = {},
) => {
console.time('makeSwingsetTestKit');
const configPath = await getNodeTestVaultsConfig(bundleDir, configSpecifier);
Expand All @@ -352,11 +341,8 @@ export const makeSwingsetTestKit = async (
/**
* Mock the bridge outbound handler. The real one is implemented in Golang so
* changes there will sometimes require changes here.
*
* @param {string} bridgeId
* @param {any} obj
*/
const bridgeOutbound = (bridgeId, obj) => {
const bridgeOutbound = (bridgeId: string, obj: any) => {
switch (bridgeId) {
case BridgeId.BANK: {
trace(
Expand Down Expand Up @@ -443,17 +429,15 @@ export const makeSwingsetTestKit = async (
console.timeEnd('makeSwingsetTestKit');

let currentTime = 0n;
/** @param {Timestamp} targetTime */
const jumpTimeTo = targetTime => {
const jumpTimeTo = (targetTime: Timestamp) => {
targetTime = TimeMath.absValue(targetTime);
targetTime >= currentTime ||
Fail`cannot reverse time :-( (${targetTime} < ${currentTime})`;
currentTime = targetTime;
trace('jumpTimeTo', currentTime);
return runUtils.runThunk(() => timer.poll(currentTime));
};
/** @param {Timestamp} targetTime */
const advanceTimeTo = async targetTime => {
const advanceTimeTo = async (targetTime: Timestamp) => {
targetTime = TimeMath.absValue(targetTime);
targetTime >= currentTime ||
Fail`cannot reverse time :-( (${targetTime} < ${currentTime})`;
Expand All @@ -463,11 +447,10 @@ export const makeSwingsetTestKit = async (
await runUtils.runThunk(() => timer.poll(currentTime));
}
};
/**
* @param {number} n
* @param {'seconds' | 'minutes' | 'hours' | 'days'} unit
*/
const advanceTimeBy = (n, unit) => {
const advanceTimeBy = (
n: number,
unit: 'seconds' | 'minutes' | 'hours' | 'days',
) => {
const multiplier = {
seconds: 1,
minutes: 60,
Expand Down Expand Up @@ -496,4 +479,4 @@ export const makeSwingsetTestKit = async (
timer,
};
};
/** @typedef {Awaited<ReturnType<import('./supports.js').makeSwingsetTestKit>>} SwingsetTestKit */
type SwingsetTestKit = Awaited<ReturnType<typeof makeSwingsetTestKit>>;
3 changes: 1 addition & 2 deletions packages/boot/test/bootstrapTests/test-demo-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js';

import { PowerFlags } from '@agoric/vats/src/walletFlags.js';

import { makeSwingsetTestKit, keyArrayEqual } from './supports.js';

import type { TestFn } from 'ava';
import { makeSwingsetTestKit, keyArrayEqual } from './supports.ts';

const { keys } = Object;

Expand Down
2 changes: 1 addition & 1 deletion packages/boot/test/bootstrapTests/test-vats-restart.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { promises as fsAmbientPromises } from 'fs';
import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
import { makeAgoricNamesRemotesFromFakeStorage } from '@agoric/vats/tools/board-utils.js';
import { makeWalletFactoryDriver } from './drivers.ts';
import { makeProposalExtractor, makeSwingsetTestKit } from './supports.js';
import { makeProposalExtractor, makeSwingsetTestKit } from './supports.ts';

const { Fail } = assert;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
slotToBoardRemote,
} from '@agoric/vats/tools/board-utils.js';
import { makeWalletFactoryDriver } from './drivers.ts';
import { makeSwingsetTestKit } from './supports.js';
import { makeSwingsetTestKit } from './supports.ts';

/**
* @type {import('ava').TestFn<
Expand Down
2 changes: 1 addition & 1 deletion packages/boot/test/bootstrapTests/test-vaults-upgrade.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Offers } from '@agoric/inter-protocol/src/clientSupport.js';
import { Far, makeMarshal } from '@endo/marshal';
import { SECONDS_PER_YEAR } from '@agoric/inter-protocol/src/interest.js';
import { makeAgoricNamesRemotesFromFakeStorage } from '@agoric/vats/tools/board-utils.js';
import { makeSwingsetTestKit } from './supports.js';
import { makeSwingsetTestKit } from './supports.ts';
import { makeWalletFactoryDriver } from './drivers.ts';

// presently all these tests use one collateral manager
Expand Down
Loading

0 comments on commit 081f1d2

Please sign in to comment.