Skip to content

Commit

Permalink
test: e2e test of kitchen-sink.contract.js
Browse files Browse the repository at this point in the history
- tests a contract that uses orchestrate/async-flow in the multichain-testing environment
  • Loading branch information
0xpatrickdev committed Jul 10, 2024
1 parent 97e03cc commit 78ec9cb
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 1 deletion.
150 changes: 150 additions & 0 deletions multichain-testing/test/kitchen-sink.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import anyTest from '@endo/ses-ava/prepare-endo.js';
import type { TestFn } from 'ava';
import { commonSetup, SetupContextWithWallets } from './support.js';
import { makeDoOffer } from '../tools/e2e-tools.js';

const test = anyTest as TestFn<SetupContextWithWallets>;

const accounts = ['user1'];

const contractName = 'kitchenSink';
const contractBuilder =
'../packages/builders/scripts/orchestration/init-kitchen-sink.js';

test.before(async t => {
const { deleteTestKeys, setupTestKeys, ...rest } = await commonSetup(t);
// XXX not necessary for CI, but helpful for unexpected failures in
// active development (test.after cleanup doesn't run).
deleteTestKeys(accounts).catch();
const wallets = await setupTestKeys(accounts);
t.context = { ...rest, wallets, deleteTestKeys };

t.log('bundle and install contract', contractName);
await t.context.deployBuilder(contractBuilder);
const vstorageClient = t.context.makeQueryTool();
await t.context.retryUntilCondition(
() => vstorageClient.queryData(`published.agoricNames.instance`),
res => contractName in Object.fromEntries(res),
`${contractName} instance is available`,
);
});

test.after(async t => {
const { deleteTestKeys } = t.context;
deleteTestKeys(accounts);
});

interface KitchenSinkScenario {
chain: string;
chainId: string;
contractName: string;
// for faucet funds
denom: string;
expectedAddressPrefix: string;
wallet: string;
// the offer to execute
callPipe: string[];
offerArgs?: Record<string, unknown>;
}

const stakeScenario = test.macro(async (t, scenario: KitchenSinkScenario) => {
const { wallets, provisionSmartWallet, makeQueryTool, retryUntilCondition } =
t.context;

const vstorageClient = makeQueryTool();

const wdUser1 = await provisionSmartWallet(wallets[scenario.wallet], {
BLD: 100n,
IST: 100n,
});
t.log(`provisioning agoric smart wallet for ${wallets[scenario.wallet]}`);

const doOffer = makeDoOffer(wdUser1);
t.log(`${scenario.callPipe.join('.')} offer`);
const offerId = `${scenario.callPipe.join('.')}-${Date.now()}`;

// FIXME we get payouts but not an offer result; it times out
// chain logs shows an UNPUBLISHED result
const _offerResult = await doOffer({
id: offerId,
invitationSpec: {
source: 'agoricContract',
instancePath: [scenario.contractName],
callPipe: [scenario.callPipe],
},
offerArgs: {
chainName: 'cosmoshub',
},
proposal: {},
});
t.true(_offerResult);
// t.is(await _offerResult, 'UNPUBLISHED', 'representation of continuing offer');

// XXX fix above so we don't have to wait for the offer result to be published
const { offerToPublicSubscriberPaths: makeAccountPublicSubscriberPaths } =
await retryUntilCondition(
() =>
vstorageClient.queryData(
`published.wallet.${wallets[scenario.wallet]}.current`,
),
({ offerToPublicSubscriberPaths }) =>
!!offerToPublicSubscriberPaths.length,
'makeAccount offer result is in vstorage',
);

t.log(makeAccountPublicSubscriberPaths[0]);
t.regex(
makeAccountPublicSubscriberPaths[0][0],
new RegExp(scenario.callPipe[0]),
);


const address = makeAccountPublicSubscriberPaths?.[0]?.[1]?.account
.split('.')
.pop();
t.log('Got address:', address);
t.regex(
address,
new RegExp(`^${scenario.expectedAddressPrefix}1`),
`address for ${scenario.chain} is valid`,
);
});

const chainConfigs = {
cosmos: {
chain: 'cosmoshub',
chainId: 'gaialocal',
denom: 'uatom',
expectedAddressPrefix: 'cosmos',
callPipe: ['makeCosmosOrchAcctInvitation'],
offerArgs: { chainName: 'cosmoshub' },
},
osmosis: {
chain: 'osmosis',
chainId: 'osmosislocal',
denom: 'uosmo',
expectedAddressPrefix: 'osmo',
callPipe: ['makeCosmosOrchAcctInvitation'],
offerArgs: { chainName: 'osmosis' },
},
agoric: {
chain: 'agoric',
chainId: 'agoriclocal',
denom: 'ubld',
expectedAddressPrefix: 'agoric',
callPipe: ['makeLocalOrchAcctInvitation'],
},
};

const scenarios = Object.entries(chainConfigs).flatMap(([chainName, config]) =>
accounts.map(wallet => ({
...config,
contractName: 'kitchenSink',
wallet,
testName: `Create account on ${chainName} for ${wallet}`,
})),
);

scenarios.forEach(scenario => {
test.serial(scenario.testName, stakeScenario, scenario);
});
2 changes: 1 addition & 1 deletion multichain-testing/test/stake-ica.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ const stakeScenario = test.macro(async (t, scenario: StakeIcaScenario) => {
const queryClient = makeQueryClient(getRestEndpoint());

t.log('Requesting faucet funds');
// XXX fails intermitently until https://github.com/cosmology-tech/starship/issues/417
// XXX fails intermittently until https://github.com/cosmology-tech/starship/issues/417
await creditFromFaucet(address);

const { balances } = await retryUntilCondition(
Expand Down

0 comments on commit 78ec9cb

Please sign in to comment.