72 lines · 1.7 KB · TypeScript
RawDownload
import { describe, expect, test } from "bun:test"import { Lock } from "../../src/util/lock" function tick() {  return new Promise<void>((r) => queueMicrotask(r))} async function flush(n = 5) {  for (let i = 0; i < n; i++) await tick()} describe("util.lock", () => {  test("writer exclusivity: blocks reads and other writes while held", async () => {    const key = "lock:" + Math.random().toString(36).slice(2)     const state = {      writer2: false,      reader: false,      writers: 0,    }     // Acquire writer1    using writer1 = await Lock.write(key)    state.writers++    expect(state.writers).toBe(1)     // Start writer2 candidate (should block)    const writer2Task = (async () => {      const w = await Lock.write(key)      state.writers++      expect(state.writers).toBe(1)      state.writer2 = true      // Hold for a tick so reader cannot slip in      await tick()      return w    })()     // Start reader candidate (should block)    const readerTask = (async () => {      const r = await Lock.read(key)      state.reader = true      return r    })()     // Flush microtasks and assert neither acquired    await flush()    expect(state.writer2).toBe(false)    expect(state.reader).toBe(false)     // Release writer1    writer1[Symbol.dispose]()    state.writers--     // writer2 should acquire next    const writer2 = await writer2Task    expect(state.writer2).toBe(true)     // Reader still blocked while writer2 held    await flush()    expect(state.reader).toBe(false)     // Release writer2    writer2[Symbol.dispose]()    state.writers--     // Reader should now acquire    const reader = await readerTask    expect(state.reader).toBe(true)     reader[Symbol.dispose]()  })})