Fix:CloudWatch List metrics with dimensions (#3461)

* Fix:CloudWatch List metrics with dimensions

* Fix:CloudWatch List metrics with dimensions

* Fixed new cases and added more tests

Co-authored-by: usmankb <usman@krazybee.com>
This commit is contained in:
usmangani1 2020-11-20 18:08:48 +05:30 committed by GitHub
parent 8a95878a81
commit 54e296eb53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 146 additions and 7 deletions

View File

@ -155,6 +155,18 @@ class FakeAlarm(BaseModel):
self.state_updated_timestamp = datetime.utcnow()
def are_dimensions_same(metric_dimensions, dimensions):
for dimension in metric_dimensions:
for new_dimension in dimensions:
if (
dimension.name != new_dimension.name
or dimension.value != new_dimension.value
):
return False
return True
class MetricDatum(BaseModel):
def __init__(self, namespace, name, value, dimensions, timestamp):
self.namespace = namespace
@ -165,11 +177,17 @@ class MetricDatum(BaseModel):
Dimension(dimension["Name"], dimension["Value"]) for dimension in dimensions
]
def filter(self, namespace, name, dimensions):
def filter(self, namespace, name, dimensions, already_present_metrics):
if namespace and namespace != self.namespace:
return False
if name and name != self.name:
return False
for metric in already_present_metrics:
if self.dimensions and are_dimensions_same(
metric.dimensions, self.dimensions
):
return False
if dimensions and any(
Dimension(d["Name"], d["Value"]) not in self.dimensions for d in dimensions
):
@ -514,12 +532,16 @@ class CloudWatchBackend(BaseBackend):
def get_filtered_metrics(self, metric_name, namespace, dimensions):
metrics = self.get_all_metrics()
metrics = [
md
for md in metrics
if md.filter(namespace=namespace, name=metric_name, dimensions=dimensions)
]
return metrics
new_metrics = []
for md in metrics:
if md.filter(
namespace=namespace,
name=metric_name,
dimensions=dimensions,
already_present_metrics=new_metrics,
):
new_metrics.append(md)
return new_metrics
def _get_paginated(self, metrics):
if len(metrics) > 500:

View File

@ -349,6 +349,123 @@ def test_get_metric_statistics():
datapoint["Sum"].should.equal(1.5)
@mock_cloudwatch
def test_duplicate_put_metric_data():
conn = boto3.client("cloudwatch", region_name="us-east-1")
utc_now = datetime.now(tz=pytz.utc)
conn.put_metric_data(
Namespace="tester",
MetricData=[
dict(
MetricName="metric",
Dimensions=[{"Name": "Name", "Value": "B"}],
Value=1.5,
Timestamp=utc_now,
)
],
)
result = conn.list_metrics(
Namespace="tester", Dimensions=[{"Name": "Name", "Value": "B"}]
)["Metrics"]
len(result).should.equal(1)
conn.put_metric_data(
Namespace="tester",
MetricData=[
dict(
MetricName="metric",
Dimensions=[{"Name": "Name", "Value": "B"}],
Value=1.5,
Timestamp=utc_now,
)
],
)
result = conn.list_metrics(
Namespace="tester", Dimensions=[{"Name": "Name", "Value": "B"}]
)["Metrics"]
len(result).should.equal(1)
conn.put_metric_data(
Namespace="tester",
MetricData=[
dict(
MetricName="metric",
Dimensions=[{"Name": "Name", "Value": "B"}],
Value=1.5,
Timestamp=utc_now,
)
],
)
result = conn.list_metrics(
Namespace="tester", Dimensions=[{"Name": "Name", "Value": "B"}]
)["Metrics"]
result.should.equal(
[
{
"Namespace": "tester",
"MetricName": "metric",
"Dimensions": [{"Name": "Name", "Value": "B"}],
}
]
)
conn.put_metric_data(
Namespace="tester",
MetricData=[
dict(
MetricName="metric",
Dimensions=[
{"Name": "Name", "Value": "B"},
{"Name": "Name", "Value": "C"},
],
Value=1.5,
Timestamp=utc_now,
)
],
)
result = conn.list_metrics(
Namespace="tester", Dimensions=[{"Name": "Name", "Value": "B"}]
)["Metrics"]
result.should.equal(
[
{
"Namespace": "tester",
"MetricName": "metric",
"Dimensions": [{"Name": "Name", "Value": "B"}],
},
{
"Namespace": "tester",
"MetricName": "metric",
"Dimensions": [
{"Name": "Name", "Value": "B"},
{"Name": "Name", "Value": "C"},
],
},
]
)
result = conn.list_metrics(
Namespace="tester", Dimensions=[{"Name": "Name", "Value": "C"}]
)["Metrics"]
result.should.equal(
[
{
"Namespace": "tester",
"MetricName": "metric",
"Dimensions": [
{"Name": "Name", "Value": "B"},
{"Name": "Name", "Value": "C"},
],
}
]
)
@mock_cloudwatch
@freeze_time("2020-02-10 18:44:05")
def test_custom_timestamp():