wait for refreshes to finish before exiting integration test

This commit is contained in:
Florian Dold 2019-09-04 15:28:19 +02:00
parent 604a74007d
commit 5c809c3d9b
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
3 changed files with 98 additions and 43 deletions

View File

@ -83,5 +83,8 @@ export async function runIntegrationTest(args: {
throw Error("payment did not succeed");
}
const refreshRes = await myWallet.refreshDirtyCoins();
console.log(`waited to refresh ${refreshRes.numRefreshed} coins`);
myWallet.stop();
}

View File

@ -301,25 +301,31 @@ program
"amount to withdraw",
"TESTKUDOS:10",
)
.option("-s, --spend-amount <spend-amt>", "amount to spend", "TESTKUDOS:5")
.option("-s, --spend-amount <spend-amt>", "amount to spend", "TESTKUDOS:4")
.description("Run integration test with bank, exchange and merchant.")
.action(async cmdObj => {
applyVerbose(program.verbose);
await runIntegrationTest({
amountToSpend: cmdObj.spendAmount,
amountToWithdraw: cmdObj.withdrawAmount,
bankBaseUrl: cmdObj.bank,
exchangeBaseUrl: cmdObj.exchange,
merchantApiKey: cmdObj.merchantApiKey,
merchantBaseUrl: cmdObj.merchant,
merchantInstance: cmdObj.merchantInstance,
}).catch(err => {
console.error("Failed with exception:");
console.error(err);
});
try {
await runIntegrationTest({
amountToSpend: cmdObj.spendAmount,
amountToWithdraw: cmdObj.withdrawAmount,
bankBaseUrl: cmdObj.bank,
exchangeBaseUrl: cmdObj.exchange,
merchantApiKey: cmdObj.merchantApiKey,
merchantBaseUrl: cmdObj.merchant,
merchantInstance: cmdObj.merchantInstance,
}).catch(err => {
console.error("Failed with exception:");
console.error(err);
});
process.exit(0);
} catch (e) {
console.error(e);
process.exit(1);
}
process.exit(0);
});
// error on unknown commands

View File

@ -53,7 +53,6 @@ import {
DenominationRecord,
DenominationStatus,
ExchangeRecord,
ExchangeWireFeesRecord,
PreCoinRecord,
ProposalDownloadRecord,
PurchaseRecord,
@ -132,7 +131,7 @@ interface SpeculativePayData {
*/
export const WALLET_PROTOCOL_VERSION = "3:0:0";
const WALLET_CACHE_BREAKER="01";
const WALLET_CACHE_BREAKER = "01";
const builtinCurrencies: CurrencyRecord[] = [
{
@ -360,6 +359,9 @@ export class Wallet {
private activeProcessPreCoinOperations: {
[preCoinPub: string]: Promise<void>;
} = {};
private activeRefreshOperations: {
[coinPub: string]: Promise<void>;
} = {};
/**
* Set of identifiers for running operations.
@ -943,9 +945,34 @@ export class Wallet {
nextUrl,
lastSessionId: sessionId,
};
return { nextUrl };
}
/**
* Refresh all dirty coins.
* The returned promise resolves only after all refresh
* operations have completed.
*/
async refreshDirtyCoins(): Promise<{ numRefreshed: number }> {
let n = 0;
const coins = await this.q()
.iter(Stores.coins)
.toArray();
for (let coin of coins) {
if (coin.status == CoinStatus.Dirty) {
try {
await this.refresh(coin.coinPub);
} catch (e) {
console.log("error during refresh");
}
n += 1;
}
}
return { numRefreshed: n };
}
/**
* Add a contract to the wallet and sign coins, and send them.
*/
@ -1955,7 +1982,9 @@ export class Wallet {
*/
async updateExchangeFromUrl(baseUrl: string): Promise<ExchangeRecord> {
baseUrl = canonicalizeBaseUrl(baseUrl);
const keysUrl = new URI("keys").absoluteTo(baseUrl).addQuery("cacheBreaker", WALLET_CACHE_BREAKER);
const keysUrl = new URI("keys")
.absoluteTo(baseUrl)
.addQuery("cacheBreaker", WALLET_CACHE_BREAKER);
const keysResp = await this.http.get(keysUrl.href());
if (keysResp.status !== 200) {
throw Error("/keys request failed");
@ -2419,32 +2448,49 @@ export class Wallet {
}
async refresh(oldCoinPub: string): Promise<void> {
const oldRefreshSessions = await this.q()
.iter(Stores.refresh)
.toArray();
for (const session of oldRefreshSessions) {
Wallet.enableTracing &&
console.log("got old refresh session for", oldCoinPub, session);
this.continueRefreshSession(session);
const refreshImpl = async () => {
const oldRefreshSessions = await this.q()
.iter(Stores.refresh)
.toArray();
for (const session of oldRefreshSessions) {
Wallet.enableTracing &&
console.log("got old refresh session for", oldCoinPub, session);
return this.continueRefreshSession(session);
}
const coin = await this.q().get(Stores.coins, oldCoinPub);
if (!coin) {
console.warn("can't refresh, coin not in database");
return;
}
if (
coin.status === CoinStatus.Useless ||
coin.status === CoinStatus.Fresh
) {
return;
}
const refreshSession = await this.createRefreshSession(oldCoinPub);
if (!refreshSession) {
// refreshing not necessary
Wallet.enableTracing && console.log("not refreshing", oldCoinPub);
return;
}
return this.continueRefreshSession(refreshSession);
};
const activeRefreshOp = this.activeRefreshOperations[oldCoinPub];
if (activeRefreshOp) {
return activeRefreshOp;
}
const coin = await this.q().get(Stores.coins, oldCoinPub);
if (!coin) {
console.warn("can't refresh, coin not in database");
return;
try {
const newOp = refreshImpl();
this.activeRefreshOperations[oldCoinPub] = newOp;
const res = await newOp;
return res;
} finally {
delete this.activeRefreshOperations[oldCoinPub];
}
if (
coin.status === CoinStatus.Useless ||
coin.status === CoinStatus.Fresh
) {
return;
}
const refreshSession = await this.createRefreshSession(oldCoinPub);
if (!refreshSession) {
// refreshing not necessary
Wallet.enableTracing && console.log("not refreshing", oldCoinPub);
return;
}
this.continueRefreshSession(refreshSession);
}
async continueRefreshSession(refreshSession: RefreshSessionRecord) {
@ -3617,8 +3663,8 @@ export class Wallet {
const refundsDoneFees = Object.values(purchase.refundsDone).map(x =>
Amounts.parseOrThrow(x.refund_amount),
);
const refundsPendingFees = Object.values(purchase.refundsPending).map(
x => Amounts.parseOrThrow(x.refund_amount),
const refundsPendingFees = Object.values(purchase.refundsPending).map(x =>
Amounts.parseOrThrow(x.refund_amount),
);
const totalRefundFees = Amounts.sum([
...refundsDoneFees,