Skip to content

Commit

Permalink
test: e2e tests of cosmosOrchAccount getBalance and getBalances
Browse files Browse the repository at this point in the history
  • Loading branch information
0xpatrickdev committed Sep 4, 2024
1 parent e79ec5f commit 11f1cde
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 1 deletion.
190 changes: 190 additions & 0 deletions multichain-testing/test/account-balance-queries.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import anyTest from '@endo/ses-ava/prepare-endo.js';
import type { TestFn } from 'ava';
import type { CosmosChainInfo } from '@agoric/orchestration';
import {
commonSetup,
SetupContextWithWallets,
chainConfig,
} from './support.js';
import { makeDoOffer } from '../tools/e2e-tools.js';
import chainInfo from '../starship-chain-info.js';
import { MAKE_ACCOUNT_AND_QUERY_BALANCE_TIMEOUT } from './config.js';

const test = anyTest as TestFn<SetupContextWithWallets>;

const accounts = ['osmosis', 'cosmoshub', 'agoric'];

const contractName = 'queryFlows';
const contractBuilder =
'../packages/builders/scripts/testing/start-query-flows.js';

test.before(async t => {
const { deleteTestKeys, setupTestKeys, ...rest } = await commonSetup(t);
deleteTestKeys(accounts).catch();
const wallets = await setupTestKeys(accounts);
t.context = { ...rest, wallets, deleteTestKeys };
const { startContract } = rest;
await startContract(contractName, contractBuilder);
});

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

const queryAccountBalances = test.macro({
title: (_, chainName: string) => `Query Account Balances on ${chainName}`,
exec: async (t, chainName: string) => {
const config = chainConfig[chainName];
if (!config) return t.fail(`Unknown chain: ${chainName}`);
const {
wallets,
provisionSmartWallet,
vstorageClient,
retryUntilCondition,
} = t.context;

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

const doOffer = makeDoOffer(wdUser1);
t.log(`${chainName} makeAccountAndGetBalancesQuery offer`);
const offerId = `${chainName}-makeAccountAndGetBalancesQuery-${Date.now()}`;

await doOffer({
id: offerId,
invitationSpec: {
source: 'agoricContract',
instancePath: [contractName],
callPipe: [['makeAccountAndGetBalancesQueryInvitation']],
},
offerArgs: { chainName },
proposal: {},
});

const offerResult = await retryUntilCondition(
() => vstorageClient.queryData(`published.wallet.${agoricAddr}`),
({ status }) => status.id === offerId && (status.result || status.error),
`${offerId} offer result is in vstorage`,
MAKE_ACCOUNT_AND_QUERY_BALANCE_TIMEOUT,
);
t.log('Account Balances Query Offer Result', offerResult);

const { icqEnabled } = (chainInfo as Record<string, CosmosChainInfo>)[
chainName
];
t.log(
icqEnabled
? 'ICQ Enabled expecting offer result.'
: 'ICQ Disabled expecting offer error',
);

const {
status: { result, error },
} = offerResult;
if (icqEnabled) {
t.is(error, undefined, 'No error observed for supported chain');
const balances = JSON.parse(result);
t.truthy(balances, 'Result is parsed successfully');
t.true(Array.isArray(balances), 'Balances is an array');
t.is(balances.length, 0, 'Balances are empty');
} else {
t.truthy(error, 'Error observed for unsupported chain');
t.regex(
error,
/Queries not available for chain/i,
'Correct error message for unsupported chain',
);
}
},
});

const queryAccountBalance = test.macro({
title: (_, chainName: string) => `Query Account Balance on ${chainName}`,
exec: async (t, chainName: string) => {
const config = chainConfig[chainName];
if (!config) return t.fail(`Unknown chain: ${chainName}`);
const {
wallets,
provisionSmartWallet,
vstorageClient,
retryUntilCondition,
useChain,
} = t.context;

const {
chainInfo: {
chain: { staking },
},
} = useChain(chainName);
const denom = staking?.staking_tokens?.[0].denom;
if (!denom) throw Error(`no denom for ${chainName}`);

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

const doOffer = makeDoOffer(wdUser1);
t.log(`${chainName} makeAccountAndGetBalanceQuery offer`);
const offerId = `${chainName}-makeAccountAndGetBalanceQuery-${Date.now()}`;

await doOffer({
id: offerId,
invitationSpec: {
source: 'agoricContract',
instancePath: [contractName],
callPipe: [['makeAccountAndGetBalanceQueryInvitation']],
},
offerArgs: { chainName, denom },
proposal: {},
});

const offerResult = await retryUntilCondition(
() => vstorageClient.queryData(`published.wallet.${agoricAddr}`),
({ status }) => status.id === offerId && (status.result || status.error),
`${offerId} offer result is in vstorage`,
MAKE_ACCOUNT_AND_QUERY_BALANCE_TIMEOUT,
);
t.log('Account Balance Query Offer Result', offerResult);
const { icqEnabled } = (chainInfo as Record<string, CosmosChainInfo>)[
chainName
];
t.log(
icqEnabled
? 'ICQ Enabled, expecting offer result.'
: 'ICQ Disabled, expecting offer error',
);

const {
status: { result, error },
} = offerResult;
if (icqEnabled) {
t.is(error, undefined, 'No error observed for supported chain');
const parsedBalance = JSON.parse(result);
t.truthy(parsedBalance, 'Result is parsed successfully');

t.truthy(parsedBalance, 'Balance object exists');
t.is(parsedBalance.denom, denom, 'Correct denom in balance');
t.is(parsedBalance.value, '[0n]', 'Balance amount is 0n');
} else {
t.truthy(error, 'Error observed for unsupported chain');
t.regex(
error,
/Queries not available for chain/i,
'Correct error message for unsupported chain',
);
}
},
});

test.serial(queryAccountBalances, 'osmosis');
test.serial(queryAccountBalances, 'cosmoshub');
test.serial(queryAccountBalance, 'osmosis');
test.serial(queryAccountBalance, 'cosmoshub');
2 changes: 1 addition & 1 deletion multichain-testing/test/chain-queries.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ const queryICQChain = test.macro({
const offerResult = await retryUntilCondition(
() => vstorageClient.queryData(`published.wallet.${agoricAddr}`),
({ status }) => status.id === offerId && (status.result || status.error),
`${offerId} continuing invitation is in vstorage`,
`${offerId} offer result is in vstorage`,
{
maxRetries: 15,
},
Expand Down
10 changes: 10 additions & 0 deletions multichain-testing/test/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,13 @@ export const AUTO_STAKE_IT_DELEGATIONS_TIMEOUT: RetryOptions = {
retryIntervalMs: 5000,
maxRetries: 24,
};

/**
* Wait about 90s to ensure:
* - ICA Account is created
* - ICQ Connection is established (in some instances)
* - Query is executed (sometimes local, sometimes via ICQ)
*/
export const MAKE_ACCOUNT_AND_QUERY_BALANCE_TIMEOUT: RetryOptions = {
maxRetries: 25,
};

0 comments on commit 11f1cde

Please sign in to comment.