From 5b67fa9d61024a8e779423defefaee493f1ecd07 Mon Sep 17 00:00:00 2001 From: Shiv Lakshminarayan Date: Mon, 6 Jul 2020 22:49:40 -0700 Subject: [PATCH] only delete stack in failed status. added unit test for updating rollback_in_progress --- packages/aws-cdk/lib/api/deploy-stack.ts | 2 +- packages/aws-cdk/test/api/bootstrap.test.ts | 4 +-- .../aws-cdk/test/api/deploy-stack.test.ts | 31 ++++++++++++++++--- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/packages/aws-cdk/lib/api/deploy-stack.ts b/packages/aws-cdk/lib/api/deploy-stack.ts index bf9267986bdea..669558bf070dd 100644 --- a/packages/aws-cdk/lib/api/deploy-stack.ts +++ b/packages/aws-cdk/lib/api/deploy-stack.ts @@ -173,7 +173,7 @@ export async function deployStack(options: DeployStackOptions): Promise ({ Stacks: [ { - StackStatus: 'ROLLBACK_COMPLETE', + StackStatus: 'ROLLBACK_FAILED', StackStatusReason: 'It is magic', Outputs: [ { OutputKey: 'BucketName', OutputValue: 'bucket' }, @@ -225,7 +225,7 @@ test('even if the bootstrap stack failed to create, can still retry bootstrappin ] })) .mockImplementationOnce(() => ({ Stacks: [ { - StackStatus: 'ROLLBACK_COMPLETE', + StackStatus: 'ROLLBACK_FAILED', StackStatusReason: 'It is magic', Outputs: [ { OutputKey: 'BucketName', OutputValue: 'bucket' }, diff --git a/packages/aws-cdk/test/api/deploy-stack.test.ts b/packages/aws-cdk/test/api/deploy-stack.test.ts index 585665b3e23d9..95c8b0d08bb1c 100644 --- a/packages/aws-cdk/test/api/deploy-stack.test.ts +++ b/packages/aws-cdk/test/api/deploy-stack.test.ts @@ -249,10 +249,10 @@ test('deploy is not skipped if parameters are different', async () => { })); }); -test('if existing stack failed to create, it is deleted and recreated', async () => { +test('if existing stack failed, it is deleted and recreated', async () => { // GIVEN givenStackExists( - { StackStatus: 'ROLLBACK_COMPLETE' }, // This is for the initial check + { StackStatus: 'ROLLBACK_FAILED' }, // This is for the initial check { StackStatus: 'DELETE_COMPLETE' }, // Poll the successful deletion { StackStatus: 'CREATE_COMPLETE' }, // Poll the recreation ); @@ -275,10 +275,10 @@ test('if existing stack failed to create, it is deleted and recreated', async () })); }); -test('if existing stack failed to create, it is deleted and recreated even if the template did not change', async () => { +test('if existing stack is in a failed state, it is deleted and recreated even if the template did not change', async () => { // GIVEN givenStackExists( - { StackStatus: 'ROLLBACK_COMPLETE' }, // This is for the initial check + { StackStatus: 'ROLLBACK_FAILED' }, // This is for the initial check { StackStatus: 'DELETE_COMPLETE' }, // Poll the successful deletion { StackStatus: 'CREATE_COMPLETE' }, // Poll the recreation ); @@ -298,6 +298,29 @@ test('if existing stack failed to create, it is deleted and recreated even if th })); }); +test('stack in ROLLBACK_COMPLETE state can be updated', async () => { + // GIVEN + givenStackExists( + { StackStatus: 'ROLLBACK_COMPLETE' }, // This is for the initial check + { StackStatus: 'UPDATE_COMPLETE' }, // Poll the successful update + ); + givenTemplateIs({ changed: 123 }); + + // WHEN + await deployStack({ + stack: FAKE_STACK, + sdk, + sdkProvider, + resolvedEnvironment: mockResolvedEnvironment(), + }); + + // THEN + expect(cfnMocks.deleteStack).not.toHaveBeenCalled(); + expect(cfnMocks.createChangeSet).toHaveBeenCalledWith(expect.objectContaining({ + ChangeSetType: 'UPDATE', + })); +}); + test('deploy not skipped if template did not change and --force is applied', async () => { // GIVEN givenStackExists();