8000 add resourcegroups validated tests (#9140) · codeperl/localstack@466bfed · GitHub
[go: up one dir, main page]

Skip to content

Commit 466bfed

Browse files
authored
add resourcegroups validated tests (localstack#9140)
1 parent ed4f0fb commit 466bfed

File tree

2 files changed

+757
-9
lines changed

2 files changed

+757
-9
lines changed

tests/aws/services/resource_groups/test_resource_groups.py

Lines changed: 346 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,87 @@
1+
import contextlib
12
import json
3+
import os
24

5+
import pytest
6+
from botocore.exceptions import ClientError
7+
8+
from localstack.constants import TEST_AWS_REGION_NAME
9+
from localstack.testing.aws.util import is_aws_cloud
310
from localstack.testing.pytest import markers
411
from localstack.utils.common import short_uid
12+
from localstack.utils.sync import retry
13+
14+
15+
@pytest.fixture
16+
def resourcegroups_create_group(aws_client):
17+
groups = []
18+
19+
def _create_group(**kwargs):
20+
response = aws_client.resource_groups.create_group(**kwargs)
21+
groups.append(response["Group"]["Name"])
22+
return response
23+
24+
yield _create_group
25+
26+
for group_name in groups:
27+
with contextlib.suppress(
28+
ClientError, KeyError
29+
): # adding KeyError to the list because Moto has a bug
30+
aws_client.resource_groups.delete_group(GroupName=group_name)
31+
32+
33+
@pytest.fixture
34+
def sqs_create_queue_in_region(aws_client_factory):
35+
queue_urls = {}
36+
37+
def factory(region, **kwargs):
38+
if "QueueName" not in kwargs:
39+
kwargs["QueueName"] = "test-queue-%s" % short_uid()
40+
response = aws_client_factory(region_name=region).sqs.create_queue(**kwargs)
41+
url = response["QueueUrl"]
42+
queue_urls.setdefault(region, []).append(url)
43+
44+
return url
45+
46+
yield factory
47+
48+
# cleanup
49+
for queues_region, queue_urls in queue_urls.items():
50+
sqs_client = aws_client_factory(region_name=queues_region).sqs
51+
for queue_url in queue_urls:
52+
with contextlib.suppress(ClientError):
53+
sqs_client.delete_queue(QueueUrl=queue_url)
554

655

56+
@pytest.fixture(autouse=True)
57+
def resource_groups_snapshot_transformers(snapshot):
58+
snapshot.add_transformers_list(
59+
[
60+
snapshot.transform.key_value("Name"),
61+
snapshot.transform.key_value("NextToken"),
62+
]
63+
)
64+
65+
66+
@markers.snapshot.skip_snapshot_verify(
67+
paths=[
68+
"$..GroupArn", # Moto is always returning the region as `us-west-1`, seems to be hard-coded
69+
"$..GroupConfiguration",
70+
"$..NextToken",
71+
]
72+
)
773
class TestResourceGroups:
8-
@markers.aws.unknown
9-
def test_create_group(self, aws_client):
10-
resource_group_client = aws_client.resource_groups
11-
name = "resource_group-{}".format(short_uid())
12-
response = resource_group_client.create_group(
74+
"""
75+
List of Services integrations with resourcegroups
76+
see: https://docs.aws.amazon.com/ARG/latest/userguide/integrated-services-list.html
77+
List of supported resources:
78+
see: https://docs.aws.amazon.com/ARG/latest/userguide/supported-resources.html
79+
"""
80+
81+
@markers.aws.validated
82+
def test_create_group(self, aws_client, resourcegroups_create_group, snapshot):
83+
name = f"resource_group-{short_uid()}"
84+
response = resourcegroups_create_group(
1385
Name=name,
1486
Description="description",
1587
ResourceQuery={
@@ -28,20 +100,285 @@ def test_create_group(self, aws_client):
28100
},
29101
Tags={"resource_group_tag_key": "resource_group_tag_value"},
30102
)
103+
snapshot.match("create-group", response)
31104
assert name == response["Group"]["Name"]
32105
assert "TAG_FILTERS_1_0" == response["ResourceQuery"]["Type"]
33106
assert "resource_group_tag_value" == response["Tags"]["resource_group_tag_key"]
34107

35-
response = resource_group_client.get_group(GroupName=name)
108+
response = aws_client.resource_groups.get_group(GroupName=name)
109+
snapshot.match("get-group", response)
36110
assert "description" == response["Group"]["Description"]
37111

38-
response = resource_group_client.list_groups()
112+
response = aws_client.resource_groups.list_groups()
113+
snapshot.match("list-groups", response)
39114
assert 1 == len(response["GroupIdentifiers"])
40115
assert 1 == len(response["Groups"])
41116

42-
response = resource_group_client.delete_group(GroupName=name)
117+
response = aws_client.resource_groups.delete_group(GroupName=name)
118+
snapshot.match("delete-group", response)
43119
assert name == response["Group"]["Name"]
44120

45-
response = resource_group_client.list_groups()
121+
response = aws_client.resource_groups.list_groups()
122+
snapshot.match("list-groups-after-delete", response)
46123
assert 0 == len(response["GroupIdentifiers"])
47124
assert 0 == len(response["Groups"])
125+
126+
@markers.aws.validated
127+
@pytest.mark.skipif(
128+
condition=not is_aws_cloud(), reason="Not implemented in moto (ListGroupResources)"
129+
)
130+
def test_resource_groups_tag_query(
131+
self, aws_client, snapshot, resourcegroups_create_group, s3_bucket, sqs_create_queue
132+
):
133+
snapshot.add_transformer(snapshot.transform.resource_name())
134+
group_name = f"resource_group-{short_uid()}"
135+
response = resourcegroups_create_group(
136+
Name=group_name,
137+
Description="test-tag-query",
138+
ResourceQuery={
139+
"Type": "TAG_FILTERS_1_0",
140+
"Query": json.dumps(
141+
{
142+
"ResourceTypeFilters": ["AWS::AllSupported"],
143+
"TagFilters": [
144+
{
145+
"Key": "Stage",
146+
"Values": ["test-resource-group"],
147+
}
148+
],
149+
}
150+
),
151+
},
152+
Tags={"GroupTag": "GroupTag1"},
153+
)
154+
snapshot.match("create-group", response)
155+
156+
response = aws_client.resource_groups.list_group_resources(Group=group_name)
157+
snapshot.match("list-group-resources-empty", response)
158+
159+
# create SQS queue
160+
tagged_queue_url = sqs_create_queue()
161+
# tag queue
162+
tags = {"Stage": "test-resource-group"}
163+
aws_client.sqs.tag_queue(QueueUrl=tagged_queue_url, Tags=tags)
164+
165+
aws_client.s3.put_bucket_tagging(
166+
Bucket=s3_bucket, Tagging={"TagSet": [{"Key": "Stage", "Value": "test-resource-group"}]}
167+
)
168+
169+
not_tagged_queue_url = sqs_create_queue()
170+
tags = {"Stage": "not-part-resource-group"}
171+
aws_client.sqs.tag_queue(QueueUrl=not_tagged_queue_url, Tags=tags)
172+
173+
response = aws_client.resource_groups.list_group_resources(Group=group_name)
174+
snapshot.match("list-group-resources", response)
175+
176+
queue_tags = aws_client.sqs.list_queue_tags(QueueUrl=tagged_queue_url)
177+
snapshot.match("get-queue-tags", queue_tags)
178+
179+
aws_client.sqs.untag_queue(QueueUrl=tagged_queue_url, TagKeys=["Stage"])
180+
181+
def _get_group_resources():
182+
_response = aws_client.resource_groups.list_group_resources(Group=group_name)
183+
assert len(response["Resources"]) == 1
184+
return _response
185+
186+
response = retry(_get_group_resources, retries=3, sleep=1)
187+
snapshot.match("list-group-resources-after-queue-removal", response)
188+
189+
@markers.aws.validated
190+
@pytest.mark.skipif(
191+
condition=not is_aws_cloud(), reason="Not implemented in moto (ListGroupResources)"
192+
)
193+
def test_resource_groups_different_region(
194+
self, aws_client_factory, snapshot, resourcegroups_create_group, sqs_create_queue_in_region
195+
):
196+
"""Resource groups can only have resources from the same Region, the one of the group"""
197+
region_1 = TEST_AWS_REGION_NAME
198+
region_2 = "us-east-2"
199+
resourcegroups_client = aws_client_factory(region_name=region_1).resource_groups
200+
snapshot.add_transformer(snapshot.transform.resource_name())
201+
group_name = f"resource_group-{short_uid()}"
202+
response = resourcegroups_create_group(
203+
Name=group_name,
204+
Description="test-tag-query",
205+
ResourceQuery={
206+
"Type": "TAG_FILTERS_1_0",
207+
"Query": json.dumps(
208+
{
209+
"ResourceTypeFilters": ["AWS::AllSupported"],
210+
"TagFilters": [
211+
{
212+
"Key": "Stage",
213+
"Values": ["test-resource-group"],
214+
}
215+
],
216+
}
217+
),
218+
},
219+
Tags={"GroupTag": "GroupTag1"},
220+
)
221+
snapshot.match("create-group", response)
222+
223+
# create 2 SQS queues in different regions with tags
224+
tags = {"Stage": "test-resource-group"}
225+
sqs_create_queue_in_region(region=region_1, tags=tags)
226+
sqs_create_queue_in_region(region=region_2, tags=tags)
227+
228+
response = resourcegroups_client.list_group_resources(Group=group_name)
229+
snapshot.match("list-group-resources", response)
230+
231+
@markers.aws.validated
232+
@pytest.mark.skipif(
233+
condition=not is_aws_cloud(), reason="Not implemented in moto (ListGroupResources)"
234+
)
235+
def test_resource_type_filters(
236+
self, aws_client, snapshot, resourcegroups_create_group, s3_bucket, sqs_create_queue
237+
):
238+
"""Resource group can filter with a ResourceType, like `AWS::S3::Bucket`"""
239+
snapshot.add_transformer(snapshot.transform.resource_name())
240+
group_name = f"resource_group-{short_uid()}"
241+
response = resourcegroups_create_group(
242+
Name=group_name,
243+
Description="test-tag-query",
244+
ResourceQuery={
245+
"Type": "TAG_FILTERS_1_0",
246+
"Query": json.dumps(
247+
{
248+
"ResourceTypeFilters": ["AWS::S3::Bucket"],
249+
"TagFilters": [
250+
{
251+
"Key": "Stage",
252+
"Values": ["test-resource-group"],
253+
}
254+
],
255+
}
256+
),
257+
},
258+
Tags={"GroupTag": "GroupTag1"},
259+
)
260+
snapshot.match("create-group", response)
261+
262+
# create SQS queue with tags
263+
sqs_create_queue(tags={"Stage": "test-resource-group"})
264+
265+
aws_client.s3.put_bucket_tagging(
266+
Bucket=s3_bucket, Tagging={"TagSet": [{"Key": "Stage", "Value": "test-resource-group"}]}
267+
)
268+
269+
response = aws_client.resource_groups.list_group_resources(Group=group_name)
270+
snapshot.match("list-group-resources", response)
271+
272+
@markers.aws.validated
273+
@pytest.mark.skipif(
274+
condition=not is_aws_cloud(), reason="Not implemented in moto (ListGroupResources)"
275+
)
276+
def test_cloudformation_query(
277+
self, aws_client, deploy_cfn_template, snapshot, resourcegroups_create_group
278+
):
279+
snapshot.add_transformers_list(
280+
[
281+
snapshot.transform.key_value("StackIdentifier"),
282+
snapshot.transform.resource_name(),
283+
]
284+
)
285+
stack = deploy_cfn_template(
286+
template_path=os.path.join(
287+
os.path.dirname(__file__), "../../templates/deploy_template_2.yaml"
288+
),
289+
parameters={"CompanyName": "MyCompany", "MyEmail1": "my@email.com"},
290+
)
291+
assert len(stack.outputs) == 3
292+
topic_arn = stack.outputs["MyTopic"]
293+
294+
group_name = f"resource_group-{short_uid()}"
295+
response = resourcegroups_create_group(
296+
Name=group_name,
297+
Description="test-cfn-query",
298+
ResourceQuery={
299+
"Type": "CLOUDFORMATION_STACK_1_0",
300+
"Query": json.dumps(
301+
{
302+
"ResourceTypeFilters": ["AWS::AllSupported"],
303+
"StackIdentifier": stack.stack_id,
304+
}
305+
),
306+
},
307+
)
308+
snapshot.match("create-group", response)
309+
310+
response = aws_client.resource_groups.list_group_resources(Group=group_name)
311+
snapshot.match("list-group-resources", response)
312+
313+
assert topic_arn in [
314+
resource["ResourceArn"] for resource in response["ResourceIdentifiers"]
315+
]
316+
317+
stack.destroy()
318+
319+
response = aws_client.resource_groups.list_group_resources(Group=group_name)
320+
snapshot.match("list-group-resources-after-destroy", response)
321+
322+
with pytest.raises(ClientError) as e:
323+
resourcegroups_create_group(
324+
Name="going-to-fail",
325+
Description="test-cfn-query",
326+
ResourceQuery={
327+
"Type": "CLOUDFORMATION_STACK_1_0",
328+
"Query": json.dumps(
329+
{
330+
"ResourceTypeFilters": ["AWS::AllSupported"],
331+
"StackIdentifier": stack.stack_id,
332+
}
333+
),
334+
},
335+
)
336+
snapshot.match("create-group-with-delete-stack", e.value.response)
337+
338+
@markers.aws.validated
339+
@pytest.mark.skipif(
340+
condition=not is_aws_cloud(), reason="Not implemented in moto (SearchResources)"
341+
)
342+
def test_search_resources(self, aws_client, sqs_create_queue, snapshot):
343+
snapshot.add_transformer(snapshot.transform.resource_name())
344+
# create SQS queue with tags
345+
queue_url = sqs_create_queue(tags={"Stage": "test-resource-group"})
346+
queue_tags = aws_client.sqs.list_queue_tags(QueueUrl=queue_url)
347+
snapshot.match("queue-tags", queue_tags)
348+
349+
def _get_resources(resource_types: list[str], expected: int):
350+
_response = aws_client.resource_groups.search_resources(
351+
ResourceQuery={
352+
"Type": "TAG_FILTERS_1_0",
353+
"Query": json.dumps(
354+
{
355+
"ResourceTypeFilters": resource_types,
356+
"Ta D38D gFilters": [
357+
{
358+
"Key": "Stage",
359+
"Values": ["test-resource-group"],
360+
}
361+
],
362+
}
363+
),
364+
}
365+
)
366+
assert len(_response["ResourceIdentifiers"]) == expected
367+
return _response
368+
369+
retries = 10 if is_aws_cloud() else 3
370+
sleep = 1 if is_aws_cloud() else 0.1
371+
372+
response = retry(
373+
_get_resources,
374+
resource_types=["AWS::AllSupported"],
375+
expected=1,
376+
retries=retries,
377+
sleep=sleep,
378+
)
379+
snapshot.match("list-group-resources-sqs", response)
380+
381+
response = retry(
382+
_get_resources, resource_types=["AWS::S3::Bucket"], expected=0, retries=1, sleep=1
383+
)
384+
snapshot.match("list-group-resources-s3", response)

0 commit comments

Comments
 (0)
0