summaryrefslogtreecommitdiffhomepage
path: root/packages/app/e2e/backend.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/app/e2e/backend.ts')
-rw-r--r--packages/app/e2e/backend.ts141
1 files changed, 0 insertions, 141 deletions
diff --git a/packages/app/e2e/backend.ts b/packages/app/e2e/backend.ts
deleted file mode 100644
index a03d1d437..000000000
--- a/packages/app/e2e/backend.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-import { spawn } from "node:child_process"
-import fs from "node:fs/promises"
-import net from "node:net"
-import os from "node:os"
-import path from "node:path"
-import { fileURLToPath } from "node:url"
-
-type Handle = {
- url: string
- stop: () => Promise<void>
-}
-
-function freePort() {
- return new Promise<number>((resolve, reject) => {
- const server = net.createServer()
- server.once("error", reject)
- server.listen(0, () => {
- const address = server.address()
- if (!address || typeof address === "string") {
- server.close(() => reject(new Error("Failed to acquire a free port")))
- return
- }
- server.close((err) => {
- if (err) reject(err)
- else resolve(address.port)
- })
- })
- })
-}
-
-async function waitForHealth(url: string, probe = "/global/health") {
- const end = Date.now() + 120_000
- let last = ""
- while (Date.now() < end) {
- try {
- const res = await fetch(`${url}${probe}`)
- if (res.ok) return
- last = `status ${res.status}`
- } catch (err) {
- last = err instanceof Error ? err.message : String(err)
- }
- await new Promise((resolve) => setTimeout(resolve, 250))
- }
- throw new Error(`Timed out waiting for backend health at ${url}${probe}${last ? ` (${last})` : ""}`)
-}
-
-function done(proc: ReturnType<typeof spawn>) {
- return proc.exitCode !== null || proc.signalCode !== null
-}
-
-async function waitExit(proc: ReturnType<typeof spawn>, timeout = 10_000) {
- if (done(proc)) return
- await Promise.race([
- new Promise<void>((resolve) => proc.once("exit", () => resolve())),
- new Promise<void>((resolve) => setTimeout(resolve, timeout)),
- ])
-}
-
-const LOG_CAP = 100
-
-function cap(input: string[]) {
- if (input.length > LOG_CAP) input.splice(0, input.length - LOG_CAP)
-}
-
-function tail(input: string[]) {
- return input.slice(-40).join("")
-}
-
-export async function startBackend(label: string, input?: { llmUrl?: string }): Promise<Handle> {
- const port = await freePort()
- const sandbox = await fs.mkdtemp(path.join(os.tmpdir(), `opencode-e2e-${label}-`))
- const appDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..")
- const repoDir = path.resolve(appDir, "../..")
- const opencodeDir = path.join(repoDir, "packages", "opencode")
- const env = {
- ...process.env,
- OPENCODE_DISABLE_LSP_DOWNLOAD: "true",
- OPENCODE_DISABLE_DEFAULT_PLUGINS: "true",
- OPENCODE_EXPERIMENTAL_DISABLE_FILEWATCHER: "true",
- OPENCODE_TEST_HOME: path.join(sandbox, "home"),
- XDG_DATA_HOME: path.join(sandbox, "share"),
- XDG_CACHE_HOME: path.join(sandbox, "cache"),
- XDG_CONFIG_HOME: path.join(sandbox, "config"),
- XDG_STATE_HOME: path.join(sandbox, "state"),
- OPENCODE_CLIENT: "app",
- OPENCODE_STRICT_CONFIG_DEPS: "true",
- OPENCODE_E2E_LLM_URL: input?.llmUrl,
- } satisfies Record<string, string | undefined>
- const out: string[] = []
- const err: string[] = []
- const proc = spawn(
- "bun",
- ["run", "--conditions=browser", "./src/index.ts", "serve", "--port", String(port), "--hostname", "127.0.0.1"],
- {
- cwd: opencodeDir,
- env,
- stdio: ["ignore", "pipe", "pipe"],
- },
- )
- proc.stdout?.on("data", (chunk) => {
- out.push(String(chunk))
- cap(out)
- })
- proc.stderr?.on("data", (chunk) => {
- err.push(String(chunk))
- cap(err)
- })
-
- const url = `http://127.0.0.1:${port}`
- try {
- await waitForHealth(url)
- } catch (error) {
- proc.kill("SIGTERM")
- await fs.rm(sandbox, { recursive: true, force: true }).catch(() => undefined)
- throw new Error(
- [
- `Failed to start isolated e2e backend for ${label}`,
- error instanceof Error ? error.message : String(error),
- tail(out),
- tail(err),
- ]
- .filter(Boolean)
- .join("\n"),
- )
- }
-
- return {
- url,
- async stop() {
- if (!done(proc)) {
- proc.kill("SIGTERM")
- await waitExit(proc)
- }
- if (!done(proc)) {
- proc.kill("SIGKILL")
- await waitExit(proc)
- }
- await fs.rm(sandbox, { recursive: true, force: true }).catch(() => undefined)
- },
- }
-}