84 lines
2.7 KiB
TypeScript
84 lines
2.7 KiB
TypeScript
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
import tmuxPlugin from "@aoagents/ao-plugin-runtime-tmux";
|
|
import type { RuntimeHandle } from "@aoagents/ao-core";
|
|
import { isTmuxAvailable, killSessionsByPrefix } from "./helpers/tmux.js";
|
|
import { sleep } from "./helpers/polling.js";
|
|
|
|
const tmuxOk = await isTmuxAvailable();
|
|
const SESSION_PREFIX = "ao-inttest-tmux-";
|
|
|
|
describe.skipIf(!tmuxOk)("runtime-tmux (integration)", () => {
|
|
const runtime = tmuxPlugin.create();
|
|
const sessionId = `${SESSION_PREFIX}${Date.now()}`;
|
|
let handle: RuntimeHandle;
|
|
|
|
beforeAll(async () => {
|
|
await killSessionsByPrefix(SESSION_PREFIX);
|
|
}, 30_000);
|
|
|
|
afterAll(async () => {
|
|
try {
|
|
await runtime.destroy(handle);
|
|
} catch {
|
|
/* best-effort cleanup */
|
|
}
|
|
await killSessionsByPrefix(SESSION_PREFIX);
|
|
}, 30_000);
|
|
|
|
it("creates a tmux session", async () => {
|
|
handle = await runtime.create({
|
|
sessionId,
|
|
workspacePath: "/tmp",
|
|
launchCommand: "cat", // cat will wait for stdin
|
|
environment: { AO_TEST: "1" },
|
|
});
|
|
|
|
expect(handle.id).toBe(sessionId);
|
|
expect(handle.runtimeName).toBe("tmux");
|
|
});
|
|
|
|
it("isAlive returns true for running session", async () => {
|
|
expect(await runtime.isAlive(handle)).toBe(true);
|
|
});
|
|
|
|
it("sendMessage sends text and getOutput captures it", async () => {
|
|
await runtime.sendMessage(handle, "hello world");
|
|
await sleep(500); // give tmux time to process
|
|
const output = await runtime.getOutput(handle);
|
|
expect(output).toContain("hello world");
|
|
});
|
|
|
|
it("sendMessage handles long text via buffer", async () => {
|
|
const longText = "x".repeat(250);
|
|
await runtime.sendMessage(handle, longText);
|
|
await sleep(500);
|
|
const output = await runtime.getOutput(handle);
|
|
// tmux wraps long text at column width, so strip ANSI escapes and newlines
|
|
// eslint-disable-next-line no-control-regex
|
|
const stripped = output.replace(/\x1b\[[0-9;]*m/g, "").replace(/\n/g, "");
|
|
expect(stripped).toContain(longText);
|
|
});
|
|
|
|
it("getMetrics returns uptime", async () => {
|
|
const metrics = await runtime.getMetrics!(handle);
|
|
expect(metrics.uptimeMs).toBeGreaterThan(0);
|
|
});
|
|
|
|
it("getAttachInfo returns tmux command", async () => {
|
|
const info = await runtime.getAttachInfo!(handle);
|
|
expect(info.type).toBe("tmux");
|
|
expect(info.target).toBe(sessionId);
|
|
expect(info.command).toContain("tmux attach");
|
|
});
|
|
|
|
it("destroy kills the session", async () => {
|
|
await runtime.destroy(handle);
|
|
expect(await runtime.isAlive(handle)).toBe(false);
|
|
});
|
|
|
|
it("destroy is idempotent", async () => {
|
|
// Should not throw even though session is already dead
|
|
await runtime.destroy(handle);
|
|
});
|
|
});
|