From dc7304d7c4db1c9c9ee2ed80a98d004371372771 Mon Sep 17 00:00:00 2001 From: Dotta Date: Mon, 12 Oct 2026 08:11:12 -0500 Subject: [PATCH] test: align Dot readiness fixtures and clean sealed runtime assets Enable the existing experiment only in its intended fixture journeys, and restore owner permissions only inside worker-owned scratch directories during exit cleanup. Co-Authored-By: Paperclip --- .../agent-test-environment-routes.test.ts | 13 ++++++++++++- server/src/__tests__/setup-supertest.ts | 16 +++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/server/src/__tests__/agent-test-environment-routes.test.ts b/server/src/__tests__/agent-test-environment-routes.test.ts index 62fbd70b57d..4bba678c432 100644 --- a/server/src/__tests__/agent-test-environment-routes.test.ts +++ b/server/src/__tests__/agent-test-environment-routes.test.ts @@ -47,7 +47,10 @@ const mockResolveEnvironmentExecutionTarget = vi.hoisted(() => vi.fn()); const mockInstanceSettingsService = vi.hoisted(() => ({ get: vi.fn(async () => ({ defaultEnvironmentId: null as string | null })), getGeneral: vi.fn(async () => ({ censorUsernameInLogs: false })), - getExperimental: vi.fn(async () => ({ enableManagedSandboxOnly: false })), + getExperimental: vi.fn(async (): Promise<{ + enableManagedSandboxOnly: boolean; + enableOpenAiDot?: boolean; + }> => ({ enableManagedSandboxOnly: false })), })); vi.mock("../services/index.js", () => ({ @@ -255,6 +258,10 @@ describe("agent test-environment route", () => { it("accepts a managed Dot environment without allocating an idle sandbox", async () => { vi.stubEnv("PAPERCLIP_PUBLIC_URL", "https://paperclip.example"); + mockInstanceSettingsService.getExperimental.mockResolvedValue({ + enableManagedSandboxOnly: false, + enableOpenAiDot: true, + }); mockInstanceSettingsService.get.mockResolvedValue({ defaultEnvironmentId: "11111111-1111-4111-8111-111111111111" }); const app = await createApp(); try { @@ -270,6 +277,10 @@ describe("agent test-environment route", () => { it("fails the Cloud Dot check without a managed sandbox instead of probing the host", async () => { vi.stubEnv("PAPERCLIP_PUBLIC_URL", "https://paperclip.example"); vi.stubEnv("PAPERCLIP_CLOUD_TENANT_SERVER_TOKEN", "test-cloud"); + mockInstanceSettingsService.getExperimental.mockResolvedValue({ + enableManagedSandboxOnly: false, + enableOpenAiDot: true, + }); const app = await createApp(); try { const res = await request(app).post("/api/companies/company-1/adapters/paperclip_runner/test-environment") diff --git a/server/src/__tests__/setup-supertest.ts b/server/src/__tests__/setup-supertest.ts index 9c7db2179d4..9165844e3f9 100644 --- a/server/src/__tests__/setup-supertest.ts +++ b/server/src/__tests__/setup-supertest.ts @@ -29,7 +29,21 @@ const paperclipTestHome = fs.mkdtempSync(path.join(os.tmpdir(), "paperclip-vites process.env.PAPERCLIP_HOME = paperclipTestHome; // Setup-file afterAll hooks run before suites drain asynchronous heartbeats. // Cleanup at worker exit, after all suite teardown, avoids deleting live state. -process.once("exit", () => fs.rmSync(paperclipTestHome, { recursive: true, force: true, maxRetries: 8, retryDelay: 50 })); +process.once("exit", () => { + // Native runtime assets intentionally seal their directories. Restore only + // this worker's scratch directories so teardown can unlink their contents; + // symlinks and immutable files keep their permissions. + const makeWritable = (directory: string): void => { + const stat = fs.lstatSync(directory, { throwIfNoEntry: false }); + if (!stat?.isDirectory()) return; + fs.chmodSync(directory, stat.mode | 0o700); + for (const entry of fs.readdirSync(directory, { withFileTypes: true })) { + if (entry.isDirectory()) makeWritable(path.join(directory, entry.name)); + } + }; + makeWritable(paperclipTestHome); + fs.rmSync(paperclipTestHome, { recursive: true, force: true, maxRetries: 8, retryDelay: 50 }); +}); const require = createRequire(import.meta.url); const SupertestTest = require("supertest/lib/test.js") as SupertestTestConstructor;