113 lines · 4.6 KB · TypeScript
RawDownload
// @effect-diagnostics nodeBuiltinImport:offimport * as NodeServices from "@effect/platform-node/NodeServices";import * as NodeOS from "node:os";import * as NodePath from "node:path";import { expect, it } from "@effect/vitest";import { ProviderInstanceId } from "@t3tools/contracts";import { HostProcessPlatform } from "@t3tools/shared/hostProcess";import * as Effect from "effect/Effect";import * as FileSystem from "effect/FileSystem";import * as Layer from "effect/Layer";import { HttpClient } from "effect/unstable/http";import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner"; import * as BackgroundPolicy from "../../background/BackgroundPolicy.ts";import { ServerConfig } from "../../config.ts";import { ServerSettingsService } from "../../serverSettings.ts";import { layerTest as codexResetCreditLayerTest } from "../Layers/codexResetCredit.ts";import { NoOpProviderEventLoggers, ProviderEventLoggers } from "../Layers/ProviderEventLoggers.ts";import * as ModelManifest from "../ModelManifest.ts";import { CodexDriver } from "./CodexDriver.ts";import { CodexAppServerClientFactory } from "../../orchestration-v2/Adapters/CodexAdapterV2.ts";import { layer as idAllocatorLayer } from "../../orchestration-v2/IdAllocator.ts"; const testLayer = ServerConfig.layerTest(process.cwd(), {  prefix: "t3-codex-driver-maintenance-",}).pipe(  Layer.provideMerge(NodeServices.layer),  Layer.provideMerge(idAllocatorLayer),  Layer.provideMerge(    Layer.mock(CodexAppServerClientFactory)({      open: () => Effect.die("Maintenance resolution must not open a Codex session"),    }),  ),  Layer.provideMerge(ServerSettingsService.layerTest()),  Layer.provideMerge(ModelManifest.layerTest),  Layer.provideMerge(codexResetCreditLayerTest),  Layer.provideMerge(    Layer.mock(BackgroundPolicy.BackgroundPolicy)({      shouldRunScopeWork: () => Effect.succeed(false),    }),  ),  Layer.provideMerge(Layer.succeed(ProviderEventLoggers, NoOpProviderEventLoggers)),  Layer.provideMerge(    Layer.succeed(      HttpClient.HttpClient,      HttpClient.make(() => Effect.die("Disabled Codex must not make an HTTP request")),    ),  ),); // The `#!/bin/sh` stub below cannot be resolved as an executable on Windows.const windowsHost = HostProcessPlatform.defaultValue() === "win32"; const noSpawn = ChildProcessSpawner.make(() =>  Effect.die("Disabled Codex must not spawn a process"),); it.layer(testLayer)("CodexDriver", (it) => {  it.effect.skipIf(windowsHost)(    "runs the standalone updater against the shared home, not the shadow home",    () =>      Effect.gen(function* () {        const fs = yield* FileSystem.FileSystem;        const tempDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-codex-driver-" });        const sharedHome = NodePath.join(tempDir, "codex-home");        const shadowHome = NodePath.join(tempDir, "codex-shadow");        const binaryPath = NodePath.join(sharedHome, "packages", "standalone", "bin", "codex");        yield* fs.makeDirectory(NodePath.dirname(binaryPath), { recursive: true });        yield* fs.writeFileString(binaryPath, "#!/bin/sh\n");        yield* fs.chmod(binaryPath, 0o755);         const instance = yield* CodexDriver.create({          instanceId: ProviderInstanceId.make("codex-shadow"),          displayName: "Codex test",          enabled: false,          environment: [],          config: {            ...CodexDriver.defaultConfig(),            binaryPath,            homePath: sharedHome,            shadowHomePath: shadowHome,          },        });         const capabilities = yield* instance.snapshot.resolveMaintenance();        expect(capabilities.update).toMatchObject({          executable: binaryPath,          args: ["update"],          lockKey: "codex-native",          env: { CODEX_HOME: sharedHome },        });      }).pipe(        Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, noSpawn),        Effect.scoped,      ),  );   it.effect("stays manual-only when the configured executable does not exist", () =>    Effect.gen(function* () {      const instance = yield* CodexDriver.create({        instanceId: ProviderInstanceId.make("codex-missing"),        displayName: "Codex test",        enabled: false,        environment: [],        config: {          ...CodexDriver.defaultConfig(),          binaryPath: NodePath.join(NodeOS.tmpdir(), "t3-codex-missing", "codex"),        },      });      expect((yield* instance.snapshot.resolveMaintenance()).update).toBeNull();    }).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, noSpawn), Effect.scoped),  );});