mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-23 21:16:06 +00:00
Run CLI subprocess tests concurrently (#28399)
This commit is contained in:
parent
34cae2f3cb
commit
a8f7c5ec93
3 changed files with 14 additions and 8 deletions
|
|
@ -10,7 +10,7 @@ import { cliIt } from "../../lib/cli-process"
|
|||
describe("opencode run (non-interactive subprocess)", () => {
|
||||
// Happy path: prompt completes, output reaches stdout, process exits 0.
|
||||
// If this fails, all the others likely will too — debug here first.
|
||||
cliIt.live(
|
||||
cliIt.concurrent(
|
||||
"exits 0 and writes the response to stdout on a successful prompt",
|
||||
({ llm, opencode }) =>
|
||||
Effect.gen(function* () {
|
||||
|
|
@ -27,7 +27,7 @@ describe("opencode run (non-interactive subprocess)", () => {
|
|||
// makes the SDK call surface an error promptly so the process exits nonzero.
|
||||
// We assert nonzero exit AND wall-clock under the harness timeout — a hang
|
||||
// would expire the timeout and produce a different (signal-killed) failure.
|
||||
cliIt.live(
|
||||
cliIt.concurrent(
|
||||
"exits nonzero promptly when the model is unknown (regression for #27371)",
|
||||
({ opencode }) =>
|
||||
Effect.gen(function* () {
|
||||
|
|
@ -47,7 +47,7 @@ describe("opencode run (non-interactive subprocess)", () => {
|
|||
//
|
||||
// This is debatable — a future cleanup might flip it to exit 1. If you're
|
||||
// changing this expectation, do it deliberately and say so in the PR.
|
||||
cliIt.live(
|
||||
cliIt.concurrent(
|
||||
"mid-stream LLM error still exits 0 today (contract lock-in)",
|
||||
({ llm, opencode }) =>
|
||||
Effect.gen(function* () {
|
||||
|
|
@ -61,7 +61,7 @@ describe("opencode run (non-interactive subprocess)", () => {
|
|||
// --format json puts one JSON object per line on stdout for each emitted
|
||||
// event. Consumers (CI scripts, tooling) parse this stream. Asserts the
|
||||
// shape so a future event-emit change has to update this expectation.
|
||||
cliIt.live(
|
||||
cliIt.concurrent(
|
||||
"--format json emits parseable line-delimited JSON to stdout",
|
||||
({ llm, opencode }) =>
|
||||
Effect.gen(function* () {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
// builders (`opencode.serve(opts)`, `opencode.acp(opts)`, `opencode.auth(...)`)
|
||||
// without changing the fixture. Long-lived commands like `serve` will need a
|
||||
// different return shape — see the TODO at the bottom of OpencodeCli.
|
||||
import type { TestOptions } from "bun:test"
|
||||
import { test, type TestOptions } from "bun:test"
|
||||
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
||||
import { AppProcess } from "@opencode-ai/core/process"
|
||||
import { Deferred, Duration, Effect, Layer, Queue, Scope, Stream } from "effect"
|
||||
|
|
@ -439,9 +439,9 @@ function expectExit(result: RunResult, expected: number, label = "opencode") {
|
|||
// `it.live(name, () => withCliFixture(fixture))` — one fewer nesting level at
|
||||
// every call site. Use this for any test that needs the opencode CLI fixture.
|
||||
//
|
||||
// Only `.live` is exposed because subprocess tests must run against the real
|
||||
// clock — a TestClock-paused environment can't drive a child process. If you
|
||||
// need `.only` or `.skip`, fall back to `it.live` + `withCliFixture` directly.
|
||||
// Subprocess tests must run against the real clock — a TestClock-paused
|
||||
// environment can't drive a child process. If you need `.only` or `.skip`, fall
|
||||
// back to `it.live` + `withCliFixture` directly.
|
||||
// Body's R is `Scope.Scope | never` so tests can yield* scope-requiring
|
||||
// resources (e.g. `opencode.serve`) without an extra `Effect.scoped` wrapper —
|
||||
// `withCliFixture`'s outer scope is the natural lifetime.
|
||||
|
|
@ -451,4 +451,9 @@ export const cliIt = {
|
|||
body: (input: CliFixture) => Effect.Effect<A, E, Scope.Scope | HttpClient.HttpClient>,
|
||||
opts?: number | TestOptions,
|
||||
) => it.live(name, () => withCliFixture(body), opts),
|
||||
concurrent: <A, E>(
|
||||
name: string,
|
||||
body: (input: CliFixture) => Effect.Effect<A, E, Scope.Scope | HttpClient.HttpClient>,
|
||||
opts?: number | TestOptions,
|
||||
) => test.concurrent(name, () => Effect.runPromise(Effect.scoped(withCliFixture(body))), opts),
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue