From 65d8aef6c2c0a272f4602cf02489e747bc5e1e7f Mon Sep 17 00:00:00 2001 From: Chris Hibbert Date: Fri, 10 Nov 2023 15:39:44 -0800 Subject: [PATCH] test: update tests to understand that executeOffer doesn't throw --- packages/agoric-cli/test/test-inter-cli.js | 4 +- .../bootstrapTests/test-vaults-integration.ts | 50 +++++++++---------- .../test-walletSurvivesZoeRestart.ts | 4 -- packages/smart-wallet/src/offerWatcher.js | 31 ++++++------ packages/smart-wallet/src/smartWallet.js | 12 +++-- 5 files changed, 52 insertions(+), 49 deletions(-) diff --git a/packages/agoric-cli/test/test-inter-cli.js b/packages/agoric-cli/test/test-inter-cli.js index 69bb924cd0c3..19a0b2edffba 100644 --- a/packages/agoric-cli/test/test-inter-cli.js +++ b/packages/agoric-cli/test/test-inter-cli.js @@ -188,7 +188,7 @@ const makeProcess = (t, keyring, out) => { }; /** - * @type {import('@agoric/smart-wallet/src/smartWallet.js').OfferStatus & + * @type {import('@agoric/smart-wallet/src/offerWatcher.js').OfferStatus & * { offerArgs: import('@agoric/inter-protocol/src/auction/auctionBook.js').OfferSpec}} */ const offerStatus2 = harden({ @@ -253,7 +253,7 @@ test('amount parsing', t => { test.todo('want as max collateral wanted'); /** - * @type {import('@agoric/smart-wallet/src/smartWallet.js').OfferStatus & + * @type {import('@agoric/smart-wallet/src/offerWatcher.js').OfferStatus & * { offerArgs: import('@agoric/inter-protocol/src/auction/auctionBook.js').OfferSpec}} */ const offerStatus1 = harden({ diff --git a/packages/boot/test/bootstrapTests/test-vaults-integration.ts b/packages/boot/test/bootstrapTests/test-vaults-integration.ts index 53df2ad119f2..c6eca04e0578 100644 --- a/packages/boot/test/bootstrapTests/test-vaults-integration.ts +++ b/packages/boot/test/bootstrapTests/test-vaults-integration.ts @@ -7,12 +7,10 @@ import { SECONDS_PER_DAY } from '@agoric/inter-protocol/src/proposals/econ-behav import { unmarshalFromVstorage } from '@agoric/internal/src/marshal.js'; import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js'; import { makeMarshal } from '@endo/marshal'; -import { - makeAgoricNamesRemotesFromFakeStorage, - slotToBoardRemote, -} from '@agoric/vats/tools/board-utils.js'; +import { makeAgoricNamesRemotesFromFakeStorage, slotToBoardRemote } from '@agoric/vats/tools/board-utils.js'; import type { TestFn } from 'ava'; import { ParamChangesOfferArgs } from '@agoric/inter-protocol/src/econCommitteeCharter.js'; + import { makeWalletFactoryDriver } from './drivers.ts'; import { makeSwingsetTestKit } from './supports.ts'; @@ -136,6 +134,8 @@ test('adjust balances', async t => { }); }); +// This test isn't marked .serial, but it depends on previous tests. + test('close vault', async t => { const { walletFactoryDriver } = t.context; @@ -151,7 +151,8 @@ test('close vault', async t => { }); t.like(wd.getLatestUpdateRecord(), { updated: 'offerStatus', - status: { id: 'open-vault', numWantsSatisfied: 1 }, + status: { id: 'open-vault', result: 'UNPUBLISHED', numWantsSatisfied: 1 }, + error: undefined, }); t.log('try giving more than is available in the purse/vbank'); await t.throwsAsync( @@ -171,20 +172,18 @@ test('close vault', async t => { const message = 'Offer {"brand":"[Alleged: IST brand]","value":"[1n]"} is not sufficient to pay off debt {"brand":"[Alleged: IST brand]","value":"[5025000n]"}'; - await t.throwsAsync( - wd.executeOfferMaker( - Offers.vaults.CloseVault, - { - offerId: 'close-insufficient', - collateralBrandKey, - giveMinted: 0.000_001, - }, - 'open-vault', - ), + + // does not throw, because it's in the result, but it will show up in errors + await wd.executeOfferMaker( + Offers.vaults.CloseVault, { - message, + offerId: 'close-insufficient', + collateralBrandKey, + giveMinted: 0.000_001, }, + 'open-vault', ); + t.like(wd.getLatestUpdateRecord(), { updated: 'offerStatus', status: { @@ -204,10 +203,13 @@ test('close vault', async t => { }, 'open-vault', ); + t.like(wd.getLatestUpdateRecord(), { updated: 'offerStatus', status: { id: 'close-well', + error: undefined, + numWantsSatisfied: 1, result: 'your vault is closed, thank you for your business', // funds are returned payouts: likePayouts(giveCollateral, 0), @@ -226,15 +228,13 @@ test('open vault with insufficient funds gives helpful error', async t => { const wantMinted = giveCollateral * 100; const message = 'Proposed debt {"brand":"[Alleged: IST brand]","value":"[904500000n]"} exceeds max {"brand":"[Alleged: IST brand]","value":"[63462857n]"} for {"brand":"[Alleged: ATOM brand]","value":"[9000000n]"} collateral'; - await t.throwsAsync( - wd.executeOfferMaker(Offers.vaults.OpenVault, { - offerId: 'open-vault', - collateralBrandKey, - giveCollateral, - wantMinted, - }), - { message }, - ); + + await wd.executeOfferMaker(Offers.vaults.OpenVault, { + offerId: 'open-vault', + collateralBrandKey, + giveCollateral, + wantMinted, + }); t.like(wd.getLatestUpdateRecord(), { updated: 'offerStatus', diff --git a/packages/boot/test/bootstrapTests/test-walletSurvivesZoeRestart.ts b/packages/boot/test/bootstrapTests/test-walletSurvivesZoeRestart.ts index 0fb5604077a1..e62be0f8589d 100644 --- a/packages/boot/test/bootstrapTests/test-walletSurvivesZoeRestart.ts +++ b/packages/boot/test/bootstrapTests/test-walletSurvivesZoeRestart.ts @@ -95,7 +95,6 @@ const checkFlow = async ( await EV(coreEvalBridgeHandler).fromBridge(bridgeMessage); }; - const metricsPath = `published.vaultFactory.managers.manager${managerIndex}.metrics`; await setupVaults(collateralBrandKey, managerIndex, setup); // restart Zoe @@ -107,9 +106,6 @@ const checkFlow = async ( }; await buildAndExecuteProposal(zoeUpgradeSpec); - // const zoe = await EV.vat('bootstrap').consumeItem('zoe'); - // const invitationIssuer = await EV(zoe).getInvitationIssuer(); - // const invitationBrand = await EV(invitationIssuer).getBrand() t.like(await buyer.getLatestUpdateRecord(), { currentAmount: { // brand from EV() doesn't compare correctly diff --git a/packages/smart-wallet/src/offerWatcher.js b/packages/smart-wallet/src/offerWatcher.js index 4276a1d1994e..9580e8ce0a07 100644 --- a/packages/smart-wallet/src/offerWatcher.js +++ b/packages/smart-wallet/src/offerWatcher.js @@ -56,7 +56,7 @@ const offerWatcherGuard = harden({ .optional(M.record()) .returns(), publishResult: M.call(M.any()).returns(), - exitOpenSeats: M.call(M.any()).returns(), + exitOpenSeat: M.call(M.any()).returns(), }), paymentWatcher: M.interface('paymentWatcher', { onFulfilled: M.call(PaymentPKeywordRecordShape, SeatShape).returns( @@ -146,7 +146,7 @@ export const makeOfferWatcherMaker = baggage => { } }, - exitOpenSeats(reason) { + exitOpenSeat(reason) { const { state } = this; void E.when(E(state.seatRef).hasExited(), hasExited => { if (!hasExited) { @@ -171,15 +171,16 @@ export const makeOfferWatcherMaker = baggage => { const amounts = await deeplyFulfilledObject(amountPKeywordRecord); facets.helper.updateStatus({ payouts: amounts }); }, - onRejected(reason, seat) { + onRejected(err, seat) { const { facets } = this; - if (isUpgradeDisconnection(reason)) { - console.log(`resetting payments watcher after upgrade`, reason); + if (isUpgradeDisconnection(err)) { + console.log(`resetting payments watcher after upgrade`, err); // eslint-disable-next-line no-use-before-define watchForPayout(seat); } else { - facets.helper.exitOpenSeats(reason); + facets.helper.updateStatus({ error: err.toString() }); + facets.helper.exitOpenSeat(err); } }, }, @@ -189,13 +190,14 @@ export const makeOfferWatcherMaker = baggage => { const { facets } = this; facets.helper.publishResult(result); }, - onRejected(reason, seat) { + onRejected(err, seat) { const { facets } = this; - if (isUpgradeDisconnection(reason)) { - console.log(`resetting offerResults watcher after upgrade`, reason); + if (isUpgradeDisconnection(err)) { + console.log(`resetting offerResults watcher after upgrade`, err); watchForOfferResult(facets, seat); } else { - facets.helper.exitOpenSeats(reason); + facets.helper.updateStatus({ error: err.toString() }); + facets.helper.exitOpenSeat(err); } }, }, @@ -206,13 +208,14 @@ export const makeOfferWatcherMaker = baggage => { facets.helper.updateStatus({ numWantsSatisfied: numSatisfied }); }, - onRejected(reason, seat) { + onRejected(err, seat) { const { facets } = this; - if (isUpgradeDisconnection(reason)) { - console.log(`resetting numWants watcher after upgrade`, reason); + if (isUpgradeDisconnection(err)) { + console.log(`resetting numWants watcher after upgrade`, err); watchForNumWants(facets, seat); } else { - facets.helper.exitOpenSeats(reason); + facets.helper.updateStatus({ error: err.toString() }); + facets.helper.exitOpenSeat(err); } }, }, diff --git a/packages/smart-wallet/src/smartWallet.js b/packages/smart-wallet/src/smartWallet.js index 8f7320a40b53..58a58afaf4c6 100644 --- a/packages/smart-wallet/src/smartWallet.js +++ b/packages/smart-wallet/src/smartWallet.js @@ -597,8 +597,7 @@ export const prepareSmartWallet = (baggage, shared) => { status: offerStatus, }); - const isSeatExited = 'numWantsSatisfied' in offerStatus; - if (isSeatExited) { + if ('numWantsSatisfied' in offerStatus) { if (state.liveOfferSeats.has(offerStatus.id)) { state.liveOfferSeats.delete(offerStatus.id); } @@ -609,6 +608,8 @@ export const prepareSmartWallet = (baggage, shared) => { if (state.liveOffers.has(offerStatus.id)) { state.liveOffers.delete(offerStatus.id); + // This might get skipped in subsequent passes, since we .delete() + // the first time through facets.helper.publishCurrentState(); } } @@ -833,10 +834,12 @@ export const prepareSmartWallet = (baggage, shared) => { seatRef, ); - watchOfferOutcomes(watcher, seatRef); state.liveOffers.init(offerSpec.id, offerSpec); - facets.helper.publishCurrentState(); state.liveOfferSeats.init(offerSpec.id, seatRef); + + watchOfferOutcomes(watcher, seatRef); + + facets.helper.publishCurrentState(); } catch (err) { console.error('OFFER ERROR:', err); // Notify the user @@ -867,6 +870,7 @@ export const prepareSmartWallet = (baggage, shared) => { } }); } + throw err; } },