diff options
author | Florian Dold <florian@dold.me> | 2023-01-04 13:24:19 +0100 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2023-01-04 13:24:24 +0100 |
commit | 60374078f4e41e9398607628d8b33b74bb3431aa (patch) | |
tree | 1cdf187aa25fbf023ac2b09f2ccd7c9eca4165ca /packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts | |
parent | 9c63d67781e1bf2253d3d26de311ef32a1026fb9 (diff) | |
download | wallet-core-60374078f4e41e9398607628d8b33b74bb3431aa.tar.xz |
wallet-core: test crypto dispatcher, fix timeout handling
Diffstat (limited to 'packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts')
-rw-r--r-- | packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts b/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts new file mode 100644 index 000000000..b63c9bf11 --- /dev/null +++ b/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts @@ -0,0 +1,130 @@ +/* + This file is part of GNU Taler + (C) 2023 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 test from "ava"; +import { CryptoDispatcher, CryptoWorkerFactory } from "./crypto-dispatcher.js"; +import { CryptoWorker, CryptoWorkerResponseMessage } from "./cryptoWorkerInterface.js"; +import { SynchronousCryptoWorkerFactoryNode } from "./synchronousWorkerFactoryNode.js"; +import { processRequestWithImpl } from "./worker-common.js"; + + +export class MyCryptoWorker implements CryptoWorker { + /** + * Function to be called when we receive a message from the worker thread. + */ + onmessage: undefined | ((m: any) => void) = undefined; + + /** + * Function to be called when we receive an error from the worker thread. + */ + onerror: undefined | ((m: any) => void) = undefined; + + /** + * Add an event listener for either an "error" or "message" event. + */ + addEventListener(event: "message" | "error", fn: (x: any) => void): void { + switch (event) { + case "message": + this.onmessage = fn; + break; + case "error": + this.onerror = fn; + break; + } + } + + private dispatchMessage(msg: any): void { + if (this.onmessage) { + this.onmessage(msg); + } + } + + /** + * Send a message to the worker thread. + */ + postMessage(msg: any): void { + const handleRequest = async () => { + let responseMsg: CryptoWorkerResponseMessage; + if (msg.operation === "testSuccess") { + responseMsg = { + id: msg.id, + type: "success", + result: { + testResult: 42, + } + } + } else if (msg.operation === "testError") { + responseMsg = { + id: msg.id, + type: "error", + error: { + code: 42, + hint: "bla", + } + } + } else if (msg.operation === "testTimeout") { + // Don't respond + return; + } + try { + setTimeout(() => this.dispatchMessage(responseMsg), 0); + } catch (e) { + console.error("got error during dispatch", e); + } + }; + handleRequest().catch((e) => { + console.error("Error while handling crypto request:", e); + }); + } + + /** + * Forcibly terminate the worker thread. + */ + terminate(): void { + // This is a no-op. + } +} + + + +export class MyCryptoWorkerFactory implements CryptoWorkerFactory { + startWorker(): CryptoWorker { + return new MyCryptoWorker(); + } + + getConcurrency(): number { + return 1; + } +} + +test("continues after error", async (t) => { + const cryptoDisp = new CryptoDispatcher( + new MyCryptoWorkerFactory(), + ); + const resp1 = await cryptoDisp.doRpc("testSuccess", 0, {}); + t.assert((resp1 as any).testResult === 42); + const exc = await t.throwsAsync(async() => { + const resp2 = await cryptoDisp.doRpc("testError", 0, {}); + }); + + // Check that it still works after one error. + const resp2 = await cryptoDisp.doRpc("testSuccess", 0, {}); + t.assert((resp2 as any).testResult === 42); + + // Check that it still works after timeout. + const resp3 = await cryptoDisp.doRpc("testSuccess", 0, {}); + t.assert((resp3 as any).testResult === 42); +}); |