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"); throw Error("payment did not succeed");
} }
const refreshRes = await myWallet.refreshDirtyCoins();
console.log(`waited to refresh ${refreshRes.numRefreshed} coins`);
myWallet.stop(); myWallet.stop();
} }

View File

@ -301,25 +301,31 @@ program
"amount to withdraw", "amount to withdraw",
"TESTKUDOS:10", "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.") .description("Run integration test with bank, exchange and merchant.")
.action(async cmdObj => { .action(async cmdObj => {
applyVerbose(program.verbose); applyVerbose(program.verbose);
await runIntegrationTest({ try {
amountToSpend: cmdObj.spendAmount, await runIntegrationTest({
amountToWithdraw: cmdObj.withdrawAmount, amountToSpend: cmdObj.spendAmount,
bankBaseUrl: cmdObj.bank, amountToWithdraw: cmdObj.withdrawAmount,
exchangeBaseUrl: cmdObj.exchange, bankBaseUrl: cmdObj.bank,
merchantApiKey: cmdObj.merchantApiKey, exchangeBaseUrl: cmdObj.exchange,
merchantBaseUrl: cmdObj.merchant, merchantApiKey: cmdObj.merchantApiKey,
merchantInstance: cmdObj.merchantInstance, merchantBaseUrl: cmdObj.merchant,
}).catch(err => { merchantInstance: cmdObj.merchantInstance,
console.error("Failed with exception:"); }).catch(err => {
console.error(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 // error on unknown commands

View File

@ -53,7 +53,6 @@ import {
DenominationRecord, DenominationRecord,
DenominationStatus, DenominationStatus,
ExchangeRecord, ExchangeRecord,
ExchangeWireFeesRecord,
PreCoinRecord, PreCoinRecord,
ProposalDownloadRecord, ProposalDownloadRecord,
PurchaseRecord, PurchaseRecord,
@ -132,7 +131,7 @@ interface SpeculativePayData {
*/ */
export const WALLET_PROTOCOL_VERSION = "3:0:0"; export const WALLET_PROTOCOL_VERSION = "3:0:0";
const WALLET_CACHE_BREAKER="01"; const WALLET_CACHE_BREAKER = "01";
const builtinCurrencies: CurrencyRecord[] = [ const builtinCurrencies: CurrencyRecord[] = [
{ {
@ -360,6 +359,9 @@ export class Wallet {
private activeProcessPreCoinOperations: { private activeProcessPreCoinOperations: {
[preCoinPub: string]: Promise<void>; [preCoinPub: string]: Promise<void>;
} = {}; } = {};
private activeRefreshOperations: {
[coinPub: string]: Promise<void>;
} = {};
/** /**
* Set of identifiers for running operations. * Set of identifiers for running operations.
@ -943,9 +945,34 @@ export class Wallet {
nextUrl, nextUrl,
lastSessionId: sessionId, lastSessionId: sessionId,
}; };
return { nextUrl }; 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. * 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> { async updateExchangeFromUrl(baseUrl: string): Promise<ExchangeRecord> {
baseUrl = canonicalizeBaseUrl(baseUrl); 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()); const keysResp = await this.http.get(keysUrl.href());
if (keysResp.status !== 200) { if (keysResp.status !== 200) {
throw Error("/keys request failed"); throw Error("/keys request failed");
@ -2419,32 +2448,49 @@ export class Wallet {
} }
async refresh(oldCoinPub: string): Promise<void> { async refresh(oldCoinPub: string): Promise<void> {
const oldRefreshSessions = await this.q() const refreshImpl = async () => {
.iter(Stores.refresh) const oldRefreshSessions = await this.q()
.toArray(); .iter(Stores.refresh)
for (const session of oldRefreshSessions) { .toArray();
Wallet.enableTracing && for (const session of oldRefreshSessions) {
console.log("got old refresh session for", oldCoinPub, session); Wallet.enableTracing &&
this.continueRefreshSession(session); 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) { try {
console.warn("can't refresh, coin not in database"); const newOp = refreshImpl();
return; 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) { async continueRefreshSession(refreshSession: RefreshSessionRecord) {
@ -3617,8 +3663,8 @@ export class Wallet {
const refundsDoneFees = Object.values(purchase.refundsDone).map(x => const refundsDoneFees = Object.values(purchase.refundsDone).map(x =>
Amounts.parseOrThrow(x.refund_amount), Amounts.parseOrThrow(x.refund_amount),
); );
const refundsPendingFees = Object.values(purchase.refundsPending).map( const refundsPendingFees = Object.values(purchase.refundsPending).map(x =>
x => Amounts.parseOrThrow(x.refund_amount), Amounts.parseOrThrow(x.refund_amount),
); );
const totalRefundFees = Amounts.sum([ const totalRefundFees = Amounts.sum([
...refundsDoneFees, ...refundsDoneFees,