From b1d30565de376a8e579d7ac50e5a3f29f55305c2 Mon Sep 17 00:00:00 2001 From: Stephen-Bao Date: Sun, 14 Aug 2022 23:50:24 -0400 Subject: [PATCH 1/3] Disallow duplicate dimension sets --- .../logger/metrics_context.py | 8 ++- tests/logger/test_metrics_context.py | 71 +++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/aws_embedded_metrics/logger/metrics_context.py b/aws_embedded_metrics/logger/metrics_context.py index 47ed1dd..7d724e8 100644 --- a/aws_embedded_metrics/logger/metrics_context.py +++ b/aws_embedded_metrics/logger/metrics_context.py @@ -17,7 +17,7 @@ from aws_embedded_metrics.constants import MAX_DIMENSION_SET_SIZE from aws_embedded_metrics.exceptions import DimensionSetExceededError from aws_embedded_metrics.logger.metric import Metric -from typing import List, Dict, Any +from typing import List, Dict, Any, Set class MetricsContext(object): @@ -79,6 +79,12 @@ def put_dimensions(self, dimensions: Dict[str, str]) -> None: self.validate_dimension_set(dimensions) + # Duplicate dimension sets are removed before being added to the end of the collection. + # This ensures only latest dimension value is used as a target member on the root EMF node. + # This operation is O(n^2), but acceptable given sets are capped at 30 dimensions + incoming_keys: Set = set(dimensions.keys()) + self.dimensions = list(filter(lambda dim: (set(dim.keys()) != incoming_keys), self.dimensions)) + self.dimensions.append(dimensions) def set_dimensions(self, dimensionSets: List[Dict[str, str]]) -> None: diff --git a/tests/logger/test_metrics_context.py b/tests/logger/test_metrics_context.py index d1f8b0c..afc2807 100644 --- a/tests/logger/test_metrics_context.py +++ b/tests/logger/test_metrics_context.py @@ -54,6 +54,77 @@ def test_put_dimension_adds_to_dimensions(): assert context.dimensions == [dimension_set] +def test_put_dimensions_accept_multiple_unique_dimensions(): + # arrange + context = MetricsContext() + dimension1 = {fake.word(): fake.word()} + dimension2 = {fake.word(): fake.word()} + + # act + context.put_dimensions(dimension1) + context.put_dimensions(dimension2) + + # assert + assert len(context.get_dimensions()) == 2 + assert context.get_dimensions()[0] == dimension1 + assert context.get_dimensions()[1] == dimension2 + + +def test_put_dimension_prevent_duplicate_dimensions(): + # arrange + context = MetricsContext() + pair1 = [fake.word(), fake.word()] + pair2 = [fake.word(), fake.word()] + + dimension1 = {pair1[0]: pair1[1]} + dimension2 = {pair2[0]: pair2[1]} + dimension3 = {pair1[0]: pair1[1], pair2[0]: pair2[1]} + + # act + context.put_dimensions(dimension1) + context.put_dimensions(dimension2) + context.put_dimensions(dimension1) + context.put_dimensions(dimension3) + context.put_dimensions(dimension2) + context.put_dimensions(dimension3) + + # assert + assert len(context.get_dimensions()) == 3 + assert context.get_dimensions()[0] == dimension1 + assert context.get_dimensions()[1] == dimension2 + assert context.get_dimensions()[2] == dimension3 + + +def test_put_dimension_sort_duplicate_dimensions(): + # arrange + context = MetricsContext() + key1 = fake.word() + key2 = fake.word() + val1 = fake.word() + val2 = fake.word() + + dimension1 = {key1: val1} + dimension2 = {key2: val2} + dimension3 = {key1: val2} + dimension4 = {key2: val1} + dimension5 = {key1: val1, key2: val2} + dimension6 = {key1: val2, key2: val1} + + # act + context.put_dimensions(dimension1) + context.put_dimensions(dimension2) + context.put_dimensions(dimension5) + context.put_dimensions(dimension3) + context.put_dimensions(dimension4) + context.put_dimensions(dimension6) + + # assert + assert len(context.get_dimensions()) == 3 + assert context.get_dimensions()[0] == dimension3 + assert context.get_dimensions()[1] == dimension4 + assert context.get_dimensions()[2] == dimension6 + + def test_get_dimensions_returns_only_custom_dimensions_if_no_default_dimensions_not_set(): # arrange context = MetricsContext() From df3f469d4f235f7470ebcce503e3a83ddf22c943 Mon Sep 17 00:00:00 2001 From: Stephen-Bao Date: Thu, 18 Aug 2022 15:23:56 -0400 Subject: [PATCH 2/3] Adjusted the test --- tests/logger/test_metrics_context.py | 29 ++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/tests/logger/test_metrics_context.py b/tests/logger/test_metrics_context.py index b1a6f87..8b41e04 100644 --- a/tests/logger/test_metrics_context.py +++ b/tests/logger/test_metrics_context.py @@ -128,22 +128,31 @@ def test_put_dimensions_sort_duplicate_dimensions(): def test_put_dimensions_with_set_dimensions(): # arrange context = MetricsContext() - pair1 = [fake.word(), fake.word()] - pair2 = [fake.word(), fake.word()] + key1 = fake.word() + key2 = fake.word() + val1 = fake.word() + val2 = fake.word() - dimension1 = {pair1[0]: pair1[1]} - dimension2 = {pair2[0]: pair2[1]} - dimension3 = {pair1[0]: pair1[1], pair2[0]: pair2[1]} + dimension1 = {key1: val1} + dimension2 = {key2: val2} + dimension3 = {key1: val2} + dimension4 = {key2: val1} + dimension5 = {key1: val1, key2: val2} + dimension6 = {key1: val2, key2: val1} # act context.put_dimensions(dimension1) - context.set_dimensions([dimension2]) - context.put_dimensions(dimension3) + context.put_dimensions(dimension2) + context.set_dimensions([dimension3]) + context.put_dimensions(dimension4) + context.put_dimensions(dimension5) + context.put_dimensions(dimension6) # assert - assert len(context.get_dimensions()) == 2 - assert context.get_dimensions()[0] == dimension2 - assert context.get_dimensions()[1] == dimension3 + assert len(context.get_dimensions()) == 3 + assert context.get_dimensions()[0] == dimension3 + assert context.get_dimensions()[1] == dimension4 + assert context.get_dimensions()[2] == dimension6 def test_get_dimensions_returns_only_custom_dimensions_if_no_default_dimensions_not_set(): From d4f6ee23d0e30cada46d8c2cc62241b4888c3226 Mon Sep 17 00:00:00 2001 From: Stephen-Bao Date: Sun, 21 Aug 2022 19:41:29 -0400 Subject: [PATCH 3/3] Ajusted naming of a test --- tests/logger/test_metrics_context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/logger/test_metrics_context.py b/tests/logger/test_metrics_context.py index 8b41e04..375bff9 100644 --- a/tests/logger/test_metrics_context.py +++ b/tests/logger/test_metrics_context.py @@ -95,7 +95,7 @@ def test_put_dimensions_prevent_duplicate_dimensions(): assert context.get_dimensions()[2] == dimension3 -def test_put_dimensions_sort_duplicate_dimensions(): +def test_put_dimensions_use_most_recent_dimension_value(): # arrange context = MetricsContext() key1 = fake.word()