diff --git a/packages/@aws-cdk/aws-rds/package.json b/packages/@aws-cdk/aws-rds/package.json index bd56c7dd94539..0da51c0d59691 100644 --- a/packages/@aws-cdk/aws-rds/package.json +++ b/packages/@aws-cdk/aws-rds/package.json @@ -79,7 +79,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "@aws-cdk/aws-events-targets": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/cdk-build-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-rds/test/cluster-engine.test.ts b/packages/@aws-cdk/aws-rds/test/cluster-engine.test.ts index 826c988688c24..f6e3824092442 100644 --- a/packages/@aws-cdk/aws-rds/test/cluster-engine.test.ts +++ b/packages/@aws-cdk/aws-rds/test/cluster-engine.test.ts @@ -1,4 +1,3 @@ -import '@aws-cdk/assert-internal/jest'; import { AuroraEngineVersion, AuroraMysqlEngineVersion, AuroraPostgresEngineVersion, DatabaseClusterEngine } from '../lib'; describe('cluster engine', () => { @@ -11,8 +10,6 @@ describe('cluster engine', () => { // THEN expect(family).toEqual('aurora5.6'); - - }); test("default parameterGroupFamily for versionless Aurora MySQL cluster engine is 'aurora-mysql5.7'", () => { @@ -24,8 +21,6 @@ describe('cluster engine', () => { // THEN expect(family).toEqual('aurora-mysql5.7'); - - }); test('default parameterGroupFamily for versionless Aurora PostgreSQL is not defined', () => { @@ -37,8 +32,6 @@ describe('cluster engine', () => { // THEN expect(family).toEqual(undefined); - - }); test('cluster parameter group correctly determined for AURORA and given version', () => { @@ -52,8 +45,6 @@ describe('cluster engine', () => { // THEN expect(family).toEqual('aurora5.6'); - - }); test('cluster parameter group correctly determined for AURORA_MYSQL and given version', () => { @@ -67,8 +58,6 @@ describe('cluster engine', () => { // THEN expect(family).toEqual('aurora-mysql5.7'); - - }); test('cluster parameter group correctly determined for AURORA_MYSQL and given version 3', () => { @@ -95,8 +84,6 @@ describe('cluster engine', () => { // THEN expect(family).toEqual('aurora-postgresql11'); - - }); test('parameter group family', () => { @@ -117,8 +104,6 @@ describe('cluster engine', () => { 'aurora-postgresql9.6'); expect(DatabaseClusterEngine.auroraPostgres({ version: AuroraPostgresEngineVersion.of('10.0', '10') }).parameterGroupFamily).toEqual( 'aurora-postgresql10'); - - }); test('supported log types', () => { @@ -126,6 +111,5 @@ describe('cluster engine', () => { expect(DatabaseClusterEngine.aurora({ version: AuroraEngineVersion.VER_1_22_2 }).supportedLogTypes).toEqual(mysqlLogTypes); expect(DatabaseClusterEngine.auroraMysql({ version: AuroraMysqlEngineVersion.VER_2_08_1 }).supportedLogTypes).toEqual(mysqlLogTypes); expect(DatabaseClusterEngine.auroraPostgres({ version: AuroraPostgresEngineVersion.VER_9_6_9 }).supportedLogTypes).toEqual(['postgresql']); - }); -}); \ No newline at end of file +}); diff --git a/packages/@aws-cdk/aws-rds/test/cluster.test.ts b/packages/@aws-cdk/aws-rds/test/cluster.test.ts index b3dbdfc81d007..1681f397c5a9f 100644 --- a/packages/@aws-cdk/aws-rds/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-rds/test/cluster.test.ts @@ -1,5 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; -import { ABSENT, ResourcePart, SynthUtils } from '@aws-cdk/assert-internal'; +import { Match, Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import { ManagedPolicy, Role, ServicePrincipal } from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; @@ -34,7 +33,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResource('AWS::RDS::DBCluster', { Properties: { Engine: 'aurora', DBSubnetGroupName: { Ref: 'DatabaseSubnets56F17B9A' }, @@ -46,13 +45,13 @@ describe('cluster', () => { }, DeletionPolicy: 'Snapshot', UpdateReplacePolicy: 'Snapshot', - }, ResourcePart.CompleteDefinition); + }); - expect(stack).toCountResources('AWS::RDS::DBInstance', 2); - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).resourceCountIs('AWS::RDS::DBInstance', 2); + Template.fromStack(stack).hasResource('AWS::RDS::DBInstance', { DeletionPolicy: 'Delete', UpdateReplacePolicy: 'Delete', - }, ResourcePart.CompleteDefinition); + }); }); test('validates that the number of instances is not a deploy-time value', () => { @@ -91,7 +90,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { Engine: 'aurora', DBSubnetGroupName: { Ref: 'DatabaseSubnets56F17B9A' }, MasterUsername: 'admin', @@ -146,7 +145,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { Engine: 'aurora', DBSubnetGroupName: { Ref: 'DatabaseSubnets56F17B9A' }, MasterUsername: 'admin', @@ -182,7 +181,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { DBClusterParameterGroupName: { Ref: 'ParamsA8366201' }, }); }); @@ -201,10 +200,10 @@ describe('cluster', () => { removalPolicy: cdk.RemovalPolicy.RETAIN, }); - expect(stack).toHaveResourceLike('AWS::RDS::DBSubnetGroup', { + Template.fromStack(stack).hasResource('AWS::RDS::DBSubnetGroup', { DeletionPolicy: 'Retain', UpdateReplacePolicy: 'Retain', - }, ResourcePart.CompleteDefinition); + }); }); test('creates a secret when master credentials are not specified', () => { @@ -226,7 +225,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { MasterUsername: { 'Fn::Join': [ '', @@ -253,7 +252,7 @@ describe('cluster', () => { }, }); - expect(stack).toHaveResource('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { GenerateSecretString: { ExcludeCharacters: '\"@/\\', GenerateStringKey: 'password', @@ -282,7 +281,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { KmsKeyId: { 'Fn::GetAtt': [ 'Key961B73FD', @@ -316,7 +315,7 @@ describe('cluster', () => { }, }); - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { DBParameterGroupName: { Ref: 'ParameterGroup5E32DECB', }, @@ -343,7 +342,7 @@ describe('cluster', () => { }, }); - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { EnablePerformanceInsights: true, PerformanceInsightsRetentionPeriod: 731, PerformanceInsightsKMSKeyId: { 'Fn::GetAtt': ['Key961B73FD', 'Arn'] }, @@ -367,7 +366,7 @@ describe('cluster', () => { }, }); - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { EnablePerformanceInsights: true, PerformanceInsightsRetentionPeriod: 731, }); @@ -408,7 +407,7 @@ describe('cluster', () => { }, }); - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { AutoMinorVersionUpgrade: false, }); }); @@ -427,7 +426,7 @@ describe('cluster', () => { }, }); - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { AllowMajorVersionUpgrade: true, }); }); @@ -446,7 +445,7 @@ describe('cluster', () => { }, }); - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { DeleteAutomatedBackups: false, }); }); @@ -471,7 +470,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { Engine: 'aurora-mysql', EngineVersion: '5.7.mysql_aurora.2.04.4', }); @@ -497,12 +496,10 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { Engine: 'aurora-postgresql', EngineVersion: '10.7', }); - - }); test('cluster exposes different read and write endpoints', () => { @@ -546,7 +543,7 @@ describe('cluster', () => { cluster.connections.allowToAnyIpv4(ec2.Port.tcp(443)); // THEN - expect(stack).toHaveResource('AWS::EC2::SecurityGroupEgress', { + Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroupEgress', { GroupId: 'sg-123456789', }); }); @@ -559,8 +556,6 @@ describe('cluster', () => { }); expect(cluster.clusterIdentifier).toEqual('identifier'); - - }); test('minimal imported cluster throws on accessing attributes for unprovided parameters', () => { @@ -621,8 +616,6 @@ describe('cluster', () => { account: '12345', region: 'us-test-1', }); - - }); test('cluster with enabled monitoring', () => { @@ -645,14 +638,14 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { MonitoringInterval: 60, MonitoringRoleArn: { 'Fn::GetAtt': ['DatabaseMonitoringRole576991DA', 'Arn'], }, - }, ResourcePart.Properties); + }); - expect(stack).toHaveResource('AWS::IAM::Role', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { AssumeRolePolicyDocument: { Statement: [ { @@ -680,8 +673,6 @@ describe('cluster', () => { }, ], }); - - }); test('create a cluster with imported monitoring role', () => { @@ -712,14 +703,12 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { MonitoringInterval: 60, MonitoringRoleArn: { 'Fn::GetAtt': ['MonitoringRole90457BF9', 'Arn'], }, - }, ResourcePart.Properties); - - + }); }); test('addRotationSingleUser()', () => { @@ -737,7 +726,7 @@ describe('cluster', () => { // WHEN cluster.addRotationSingleUser(); - expect(stack).toHaveResource('AWS::SecretsManager::RotationSchedule', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::RotationSchedule', { SecretId: { Ref: 'DatabaseSecretAttachmentE5D1B020', }, @@ -768,7 +757,7 @@ describe('cluster', () => { const userSecret = new DatabaseSecret(stack, 'UserSecret', { username: 'user' }); cluster.addRotationMultiUser('user', { secret: userSecret.attach(cluster) }); - expect(stack).toHaveResource('AWS::SecretsManager::RotationSchedule', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::RotationSchedule', { SecretId: { Ref: 'UserSecretAttachment16ACBE6D', }, @@ -783,7 +772,7 @@ describe('cluster', () => { }, }); - expect(stack).toHaveResourceLike('AWS::Serverless::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::Serverless::Application', { Parameters: { masterSecretArn: { Ref: 'DatabaseSecretAttachmentE5D1B020', @@ -822,13 +811,13 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::SecretsManager::RotationSchedule', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::RotationSchedule', { RotationRules: { AutomaticallyAfterDays: 15, }, }); - expect(stack).toHaveResource('AWS::Serverless::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::Serverless::Application', { Parameters: { endpoint: { 'Fn::Join': ['', [ @@ -882,7 +871,7 @@ describe('cluster', () => { // Rotation in isolated subnet with access to Secrets Manager API via endpoint cluster.addRotationSingleUser({ endpoint }); - expect(stack).toHaveResource('AWS::Serverless::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::Serverless::Application', { Parameters: { endpoint: { 'Fn::Join': ['', [ @@ -933,8 +922,6 @@ describe('cluster', () => { // THEN expect(() => cluster.addRotationSingleUser()).toThrow(/without secret/); - - }); test('throws when trying to add single user rotation multiple times', () => { @@ -955,8 +942,6 @@ describe('cluster', () => { // THEN expect(() => cluster.addRotationSingleUser()).toThrow(/A single user rotation was already added to this cluster/); - - }); test('create a cluster with s3 import role', () => { @@ -983,7 +968,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { AssociatedRoles: [{ RoleArn: { 'Fn::GetAtt': [ @@ -994,7 +979,7 @@ describe('cluster', () => { }], }); - expect(stack).toHaveResource('AWS::RDS::DBClusterParameterGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBClusterParameterGroup', { Family: 'aurora5.6', Parameters: { aurora_load_from_s3_role: { @@ -1005,8 +990,6 @@ describe('cluster', () => { }, }, }); - - }); test('create a cluster with s3 import buckets', () => { @@ -1031,7 +1014,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { AssociatedRoles: [{ RoleArn: { 'Fn::GetAtt': [ @@ -1042,7 +1025,7 @@ describe('cluster', () => { }], }); - expect(stack).toHaveResource('AWS::RDS::DBClusterParameterGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBClusterParameterGroup', { Family: 'aurora5.6', Parameters: { aurora_load_from_s3_role: { @@ -1054,7 +1037,7 @@ describe('cluster', () => { }, }); - expect(stack).toHaveResource('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -1091,8 +1074,6 @@ describe('cluster', () => { Version: '2012-10-17', }, }); - - }); test('cluster with s3 import bucket adds supported feature name to IAM role', () => { @@ -1119,7 +1100,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { AssociatedRoles: [{ RoleArn: { 'Fn::GetAtt': [ @@ -1130,8 +1111,6 @@ describe('cluster', () => { FeatureName: 's3Import', }], }); - - }); test('throws when s3 import bucket or s3 export bucket is supplied for a Postgres version that does not support it', () => { @@ -1175,8 +1154,6 @@ describe('cluster', () => { s3ExportBuckets: [bucket], }); }).toThrow(/s3Export is not supported for Postgres version: 10.4. Use a version that supports the s3Export feature./); - - }); test('cluster with s3 export bucket adds supported feature name to IAM role', () => { @@ -1203,7 +1180,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { AssociatedRoles: [{ RoleArn: { 'Fn::GetAtt': [ @@ -1214,8 +1191,6 @@ describe('cluster', () => { FeatureName: 's3Export', }], }); - - }); test('create a cluster with s3 export role', () => { @@ -1242,7 +1217,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { AssociatedRoles: [{ RoleArn: { 'Fn::GetAtt': [ @@ -1253,7 +1228,7 @@ describe('cluster', () => { }], }); - expect(stack).toHaveResource('AWS::RDS::DBClusterParameterGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBClusterParameterGroup', { Family: 'aurora5.6', Parameters: { aurora_select_into_s3_role: { @@ -1264,8 +1239,6 @@ describe('cluster', () => { }, }, }); - - }); testFutureBehavior('create a cluster with s3 export buckets', { [cxapi.S3_GRANT_WRITE_WITHOUT_ACL]: true }, cdk.App, (app) => { @@ -1290,7 +1263,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { AssociatedRoles: [{ RoleArn: { 'Fn::GetAtt': [ @@ -1301,7 +1274,7 @@ describe('cluster', () => { }], }); - expect(stack).toHaveResource('AWS::RDS::DBClusterParameterGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBClusterParameterGroup', { Family: 'aurora5.6', Parameters: { aurora_select_into_s3_role: { @@ -1313,7 +1286,7 @@ describe('cluster', () => { }, }); - expect(stack).toHaveResource('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -1353,8 +1326,6 @@ describe('cluster', () => { Version: '2012-10-17', }, }); - - }); test('create a cluster with s3 import and export buckets', () => { @@ -1381,7 +1352,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { AssociatedRoles: [{ RoleArn: { 'Fn::GetAtt': [ @@ -1400,7 +1371,7 @@ describe('cluster', () => { }], }); - expect(stack).toHaveResource('AWS::RDS::DBClusterParameterGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBClusterParameterGroup', { Family: 'aurora5.6', Parameters: { aurora_load_from_s3_role: { @@ -1417,8 +1388,6 @@ describe('cluster', () => { }, }, }); - - }); test('create a cluster with s3 import and export buckets and custom parameter group', () => { @@ -1453,7 +1422,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { AssociatedRoles: [{ RoleArn: { 'Fn::GetAtt': [ @@ -1472,7 +1441,7 @@ describe('cluster', () => { }], }); - expect(stack).toHaveResource('AWS::RDS::DBClusterParameterGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBClusterParameterGroup', { Family: 'aurora5.6', Parameters: { key: 'value', @@ -1490,8 +1459,6 @@ describe('cluster', () => { }, }, }); - - }); test('PostgreSQL cluster with s3 export buckets does not generate custom parameter group and specifies the correct port', () => { @@ -1518,7 +1485,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { AssociatedRoles: [{ RoleArn: { 'Fn::GetAtt': [ @@ -1531,9 +1498,7 @@ describe('cluster', () => { Port: 5432, }); - expect(stack).not.toHaveResource('AWS::RDS::DBClusterParameterGroup'); - - + Template.fromStack(stack).resourceCountIs('AWS::RDS::DBClusterParameterGroup', 0); }); test('unversioned PostgreSQL cluster can be used with s3 import and s3 export buckets', () => { @@ -1560,7 +1525,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { AssociatedRoles: [ { FeatureName: 's3Import', @@ -1582,8 +1547,6 @@ describe('cluster', () => { }, ], }); - - }); test("Aurora PostgreSQL cluster uses a different default master username than 'admin', which is a reserved word", () => { @@ -1600,13 +1563,11 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { GenerateSecretString: { SecretStringTemplate: '{"username":"postgres"}', }, }); - - }); test('MySQL cluster without S3 exports or imports references the correct default ParameterGroup', () => { @@ -1628,13 +1589,11 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { DBClusterParameterGroupName: 'default.aurora-mysql5.7', }); - expect(stack).not.toHaveResource('AWS::RDS::DBClusterParameterGroup'); - - + Template.fromStack(stack).resourceCountIs('AWS::RDS::DBClusterParameterGroup', 0); }); test('throws when s3ExportRole and s3ExportBuckets properties are both specified', () => { @@ -1661,8 +1620,6 @@ describe('cluster', () => { s3ExportRole: exportRole, s3ExportBuckets: [exportBucket], })).toThrow(); - - }); test('throws when s3ImportRole and s3ImportBuckets properties are both specified', () => { @@ -1689,8 +1646,6 @@ describe('cluster', () => { s3ImportRole: importRole, s3ImportBuckets: [importBucket], })).toThrow(); - - }); test('can set CloudWatch log exports', () => { @@ -1713,11 +1668,9 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { EnableCloudwatchLogsExports: ['error', 'general', 'slowquery', 'audit'], }); - - }); test('can set CloudWatch log retention', () => { @@ -1741,7 +1694,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('Custom::LogRetention', { + Template.fromStack(stack).hasResourceProperties('Custom::LogRetention', { ServiceToken: { 'Fn::GetAtt': [ 'LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A', @@ -1751,7 +1704,7 @@ describe('cluster', () => { LogGroupName: { 'Fn::Join': ['', ['/aws/rds/cluster/', { Ref: 'DatabaseB269D8BB' }, '/error']] }, RetentionInDays: 90, }); - expect(stack).toHaveResource('Custom::LogRetention', { + Template.fromStack(stack).hasResourceProperties('Custom::LogRetention', { ServiceToken: { 'Fn::GetAtt': [ 'LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A', @@ -1761,8 +1714,6 @@ describe('cluster', () => { LogGroupName: { 'Fn::Join': ['', ['/aws/rds/cluster/', { Ref: 'DatabaseB269D8BB' }, '/general']] }, RetentionInDays: 90, }); - - }); test('throws if given unsupported CloudWatch log exports', () => { @@ -1784,8 +1735,6 @@ describe('cluster', () => { cloudwatchLogsExports: ['error', 'general', 'slowquery', 'audit', 'thislogdoesnotexist', 'neitherdoesthisone'], }); }).toThrow(/Unsupported logs for the current engine type: thislogdoesnotexist,neitherdoesthisone/); - - }); test('can set deletion protection', () => { @@ -1808,16 +1757,15 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { DeletionProtection: true, }); - - }); test('does not throw (but adds a node error) if a (dummy) VPC does not have sufficient subnets', () => { // GIVEN - const stack = testStack(); + const app = new cdk.App(); + const stack = testStack(app, 'TestStack'); const vpc = ec2.Vpc.fromLookup(stack, 'VPC', { isDefault: true }); // WHEN @@ -1837,11 +1785,9 @@ describe('cluster', () => { }); // THEN - const art = SynthUtils.synthesize(stack); + const art = app.synth().getStackArtifact('TestStack'); const meta = art.findMetadataByType('aws:cdk:error'); expect(meta[0].data).toEqual('Cluster requires at least 2 subnets, got 0'); - - }); test('create a cluster from a snapshot', () => { @@ -1859,7 +1805,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResource('AWS::RDS::DBCluster', { Properties: { Engine: 'aurora', EngineVersion: '5.6.mysql_aurora.1.22.2', @@ -1870,9 +1816,9 @@ describe('cluster', () => { }, DeletionPolicy: 'Snapshot', UpdateReplacePolicy: 'Snapshot', - }, ResourcePart.CompleteDefinition); + }); - expect(stack).toCountResources('AWS::RDS::DBInstance', 2); + Template.fromStack(stack).resourceCountIs('AWS::RDS::DBInstance', 2); expect(cluster.instanceIdentifiers).toHaveLength(2); expect(stack.resolve(cluster.instanceIdentifiers[0])).toEqual({ @@ -1915,12 +1861,10 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { DBSubnetGroupName: 'my-subnet-group', }); - expect(stack).toCountResources('AWS::RDS::DBSubnetGroup', 0); - - + Template.fromStack(stack).resourceCountIs('AWS::RDS::DBSubnetGroup', 0); }); test('defaultChild returns the DB Cluster', () => { @@ -1941,8 +1885,6 @@ describe('cluster', () => { // THEN expect(cluster.node.defaultChild instanceof CfnDBCluster).toBeTruthy(); - - }); test('fromGeneratedSecret', () => { @@ -1960,7 +1902,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { MasterUsername: 'admin', // username is a string MasterUserPassword: { 'Fn::Join': [ @@ -1994,7 +1936,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { ReplicaRegions: [ { Region: 'eu-west-1', @@ -2023,7 +1965,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { Name: secretName, }); }); @@ -2044,7 +1986,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { Name: secretName, }); }); @@ -2066,12 +2008,10 @@ describe('cluster', () => { }, }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { Engine: 'aurora', PubliclyAccessible: true, }); - - }); test('can set public accessibility for database cluster with instances in public subnet', () => { @@ -2091,12 +2031,10 @@ describe('cluster', () => { }, }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { Engine: 'aurora', PubliclyAccessible: false, }); - - }); test('database cluster instances in public subnet should by default have publiclyAccessible set to true', () => { @@ -2115,12 +2053,10 @@ describe('cluster', () => { }, }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { Engine: 'aurora', PubliclyAccessible: true, }); - - }); test('changes the case of the cluster identifier if the lowercaseDbIdentifier feature flag is enabled', () => { @@ -2140,7 +2076,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { DBClusterIdentifier: clusterIdentifier.toLowerCase(), }); }); @@ -2160,7 +2096,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { DBClusterIdentifier: clusterIdentifier, }); }); @@ -2179,7 +2115,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { CopyTagsToSnapshot: true, }); }); @@ -2199,7 +2135,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { CopyTagsToSnapshot: false, }); }); @@ -2219,7 +2155,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { CopyTagsToSnapshot: true, }); }); @@ -2239,7 +2175,7 @@ describe('cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { BacktrackWindow: 24 * 60 * 60, }); }); @@ -2247,8 +2183,8 @@ describe('cluster', () => { test.each([ [cdk.RemovalPolicy.RETAIN, 'Retain', 'Retain', 'Retain'], - [cdk.RemovalPolicy.SNAPSHOT, 'Snapshot', 'Delete', ABSENT], - [cdk.RemovalPolicy.DESTROY, 'Delete', 'Delete', ABSENT], + [cdk.RemovalPolicy.SNAPSHOT, 'Snapshot', 'Delete', Match.absent()], + [cdk.RemovalPolicy.DESTROY, 'Delete', 'Delete', Match.absent()], ])('if Cluster RemovalPolicy is \'%s\', the DBCluster has DeletionPolicy \'%s\', the DBInstance has \'%s\' and the DBSubnetGroup has \'%s\'', (clusterRemovalPolicy, clusterValue, instanceValue, subnetValue) => { const stack = new cdk.Stack(); @@ -2264,25 +2200,25 @@ test.each([ }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResource('AWS::RDS::DBCluster', { DeletionPolicy: clusterValue, UpdateReplacePolicy: clusterValue, - }, ResourcePart.CompleteDefinition); + }); - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResource('AWS::RDS::DBInstance', { DeletionPolicy: instanceValue, UpdateReplacePolicy: instanceValue, - }, ResourcePart.CompleteDefinition); + }); - expect(stack).toHaveResourceLike('AWS::RDS::DBSubnetGroup', { + Template.fromStack(stack).hasResource('AWS::RDS::DBSubnetGroup', { DeletionPolicy: subnetValue, - }, ResourcePart.CompleteDefinition); + }); }); test.each([ [cdk.RemovalPolicy.RETAIN, 'Retain', 'Retain', 'Retain'], - [cdk.RemovalPolicy.SNAPSHOT, 'Snapshot', 'Delete', ABSENT], - [cdk.RemovalPolicy.DESTROY, 'Delete', 'Delete', ABSENT], + [cdk.RemovalPolicy.SNAPSHOT, 'Snapshot', 'Delete', Match.absent()], + [cdk.RemovalPolicy.DESTROY, 'Delete', 'Delete', Match.absent()], ])('if Cluster RemovalPolicy is \'%s\', the DBCluster has DeletionPolicy \'%s\', the DBInstance has \'%s\' and the DBSubnetGroup has \'%s\'', (clusterRemovalPolicy, clusterValue, instanceValue, subnetValue) => { const stack = new cdk.Stack(); @@ -2298,25 +2234,24 @@ test.each([ }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResource('AWS::RDS::DBCluster', { DeletionPolicy: clusterValue, UpdateReplacePolicy: clusterValue, - }, ResourcePart.CompleteDefinition); + }); - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResource('AWS::RDS::DBInstance', { DeletionPolicy: instanceValue, UpdateReplacePolicy: instanceValue, - }, ResourcePart.CompleteDefinition); + }); - expect(stack).toHaveResourceLike('AWS::RDS::DBSubnetGroup', { + Template.fromStack(stack).hasResource('AWS::RDS::DBSubnetGroup', { DeletionPolicy: subnetValue, UpdateReplacePolicy: subnetValue, - }, ResourcePart.CompleteDefinition); + }); }); - -function testStack(app?: cdk.App) { - const stack = new cdk.Stack(app, undefined, { env: { account: '12345', region: 'us-test-1' } }); +function testStack(app?: cdk.App, stackId?: string) { + const stack = new cdk.Stack(app, stackId, { env: { account: '12345', region: 'us-test-1' } }); stack.node.setContext('availability-zones:12345:us-test-1', ['us-test-1a', 'us-test-1b']); return stack; } diff --git a/packages/@aws-cdk/aws-rds/test/database-secret.test.ts b/packages/@aws-cdk/aws-rds/test/database-secret.test.ts index 9fe7793536a1c..424fe4164fd74 100644 --- a/packages/@aws-cdk/aws-rds/test/database-secret.test.ts +++ b/packages/@aws-cdk/aws-rds/test/database-secret.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { CfnResource, Stack } from '@aws-cdk/core'; import { DatabaseSecret } from '../lib'; import { DEFAULT_PASSWORD_EXCLUDE_CHARS } from '../lib/private/util'; @@ -14,7 +14,7 @@ describe('database secret', () => { }); // THEN - expect(stack).toHaveResource('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { Description: { 'Fn::Join': [ '', @@ -35,8 +35,6 @@ describe('database secret', () => { }); expect(getSecretLogicalId(dbSecret, stack)).toEqual('SecretA720EF05'); - - }); test('with master secret', () => { @@ -54,7 +52,7 @@ describe('database secret', () => { }); // THEN - expect(stack).toHaveResource('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { GenerateSecretString: { ExcludeCharacters: '"@/\\', GenerateStringKey: 'password', @@ -73,8 +71,6 @@ describe('database secret', () => { }, }, }); - - }); test('replace on password critera change', () => { @@ -106,8 +102,6 @@ describe('database secret', () => { replaceOnPasswordCriteriaChanges: true, }); expect(dbSecretlogicalId).not.toEqual(getSecretLogicalId(otherSecret2, stack)); - - }); }); diff --git a/packages/@aws-cdk/aws-rds/test/database-secretmanager.test.ts b/packages/@aws-cdk/aws-rds/test/database-secretmanager.test.ts index 135704a893f75..8d1da9e04b1b6 100644 --- a/packages/@aws-cdk/aws-rds/test/database-secretmanager.test.ts +++ b/packages/@aws-cdk/aws-rds/test/database-secretmanager.test.ts @@ -1,5 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; -import { ResourcePart } from '@aws-cdk/assert-internal'; +import { Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as secretsmanager from '@aws-cdk/aws-secretsmanager'; import * as cdk from '@aws-cdk/core'; @@ -21,7 +20,7 @@ describe('database secret manager', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResource('AWS::RDS::DBCluster', { Properties: { Engine: 'aurora-postgresql', DBClusterParameterGroupName: 'default.aurora-postgresql10', @@ -65,9 +64,7 @@ describe('database secret manager', () => { }, DeletionPolicy: 'Snapshot', UpdateReplacePolicy: 'Snapshot', - }, ResourcePart.CompleteDefinition); - - + }); }); }); diff --git a/packages/@aws-cdk/aws-rds/test/instance-engine.test.ts b/packages/@aws-cdk/aws-rds/test/instance-engine.test.ts index 99ed162c4f5eb..f9a93f3bca867 100644 --- a/packages/@aws-cdk/aws-rds/test/instance-engine.test.ts +++ b/packages/@aws-cdk/aws-rds/test/instance-engine.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; import * as rds from '../lib'; @@ -10,8 +10,6 @@ describe('instance engine', () => { const family = engine.parameterGroupFamily; expect(family).toEqual(undefined); - - }); test('default parameterGroupFamily for versionless MySQL instance engine is not defined', () => { @@ -20,8 +18,6 @@ describe('instance engine', () => { const family = engine.parameterGroupFamily; expect(family).toEqual(undefined); - - }); test('default parameterGroupFamily for versionless PostgreSQL instance engine is not defined', () => { @@ -30,8 +26,6 @@ describe('instance engine', () => { const family = engine.parameterGroupFamily; expect(family).toEqual(undefined); - - }); test("default parameterGroupFamily for versionless Oracle SE instance engine is 'oracle-se-11.2'", () => { @@ -40,8 +34,6 @@ describe('instance engine', () => { const family = engine.parameterGroupFamily; expect(family).toEqual('oracle-se-11.2'); - - }); test("default parameterGroupFamily for versionless Oracle SE 1 instance engine is 'oracle-se1-11.2'", () => { @@ -50,8 +42,6 @@ describe('instance engine', () => { const family = engine.parameterGroupFamily; expect(family).toEqual('oracle-se1-11.2'); - - }); test('default parameterGroupFamily for versionless Oracle SE 2 instance engine is not defined', () => { @@ -60,8 +50,6 @@ describe('instance engine', () => { const family = engine.parameterGroupFamily; expect(family).toEqual(undefined); - - }); test('default parameterGroupFamily for versionless Oracle EE instance engine is not defined', () => { @@ -70,8 +58,6 @@ describe('instance engine', () => { const family = engine.parameterGroupFamily; expect(family).toEqual(undefined); - - }); test('default parameterGroupFamily for versionless SQL Server SE instance engine is not defined', () => { @@ -80,8 +66,6 @@ describe('instance engine', () => { const family = engine.parameterGroupFamily; expect(family).toEqual(undefined); - - }); test('default parameterGroupFamily for versionless SQL Server EX instance engine is not defined', () => { @@ -90,8 +74,6 @@ describe('instance engine', () => { const family = engine.parameterGroupFamily; expect(family).toEqual(undefined); - - }); test('default parameterGroupFamily for versionless SQL Server Web instance engine is not defined', () => { @@ -100,8 +82,6 @@ describe('instance engine', () => { const family = engine.parameterGroupFamily; expect(family).toEqual(undefined); - - }); test('default parameterGroupFamily for versionless SQL Server EE instance engine is not defined', () => { @@ -110,8 +90,6 @@ describe('instance engine', () => { const family = engine.parameterGroupFamily; expect(family).toEqual(undefined); - - }); describe('Oracle engine bindToInstance', () => { @@ -122,8 +100,6 @@ describe('instance engine', () => { const engineConfig = engine.bindToInstance(new cdk.Stack(), {}); expect(engineConfig.features?.s3Import).toEqual('S3_INTEGRATION'); expect(engineConfig.features?.s3Export).toEqual('S3_INTEGRATION'); - - }); test('s3 import/export - creates an option group if needed', () => { @@ -136,15 +112,13 @@ describe('instance engine', () => { }); expect(engineConfig.optionGroup).toBeDefined(); - expect(stack).toHaveResourceLike('AWS::RDS::OptionGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::OptionGroup', { EngineName: 'oracle-se2', OptionConfigurations: [{ OptionName: 'S3_INTEGRATION', OptionVersion: '1.0', }], }); - - }); test('s3 import/export - appends to an existing option group if it exists', () => { @@ -163,7 +137,7 @@ describe('instance engine', () => { }); expect(engineConfig.optionGroup).toEqual(optionGroup); - expect(stack).toHaveResourceLike('AWS::RDS::OptionGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::OptionGroup', { EngineName: 'oracle-se2', OptionConfigurations: [{ OptionName: 'MY_OPTION_CONFIG', @@ -173,8 +147,6 @@ describe('instance engine', () => { OptionVersion: '1.0', }], }); - - }); }); @@ -185,8 +157,6 @@ describe('instance engine', () => { const engineConfig = engine.bindToInstance(new cdk.Stack(), {}); expect(engineConfig.features?.s3Import).toEqual('S3_INTEGRATION'); expect(engineConfig.features?.s3Export).toEqual('S3_INTEGRATION'); - - }); test('s3 import/export - throws if roles are not equal', () => { @@ -200,8 +170,6 @@ describe('instance engine', () => { expect(() => engine.bindToInstance(new cdk.Stack(), { s3ImportRole })).not.toThrow(); expect(() => engine.bindToInstance(new cdk.Stack(), { s3ExportRole })).not.toThrow(); expect(() => engine.bindToInstance(new cdk.Stack(), { s3ImportRole, s3ExportRole: s3ImportRole })).not.toThrow(); - - }); test('s3 import/export - creates an option group if needed', () => { @@ -214,7 +182,7 @@ describe('instance engine', () => { }); expect(engineConfig.optionGroup).toBeDefined(); - expect(stack).toHaveResourceLike('AWS::RDS::OptionGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::OptionGroup', { EngineName: 'sqlserver-se', OptionConfigurations: [{ OptionName: 'SQLSERVER_BACKUP_RESTORE', @@ -224,8 +192,6 @@ describe('instance engine', () => { }], }], }); - - }); test('s3 import/export - appends to an existing option group if it exists', () => { @@ -244,7 +210,7 @@ describe('instance engine', () => { }); expect(engineConfig.optionGroup).toEqual(optionGroup); - expect(stack).toHaveResourceLike('AWS::RDS::OptionGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::OptionGroup', { EngineName: 'sqlserver-se', OptionConfigurations: [{ OptionName: 'MY_OPTION_CONFIG', @@ -257,8 +223,6 @@ describe('instance engine', () => { }], }], }); - - }); }); @@ -269,8 +233,6 @@ describe('instance engine', () => { const engineConfig = engineNewerVersion.bindToInstance(new cdk.Stack(), {}); expect(engineConfig.features?.s3Import).toEqual(undefined); expect(engineConfig.features?.s3Export).toEqual(undefined); - - }); test('returns s3 import/export feature if the version supports it', () => { @@ -279,8 +241,6 @@ describe('instance engine', () => { const engineConfig = engineNewerVersion.bindToInstance(new cdk.Stack(), {}); expect(engineConfig.features?.s3Import).toEqual('s3Import'); expect(engineConfig.features?.s3Export).toEqual('s3Export'); - - }); }); }); diff --git a/packages/@aws-cdk/aws-rds/test/instance.test.ts b/packages/@aws-cdk/aws-rds/test/instance.test.ts index 484ad765cb790..29ced7cbb1940 100644 --- a/packages/@aws-cdk/aws-rds/test/instance.test.ts +++ b/packages/@aws-cdk/aws-rds/test/instance.test.ts @@ -1,5 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; -import { ABSENT, ResourcePart, anything } from '@aws-cdk/assert-internal'; +import { Match, Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as targets from '@aws-cdk/aws-events-targets'; import { ManagedPolicy, Role, ServicePrincipal, AccountPrincipal } from '@aws-cdk/aws-iam'; @@ -49,7 +48,7 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResource('AWS::RDS::DBInstance', { Properties: { DBInstanceClass: 'db.t2.medium', AllocatedStorage: '100', @@ -117,9 +116,9 @@ describe('instance', () => { }, DeletionPolicy: 'Snapshot', UpdateReplacePolicy: 'Snapshot', - }, ResourcePart.CompleteDefinition); + }); - expect(stack).toHaveResource('AWS::RDS::DBSubnetGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBSubnetGroup', { DBSubnetGroupDescription: 'Subnet group for Instance database', SubnetIds: [ { @@ -131,11 +130,11 @@ describe('instance', () => { ], }); - expect(stack).toHaveResource('AWS::EC2::SecurityGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroup', { GroupDescription: 'Security group for Instance database', }); - expect(stack).toHaveResource('AWS::IAM::Role', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { AssumeRolePolicyDocument: { Statement: [ { @@ -164,7 +163,7 @@ describe('instance', () => { ], }); - expect(stack).toHaveResource('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { Description: { 'Fn::Join': [ '', @@ -184,7 +183,7 @@ describe('instance', () => { }, }); - expect(stack).toHaveResource('AWS::SecretsManager::SecretTargetAttachment', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::SecretTargetAttachment', { SecretId: { Ref: 'InstanceSecret478E0A47', }, @@ -194,9 +193,7 @@ describe('instance', () => { TargetType: 'AWS::RDS::DBInstance', }); - expect(stack).toCountResources('Custom::LogRetention', 4); - - + Template.fromStack(stack).resourceCountIs('Custom::LogRetention', 4); }); test('throws when create database with specific AZ and multiAZ enabled', () => { @@ -239,7 +236,7 @@ describe('instance', () => { parameterGroup, }); - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { DBParameterGroupName: { Ref: 'ParameterGroup5E32DECB', }, @@ -247,8 +244,6 @@ describe('instance', () => { Ref: 'OptionGroupACA43DC1', }, }); - - }); test('can specify subnet type', () => { @@ -263,13 +258,13 @@ describe('instance', () => { }, }); - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { DBSubnetGroupName: { Ref: 'InstanceSubnetGroupF2CBA54F', }, PubliclyAccessible: false, }); - expect(stack).toHaveResource('AWS::RDS::DBSubnetGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBSubnetGroup', { DBSubnetGroupDescription: 'Subnet group for Instance database', SubnetIds: [ { @@ -280,8 +275,6 @@ describe('instance', () => { }, ], }); - - }); describe('DatabaseInstanceFromSnapshot', () => { @@ -293,11 +286,9 @@ describe('instance', () => { vpc, }); - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { DBSnapshotIdentifier: 'my-snapshot', }); - - }); test('can generate a new snapshot password', () => { @@ -310,8 +301,8 @@ describe('instance', () => { }), }); - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { - MasterUsername: ABSENT, + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { + MasterUsername: Match.absent(), MasterUserPassword: { 'Fn::Join': ['', [ '{{resolve:secretsmanager:', @@ -320,7 +311,7 @@ describe('instance', () => { ]], }, }); - expect(stack).toHaveResource('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { Description: { 'Fn::Join': ['', ['Generated by the CDK for stack: ', { Ref: 'AWS::StackName' }]], }, @@ -331,8 +322,6 @@ describe('instance', () => { SecretStringTemplate: '{"username":"admin"}', }, }); - - }); test('fromGeneratedSecret with replica regions', () => { @@ -345,7 +334,7 @@ describe('instance', () => { }), }); - expect(stack).toHaveResource('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { ReplicaRegions: [ { Region: 'eu-west-1', @@ -361,8 +350,6 @@ describe('instance', () => { vpc, credentials: { generatePassword: true }, })).toThrow(/`credentials` `username` must be specified when `generatePassword` is set to true/); - - }); test('can set a new snapshot password from an existing SecretValue', () => { @@ -374,12 +361,10 @@ describe('instance', () => { }); // TODO - Expect this to be broken - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { - MasterUsername: ABSENT, + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { + MasterUsername: Match.absent(), MasterUserPassword: 'mysecretpassword', }); - - }); test('can set a new snapshot password from an existing Secret', () => { @@ -394,14 +379,12 @@ describe('instance', () => { credentials: rds.SnapshotCredentials.fromSecret(secret), }); - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { - MasterUsername: ABSENT, + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { + MasterUsername: Match.absent(), MasterUserPassword: { 'Fn::Join': ['', ['{{resolve:secretsmanager:', { Ref: 'DBSecretD58955BC' }, ':SecretString:password::}}']], }, }); - - }); test('can create a new database instance with fromDatabaseInstanceAttributes using a token for the port', () => { @@ -425,9 +408,9 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveOutput({ - exportName: 'databaseUrl', - outputValue: { + Template.fromStack(stack).hasOutput('portOutput', { + Export: { Name: 'databaseUrl' }, + Value: { Ref: 'DatabasePort', }, }); @@ -449,7 +432,7 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { SourceDBInstanceIdentifier: { 'Fn::Join': ['', [ 'arn:', @@ -466,8 +449,6 @@ describe('instance', () => { Ref: 'ReadReplicaSubnetGroup680C605C', }, }); - - }); test('on event', () => { @@ -485,7 +466,7 @@ describe('instance', () => { instance.onEvent('InstanceEvent', { target: new targets.LambdaFunction(fn) }); // THEN - expect(stack).toHaveResource('AWS::Events::Rule', { + Template.fromStack(stack).hasResourceProperties('AWS::Events::Rule', { EventPattern: { source: [ 'aws.rds', @@ -528,8 +509,6 @@ describe('instance', () => { }, ], }); - - }); test('on event without target', () => { @@ -542,7 +521,7 @@ describe('instance', () => { instance.onEvent('InstanceEvent'); // THEN - expect(stack).toHaveResource('AWS::Events::Rule', { + Template.fromStack(stack).hasResourceProperties('AWS::Events::Rule', { EventPattern: { source: [ 'aws.rds', @@ -574,8 +553,6 @@ describe('instance', () => { ], }, }); - - }); test('can use metricCPUUtilization', () => { @@ -593,8 +570,6 @@ describe('instance', () => { period: cdk.Duration.minutes(5), statistic: 'Average', }); - - }); test('can resolve endpoint port and socket address', () => { @@ -618,8 +593,6 @@ describe('instance', () => { ], ], }); - - }); test('can deactivate backup', () => { @@ -631,11 +604,9 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { BackupRetentionPeriod: 0, }); - - }); test('imported instance with imported security group with allowAllOutbound set to false', () => { @@ -652,11 +623,9 @@ describe('instance', () => { instance.connections.allowToAnyIpv4(ec2.Port.tcp(443)); // THEN - expect(stack).toHaveResource('AWS::EC2::SecurityGroupEgress', { + Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroupEgress', { GroupId: 'sg-123456789', }); - - }); test('create an instance with imported monitoring role', () => { @@ -676,14 +645,12 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { MonitoringInterval: 60, MonitoringRoleArn: { 'Fn::GetAtt': ['MonitoringRole90457BF9', 'Arn'], }, - }, ResourcePart.Properties); - - + }); }); test('create an instance with an existing security group', () => { @@ -700,11 +667,11 @@ describe('instance', () => { instance.connections.allowDefaultPortFromAnyIpv4(); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { VPCSecurityGroups: ['sg-123456789'], }); - expect(stack).toHaveResource('AWS::EC2::SecurityGroupIngress', { + Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroupIngress', { FromPort: { 'Fn::GetAtt': [ 'InstanceC1063A87', @@ -719,8 +686,6 @@ describe('instance', () => { ], }, }); - - }); test('addRotationSingleUser()', () => { @@ -734,7 +699,7 @@ describe('instance', () => { instance.addRotationSingleUser(); // THEN - expect(stack).toHaveResource('AWS::SecretsManager::RotationSchedule', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::RotationSchedule', { SecretId: { Ref: 'DatabaseSecretAttachmentE5D1B020', }, @@ -762,7 +727,7 @@ describe('instance', () => { instance.addRotationMultiUser('user', { secret: userSecret.attach(instance) }); // THEN - expect(stack).toHaveResource('AWS::SecretsManager::RotationSchedule', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::RotationSchedule', { SecretId: { Ref: 'UserSecretAttachment16ACBE6D', }, @@ -777,7 +742,7 @@ describe('instance', () => { }, }); - expect(stack).toHaveResourceLike('AWS::Serverless::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::Serverless::Application', { Parameters: { masterSecretArn: { Ref: 'DatabaseSecretAttachmentE5D1B020', @@ -812,13 +777,13 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResource('AWS::SecretsManager::RotationSchedule', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::RotationSchedule', { RotationRules: { AutomaticallyAfterDays: 15, }, }); - expect(stack).toHaveResource('AWS::Serverless::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::Serverless::Application', { Parameters: { endpoint: { 'Fn::Join': ['', [ @@ -870,7 +835,7 @@ describe('instance', () => { instance.addRotationSingleUser({ endpoint }); // THEN - expect(stack).toHaveResource('AWS::Serverless::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::Serverless::Application', { Parameters: { endpoint: { 'Fn::Join': ['', [ @@ -910,8 +875,6 @@ describe('instance', () => { // THEN expect(() => instance.addRotationSingleUser()).toThrow(/without secret/); - - }); test('throws when trying to add single user rotation multiple times', () => { @@ -927,8 +890,6 @@ describe('instance', () => { // THEN expect(() => instance.addRotationSingleUser()).toThrow(/A single user rotation was already added to this instance/); - - }); test('throws when timezone is set for non-sqlserver database engine', () => { @@ -953,8 +914,6 @@ describe('instance', () => { vpc, })).toThrow(/timezone property can not be configured for/); }); - - }); test('create an instance from snapshot with maximum allocated storage', () => { @@ -967,12 +926,10 @@ describe('instance', () => { maxAllocatedStorage: 200, }); - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { DBSnapshotIdentifier: 'my-snapshot', MaxAllocatedStorage: 200, }); - - }); test('create a DB instance with maximum allocated storage', () => { @@ -985,12 +942,10 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { BackupRetentionPeriod: 0, MaxAllocatedStorage: 250, }); - - }); test('iam authentication - off by default', () => { @@ -999,11 +954,9 @@ describe('instance', () => { vpc, }); - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { - EnableIAMDatabaseAuthentication: ABSENT, + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { + EnableIAMDatabaseAuthentication: Match.absent(), }); - - }); test('createGrant - creates IAM policy and enables IAM auth', () => { @@ -1016,10 +969,10 @@ describe('instance', () => { }); instance.grantConnect(role); - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { EnableIAMDatabaseAuthentication: true, }); - expect(stack).toHaveResource('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [{ Effect: 'Allow', @@ -1031,8 +984,6 @@ describe('instance', () => { Version: '2012-10-17', }, }); - - }); test('createGrant - throws if IAM auth disabled', () => { @@ -1046,8 +997,6 @@ describe('instance', () => { }); expect(() => { instance.grantConnect(role); }).toThrow(/Cannot grant connect when IAM authentication is disabled/); - - }); test('domain - sets domain property', () => { @@ -1061,11 +1010,9 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { Domain: domain, }); - - }); test('domain - uses role if provided', () => { @@ -1081,12 +1028,10 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { Domain: domain, DomainIAMRoleName: stack.resolve(role.roleName), }); - - }); test('domain - creates role if not provided', () => { @@ -1100,12 +1045,12 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { Domain: domain, - DomainIAMRoleName: anything(), + DomainIAMRoleName: Match.anyValue(), }); - expect(stack).toHaveResource('AWS::IAM::Role', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { AssumeRolePolicyDocument: { Statement: [ { @@ -1133,8 +1078,6 @@ describe('instance', () => { }, ], }); - - }); test('throws when domain is set for mariadb database engine', () => { @@ -1161,8 +1104,6 @@ describe('instance', () => { vpc, })).toThrow(expectedError); }); - - }); describe('performance insights', () => { @@ -1175,13 +1116,11 @@ describe('instance', () => { performanceInsightEncryptionKey: new kms.Key(stack, 'Key'), }); - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { EnablePerformanceInsights: true, PerformanceInsightsRetentionPeriod: 731, PerformanceInsightsKMSKeyId: { 'Fn::GetAtt': ['Key961B73FD', 'Arn'] }, }); - - }); test('setting performance insights fields enables performance insights', () => { @@ -1191,12 +1130,10 @@ describe('instance', () => { performanceInsightRetention: rds.PerformanceInsightRetention.LONG_TERM, }); - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { EnablePerformanceInsights: true, PerformanceInsightsRetentionPeriod: 731, }); - - }); test('throws if performance insights fields are set but performance insights is disabled', () => { @@ -1208,8 +1145,6 @@ describe('instance', () => { performanceInsightRetention: rds.PerformanceInsightRetention.DEFAULT, }); }).toThrow(/`enablePerformanceInsights` disabled, but `performanceInsightRetention` or `performanceInsightEncryptionKey` was set/); - - }); }); @@ -1220,12 +1155,10 @@ describe('instance', () => { subnetGroup: rds.SubnetGroup.fromSubnetGroupName(stack, 'SubnetGroup', 'my-subnet-group'), }); - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { DBSubnetGroupName: 'my-subnet-group', }); - expect(stack).toCountResources('AWS::RDS::DBSubnetGroup', 0); - - + Template.fromStack(stack).resourceCountIs('AWS::RDS::DBSubnetGroup', 0); }); test('defaultChild returns the DB Instance', () => { @@ -1236,8 +1169,6 @@ describe('instance', () => { // THEN expect(instance.node.defaultChild instanceof rds.CfnDBInstance).toBeTruthy(); - - }); test("PostgreSQL database instance uses a different default master username than 'admin', which is a reserved word", () => { @@ -1249,13 +1180,11 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { GenerateSecretString: { SecretStringTemplate: '{"username":"postgres"}', }, }); - - }); describe('S3 Import/Export', () => { @@ -1269,7 +1198,7 @@ describe('instance', () => { s3ExportBuckets: [new s3.Bucket(stack, 'S3Export')], }); - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { AssociatedRoles: [ { FeatureName: 'S3_INTEGRATION', @@ -1280,7 +1209,7 @@ describe('instance', () => { }); // Can read from import bucket, and read/write from export bucket - expect(stack).toHaveResource('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [{ Action: [ @@ -1312,8 +1241,6 @@ describe('instance', () => { Version: '2012-10-17', }, }); - - }); test('throws if using s3 import on unsupported engine', () => { @@ -1335,8 +1262,6 @@ describe('instance', () => { s3ImportRole, }); }).toThrow(/Engine 'mysql-8.0.19' does not support S3 import/); - - }); test('throws if using s3 export on unsupported engine', () => { @@ -1358,8 +1283,6 @@ describe('instance', () => { s3ExportRole: s3ExportRole, }); }).toThrow(/Engine 'mysql-8.0.19' does not support S3 export/); - - }); test('throws if provided two different roles for import/export', () => { @@ -1378,8 +1301,6 @@ describe('instance', () => { s3ExportRole, }); }).toThrow(/S3 import and export roles must be the same/); - - }); }); @@ -1392,7 +1313,7 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { MasterUsername: 'postgres', // username is a string MasterUserPassword: { 'Fn::Join': [ @@ -1420,7 +1341,7 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResource('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { ReplicaRegions: [ { Region: 'eu-west-1', @@ -1438,7 +1359,7 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { MasterUsername: 'postgres', // username is a string MasterUserPassword: '{{resolve:ssm-secure:/dbPassword:1}}', // reference to SSM }); @@ -1460,7 +1381,7 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { Name: secretName, }); }); @@ -1477,7 +1398,7 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { Name: secretName, }); }); @@ -1494,11 +1415,9 @@ describe('instance', () => { publiclyAccessible: false, }); - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { PubliclyAccessible: false, }); - - }); test('can set publiclyAccessible to true with private subnets', () => { @@ -1513,7 +1432,7 @@ describe('instance', () => { publiclyAccessible: true, }); - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { PubliclyAccessible: true, }); }); @@ -1537,7 +1456,7 @@ describe('instance', () => { } ); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { DBInstanceIdentifier: instanceIdentifier.toLowerCase(), }); }); @@ -1559,7 +1478,7 @@ describe('instance', () => { } ); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { DBInstanceIdentifier: instanceIdentifier, }); }); @@ -1605,7 +1524,7 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { DBParameterGroupName: { Ref: 'ParameterGroup5E32DECB', }, @@ -1622,7 +1541,7 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { Port: '3306', }); }); @@ -1642,7 +1561,7 @@ describe('instance', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBInstance', { Port: { Ref: 'Port', }, @@ -1652,8 +1571,8 @@ describe('instance', () => { test.each([ [cdk.RemovalPolicy.RETAIN, 'Retain', 'Retain'], - [cdk.RemovalPolicy.SNAPSHOT, 'Snapshot', ABSENT], - [cdk.RemovalPolicy.DESTROY, 'Delete', ABSENT], + [cdk.RemovalPolicy.SNAPSHOT, 'Snapshot', Match.absent()], + [cdk.RemovalPolicy.DESTROY, 'Delete', Match.absent()], ])('if Instance RemovalPolicy is \'%s\', the instance has DeletionPolicy \'%s\' and the DBSubnetGroup has \'%s\'', (instanceRemovalPolicy, instanceValue, subnetValue) => { // GIVEN stack = new cdk.Stack(); @@ -1670,15 +1589,15 @@ test.each([ }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBInstance', { + Template.fromStack(stack).hasResource('AWS::RDS::DBInstance', { DeletionPolicy: instanceValue, UpdateReplacePolicy: instanceValue, - }, ResourcePart.CompleteDefinition); + }); - expect(stack).toHaveResourceLike('AWS::RDS::DBSubnetGroup', { + Template.fromStack(stack).hasResource('AWS::RDS::DBSubnetGroup', { DeletionPolicy: subnetValue, UpdateReplacePolicy: subnetValue, - }, ResourcePart.CompleteDefinition); + }); }); describe('cross-account instance', () => { @@ -1707,7 +1626,7 @@ describe('cross-account instance', () => { value: instance.instanceIdentifier, }); - expect(outputStack).toMatchTemplate({ + Template.fromStack(outputStack).templateMatches({ Outputs: { DatabaseInstanceArn: { Value: { diff --git a/packages/@aws-cdk/aws-rds/test/option-group.test.ts b/packages/@aws-cdk/aws-rds/test/option-group.test.ts index a0ab91ac0dfdf..5e8fb5b9f5261 100644 --- a/packages/@aws-cdk/aws-rds/test/option-group.test.ts +++ b/packages/@aws-cdk/aws-rds/test/option-group.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as cdk from '@aws-cdk/core'; import { DatabaseInstanceEngine, OptionGroup, OracleEngineVersion } from '../lib'; @@ -21,7 +21,7 @@ describe('option group', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::OptionGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::OptionGroup', { EngineName: 'oracle-se2', MajorEngineVersion: '12.1', OptionConfigurations: [ @@ -30,8 +30,6 @@ describe('option group', () => { }, ], }); - - }); test('option group with new security group', () => { @@ -55,7 +53,7 @@ describe('option group', () => { optionGroup.optionConnections.OEM.connections.allowDefaultPortFromAnyIpv4(); // THEN - expect(stack).toHaveResource('AWS::RDS::OptionGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::OptionGroup', { OptionConfigurations: [ { OptionName: 'OEM', @@ -72,7 +70,7 @@ describe('option group', () => { ], }); - expect(stack).toHaveResource('AWS::EC2::SecurityGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroup', { GroupDescription: 'Security group for OEM option', SecurityGroupIngress: [ { @@ -87,8 +85,6 @@ describe('option group', () => { Ref: 'VPCB9E5F0B4', }, }); - - }); test('option group with existing security group', () => { @@ -113,7 +109,7 @@ describe('option group', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::OptionGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::OptionGroup', { OptionConfigurations: [ { OptionName: 'OEM', @@ -129,8 +125,6 @@ describe('option group', () => { }, ], }); - - }); test('throws when using an option with port and no vpc', () => { @@ -149,7 +143,5 @@ describe('option group', () => { }, ], })).toThrow(/`port`.*`vpc`/); - - }); }); diff --git a/packages/@aws-cdk/aws-rds/test/parameter-group.test.ts b/packages/@aws-cdk/aws-rds/test/parameter-group.test.ts index bf8e789aee0ad..594fab914310a 100644 --- a/packages/@aws-cdk/aws-rds/test/parameter-group.test.ts +++ b/packages/@aws-cdk/aws-rds/test/parameter-group.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import { DatabaseClusterEngine, ParameterGroup } from '../lib'; @@ -17,10 +17,8 @@ describe('parameter group', () => { }); // THEN - expect(stack).toCountResources('AWS::RDS::DBParameterGroup', 0); - expect(stack).toCountResources('AWS::RDS::DBClusterParameterGroup', 0); - - + Template.fromStack(stack).resourceCountIs('AWS::RDS::DBParameterGroup', 0); + Template.fromStack(stack).resourceCountIs('AWS::RDS::DBClusterParameterGroup', 0); }); test('create a parameter group when bound to an instance', () => { @@ -38,15 +36,13 @@ describe('parameter group', () => { parameterGroup.bindToInstance({}); // THEN - expect(stack).toHaveResource('AWS::RDS::DBParameterGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBParameterGroup', { Description: 'desc', Family: 'aurora5.6', Parameters: { key: 'value', }, }); - - }); test('create a parameter group when bound to a cluster', () => { @@ -64,15 +60,13 @@ describe('parameter group', () => { parameterGroup.bindToCluster({}); // THEN - expect(stack).toHaveResource('AWS::RDS::DBClusterParameterGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBClusterParameterGroup', { Description: 'desc', Family: 'aurora5.6', Parameters: { key: 'value', }, }); - - }); test('creates 2 parameter groups when bound to a cluster and an instance', () => { @@ -91,10 +85,8 @@ describe('parameter group', () => { parameterGroup.bindToInstance({}); // THEN - expect(stack).toCountResources('AWS::RDS::DBParameterGroup', 1); - expect(stack).toCountResources('AWS::RDS::DBClusterParameterGroup', 1); - - + Template.fromStack(stack).resourceCountIs('AWS::RDS::DBParameterGroup', 1); + Template.fromStack(stack).resourceCountIs('AWS::RDS::DBClusterParameterGroup', 1); }); test('Add an additional parameter to an existing parameter group', () => { @@ -114,7 +106,7 @@ describe('parameter group', () => { clusterParameterGroup.addParameter('key2', 'value2'); // THEN - expect(stack).toHaveResource('AWS::RDS::DBClusterParameterGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBClusterParameterGroup', { Description: 'desc', Family: 'aurora5.6', Parameters: { @@ -122,7 +114,5 @@ describe('parameter group', () => { key2: 'value2', }, }); - - }); }); diff --git a/packages/@aws-cdk/aws-rds/test/proxy.test.ts b/packages/@aws-cdk/aws-rds/test/proxy.test.ts index 9cd48e7686dd9..f98e36bdf3647 100644 --- a/packages/@aws-cdk/aws-rds/test/proxy.test.ts +++ b/packages/@aws-cdk/aws-rds/test/proxy.test.ts @@ -1,5 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; -import { ABSENT, ResourcePart } from '@aws-cdk/assert-internal'; +import { Match, Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import { AccountPrincipal, Role } from '@aws-cdk/aws-iam'; import * as secretsmanager from '@aws-cdk/aws-secretsmanager'; @@ -15,8 +14,6 @@ describe('proxy', () => { beforeEach(() => { stack = new cdk.Stack(); vpc = new ec2.Vpc(stack, 'VPC'); - - }); test('create a DB proxy from an instance', () => { @@ -36,7 +33,7 @@ describe('proxy', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBProxy', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBProxy', { Auth: [ { AuthScheme: 'SECRETS', @@ -66,7 +63,7 @@ describe('proxy', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBProxyTargetGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBProxyTargetGroup', { DBProxyName: { Ref: 'ProxyCB0DFB71', }, @@ -78,8 +75,6 @@ describe('proxy', () => { ], TargetGroupName: 'default', }); - - }); test('create a DB proxy from a cluster', () => { @@ -99,7 +94,7 @@ describe('proxy', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBProxy', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBProxy', { Auth: [ { AuthScheme: 'SECRETS', @@ -127,7 +122,7 @@ describe('proxy', () => { }, ], }); - expect(stack).toHaveResourceLike('AWS::RDS::DBProxyTargetGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBProxyTargetGroup', { DBProxyName: { Ref: 'ProxyCB0DFB71', }, @@ -137,10 +132,10 @@ describe('proxy', () => { Ref: 'DatabaseB269D8BB', }, ], - DBInstanceIdentifiers: ABSENT, + DBInstanceIdentifiers: Match.absent(), TargetGroupName: 'default', }); - expect(stack).toHaveResourceLike('AWS::EC2::SecurityGroupIngress', { + Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroupIngress', { IpProtocol: 'tcp', Description: 'Allow connections to the database Cluster from the Proxy', FromPort: { @@ -156,8 +151,6 @@ describe('proxy', () => { 'Fn::GetAtt': ['DatabaseB269D8BB', 'Endpoint.Port'], }, }); - - }); test('One or more secrets are required.', () => { @@ -175,8 +168,6 @@ describe('proxy', () => { vpc, }); }).toThrow('One or more secrets are required.'); - - }); test('fails when trying to create a proxy for a target without an engine', () => { @@ -191,8 +182,6 @@ describe('proxy', () => { secrets: [new secretsmanager.Secret(stack, 'Secret')], }); }).toThrow(/Could not determine engine for proxy target 'Default\/Cluster'\. Please provide it explicitly when importing the resource/); - - }); test("fails when trying to create a proxy for a target with an engine that doesn't have engineFamily", () => { @@ -213,8 +202,6 @@ describe('proxy', () => { secrets: [new secretsmanager.Secret(stack, 'Secret')], }); }).toThrow(/Engine 'mariadb-10\.0\.24' does not support proxies/); - - }); test('correctly creates a proxy for an imported Cluster if its engine is known', () => { @@ -232,20 +219,18 @@ describe('proxy', () => { secrets: [new secretsmanager.Secret(stack, 'Secret')], }); - expect(stack).toHaveResourceLike('AWS::RDS::DBProxy', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBProxy', { EngineFamily: 'POSTGRESQL', }); - expect(stack).toHaveResourceLike('AWS::RDS::DBProxyTargetGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBProxyTargetGroup', { DBClusterIdentifiers: [ 'my-cluster', ], }); - expect(stack).toHaveResourceLike('AWS::EC2::SecurityGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroup', { GroupDescription: 'SecurityGroup for Database Proxy', VpcId: { Ref: 'VPCB9E5F0B4' }, }); - - }); describe('imported Proxies', () => { @@ -256,8 +241,6 @@ describe('proxy', () => { endpoint: 'my-endpoint', securityGroups: [], }); - - }); test('grant rds-db:connect in grantConnect() with a dbUser explicitly passed', () => { @@ -269,7 +252,7 @@ describe('proxy', () => { importedDbProxy.grantConnect(role, databaseUser); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [{ Effect: 'Allow', @@ -289,8 +272,6 @@ describe('proxy', () => { Version: '2012-10-17', }, }); - - }); test('throws when grantConnect() is used without a dbUser', () => { @@ -303,8 +284,6 @@ describe('proxy', () => { expect(() => { importedDbProxy.grantConnect(role); }).toThrow(/For imported Database Proxies, the dbUser is required in grantConnect/); - - }); }); @@ -328,7 +307,7 @@ describe('proxy', () => { proxy.grantConnect(role); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [{ Effect: 'Allow', @@ -362,8 +341,6 @@ describe('proxy', () => { Version: '2012-10-17', }, }); - - }); test('new Proxy with multiple Secrets cannot use grantConnect() without a dbUser passed', () => { @@ -391,8 +368,6 @@ describe('proxy', () => { expect(() => { proxy.grantConnect(role); }).toThrow(/When the Proxy contains multiple Secrets, you must pass a dbUser explicitly to grantConnect/); - - }); test('DBProxyTargetGroup should have dependency on the proxy targets', () => { @@ -412,7 +387,7 @@ describe('proxy', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBProxyTargetGroup', { + Template.fromStack(stack).hasResource('AWS::RDS::DBProxyTargetGroup', { Properties: { DBProxyName: { Ref: 'proxy3A1DA9C7', @@ -429,8 +404,6 @@ describe('proxy', () => { 'clusterSecurityGroupF441DCEA', 'clusterSubnets81E3593F', ], - }, ResourcePart.CompleteDefinition); - - + }); }); }); diff --git a/packages/@aws-cdk/aws-rds/test/serverless-cluster-from-snapshot.test.ts b/packages/@aws-cdk/aws-rds/test/serverless-cluster-from-snapshot.test.ts index 4953fa6da7a71..489cd91ae861d 100644 --- a/packages/@aws-cdk/aws-rds/test/serverless-cluster-from-snapshot.test.ts +++ b/packages/@aws-cdk/aws-rds/test/serverless-cluster-from-snapshot.test.ts @@ -1,5 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; -import { ABSENT, ResourcePart } from '@aws-cdk/assert-internal'; +import { Match, Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as kms from '@aws-cdk/aws-kms'; import * as cdk from '@aws-cdk/core'; @@ -18,7 +17,7 @@ describe('serverless cluster from snapshot', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResource('AWS::RDS::DBCluster', { Properties: { Engine: 'aurora-mysql', DBClusterParameterGroupName: 'default.aurora-mysql5.7', @@ -39,7 +38,7 @@ describe('serverless cluster from snapshot', () => { }, DeletionPolicy: 'Snapshot', UpdateReplacePolicy: 'Snapshot', - }, ResourcePart.CompleteDefinition); + }); }); test('can generate a new snapshot password', () => { @@ -57,8 +56,8 @@ describe('serverless cluster from snapshot', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { - MasterUsername: ABSENT, + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { + MasterUsername: Match.absent(), MasterUserPassword: { 'Fn::Join': ['', [ '{{resolve:secretsmanager:', @@ -67,7 +66,7 @@ describe('serverless cluster from snapshot', () => { ]], }, }); - expect(stack).toHaveResource('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { Description: { 'Fn::Join': ['', ['Generated by the CDK for stack: ', { Ref: 'AWS::StackName' }]], }, @@ -95,7 +94,7 @@ describe('serverless cluster from snapshot', () => { }); // THEN - expect(stack).toHaveResource('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { ReplicaRegions: [ { Region: 'eu-west-1', @@ -130,8 +129,8 @@ describe('serverless cluster from snapshot', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { - MasterUsername: ABSENT, + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { + MasterUsername: Match.absent(), MasterUserPassword: 'mysecretpassword', }); }); @@ -153,8 +152,8 @@ describe('serverless cluster from snapshot', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { - MasterUsername: ABSENT, + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { + MasterUsername: Match.absent(), MasterUserPassword: { 'Fn::Join': ['', ['{{resolve:secretsmanager:', { Ref: 'DBSecretD58955BC' }, ':SecretString:password::}}']], }, @@ -162,8 +161,8 @@ describe('serverless cluster from snapshot', () => { }); }); -function testStack(app?: cdk.App, id?: string): cdk.Stack { - const stack = new cdk.Stack(app, id, { env: { account: '12345', region: 'us-test-1' } }); +function testStack(): cdk.Stack { + const stack = new cdk.Stack(undefined, undefined, { env: { account: '12345', region: 'us-test-1' } }); stack.node.setContext('availability-zones:12345:us-test-1', ['us-test-1a', 'us-test-1b']); return stack; } diff --git a/packages/@aws-cdk/aws-rds/test/serverless-cluster.test.ts b/packages/@aws-cdk/aws-rds/test/serverless-cluster.test.ts index dff8d035b78a3..3849a99cdeb02 100644 --- a/packages/@aws-cdk/aws-rds/test/serverless-cluster.test.ts +++ b/packages/@aws-cdk/aws-rds/test/serverless-cluster.test.ts @@ -1,5 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; -import { ResourcePart, SynthUtils } from '@aws-cdk/assert-internal'; +import { Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; @@ -25,7 +24,7 @@ describe('serverless cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResource('AWS::RDS::DBCluster', { Properties: { Engine: 'aurora-postgresql', DBClusterParameterGroupName: 'default.aurora-postgresql10', @@ -47,9 +46,7 @@ describe('serverless cluster', () => { }, DeletionPolicy: 'Snapshot', UpdateReplacePolicy: 'Snapshot', - }, ResourcePart.CompleteDefinition); - - + }); }); test('can create a Serverless Cluster with Aurora Mysql database engine', () => { @@ -64,7 +61,7 @@ describe('serverless cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResource('AWS::RDS::DBCluster', { Properties: { Engine: 'aurora-mysql', DBClusterParameterGroupName: 'default.aurora-mysql5.7', @@ -108,8 +105,7 @@ describe('serverless cluster', () => { }, DeletionPolicy: 'Snapshot', UpdateReplacePolicy: 'Snapshot', - }, ResourcePart.CompleteDefinition); - + }); }); test('can create a Serverless cluster with imported vpc and security group', () => { @@ -129,7 +125,7 @@ describe('serverless cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { Engine: 'aurora-postgresql', DBClusterParameterGroupName: 'default.aurora-postgresql10', EngineMode: 'serverless', @@ -160,8 +156,6 @@ describe('serverless cluster', () => { }, VpcSecurityGroupIds: ['SecurityGroupId12345'], }); - - }); test("sets the retention policy of the SubnetGroup to 'Retain' if the Serverless Cluster is created with 'Retain'", () => { @@ -174,12 +168,10 @@ describe('serverless cluster', () => { removalPolicy: cdk.RemovalPolicy.RETAIN, }); - expect(stack).toHaveResourceLike('AWS::RDS::DBSubnetGroup', { + Template.fromStack(stack).hasResource('AWS::RDS::DBSubnetGroup', { DeletionPolicy: 'Retain', UpdateReplacePolicy: 'Retain', - }, ResourcePart.CompleteDefinition); - - + }); }); test('creates a secret when master credentials are not specified', () => { @@ -198,7 +190,7 @@ describe('serverless cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { MasterUsername: { 'Fn::Join': [ '', @@ -225,7 +217,7 @@ describe('serverless cluster', () => { }, }); - expect(stack).toHaveResource('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { GenerateSecretString: { ExcludeCharacters: '"@/\\', GenerateStringKey: 'password', @@ -233,8 +225,6 @@ describe('serverless cluster', () => { SecretStringTemplate: '{"username":"myuser"}', }, }); - - }); test('create an Serverless cluster with custom KMS key for storage', () => { @@ -250,7 +240,7 @@ describe('serverless cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { KmsKeyId: { 'Fn::GetAtt': [ 'Key961B73FD', @@ -258,8 +248,6 @@ describe('serverless cluster', () => { ], }, }); - - }); test('create a cluster using a specific version of Postgresql', () => { @@ -276,13 +264,11 @@ describe('serverless cluster', () => { }); // THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { Engine: 'aurora-postgresql', EngineMode: 'serverless', EngineVersion: '10.7', }); - - }); test('cluster exposes different read and write endpoints', () => { @@ -302,8 +288,6 @@ describe('serverless cluster', () => { // THEN expect(stack.resolve(cluster.clusterEndpoint)).not .toEqual(stack.resolve(cluster.clusterReadEndpoint)); - - }); test('imported cluster with imported security group honors allowAllOutbound', () => { @@ -324,11 +308,9 @@ describe('serverless cluster', () => { cluster.connections.allowToAnyIpv4(ec2.Port.tcp(443)); // THEN - expect(stack).toHaveResource('AWS::EC2::SecurityGroupEgress', { + Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroupEgress', { GroupId: 'sg-123456789', }); - - }); test('can import a serverless cluster with minimal attributes', () => { @@ -339,8 +321,6 @@ describe('serverless cluster', () => { }); expect(cluster.clusterIdentifier).toEqual('identifier'); - - }); test('minimal imported cluster throws on accessing attributes for missing parameters', () => { @@ -352,8 +332,6 @@ describe('serverless cluster', () => { expect(() => cluster.clusterEndpoint).toThrow(/Cannot access `clusterEndpoint` of an imported cluster/); expect(() => cluster.clusterReadEndpoint).toThrow(/Cannot access `clusterReadEndpoint` of an imported cluster/); - - }); test('imported cluster can access properties if attributes are provided', () => { @@ -371,8 +349,6 @@ describe('serverless cluster', () => { expect(cluster.clusterEndpoint.socketAddress).toEqual('addr:3306'); expect(cluster.clusterReadEndpoint.socketAddress).toEqual('reader-address:3306'); - - }); test('throws when trying to add rotation to a serverless cluster without secret', () => { @@ -392,8 +368,6 @@ describe('serverless cluster', () => { // THEN expect(() => cluster.addRotationSingleUser()).toThrow(/without secret/); - - }); test('throws when trying to add single user rotation multiple times', () => { @@ -411,8 +385,6 @@ describe('serverless cluster', () => { // THEN expect(() => cluster.addRotationSingleUser()).toThrow(/A single user rotation was already added to this cluster/); - - }); test('can set deletion protection', () => { @@ -428,11 +400,9 @@ describe('serverless cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { DeletionProtection: true, }); - - }); test('can set backup retention', () => { @@ -448,16 +418,15 @@ describe('serverless cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { BackupRetentionPeriod: 2, }); - - }); test('does not throw (but adds a node error) if a (dummy) VPC does not have sufficient subnets', () => { // GIVEN - const stack = testStack(); + const app = new cdk.App(); + const stack = testStack(app, 'TestStack'); const vpc = ec2.Vpc.fromLookup(stack, 'VPC', { isDefault: true }); // WHEN @@ -470,11 +439,9 @@ describe('serverless cluster', () => { }); // THEN - const art = SynthUtils.synthesize(stack); + const art = app.synth().getStackArtifact('TestStack'); const meta = art.findMetadataByType('aws:cdk:error'); expect(meta[0].data).toEqual('Cluster requires at least 2 subnets, got 0'); - - }); test('can set scaling configuration', () => { @@ -494,7 +461,7 @@ describe('serverless cluster', () => { }); //THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { ScalingConfiguration: { AutoPause: true, MaxCapacity: 128, @@ -502,8 +469,6 @@ describe('serverless cluster', () => { SecondsUntilAutoPause: 600, }, }); - - }); test('can enable Data API', () => { @@ -519,11 +484,9 @@ describe('serverless cluster', () => { }); //THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { EnableHttpEndpoint: true, }); - - }); test('default scaling options', () => { @@ -539,13 +502,11 @@ describe('serverless cluster', () => { }); //THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { ScalingConfiguration: { AutoPause: true, }, }); - - }); test('auto pause is disabled if a time of zero is specified', () => { @@ -563,13 +524,11 @@ describe('serverless cluster', () => { }); //THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { ScalingConfiguration: { AutoPause: false, }, }); - - }); test('throws when invalid auto pause time is specified', () => { @@ -595,8 +554,6 @@ describe('serverless cluster', () => { autoPause: cdk.Duration.days(2), }, })).toThrow(/auto pause time must be between 5 minutes and 1 day./); - - }); test('throws when invalid backup retention period is specified', () => { @@ -618,8 +575,6 @@ describe('serverless cluster', () => { vpc, backupRetention: cdk.Duration.days(36), })).toThrow(/backup retention period must be between 1 and 35 days. received: 36/); - - }); test('throws error when min capacity is greater than max capacity', () => { @@ -637,8 +592,6 @@ describe('serverless cluster', () => { maxCapacity: AuroraCapacityUnit.ACU_1, }, })).toThrow(/maximum capacity must be greater than or equal to minimum capacity./); - - }); test('check that clusterArn property works', () => { @@ -669,7 +622,6 @@ describe('serverless cluster', () => { ], ], }); - }); test('can grant Data API access', () => { @@ -687,7 +639,7 @@ describe('serverless cluster', () => { cluster.grantDataApiAccess(user); // THEN - expect(stack).toHaveResource('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -721,8 +673,6 @@ describe('serverless cluster', () => { }, ], }); - - }); test('can grant Data API access on imported cluster with given secret', () => { @@ -742,7 +692,7 @@ describe('serverless cluster', () => { cluster.grantDataApiAccess(user); // THEN - expect(stack).toHaveResource('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -776,8 +726,6 @@ describe('serverless cluster', () => { }, ], }); - - }); test('grant Data API access enables the Data API', () => { @@ -794,11 +742,9 @@ describe('serverless cluster', () => { cluster.grantDataApiAccess(user); //THEN - expect(stack).toHaveResource('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { EnableHttpEndpoint: true, }); - - }); test('grant Data API access throws if the Data API is disabled', () => { @@ -814,8 +760,6 @@ describe('serverless cluster', () => { // WHEN expect(() => cluster.grantDataApiAccess(user)).toThrow(/Cannot grant Data API access when the Data API is disabled/); - - }); test('changes the case of the cluster identifier if the lowercaseDbIdentifier feature flag is enabled', () => { @@ -835,11 +779,9 @@ describe('serverless cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { DBClusterIdentifier: clusterIdentifier.toLowerCase(), }); - - }); test('does not change the case of the cluster identifier if the lowercaseDbIdentifier feature flag is disabled', () => { @@ -857,11 +799,9 @@ describe('serverless cluster', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::RDS::DBCluster', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBCluster', { DBClusterIdentifier: clusterIdentifier, }); - - }); }); diff --git a/packages/@aws-cdk/aws-rds/test/sql-server/sql-server.instance-engine.test.ts b/packages/@aws-cdk/aws-rds/test/sql-server/sql-server.instance-engine.test.ts index 72615d08f2093..a591dfd4a7bf1 100644 --- a/packages/@aws-cdk/aws-rds/test/sql-server/sql-server.instance-engine.test.ts +++ b/packages/@aws-cdk/aws-rds/test/sql-server/sql-server.instance-engine.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as core from '@aws-cdk/core'; import * as rds from '../../lib'; @@ -12,11 +12,9 @@ describe('sql server instance engine', () => { }), }).bindToInstance({}); - expect(stack).toHaveResourceLike('AWS::RDS::DBParameterGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBParameterGroup', { Family: 'sqlserver-web-11.0', }); - - }); test("has MajorEngineVersion ending in '11.00' for major version 11", () => { @@ -35,11 +33,9 @@ describe('sql server instance engine', () => { ], }); - expect(stack).toHaveResourceLike('AWS::RDS::OptionGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::OptionGroup', { MajorEngineVersion: '11.00', }); - - }); }); }); diff --git a/packages/@aws-cdk/aws-rds/test/subnet-group.test.ts b/packages/@aws-cdk/aws-rds/test/subnet-group.test.ts index 1dc9718258deb..44fd4e24482a8 100644 --- a/packages/@aws-cdk/aws-rds/test/subnet-group.test.ts +++ b/packages/@aws-cdk/aws-rds/test/subnet-group.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as cdk from '@aws-cdk/core'; import * as rds from '../lib'; @@ -10,7 +10,6 @@ describe('subnet group', () => { beforeEach(() => { stack = new cdk.Stack(); vpc = new ec2.Vpc(stack, 'VPC'); - }); test('creates a subnet group from minimal properties', () => { @@ -19,15 +18,13 @@ describe('subnet group', () => { vpc, }); - expect(stack).toHaveResource('AWS::RDS::DBSubnetGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBSubnetGroup', { DBSubnetGroupDescription: 'MyGroup', SubnetIds: [ { Ref: 'VPCPrivateSubnet1Subnet8BCA10E0' }, { Ref: 'VPCPrivateSubnet2SubnetCFCDAA7A' }, ], }); - - }); test('creates a subnet group from all properties', () => { @@ -38,7 +35,7 @@ describe('subnet group', () => { vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE }, }); - expect(stack).toHaveResource('AWS::RDS::DBSubnetGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBSubnetGroup', { DBSubnetGroupDescription: 'My Shared Group', DBSubnetGroupName: 'sharedgroup', SubnetIds: [ @@ -46,8 +43,6 @@ describe('subnet group', () => { { Ref: 'VPCPrivateSubnet2SubnetCFCDAA7A' }, ], }); - - }); test('correctly creates a subnet group with a deploy-time value for its name', () => { @@ -59,13 +54,11 @@ describe('subnet group', () => { vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE }, }); - expect(stack).toHaveResourceLike('AWS::RDS::DBSubnetGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBSubnetGroup', { DBSubnetGroupName: { Ref: 'Parameter', }, }); - - }); describe('subnet selection', () => { @@ -75,15 +68,13 @@ describe('subnet group', () => { vpc, }); - expect(stack).toHaveResource('AWS::RDS::DBSubnetGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBSubnetGroup', { DBSubnetGroupDescription: 'MyGroup', SubnetIds: [ { Ref: 'VPCPrivateSubnet1Subnet8BCA10E0' }, { Ref: 'VPCPrivateSubnet2SubnetCFCDAA7A' }, ], }); - - }); test('can specify subnet type', () => { @@ -93,14 +84,13 @@ describe('subnet group', () => { vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC }, }); - expect(stack).toHaveResource('AWS::RDS::DBSubnetGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::RDS::DBSubnetGroup', { DBSubnetGroupDescription: 'MyGroup', SubnetIds: [ { Ref: 'VPCPublicSubnet1SubnetB4246D30' }, { Ref: 'VPCPublicSubnet2Subnet74179F39' }, ], }); - }); }); @@ -108,8 +98,5 @@ describe('subnet group', () => { const subnetGroup = rds.SubnetGroup.fromSubnetGroupName(stack, 'Group', 'my-subnet-group'); expect(subnetGroup.subnetGroupName).toEqual('my-subnet-group'); - - }); - });