test: extend sandbox idle window for recovery qualification

Give the explicit controller-outage fixture a provider idle window beyond the five-minute outage and replacement startup budget. Preserve generic fixtures, native lifecycle timing, ownership and reconnect limits.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-30 16:50:00 -05:00
1 parent abed921e12
commit 0b6afc499f
3 files changed
+44 -2

No files matched your search

+3
View File
@@ -22,6 +22,9 @@ oracle requires the same retained provider session and a new useful result.
It permits one attempt per cell and retains failed evidence. This is
development API-key acceptance, distinct from staging subscription recovery.
The five-minute outage is a resilience test, not an HTTP downtime allowance.
This suite gives its Daytona sandbox a 15-minute provider auto-stop interval,
leaving headroom for the outage and replacement startup. Native agent idle timing,
ownership/reconnect limits, archive/delete backstops and owned cleanup remain unchanged.
The explicit-only [GitHub review bot journey](GITHUB-REVIEW-JOURNEY.md) tests
attended bot setup and an automatic PR review against an attached deployment.
+31
View File
@@ -33,6 +33,37 @@ import {
} from "./selectors.js";
describe("runner E2E catalog", () => {
it("keeps the Daytona controller outage inside the provider idle lifetime", () => {
const suite = runnerSuites.find(candidate => candidate.id === "daytona-restart-continuity")!;
const secretRefs = {
OPENAI_API_KEY: { type: "secret_ref" as const, secretId: "22222222-2222-4222-8222-222222222222", version: "latest" as const },
ANTHROPIC_API_KEY: { type: "secret_ref" as const, secretId: "33333333-3333-4333-8333-333333333333", version: "latest" as const },
DAYTONA_API_KEY: { type: "secret_ref" as const, secretId: "44444444-4444-4444-8444-444444444444", version: "latest" as const },
};
const environmentInput = { executionId: "controller-outage", secretRefs, daytonaImage: `fixture@sha256:${"a".repeat(64)}` };
const base = runnerEnvironments.find(environment => environment.id === "daytona")!;
const baseConfig = base.buildEnvironment(environmentInput).config as Record<string, unknown>;
const cells = runnerMatrix.filter(entry => entry.suite.id === suite.id);
expect(cells).toHaveLength(2);
for (const cell of cells) {
const config = cell.environment.buildEnvironment(environmentInput).config as Record<string, unknown>;
expect(config.autoStopInterval).toBe(15);
expect(Number(config.autoStopInterval) * 60_000).toBeGreaterThan(420_000);
expect(config).toEqual({ ...baseConfig, autoStopInterval: 15 });
expect(cell.environment.configurationKey).toBe("controller-outage-v1");
const agentInput = { ...environmentInput, environmentId: "env-1", environmentFixtureId: "daytona" as const, workspacePath: "/workspace" };
const adapterConfig = cell.profile.buildAgent(agentInput).adapterConfig as Record<string, unknown>;
const original = runnerProfiles.find(profile => profile.id === cell.profile.id)!.buildAgent(agentInput).adapterConfig as Record<string, unknown>;
expect(adapterConfig.idleTimeoutMs).toBe(300_000);
expect(adapterConfig.lifecycleMode).toBe(original.lifecycleMode);
expect(cell.suite.manualOnly).toBe(true);
expect(cell.task.automaticRetryPolicy).toBe("single_attempt");
}
expect(baseConfig.autoStopInterval).toBe(5);
expect(daytonaWarmEnvironment.buildEnvironment(environmentInput).config).toMatchObject({ autoStopInterval: 5 });
expect(suite.definitionMetadata).toMatchObject({ version: 4, controllerDowntimeMs: 300_000, autoStopIntervalMinutes: 15 });
});
it.each([
["runner-codex-subscription", "CODEX_AUTH_JSON"], ["runner-codex", "OPENAI_API_KEY"],
])("keeps %s receipt smoke separately selectable with exactly four bounded native turns", (profile, credential) => {
+10 -2
View File
@@ -1162,10 +1162,18 @@ export const runnerSuites: readonly RunnerSuiteFixture[] = [
id: "daytona-restart-continuity", label: "Daytona controller outage continuity", manualOnly: true,
description: "Keep the original active native runner, task tools and saved files through five minutes without a controller, then continue the completed session after another replacement.",
groups: [], profiles: repositoryModelProfiles.map(({ native }) => productionStoryProfile(native)),
environments: runnerEnvironments.filter(environment => environment.id === "daytona"),
environments: runnerEnvironments.filter(environment => environment.id === "daytona").map(environment => ({
...environment,
configurationKey: "controller-outage-v1",
buildEnvironment(input: EnvironmentFixtureBuildInput) {
const payload = environment.buildEnvironment(input);
// Keep provider idle stop beyond the outage and replacement budget.
return { ...payload, config: { ...(payload.config as Record<string, unknown>), autoStopInterval: 15 } };
},
})),
tasks: everydayTasks.filter(task => task.id === "recover-controller")
.map(task => ({ ...task, expectedRunCount: task.expectedRunCount + 1, automaticRetryPolicy: "single_attempt" as const })), expectedMatrixSize: 2,
definitionMetadata: { version: 3, scheduling: "explicit-only", controllerDowntimeMs: 300_000, retainedControllerContinuation: true,
definitionMetadata: { version: 4, scheduling: "explicit-only", controllerDowntimeMs: 300_000, autoStopIntervalMinutes: 15, retainedControllerContinuation: true,
maximumAttemptsPerCell: 1, budgetMonthlyCents: 1000, instructions: "production", grading: "same-active-process-lease-native-prefix-and-workspace-receipt",
authentication: "api-key", stagingAuthentication: "subscription", stagingQualification: false },
},