diff --git a/tools/@aws-cdk/integration-test-deployment/lib/integration-test-runner.ts b/tools/@aws-cdk/integration-test-deployment/lib/integration-test-runner.ts index b56c45b8124fc..0183538af4a6c 100644 --- a/tools/@aws-cdk/integration-test-deployment/lib/integration-test-runner.ts +++ b/tools/@aws-cdk/integration-test-deployment/lib/integration-test-runner.ts @@ -1,4 +1,4 @@ -/* eslint-disable no-console */ + import { spawn } from 'child_process'; import { STSClient, AssumeRoleCommand } from '@aws-sdk/client-sts'; import { AtmosphereAllocation } from './atmosphere'; @@ -53,7 +53,20 @@ export const deployIntegTests = async (props: { console.error(e); hasFailure = true; } finally { - await allocation.release(outcome); + try { + await allocation.release(outcome); + } catch (e) { + if (e instanceof Error && e.message.includes('The security token included in the request is expired')) { + // In case of timeouts, the expired security token error can occur. We can skip the release as it will automatically be deleted. + // Atmosphere will automatically release the resource if a timeout occurs on the backend. + // + // Log uses Github warning syntax, see: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-commands#setting-a-warning-message + console.warn(`::warning::Atmosphere allocation release failed: ${e}`); + console.warn('Skipping release request as we assume its caused by an integ test timing out.'); + } else { + throw e; + } + } } } diff --git a/tools/@aws-cdk/integration-test-deployment/test/integration-test-deployment.test.ts b/tools/@aws-cdk/integration-test-deployment/test/integration-test-deployment.test.ts index 3f38722b64415..001428b4ebf8c 100644 --- a/tools/@aws-cdk/integration-test-deployment/test/integration-test-deployment.test.ts +++ b/tools/@aws-cdk/integration-test-deployment/test/integration-test-deployment.test.ts @@ -100,4 +100,26 @@ describe('Run Integration Tests with Atmosphere', () => { validateSnapshotRun({ batchSize: 3 }); }); + + test('failed Atmosphere release requests after timeout creates a warning and proceeds with the next batch', async () => { + jest.spyOn(integRunner, 'deployIntegrationTest').mockImplementation(() => { + return Promise.reject(new Error('Integration tests failed with exit code 1')); + }); + + jest.spyOn(mockAtmosphereAllocation, 'release').mockImplementation(() => { + return Promise.reject(new Error('The security token included in the request is expired')); + }); + + const consoleSpy = jest.spyOn(console, 'warn').mockImplementation(); + + await expect(integRunner.deployIntegTests({ atmosphereRoleArn, endpoint, pool })).rejects.toThrow( + 'Deployment integration test did not pass', + ); + + expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('::warning::Atmosphere allocation release failed: Error: The security token included in the request is expired')); + + consoleSpy.mockRestore(); + + validateSnapshotRun({ batchSize: 3 }); + }); });