summaryrefslogtreecommitdiff
path: root/cli/tests/unit/flock_test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tests/unit/flock_test.ts')
-rw-r--r--cli/tests/unit/flock_test.ts197
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();
- },
- };
-}