mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
82 lines
2.0 KiB
TypeScript
82 lines
2.0 KiB
TypeScript
import { randomUUID } from 'node:crypto';
|
|
|
|
import { TestingModule } from '@nestjs/testing';
|
|
import ava, { TestFn } from 'ava';
|
|
import Sinon from 'sinon';
|
|
|
|
import { Locker, Mutex } from '../src/base/mutex';
|
|
import { SessionRedis } from '../src/base/redis';
|
|
import { createTestingModule, sleep } from './utils';
|
|
|
|
const test = ava as TestFn<{
|
|
module: TestingModule;
|
|
mutex: Mutex;
|
|
locker: Locker;
|
|
session: SessionRedis;
|
|
}>;
|
|
|
|
test.beforeEach(async t => {
|
|
const module = await createTestingModule();
|
|
|
|
t.context.module = module;
|
|
t.context.mutex = module.get(Mutex);
|
|
t.context.locker = module.get(Locker);
|
|
t.context.session = module.get(SessionRedis);
|
|
});
|
|
|
|
test.afterEach(async t => {
|
|
await t.context.module.close();
|
|
});
|
|
|
|
const lockerPrefix = randomUUID();
|
|
test('should be able to acquire lock', async t => {
|
|
const { mutex } = t.context;
|
|
|
|
{
|
|
t.truthy(
|
|
await mutex.acquire(`${lockerPrefix}1`),
|
|
'should be able to acquire lock'
|
|
);
|
|
t.falsy(
|
|
await mutex.acquire(`${lockerPrefix}1`),
|
|
'should not be able to acquire lock again'
|
|
);
|
|
}
|
|
|
|
{
|
|
const lock1 = await mutex.acquire(`${lockerPrefix}2`);
|
|
t.truthy(lock1);
|
|
await lock1?.release();
|
|
const lock2 = await mutex.acquire(`${lockerPrefix}2`);
|
|
t.truthy(lock2);
|
|
}
|
|
});
|
|
|
|
test('should be able to acquire lock parallel', async t => {
|
|
const { mutex, locker } = t.context;
|
|
const spyedLocker = Sinon.spy(locker, 'lock');
|
|
const requestLock = async (key: string) => {
|
|
const lock = mutex.acquire(key);
|
|
await using _lock = await lock;
|
|
const lastCall = spyedLocker.lastCall.returnValue;
|
|
try {
|
|
// in rare cases, the lock can be acquired
|
|
// in which case skip the error message check
|
|
await lastCall;
|
|
} catch {
|
|
await t.throwsAsync(lastCall, {
|
|
message: `Failed to acquire lock for resource [${key}]`,
|
|
});
|
|
}
|
|
|
|
await sleep(100);
|
|
};
|
|
|
|
await t.notThrowsAsync(
|
|
Promise.all(
|
|
Array.from({ length: 10 }, _ => requestLock(`${lockerPrefix}3`))
|
|
),
|
|
'should be able to acquire lock parallel'
|
|
);
|
|
});
|