From 7fbe28e640d81f60b815ba123e30e97bc0747220 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 23 Aug 2023 16:04:16 +0200 Subject: harness: reusable test env --- packages/taler-harness/src/harness/harness.ts | 68 ++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 12 deletions(-) (limited to 'packages/taler-harness/src/harness/harness.ts') diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts index 4e2bae8f2..3a12024dc 100644 --- a/packages/taler-harness/src/harness/harness.ts +++ b/packages/taler-harness/src/harness/harness.ts @@ -489,6 +489,7 @@ export interface BankConfig { database: string; allowRegistrations: boolean; maxDebt?: string; + overrideTestDir?: string; } export interface FakeBankConfig { @@ -534,6 +535,14 @@ function setCoin(config: Configuration, c: CoinConfig) { } } +function backoffStart(): number { + return 10; +} + +function backoffIncrement(n: number): number { + return Math.max(n * 2, 1000); +} + /** * Send an HTTP request until it succeeds or the process dies. */ @@ -545,6 +554,7 @@ export async function pingProc( if (!proc || proc.proc.exitCode !== null) { throw Error(`service process ${serviceName} not started, can't ping`); } + let nextDelay = backoffStart(); while (true) { try { logger.trace(`pinging ${serviceName} at ${url}`); @@ -554,7 +564,8 @@ export async function pingProc( } catch (e: any) { logger.warn(`service ${serviceName} not ready:`, e.toString()); //console.log(e); - await delayMs(1000); + await delayMs(nextDelay); + nextDelay = backoffIncrement(nextDelay); } if (!proc || proc.proc.exitCode != null || proc.proc.signalCode != null) { throw Error(`service process ${serviceName} stopped unexpectedly`); @@ -875,7 +886,7 @@ export class FakebankService /** * Create a new fakebank service handle. - * + * * First generates the configuration for the fakebank and * then creates a fakebank handle, but doesn't start the fakebank * service yet. @@ -885,19 +896,38 @@ export class FakebankService bc: BankConfig, ): Promise { const config = new Configuration(); - setTalerPaths(config, gc.testDir + "/talerhome"); + const testDir = bc.overrideTestDir ?? gc.testDir; + setTalerPaths(config, testDir + "/talerhome"); config.setString("taler", "currency", bc.currency); config.setString("bank", "http_port", `${bc.httpPort}`); config.setString("bank", "serve", "http"); config.setString("bank", "max_debt_bank", `${bc.currency}:999999`); config.setString("bank", "max_debt", bc.maxDebt ?? `${bc.currency}:100`); config.setString("bank", "ram_limit", `${1024}`); - const cfgFilename = gc.testDir + "/bank.conf"; + const cfgFilename = testDir + "/bank.conf"; config.write(cfgFilename); return new FakebankService(gc, bc, cfgFilename); } + static fromExistingConfig( + gc: GlobalTestState, + opts: { overridePath?: string }, + ): FakebankService { + const testDir = opts.overridePath ?? gc.testDir; + const cfgFilename = testDir + `/bank.conf`; + const config = Configuration.load(cfgFilename); + const bc: BankConfig = { + allowRegistrations: + config.getYesNo("bank", "allow_registrations").orUndefined() ?? true, + currency: config.getString("taler", "currency").required(), + database: "none", + httpPort: config.getNumber("bank", "http_port").required(), + maxDebt: config.getString("bank", "max_debt").required(), + }; + return new FakebankService(gc, bc, cfgFilename); + } + setSuggestedExchange(e: ExchangeServiceInterface, exchangePayto: string) { if (!!this.proc) { throw Error("Can't set suggested exchange while bank is running."); @@ -981,6 +1011,7 @@ export interface ExchangeConfig { roundUnit?: string; httpPort: number; database: string; + overrideTestDir?: string; } export interface ExchangeServiceInterface { @@ -991,8 +1022,13 @@ export interface ExchangeServiceInterface { } export class ExchangeService implements ExchangeServiceInterface { - static fromExistingConfig(gc: GlobalTestState, exchangeName: string) { - const cfgFilename = gc.testDir + `/exchange-${exchangeName}.conf`; + static fromExistingConfig( + gc: GlobalTestState, + exchangeName: string, + opts: { overridePath?: string }, + ) { + const testDir = opts.overridePath ?? gc.testDir; + const cfgFilename = testDir + `/exchange-${exchangeName}.conf`; const config = Configuration.load(cfgFilename); const ec: ExchangeConfig = { currency: config.getString("taler", "currency").required(), @@ -1103,7 +1139,9 @@ export class ExchangeService implements ExchangeServiceInterface { } static create(gc: GlobalTestState, e: ExchangeConfig) { + const testDir = e.overrideTestDir ?? gc.testDir; const config = new Configuration(); + setTalerPaths(config, testDir + "/talerhome"); config.setString("taler", "currency", e.currency); // Required by the exchange but not really used yet. config.setString("exchange", "aml_threshold", `${e.currency}:1000000`); @@ -1112,7 +1150,6 @@ export class ExchangeService implements ExchangeServiceInterface { "currency_round_unit", e.roundUnit ?? `${e.currency}:0.01`, ); - setTalerPaths(config, gc.testDir + "/talerhome"); config.setString( "exchange", "revocation_dir", @@ -1149,7 +1186,7 @@ export class ExchangeService implements ExchangeServiceInterface { fs.writeFileSync(masterPrivFile, Buffer.from(exchangeMasterKey.eddsaPriv)); - const cfgFilename = gc.testDir + `/exchange-${e.name}.conf`; + const cfgFilename = testDir + `/exchange-${e.name}.conf`; config.write(cfgFilename); return new ExchangeService(gc, e, cfgFilename, exchangeMasterKey); } @@ -1553,6 +1590,7 @@ export interface MerchantConfig { currency: string; httpPort: number; database: string; + overrideTestDir?: string; } export interface PrivateOrderStatusQuery { @@ -1798,8 +1836,13 @@ export interface CreateMerchantTippingReserveRequest { } export class MerchantService implements MerchantServiceInterface { - static fromExistingConfig(gc: GlobalTestState, name: string) { - const cfgFilename = gc.testDir + `/merchant-${name}.conf`; + static fromExistingConfig( + gc: GlobalTestState, + name: string, + opts: { overridePath?: string }, + ) { + const testDir = opts.overridePath ?? gc.testDir; + const cfgFilename = testDir + `/merchant-${name}.conf`; const config = Configuration.load(cfgFilename); const mc: MerchantConfig = { currency: config.getString("taler", "currency").required(), @@ -1894,11 +1937,12 @@ export class MerchantService implements MerchantServiceInterface { gc: GlobalTestState, mc: MerchantConfig, ): Promise { + const testDir = mc.overrideTestDir ?? gc.testDir; const config = new Configuration(); config.setString("taler", "currency", mc.currency); - const cfgFilename = gc.testDir + `/merchant-${mc.name}.conf`; - setTalerPaths(config, gc.testDir + "/talerhome"); + const cfgFilename = testDir + `/merchant-${mc.name}.conf`; + setTalerPaths(config, testDir + "/talerhome"); config.setString("merchant", "serve", "tcp"); config.setString("merchant", "port", `${mc.httpPort}`); config.setString( -- cgit v1.2.3