Ctrl K
ComunidadGuías…

test/scripts/stale-claim/freshness.test.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { expect } from "@std/expect";
import { describe, it as test } from "@std/testing/bdd";
import { stub } from "@std/testing/mock";
import { FakeTime } from "@std/testing/time";
import { claimIsFresh, withClaimGuard } from "#scripts/stale-claim.ts";
import {
  FRESH_FOR_MS,
  LONG_AGO_MS,
  SETTINGS,
  withClaimDir,
  withTestClaim,
  writeClaim,
} from "#test/scripts/stale-claim/helpers.ts";

describe("asking whether a claim is fresh", () => {
  test("a missing claim is nobody's", async () => {
    await withClaimDir(async (path) => {
      expect(await claimIsFresh(path, FRESH_FOR_MS)).toBe(false);
    });
  });

  test("a held claim is fresh and a walked-away one is not", async () => {
    await withClaimDir(async (path) => {
      await writeClaim(path, `someone\n${Date.now()}`);
      expect(await claimIsFresh(path, FRESH_FOR_MS)).toBe(true);

      await writeClaim(path, `someone\n${LONG_AGO_MS}`);
      expect(await claimIsFresh(path, FRESH_FOR_MS)).toBe(false);
    });
  });

  test("a claim stamped in the future is nobody's to trust", async () => {
    await withClaimDir(async (path) => {
      // A frozen clock, so "this very instant" below is exact, not racy.
      using _clock = new FakeTime();
      // A clock put back must not leave a dead owner's claim unstealable
      // until the wall clock catches its stamp up.
      await writeClaim(path, `someone\n${Date.now() + 5_000}`);
      expect(await claimIsFresh(path, FRESH_FOR_MS)).toBe(false);

      // Stamped this very instant, the claim is exactly fresh.
      await writeClaim(path, `someone\n${Date.now()}`);
      expect(await claimIsFresh(path, FRESH_FOR_MS)).toBe(true);
    });
  });

  test("says so loudly when there is no time at all to judge by", async () => {
    await withClaimDir(async (path) => {
      await writeClaim(path, "someone\nnot-a-time");
      const stat = Deno.stat;
      using _stat = stub(Deno, "stat", (async (target: string | URL) => ({
        ...(await stat(target)),
        mtime: null,
      })) as typeof Deno.stat);

      // Neither the record nor the filesystem offers a time: guessing
      // either way could steal a live claim or keep a dead one for ever.
      await expect(claimIsFresh(path, FRESH_FOR_MS)).rejects.toThrow(
        "keeps no last-write time",
      );
    });
  });

  test("a claim from before owners were named is judged by its time", async () => {
    await withClaimDir(async (path) => {
      await writeClaim(path, String(Date.now()));

      expect(await claimIsFresh(path, FRESH_FOR_MS)).toBe(true);
    });
  });

  test("a disk that cannot be read does not read as nobody's claim", async () => {
    await withClaimDir(async (path) => {
      using _read = stub(Deno, "readTextFile", (() =>
        Promise.reject(
          new Deno.errors.PermissionDenied("no access"),
        )) as typeof Deno.readTextFile);

      await expect(claimIsFresh(path, FRESH_FOR_MS)).rejects.toThrow(
        "no access",
      );
    });
  });
});

describe("holding the takers' guard", () => {
  test("keeps a taker at the door until the guard is let go", async () => {
    await withClaimDir(async (path) => {
      const order: string[] = [];
      const inside = Promise.withResolvers<void>();
      const release = Promise.withResolvers<void>();

      const holding = withClaimGuard(path, async () => {
        inside.resolve();
        await release.promise;
        order.push("guard let go");
      });
      await inside.promise;

      const taking = withTestClaim(
        path,
        () => {
          order.push("claim taken");
          return Promise.resolve();
        },
        { ...SETTINGS, timeoutMs: 5_000 },
      );
      release.resolve();
      await Promise.all([holding, taking]);

      expect(order).toEqual(["guard let go", "claim taken"]);
    });
  });
});