import { test, beforeEach } from 'node:test' import assert from 'node:assert/strict' import { withLocks } from '../server/services/keyedLock.js' const sleep = (ms) => new Promise((r) => setTimeout(r, ms)) let log beforeEach(() => { log = [] }) const job = (name, ms) => async () => { log.push(name + ':start') await sleep(ms) log.push(name + ':end') } test('gleicher Schlüssel läuft nacheinander', async () => { await Promise.all([withLocks(['a'], job('1', 50)), withLocks(['a'], job('2', 10))]) assert.deepEqual(log, ['1:start', '1:end', '2:start', '2:end']) }) test('verschiedene Schlüssel laufen parallel', async () => { await Promise.all([withLocks(['a'], job('1', 50)), withLocks(['b'], job('2', 10))]) assert.deepEqual(log.slice(0, 2), ['1:start', '2:start']) }) test('mehrere Schlüssel sperren alle', async () => { await Promise.all([withLocks(['a', 'b'], job('1', 50)), withLocks(['b'], job('2', 10))]) assert.deepEqual(log, ['1:start', '1:end', '2:start', '2:end']) }) test('waitMs begrenzt das Warten', async () => { const t0 = Date.now() let started await Promise.all([withLocks(['a'], job('1', 300)), withLocks(['a'], async () => { started = Date.now() - t0 }, { waitMs: 50 })]) assert.ok(started >= 45 && started < 250, `gestartet nach ${started} ms`) }) test('Fehler geben die Sperre frei', async () => { await assert.rejects(withLocks(['a'], async () => { throw new Error('x') })) assert.equal(await withLocks(['a'], async () => 42), 42) }) test('Timeout eines Wartenden hebt die Sperre nicht auf', async () => { const call3 = (async () => { await sleep(100) await withLocks(['a'], job('3', 10)) })() await Promise.all([ withLocks(['a'], job('1', 300)), withLocks(['a'], job('2', 10), { waitMs: 50 }), call3, ]) assert.ok(log.indexOf('3:start') > log.indexOf('1:end'), `log: ${log.join(',')}`) })