diff options
Diffstat (limited to 'packages/taler-harness/src')
20 files changed, 227 insertions, 98 deletions
| diff --git a/packages/taler-harness/src/bench1.ts b/packages/taler-harness/src/bench1.ts index 941d9244a..fb7cc9e1f 100644 --- a/packages/taler-harness/src/bench1.ts +++ b/packages/taler-harness/src/bench1.ts @@ -48,6 +48,7 @@ export async function runBench1(configJson: any): Promise<void> {    const myHttpLib = createPlatformHttpLib({      enableThrottling: false, +    allowHttp: true,    });    const numIter = b1conf.iterations ?? 1; @@ -92,8 +93,8 @@ export async function runBench1(configJson: any): Promise<void> {            },            features: {              batchWithdrawal, -          } -        } +          }, +        },        });        wallet = res.wallet;        getDbStats = res.getDbStats; diff --git a/packages/taler-harness/src/bench2.ts b/packages/taler-harness/src/bench2.ts index ff87da52a..48ac76b9f 100644 --- a/packages/taler-harness/src/bench2.ts +++ b/packages/taler-harness/src/bench2.ts @@ -34,6 +34,7 @@ import {    findDenomOrThrow,    refreshCoin,    SynchronousCryptoWorkerFactoryPlain, +  Wallet,    withdrawCoin,  } from "@gnu-taler/taler-wallet-core"; @@ -56,6 +57,7 @@ export async function runBench2(configJson: any): Promise<void> {    const http = createPlatformHttpLib({      enableThrottling: false, +    allowHttp: true,    });    const numIter = benchConf.iterations ?? 1; @@ -84,7 +86,9 @@ export async function runBench2(configJson: any): Promise<void> {      console.log("reserve found"); -    const d1 = findDenomOrThrow(exchangeInfo, `${curr}:8`); +    const d1 = findDenomOrThrow(exchangeInfo, `${curr}:8`, { +      denomselAllowLate: Wallet.defaultConfig.testing.denomselAllowLate, +    });      for (let j = 0; j < numDeposits; j++) {        console.log("withdrawing coin"); @@ -111,8 +115,12 @@ export async function runBench2(configJson: any): Promise<void> {        });        const refreshDenoms = [ -        findDenomOrThrow(exchangeInfo, `${curr}:1`), -        findDenomOrThrow(exchangeInfo, `${curr}:1`), +        findDenomOrThrow(exchangeInfo, `${curr}:1`, { +          denomselAllowLate: Wallet.defaultConfig.testing.denomselAllowLate, +        }), +        findDenomOrThrow(exchangeInfo, `${curr}:1`, { +          denomselAllowLate: Wallet.defaultConfig.testing.denomselAllowLate, +        }),        ];        console.log("refreshing coin"); diff --git a/packages/taler-harness/src/bench3.ts b/packages/taler-harness/src/bench3.ts index 2573aec14..ffafc75d2 100644 --- a/packages/taler-harness/src/bench3.ts +++ b/packages/taler-harness/src/bench3.ts @@ -52,6 +52,7 @@ export async function runBench3(configJson: any): Promise<void> {    const myHttpLib = createPlatformHttpLib({      enableThrottling: false, +    allowHttp: true,    });    const numIter = b3conf.iterations ?? 1; @@ -96,7 +97,7 @@ export async function runBench3(configJson: any): Promise<void> {          httpLib: myHttpLib,          config: {            features: { -            batchWithdrawal: batchWithdrawal, +            batchWithdrawal,            },            testing: {              insecureTrustExchange: trustExchange, diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts index b6e80cfb7..0ee0d7960 100644 --- a/packages/taler-harness/src/harness/harness.ts +++ b/packages/taler-harness/src/harness/harness.ts @@ -102,6 +102,21 @@ interface WaitResult {    signal: NodeJS.Signals | null;  } +class CommandError extends Error { +  constructor( +    public message: string, +    public logName: string, +    public command: string, +    public args: string[], +    public env: Env, +    public code: number | null, +  ) { +    super(message); +  } +} +interface Env { +  [index: string]: string | undefined; +}  /**   * Run a shell command, return stdout.   */ @@ -109,15 +124,15 @@ export async function sh(    t: GlobalTestState,    logName: string,    command: string, -  env: { [index: string]: string | undefined } = process.env, +  env: Env = process.env,  ): Promise<string> { -  logger.info(`running command ${command}`); +  logger.trace(`running command ${command}`);    return new Promise((resolve, reject) => {      const stdoutChunks: Buffer[] = [];      const proc = spawn(command, {        stdio: ["inherit", "pipe", "pipe"],        shell: true, -      env: env, +      env,      });      proc.stdout.on("data", (x) => {        if (x instanceof Buffer) { @@ -132,16 +147,34 @@ export async function sh(      });      proc.stderr.pipe(stderrLog);      proc.on("exit", (code, signal) => { -      logger.info(`child process exited (${code} / ${signal})`); +      logger.info(`child process ${logName} exited (${code} / ${signal})`);        if (code != 0) { -        reject(Error(`Unexpected exit code ${code} for '${command}'`)); +        reject( +          new CommandError( +            `Unexpected exit code ${code}`, +            logName, +            command, +            [], +            env, +            code, +          ), +        );          return;        }        const b = Buffer.concat(stdoutChunks).toString("utf-8");        resolve(b);      }); -    proc.on("error", () => { -      reject(Error("Child process had error")); +    proc.on("error", (err) => { +      reject( +        new CommandError( +          "Child process had error:" + err.message, +          logName, +          command, +          [], +          env, +          null, +        ), +      );      });    });  } @@ -170,6 +203,7 @@ export async function runCommand(    env: { [index: string]: string | undefined } = process.env,  ): Promise<string> {    logger.info(`running command ${shellescape([command, ...args])}`); +    return new Promise((resolve, reject) => {      const stdoutChunks: Buffer[] = [];      const proc = spawn(command, args, { @@ -190,16 +224,34 @@ export async function runCommand(      });      proc.stderr.pipe(stderrLog);      proc.on("exit", (code, signal) => { -      logger.info(`child process exited (${code} / ${signal})`); +      logger.trace(`child process exited (${code} / ${signal})`);        if (code != 0) { -        reject(Error(`Unexpected exit code ${code} for '${command}'`)); +        reject( +          new CommandError( +            `Unexpected exit code ${code}`, +            logName, +            command, +            [], +            env, +            code, +          ), +        );          return;        }        const b = Buffer.concat(stdoutChunks).toString("utf-8");        resolve(b);      }); -    proc.on("error", () => { -      reject(Error("Child process had error")); +    proc.on("error", (err) => { +      reject( +        new CommandError( +          "Child process had error:" + err.message, +          logName, +          command, +          [], +          env, +          null, +        ), +      );      });    });  } @@ -321,14 +373,14 @@ export class GlobalTestState {      logName: string,      env: { [index: string]: string | undefined } = process.env,    ): ProcessWrapper { -    logger.info( +    logger.trace(        `spawning process (${logName}): ${shellescape([command, ...args])}`,      );      const proc = spawn(command, args, {        stdio: ["inherit", "pipe", "pipe"],        env: env,      }); -    logger.info(`spawned process (${logName}) with pid ${proc.pid}`); +    logger.trace(`spawned process (${logName}) with pid ${proc.pid}`);      proc.on("error", (err) => {        logger.warn(`could not start process (${command})`, err);      }); @@ -355,18 +407,18 @@ export class GlobalTestState {        return;      }      if (shouldLingerInTest()) { -      logger.info("refusing to shut down, lingering was requested"); +      logger.trace("refusing to shut down, lingering was requested");        return;      }      this.inShutdown = true; -    logger.info("shutting down"); +    logger.trace("shutting down");      for (const s of this.servers) {        s.close();        s.removeAllListeners();      }      for (const p of this.procs) {        if (p.proc.exitCode == null) { -        logger.info(`killing process ${p.proc.pid}`); +        logger.trace(`killing process ${p.proc.pid}`);          p.proc.kill("SIGTERM");          await p.wait();        } @@ -473,12 +525,12 @@ export async function pingProc(    }    while (true) {      try { -      logger.info(`pinging ${serviceName} at ${url}`); +      logger.trace(`pinging ${serviceName} at ${url}`);        const resp = await axios.get(url); -      logger.info(`service ${serviceName} available`); +      logger.trace(`service ${serviceName} available`);        return;      } catch (e: any) { -      logger.info(`service ${serviceName} not ready:`, e.toString()); +      logger.warn(`service ${serviceName} not ready:`, e.toString());        //console.log(e);        await delayMs(1000);      } @@ -506,7 +558,10 @@ class LibEuFinBankService extends BankServiceBase implements BankServiceHandle {    sandboxProc: ProcessWrapper | undefined;    nexusProc: ProcessWrapper | undefined; -  http = createPlatformHttpLib(); +  http = createPlatformHttpLib({ +    allowHttp: true, +    enableThrottling: false, +  });    static async create(      gc: GlobalTestState, @@ -539,12 +594,6 @@ class LibEuFinBankService extends BankServiceBase implements BankServiceHandle {      return url.href;    } -  // FIXME: Duplicate?  Where is this needed? -  get baseUrlAccessApi(): string { -    let url = new URL("access-api/", this.baseUrlDemobank); -    return url.href; -  } -    get bankAccessApiBaseUrl(): string {      let url = new URL("access-api/", this.baseUrlDemobank);      return url.href; @@ -555,7 +604,7 @@ class LibEuFinBankService extends BankServiceBase implements BankServiceHandle {    }    get baseUrl(): string { -    return this.baseUrlAccessApi; +    return this.bankAccessApiBaseUrl;    }    async setSuggestedExchange( @@ -587,7 +636,7 @@ class LibEuFinBankService extends BankServiceBase implements BankServiceHandle {      await this.start();      await this.pingUntilAvailable();      await LibeufinSandboxApi.createDemobankAccount(accountName, password, { -      baseUrl: this.baseUrlAccessApi, +      baseUrl: this.bankAccessApiBaseUrl,      });      let bankAccountLabel = accountName;      await LibeufinSandboxApi.createDemobankEbicsSubscriber( @@ -697,7 +746,7 @@ class LibEuFinBankService extends BankServiceBase implements BankServiceHandle {      let accountInfoResp = await LibeufinSandboxApi.demobankAccountInfo(        "admin",        "secret", -      { baseUrl: this.baseUrlAccessApi }, +      { baseUrl: this.bankAccessApiBaseUrl },        accountName, // bank account label.      );      return { @@ -793,7 +842,7 @@ export class FakebankService  {    proc: ProcessWrapper | undefined; -  http = createPlatformHttpLib(); +  http = createPlatformHttpLib({ allowHttp: true, enableThrottling: false });    // We store "created" accounts during setup and    // register them after startup. @@ -1282,7 +1331,9 @@ export class ExchangeService implements ExchangeServiceInterface {        }      } -    logger.info("configuring bank accounts", accounts); +    const accountsDescription = accounts.map((acc) => ` * ${acc}`).join("\n"); +    logger.info("configuring bank accounts:"); +    logger.info(accountsDescription);      for (const acc of accounts) {        await runCommand( @@ -1494,7 +1545,7 @@ export class MerchantApiClient {    ) {}    // FIXME: Migrate everything to this in favor of axios -  http = createPlatformHttpLib(); +  http = createPlatformHttpLib({ allowHttp: true, enableThrottling: false });    async changeAuth(auth: MerchantAuthConfiguration): Promise<void> {      const url = new URL("private/auth", this.baseUrl); @@ -2052,6 +2103,7 @@ export async function runTestWithState(    try {      logger.info("running test in directory", gc.testDir);      await Promise.race([testMain(gc), p.promise]); +    logger.info("completed test in directory", gc.testDir);      status = "pass";      if (linger) {        const rl = readline.createInterface({ @@ -2068,9 +2120,22 @@ export async function runTestWithState(        rl.close();      }    } catch (e) { -    console.error("FATAL: test failed with exception", e); -    if (e instanceof TalerError) { -      console.error(`error detail: ${j2s(e.errorDetail)}`); +    if (e instanceof CommandError) { +      console.error("FATAL: test failed for", e.logName); +      const errorLog = fs.readFileSync( +        path.join(gc.testDir, `${e.logName}-stderr.log`), +      ); +      console.error(`${e.message}: "${e.command}"`); +      console.error(errorLog.toString()); +      console.error(e); +    } else if (e instanceof TalerError) { +      console.error( +        "FATAL: test failed", +        e.message, +        `error detail: ${j2s(e.errorDetail)}`, +      ); +    } else { +      console.error("FATAL: test failed with exception", e);      }      status = "fail";    } finally { @@ -2243,23 +2308,28 @@ export class WalletCli {          const cryptoWorkerArg = cliOpts.cryptoWorkerType            ? `--crypto-worker=${cliOpts.cryptoWorkerType}`            : ""; -        const resp = await sh( -          self.globalTestState, -          `wallet-${self.name}`, -          `taler-wallet-cli ${ -            self.timetravelArg ?? "" -          } ${cryptoWorkerArg} --no-throttle -LTRACE --skip-defaults --wallet-db '${ -            self.dbfile -          }' api '${op}' ${shellWrap(JSON.stringify(payload))}`, -        ); +        const logName = `wallet-${self.name}`; +        const command = `taler-wallet-cli ${ +          self.timetravelArg ?? "" +        } ${cryptoWorkerArg} --allow-http --no-throttle -LTRACE --skip-defaults --wallet-db '${ +          self.dbfile +        }' api '${op}' ${shellWrap(JSON.stringify(payload))}`; +        const resp = await sh(self.globalTestState, logName, command);          logger.info("--- wallet core response ---");          logger.info(resp);          logger.info("--- end of response ---"); -        let ar: any; +        let ar: CoreApiResponse;          try { -          ar = JSON.parse(resp) as CoreApiResponse; +          ar = JSON.parse(resp);          } catch (e) { -          throw new Error("wallet CLI did not return a proper JSON response"); +          throw new CommandError( +            "wallet CLI did not return a proper JSON response", +            logName, +            command, +            [], +            {}, +            null, +          );          }          if (ar.type === "error") {            throw TalerError.fromUncheckedDetail(ar.error); @@ -2295,6 +2365,7 @@ export class WalletCli {        `wallet-${this.name}`,        "taler-wallet-cli",        [ +        "--allow-http",          "--no-throttle",          ...this.timetravelArgArr,          "-LTRACE", @@ -2313,6 +2384,7 @@ export class WalletCli {        `wallet-${this.name}`,        "taler-wallet-cli",        [ +        "--allow-http",          "--no-throttle",          "--skip-defaults",          "-LTRACE", diff --git a/packages/taler-harness/src/harness/helpers.ts b/packages/taler-harness/src/harness/helpers.ts index 516312ed8..b13fa9cf4 100644 --- a/packages/taler-harness/src/harness/helpers.ts +++ b/packages/taler-harness/src/harness/helpers.ts @@ -99,7 +99,7 @@ export interface EnvOptions {  /**   * Run a test case with a simple TESTKUDOS Taler environment, consisting   * of one exchange, one bank and one merchant. - *  + *   * @deprecated use {@link createSimpleTestkudosEnvironmentV2} instead   */  export async function createSimpleTestkudosEnvironment( @@ -557,7 +557,7 @@ export async function withdrawViaBankV2(  /**   * Withdraw balance. - *  + *   * @deprecated use {@link withdrawViaBankV2 instead}   */  export async function withdrawViaBank( diff --git a/packages/taler-harness/src/harness/libeufin-apis.ts b/packages/taler-harness/src/harness/libeufin-apis.ts index 4ef588fb5..cb9acdaa4 100644 --- a/packages/taler-harness/src/harness/libeufin-apis.ts +++ b/packages/taler-harness/src/harness/libeufin-apis.ts @@ -5,10 +5,9 @@   * the services get actually started and managed.   */ +import { URL } from "@gnu-taler/taler-util";  import axiosImp from "axios";  const axios = axiosImp.default; -import { AmountString, Logger, URL } from "@gnu-taler/taler-util"; -import { createPlatformHttpLib } from "@gnu-taler/taler-util/http";  export interface LibeufinSandboxServiceInterface {    baseUrl: string; diff --git a/packages/taler-harness/src/harness/libeufin.ts b/packages/taler-harness/src/harness/libeufin.ts index 001fb613b..8fd276fad 100644 --- a/packages/taler-harness/src/harness/libeufin.ts +++ b/packages/taler-harness/src/harness/libeufin.ts @@ -899,6 +899,8 @@ export function findNexusPayment(  ): LibeufinNexusMoneyMovement | void {    let transactions = payments["transactions"];    for (let i = 0; i < transactions.length; i++) { +    //FIXME: last line won't compile with the current definition of the type +    //@ts-ignore      let batches = transactions[i]["camtData"]["batches"];      for (let y = 0; y < batches.length; y++) {        let movements = batches[y]["batchTransactions"]; diff --git a/packages/taler-harness/src/index.ts b/packages/taler-harness/src/index.ts index 30b557986..bd58a7fd6 100644 --- a/packages/taler-harness/src/index.ts +++ b/packages/taler-harness/src/index.ts @@ -17,10 +17,6 @@  /**   * Imports.   */ -import { deepStrictEqual } from "assert"; -import fs from "fs"; -import os from "os"; -import path from "path";  import {    addPaytoQueryParams,    Amounts, @@ -28,33 +24,34 @@ import {    decodeCrock,    j2s,    Logger, -  parsePaytoUri,    rsaBlind,    setGlobalLogLevelFromString,  } from "@gnu-taler/taler-util"; +import { clk } from "@gnu-taler/taler-util/clk"; +import { createPlatformHttpLib } from "@gnu-taler/taler-util/http"; +import { +  BankAccessApiClient, +  CryptoDispatcher, +  downloadExchangeInfo, +  SynchronousCryptoWorkerFactoryPlain, +  topupReserveWithDemobank, +} from "@gnu-taler/taler-wallet-core"; +import { deepStrictEqual } from "assert"; +import fs from "fs"; +import os from "os"; +import path from "path";  import { runBench1 } from "./bench1.js";  import { runBench2 } from "./bench2.js";  import { runBench3 } from "./bench3.js"; +import { runEnvFull } from "./env-full.js";  import { runEnv1 } from "./env1.js";  import {    GlobalTestState,    MerchantApiClient, -  MerchantPrivateApi,    runTestWithState,  } from "./harness/harness.js";  import { getTestInfo, runTests } from "./integrationtests/testrunner.js";  import { lintExchangeDeployment } from "./lint.js"; -import { runEnvFull } from "./env-full.js"; -import { clk } from "@gnu-taler/taler-util/clk"; -import { createPlatformHttpLib } from "@gnu-taler/taler-util/http"; -import { -  BankAccessApiClient, -  checkReserve, -  CryptoDispatcher, -  downloadExchangeInfo, -  SynchronousCryptoWorkerFactoryPlain, -  topupReserveWithDemobank, -} from "@gnu-taler/taler-wallet-core";  const logger = new Logger("taler-harness:index.ts"); @@ -213,6 +210,7 @@ deploymentCli        baseUrl: args.tipTopup.bankAccessUrl,        username: args.tipTopup.bankAccount,        password: args.tipTopup.bankPassword, +      allowHttp: true,      });      const paytoUri = addPaytoQueryParams(tipReserveResp.payto_uri, { @@ -495,6 +493,12 @@ testingCli    .flag("experimental", ["--experimental"], {      help: "Include tests marked as experimental",    }) +  .flag("failFast", ["--fail-fast"], { +    help: "Exit after the first error", +  }) +  .flag("waitOnFail", ["--wait-on-fail"], { +    help: "Exit after the first error", +  })    .flag("quiet", ["--quiet"], {      help: "Produce less output.",    }) @@ -504,6 +508,8 @@ testingCli    .action(async (args) => {      await runTests({        includePattern: args.runIntegrationtests.pattern, +      failFast: args.runIntegrationtests.failFast, +      waitOnFail: args.runIntegrationtests.waitOnFail,        suiteSpec: args.runIntegrationtests.suites,        dryRun: args.runIntegrationtests.dryRun,        verbosity: args.runIntegrationtests.quiet ? 0 : 1, diff --git a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts index 561a10e6d..38cbd6925 100644 --- a/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts +++ b/packages/taler-harness/src/integrationtests/test-age-restrictions-merchant.ts @@ -166,6 +166,7 @@ export async function runAgeRestrictionsMerchantTest(t: GlobalTestState) {        wireGatewayApiBaseUrl: exchangeBankAccount.wireGatewayApiBaseUrl,        accountName: exchangeBankAccount.accountName,        accountPassword: exchangeBankAccount.accountPassword, +      allowHttp: true,      });      await wireGatewayApiClient.adminAddIncoming({ diff --git a/packages/taler-harness/src/integrationtests/test-age-restrictions-peer.ts b/packages/taler-harness/src/integrationtests/test-age-restrictions-peer.ts index d129a5217..0bb811f39 100644 --- a/packages/taler-harness/src/integrationtests/test-age-restrictions-peer.ts +++ b/packages/taler-harness/src/integrationtests/test-age-restrictions-peer.ts @@ -18,9 +18,7 @@   * Imports.   */  import { AbsoluteTime, Duration } from "@gnu-taler/taler-util"; -import { -  WalletApiOperation, -} from "@gnu-taler/taler-wallet-core"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";  import { defaultCoinConfig } from "../harness/denomStructures.js";  import { GlobalTestState, WalletCli } from "../harness/harness.js";  import { diff --git a/packages/taler-harness/src/integrationtests/test-bank-api.ts b/packages/taler-harness/src/integrationtests/test-bank-api.ts index d97860a2c..5e3448625 100644 --- a/packages/taler-harness/src/integrationtests/test-bank-api.ts +++ b/packages/taler-harness/src/integrationtests/test-bank-api.ts @@ -126,6 +126,7 @@ export async function runBankApiTest(t: GlobalTestState) {      wireGatewayApiBaseUrl: exchangeBankAccount.wireGatewayApiBaseUrl,      accountName: exchangeBankAccount.accountName,      accountPassword: exchangeBankAccount.accountPassword, +    allowHttp: true,    });    await wireGatewayApiClient.adminAddIncoming({ diff --git a/packages/taler-harness/src/integrationtests/test-exchange-deposit.ts b/packages/taler-harness/src/integrationtests/test-exchange-deposit.ts index 18a3c172a..6c0d070d0 100644 --- a/packages/taler-harness/src/integrationtests/test-exchange-deposit.ts +++ b/packages/taler-harness/src/integrationtests/test-exchange-deposit.ts @@ -33,6 +33,7 @@ import {    refreshCoin,    SynchronousCryptoWorkerFactoryPlain,    topupReserveWithDemobank, +  Wallet,    withdrawCoin,  } from "@gnu-taler/taler-wallet-core";  import { GlobalTestState } from "../harness/harness.js"; @@ -46,7 +47,10 @@ export async function runExchangeDepositTest(t: GlobalTestState) {    const { bank, exchange } = await createSimpleTestkudosEnvironment(t); -  const http = createPlatformHttpLib(); +  const http = createPlatformHttpLib({ +    allowHttp: true, +    enableThrottling: false, +  });    const cryptiDisp = new CryptoDispatcher(      new SynchronousCryptoWorkerFactoryPlain(),    ); @@ -71,7 +75,9 @@ export async function runExchangeDepositTest(t: GlobalTestState) {      await checkReserve(http, exchange.baseUrl, reserveKeyPair.pub); -    const d1 = findDenomOrThrow(exchangeInfo, "TESTKUDOS:8"); +    const d1 = findDenomOrThrow(exchangeInfo, "TESTKUDOS:8", { +      denomselAllowLate: Wallet.defaultConfig.testing.denomselAllowLate, +    });      const coin = await withdrawCoin({        http, diff --git a/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts b/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts index 20285cb6a..7f94628a6 100644 --- a/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts +++ b/packages/taler-harness/src/integrationtests/test-exchange-timetravel.ts @@ -24,7 +24,10 @@ import {    Duration,    durationFromSpec,  } from "@gnu-taler/taler-util"; -import { createPlatformHttpLib, readSuccessResponseJsonOrThrow } from "@gnu-taler/taler-util/http"; +import { +  createPlatformHttpLib, +  readSuccessResponseJsonOrThrow, +} from "@gnu-taler/taler-util/http";  import { makeNoFeeCoinConfig } from "../harness/denomStructures.js";  import {    BankService, @@ -65,7 +68,10 @@ async function applyTimeTravel(    }  } -const http = createPlatformHttpLib(); +const http = createPlatformHttpLib({ +  allowHttp: true, +  enableThrottling: false, +});  /**   * Basic time travel test. diff --git a/packages/taler-harness/src/integrationtests/test-kyc.ts b/packages/taler-harness/src/integrationtests/test-kyc.ts index b7ea0ff77..b86c8dd5b 100644 --- a/packages/taler-harness/src/integrationtests/test-kyc.ts +++ b/packages/taler-harness/src/integrationtests/test-kyc.ts @@ -340,7 +340,10 @@ export async function runKycTest(t: GlobalTestState) {    // We now simulate the user interacting with the KYC service,    // which would usually done in the browser. -  const httpLib = createPlatformHttpLib(); +  const httpLib = createPlatformHttpLib({ +    allowHttp: true, +    enableThrottling: false, +  });    const kycServerResp = await httpLib.get(kycNotif.kycUrl);    const kycLoginResp = await kycServerResp.json();    console.log("kyc server resp:", j2s(kycLoginResp)); diff --git a/packages/taler-harness/src/integrationtests/test-merchant-spec-public-orders.ts b/packages/taler-harness/src/integrationtests/test-merchant-spec-public-orders.ts index 2fafe7584..975ba707b 100644 --- a/packages/taler-harness/src/integrationtests/test-merchant-spec-public-orders.ts +++ b/packages/taler-harness/src/integrationtests/test-merchant-spec-public-orders.ts @@ -39,7 +39,10 @@ import {    withdrawViaBank,  } from "../harness/helpers.js"; -const httpLib = createPlatformHttpLib(); +const httpLib = createPlatformHttpLib({ +  allowHttp: true, +  enableThrottling: false, +});  interface Context {    merchant: MerchantService; diff --git a/packages/taler-harness/src/integrationtests/test-tipping.ts b/packages/taler-harness/src/integrationtests/test-tipping.ts index 69afad6fd..b124fbf0d 100644 --- a/packages/taler-harness/src/integrationtests/test-tipping.ts +++ b/packages/taler-harness/src/integrationtests/test-tipping.ts @@ -61,6 +61,7 @@ export async function runTippingTest(t: GlobalTestState) {      wireGatewayApiBaseUrl: exchangeBankAccount.wireGatewayApiBaseUrl,      accountName: exchangeBankAccount.accountName,      accountPassword: exchangeBankAccount.accountPassword, +    allowHttp: true,    });    await wireGatewayApiClient.adminAddIncoming({ diff --git a/packages/taler-harness/src/integrationtests/test-wallet-dbless.ts b/packages/taler-harness/src/integrationtests/test-wallet-dbless.ts index 37be9dcf8..c384a6e74 100644 --- a/packages/taler-harness/src/integrationtests/test-wallet-dbless.ts +++ b/packages/taler-harness/src/integrationtests/test-wallet-dbless.ts @@ -33,6 +33,7 @@ import {    refreshCoin,    SynchronousCryptoWorkerFactoryPlain,    topupReserveWithDemobank, +  Wallet,    withdrawCoin,  } from "@gnu-taler/taler-wallet-core";  import { GlobalTestState } from "../harness/harness.js"; @@ -46,7 +47,10 @@ export async function runWalletDblessTest(t: GlobalTestState) {    const { bank, exchange } = await createSimpleTestkudosEnvironment(t); -  const http = createPlatformHttpLib(); +  const http = createPlatformHttpLib({ +    allowHttp: true, +    enableThrottling: false, +  });    const cryptiDisp = new CryptoDispatcher(      new SynchronousCryptoWorkerFactoryPlain(),    ); @@ -84,7 +88,9 @@ export async function runWalletDblessTest(t: GlobalTestState) {      await checkReserve(http, exchange.baseUrl, reserveKeyPair.pub); -    const d1 = findDenomOrThrow(exchangeInfo, "TESTKUDOS:8"); +    const d1 = findDenomOrThrow(exchangeInfo, "TESTKUDOS:8", { +      denomselAllowLate: Wallet.defaultConfig.testing.denomselAllowLate, +    });      const coin = await withdrawCoin({        http, @@ -125,8 +131,12 @@ export async function runWalletDblessTest(t: GlobalTestState) {      });      const refreshDenoms = [ -      findDenomOrThrow(exchangeInfo, "TESTKUDOS:1"), -      findDenomOrThrow(exchangeInfo, "TESTKUDOS:1"), +      findDenomOrThrow(exchangeInfo, "TESTKUDOS:1", { +        denomselAllowLate: Wallet.defaultConfig.testing.denomselAllowLate, +      }), +      findDenomOrThrow(exchangeInfo, "TESTKUDOS:1", { +        denomselAllowLate: Wallet.defaultConfig.testing.denomselAllowLate, +      }),      ];      await refreshCoin({ diff --git a/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts b/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts index 4a79d2c21..a356a5c1a 100644 --- a/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts +++ b/packages/taler-harness/src/integrationtests/test-withdrawal-manual.ts @@ -73,6 +73,7 @@ export async function runWithdrawalManualTest(t: GlobalTestState) {      wireGatewayApiBaseUrl: exchangeBankAccount.wireGatewayApiBaseUrl,      accountName: exchangeBankAccount.accountName,      accountPassword: exchangeBankAccount.accountPassword, +    allowHttp: true,    });    await wireGatewayApiClient.adminAddIncoming({ diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts index f845f4e99..c76ce1b18 100644 --- a/packages/taler-harness/src/integrationtests/testrunner.ts +++ b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -14,7 +14,7 @@   GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>   */ -import { CancellationToken, minimatch } from "@gnu-taler/taler-util"; +import { CancellationToken, Logger, minimatch } from "@gnu-taler/taler-util";  import * as child_process from "child_process";  import * as fs from "fs";  import * as os from "os"; @@ -105,6 +105,7 @@ import { runExchangeDepositTest } from "./test-exchange-deposit.js";  /**   * Test runner.   */ +const logger = new Logger("testrunner.ts");  /**   * Spec for one test. @@ -199,6 +200,8 @@ export interface TestRunSpec {    includePattern?: string;    suiteSpec?: string;    dryRun?: boolean; +  failFast?: boolean; +  waitOnFail?: boolean;    includeExperimental: boolean;    noTimeout: boolean;    verbosity: number; @@ -357,7 +360,7 @@ export async function runTests(spec: TestRunSpec) {            if (token.isCancelled) {              return;            } -          console.log(`process exited code=${code} signal=${signal}`); +          logger.info(`process exited code=${code} signal=${signal}`);            if (signal) {              reject(new Error(`test worker exited with signal ${signal}`));            } else if (code != 0) { @@ -385,6 +388,10 @@ export async function runTests(spec: TestRunSpec) {      try {        result = await token.racePromise(resultPromise); +      if (result.status === "fail" && spec.failFast) { +        logger.error("test failed and failing fast, exit!"); +        throw Error("exit on fail fast"); +      }      } catch (e: any) {        console.error(`test ${testName} timed out`);        if (token.isCancelled) { @@ -469,10 +476,9 @@ if (runTestInstrStr && process.argv.includes("__TWCLI_TESTWORKER")) {    const { testRootDir, testName } = JSON.parse(      runTestInstrStr,    ) as RunTestChildInstruction; -  console.log(`running test ${testName} in worker process`);    process.on("disconnect", () => { -    console.log("got disconnect from parent"); +    logger.trace("got disconnect from parent");      process.exit(3);    }); @@ -486,35 +492,36 @@ if (runTestInstrStr && process.argv.includes("__TWCLI_TESTWORKER")) {      }      if (!process.send) { -      console.error("can't communicate with parent"); +      logger.error("can't communicate with parent");        process.exit(2);      }      if (!testMain) { -      console.log(`test ${testName} not found`); +      logger.info(`test ${testName} not found`);        process.exit(2);      }      const testDir = path.join(testRootDir, testName); -    console.log(`running test ${testName}`); +    logger.info(`running test ${testName}`);      const gc = new GlobalTestState({        testDir,      });      const testResult = await runTestWithState(gc, testMain, testName); +    logger.info(`done test ${testName}: ${testResult.status}`);      process.send(testResult);    };    runTest()      .then(() => { -      console.log(`test ${testName} finished in worker`); +      logger.trace(`test ${testName} finished in worker`);        if (shouldLingerInTest()) { -        console.log("lingering ..."); +        logger.trace("lingering ...");          return;        }        process.exit(0);      })      .catch((e) => { -      console.log(e); +      logger.error(e);        process.exit(1);      });  } diff --git a/packages/taler-harness/src/lint.ts b/packages/taler-harness/src/lint.ts index 3d3805e79..715227c7f 100644 --- a/packages/taler-harness/src/lint.ts +++ b/packages/taler-harness/src/lint.ts @@ -53,7 +53,10 @@ interface PubkeyConf {    masterPublicKey: string;  } -const httpLib = createPlatformHttpLib(); +const httpLib = createPlatformHttpLib({ +  enableThrottling: false, +  allowHttp: true, +});  interface ShellResult {    stdout: string; | 
