101 lines · 3.8 KB · TypeScript
RawDownload
import { assert, describe, it } from "@effect/vitest";import * as NetService from "@t3tools/shared/Net";import { HostProcessPlatform } from "@t3tools/shared/hostProcess";import * as Effect from "effect/Effect";import * as Layer from "effect/Layer";import * as Result from "effect/Result";import * as Sink from "effect/Sink";import * as Stream from "effect/Stream";import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner"; import * as OpenCodeRuntime from "./opencodeRuntime.ts"; const encoder = new TextEncoder(); function exitedProcess(stdout: string, stderr: string, exitCode: number) {  return ChildProcessSpawner.makeHandle({    pid: ChildProcessSpawner.ProcessId(123),    stdout: Stream.make(encoder.encode(stdout)),    stderr: Stream.make(encoder.encode(stderr)),    all: Stream.empty,    exitCode: Effect.yieldNow.pipe(      Effect.andThen(Effect.succeed(ChildProcessSpawner.ExitCode(exitCode))),    ),    isRunning: Effect.succeed(false),    kill: () => Effect.void,    stdin: Sink.drain,    getInputFd: () => Sink.drain,    getOutputFd: () => Stream.empty,    unref: Effect.succeed(Effect.void),  });} const netService = {  canListenOnHost: () => Effect.succeed(true),  isPortAvailableOnLoopback: () => Effect.succeed(true),  reserveLoopbackPort: () => Effect.succeed(12_345),  findAvailablePort: () => Effect.succeed(12_345),} satisfies NetService.NetServiceShape; describe("OpenCodeRuntime", () => {  it.effect("retains SDK status and cause without copying arbitrary response bodies", () => {    const cause = {      response: { status: 401 },      body: { accessToken: "sdk-secret" },    };     return Effect.gen(function* () {      const result = yield* Effect.result(        OpenCodeRuntime.runOpenCodeSdk("session.get", () => Promise.reject(cause)),      );       assert.isTrue(Result.isFailure(result));      if (Result.isFailure(result)) {        assert.instanceOf(result.failure, OpenCodeRuntime.OpenCodeRuntimeError);        assert.equal(result.failure.operation, "session.get");        assert.equal(result.failure.detail, "OpenCode SDK request failed.");        assert.equal(result.failure.responseStatus, 401);        assert.strictEqual(result.failure.cause, cause);        assert.notInclude(result.failure.detail, "sdk-secret");        assert.isFalse("body" in result.failure);      }    });  });   it.live("records startup output sizes without retaining process streams", () => {    const stdout = "startup output with a credential sdk-secret";    const stderr = "startup failed";    const layer = Layer.mergeAll(      Layer.succeed(        ChildProcessSpawner.ChildProcessSpawner,        ChildProcessSpawner.make(() => Effect.succeed(exitedProcess(stdout, stderr, 17))),      ),      Layer.succeed(NetService.NetService, netService),      Layer.succeed(HostProcessPlatform, "win32"),    );     return Effect.gen(function* () {      const runtime = yield* OpenCodeRuntime.make;      const result = yield* Effect.result(        Effect.scoped(          runtime.startOpenCodeServerProcess({            binaryPath: "opencode",            port: 12_345,          }),        ),      );       assert.isTrue(Result.isFailure(result));      if (Result.isFailure(result)) {        assert.instanceOf(result.failure, OpenCodeRuntime.OpenCodeRuntimeError);        assert.equal(result.failure.exitCode, 17);        assert.equal(result.failure.argumentCount, 3);        assert.equal(result.failure.stdoutBytes, encoder.encode(stdout).byteLength);        assert.equal(result.failure.stderrBytes, encoder.encode(stderr).byteLength);        assert.isFalse("stdout" in result.failure);        assert.isFalse("stderr" in result.failure);        assert.notInclude(result.failure.detail, "sdk-secret");      }    }).pipe(Effect.provide(layer));  });});