taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit d983ff060560c0e0807020047676d46d97077cc3
parent 75f1058c4555854ee3718f8c3c7bb80b48feec07
Author: Florian Dold <dold@taler.net>
Date:   Thu,  3 Sep 2026 15:44:44 +0200

wallet-core: test that a released lock goes to its waiter first

Diffstat:
Apackages/taler-wallet-core/src/sequential-locks.test.ts | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+), 0 deletions(-)

diff --git a/packages/taler-wallet-core/src/sequential-locks.test.ts b/packages/taler-wallet-core/src/sequential-locks.test.ts @@ -0,0 +1,56 @@ +/* + This file is part of GNU Taler + (C) 2026 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 assert from "node:assert"; +import { test } from "node:test"; +import { SequentialLocks } from "./sequential-locks.js"; + +test("a lock is handed to its waiter before a newcomer can take it", async () => { + const locks = new SequentialLocks(); + const token = "coins"; + let active = 0; + let maxActive = 0; + const order: string[] = []; + const section = (name: string) => async () => { + active++; + maxActive = Math.max(maxActive, active); + order.push(name); + await null; + await null; + active--; + }; + + let newcomer: Promise<void> | undefined; + const holder = locks.run([token], async () => { + // Queue the newcomer so that it checks the lock right after the holder + // released it, in the same microtask checkpoint that resumes the waiter. + Promise.resolve().then(() => { + queueMicrotask(() => { + newcomer = locks.run([token], section("newcomer")); + }); + }); + }); + const waiter = locks.run([token], section("waiter")); + + await holder; + await waiter; + assert.ok(newcomer); + await newcomer; + + assert.strictEqual(maxActive, 1); + assert.deepStrictEqual(order, ["waiter", "newcomer"]); +});