integration tests: test crypto worker

We test instantiations of both crypto workers that are available for
node.
This commit is contained in:
Florian Dold 2022-10-05 15:45:10 +02:00
parent efc4ac8dca
commit 70d37e4ed3
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
7 changed files with 84 additions and 4 deletions

View File

@ -1860,6 +1860,10 @@ function shellWrap(s: string) {
return "'" + s.replace("\\", "\\\\").replace("'", "\\'") + "'"; return "'" + s.replace("\\", "\\\\").replace("'", "\\'") + "'";
} }
export interface WalletCliOpts {
cryptoWorkerType?: "sync" | "node-worker-thread";
}
export class WalletCli { export class WalletCli {
private currentTimetravel: Duration | undefined; private currentTimetravel: Duration | undefined;
private _client: WalletCoreApiClient; private _client: WalletCoreApiClient;
@ -1879,6 +1883,7 @@ export class WalletCli {
constructor( constructor(
private globalTestState: GlobalTestState, private globalTestState: GlobalTestState,
private name: string = "default", private name: string = "default",
cliOpts: WalletCliOpts = {},
) { ) {
const self = this; const self = this;
this._client = { this._client = {
@ -1886,12 +1891,15 @@ export class WalletCli {
logger.info( logger.info(
`calling wallet with timetravel arg ${j2s(self.timetravelArg)}`, `calling wallet with timetravel arg ${j2s(self.timetravelArg)}`,
); );
const cryptoWorkerArg = cliOpts.cryptoWorkerType
? `--crypto-worker=${cliOpts.cryptoWorkerType}`
: "";
const resp = await sh( const resp = await sh(
self.globalTestState, self.globalTestState,
`wallet-${self.name}`, `wallet-${self.name}`,
`taler-wallet-cli ${ `taler-wallet-cli ${
self.timetravelArg ?? "" self.timetravelArg ?? ""
} --no-throttle -LTRACE --skip-defaults --wallet-db '${ } ${cryptoWorkerArg} --no-throttle -LTRACE --skip-defaults --wallet-db '${
self.dbfile self.dbfile
}' api '${op}' ${shellWrap(JSON.stringify(payload))}`, }' api '${op}' ${shellWrap(JSON.stringify(payload))}`,
); );

View File

@ -181,6 +181,9 @@ export const walletCli = clk
setDangerousTimetravel(x / 1000); setDangerousTimetravel(x / 1000);
}, },
}) })
.maybeOption("cryptoWorker", ["--crypto-worker"], clk.STRING, {
help: "Override crypto worker implementation type."
})
.maybeOption("log", ["-L", "--log"], clk.STRING, { .maybeOption("log", ["-L", "--log"], clk.STRING, {
help: "configure log level (NONE, ..., TRACE)", help: "configure log level (NONE, ..., TRACE)",
onPresentHandler: (x) => { onPresentHandler: (x) => {
@ -228,6 +231,7 @@ async function withWallet<T>(
notifyHandler: (n) => { notifyHandler: (n) => {
logger.info(`wallet notification: ${j2s(n)}`); logger.info(`wallet notification: ${j2s(n)}`);
}, },
cryptoWorkerType: walletCliArgs.wallet.cryptoWorker as any,
}); });
if (checkEnvFlag("TALER_WALLET_BATCH_WITHDRAWAL")) { if (checkEnvFlag("TALER_WALLET_BATCH_WITHDRAWAL")) {

View File

@ -0,0 +1,55 @@
/*
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 { j2s } from "@gnu-taler/taler-util";
import {
checkReserve,
CryptoDispatcher,
depositCoin,
downloadExchangeInfo,
findDenomOrThrow,
NodeHttpLib,
refreshCoin,
SynchronousCryptoWorkerFactory,
TalerError,
topupReserveWithDemobank,
WalletApiOperation,
withdrawCoin,
} from "@gnu-taler/taler-wallet-core";
import { GlobalTestState, WalletCli } from "../harness/harness.js";
import { createSimpleTestkudosEnvironment } from "../harness/helpers.js";
/**
* Run test for the different crypto workers.
*/
export async function runWalletCryptoWorkerTest(t: GlobalTestState) {
const wallet1 = new WalletCli(t, "w1", {
cryptoWorkerType: "sync",
});
await wallet1.client.call(WalletApiOperation.CryptoTest, {});
const wallet2 = new WalletCli(t, "w2", {
cryptoWorkerType: "node-worker-thread",
});
await wallet2.client.call(WalletApiOperation.CryptoTest, {});
}
runWalletCryptoWorkerTest.suites = ["wallet"];

View File

@ -93,6 +93,7 @@ import { runTestWithdrawalManualTest } from "./test-withdrawal-manual.js";
import { runAgeRestrictionsPeerTest } from "./test-age-restrictions-peer.js"; import { runAgeRestrictionsPeerTest } from "./test-age-restrictions-peer.js";
import { runWalletBalanceTest } from "./test-wallet-balance.js"; import { runWalletBalanceTest } from "./test-wallet-balance.js";
import { runAgeRestrictionsMixedMerchantTest } from "./test-age-restrictions-mixed-merchant.js"; import { runAgeRestrictionsMixedMerchantTest } from "./test-age-restrictions-mixed-merchant.js";
import { runWalletCryptoWorkerTest } from "./test-wallet-cryptoworker.js";
/** /**
* Test runner. * Test runner.
@ -115,6 +116,7 @@ const allTests: TestMainFunction[] = [
runBankApiTest, runBankApiTest,
runClaimLoopTest, runClaimLoopTest,
runClauseSchnorrTest, runClauseSchnorrTest,
runWalletCryptoWorkerTest,
runDepositTest, runDepositTest,
runDenomUnofferedTest, runDenomUnofferedTest,
runExchangeManagementTest, runExchangeManagementTest,

View File

@ -15,7 +15,8 @@
*/ */
/** /**
* API to access the Taler crypto worker thread. * API to access the Taler crypto worker.
*
* @author Florian Dold * @author Florian Dold
*/ */
@ -76,6 +77,10 @@ interface WorkItem {
*/ */
const NUM_PRIO = 5; const NUM_PRIO = 5;
/**
* A crypto worker factory is responsible for creating new
* crypto workers on-demand.
*/
export interface CryptoWorkerFactory { export interface CryptoWorkerFactory {
/** /**
* Start a new worker. * Start a new worker.

View File

@ -61,6 +61,8 @@ export interface DefaultNodeWalletArgs {
* of the default one. * of the default one.
*/ */
httpLib?: HttpRequestLibrary; httpLib?: HttpRequestLibrary;
cryptoWorkerType?: "sync" | "node-worker-thread";
} }
/** /**
@ -160,10 +162,11 @@ export async function getDefaultNodeWallet2(
const myDb = await openTalerDatabase(myIdbFactory, myVersionChange); const myDb = await openTalerDatabase(myIdbFactory, myVersionChange);
let workerFactory; let workerFactory;
if (process.env["TALER_WALLET_SYNC_CRYPTO"]) { const cryptoWorkerType = args.cryptoWorkerType ?? "node-worker-thread";
if (cryptoWorkerType === "sync") {
logger.info("using synchronous crypto worker"); logger.info("using synchronous crypto worker");
workerFactory = new SynchronousCryptoWorkerFactory(); workerFactory = new SynchronousCryptoWorkerFactory();
} else { } else if (cryptoWorkerType === "node-worker-thread") {
try { try {
// Try if we have worker threads available, fails in older node versions. // Try if we have worker threads available, fails in older node versions.
const _r = "require"; const _r = "require";
@ -177,6 +180,8 @@ export async function getDefaultNodeWallet2(
); );
workerFactory = new SynchronousCryptoWorkerFactory(); workerFactory = new SynchronousCryptoWorkerFactory();
} }
} else {
throw Error(`unsupported crypto worker type '${cryptoWorkerType}'`);
} }
const timer = new SetTimeoutTimerAPI(); const timer = new SetTimeoutTimerAPI();

View File

@ -219,6 +219,7 @@ async function reinitWallet(): Promise<void> {
httpLib = new BrowserHttpLib(); httpLib = new BrowserHttpLib();
// We could (should?) use the BrowserCryptoWorkerFactory here, // We could (should?) use the BrowserCryptoWorkerFactory here,
// but right now we don't, to have less platform differences. // but right now we don't, to have less platform differences.
// cryptoWorker = new BrowserCryptoWorkerFactory();
cryptoWorker = new SynchronousCryptoWorkerFactory(); cryptoWorker = new SynchronousCryptoWorkerFactory();
timer = new SetTimeoutTimerAPI(); timer = new SetTimeoutTimerAPI();
} }