Rhys Sullivanfmtc92c57d6 months agoHistory
197 lines · 6.0 KB · TypeScript
RawDownload
import { mkdtempSync, rmSync } from "node:fs";import { mkdir, readFile, rm, writeFile } from "node:fs/promises";import { tmpdir } from "node:os";import { join } from "node:path";import { describe, expect, it } from "@effect/vitest";import { Effect, FileSystem, Layer, Path, PlatformError } from "effect"; import {  acquireDaemonStartLock,  canonicalDaemonHost,  currentDaemonScopeId,  isPidAlive,  readDaemonPointer,  readDaemonRecord,  releaseDaemonStartLock,  removeDaemonPointer,  removeDaemonRecord,  writeDaemonPointer,  writeDaemonRecord,} from "../apps/cli/src/daemon-state"; const fileSystemError = (method: string, cause: unknown) =>  PlatformError.systemError({    _tag: "Unknown",    module: "FileSystem",    method,    description: "FileSystem operation failed",    cause,  }); const fileSystemLayer = FileSystem.layerNoop({  makeDirectory: (path, options) =>    Effect.tryPromise({      try: () => mkdir(path, { recursive: options?.recursive, mode: options?.mode }),      catch: (cause) => fileSystemError("makeDirectory", cause),    }),  writeFileString: (path, data, options) =>    Effect.tryPromise({      try: () => writeFile(path, data, { encoding: "utf8", flag: options?.flag }),      catch: (cause) => fileSystemError("writeFileString", cause),    }),  readFileString: (path, encoding = "utf8") =>    Effect.tryPromise({      try: () => readFile(path, { encoding: encoding as BufferEncoding }),      catch: (cause) => fileSystemError("readFileString", cause),    }),  remove: (path, options) =>    Effect.tryPromise({      try: () =>        rm(path, { recursive: options?.recursive ?? false, force: options?.force ?? false }),      catch: (cause) => fileSystemError("remove", cause),    }),}); const daemonStateLayer = Layer.merge(fileSystemLayer, Path.layer); const withDaemonDataDir = <A, E>(effect: Effect.Effect<A, E, FileSystem.FileSystem | Path.Path>) =>  Effect.acquireUseRelease(    Effect.sync(() => {      const prev = process.env.EXECUTOR_DATA_DIR;      const dir = mkdtempSync(join(tmpdir(), "executor-daemon-state-test-"));      process.env.EXECUTOR_DATA_DIR = dir;      return { dir, prev };    }),    () => effect,    ({ dir, prev }) =>      Effect.sync(() => {        if (prev === undefined) {          delete process.env.EXECUTOR_DATA_DIR;        } else {          process.env.EXECUTOR_DATA_DIR = prev;        }        rmSync(dir, { recursive: true, force: true });      }),  ).pipe(Effect.provide(daemonStateLayer)); describe("daemon state", () => {  it("normalizes local host aliases", () => {    expect(canonicalDaemonHost("localhost")).toBe("localhost");    expect(canonicalDaemonHost("127.0.0.1")).toBe("localhost");    expect(canonicalDaemonHost("::1")).toBe("localhost");    expect(canonicalDaemonHost("0.0.0.0")).toBe("localhost");    expect(canonicalDaemonHost("api.example.com")).toBe("api.example.com");  });   it.effect("writes, reads, and removes daemon records", () =>    withDaemonDataDir(      Effect.gen(function* () {        yield* writeDaemonRecord({          hostname: "127.0.0.1",          port: 4788,          pid: 12345,          scopeDir: "/tmp/scope",        });         const stored = yield* readDaemonRecord({ hostname: "localhost", port: 4788 });        expect(stored).toEqual({          version: 1,          hostname: "localhost",          port: 4788,          pid: 12345,          startedAt: expect.any(String),          scopeDir: "/tmp/scope",        });         yield* removeDaemonRecord({ hostname: "localhost", port: 4788 });        const after = yield* readDaemonRecord({ hostname: "localhost", port: 4788 });        expect(after).toBeNull();      }),    ),  );   it.effect("writes, reads, and removes daemon pointers", () =>    withDaemonDataDir(      Effect.gen(function* () {        yield* writeDaemonPointer({          hostname: "127.0.0.1",          port: 5799,          pid: 24680,          scopeId: "scope:/tmp/project",          scopeDir: "/tmp/project",          token: "tok_123",        });         const stored = yield* readDaemonPointer({          hostname: "localhost",          scopeId: "scope:/tmp/project",        });        expect(stored).toEqual({          version: 1,          hostname: "localhost",          port: 5799,          pid: 24680,          startedAt: expect.any(String),          scopeId: "scope:/tmp/project",          scopeDir: "/tmp/project",          token: "tok_123",        });         yield* removeDaemonPointer({          hostname: "localhost",          scopeId: "scope:/tmp/project",        });        const after = yield* readDaemonPointer({          hostname: "localhost",          scopeId: "scope:/tmp/project",        });        expect(after).toBeNull();      }),    ),  );   it.effect("serializes daemon startup with lock files", () =>    withDaemonDataDir(      Effect.gen(function* () {        const lock = yield* acquireDaemonStartLock({          hostname: "localhost",          scopeId: "scope:/tmp/project",        });         const second = yield* acquireDaemonStartLock({          hostname: "localhost",          scopeId: "scope:/tmp/project",        }).pipe(Effect.flip);         expect(second.message).toContain("already in progress");         yield* releaseDaemonStartLock(lock);         const third = yield* acquireDaemonStartLock({          hostname: "localhost",          scopeId: "scope:/tmp/project",        });        yield* releaseDaemonStartLock(third);      }),    ),  );   it("derives scope id from EXECUTOR_SCOPE_DIR or cwd", () => {    const prev = process.env.EXECUTOR_SCOPE_DIR;    process.env.EXECUTOR_SCOPE_DIR = "/tmp/explicit-scope";    expect(currentDaemonScopeId()).toBe("scope:/tmp/explicit-scope");     if (prev === undefined) {      delete process.env.EXECUTOR_SCOPE_DIR;    } else {      process.env.EXECUTOR_SCOPE_DIR = prev;    }     expect(currentDaemonScopeId()).toContain("cwd:");  });   it("detects live and invalid pids", () => {    expect(isPidAlive(process.pid)).toBe(true);    expect(isPidAlive(-1)).toBe(false);  });});