gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 02/02: make integration tests part of taler-wallet-c


From: gnunet
Subject: [taler-wallet-core] 02/02: make integration tests part of taler-wallet-cli
Date: Tue, 12 Jan 2021 20:04:24 +0100

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

commit a5681579fbddb001f5b7118fe705c6643581c722
Author: Florian Dold <florian@dold.me>
AuthorDate: Tue Jan 12 20:04:16 2021 +0100

    make integration tests part of taler-wallet-cli
---
 packages/taler-integrationtests/package.json       |  25 ---
 packages/taler-integrationtests/scenario           |  26 ---
 .../src/scenario-rerun-payment-multiple.ts         | 128 ---------------
 packages/taler-integrationtests/testrunner         |  77 ---------
 packages/taler-integrationtests/tsconfig.json      |  32 ----
 packages/taler-wallet-cli/package.json             |   2 +
 packages/taler-wallet-cli/src/index.ts             |  20 +++
 .../src/integrationtests}/denomStructures.ts       |   0
 .../src/integrationtests}/faultInjection.ts        |   0
 .../src/integrationtests}/harness.ts               | 123 ++++++--------
 .../src/integrationtests}/helpers.ts               |   0
 .../src/integrationtests}/merchantApiTypes.ts      |   0
 .../integrationtests}/scenario-prompt-payment.ts   |   6 +-
 .../src/integrationtests}/test-bank-api.ts         |   5 +-
 .../src/integrationtests}/test-claim-loop.ts       |   6 +-
 .../integrationtests}/test-exchange-management.ts  |   5 +-
 .../src/integrationtests}/test-fee-regression.ts   |   6 +-
 .../integrationtests}/test-merchant-longpolling.ts |   6 +-
 .../integrationtests}/test-merchant-refund-api.ts  |   6 +-
 .../src/integrationtests}/test-pay-abort.ts        |   7 +-
 .../src/integrationtests}/test-pay-paid.ts         |   6 +-
 .../src/integrationtests}/test-payment-claim.ts    |  11 +-
 .../src/integrationtests}/test-payment-fault.ts    |   5 +-
 .../integrationtests}/test-payment-idempotency.ts  |   6 +-
 .../src/integrationtests}/test-payment-multiple.ts |   5 +-
 .../integrationtests}/test-payment-transient.ts    |   6 +-
 .../src/integrationtests}/test-payment.ts          |   6 +-
 .../src/integrationtests}/test-paywall-flow.ts     |   6 +-
 .../src/integrationtests}/test-refund-auto.ts      |   8 +-
 .../src/integrationtests}/test-refund-gone.ts      |   6 +-
 .../integrationtests}/test-refund-incremental.ts   |  11 +-
 .../src/integrationtests}/test-refund.ts           |   6 +-
 .../src/integrationtests}/test-revocation.ts       |   6 +-
 .../test-timetravel-autorefresh.ts                 |   5 +-
 .../integrationtests}/test-timetravel-withdraw.ts  |   6 +-
 .../src/integrationtests}/test-tipping.ts          |   5 +-
 .../src/integrationtests}/test-wallettesting.ts    |   6 +-
 .../test-withdrawal-abort-bank.ts                  |   6 +-
 .../test-withdrawal-bank-integrated.ts             |   6 +-
 .../integrationtests}/test-withdrawal-manual.ts    |   6 +-
 .../src/integrationtests/testrunner.ts             | 176 +++++++++++++++++++++
 pnpm-lock.yaml                                     |  36 +++--
 tsconfig.build.json                                |   5 +-
 43 files changed, 339 insertions(+), 486 deletions(-)

diff --git a/packages/taler-integrationtests/package.json 
b/packages/taler-integrationtests/package.json
deleted file mode 100644
index 7da65b14..00000000
--- a/packages/taler-integrationtests/package.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
-  "name": "taler-integrationtests",
-  "version": "0.0.1",
-  "description": "Integration tests and fault injection for GNU Taler 
components",
-  "main": "index.js",
-  "scripts": {
-    "compile": "tsc -b",
-    "pretty": "prettier --write src"
-  },
-  "author": "Florian Dold <dold@taler.net>",
-  "license": "AGPL-3.0-or-later",
-  "devDependencies": {
-    "esm": "^3.2.25",
-    "nyc": "^15.1.0",
-    "prettier": "^2.1.2",
-    "source-map-support": "^0.5.19",
-    "ts-node": "^9.0.0",
-    "typescript": "^4.0.5"
-  },
-  "dependencies": {
-    "axios": "^0.21.0",
-    "taler-wallet-core": "workspace:*",
-    "tslib": "^2.0.3"
-  }
-}
diff --git a/packages/taler-integrationtests/scenario 
b/packages/taler-integrationtests/scenario
deleted file mode 100755
index 9bef68ff..00000000
--- a/packages/taler-integrationtests/scenario
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env bash
-
-# Simple test runner for the wallet integration tests.
-#
-# Usage: $0 TESTGLOB
-#
-# The TESTGLOB can be used to select which test cases to execute
-
-set -eu
-
-if [ "$#" -ne 1 ]; then
-    echo "Usage: $0 SCENARIO"
-    exit 1
-fi
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-
-cd $DIR
-
-./node_modules/.bin/tsc -b
-
-export ESM_OPTIONS='{"sourceMap": true}'
-
-file=lib/scenario-$1.js
-
-exec node -r source-map-support/register -r esm $file
diff --git 
a/packages/taler-integrationtests/src/scenario-rerun-payment-multiple.ts 
b/packages/taler-integrationtests/src/scenario-rerun-payment-multiple.ts
deleted file mode 100644
index 3a98987b..00000000
--- a/packages/taler-integrationtests/src/scenario-rerun-payment-multiple.ts
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2020 Taler Systems S.A.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- * Imports.
- */
-import {
-  GlobalTestState,
-  BankService,
-  ExchangeService,
-  MerchantService,
-  WalletCli,
-  runTestWithState,
-  MerchantPrivateApi,
-} from "./harness";
-import { withdrawViaBank } from "./helpers";
-import fs from "fs";
-
-let existingTestDir =
-  process.env["TALER_TEST_OLD_DIR"] ?? "/tmp/taler-integrationtest-current";
-
-if (!fs.existsSync(existingTestDir)) {
-  throw Error("old test dir not found");
-}
-
-existingTestDir = fs.realpathSync(existingTestDir);
-
-const prevT = new GlobalTestState({
-  testDir: existingTestDir,
-});
-
-async function withdrawAndPay(
-  t: GlobalTestState,
-  wallet: WalletCli,
-  bank: BankService,
-  exchange: ExchangeService,
-  merchant: MerchantService,
-): Promise<void> {
-  await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:100" 
});
-
-  // Set up order.
-
-  const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {
-    order: {
-      summary: "Buy me!",
-      amount: "TESTKUDOS:80",
-      fulfillment_url: "taler://fulfillment-success/thx",
-    },
-  });
-
-  let orderStatus = await MerchantPrivateApi.queryPrivateOrderStatus(merchant, 
{
-    orderId: orderResp.order_id,
-  });
-
-  t.assertTrue(orderStatus.order_status === "unpaid");
-
-  // Make wallet pay for the order
-
-  const r1 = await wallet.apiRequest("preparePay", {
-    talerPayUri: orderStatus.taler_pay_uri,
-  });
-  t.assertTrue(r1.type === "response");
-
-  const r2 = await wallet.apiRequest("confirmPay", {
-    // FIXME: should be validated, don't cast!
-    proposalId: (r1.result as any).proposalId,
-  });
-  t.assertTrue(r2.type === "response");
-
-  // Check if payment was successful.
-
-  orderStatus = await MerchantPrivateApi.queryPrivateOrderStatus(merchant, {
-    orderId: orderResp.order_id,
-  });
-
-  t.assertTrue(orderStatus.order_status === "paid");
-}
-
-/**
- * Run test.
- */
-runTestWithState(prevT, async (t: GlobalTestState) => {
-  // Set up test environment
-
-  const bank = BankService.fromExistingConfig(t);
-  const exchange = ExchangeService.fromExistingConfig(t, "testexchange-1");
-  const merchant = MerchantService.fromExistingConfig(t, "testmerchant-1");
-
-  await bank.start();
-  await exchange.start();
-  await merchant.start();
-  await Promise.all([
-    bank.pingUntilAvailable(),
-    merchant.pingUntilAvailable(),
-    exchange.pingUntilAvailable(),
-  ]);
-
-  const wallet = new WalletCli(t);
-
-  // Withdraw digital cash into the wallet.
-
-  const repetitions = Number.parseInt(process.env["TALER_TEST_REPEAT"] ?? "1");
-
-  for (let rep = 0; rep < repetitions; rep++) {
-    console.log("repetition", rep);
-    try {
-      wallet.deleteDatabase();
-      await withdrawAndPay(t, wallet, bank, exchange, merchant);
-    } catch (e) {
-      console.log("ignoring exception", e);
-    }
-  }
-
-  await t.shutdown();
-});
diff --git a/packages/taler-integrationtests/testrunner 
b/packages/taler-integrationtests/testrunner
deleted file mode 100755
index c03f6ed9..00000000
--- a/packages/taler-integrationtests/testrunner
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env bash
-
-# Simple test runner for the wallet integration tests.
-#
-# Usage: $0 TESTGLOB
-#
-# The TESTGLOB can be used to select which test cases to execute
-
-set -eu
-
-exit_int() {
-  echo "Interrupted..."
-  exit 2
-}
-
-trap "exit_int" INT
-
-if [ "$#" -ne 1 ]; then
-    echo "Usage: $0 TESTGLOB"
-    exit 1
-fi
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-
-cd $DIR
-
-./node_modules/.bin/tsc -b
-
-export ESM_OPTIONS='{"sourceMap": true}'
-
-shopt -s extglob
-
-num_exec=0
-num_fail=0
-num_succ=0
-
-files_failed=''
-
-# Glob tests
-for file in lib/$1?(.js); do
-  case "$file" in
-    */test-*.js)
-      echo "executing test $file"
-      ret=0
-      node -r source-map-support/register -r esm $file || ret=$?
-      num_exec=$((num_exec+1))
-      case $ret in
-        0)
-          num_succ=$((num_succ+1))
-          ;;
-        *)
-          num_fail=$((num_fail+1))
-          files_failed=$files_failed:$file
-          ;;
-      esac
-      ;;
-    *)
-      continue
-    ;;
-  esac
-done
-
-echo "-----------------------------------"
-echo "Tests finished"
-echo "$num_succ/$num_exec tests succeeded"
-if [[ $num_fail != 0 ]]; then
-  echo "These tests failed:"
-  echo $files_failed | tr : \\n | sed '/^$/d'
-fi
-echo "-----------------------------------"
-
-if [[ $num_fail = 0 ]]; then
-  exit 0
-else
-  exit 1
-fi
-
diff --git a/packages/taler-integrationtests/tsconfig.json 
b/packages/taler-integrationtests/tsconfig.json
deleted file mode 100644
index 2fe0853d..00000000
--- a/packages/taler-integrationtests/tsconfig.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-  "compileOnSave": true,
-  "compilerOptions": {
-    "composite": true,
-    "declaration": true,
-    "declarationMap": false,
-    "target": "ES6",
-    "module": "ESNext",
-    "moduleResolution": "node",
-    "sourceMap": true,
-    "lib": ["es6"],
-    "types": ["node"],
-    "noImplicitReturns": true,
-    "noFallthroughCasesInSwitch": true,
-    "strict": true,
-    "strictPropertyInitialization": false,
-    "outDir": "lib",
-    "noImplicitAny": true,
-    "noImplicitThis": true,
-    "incremental": true,
-    "esModuleInterop": true,
-    "importHelpers": true,
-    "rootDir": "./src",
-    "typeRoots": ["./node_modules/@types"]
-  },
-  "references": [
-    {
-      "path": "../taler-wallet-core"
-    }
-  ],
-  "include": ["src/**/*"]
-}
diff --git a/packages/taler-wallet-cli/package.json 
b/packages/taler-wallet-cli/package.json
index 564cf7f4..c3fa6e79 100644
--- a/packages/taler-wallet-cli/package.json
+++ b/packages/taler-wallet-cli/package.json
@@ -43,7 +43,9 @@
     "typescript": "^4.0.5"
   },
   "dependencies": {
+    "@types/minimatch": "^3.0.3",
     "axios": "^0.21.0",
+    "minimatch": "^3.0.4",
     "source-map-support": "^0.5.19",
     "taler-wallet-core": "workspace:*",
     "tslib": "^2.0.3"
diff --git a/packages/taler-wallet-cli/src/index.ts 
b/packages/taler-wallet-cli/src/index.ts
index 87a51f30..e4f1ccb5 100644
--- a/packages/taler-wallet-cli/src/index.ts
+++ b/packages/taler-wallet-cli/src/index.ts
@@ -41,6 +41,7 @@ import {
 } from "taler-wallet-core";
 import * as clk from "./clk";
 import { deepStrictEqual } from "assert";
+import { getTestInfo, runTests } from "./integrationtests/testrunner";
 
 // This module also serves as the entry point for the crypto
 // thread worker, and thus must expose these two handlers.
@@ -749,6 +750,25 @@ const testCli = walletCli.subcommand("testingArgs", 
"testing", {
   help: "Subcommands for testing GNU Taler deployments.",
 });
 
+testCli
+  .subcommand("listIntegrationtests", "list-integrationtests")
+  .action(async (args) => {
+    for (const t of getTestInfo()) {
+      console.log(t.name);
+    }
+  });
+
+testCli
+  .subcommand("runIntegrationtests", "run-integrationtests")
+  .maybeArgument("pattern", clk.STRING, {
+    help: "Glob pattern to select which tests to run",
+  })
+  .action(async (args) => {
+    await runTests({
+      include_pattern: args.runIntegrationtests.pattern,
+    });
+  });
+
 testCli.subcommand("vectors", "vectors").action(async (args) => {
   printTestVectors();
 });
diff --git a/packages/taler-integrationtests/src/denomStructures.ts 
b/packages/taler-wallet-cli/src/integrationtests/denomStructures.ts
similarity index 100%
rename from packages/taler-integrationtests/src/denomStructures.ts
rename to packages/taler-wallet-cli/src/integrationtests/denomStructures.ts
diff --git a/packages/taler-integrationtests/src/faultInjection.ts 
b/packages/taler-wallet-cli/src/integrationtests/faultInjection.ts
similarity index 100%
rename from packages/taler-integrationtests/src/faultInjection.ts
rename to packages/taler-wallet-cli/src/integrationtests/faultInjection.ts
diff --git a/packages/taler-integrationtests/src/harness.ts 
b/packages/taler-wallet-cli/src/integrationtests/harness.ts
similarity index 95%
rename from packages/taler-integrationtests/src/harness.ts
rename to packages/taler-wallet-cli/src/integrationtests/harness.ts
index 58bcf2cf..108b7854 100644
--- a/packages/taler-integrationtests/src/harness.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/harness.ts
@@ -77,6 +77,7 @@ import {
   codecForPrepareTipResult,
   AcceptTipRequest,
   AbortPayWithRefundRequest,
+  handleWorkerError,
 } from "taler-wallet-core";
 import { URL } from "url";
 import axios, { AxiosError } from "axios";
@@ -93,6 +94,7 @@ import {
 import { ApplyRefundResponse } from "taler-wallet-core";
 import { PendingOperationsResponse } from "taler-wallet-core";
 import { CoinConfig } from "./denomStructures";
+import { after } from "taler-wallet-core/src/util/timer";
 
 const exec = util.promisify(require("child_process").exec);
 
@@ -236,11 +238,6 @@ export class GlobalTestState {
     this.testDir = params.testDir;
     this.procs = [];
     this.servers = [];
-
-    process.on("SIGINT", () => this.shutdownSync());
-    process.on("SIGTERM", () => this.shutdownSync());
-    process.on("unhandledRejection", () => this.shutdownSync());
-    process.on("uncaughtException", () => this.shutdownSync());
   }
 
   async assertThrowsOperationErrorAsync(
@@ -307,7 +304,7 @@ export class GlobalTestState {
     }
   }
 
-  private shutdownSync(): void {
+  shutdownSync(): void {
     for (const s of this.servers) {
       s.close();
       s.removeAllListeners();
@@ -315,12 +312,8 @@ export class GlobalTestState {
     for (const p of this.procs) {
       if (p.proc.exitCode == null) {
         p.proc.kill("SIGTERM");
-      } else {
       }
     }
-    console.log("*** test harness interrupted");
-    console.log("*** test state can be found under", this.testDir);
-    process.exit(1);
   }
 
   spawnService(
@@ -362,11 +355,6 @@ export class GlobalTestState {
     }
     this.inShutdown = true;
     console.log("shutting down");
-    if (shouldLingerAlways()) {
-      console.log("*** test finished, but requested to linger");
-      console.log("*** test state can be found under", this.testDir);
-      return;
-    }
     for (const s of this.servers) {
       s.close();
       s.removeAllListeners();
@@ -1047,7 +1035,7 @@ export class ExchangeService implements 
ExchangeServiceInterface {
     }
 
     const year = new Date().getFullYear();
-    for (let i = year; i < year+5; i++) {
+    for (let i = year; i < year + 5; i++) {
       await runCommand(
         this.globalState,
         "exchange-offline",
@@ -1438,76 +1426,57 @@ export interface MerchantInstanceConfig {
   defaultPayDelay?: Duration;
 }
 
-/**
- * Check if the test should hang around after it failed.
- */
-function shouldLinger(): boolean {
-  return (
-    process.env["TALER_TEST_LINGER"] == "1" ||
-    process.env["TALER_TEST_LINGER_ALWAYS"] == "1"
-  );
-}
+type TestStatus = "pass" | "fail" | "skip";
 
-/**
- * Check if the test should hang around even after it finished
- * successfully.
- */
-function shouldLingerAlways(): boolean {
-  return process.env["TALER_TEST_LINGER_ALWAYS"] == "1";
-}
+export interface TestRunResult {
+  /**
+   * Name of the test.
+   */
+  name: string;
 
-function updateCurrentSymlink(testDir: string): void {
-  const currLink = path.join(os.tmpdir(), "taler-integrationtest-current");
-  try {
-    fs.unlinkSync(currLink);
-  } catch (e) {
-    // Ignore
-  }
-  try {
-    fs.symlinkSync(testDir, currLink);
-  } catch (e) {
-    console.log(e);
-    // Ignore
-  }
+  /**
+   * How long did the test run?
+   */
+  timeSec: number;
+
+  status: TestStatus;
 }
 
-export function runTestWithState(
+export async function runTestWithState(
   gc: GlobalTestState,
   testMain: (t: GlobalTestState) => Promise<void>,
-) {
-  const main = async () => {
-    let ret = 0;
-    try {
-      updateCurrentSymlink(gc.testDir);
-      console.log("running test in directory", gc.testDir);
-      await testMain(gc);
-    } catch (e) {
-      console.error("FATAL: test failed with exception", e);
-      ret = 1;
-    } finally {
-      if (gc) {
-        if (shouldLinger()) {
-          console.log("test logs and config can be found under", gc.testDir);
-          console.log("keeping test environment running");
-        } else {
-          await gc.shutdown();
-          console.log("test logs and config can be found under", gc.testDir);
-          process.exit(ret);
-        }
-      }
-    }
+  testName: string,
+): Promise<TestRunResult> {
+  const startMs = new Date().getTime();
+
+  const handleSignal = () => {
+    gc.shutdownSync();
+    console.warn("**** received fatal signal, shutting down test harness");
+    process.exit(1);
   };
 
-  main();
-}
+  process.on("SIGINT", handleSignal);
+  process.on("SIGTERM", handleSignal);
+  process.on("unhandledRejection", handleSignal);
+  process.on("uncaughtException", handleSignal);
 
-export function runTest(
-  testMain: (gc: GlobalTestState) => Promise<void>,
-): void {
-  const gc = new GlobalTestState({
-    testDir: fs.mkdtempSync(path.join(os.tmpdir(), "taler-integrationtest-")),
-  });
-  runTestWithState(gc, testMain);
+  let status: TestStatus;
+  try {
+    console.log("running test in directory", gc.testDir);
+    await testMain(gc);
+    status = "pass";
+  } catch (e) {
+    console.error("FATAL: test failed with exception", e);
+    status = "fail";
+  } finally {
+    await gc.shutdown();
+  }
+  const afterMs = new Date().getTime();
+  return {
+    name: testName,
+    timeSec: (afterMs - startMs) / 1000,
+    status,
+  };
 }
 
 function shellWrap(s: string) {
diff --git a/packages/taler-integrationtests/src/helpers.ts 
b/packages/taler-wallet-cli/src/integrationtests/helpers.ts
similarity index 100%
rename from packages/taler-integrationtests/src/helpers.ts
rename to packages/taler-wallet-cli/src/integrationtests/helpers.ts
diff --git a/packages/taler-integrationtests/src/merchantApiTypes.ts 
b/packages/taler-wallet-cli/src/integrationtests/merchantApiTypes.ts
similarity index 100%
rename from packages/taler-integrationtests/src/merchantApiTypes.ts
rename to packages/taler-wallet-cli/src/integrationtests/merchantApiTypes.ts
diff --git a/packages/taler-integrationtests/src/scenario-prompt-payment.ts 
b/packages/taler-wallet-cli/src/integrationtests/scenario-prompt-payment.ts
similarity index 92%
rename from packages/taler-integrationtests/src/scenario-prompt-payment.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/scenario-prompt-payment.ts
index 3c34075d..e3c2af8e 100644
--- a/packages/taler-integrationtests/src/scenario-prompt-payment.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/scenario-prompt-payment.ts
@@ -17,13 +17,13 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPromptPaymentScenario(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -57,4 +57,4 @@ runTest(async (t: GlobalTestState) => {
 
   // Wait "forever"
   await new Promise(() => {});
-});
+}
diff --git a/packages/taler-integrationtests/src/test-bank-api.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-bank-api.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-bank-api.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-bank-api.ts
index 08991e27..b5cf6d5b 100644
--- a/packages/taler-integrationtests/src/test-bank-api.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-bank-api.ts
@@ -18,7 +18,6 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   WalletCli,
   ExchangeService,
@@ -35,7 +34,7 @@ import { defaultCoinConfig } from "./denomStructures";
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runBankApiTest(t: GlobalTestState) {
   // Set up test environment
 
   const db = await setupDb(t);
@@ -134,4 +133,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertTrue(
     balResp.balance.credit_debit_indicator === CreditDebitIndicator.Debit,
   );
-});
+}
diff --git a/packages/taler-integrationtests/src/test-claim-loop.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-claim-loop.ts
similarity index 97%
rename from packages/taler-integrationtests/src/test-claim-loop.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-claim-loop.ts
index 8c4df874..5a0540e9 100644
--- a/packages/taler-integrationtests/src/test-claim-loop.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-claim-loop.ts
@@ -18,10 +18,8 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   MerchantPrivateApi,
-  WalletCli,
 } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 import { URL } from "url";
@@ -32,7 +30,7 @@ import { URL } from "url";
  * FIXME: Is this test still necessary?  We initially wrote if to 
confirm/document
  * assumptions about how the merchant should work.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runClaimLoopTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -80,4 +78,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertTrue(orderStatusAfter.order_status === "claimed");
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-exchange-management.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-exchange-management.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-exchange-management.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-exchange-management.ts
index be990d9b..0fbef568 100644
--- a/packages/taler-integrationtests/src/test-exchange-management.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-exchange-management.ts
@@ -18,7 +18,6 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   WalletCli,
   setupDb,
@@ -43,7 +42,7 @@ import { defaultCoinConfig } from "./denomStructures";
 /**
  * Test if the wallet handles outdated exchange versions correct.y
  */
-runTest(async (t: GlobalTestState) => {
+export async function runExchangeManagementTest(t: GlobalTestState) {
   // Set up test environment
 
   const db = await setupDb(t);
@@ -247,4 +246,4 @@ runTest(async (t: GlobalTestState) => {
 
   // Make sure the faulty exchange isn't used for the suggestion.
   t.assertTrue(wd.possibleExchanges.length === 0);
-});
+}
diff --git a/packages/taler-integrationtests/src/test-fee-regression.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-fee-regression.ts
similarity index 97%
rename from packages/taler-integrationtests/src/test-fee-regression.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-fee-regression.ts
index 7b3193df..c56fe7ab 100644
--- a/packages/taler-integrationtests/src/test-fee-regression.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-fee-regression.ts
@@ -17,9 +17,7 @@
 /**
  * Imports.
  */
-import { defaultCoinConfig } from "./denomStructures";
 import {
-  runTest,
   GlobalTestState,
   BankService,
   ExchangeService,
@@ -166,7 +164,7 @@ export async function createMyTestkudosEnvironment(
 /**
  * Run test for basic, bank-integrated withdrawal and payment.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runFeeRegressionTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -203,4 +201,4 @@ runTest(async (t: GlobalTestState) => {
   const txs = await wallet.getTransactions();
   t.assertAmountEquals(txs.transactions[1].amountEffective, "TESTKUDOS:1.30");
   console.log(txs);
-});
+}
diff --git a/packages/taler-integrationtests/src/test-merchant-longpolling.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-merchant-longpolling.ts
similarity index 96%
rename from packages/taler-integrationtests/src/test-merchant-longpolling.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-merchant-longpolling.ts
index 5189d247..7ceccbf6 100644
--- a/packages/taler-integrationtests/src/test-merchant-longpolling.ts
+++ 
b/packages/taler-wallet-cli/src/integrationtests/test-merchant-longpolling.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 import {
   PreparePayResultType,
@@ -30,7 +30,7 @@ import axios from "axios";
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runMerchantLongpollingTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -129,4 +129,4 @@ runTest(async (t: GlobalTestState) => {
   });
 
   t.assertTrue(confirmPayRes.type === ConfirmPayResultType.Done);
-});
+}
diff --git a/packages/taler-integrationtests/src/test-merchant-refund-api.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-merchant-refund-api.ts
similarity index 99%
rename from packages/taler-integrationtests/src/test-merchant-refund-api.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-merchant-refund-api.ts
index 121c571d..27cf34b5 100644
--- a/packages/taler-integrationtests/src/test-merchant-refund-api.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-merchant-refund-api.ts
@@ -18,10 +18,8 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   MerchantPrivateApi,
-  MerchantService,
   BankServiceInterface,
   MerchantServiceInterface,
   WalletCli,
@@ -256,7 +254,7 @@ async function testRefundApiWithFulfillmentMessage(
 /**
  * Test case for the refund API of the merchant backend.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runMerchantRefundApiTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -283,4 +281,4 @@ runTest(async (t: GlobalTestState) => {
     exchange,
     merchant,
   });
-});
+}
diff --git a/packages/taler-integrationtests/src/test-pay-abort.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-pay-abort.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-pay-abort.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-pay-abort.ts
index 56650009..4fd6edc9 100644
--- a/packages/taler-integrationtests/src/test-pay-abort.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-pay-abort.ts
@@ -23,7 +23,6 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   MerchantService,
   ExchangeService,
@@ -31,8 +30,6 @@ import {
   BankService,
   WalletCli,
   MerchantPrivateApi,
-  BankApi,
-  BankAccessApi,
 } from "./harness";
 import {
   FaultInjectedExchangeService,
@@ -46,7 +43,7 @@ import { withdrawViaBank, makeTestPayment } from "./helpers";
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPayAbortTest(t: GlobalTestState) {
   // Set up test environment
 
   const db = await setupDb(t);
@@ -199,4 +196,4 @@ runTest(async (t: GlobalTestState) => {
   const txTypes = txr.transactions.map((x) => x.type);
 
   t.assertDeepEqual(txTypes, ["withdrawal", "payment", "refund"]);
-});
+}
diff --git a/packages/taler-integrationtests/src/test-pay-paid.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-pay-paid.ts
similarity index 97%
rename from packages/taler-integrationtests/src/test-pay-paid.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-pay-paid.ts
index 40f7d014..4d270660 100644
--- a/packages/taler-integrationtests/src/test-pay-paid.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-pay-paid.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import {
   withdrawViaBank,
   createFaultInjectedMerchantTestkudosEnvironment,
@@ -39,7 +39,7 @@ import { FaultInjectionRequestContext } from 
"./faultInjection";
  * since we can't initiate payment via a "claimed" private order status
  * response.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPayPaidTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -203,4 +203,4 @@ runTest(async (t: GlobalTestState) => {
   // Make sure the wallet is actually doing the replay properly.
   t.assertTrue(numPaidRequested == 1);
   t.assertTrue(numPayRequested == 0);
-});
+}
diff --git a/packages/taler-integrationtests/src/test-payment-claim.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-payment-claim.ts
similarity index 95%
rename from packages/taler-integrationtests/src/test-payment-claim.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-payment-claim.ts
index 6aed7e9e..ee8a8e49 100644
--- a/packages/taler-integrationtests/src/test-payment-claim.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-payment-claim.ts
@@ -17,19 +17,14 @@
 /**
  * Imports.
  */
-import {
-  runTest,
-  GlobalTestState,
-  MerchantPrivateApi,
-  WalletCli,
-} from "./harness";
+import { GlobalTestState, MerchantPrivateApi, WalletCli } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 import { PreparePayResultType, TalerErrorCode } from "taler-wallet-core";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPaymentClaimTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -106,4 +101,4 @@ runTest(async (t: GlobalTestState) => {
   );
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-payment-fault.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-payment-fault.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-payment-fault.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-payment-fault.ts
index ca31e8ee..55609f3f 100644
--- a/packages/taler-integrationtests/src/test-payment-fault.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-payment-fault.ts
@@ -22,7 +22,6 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   MerchantService,
   ExchangeService,
@@ -44,7 +43,7 @@ import { defaultCoinConfig } from "./denomStructures";
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPaymentFaultTest(t: GlobalTestState) {
   // Set up test environment
 
   const db = await setupDb(t);
@@ -207,4 +206,4 @@ runTest(async (t: GlobalTestState) => {
   });
 
   t.assertTrue(orderStatus.order_status === "paid");
-});
+}
diff --git a/packages/taler-integrationtests/src/test-payment-idempotency.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-payment-idempotency.ts
similarity index 95%
rename from packages/taler-integrationtests/src/test-payment-idempotency.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-payment-idempotency.ts
index 85be04d5..4323a7c9 100644
--- a/packages/taler-integrationtests/src/test-payment-idempotency.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-payment-idempotency.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 import { PreparePayResultType } from "taler-wallet-core";
 
@@ -25,7 +25,7 @@ import { PreparePayResultType } from "taler-wallet-core";
  * Test the wallet-core payment API, especially that repeated operations
  * return the expected result.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPaymentIdempotencyTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -100,4 +100,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertTrue(preparePayResultAfter.paid === true);
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-payment-multiple.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-payment-multiple.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-payment-multiple.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-payment-multiple.ts
index c6a0868a..6d05df33 100644
--- a/packages/taler-integrationtests/src/test-payment-multiple.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-payment-multiple.ts
@@ -18,7 +18,6 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   setupDb,
   BankService,
@@ -109,7 +108,7 @@ async function setupTest(
  *
  * This test uses a very sub-optimal denomination structure.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPaymentMultipleTest(t: GlobalTestState) {
   // Set up test environment
 
   const { merchant, bank, exchange } = await setupTest(t);
@@ -158,4 +157,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertTrue(orderStatus.order_status === "paid");
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-payment-transient.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-payment-transient.ts
similarity index 97%
rename from packages/taler-integrationtests/src/test-payment-transient.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-payment-transient.ts
index dc7ebbb1..73973bdc 100644
--- a/packages/taler-integrationtests/src/test-payment-transient.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-payment-transient.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import {
   withdrawViaBank,
   createFaultInjectedMerchantTestkudosEnvironment,
@@ -41,7 +41,7 @@ import {
  * Run test for a payment where the merchant has a transient
  * failure in /pay
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPaymentTransientTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -169,4 +169,4 @@ runTest(async (t: GlobalTestState) => {
       `expected status 202 (after paying), but got 
${publicOrderStatusResp.status}`,
     );
   }
-});
+}
\ No newline at end of file
diff --git a/packages/taler-integrationtests/src/test-payment.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-payment.ts
similarity index 92%
rename from packages/taler-integrationtests/src/test-payment.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-payment.ts
index 8a1240da..68713fd9 100644
--- a/packages/taler-integrationtests/src/test-payment.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-payment.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState } from "./harness";
+import { GlobalTestState } from "./harness";
 import {
   createSimpleTestkudosEnvironment,
   withdrawViaBank,
@@ -27,7 +27,7 @@ import {
 /**
  * Run test for basic, bank-integrated withdrawal and payment.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPaymentTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -50,4 +50,4 @@ runTest(async (t: GlobalTestState) => {
   await makeTestPayment(t, { wallet, merchant, order });
 
   await wallet.runUntilDone();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-paywall-flow.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-paywall-flow.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-paywall-flow.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-paywall-flow.ts
index 54c8ab46..5eeb7d27 100644
--- a/packages/taler-integrationtests/src/test-paywall-flow.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-paywall-flow.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 import {
   PreparePayResultType,
@@ -29,7 +29,7 @@ import axios from "axios";
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runPaywallFlowTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -230,4 +230,4 @@ runTest(async (t: GlobalTestState) => {
   console.log(publicOrderStatusResp.data);
 
   t.assertTrue(pubUnpaidStatus.already_paid_order_id === firstOrderId);
-});
+}
diff --git a/packages/taler-integrationtests/src/test-refund-auto.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-refund-auto.ts
similarity index 93%
rename from packages/taler-integrationtests/src/test-refund-auto.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-refund-auto.ts
index 1a7055fd..afac993b 100644
--- a/packages/taler-integrationtests/src/test-refund-auto.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-refund-auto.ts
@@ -17,14 +17,14 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
-import { CoreApiResponse, durationFromSpec } from "taler-wallet-core";
+import { durationFromSpec } from "taler-wallet-core";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runRefundAutoTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -97,4 +97,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertDeepEqual(transactionTypes, ["withdrawal", "payment", "refund"]);
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-refund-gone.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-refund-gone.ts
similarity index 96%
rename from packages/taler-integrationtests/src/test-refund-gone.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-refund-gone.ts
index 764d5c28..483e9e06 100644
--- a/packages/taler-integrationtests/src/test-refund-gone.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-refund-gone.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import {
   createSimpleTestkudosEnvironment,
   withdrawViaBank,
@@ -33,7 +33,7 @@ import {
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runRefundGoneTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -124,4 +124,4 @@ runTest(async (t: GlobalTestState) => {
   console.log(JSON.stringify(r, undefined, 2));
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-refund-incremental.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-refund-incremental.ts
similarity index 97%
rename from packages/taler-integrationtests/src/test-refund-incremental.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-refund-incremental.ts
index 7ad406da..d90a4b5f 100644
--- a/packages/taler-integrationtests/src/test-refund-incremental.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-refund-incremental.ts
@@ -17,19 +17,14 @@
 /**
  * Imports.
  */
-import {
-  runTest,
-  GlobalTestState,
-  delayMs,
-  MerchantPrivateApi,
-} from "./harness";
+import { GlobalTestState, delayMs, MerchantPrivateApi } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 import { TransactionType, Amounts, durationFromSpec } from "taler-wallet-core";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runRefundIncrementalTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -188,4 +183,4 @@ runTest(async (t: GlobalTestState) => {
   }
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-refund.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-refund.ts
similarity index 95%
rename from packages/taler-integrationtests/src/test-refund.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-refund.ts
index 90813651..12e6b178 100644
--- a/packages/taler-integrationtests/src/test-refund.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-refund.ts
@@ -18,13 +18,13 @@
  * Imports.
  */
 import { durationFromSpec } from "taler-wallet-core";
-import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
+import { GlobalTestState, MerchantPrivateApi } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runRefundTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -100,4 +100,4 @@ runTest(async (t: GlobalTestState) => {
   console.log(JSON.stringify(r, undefined, 2));
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-revocation.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-revocation.ts
similarity index 97%
rename from packages/taler-integrationtests/src/test-revocation.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-revocation.ts
index 32cb5d62..ac989855 100644
--- a/packages/taler-integrationtests/src/test-revocation.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-revocation.ts
@@ -18,9 +18,7 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
-  MerchantPrivateApi,
   ExchangeService,
   MerchantService,
   WalletCli,
@@ -63,7 +61,7 @@ async function revokeAllWalletCoins(req: {
 /**
  * Basic time travel test.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runRevocationTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -119,4 +117,4 @@ runTest(async (t: GlobalTestState) => {
   }
 
   await makeTestPayment(t, { wallet, merchant, order });
-});
+}
diff --git a/packages/taler-integrationtests/src/test-timetravel-autorefresh.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-timetravel-autorefresh.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-timetravel-autorefresh.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-timetravel-autorefresh.ts
index 382051c8..747f6d75 100644
--- a/packages/taler-integrationtests/src/test-timetravel-autorefresh.ts
+++ 
b/packages/taler-wallet-cli/src/integrationtests/test-timetravel-autorefresh.ts
@@ -31,7 +31,6 @@ import {
   GlobalTestState,
   MerchantPrivateApi,
   MerchantService,
-  runTest,
   setupDb,
   WalletCli,
 } from "./harness";
@@ -67,7 +66,7 @@ async function applyTimeTravel(
 /**
  * Basic time travel test.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runTimetravelAutorefreshTest(t: GlobalTestState) {
   // Set up test environment
 
   const db = await setupDb(t);
@@ -201,4 +200,4 @@ runTest(async (t: GlobalTestState) => {
   });
 
   t.assertTrue(cpr.type === ConfirmPayResultType.Done);
-});
+}
diff --git a/packages/taler-integrationtests/src/test-timetravel-withdraw.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-timetravel-withdraw.ts
similarity index 95%
rename from packages/taler-integrationtests/src/test-timetravel-withdraw.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-timetravel-withdraw.ts
index e0124d46..b4de50b9 100644
--- a/packages/taler-integrationtests/src/test-timetravel-withdraw.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-timetravel-withdraw.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState } from "./harness";
+import { GlobalTestState } from "./harness";
 import {
   createSimpleTestkudosEnvironment,
   withdrawViaBank,
@@ -28,7 +28,7 @@ import { Duration, TransactionType } from "taler-wallet-core";
 /**
  * Basic time travel test.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runTimetravelWithdrawTest(t: GlobalTestState){
   // Set up test environment
 
   const {
@@ -87,4 +87,4 @@ runTest(async (t: GlobalTestState) => {
   // This doesn't work yet, see https://bugs.taler.net/n/6585
 
   // await wallet.runUntilDone({ maxRetries: 5 });
-});
+}
\ No newline at end of file
diff --git a/packages/taler-integrationtests/src/test-tipping.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-tipping.ts
similarity index 98%
rename from packages/taler-integrationtests/src/test-tipping.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-tipping.ts
index 4735de81..01ec6c1b 100644
--- a/packages/taler-integrationtests/src/test-tipping.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-tipping.ts
@@ -18,7 +18,6 @@
  * Imports.
  */
 import {
-  runTest,
   GlobalTestState,
   MerchantPrivateApi,
   BankApi,
@@ -28,7 +27,7 @@ import { createSimpleTestkudosEnvironment, withdrawViaBank } 
from "./helpers";
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runTippingTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -125,4 +124,4 @@ runTest(async (t: GlobalTestState) => {
   // Check twice so make sure tip handling is idempotent
   await doTip();
   await doTip();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-wallettesting.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-wallettesting.ts
similarity index 95%
rename from packages/taler-integrationtests/src/test-wallettesting.ts
rename to packages/taler-wallet-cli/src/integrationtests/test-wallettesting.ts
index a6014a88..cdb95485 100644
--- a/packages/taler-integrationtests/src/test-wallettesting.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-wallettesting.ts
@@ -22,13 +22,13 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState } from "./harness";
+import { GlobalTestState } from "./harness";
 import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runWallettestingTest(t: GlobalTestState) {
   const {
     wallet,
     bank,
@@ -84,4 +84,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertDeepEqual(txTypes, ["withdrawal", "payment"]);
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-withdrawal-abort-bank.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-abort-bank.ts
similarity index 92%
rename from packages/taler-integrationtests/src/test-withdrawal-abort-bank.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-withdrawal-abort-bank.ts
index dd848b93..9a4e6004 100644
--- a/packages/taler-integrationtests/src/test-withdrawal-abort-bank.ts
+++ 
b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-abort-bank.ts
@@ -17,14 +17,14 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, BankApi, BankAccessApi } from "./harness";
+import { GlobalTestState, BankApi, BankAccessApi } from "./harness";
 import { createSimpleTestkudosEnvironment } from "./helpers";
 import { codecForBalancesResponse, TalerErrorCode } from "taler-wallet-core";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runWithdrawalAbortBankTest(t: GlobalTestState) {
   // Set up test environment
 
   const { wallet, bank, exchange } = await createSimpleTestkudosEnvironment(t);
@@ -64,4 +64,4 @@ runTest(async (t: GlobalTestState) => {
   );
 
   await t.shutdown();
-});
+}
diff --git 
a/packages/taler-integrationtests/src/test-withdrawal-bank-integrated.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-bank-integrated.ts
similarity index 93%
rename from 
packages/taler-integrationtests/src/test-withdrawal-bank-integrated.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-withdrawal-bank-integrated.ts
index d54309b3..89f5104a 100644
--- a/packages/taler-integrationtests/src/test-withdrawal-bank-integrated.ts
+++ 
b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-bank-integrated.ts
@@ -17,14 +17,14 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, BankApi, BankAccessApi } from "./harness";
+import { GlobalTestState, BankApi, BankAccessApi } from "./harness";
 import { createSimpleTestkudosEnvironment } from "./helpers";
 import { codecForBalancesResponse } from "taler-wallet-core";
 
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runWithdrawalBankIntegratedTest(t: GlobalTestState) {
   // Set up test environment
 
   const { wallet, bank, exchange } = await createSimpleTestkudosEnvironment(t);
@@ -68,4 +68,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertAmountEquals("TESTKUDOS:9.72", balResp.balances[0].available);
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-integrationtests/src/test-withdrawal-manual.ts 
b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-manual.ts
similarity index 94%
rename from packages/taler-integrationtests/src/test-withdrawal-manual.ts
rename to 
packages/taler-wallet-cli/src/integrationtests/test-withdrawal-manual.ts
index aeac74d9..ef0db4a1 100644
--- a/packages/taler-integrationtests/src/test-withdrawal-manual.ts
+++ b/packages/taler-wallet-cli/src/integrationtests/test-withdrawal-manual.ts
@@ -17,7 +17,7 @@
 /**
  * Imports.
  */
-import { runTest, GlobalTestState, BankApi } from "./harness";
+import { GlobalTestState, BankApi } from "./harness";
 import { createSimpleTestkudosEnvironment } from "./helpers";
 import { CoreApiResponse } from "taler-wallet-core";
 import { codecForBalancesResponse } from "taler-wallet-core";
@@ -25,7 +25,7 @@ import { codecForBalancesResponse } from "taler-wallet-core";
 /**
  * Run test for basic, bank-integrated withdrawal.
  */
-runTest(async (t: GlobalTestState) => {
+export async function runTestWithdrawalManualTest(t: GlobalTestState) {
   // Set up test environment
 
   const {
@@ -75,4 +75,4 @@ runTest(async (t: GlobalTestState) => {
   t.assertAmountEquals("TESTKUDOS:9.72", balResp.balances[0].available);
 
   await t.shutdown();
-});
+}
diff --git a/packages/taler-wallet-cli/src/integrationtests/testrunner.ts 
b/packages/taler-wallet-cli/src/integrationtests/testrunner.ts
new file mode 100644
index 00000000..d9804562
--- /dev/null
+++ b/packages/taler-wallet-cli/src/integrationtests/testrunner.ts
@@ -0,0 +1,176 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+import { GlobalTestState, runTestWithState, TestRunResult } from "./harness";
+import { runPaymentTest } from "./test-payment";
+import * as fs from "fs";
+import * as path from "path";
+import * as os from "os";
+import { runBankApiTest } from "./test-bank-api";
+import { runClaimLoopTest } from "./test-claim-loop";
+import { runExchangeManagementTest } from "./test-exchange-management";
+import { runFeeRegressionTest } from "./test-fee-regression";
+import { runMerchantLongpollingTest } from "./test-merchant-longpolling";
+import { runMerchantRefundApiTest } from "./test-merchant-refund-api";
+import { runPayAbortTest } from "./test-pay-abort";
+import { runPayPaidTest } from "./test-pay-paid";
+import { runPaymentClaimTest } from "./test-payment-claim";
+import { runPaymentFaultTest } from "./test-payment-fault";
+import { runPaymentIdempotencyTest } from "./test-payment-idempotency";
+import { runPaymentMultipleTest } from "./test-payment-multiple";
+import { runPaymentTransientTest } from "./test-payment-transient";
+import { runPaywallFlowTest } from "./test-paywall-flow";
+import { runRefundAutoTest } from "./test-refund-auto";
+import { runRefundGoneTest } from "./test-refund-gone";
+import { runRefundIncrementalTest } from "./test-refund-incremental";
+import { runRefundTest } from "./test-refund";
+import { runRevocationTest } from "./test-revocation";
+import { runTimetravelAutorefreshTest } from "./test-timetravel-autorefresh";
+import { runTimetravelWithdrawTest } from "./test-timetravel-withdraw";
+import { runTippingTest } from "./test-tipping";
+import { runWallettestingTest } from "./test-wallettesting";
+import { runTestWithdrawalManualTest } from "./test-withdrawal-manual";
+import { runWithdrawalAbortBankTest } from "./test-withdrawal-abort-bank";
+import { runWithdrawalBankIntegratedTest } from 
"./test-withdrawal-bank-integrated";
+import M from "minimatch";
+
+/**
+ * Test runner.
+ */
+
+/**
+ * Spec for one test.
+ */
+interface TestMainFunction {
+  (t: GlobalTestState): Promise<void>;
+}
+
+const allTests: TestMainFunction[] = [
+  runBankApiTest,
+  runClaimLoopTest,
+  runExchangeManagementTest,
+  runFeeRegressionTest,
+  runMerchantLongpollingTest,
+  runMerchantRefundApiTest,
+  runPayAbortTest,
+  runPayPaidTest,
+  runPaymentClaimTest,
+  runPaymentFaultTest,
+  runPaymentIdempotencyTest,
+  runPaymentMultipleTest,
+  runPaymentTransientTest,
+  runPaywallFlowTest,
+  runRefundAutoTest,
+  runRefundGoneTest,
+  runRefundIncrementalTest,
+  runRefundTest,
+  runRevocationTest,
+  runTimetravelAutorefreshTest,
+  runTimetravelWithdrawTest,
+  runTippingTest,
+  runWallettestingTest,
+  runWithdrawalAbortBankTest,
+  runWithdrawalBankIntegratedTest,
+  runWallettestingTest,
+  runPaymentTest,
+];
+
+export interface TestRunSpec {
+  include_pattern?: string;
+}
+
+export interface TestInfo {
+  name: string;
+}
+
+function updateCurrentSymlink(testDir: string): void {
+  const currLink = path.join(os.tmpdir(), "taler-integrationtests-current");
+  try {
+    fs.unlinkSync(currLink);
+  } catch (e) {
+    // Ignore
+  }
+  try {
+    fs.symlinkSync(testDir, currLink);
+  } catch (e) {
+    console.log(e);
+    // Ignore
+  }
+}
+
+export function getTestName(tf: TestMainFunction): string {
+  const res = tf.name.match(/run([a-zA-Z0-9]*)Test/);
+  if (!res) {
+    throw Error("invalid test name, must be 'run${NAME}Test'");
+  }
+  return res[1]
+    .replace(/[a-z0-9][A-Z]/, (x) => {
+      return x[0] + "-" + x[1];
+    })
+    .toLowerCase();
+}
+
+export async function runTests(spec: TestRunSpec) {
+  const testRootDir = fs.mkdtempSync(
+    path.join(os.tmpdir(), "taler-integrationtests-"),
+  );
+  updateCurrentSymlink(testRootDir);
+  console.log("testsuite root directory: ", testRootDir);
+
+  let numTotal = 0;
+  let numFail = 0;
+  let numSkip = 0;
+  let numPass = 0;
+
+  const testResults: TestRunResult[] = [];
+
+  for (const [n, testCase] of allTests.entries()) {
+    const testName = getTestName(testCase);
+    if (spec.include_pattern && !M(testName, spec.include_pattern)) {
+      continue;
+    }
+    const testDir = path.join(testRootDir, testName);
+    fs.mkdirSync(testDir);
+    console.log(`running test ${testName}`);
+    const gc = new GlobalTestState({
+      testDir,
+    });
+    const result = await runTestWithState(gc, testCase, testName);
+    testResults.push(result);
+    console.log(result);
+    numTotal++;
+    if (result.status === "fail") {
+      numFail++;
+    } else if (result.status === "skip") {
+      numSkip++;
+    } else if (result.status === "pass") {
+      numPass++;
+    }
+  }
+  const resultsFile = path.join(testRootDir, "results.json");
+  fs.writeFileSync(
+    path.join(testRootDir, "results.json"),
+    JSON.stringify({ testResults }, undefined, 2),
+  );
+  console.log(`See ${resultsFile} for details`);
+  console.log(`Passed: ${numPass}/${numTotal}`);
+}
+
+export function getTestInfo(): TestInfo[] {
+  return allTests.map((x) => ({
+    name: getTestName(x),
+  }));
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a81089d8..9c3dcaac 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -34,7 +34,7 @@ importers:
   packages/taler-integrationtests:
     dependencies:
       axios: 0.21.0
-      taler-wallet-core: 'link:../taler-wallet-core'
+      taler-wallet-core: link:../taler-wallet-core
       tslib: 2.0.3
     devDependencies:
       esm: 3.2.25
@@ -49,13 +49,13 @@ importers:
       nyc: ^15.1.0
       prettier: ^2.1.2
       source-map-support: ^0.5.19
-      taler-wallet-core: 'workspace:*'
+      taler-wallet-core: workspace:*
       ts-node: ^9.0.0
       tslib: ^2.0.3
       typescript: ^4.0.5
   packages/taler-wallet-android:
     dependencies:
-      taler-wallet-core: 'link:../taler-wallet-core'
+      taler-wallet-core: link:../taler-wallet-core
       tslib: 2.0.3
     devDependencies:
       '@rollup/plugin-commonjs': 16.0.0_rollup@2.33.2
@@ -80,14 +80,16 @@ importers:
       rollup: ^2.33.2
       rollup-plugin-sourcemaps: ^0.6.3
       rollup-plugin-terser: ^7.0.2
-      taler-wallet-core: 'workspace:*'
+      taler-wallet-core: workspace:*
       tslib: ^2.0.3
       typescript: ^4.0.5
   packages/taler-wallet-cli:
     dependencies:
+      '@types/minimatch': 3.0.3
       axios: 0.21.0
+      minimatch: 3.0.4
       source-map-support: 0.5.19
-      taler-wallet-core: 'link:../taler-wallet-core'
+      taler-wallet-core: link:../taler-wallet-core
       tslib: 2.0.3
     devDependencies:
       '@rollup/plugin-commonjs': 16.0.0_rollup@2.33.2
@@ -107,15 +109,17 @@ importers:
       '@rollup/plugin-json': ^4.1.0
       '@rollup/plugin-node-resolve': ^10.0.0
       '@rollup/plugin-replace': ^2.3.4
+      '@types/minimatch': ^3.0.3
       '@types/node': ^14.14.7
       axios: ^0.21.0
+      minimatch: ^3.0.4
       prettier: ^2.1.2
       rimraf: ^3.0.2
       rollup: ^2.33.2
       rollup-plugin-sourcemaps: ^0.6.3
       rollup-plugin-terser: ^7.0.2
       source-map-support: ^0.5.19
-      taler-wallet-core: 'workspace:*'
+      taler-wallet-core: workspace:*
       tslib: ^2.0.3
       typedoc: ^0.19.2
       typescript: ^4.0.5
@@ -125,7 +129,7 @@ importers:
       axios: 0.21.0
       big-integer: 1.6.48
       fflate: 0.3.10
-      idb-bridge: 'link:../idb-bridge'
+      idb-bridge: link:../idb-bridge
       source-map-support: 0.5.19
       tslib: 2.0.3
     devDependencies:
@@ -144,7 +148,7 @@ importers:
       jed: 1.1.1
       nyc: 15.1.0
       po2json: 0.4.5
-      pogen: 'link:../pogen'
+      pogen: link:../pogen
       prettier: 2.1.2
       rimraf: 3.0.2
       rollup: 2.33.2
@@ -169,11 +173,11 @@ importers:
       eslint-plugin-react-hooks: ^4.2.0
       esm: ^3.2.25
       fflate: ^0.3.10
-      idb-bridge: 'workspace:*'
+      idb-bridge: workspace:*
       jed: ^1.1.1
       nyc: ^15.1.0
       po2json: ^0.4.5
-      pogen: 'workspace:*'
+      pogen: workspace:*
       prettier: ^2.1.2
       rimraf: ^3.0.2
       rollup: ^2.33.2
@@ -186,7 +190,7 @@ importers:
   packages/taler-wallet-webextension:
     dependencies:
       moment: 2.29.1
-      taler-wallet-core: 'link:../taler-wallet-core'
+      taler-wallet-core: link:../taler-wallet-core
       tslib: 2.0.3
     devDependencies:
       '@rollup/plugin-commonjs': 16.0.0_rollup@2.33.2
@@ -232,7 +236,7 @@ importers:
       rollup-plugin-ignore: ^1.0.9
       rollup-plugin-sourcemaps: ^0.6.3
       rollup-plugin-terser: ^7.0.2
-      taler-wallet-core: 'workspace:*'
+      taler-wallet-core: workspace:*
       tslib: ^2.0.3
       typescript: ^4.0.5
 lockfileVersion: 5.2
@@ -684,6 +688,10 @@ packages:
     dev: true
     resolution:
       integrity: sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
+  /@types/minimatch/3.0.3:
+    dev: false
+    resolution:
+      integrity: 
sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
   /@types/node/10.17.13:
     dev: true
     resolution:
@@ -1222,7 +1230,6 @@ packages:
     resolution:
       integrity: 
sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==
   /balanced-match/1.0.0:
-    dev: true
     resolution:
       integrity: sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
   /big-integer/1.6.48:
@@ -1264,7 +1271,6 @@ packages:
     dependencies:
       balanced-match: 1.0.0
       concat-map: 0.0.1
-    dev: true
     resolution:
       integrity: 
sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
   /braces/3.0.2:
@@ -1525,7 +1531,6 @@ packages:
     resolution:
       integrity: sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
   /concat-map/0.0.1:
-    dev: true
     resolution:
       integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
   /concordance/5.0.1:
@@ -3431,7 +3436,6 @@ packages:
   /minimatch/3.0.4:
     dependencies:
       brace-expansion: 1.1.11
-    dev: true
     resolution:
       integrity: 
sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
   /minimist/1.2.5:
diff --git a/tsconfig.build.json b/tsconfig.build.json
index 6755b8e8..6db804a3 100644
--- a/tsconfig.build.json
+++ b/tsconfig.build.json
@@ -1,7 +1,7 @@
 {
   "compileOnSave": true,
   "compilerOptions": {
-    "composite": true,
+    "composite": true
   },
   "references": [
     {
@@ -10,9 +10,6 @@
     {
       "path": "packages/taler-wallet-core/"
     },
-    {
-      "path": "packages/taler-integrationtests"
-    },
     {
       "path": "packages/taler-wallet-cli"
     }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]