Skip to content

Commit

Permalink
test(a3p): update test with new helper functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Jorge-Lopes committed Oct 28, 2024
1 parent edcde9d commit d59c30e
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 11 deletions.
30 changes: 19 additions & 11 deletions a3p-integration/proposals/n:upgrade-next/priceFeedUpdate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ import {
getVaultPrices,
getVatDetails,
openVault,
pushPrices,
registerOraclesForBrand,
USER1ADDR,
} from '@agoric/synthetic-chain';
import {
getPriceFeedRoundId,
verifyPushedPrice,
} from './test-lib/price-feed.js';

import { BID_OFFER_ID } from './agd-tools.js';

Expand All @@ -37,12 +39,17 @@ const checkPriceFeedVatsUpdated = async t => {
await checkForOracle(t, 'stATOM');
};

console.log('adding oracle for each brand');
const oraclesByBrand = generateOracleMap('f-priceFeeds', ['ATOM', 'stATOM']);
await registerOraclesForBrand('ATOM', oraclesByBrand);
await registerOraclesForBrand('stATOM', oraclesByBrand);
/*
* The Oracle for ATOM and stATOM brands are being registered in the offer made at file:
* a3p-integration/proposals/n:upgrade-next/verifyPushedPrice.js
* which is being executed during the use phase of upgrade-next proposal
*/
const oraclesByBrand = generateOracleMap('n-upgrade', ['ATOM', 'stATOM']);

let roundId = 1;
const latestAtomRoundId = await getPriceFeedRoundId('ATOM');
const latestStAtomRoundId = await getPriceFeedRoundId('stATOM');
let atomRoundId = latestAtomRoundId + 1;
let stAtomRoundId = latestStAtomRoundId + 1;

const tryPushPrices = async t => {
// There are no old prices for the other currencies.
Expand All @@ -52,9 +59,10 @@ const tryPushPrices = async t => {
// t.is(stAtomOutPre, '+12010000');

t.log('pushing new prices');
await pushPrices(13.4, 'ATOM', oraclesByBrand, roundId);
await pushPrices(13.7, 'stATOM', oraclesByBrand, roundId);
roundId += 1;
await verifyPushedPrice(13.4, 'ATOM', oraclesByBrand, atomRoundId);
await verifyPushedPrice(13.7, 'stATOM', oraclesByBrand, stAtomRoundId);
atomRoundId += 1;
stAtomRoundId += 1;

t.log('awaiting new quotes');
const atomOut = await getPriceQuote('ATOM');
Expand Down Expand Up @@ -89,7 +97,7 @@ const openMarginalVault = async t => {
};

const triggerAuction = async t => {
await pushPrices(5.2, 'ATOM', oraclesByBrand, roundId);
await verifyPushedPrice(5.2, 'ATOM', oraclesByBrand, atomRoundId);

const atomOut = await getPriceQuote('ATOM');
t.is(atomOut, '+5200000');
Expand Down
62 changes: 62 additions & 0 deletions a3p-integration/proposals/n:upgrade-next/test-lib/price-feed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* eslint-env node */

import {
agoric,
getContractInfo,
pushPrices,
getPriceQuote,
} from '@agoric/synthetic-chain';
import { retryUntilCondition } from './sync-tools.js';

export const scale6 = x => BigInt(x * 1_000_000);

/**
*
* @param {number} price
* @param {string} brand
* @param {Map<any, any>} oraclesByBrand
* @param {number} roundId
* @returns {Promise<void>}
*/
export const verifyPushedPrice = async (
price,
brand,
oraclesByBrand,
roundId,
) => {
const pushPriceRetryOpts = {
maxRetries: 5, // arbitrary
retryIntervalMs: 5000, // in ms
};

await pushPrices(price, brand, oraclesByBrand, roundId);
console.log(`Pushing price ${price} for ${brand}`);

await retryUntilCondition(
() => getPriceQuote(brand),
res => res === `+${scale6(price).toString()}`,
'price not pushed yet',
{
log: console.log,
setTimeout: global.setTimeout,
...pushPriceRetryOpts,
},
);
console.log(`Price ${price} pushed for ${brand}`);
};

/**
*
* @param {string} brand
* @returns {Promise<number>}
*/
export const getPriceFeedRoundId = async brand => {
const latestRoundPath = `published.priceFeed.${brand}-USD_price_feed.latestRound`;
const latestRound = await getContractInfo(latestRoundPath, {
agoric,
prefix: '',
});

console.log('latestRound: ', latestRound);
return Number(latestRound.roundId);
};
72 changes: 72 additions & 0 deletions a3p-integration/proposals/n:upgrade-next/test-lib/sync-tools.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/* eslint-env node */

/**
* @file These tools mostly duplicate code that will be added in other PRs
* and eventually migrated to synthetic-chain. Sorry for the duplication.
*/

/**
* @typedef {object} RetryOptions
* @property {number} [maxRetries]
* @property {number} [retryIntervalMs]
* @property {(...arg0: string[]) => void} log
* @property {(object) => void} [setTimeout]
* @property {string} [errorMessage=Error]
*/

const ambientSetTimeout = global.setTimeout;

/**
* From https://github.com/Agoric/agoric-sdk/blob/442f07c8f0af03281b52b90e90c27131eef6f331/multichain-testing/tools/sleep.ts#L10
*
* @param {number} ms
* @param {*} sleepOptions
*/
const sleep = (ms, { log = () => {}, setTimeout = ambientSetTimeout }) =>
new Promise(resolve => {
log(`Sleeping for ${ms}ms...`);
setTimeout(resolve, ms);
});

/**
* From https://github.com/Agoric/agoric-sdk/blob/442f07c8f0af03281b52b90e90c27131eef6f331/multichain-testing/tools/sleep.ts#L24
*
* @param {() => Promise} operation
* @param {(result: any) => boolean} condition
* @param {string} message
* @param {RetryOptions} options
*/
export const retryUntilCondition = async (
operation,
condition,
message,
{ maxRetries = 6, retryIntervalMs = 3500, log, setTimeout },
) => {
console.log({ maxRetries, retryIntervalMs, message });
let retries = 0;

await null;
while (retries < maxRetries) {
try {
const result = await operation();
log('RESULT', result);
if (condition(result)) {
return result;
}
} catch (error) {
if (error instanceof Error) {
log(`Error: ${error.message}`);
} else {
log(`Unknown error: ${String(error)}`);
}
}

retries += 1;
console.log(
`Retry ${retries}/${maxRetries} - Waiting for ${retryIntervalMs}ms for ${message}...`,
);
await sleep(retryIntervalMs, { log, setTimeout });
}

throw Error(`${message} condition failed after ${maxRetries} retries.`);
};

0 comments on commit d59c30e

Please sign in to comment.