11import os
2+ from collections .abc import Callable
23
34import pytest
45from localstack_snapshot .snapshots .transformer import SortingTransformer
5- from tests .aws .services .cloudformation .conftest import skip_if_v2_provider
6+ from tests .aws .services .cloudformation .conftest import skip_if_v1_provider
67
8+ from localstack .aws .api .cloudformation import Parameter
79from localstack .testing .pytest import markers
810from localstack .utils .files import load_file
911from localstack .utils .strings import short_uid
1012
1113
1214class TestCdkInit :
13- @pytest .mark .parametrize ("bootstrap_version" , ["10" , "11" , "12" ])
15+ @pytest .mark .parametrize (
16+ "bootstrap_version,parameters" ,
17+ [
18+ ("10" , {"FileAssetsBucketName" : f"cdk-bootstrap-{ short_uid ()} " }),
19+ ("11" , {"FileAssetsBucketName" : f"cdk-bootstrap-{ short_uid ()} " }),
20+ ("12" , {"FileAssetsBucketName" : f"cdk-bootstrap-{ short_uid ()} " }),
21+ (
22+ "28" ,
23+ {
24+ "CloudFormationExecutionPolicies" : "" ,
25+ "FileAssetsBucketKmsKeyId" : "AWS_MANAGED_KEY" ,
26+ "PublicAccessBlockConfiguration" : "true" ,
27+ "TrustedAccounts" : "" ,
28+ "TrustedAccountsForLookup" : "" ,
29+ },
30+ ),
31+ ],
32+ ids = ["10" , "11" , "12" , "28" ],
33+ )
1434 @markers .aws .validated
15- def test_cdk_bootstrap (self , deploy_cfn_template , bootstrap_version , aws_client ):
35+ def test_cdk_bootstrap (self , deploy_cfn_template , aws_client , bootstrap_version , parameters ):
1636 deploy_cfn_template (
1737 template_path = os .path .join (
1838 os .path .dirname (__file__ ),
1939 f"../../../templates/cdk_bootstrap_v{ bootstrap_version } .yaml" ,
2040 ),
21- parameters = { "FileAssetsBucketName" : f"cdk-bootstrap- { short_uid () } " } ,
41+ parameters = parameters ,
2242 )
2343 init_stack_result = deploy_cfn_template (
2444 template_path = os .path .join (
@@ -32,61 +52,136 @@ def test_cdk_bootstrap(self, deploy_cfn_template, bootstrap_version, aws_client)
3252 assert len (stack_res ["StackResources" ]) == 1
3353 assert stack_res ["StackResources" ][0 ]["LogicalResourceId" ] == "CDKMetadata"
3454
35- @skip_if_v2_provider (reason = "CFNV2:Provider" )
3655 @markers .aws .validated
37- def test_cdk_bootstrap_redeploy (self , aws_client , cleanup_stacks , cleanup_changesets , cleanups ):
56+ @pytest .mark .parametrize (
57+ "template,parameters_fn" ,
58+ [
59+ pytest .param (
60+ "cdk_bootstrap.yml" ,
61+ lambda qualifier : [
62+ {
63+ "ParameterKey" : "BootstrapVariant" ,
64+ "ParameterValue" : "AWS CDK: Default Resources" ,
65+ },
66+ {"ParameterKey" : "TrustedAccounts" , "ParameterValue" : "" },
67+ {"ParameterKey" : "TrustedAccountsForLookup" , "ParameterValue" : "" },
68+ {"ParameterKey" : "CloudFormationExecutionPolicies" , "ParameterValue" : "" },
69+ {
70+ "ParameterKey" : "FileAssetsBucketKmsKeyId" ,
71+ "ParameterValue" : "AWS_MANAGED_KEY" ,
72+ },
73+ {
74+ "ParameterKey" : "PublicAccessBlockConfiguration" ,
75+ "ParameterValue" : "true" ,
76+ },
77+ {"ParameterKey" : "Qualifier" , "ParameterValue" : qualifier },
78+ {
79+ "ParameterKey" : "UseExamplePermissionsBoundary" ,
80+ "ParameterValue" : "false" ,
81+ },
82+ ],
83+ id = "v20" ,
84+ ),
85+ pytest .param (
86+ "cdk_bootstrap_v28.yaml" ,
87+ lambda qualifier : [
88+ {"ParameterKey" : "CloudFormationExecutionPolicies" , "ParameterValue" : "" },
89+ {
90+ "ParameterKey" : "FileAssetsBucketKmsKeyId" ,
91+ "ParameterValue" : "AWS_MANAGED_KEY" ,
92+ },
93+ {
94+ "ParameterKey" : "PublicAccessBlockConfiguration" ,
95+ "ParameterValue" : "true" ,
96+ },
97+ {"ParameterKey" : "Qualifier" , "ParameterValue" : qualifier },
98+ {"ParameterKey" : "TrustedAccounts" , "ParameterValue" : "" },
99+ {"ParameterKey" : "TrustedAccountsForLookup" , "ParameterValue" : "" },
100+ ],
101+ id = "v28" ,
102+ ),
103+ ],
104+ )
105+ @markers .snapshot .skip_snapshot_verify (
106+ paths = [
107+ # CFNV2:Provider
108+ "$..Description" ,
109+ # Wrong format, they are our internal parameter format
110+ "$..Parameters" ,
111+ # from the list of changes
112+ "$..Changes..Details" ,
113+ "$..Changes..LogicalResourceId" ,
114+ "$..Changes..ResourceType" ,
115+ "$..Changes..Scope" ,
116+ # provider
117+ "$..IncludeNestedStacks" ,
118+ "$..NotificationARNs" ,
119+ # CFNV2:Describe not supported yet
120+ "$..Outputs..ExportName" ,
121+ # mismatch between amazonaws.com and localhost.localstack.cloud
122+ "$..Outputs..OutputValue" ,
123+ ]
124+ )
125+ @skip_if_v1_provider (reason = "Changes array not in parity" )
126+ def test_cdk_bootstrap_redeploy (
127+ self ,
128+ aws_client ,
129+ cleanup_stacks ,
130+ cleanup_changesets ,
131+ cleanups ,
132+ snapshot ,
133+ template ,
134+ parameters_fn : Callable [[str ], list [Parameter ]],
135+ ):
38136 """Test that simulates a sequence of commands executed by CDK when running 'cdk bootstrap' twice"""
137+ snapshot .add_transformer (snapshot .transform .cloudformation_api ())
138+ snapshot .add_transformer (SortingTransformer ("Parameters" , lambda p : p ["ParameterKey" ]))
139+ snapshot .add_transformer (SortingTransformer ("Outputs" , lambda p : p ["OutputKey" ]))
39140
40141 stack_name = f"CDKToolkit-{ short_uid ()} "
41142 change_set_name = f"cdk-deploy-change-set-{ short_uid ()} "
143+ qualifier = short_uid ()
144+ snapshot .add_transformer (snapshot .transform .regex (qualifier , "<qualifier>" ))
42145
43146 def clean_resources ():
44147 cleanup_stacks ([stack_name ])
45148 cleanup_changesets ([change_set_name ])
46149
47150 cleanups .append (clean_resources )
48151
49- template_body = load_file (
50- os .path .join (os .path .dirname (__file__ ), "../../../templates/cdk_bootstrap.yml " )
152+ template_path = os . path . realpath (
153+ os .path .join (os .path .dirname (__file__ ), f "../../../templates/{ template } " )
51154 )
155+ template_body = load_file (template_path )
156+ if template_body is None :
157+ raise RuntimeError (f"Template { template_path } not loaded" )
158+
52159 aws_client .cloudformation .create_change_set (
53160 StackName = stack_name ,
54161 ChangeSetName = change_set_name ,
55162 TemplateBody = template_body ,
56163 ChangeSetType = "CREATE" ,
57164 Capabilities = ["CAPABILITY_IAM" , "CAPABILITY_NAMED_IAM" , "CAPABILITY_AUTO_EXPAND" ],
58165 Description = "CDK Changeset for execution 731ed7da-8b2d-49c6-bca3-4698b6875954" ,
59- Parameters = [
60- {
61- "ParameterKey" : "BootstrapVariant" ,
62- "ParameterValue" : "AWS CDK: Default Resources" ,
63- },
64- {"ParameterKey" : "TrustedAccounts" , "ParameterValue" : "" },
65- {"ParameterKey" : "TrustedAccountsForLookup" , "ParameterValue" : "" },
66- {"ParameterKey" : "CloudFormationExecutionPolicies" , "ParameterValue" : "" },
67- {"ParameterKey" : "FileAssetsBucketKmsKeyId" , "ParameterValue" : "AWS_MANAGED_KEY" },
68- {"ParameterKey" : "PublicAccessBlockConfiguration" , "ParameterValue" : "true" },
69- {"ParameterKey" : "Qualifier" , "ParameterValue" : "hnb659fds" },
70- {"ParameterKey" : "UseExamplePermissionsBoundary" , "ParameterValue" : "false" },
71- ],
166+ Parameters = parameters_fn (qualifier ),
72167 )
73- aws_client .cloudformation .describe_change_set (
168+ aws_client .cloudformation .get_waiter ( "change_set_create_complete" ). wait (
74169 StackName = stack_name , ChangeSetName = change_set_name
75170 )
76-
77- aws_client .cloudformation .get_waiter ("change_set_create_complete" ).wait (
171+ describe_change_set = aws_client .cloudformation .describe_change_set (
78172 StackName = stack_name , ChangeSetName = change_set_name
79173 )
174+ snapshot .match ("describe-change-set" , describe_change_set )
80175
81176 aws_client .cloudformation .execute_change_set (
82177 StackName = stack_name , ChangeSetName = change_set_name
83178 )
84179
85180 aws_client .cloudformation .get_waiter ("stack_create_complete" ).wait (StackName = stack_name )
86- aws_client .cloudformation .describe_stacks (StackName = stack_name )
181+ stacks = aws_client .cloudformation .describe_stacks (StackName = stack_name )["Stacks" ][0 ]
182+ snapshot .match ("describe-stacks" , stacks )
87183
88- # When CDK toolstrap command is executed again it just confirms that the template is the same
89- aws_client .sts .get_caller_identity ()
184+ # When CDK bootstrap command is executed again it just confirms that the template is the same
90185 aws_client .cloudformation .get_template (StackName = stack_name , TemplateStage = "Original" )
91186
92187 # TODO: create scenario where the template is different to catch cdk behavior
0 commit comments