Skip to content
Closed
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 44 additions & 7 deletions apps/server/src/terminal/Layers/Manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ function multiTerminalHistoryLogPath(
interface CreateManagerOptions {
shellResolver?: () => string;
subprocessChecker?: (terminalPid: number) => Effect.Effect<boolean>;
subprocessInspector?: (
terminalPid: number,
) => Effect.Effect<{ hasRunningSubprocess: boolean; runningPorts: number[] }>;
webPortInspector?: (port: number) => Effect.Effect<boolean>;
subprocessPollIntervalMs?: number;
processKillGraceMs?: number;
maxRetainedInactiveSessions?: number;
Expand Down Expand Up @@ -225,6 +229,12 @@ const createManager = (
...(options.subprocessChecker !== undefined
? { subprocessChecker: options.subprocessChecker }
: {}),
...(options.subprocessInspector !== undefined
? { subprocessInspector: options.subprocessInspector }
: {}),
...(options.webPortInspector !== undefined
? { webPortInspector: options.webPortInspector }
: {}),
...(options.subprocessPollIntervalMs !== undefined
? { subprocessPollIntervalMs: options.subprocessPollIntervalMs }
: {}),
Expand Down Expand Up @@ -548,29 +558,56 @@ it.layer(NodeServices.layer, { excludeTestServices: true })("TerminalManager", (
}),
);

it.effect("emits subprocess activity events when child-process state changes", () =>
it.effect("emits subprocess activity events when child-process state or web ports change", () =>
Effect.gen(function* () {
let hasRunningSubprocess = false;
let activity = {
hasRunningSubprocess: false,
runningPorts: [] as number[],
};
const { manager, getEvents } = yield* createManager(5, {
subprocessChecker: () => Effect.succeed(hasRunningSubprocess),
subprocessInspector: () => Effect.succeed(activity),
webPortInspector: (port) => Effect.succeed(port === 3000),
subprocessPollIntervalMs: 20,
});

yield* manager.open(openInput());
expect((yield* getEvents).some((event) => event.type === "activity")).toBe(false);

hasRunningSubprocess = true;
activity = { hasRunningSubprocess: true, runningPorts: [3000] };
yield* waitFor(
Effect.map(getEvents, (events) =>
events.some((event) => event.type === "activity" && event.hasRunningSubprocess === true),
events.some(
(event) =>
event.type === "activity" &&
event.hasRunningSubprocess === true &&
event.runningPorts.join(",") === "3000",
),
),
"1200 millis",
);

hasRunningSubprocess = false;
activity = { hasRunningSubprocess: true, runningPorts: [5173] };
yield* waitFor(
Effect.map(getEvents, (events) =>
events.some((event) => event.type === "activity" && event.hasRunningSubprocess === false),
events.some(
(event) =>
event.type === "activity" &&
event.hasRunningSubprocess === true &&
event.runningPorts.length === 0,
),
),
"1200 millis",
);

activity = { hasRunningSubprocess: false, runningPorts: [5173] };
yield* waitFor(
Effect.map(getEvents, (events) =>
events.some(
(event) =>
event.type === "activity" &&
event.hasRunningSubprocess === false &&
event.runningPorts.length === 0,
),
),
"1200 millis",
);
Expand Down
Loading
Loading