summaryrefslogtreecommitdiff
path: root/packages/taler-harness/src/bench1.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-harness/src/bench1.ts')
-rw-r--r--packages/taler-harness/src/bench1.ts185
1 files changed, 185 insertions, 0 deletions
diff --git a/packages/taler-harness/src/bench1.ts b/packages/taler-harness/src/bench1.ts
new file mode 100644
index 000000000..d260ea731
--- /dev/null
+++ b/packages/taler-harness/src/bench1.ts
@@ -0,0 +1,185 @@
+/*
+ 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/>
+ */
+
+/**
+ * Imports.
+ */
+import {
+ AmountString,
+ buildCodecForObject,
+ codecForBoolean,
+ codecForNumber,
+ codecForString,
+ codecOptional,
+ j2s,
+ Logger,
+} from "@gnu-taler/taler-util";
+import {
+ AccessStats,
+ createNativeWalletHost2,
+ Wallet,
+ WalletApiOperation,
+} from "@gnu-taler/taler-wallet-core";
+import { harnessHttpLib } from "./harness/harness.js";
+
+/**
+ * Entry point for the benchmark.
+ *
+ * The benchmark runs against an existing Taler deployment and does not
+ * set up its own services.
+ */
+export async function runBench1(configJson: any): Promise<void> {
+ const logger = new Logger("Bench1");
+
+ // Validate the configuration file for this benchmark.
+ const b1conf = codecForBench1Config().decode(configJson);
+
+ const numIter = b1conf.iterations ?? 1;
+ const numDeposits = b1conf.deposits ?? 5;
+ const restartWallet = b1conf.restartAfter ?? 20;
+
+ const withdrawOnly = b1conf.withdrawOnly ?? false;
+ const withdrawAmount = (numDeposits + 1) * 10;
+
+ logger.info(
+ `Starting Benchmark iterations=${numIter} deposits=${numDeposits}`,
+ );
+
+ const trustExchange = !!process.env["TALER_WALLET_INSECURE_TRUST_EXCHANGE"];
+ if (trustExchange) {
+ logger.info("trusting exchange (not validating signatures)");
+ } else {
+ logger.info("not trusting exchange (validating signatures)");
+ }
+
+ let wallet = {} as Wallet;
+ let getDbStats: () => AccessStats;
+
+ for (let i = 0; i < numIter; i++) {
+ // Create a new wallet in each iteration
+ // otherwise the TPS go down
+ // my assumption is that the in-memory db file gets too large
+ if (i % restartWallet == 0) {
+ if (Object.keys(wallet).length !== 0) {
+ await wallet.client.call(WalletApiOperation.Shutdown, {});
+ console.log("wallet DB stats", j2s(getDbStats!()));
+ }
+
+ const res = await createNativeWalletHost2({
+ // No persistent DB storage.
+ persistentStoragePath: undefined,
+ httpLib: harnessHttpLib,
+ });
+ wallet = res.wallet;
+ getDbStats = res.getDbStats;
+ await wallet.client.call(WalletApiOperation.InitWallet, {
+ config: {
+ testing: {
+ insecureTrustExchange: trustExchange,
+ },
+ features: {},
+ },
+ });
+ }
+
+ logger.trace(`Starting withdrawal amount=${withdrawAmount}`);
+ let start = Date.now();
+
+ await wallet.client.call(WalletApiOperation.WithdrawTestBalance, {
+ amount: (b1conf.currency + ":" + withdrawAmount) as AmountString,
+ corebankApiBaseUrl: b1conf.bank,
+ exchangeBaseUrl: b1conf.exchange,
+ });
+
+ await wallet.client.call(WalletApiOperation.TestingWaitTasksDone, {});
+
+ logger.info(
+ `Finished withdrawal amount=${withdrawAmount} time=${Date.now() - start}`,
+ );
+
+ if (!withdrawOnly) {
+ for (let i = 0; i < numDeposits; i++) {
+ logger.trace(`Starting deposit amount=10`);
+ start = Date.now();
+
+ await wallet.client.call(WalletApiOperation.CreateDepositGroup, {
+ amount: (b1conf.currency + ":10") as AmountString,
+ depositPaytoUri: b1conf.payto,
+ });
+
+ await wallet.client.call(WalletApiOperation.TestingWaitTasksDone, {});
+
+ logger.info(`Finished deposit amount=10 time=${Date.now() - start}`);
+ }
+ }
+ }
+
+ await wallet.client.call(WalletApiOperation.Shutdown, {});
+ console.log("wallet DB stats", j2s(getDbStats!()));
+}
+
+/**
+ * Format of the configuration file passed to the benchmark
+ */
+interface Bench1Config {
+ /**
+ * Base URL of the bank.
+ */
+ bank: string;
+
+ /**
+ * Payto url for deposits.
+ */
+ payto: string;
+
+ /**
+ * Base URL of the exchange.
+ */
+ exchange: string;
+
+ /**
+ * How many withdraw/deposit iterations should be made?
+ * Defaults to 1.
+ */
+ iterations?: number;
+
+ currency: string;
+
+ deposits?: number;
+
+ /**
+ * How any iterations run until the wallet db gets purged
+ * Defaults to 20.
+ */
+ restartAfter?: number;
+
+ withdrawOnly?: boolean;
+}
+
+/**
+ * Schema validation codec for Bench1Config.
+ */
+const codecForBench1Config = () =>
+ buildCodecForObject<Bench1Config>()
+ .property("bank", codecForString())
+ .property("payto", codecForString())
+ .property("exchange", codecForString())
+ .property("iterations", codecOptional(codecForNumber()))
+ .property("deposits", codecOptional(codecForNumber()))
+ .property("currency", codecForString())
+ .property("restartAfter", codecOptional(codecForNumber()))
+ .property("withdrawOnly", codecOptional(codecForBoolean()))
+ .build("Bench1Config");