Skip to content

Commit

Permalink
test: restart basic-flow's orchestration flow
Browse files Browse the repository at this point in the history
  • Loading branch information
turadg committed Jul 26, 2024
1 parent e67d771 commit 3043994
Show file tree
Hide file tree
Showing 2 changed files with 198 additions and 0 deletions.
98 changes: 98 additions & 0 deletions packages/boot/test/orchestration/restart-contracts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,101 @@ test('stakeAtom', async t => {
t.is(await flushInboundQueue(), 1);
t.true(hasResult(wd.getLatestUpdateRecord()));
});

// Tests restart of an orchestration() flow while an IBC response is pending.
// TODO make this a macro so we test at arbitrary depth
test.serial('basicFlows', async t => {
const {
walletFactoryDriver,
buildProposal,
evalProposal,
bridgeUtils: { getInboundQueueLength, flushInboundQueue },
} = t.context;

t.log('start basicFlows');
await evalProposal(
buildProposal('@agoric/builders/scripts/orchestration/init-basic-flows.js'),
);

t.log('making offer');
const wallet = await walletFactoryDriver.provideSmartWallet('agoric1test');
const id1 = 'make-orch-account';
// send because it won't resolve
await wallet.sendOffer({
id: id1,
invitationSpec: {
source: 'agoricContract',
instancePath: ['basicFlows'],
callPipe: [['makeOrchAccountInvitation']],
},
proposal: {},
offerArgs: {
chainName: 'cosmoshub',
},
});
// no errors and no result yet
t.like(wallet.getLatestUpdateRecord(), {
status: {
id: id1,
error: undefined,
numWantsSatisfied: 1,
payouts: {},
result: undefined, // no property
},
});
t.is(getInboundQueueLength(), 1);

const id2 = 'makePortfolio';
await wallet.sendOffer({
id: id2,
invitationSpec: {
source: 'agoricContract',
instancePath: ['basicFlows'],
callPipe: [['makePortfolioAccountInvitation']],
},
proposal: {},
offerArgs: {
chainNames: ['agoric', 'cosmoshub'],
},
});
// no errors and no result yet
t.like(wallet.getLatestUpdateRecord(), {
status: {
id: id2,
error: undefined,
numWantsSatisfied: 1,
payouts: {},
result: undefined, // no property
},
});
t.is(getInboundQueueLength(), 2);

t.log('restart basicFlows');
await evalProposal(
buildProposal('@agoric/builders/scripts/testing/restart-basic-flows.js'),
);

t.log('flush and verify results');
const beforeFlush = wallet.getLatestUpdateRecord();
t.like(beforeFlush, {
status: {
result: undefined,
},
});
t.is(await flushInboundQueue(1), 1);
t.like(wallet.getLatestUpdateRecord(), {
status: {
id: id1,
error: undefined,
result: 'UNPUBLISHED',
},
});
t.is(await flushInboundQueue(1), 1);
t.like(wallet.getLatestUpdateRecord(), {
status: {
id: id2,
error: undefined,
result: 'UNPUBLISHED',
},
});
});
100 changes: 100 additions & 0 deletions packages/builders/scripts/testing/restart-basic-flows.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* @file This is for use in tests.
* Unlike most builder scripts, this one includes the proposal exports as well.
*/
import {
deeplyFulfilledObject,
makeTracer,
NonNullish,
} from '@agoric/internal';
import { E } from '@endo/far';

/// <reference types="@agoric/vats/src/core/types-ambient"/>

const trace = makeTracer('RestartBasicFlows', true);

/**
* @import {start as StartFn} from '@agoric/orchestration/src/examples/basic-flows.contract.js';
*/

/**
* @param {BootstrapPowers} powers
*/
export const restartBasicFlows = async ({
consume: {
agoricNames,
board,
chainStorage,
chainTimerService,
cosmosInterchainService,
localchain,

contractKits,
},
instance: instances,
}) => {
trace(restartBasicFlows.name);

// @ts-expect-error unknown instance
const instance = await instances.consume.basicFlows;
trace('instance', instance);
/** @type {StartedInstanceKit<StartFn>} */
const kit = /** @type {any} */ (await E(contractKits).get(instance));

const marshaller = await E(board).getReadonlyMarshaller();

const privateArgs = await deeplyFulfilledObject(
harden({
agoricNames,
localchain,
marshaller,
orchestrationService: cosmosInterchainService,
storageNode: E(NonNullish(await chainStorage)).makeChildNode(
'basicFlows',
),
timerService: chainTimerService,
}),
);

await E(kit.adminFacet).restartContract(privateArgs);
trace('done');
};
harden(restartBasicFlows);

export const getManifest = () => {
return {
manifest: {
[restartBasicFlows.name]: {
consume: {
agoricNames: true,
board: true,
chainStorage: true,
chainTimerService: true,
cosmosInterchainService: true,
localchain: true,

contractKits: true,
},
instance: {
consume: { basicFlows: true },
},
},
},
};
};

/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */
export const defaultProposalBuilder = async () =>
harden({
// Somewhat unorthodox, source the exports from this builder module
sourceSpec: '@agoric/builders/scripts/testing/restart-basic-flows.js',
getManifestCall: [getManifest.name],
});

export default async (homeP, endowments) => {
// import dynamically so the module can work in CoreEval environment
const dspModule = await import('@agoric/deploy-script-support');
const { makeHelpers } = dspModule;
const { writeCoreEval } = await makeHelpers(homeP, endowments);
await writeCoreEval(restartBasicFlows.name, defaultProposalBuilder);
};

0 comments on commit 3043994

Please sign in to comment.