Skip to content

Commit

Permalink
Core: Parameter handling: fix parsing of >= 10 members (#7056)
Browse files Browse the repository at this point in the history
  • Loading branch information
steffyP authored Nov 22, 2023
1 parent b3c3883 commit 7c83ca1
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 7 deletions.
17 changes: 10 additions & 7 deletions moto/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,16 +326,19 @@ def extract_region_from_aws_authorization(string: str) -> Optional[str]:
return region


def params_sort_function(item: Tuple[str, Any]) -> Tuple[str, Any]:
def params_sort_function(item: Tuple[str, Any]) -> Tuple[str, int, str]:
"""
Comparison function used to sort params appropriately taking tags non
alphabetical order into consideration
sort by <string-prefix>.member.<integer>.<string-postfix>:
in case there are more than 10 members, the default-string sort would lead to IndexError when parsing the content.
Note: currently considers only the first occurence of `member`, but there may be cases with nested members
"""
key, _ = item
if key.startswith("Tags.member"):
member_num = int(key.split(".")[2])
return ("Tags.member", member_num)
return item

match = re.search(r"(.*?member)\.(\d+)(.*)", key)
if match:
return (match.group(1), int(match.group(2)), match.group(3))
return (key, 0, "")


def gzip_decompress(body: bytes) -> bytes:
Expand Down
35 changes: 35 additions & 0 deletions tests/test_autoscaling/test_autoscaling_tags.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import copy

import boto3

from moto import mock_autoscaling, mock_ec2
Expand Down Expand Up @@ -231,6 +233,39 @@ def test_describe_tags_filter_by_propgateatlaunch():
]


@mock_autoscaling
def test_create_20_tags_auto_scaling_group():
"""test to verify that the tag-members are sorted correctly, and there is no regression for
https://github.com/getmoto/moto/issues/6033
"""
subnet = setup_networking()["subnet1"]
client = boto3.client("autoscaling", region_name="us-east-1")
original = {
"ResourceId": "test_asg",
"PropagateAtLaunch": True,
}
tags = []
for i in range(0, 20):
cp = copy.deepcopy(original)
cp["Key"] = f"test_key{i}"
cp["Value"] = f"random-value-{i}"
tags.append(cp)
client.create_launch_configuration(
LaunchConfigurationName="test_launch_configuration",
ImageId=EXAMPLE_AMI_ID,
InstanceType="t2.medium",
)
client.create_auto_scaling_group(
AutoScalingGroupName="test_asg",
LaunchConfigurationName="test_launch_configuration",
MinSize=0,
MaxSize=20,
DesiredCapacity=5,
Tags=tags,
VPCZoneIdentifier=subnet,
)


def create_asgs(client, subnet):
_ = client.create_launch_configuration(
LaunchConfigurationName="test_launch_configuration",
Expand Down
40 changes: 40 additions & 0 deletions tests/test_cloudwatch/test_cloudwatch_boto3.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import copy

import boto3
import pytest

Expand Down Expand Up @@ -1903,3 +1905,41 @@ def test_get_metric_data_with_custom_label():
)
assert len(metric_result_data) == 1
assert metric_result_data[0]["Label"] == expected_value


@mock_cloudwatch
def test_get_metric_data_queries():
"""
verify that >= 10 queries can still be parsed
there was an error with the order of parsing items, leading to IndexError
"""
now = datetime.utcnow().replace(microsecond=0)
start_time = now - timedelta(minutes=10)
end_time = now + timedelta(minutes=5)
original_query = {
"MetricStat": {
"Metric": {
"Namespace": "AWS/RDS",
"MetricName": "CPUUtilization",
"Dimensions": [{"Name": "DBInstanceIdentifier", "Value": ""}],
},
"Period": 1,
"Stat": "Average",
"Unit": "Percent",
},
}

queries = []
for i in range(0, 20):
query = copy.deepcopy(original_query)
query["Id"] = f"q{i}"
query["MetricStat"]["Metric"]["Dimensions"][0]["Value"] = f"id-{i}"
queries.append(query)

assert len(queries) == 20
response = boto3.client("cloudwatch", "eu-west-1").get_metric_data(
StartTime=start_time, EndTime=end_time, MetricDataQueries=queries
)

# we expect twenty results
assert len(response["MetricDataResults"]) == 20

0 comments on commit 7c83ca1

Please sign in to comment.