From 21a27f5d54ef43927a3a92d78d95f151612ed278 Mon Sep 17 00:00:00 2001 From: Chris Hibbert Date: Thu, 16 Jun 2022 11:22:42 -0700 Subject: [PATCH 1/2] refactor: move eventLoopIteration to zoe near buildManualTimer some minor drive-by cleanups of the files that were touched. --- .../run-protocol/test/reserve/test-reserve.js | 2 +- packages/run-protocol/test/supports.js | 13 ------------ .../run-protocol/test/test-feeDistributor.js | 21 ++++++++++++------- .../test/vaultFactory/test-liquidator.js | 2 +- .../test/vaultFactory/test-vaultFactory.js | 2 +- packages/zoe/tools/eventLoopIteration.js | 17 +++++++++++++++ 6 files changed, 34 insertions(+), 23 deletions(-) create mode 100644 packages/zoe/tools/eventLoopIteration.js diff --git a/packages/run-protocol/test/reserve/test-reserve.js b/packages/run-protocol/test/reserve/test-reserve.js index ac5f2e33031..5d2bf6cc58f 100644 --- a/packages/run-protocol/test/reserve/test-reserve.js +++ b/packages/run-protocol/test/reserve/test-reserve.js @@ -6,11 +6,11 @@ import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; import { E } from '@endo/eventual-send'; import { makeIssuerKit, AmountMath } from '@agoric/ertp'; import buildManualTimer from '@agoric/zoe/tools/manualTimer.js'; +import { eventLoopIteration } from '@agoric/zoe/tools/eventLoopIteration.js'; import { setupReserveServices } from './setup.js'; import { unsafeMakeBundleCache } from '../bundleTool.js'; import { subscriptionTracker } from '../metrics.js'; -import { eventLoopIteration } from '../supports.js'; const addLiquidPool = async ( runPayment, diff --git a/packages/run-protocol/test/supports.js b/packages/run-protocol/test/supports.js index c7e8b6b16a0..bdaf0b0aaa8 100644 --- a/packages/run-protocol/test/supports.js +++ b/packages/run-protocol/test/supports.js @@ -1,5 +1,4 @@ // @ts-check -/* global setImmediate */ import { AmountMath } from '@agoric/ertp'; import binaryVoteCounterBundle from '@agoric/governance/bundles/bundle-binaryVoteCounter.js'; @@ -34,18 +33,6 @@ export const provideBundle = (t, sourceRoot, bundleName) => { }; harden(provideBundle); -/** - * A workaround for some issues with fake time in tests. - * - * Lines of test code can depend on async promises outside the test - * resolving before they run. Awaiting this function result ensures - * that all promises that can do resolve. - * Note that this doesn't mean all outstanding promises. - */ -export const eventLoopIteration = async () => - new Promise(resolve => setImmediate(resolve)); -harden(eventLoopIteration); - /** * Returns promises for `zoe` and the `feeMintAccess`. * diff --git a/packages/run-protocol/test/test-feeDistributor.js b/packages/run-protocol/test/test-feeDistributor.js index 27a31e1535a..38610c33b26 100644 --- a/packages/run-protocol/test/test-feeDistributor.js +++ b/packages/run-protocol/test/test-feeDistributor.js @@ -4,17 +4,17 @@ import { test } from '@agoric/swingset-vat/tools/prepare-test-env-ava.js'; import { AmountMath } from '@agoric/ertp'; import buildManualTimer from '@agoric/zoe/tools/manualTimer.js'; +import { eventLoopIteration } from '@agoric/zoe/tools/eventLoopIteration.js'; import { setup } from '@agoric/zoe/test/unitTests/setupBasicMints.js'; import { assertPayoutAmount } from '@agoric/zoe/test/zoeTestHelpers.js'; import { E, Far } from '@endo/far'; import { makeFeeDistributor } from '../src/feeDistributor.js'; -import { eventLoopIteration } from './supports.js'; /** * @param {Issuer} feeIssuer */ -function makeFakeFeeDepositFacetKit(feeIssuer) { +const makeFakeFeeDepositFacetKit = feeIssuer => { const depositPayments = []; const feeDepositFacet = { @@ -29,9 +29,9 @@ function makeFakeFeeDepositFacetKit(feeIssuer) { Promise.resolve(eventLoopIteration()).then(_ => depositPayments); return { feeDepositFacet, getPayments }; -} +}; -function makeFakeFeeProducer(makeEmptyPayment = () => {}) { +const makeFakeFeeProducer = (makeEmptyPayment = () => {}) => { const feePayments = []; return Far('feeCollector', { collectFees: () => feePayments.shift() || makeEmptyPayment(), @@ -39,7 +39,7 @@ function makeFakeFeeProducer(makeEmptyPayment = () => {}) { // tools for the fake: pushFees: payment => feePayments.push(payment), }); -} +}; /** * * @param {*} t @@ -49,7 +49,14 @@ function makeFakeFeeProducer(makeEmptyPayment = () => {}) { * @param {Issuer} issuer * @param {Brand} brand */ -async function assertPaymentArray(t, paymentsP, count, values, issuer, brand) { +const assertPaymentArray = async ( + t, + paymentsP, + count, + values, + issuer, + brand, +) => { const payments = await paymentsP; for (let i = 0; i < count; i += 1) { // XXX https://github.com/Agoric/agoric-sdk/issues/5527 @@ -61,7 +68,7 @@ async function assertPaymentArray(t, paymentsP, count, values, issuer, brand) { AmountMath.make(brand, values[i]), ); } -} +}; test('fee distribution', async t => { const { brands, moolaIssuer: issuer, moolaMint: runMint } = setup(); diff --git a/packages/run-protocol/test/vaultFactory/test-liquidator.js b/packages/run-protocol/test/vaultFactory/test-liquidator.js index 6da8a9c6000..426440e334c 100644 --- a/packages/run-protocol/test/vaultFactory/test-liquidator.js +++ b/packages/run-protocol/test/vaultFactory/test-liquidator.js @@ -8,6 +8,7 @@ import { deeplyFulfilled } from '@endo/marshal'; import { makeIssuerKit, AssetKind, AmountMath } from '@agoric/ertp'; import buildManualTimer from '@agoric/zoe/tools/manualTimer.js'; +import { eventLoopIteration } from '@agoric/zoe/tools/eventLoopIteration.js'; import { makeRatioFromAmounts, ceilMultiplyBy, @@ -29,7 +30,6 @@ import { setUpZoeForTest, setupBootstrap, installGovernance, - eventLoopIteration, withAmountUtils, } from '../supports.js'; import { unsafeMakeBundleCache } from '../bundleTool.js'; diff --git a/packages/run-protocol/test/vaultFactory/test-vaultFactory.js b/packages/run-protocol/test/vaultFactory/test-vaultFactory.js index e08b3493bab..4c9073d94c1 100644 --- a/packages/run-protocol/test/vaultFactory/test-vaultFactory.js +++ b/packages/run-protocol/test/vaultFactory/test-vaultFactory.js @@ -8,6 +8,7 @@ import { deeplyFulfilled } from '@endo/marshal'; import { AmountMath, AssetKind, makeIssuerKit } from '@agoric/ertp'; import buildManualTimer from '@agoric/zoe/tools/manualTimer.js'; +import { eventLoopIteration } from '@agoric/zoe/tools/eventLoopIteration.js'; import { ceilMultiplyBy, makeRatio, @@ -38,7 +39,6 @@ import { installGovernance, setupBootstrap, setUpZoeForTest, - eventLoopIteration, withAmountUtils, produceInstallations, } from '../supports.js'; diff --git a/packages/zoe/tools/eventLoopIteration.js b/packages/zoe/tools/eventLoopIteration.js new file mode 100644 index 00000000000..35968df10c3 --- /dev/null +++ b/packages/zoe/tools/eventLoopIteration.js @@ -0,0 +1,17 @@ +// @ts-check +/* global setImmediate */ + +import './types.js'; +import './internal-types.js'; + +/** + * A workaround for some issues with fake time in tests. + * + * Lines of test code can depend on async promises outside the test + * resolving before they run. Awaiting this function result ensures + * that all promises that can do resolve. + * Note that this doesn't mean all outstanding promises. + */ +export const eventLoopIteration = async () => + new Promise(resolve => setImmediate(resolve)); +harden(eventLoopIteration); From c664d1639a29d1de7d1d2e17929bfa46e15bdae1 Mon Sep 17 00:00:00 2001 From: Chris Hibbert Date: Thu, 16 Jun 2022 11:26:14 -0700 Subject: [PATCH 2/2] fix!(manualTimer): add eventLoopIteration() to tickN() in manualTimer --- .../test/vaultFactory/test-vaultFactory.js | 10 +--------- packages/zoe/tools/manualTimer.js | 6 +++++- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/run-protocol/test/vaultFactory/test-vaultFactory.js b/packages/run-protocol/test/vaultFactory/test-vaultFactory.js index 4c9073d94c1..985b27e79eb 100644 --- a/packages/run-protocol/test/vaultFactory/test-vaultFactory.js +++ b/packages/run-protocol/test/vaultFactory/test-vaultFactory.js @@ -2725,15 +2725,7 @@ test('manager notifiers', async t => { totalDebt: { value: DEBT1 }, }); m.addDebt(DEBT1); - const periods = 5n; - // FIXME test result relies on awaiting each tick - // timer.tickN() awaits only the last tick - for (let i = 0; i < periods; i += 1) { - // eslint-disable-next-line no-await-in-loop - await manualTimer.tick(); - } - // wait to let interest charging catch up - await eventLoopIteration(); + await manualTimer.tickN(5); const interestAccrued = (await E(vault).getCurrentDebt()).value - DEBT1; m.addDebt(interestAccrued); t.is(interestAccrued, 10n); diff --git a/packages/zoe/tools/manualTimer.js b/packages/zoe/tools/manualTimer.js index 6745d38b1e6..d8d2dbba20e 100644 --- a/packages/zoe/tools/manualTimer.js +++ b/packages/zoe/tools/manualTimer.js @@ -2,7 +2,6 @@ import { E } from '@endo/eventual-send'; import { makeScalarMapStore } from '@agoric/store'; -import { assert, details as X } from '@agoric/assert'; import { Nat } from '@agoric/nat'; import { Far } from '@endo/marshal'; @@ -10,6 +9,9 @@ import './types.js'; import './internal-types.js'; import { makeNotifierKit } from '@agoric/notifier'; import { makePromiseKit } from '@endo/promise-kit'; +import { eventLoopIteration } from './eventLoopIteration.js'; + +const { details: X } = assert; /** * A fake clock that also logs progress. @@ -102,6 +104,7 @@ export default function buildManualTimer(log, startValue = 0n, timeStep = 1n) { for (let i = 0; i < nTimes - 1; i += 1) { timer.tick(msg); } + await eventLoopIteration(); // suffices that only the last be awaited await timer.tick(msg); }, @@ -189,3 +192,4 @@ export default function buildManualTimer(log, startValue = 0n, timeStep = 1n) { }); return timer; } +harden(buildManualTimer);