diff options
Diffstat (limited to 'cli/tests/unit/flock_test.ts')
-rw-r--r-- | cli/tests/unit/flock_test.ts | 197 |
1 files changed, 0 insertions, 197 deletions
diff --git a/cli/tests/unit/flock_test.ts b/cli/tests/unit/flock_test.ts deleted file mode 100644 index 3189b4a56..000000000 --- a/cli/tests/unit/flock_test.ts +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. -import { assertEquals } from "./test_util.ts"; - -Deno.test( - { permissions: { read: true, run: true, hrtime: true } }, - async function flockFileSync() { - await runFlockTests({ sync: true }); - }, -); - -Deno.test( - { permissions: { read: true, run: true, hrtime: true } }, - async function flockFileAsync() { - await runFlockTests({ sync: false }); - }, -); - -async function runFlockTests(opts: { sync: boolean }) { - assertEquals( - await checkFirstBlocksSecond({ - firstExclusive: true, - secondExclusive: false, - sync: opts.sync, - }), - true, - "exclusive blocks shared", - ); - assertEquals( - await checkFirstBlocksSecond({ - firstExclusive: false, - secondExclusive: true, - sync: opts.sync, - }), - true, - "shared blocks exclusive", - ); - assertEquals( - await checkFirstBlocksSecond({ - firstExclusive: true, - secondExclusive: true, - sync: opts.sync, - }), - true, - "exclusive blocks exclusive", - ); - assertEquals( - await checkFirstBlocksSecond({ - firstExclusive: false, - secondExclusive: false, - sync: opts.sync, - // need to wait for both to enter the lock to prevent the case where the - // first process enters and exits the lock before the second even enters - waitBothEnteredLock: true, - }), - false, - "shared does not block shared", - ); -} - -async function checkFirstBlocksSecond(opts: { - firstExclusive: boolean; - secondExclusive: boolean; - sync: boolean; - waitBothEnteredLock?: boolean; -}) { - const firstProcess = runFlockTestProcess({ - exclusive: opts.firstExclusive, - sync: opts.sync, - }); - const secondProcess = runFlockTestProcess({ - exclusive: opts.secondExclusive, - sync: opts.sync, - }); - try { - const sleep = (time: number) => new Promise((r) => setTimeout(r, time)); - - await Promise.all([ - firstProcess.waitStartup(), - secondProcess.waitStartup(), - ]); - - await firstProcess.enterLock(); - await firstProcess.waitEnterLock(); - - await secondProcess.enterLock(); - await sleep(100); - - if (!opts.waitBothEnteredLock) { - await firstProcess.exitLock(); - } - - await secondProcess.waitEnterLock(); - - if (opts.waitBothEnteredLock) { - await firstProcess.exitLock(); - } - - await secondProcess.exitLock(); - - // collect the final output - const firstPsTimes = await firstProcess.getTimes(); - const secondPsTimes = await secondProcess.getTimes(); - return firstPsTimes.exitTime < secondPsTimes.enterTime; - } finally { - await firstProcess.close(); - await secondProcess.close(); - } -} - -function runFlockTestProcess(opts: { exclusive: boolean; sync: boolean }) { - const path = "cli/tests/testdata/assets/lock_target.txt"; - const scriptText = ` - const { rid } = Deno.openSync("${path}"); - - // ready signal - Deno.stdout.writeSync(new Uint8Array(1)); - // wait for enter lock signal - Deno.stdin.readSync(new Uint8Array(1)); - - // entering signal - Deno.stdout.writeSync(new Uint8Array(1)); - // lock and record the entry time - ${ - opts.sync - ? `Deno.flockSync(rid, ${opts.exclusive ? "true" : "false"});` - : `await Deno.flock(rid, ${opts.exclusive ? "true" : "false"});` - } - const enterTime = new Date().getTime(); - // entered signal - Deno.stdout.writeSync(new Uint8Array(1)); - - // wait for exit lock signal - Deno.stdin.readSync(new Uint8Array(1)); - - // record the exit time and wait a little bit before releasing - // the lock so that the enter time of the next process doesn't - // occur at the same time as this exit time - const exitTime = new Date().getTime(); - await new Promise(resolve => setTimeout(resolve, 100)); - - // release the lock - ${opts.sync ? "Deno.funlockSync(rid);" : "await Deno.funlock(rid);"} - - // exited signal - Deno.stdout.writeSync(new Uint8Array(1)); - - // output the enter and exit time - console.log(JSON.stringify({ enterTime, exitTime })); -`; - - const process = new Deno.Command(Deno.execPath(), { - args: ["eval", "--unstable", scriptText], - stdin: "piped", - stdout: "piped", - stderr: "null", - }).spawn(); - - const waitSignal = async () => { - const reader = process.stdout.getReader({ mode: "byob" }); - await reader.read(new Uint8Array(1)); - reader.releaseLock(); - }; - const signal = async () => { - const writer = process.stdin.getWriter(); - await writer.write(new Uint8Array(1)); - writer.releaseLock(); - }; - - return { - async waitStartup() { - await waitSignal(); - }, - async enterLock() { - await signal(); - await waitSignal(); // entering signal - }, - async waitEnterLock() { - await waitSignal(); - }, - async exitLock() { - await signal(); - await waitSignal(); - }, - getTimes: async () => { - const { stdout } = await process.output(); - const text = new TextDecoder().decode(stdout); - return JSON.parse(text) as { - enterTime: number; - exitTime: number; - }; - }, - close: async () => { - await process.status; - await process.stdin.close(); - }, - }; -} |