Skip to content

Commit 2f1d59f

Browse files
authored
fix(e2e): clean up stale credential providers before test runs (#698)
E2e tests create API key credential providers that leak when CI kills the process before afterAll teardown runs. Over multiple runs these accumulate and hit the account-level limit, causing all deploys to fail. Add cleanupStaleCredentialProviders() in beforeAll that lists all E2e* providers older than 1 hour and deletes them, preventing accumulation regardless of how previous runs terminated. Constraint: Only deletes providers with E2e prefix to avoid touching non-test resources Constraint: 1-hour age threshold avoids deleting providers from a concurrent test run Confidence: high Scope-risk: narrow
1 parent 9c7f143 commit 2f1d59f

1 file changed

Lines changed: 34 additions & 0 deletions

File tree

e2e-tests/e2e-helper.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
BedrockAgentCoreControlClient,
1111
DeleteApiKeyCredentialProviderCommand,
1212
GetAgentRuntimeCommand,
13+
ListApiKeyCredentialProvidersCommand,
1314
} from '@aws-sdk/client-bedrock-agentcore-control';
1415
import { execSync } from 'node:child_process';
1516
import { randomUUID } from 'node:crypto';
@@ -46,6 +47,8 @@ export function createE2ESuite(cfg: E2EConfig) {
4647
beforeAll(async () => {
4748
if (!canRun) return;
4849

50+
await cleanupStaleCredentialProviders();
51+
4952
testDir = join(tmpdir(), `agentcore-e2e-${randomUUID()}`);
5053
await mkdir(testDir, { recursive: true });
5154

@@ -329,6 +332,37 @@ export function installCdkTarball(projectPath: string): void {
329332
}
330333
}
331334

335+
/**
336+
* Delete stale E2e* credential providers older than the given max age.
337+
* Runs in beforeAll to prevent accumulation from previous runs that
338+
* crashed or timed out before their afterAll teardown could execute.
339+
*/
340+
export async function cleanupStaleCredentialProviders(maxAgeMs: number = 60 * 60 * 1000): Promise<void> {
341+
const region = process.env.AWS_REGION ?? 'us-east-1';
342+
const client = new BedrockAgentCoreControlClient({ region });
343+
const cutoff = new Date(Date.now() - maxAgeMs);
344+
345+
let nextToken: string | undefined;
346+
do {
347+
const response = await client.send(new ListApiKeyCredentialProvidersCommand({ nextToken }));
348+
const providers = response.credentialProviders ?? [];
349+
const stale = providers.filter(p => p.name?.startsWith('E2e') && p.createdTime && p.createdTime < cutoff);
350+
351+
await Promise.all(
352+
stale.map(async p => {
353+
try {
354+
await client.send(new DeleteApiKeyCredentialProviderCommand({ name: p.name! }));
355+
console.log(`Cleaned up stale credential provider: ${p.name}`);
356+
} catch {
357+
console.warn(`Failed to clean up stale credential provider: ${p.name}`);
358+
}
359+
})
360+
);
361+
362+
nextToken = response.nextToken;
363+
} while (nextToken);
364+
}
365+
332366
export async function teardownE2EProject(projectPath: string, agentName: string, modelProvider: string): Promise<void> {
333367
await spawnAndCollect('agentcore', ['remove', 'all', '--json'], projectPath);
334368
const result = await spawnAndCollect('agentcore', ['deploy', '--yes', '--json'], projectPath);

0 commit comments

Comments
 (0)