diff options
Diffstat (limited to 'packages/taler-harness/src/harness')
-rw-r--r-- | packages/taler-harness/src/harness/harness.ts | 87 | ||||
-rw-r--r-- | packages/taler-harness/src/harness/helpers.ts | 40 |
2 files changed, 84 insertions, 43 deletions
diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts index 8f1f3f452..926a0c93b 100644 --- a/packages/taler-harness/src/harness/harness.ts +++ b/packages/taler-harness/src/harness/harness.ts @@ -563,7 +563,7 @@ export async function pingProc( return; } catch (e: any) { logger.warn(`service ${serviceName} not ready:`, e.toString()); - logger.info(`waiting ${nextDelay}ms`); + logger.info(`waiting ${nextDelay}ms on ${serviceName}`); await delayMs(nextDelay); nextDelay = backoffIncrement(nextDelay); } @@ -905,7 +905,7 @@ export class FakebankService config.setString("bank", "max_debt", bc.maxDebt ?? `${bc.currency}:100`); config.setString("bank", "ram_limit", `${1024}`); const cfgFilename = testDir + "/bank.conf"; - config.write(cfgFilename); + config.write(cfgFilename, { excludeDefaults: true }); return new FakebankService(gc, bc, cfgFilename); } @@ -934,7 +934,7 @@ export class FakebankService } const config = Configuration.load(this.configFile); config.setString("bank", "suggested_exchange", e.baseUrl); - config.write(this.configFile); + config.write(this.configFile, { excludeDefaults: true }); } get baseUrl(): string { @@ -1037,7 +1037,9 @@ export class ExchangeService implements ExchangeServiceInterface { name: exchangeName, roundUnit: config.getString("taler", "currency_round_unit").required(), }; - const privFile = config.getPath("exchange", "master_priv_file").required(); + const privFile = config + .getPath("exchange-offline", "master_priv_file") + .required(); const eddsaPriv = fs.readFileSync(privFile); const keyPair: EddsaKeyPair = { eddsaPriv, @@ -1135,7 +1137,7 @@ export class ExchangeService implements ExchangeServiceInterface { changeConfig(f: (config: Configuration) => void) { const config = Configuration.load(this.configFilename); f(config); - config.write(this.configFilename); + config.write(this.configFilename, { excludeDefaults: true }); } static create(gc: GlobalTestState, e: ExchangeConfig) { @@ -1184,10 +1186,16 @@ export class ExchangeService implements ExchangeServiceInterface { fs.mkdirSync(path.dirname(masterPrivFile), { recursive: true }); + if (fs.existsSync(masterPrivFile)) { + throw new Error( + "master priv file already exists, can't create new exchange config", + ); + } + fs.writeFileSync(masterPrivFile, Buffer.from(exchangeMasterKey.eddsaPriv)); const cfgFilename = testDir + `/exchange-${e.name}.conf`; - config.write(cfgFilename); + config.write(cfgFilename, { excludeDefaults: true }); return new ExchangeService(gc, e, cfgFilename, exchangeMasterKey); } @@ -1196,13 +1204,13 @@ export class ExchangeService implements ExchangeServiceInterface { offeredCoins.forEach((cc) => setCoin(config, cc(this.exchangeConfig.currency)), ); - config.write(this.configFilename); + config.write(this.configFilename, { excludeDefaults: true }); } addCoinConfigList(ccs: CoinConfig[]) { const config = Configuration.load(this.configFilename); ccs.forEach((cc) => setCoin(config, cc)); - config.write(this.configFilename); + config.write(this.configFilename, { excludeDefaults: true }); } enableAgeRestrictions(maskStr: string) { @@ -1213,7 +1221,7 @@ export class ExchangeService implements ExchangeServiceInterface { "age_groups", maskStr, ); - config.write(this.configFilename); + config.write(this.configFilename, { excludeDefaults: true }); } get masterPub() { @@ -1234,7 +1242,7 @@ export class ExchangeService implements ExchangeServiceInterface { ): Promise<void> { const config = Configuration.load(this.configFilename); await f(config); - config.write(this.configFilename); + config.write(this.configFilename, { excludeDefaults: true }); } async addBankAccount( @@ -1274,7 +1282,7 @@ export class ExchangeService implements ExchangeServiceInterface { "password", exchangeBankAccount.accountPassword, ); - config.write(this.configFilename); + config.write(this.configFilename, { excludeDefaults: true }); } exchangeHttpProc: ProcessWrapper | undefined; @@ -1535,19 +1543,25 @@ export class ExchangeService implements ExchangeServiceInterface { ); } - async start(opts: { skipSetup?: boolean } = {}): Promise<void> { + async dbinit() { + await sh( + this.globalState, + "exchange-dbinit", + `taler-exchange-dbinit -c "${this.configFilename}"`, + ); + } + + async start( + opts: { skipDbinit?: boolean; skipKeyup?: boolean } = {}, + ): Promise<void> { if (this.isRunning()) { throw Error("exchange is already running"); } - const skipSetup = opts.skipSetup ?? false; + const skipDbinit = opts.skipDbinit ?? false; - if (!skipSetup) { - await sh( - this.globalState, - "exchange-dbinit", - `taler-exchange-dbinit -c "${this.configFilename}"`, - ); + if (!skipDbinit) { + await this.dbinit(); } this.helperCryptoEddsaProc = this.globalState.spawnService( @@ -1579,7 +1593,10 @@ export class ExchangeService implements ExchangeServiceInterface { ); await this.pingUntilAvailable(); - if (!skipSetup) { + + const skipKeyup = opts.skipKeyup ?? false; + + if (!skipKeyup) { await this.keyup(); } else { logger.info("skipping keyup"); @@ -1921,16 +1938,23 @@ export class MerchantService implements MerchantServiceInterface { } } - async start(opts: { skipSetup?: boolean } = {}): Promise<void> { - const skipSetup = opts.skipSetup ?? false; + async dbinit() { + await runCommand( + this.globalState, + "merchant-dbinit", + "taler-merchant-dbinit", + ["-c", this.configFilename], + ); + } + + /** + * Start the merchant, + */ + async start(opts: { skipDbinit?: boolean } = {}): Promise<void> { + const skipSetup = opts.skipDbinit ?? false; if (!skipSetup) { - await runCommand( - this.globalState, - "merchant-dbinit", - "taler-merchant-dbinit", - ["-c", this.configFilename], - ); + await this.dbinit(); } this.proc = this.globalState.spawnService( @@ -1964,7 +1988,7 @@ export class MerchantService implements MerchantServiceInterface { "${TALER_DATA_HOME}/merchant/merchant.priv", ); config.setString("merchantdb-postgres", "config", mc.database); - config.write(cfgFilename); + config.write(cfgFilename, { excludeDefaults: true }); return new MerchantService(gc, mc, cfgFilename); } @@ -1982,7 +2006,7 @@ export class MerchantService implements MerchantServiceInterface { this.merchantConfig.currency, ); config.setString(`merchant-exchange-${e.name}`, "master_key", e.masterPub); - config.write(this.configFilename); + config.write(this.configFilename, { excludeDefaults: true }); } async addDefaultInstance(): Promise<void> { @@ -2303,7 +2327,8 @@ export class WalletService { try { await tryUnixConnect(this.socketPath); } catch (e) { - logger.info(`connection attempt failed: ${e}`); + logger.info(`wallet connection attempt failed: ${e}`); + logger.info(`waiting on wallet for ${nextDelay}ms`); await delayMs(nextDelay); nextDelay = backoffIncrement(nextDelay); continue; diff --git a/packages/taler-harness/src/harness/helpers.ts b/packages/taler-harness/src/harness/helpers.ts index 932854a1e..d41ffdd00 100644 --- a/packages/taler-harness/src/harness/helpers.ts +++ b/packages/taler-harness/src/harness/helpers.ts @@ -230,6 +230,11 @@ export async function useSharedTestkudosEnvironment(t: GlobalTestState) { logger.info(`previous setup done: ${prevSetupDone}`); + + // Wallet has longer startup-time and no dependencies, + // so we start it rather early. + const walletStartProm = createWalletDaemonWithClient(t, { name: "wallet" }) + if (fs.existsSync(sharedDir + "/bank.conf")) { logger.info("reusing existing bank"); bank = BankService.fromExistingConfig(t, { @@ -249,15 +254,19 @@ export async function useSharedTestkudosEnvironment(t: GlobalTestState) { logger.info("setting up exchange"); const exchangeName = "testexchange-1"; - const exchangeConfigFilename = sharedDir + `/exchange-${exchangeName}}`; + const exchangeConfigFilename = sharedDir + `/exchange-${exchangeName}.conf`; + + logger.info(`exchange config filename: ${exchangeConfigFilename}`); let exchange: ExchangeService; if (fs.existsSync(exchangeConfigFilename)) { + logger.info("reusing existing exchange config"); exchange = ExchangeService.fromExistingConfig(t, exchangeName, { overridePath: sharedDir, }); } else { + logger.info("creating new exchange config"); exchange = ExchangeService.create(t, { name: "testexchange-1", currency: "TESTKUDOS", @@ -305,22 +314,29 @@ export async function useSharedTestkudosEnvironment(t: GlobalTestState) { logger.info("basic setup done, starting services"); + if (!prevSetupDone) { + // Must be done sequentially, due to a concurrency + // issue in the *-dbinit tools. + await exchange.dbinit(); + await merchant.dbinit(); + } + const bankStart = async () => { await bank.start(); - await bank.pingUntilAvailable(); }; const exchangeStart = async () => { await exchange.start({ - skipSetup: prevSetupDone, + skipDbinit: true, + skipKeyup: prevSetupDone, }); await exchange.pingUntilAvailable(); }; const merchStart = async () => { await merchant.start({ - skipSetup: prevSetupDone, + skipDbinit: true, }); await merchant.pingUntilAvailable(); @@ -345,24 +361,22 @@ export async function useSharedTestkudosEnvironment(t: GlobalTestState) { } }; - const walletStart = async () => { - return await createWalletDaemonWithClient(t, { name: "wallet" }); - }; + await bankStart() const res = await Promise.all([ exchangeStart(), merchStart(), - bankStart(), - walletStart(), + undefined, + walletStartProm, ]); const walletClient = res[3].walletClient; const walletService = res[3].walletService; - console.log("setup done!"); - fs.writeFileSync(sharedDir + "/setup-done", "OK"); + logger.info("setup done!"); + return { commonDb: db, exchange, @@ -515,7 +529,7 @@ export async function createWalletDaemonWithClient( const walletClient = new WalletClient({ unixPath: walletService.socketPath, onNotification(n) { - console.log("got notification", n); + console.log(`got ${args.name} notification`, n); if (args.handleNotification) { args.handleNotification(n); } @@ -789,6 +803,8 @@ export async function applyTimeTravel( /** * Make a simple payment and check that it succeeded. + * + * @deprecated */ export async function makeTestPayment( t: GlobalTestState, |