diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/drift/cdk-cdk-drift---verbose-shows-unchecked-resources.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/drift/cdk-cdk-drift---verbose-shows-unchecked-resources.integtest.ts deleted file mode 100644 index d8a5ef58e..000000000 --- a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/drift/cdk-cdk-drift---verbose-shows-unchecked-resources.integtest.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { integTest, withDefaultFixture } from '../../../lib'; - -integTest( - 'cdk drift --verbose shows unchecked resources', - withDefaultFixture(async (fixture) => { - await fixture.cdkDeploy('define-vpc', { modEnv: { ENABLE_VPC_TESTING: 'DEFINE' } }); - - // Assert that there's no drift when we deploy it, but there should be - // unchecked resources, as there are some EC2 connection resources - // (e.g. SubnetRouteTableAssociation) that do not support drift detection - const drift = await fixture.cdk(['drift', '--verbose', fixture.fullStackName('define-vpc')], { modEnv: { ENABLE_VPC_TESTING: 'DEFINE' } }); - - expect(drift).toMatch(/Stack.*define-vpc/); // cant just .toContain because of formatting - expect(drift).toContain('No drift detected'); - expect(drift).toContain('(3 unchecked)'); // 2 SubnetRouteTableAssociations, 1 VPCGatewayAttachment - }), -); diff --git a/packages/@aws-cdk/toolkit-lib/test/actions/drift.test.ts b/packages/@aws-cdk/toolkit-lib/test/actions/drift.test.ts index 9d13b04da..e9c0f07f0 100644 --- a/packages/@aws-cdk/toolkit-lib/test/actions/drift.test.ts +++ b/packages/@aws-cdk/toolkit-lib/test/actions/drift.test.ts @@ -88,4 +88,57 @@ describe('drift', () => { expect(Object.keys(result).length).toBe(0); ioHost.expectMessage({ containing: 'No drift results available' }); }); + + test('resources without a drift record are reported as unchecked in the summary', async () => { + // GIVEN - drift detection completes, but CloudFormation returns no drift + // record for the bucket (e.g. the resource type does not support drift + // detection) + mockCloudFormationClient.on(DetectStackDriftCommand).resolves({ StackDriftDetectionId: '12345' }); + mockCloudFormationClient.on(DescribeStackDriftDetectionStatusCommand).resolves({ DetectionStatus: 'DETECTION_COMPLETE' }); + mockCloudFormationClient.on(DescribeStackResourceDriftsCommand).resolvesOnce({ + StackResourceDrifts: [], + }); + + // WHEN + const cx = await builderFixture(toolkit, 'stack-with-bucket'); + const result = await toolkit.drift(cx, { + stacks: { strategy: StackSelectionStrategy.ALL_STACKS }, + }); + + // THEN + expect(result.Stack1.numResourcesWithDrift).toBe(0); + expect(result.Stack1.numResourcesUnchecked).toBe(1); + // the final tally includes the unchecked count + ioHost.expectMessage({ containing: 'Number of resources with drift: 0 (1 unchecked)' }); + }); + + test('summary has no unchecked suffix when all resources were checked', async () => { + // GIVEN - every resource has a drift record + mockCloudFormationClient.on(DetectStackDriftCommand).resolves({ StackDriftDetectionId: '12345' }); + mockCloudFormationClient.on(DescribeStackDriftDetectionStatusCommand).resolves({ DetectionStatus: 'DETECTION_COMPLETE' }); + mockCloudFormationClient.on(DescribeStackResourceDriftsCommand).resolvesOnce({ + StackResourceDrifts: [ + { + StackId: 'some:stack:arn', + StackResourceDriftStatus: 'IN_SYNC', + LogicalResourceId: 'MyBucketF68F3FF0', + PhysicalResourceId: 'physical-id-1', + ResourceType: 'AWS::S3::Bucket', + Timestamp: new Date(Date.now()), + }, + ], + }); + + // WHEN + const cx = await builderFixture(toolkit, 'stack-with-bucket'); + const result = await toolkit.drift(cx, { + stacks: { strategy: StackSelectionStrategy.ALL_STACKS }, + }); + + // THEN + expect(result.Stack1.numResourcesWithDrift).toBe(0); + expect(result.Stack1.numResourcesUnchecked).toBe(0); + ioHost.expectMessage({ containing: 'Number of resources with drift: 0' }); + expect(() => ioHost.expectMessage({ containing: 'unchecked' })).toThrow(); + }); });