From 24fc63d583d0df9b8d8fa63902a558dbcc0fbec9 Mon Sep 17 00:00:00 2001 From: jjllee Date: Tue, 13 Feb 2024 18:14:49 -0800 Subject: [PATCH] lint, fix test, debug log --- .../sampler/_aws_xray_sampling_client.py | 21 ++--- .../distro/sampler/_rule_cache.py | 8 +- .../distro/sampler/_sampling_rule_applier.py | 21 +++-- .../distro/sampler/_sampling_target.py | 5 +- .../sampler/test_aws_xray_remote_sampler.py | 22 +++--- .../sampler/test_aws_xray_sampling_client.py | 15 ++-- .../distro/sampler/test_clock.py | 3 +- .../distro/sampler/test_fallback_sampler.py | 27 +++---- .../distro/sampler/test_rate_limiter.py | 14 ++-- .../sampler/test_rate_limiting_sampler.py | 15 ++-- .../distro/sampler/test_rule_cache.py | 79 ++++++++++++------- .../sampler/test_sampling_rule_applier.py | 44 ++++++----- .../test_sampling_statistics_document.py | 1 - 13 files changed, 153 insertions(+), 122 deletions(-) diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_aws_xray_sampling_client.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_aws_xray_sampling_client.py index c06f60c80..411ccd295 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_aws_xray_sampling_client.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_aws_xray_sampling_client.py @@ -48,13 +48,16 @@ def get_sampling_rules(self) -> [_SamplingRule]: _logger.error("Request error occurred: %s", req_err) except json.JSONDecodeError as json_err: _logger.error("Error in decoding JSON response: %s", json_err) + # pylint: disable=broad-exception-caught except Exception as err: _logger.error("Error occurred when attempting to fetch rules: %s", err) return sampling_rules def get_sampling_targets_response(self, statistics: [dict]) -> _SamplingTargetResponse: - sampling_targets_response = _SamplingTargetResponse(LastRuleModification=None, SamplingTargetDocuments=None, UnprocessedStatistics=None) + sampling_targets_response = _SamplingTargetResponse( + LastRuleModification=None, SamplingTargetDocuments=None, UnprocessedStatistics=None + ) headers = {"content-type": "application/json"} try: xray_response = requests.post( @@ -64,22 +67,20 @@ def get_sampling_targets_response(self, statistics: [dict]) -> _SamplingTargetRe json={"SamplingStatisticsDocuments": statistics}, ) if xray_response is None: - _logger.error("GetSamplingTargets response is None. Unable to update targets.") + _logger.debug("GetSamplingTargets response is None. Unable to update targets.") return sampling_targets_response xray_response_json = xray_response.json() - if ( - "SamplingTargetDocuments" not in xray_response_json - or "LastRuleModification" not in xray_response_json - ): - _logger.error("getSamplingTargets response is invalid. Unable to update targets.") + if "SamplingTargetDocuments" not in xray_response_json or "LastRuleModification" not in xray_response_json: + _logger.debug("getSamplingTargets response is invalid. Unable to update targets.") return sampling_targets_response sampling_targets_response = _SamplingTargetResponse(**xray_response_json) except requests.exceptions.RequestException as req_err: - _logger.error("Request error occurred: %s", req_err) + _logger.debug("Request error occurred: %s", req_err) except json.JSONDecodeError as json_err: - _logger.error("Error in decoding JSON response: %s", json_err) + _logger.debug("Error in decoding JSON response: %s", json_err) + # pylint: disable=broad-exception-caught except Exception as err: - _logger.error("Error occurred when attempting to fetch targets: %s", err) + _logger.debug("Error occurred when attempting to fetch targets: %s", err) return sampling_targets_response diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_rule_cache.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_rule_cache.py index 084a5a388..706b11f81 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_rule_cache.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_rule_cache.py @@ -49,7 +49,13 @@ def should_sample( for rule_applier in self.__rule_appliers: if rule_applier.matches(self.__resource, attributes): return rule_applier.should_sample( - parent_context, trace_id, name, kind=kind, attributes=attributes, links=links, trace_state=trace_state + parent_context, + trace_id, + name, + kind=kind, + attributes=attributes, + links=links, + trace_state=trace_state, ) # Should not ever reach fallback sampler as default rule is able to match diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_rule_applier.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_rule_applier.py index 48be3b560..4d13228ba 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_rule_applier.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_rule_applier.py @@ -114,8 +114,12 @@ def matches(self, resource: Resource, attributes: Attributes) -> bool: # also check `HTTP_TARGET/HTTP_URL/HTTP_METHOD/HTTP_HOST` respectively as backup url_path = attributes.get(SpanAttributes.URL_PATH, attributes.get(SpanAttributes.HTTP_TARGET, None)) url_full = attributes.get(SpanAttributes.URL_FULL, attributes.get(SpanAttributes.HTTP_URL, None)) - http_request_method = attributes.get(SpanAttributes.HTTP_REQUEST_METHOD, attributes.get(SpanAttributes.HTTP_METHOD, None)) - server_address = attributes.get(SpanAttributes.SERVER_ADDRESS, attributes.get(SpanAttributes.HTTP_HOST, None)) + http_request_method = attributes.get( + SpanAttributes.HTTP_REQUEST_METHOD, attributes.get(SpanAttributes.HTTP_METHOD, None) + ) + server_address = attributes.get( + SpanAttributes.SERVER_ADDRESS, attributes.get(SpanAttributes.HTTP_HOST, None) + ) # Resource shouldn't be none as it should default to empty resource if resource is not None: @@ -163,21 +167,24 @@ def __get_arn(self, resource: Resource, attributes: Attributes) -> str: arn = resource.attributes.get(ResourceAttributes.AWS_ECS_CONTAINER_ARN, None) if arn is not None: return arn - if resource is not None and resource.attributes.get(ResourceAttributes.CLOUD_PLATFORM) == CloudPlatformValues.AWS_LAMBDA.value: + if ( + resource is not None + and resource.attributes.get(ResourceAttributes.CLOUD_PLATFORM) == CloudPlatformValues.AWS_LAMBDA.value + ): return self.__get_lambda_arn(resource, attributes) return "" def __get_lambda_arn(self, resource: Resource, attributes: Attributes) -> str: - arn = resource.attributes.get(ResourceAttributes.CLOUD_RESOURCE_ID, - resource.attributes.get(ResourceAttributes.FAAS_ID, None)) + arn = resource.attributes.get( + ResourceAttributes.CLOUD_RESOURCE_ID, resource.attributes.get(ResourceAttributes.FAAS_ID, None) + ) if arn is not None: return arn # Note from `SpanAttributes.CLOUD_RESOURCE_ID`: # "On some cloud providers, it may not be possible to determine the full ID at startup, # so it may be necessary to set cloud.resource_id as a span attribute instead." - arn = attributes.get(SpanAttributes.CLOUD_RESOURCE_ID, - attributes.get("faas.id", None)) + arn = attributes.get(SpanAttributes.CLOUD_RESOURCE_ID, attributes.get("faas.id", None)) if arn is not None: return arn diff --git a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_target.py b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_target.py index 3ee00ffcc..32c32f5ce 100644 --- a/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_target.py +++ b/aws-opentelemetry-distro/src/amazon/opentelemetry/distro/sampler/_sampling_target.py @@ -4,6 +4,7 @@ _logger = getLogger(__name__) + # Disable snake_case naming style so this class can match the sampling rules response from X-Ray # pylint: disable=invalid-name class _SamplingTarget: @@ -49,7 +50,7 @@ def __init__( try: self.SamplingTargetDocuments.append(_SamplingTarget(**document)) except TypeError as e: - _logger.debug("TypeError occurred: ", e) + _logger.debug("TypeError occurred: %s", e) self.UnprocessedStatistics: [_UnprocessedStatistics] = [] if UnprocessedStatistics is not None: @@ -57,4 +58,4 @@ def __init__( try: self.UnprocessedStatistics.append(_UnprocessedStatistics(**unprocessed)) except TypeError as e: - _logger.debug("TypeError occurred: ", e) + _logger.debug("TypeError occurred: %s", e) diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_aws_xray_remote_sampler.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_aws_xray_remote_sampler.py index d2b880789..3880189da 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_aws_xray_remote_sampler.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_aws_xray_remote_sampler.py @@ -7,11 +7,6 @@ from unittest import TestCase from unittest.mock import patch -from mock_clock import MockClock - -from amazon.opentelemetry.distro.sampler import _clock -from amazon.opentelemetry.distro.sampler._sampling_rule import _SamplingRule -from amazon.opentelemetry.distro.sampler._sampling_target import _SamplingTargetResponse from amazon.opentelemetry.distro.sampler.aws_xray_remote_sampler import AwsXRayRemoteSampler from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace.sampling import Decision @@ -19,6 +14,7 @@ TEST_DIR = os.path.dirname(os.path.realpath(__file__)) DATA_DIR = os.path.join(TEST_DIR, "data") + class TestAwsXRayRemoteSampler(TestCase): def test_create_remote_sampler_with_empty_resource(self): rs = AwsXRayRemoteSampler(resource=Resource.get_empty()) @@ -63,31 +59,35 @@ class MockResponse: def __init__(self, json_data, status_code): self.json_data = json_data self.status_code = status_code + def json(self): return self.json_data - if kwargs["url"] == 'http://127.0.0.1:2000/GetSamplingRules': + if kwargs["url"] == "http://127.0.0.1:2000/GetSamplingRules": with open(f"{DATA_DIR}/test-remote-sampler_sampling-rules-response-sample.json", encoding="UTF-8") as file: sample_response = json.load(file) file.close() return MockResponse(sample_response, 200) - elif kwargs["url"] == 'http://127.0.0.1:2000/SamplingTargets': - with open(f"{DATA_DIR}/test-remote-sampler_sampling-targets-response-sample.json", encoding="UTF-8") as file: + if kwargs["url"] == "http://127.0.0.1:2000/SamplingTargets": + with open( + f"{DATA_DIR}/test-remote-sampler_sampling-targets-response-sample.json", encoding="UTF-8" + ) as file: sample_response = json.load(file) file.close() return MockResponse(sample_response, 200) return MockResponse(None, 404) - @patch("requests.post", side_effect=mocked_requests_get) - @patch('amazon.opentelemetry.distro.sampler.aws_xray_remote_sampler.DEFAULT_TARGET_POLLING_INTERVAL_SECONDS', new=2) + @patch("amazon.opentelemetry.distro.sampler.aws_xray_remote_sampler.DEFAULT_TARGET_POLLING_INTERVAL_SECONDS", new=2) def test_update_sampling_rules_and_targets_with_pollers_and_should_sample(self, mock_post=None): rs = AwsXRayRemoteSampler( resource=Resource.create({"service.name": "test-service-name", "cloud.platform": "test-cloud-platform"}) ) time.sleep(1.0) - self.assertEqual(rs._AwsXRayRemoteSampler__rule_cache._RuleCache__rule_appliers[0].sampling_rule.RuleName, "test") + self.assertEqual( + rs._AwsXRayRemoteSampler__rule_cache._RuleCache__rule_appliers[0].sampling_rule.RuleName, "test" + ) self.assertEqual(rs.should_sample(None, 0, "name", attributes={"abc": "1234"}).decision, Decision.DROP) # wait 2 more seconds since targets polling was patched to 2 seconds (rather than 10s) diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_aws_xray_sampling_client.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_aws_xray_sampling_client.py index 444a84113..d2d08a448 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_aws_xray_sampling_client.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_aws_xray_sampling_client.py @@ -106,7 +106,6 @@ def validate_match_sampling_rules_properties_with_records(self, sampling_rules, @patch("requests.post") def test_get_sampling_targets(self, mock_post=None): - sampling_targets = [] with open(f"{DATA_DIR}/get-sampling-targets-response-sample.json", encoding="UTF-8") as file: sample_response = json.load(file) mock_post.return_value.configure_mock(**{"json.return_value": sample_response}) @@ -119,11 +118,15 @@ def test_get_sampling_targets(self, mock_post=None): @patch("requests.post") def test_get_invalid_sampling_targets(self, mock_post=None): - mock_post.return_value.configure_mock(**{"json.return_value": { - "LastRuleModification": None, - "SamplingTargetDocuments": None, - "UnprocessedStatistics": None - }}) + mock_post.return_value.configure_mock( + **{ + "json.return_value": { + "LastRuleModification": None, + "SamplingTargetDocuments": None, + "UnprocessedStatistics": None, + } + } + ) client = _AwsXRaySamplingClient("http://127.0.0.1:2000") sampling_targets_response = client.get_sampling_targets_response(statistics=[]) self.assertEqual(sampling_targets_response.SamplingTargetDocuments, []) diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_clock.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_clock.py index 61cc082f3..fc7740799 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_clock.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_clock.py @@ -8,9 +8,10 @@ class TestClock(TestCase): def test_from_timestamp(self): pass + def test_time_delta(self): clock = _Clock() dt = clock.from_timestamp(1707551387.0) delta = clock.time_delta(3600) new_dt = dt + delta - self.assertTrue(new_dt.timestamp() - dt.timestamp() == 3600) \ No newline at end of file + self.assertTrue(new_dt.timestamp() - dt.timestamp() == 3600) diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_fallback_sampler.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_fallback_sampler.py index 609bca54b..44c5d7891 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_fallback_sampler.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_fallback_sampler.py @@ -1,18 +1,16 @@ -# # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -# # SPDX-License-Identifier: Apache-2.0 -# from decimal import Decimal -# from threading import Lock +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 import datetime from unittest import TestCase from mock_clock import MockClock from amazon.opentelemetry.distro.sampler._fallback_sampler import _FallbackSampler -from amazon.opentelemetry.distro.sampler._rate_limiter import _RateLimiter from opentelemetry.sdk.trace.sampling import ALWAYS_OFF, Decision class TestRateLimitingSampler(TestCase): + # pylint: disable=too-many-branches def test_should_sample(self): time_now = datetime.datetime.fromtimestamp(1707551387.0) clock = MockClock(time_now) @@ -26,7 +24,7 @@ def test_should_sample(self): # 0 seconds passed, 0 quota available sampled = 0 - for _ in range(0,100): + for _ in range(0, 30): if sampler.should_sample(None, 1234, "name").decision != Decision.DROP: sampled += 1 self.assertEqual(sampled, 0) @@ -34,7 +32,7 @@ def test_should_sample(self): # 0.4 seconds passed, 0.4 quota available sampled = 0 clock.add_time(0.4) - for _ in range(0,100): + for _ in range(0, 30): if sampler.should_sample(None, 1234, "name").decision != Decision.DROP: sampled += 1 self.assertEqual(sampled, 0) @@ -42,7 +40,7 @@ def test_should_sample(self): # 0.8 seconds passed, 0.8 quota available sampled = 0 clock.add_time(0.4) - for _ in range(0,100): + for _ in range(0, 30): if sampler.should_sample(None, 1234, "name").decision != Decision.DROP: sampled += 1 self.assertEqual(sampled, 0) @@ -50,7 +48,7 @@ def test_should_sample(self): # 1.2 seconds passed, 1 quota consumed, 0 quota available sampled = 0 clock.add_time(0.4) - for _ in range(0,100): + for _ in range(0, 30): if sampler.should_sample(None, 1234, "name").decision != Decision.DROP: sampled += 1 self.assertEqual(sampled, 1) @@ -58,16 +56,15 @@ def test_should_sample(self): # 1.6 seconds passed, 0.4 quota available sampled = 0 clock.add_time(0.4) - for _ in range(0,100): + for _ in range(0, 30): if sampler.should_sample(None, 1234, "name").decision != Decision.DROP: sampled += 1 self.assertEqual(sampled, 0) - # 2.0 seconds passed, 0.8 quota available sampled = 0 clock.add_time(0.4) - for _ in range(0,100): + for _ in range(0, 30): if sampler.should_sample(None, 1234, "name").decision != Decision.DROP: sampled += 1 self.assertEqual(sampled, 0) @@ -75,15 +72,15 @@ def test_should_sample(self): # 2.4 seconds passed, one more quota consumed, 0 quota available sampled = 0 clock.add_time(0.4) - for _ in range(0,100): + for _ in range(0, 30): if sampler.should_sample(None, 1234, "name").decision != Decision.DROP: sampled += 1 self.assertEqual(sampled, 1) - # 100 seconds passed, only one quota can be consumed + # 30 seconds passed, only one quota can be consumed sampled = 0 clock.add_time(100) - for _ in range(0,100): + for _ in range(0, 30): if sampler.should_sample(None, 1234, "name").decision != Decision.DROP: sampled += 1 self.assertEqual(sampled, 1) diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_rate_limiter.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_rate_limiter.py index 90242b4a6..6b35a467d 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_rate_limiter.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_rate_limiter.py @@ -1,7 +1,5 @@ -# # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -# # SPDX-License-Identifier: Apache-2.0 -# from decimal import Decimal -# from threading import Lock +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 import datetime from unittest import TestCase @@ -17,28 +15,28 @@ def test_try_spend(self): rate_limiter = _RateLimiter(1, 30, clock) spent = 0 - for _ in range(0,100): + for _ in range(0, 100): if rate_limiter.try_spend(1, False): spent += 1 self.assertEqual(spent, 0) spent = 0 clock.add_time(0.5) - for _ in range(0,100): + for _ in range(0, 100): if rate_limiter.try_spend(1, False): spent += 1 self.assertEqual(spent, 15) spent = 0 clock.add_time(1) - for _ in range(0,100): + for _ in range(0, 100): if rate_limiter.try_spend(1, True): spent += 1 self.assertEqual(spent, 1) spent = 0 clock.add_time(1000) - for _ in range(0,100): + for _ in range(0, 100): if rate_limiter.try_spend(1, False): spent += 1 self.assertEqual(spent, 30) diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_rate_limiting_sampler.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_rate_limiting_sampler.py index 173072009..0c77d4886 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_rate_limiting_sampler.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_rate_limiting_sampler.py @@ -1,13 +1,10 @@ -# # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -# # SPDX-License-Identifier: Apache-2.0 -# from decimal import Decimal -# from threading import Lock +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 import datetime from unittest import TestCase from mock_clock import MockClock -from amazon.opentelemetry.distro.sampler._rate_limiter import _RateLimiter from amazon.opentelemetry.distro.sampler._rate_limiting_sampler import _RateLimitingSampler from opentelemetry.sdk.trace.sampling import Decision @@ -20,14 +17,14 @@ def test_should_sample(self): # Essentially the same tests as test_rate_limiter.py sampled = 0 - for _ in range(0,100): + for _ in range(0, 100): if sampler.should_sample(None, 1234, "name").decision != Decision.DROP: sampled += 1 self.assertEqual(sampled, 0) sampled = 0 clock.add_time(0.5) - for _ in range(0,100): + for _ in range(0, 100): if sampler.should_sample(None, 1234, "name").decision != Decision.DROP: sampled += 1 self.assertEqual(sampled, 15) @@ -35,7 +32,7 @@ def test_should_sample(self): sampler.borrowing = True sampled = 0 clock.add_time(1) - for _ in range(0,100): + for _ in range(0, 100): if sampler.should_sample(None, 1234, "name").decision != Decision.DROP: sampled += 1 self.assertEqual(sampled, 1) @@ -43,7 +40,7 @@ def test_should_sample(self): sampler.borrowing = False sampled = 0 clock.add_time(1000) - for _ in range(0,100): + for _ in range(0, 100): if sampler.should_sample(None, 1234, "name").decision != Decision.DROP: sampled += 1 self.assertEqual(sampled, 30) diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_rule_cache.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_rule_cache.py index 15e98d4a9..a70b3beee 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_rule_cache.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_rule_cache.py @@ -11,7 +11,7 @@ from amazon.opentelemetry.distro.sampler._sampling_rule import _SamplingRule from amazon.opentelemetry.distro.sampler._sampling_rule_applier import _SamplingRuleApplier from amazon.opentelemetry.distro.sampler._sampling_statistics_document import _SamplingStatisticsDocument -from amazon.opentelemetry.distro.sampler._sampling_target import _SamplingTarget, _SamplingTargetResponse +from amazon.opentelemetry.distro.sampler._sampling_target import _SamplingTargetResponse from opentelemetry.sdk.resources import Resource CLIENT_ID = "12345678901234567890abcd" @@ -134,31 +134,38 @@ def test_update_sampling_targets(self): rule_cache.update_sampling_rules([sampling_rule_1, sampling_rule_2]) # quota should be 1 because of borrowing=true until targets are updated - rule_cache._RuleCache__rule_appliers[0]._SamplingRuleApplier__reservoir_sampler._root._RateLimitingSampler__reservoir._quota = 1 - rule_cache._RuleCache__rule_appliers[0]._SamplingRuleApplier__fixed_rate_sampler._root._rate = sampling_rule_2.FixedRate - rule_cache._RuleCache__rule_appliers[1]._SamplingRuleApplier__reservoir_sampler._root._RateLimitingSampler__reservoir._quota = 1 - rule_cache._RuleCache__rule_appliers[1]._SamplingRuleApplier__fixed_rate_sampler._root._rate = sampling_rule_1.FixedRate + rule_applier_0 = rule_cache._RuleCache__rule_appliers[0] + self.assertEqual( + rule_applier_0._SamplingRuleApplier__reservoir_sampler._root._RateLimitingSampler__reservoir._quota, 1 + ) + self.assertEqual(rule_applier_0._SamplingRuleApplier__fixed_rate_sampler._root._rate, sampling_rule_2.FixedRate) + + rule_applier_1 = rule_cache._RuleCache__rule_appliers[1] + self.assertEqual( + rule_applier_1._SamplingRuleApplier__reservoir_sampler._root._RateLimitingSampler__reservoir._quota, 1 + ) + self.assertEqual(rule_applier_1._SamplingRuleApplier__fixed_rate_sampler._root._rate, sampling_rule_1.FixedRate) target_1 = { "FixedRate": 0.05, "Interval": 15, "ReservoirQuota": 1, "ReservoirQuotaTTL": mock_clock.now().timestamp() + 10, - "RuleName": "default" + "RuleName": "default", } target_2 = { "FixedRate": 0.15, "Interval": 12, "ReservoirQuota": 5, "ReservoirQuotaTTL": mock_clock.now().timestamp() + 10, - "RuleName": "test" + "RuleName": "test", } target_3 = { "FixedRate": 0.15, "Interval": 3, "ReservoirQuota": 5, "ReservoirQuotaTTL": mock_clock.now().timestamp() + 10, - "RuleName": "associated rule does not exist" + "RuleName": "associated rule does not exist", } target_response = _SamplingTargetResponse(mock_clock.now().timestamp() - 10, [target_1, target_2, target_3], []) refresh_rules, min_polling_interval = rule_cache.update_sampling_targets(target_response) @@ -170,10 +177,19 @@ def test_update_sampling_targets(self): self.assertEqual(len(rule_cache._RuleCache__rule_appliers), 2) # borrowing=false, use quota from targets - rule_cache._RuleCache__rule_appliers[0]._SamplingRuleApplier__reservoir_sampler._root._RateLimitingSampler__reservoir._quota = target_2["ReservoirQuota"] - rule_cache._RuleCache__rule_appliers[0]._SamplingRuleApplier__fixed_rate_sampler._root._rate = target_2["FixedRate"] - rule_cache._RuleCache__rule_appliers[1]._SamplingRuleApplier__reservoir_sampler._root._RateLimitingSampler__reservoir._quota = target_1["ReservoirQuota"] - rule_cache._RuleCache__rule_appliers[1]._SamplingRuleApplier__fixed_rate_sampler._root._rate = target_1["FixedRate"] + rule_applier_0 = rule_cache._RuleCache__rule_appliers[0] + self.assertEqual( + rule_applier_0._SamplingRuleApplier__reservoir_sampler._root._RateLimitingSampler__reservoir._quota, + target_2["ReservoirQuota"], + ) + self.assertEqual(rule_applier_0._SamplingRuleApplier__fixed_rate_sampler._root._rate, target_2["FixedRate"]) + + rule_applier_1 = rule_cache._RuleCache__rule_appliers[1] + self.assertEqual( + rule_applier_1._SamplingRuleApplier__reservoir_sampler._root._RateLimitingSampler__reservoir._quota, + target_1["ReservoirQuota"], + ) + self.assertEqual(rule_applier_1._SamplingRuleApplier__fixed_rate_sampler._root._rate, target_1["FixedRate"]) # Test target response modified after Rule cache's last modified date target_response.LastRuleModification = mock_clock.now().timestamp() + 1 @@ -195,21 +211,24 @@ def test_get_all_statistics(self): mock_clock.add_time(10) statistics = rule_cache.get_all_statistics() - self.assertEqual(statistics, [ - { - "ClientID": CLIENT_ID, - "RuleName": "test", - "Timestamp": mock_clock.now().timestamp(), - "RequestCount": 4, - "BorrowCount": 2, - "SampleCount": 2, - }, - { - "ClientID": CLIENT_ID, - "RuleName": "default", - "Timestamp": mock_clock.now().timestamp(), - "RequestCount": 5, - "BorrowCount": 5, - "SampleCount": 5, - } - ]) + self.assertEqual( + statistics, + [ + { + "ClientID": CLIENT_ID, + "RuleName": "test", + "Timestamp": mock_clock.now().timestamp(), + "RequestCount": 4, + "BorrowCount": 2, + "SampleCount": 2, + }, + { + "ClientID": CLIENT_ID, + "RuleName": "default", + "Timestamp": mock_clock.now().timestamp(), + "RequestCount": 5, + "BorrowCount": 5, + "SampleCount": 5, + }, + ], + ) diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_sampling_rule_applier.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_sampling_rule_applier.py index 4b7bb62d0..bfadb7c3b 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_sampling_rule_applier.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_sampling_rule_applier.py @@ -25,6 +25,7 @@ CLIENT_ID = "12345678901234567890abcd" +# pylint: disable=no-member class TestSamplingRuleApplier(TestCase): def test_applier_attribute_matching_from_xray_response(self): default_rule = None @@ -91,7 +92,6 @@ def test_applier_matches_with_all_attributes(self): "abc": "123", "def": "456", "ghi": "789", - # Test that deprecated attributes are not used in matching when above new attributes are set "http.host": "deprecated and will not be used in matching", SpanAttributes.HTTP_METHOD: "deprecated and will not be used in matching", @@ -389,15 +389,13 @@ def test_update_sampling_targets(self): rule_applier = _SamplingRuleApplier(sampling_rule, CLIENT_ID, mock_clock) self.assertEqual(rule_applier._SamplingRuleApplier__fixed_rate_sampler._root._rate, 0.11) - self.assertEqual(rule_applier._SamplingRuleApplier__reservoir_sampler._root._RateLimitingSampler__reservoir._quota, 1) + self.assertEqual( + rule_applier._SamplingRuleApplier__reservoir_sampler._root._RateLimitingSampler__reservoir._quota, 1 + ) self.assertEqual(rule_applier._SamplingRuleApplier__reservoir_expiry, mock_clock.now()) target = _SamplingTarget( - FixedRate = 1.0, - Interval = 10, - ReservoirQuota = 30, - ReservoirQuotaTTL = 1707764006.0, - RuleName = "test" + FixedRate=1.0, Interval=10, ReservoirQuota=30, ReservoirQuotaTTL=1707764006.0, RuleName="test" ) rule_applier.update_target(target) @@ -405,7 +403,9 @@ def test_update_sampling_targets(self): mock_clock.set_time(time_now) self.assertEqual(rule_applier._SamplingRuleApplier__fixed_rate_sampler._root._rate, 1.0) - self.assertEqual(rule_applier._SamplingRuleApplier__reservoir_sampler._root._RateLimitingSampler__reservoir._quota, 30) + self.assertEqual( + rule_applier._SamplingRuleApplier__reservoir_sampler._root._RateLimitingSampler__reservoir._quota, 30 + ) self.assertEqual(rule_applier._SamplingRuleApplier__reservoir_expiry, mock_clock.now()) @staticmethod @@ -420,8 +420,8 @@ def fake_ratio_do_sample(*args, **kwargs): def fake_ratio_do_not_sample(*args, **kwargs): return SamplingResult(decision=Decision.RECORD_AND_SAMPLE, attributes=None, trace_state=None) - @patch.object(TraceIdRatioBased, 'should_sample', fake_ratio_do_sample) - @patch.object(_RateLimitingSampler, 'should_sample', fake_reservoir_do_sample) + @patch.object(TraceIdRatioBased, "should_sample", fake_ratio_do_sample) + @patch.object(_RateLimitingSampler, "should_sample", fake_reservoir_do_sample) def test_populate_and_get_then_reset_statistics(self): mock_clock = MockClock() rule_applier = _SamplingRuleApplier(_SamplingRule(RuleName="test", ReservoirSize=10), CLIENT_ID, mock_clock) @@ -445,29 +445,31 @@ def test_should_sample_logic_from_reservoir(self): reservoir_size = 10 time_now = datetime.datetime.fromtimestamp(1707551387.0) mock_clock = MockClock(time_now) - rule_applier = _SamplingRuleApplier(_SamplingRule(RuleName="test", ReservoirSize=reservoir_size, FixedRate=0.0), CLIENT_ID, mock_clock) + rule_applier = _SamplingRuleApplier( + _SamplingRule(RuleName="test", ReservoirSize=reservoir_size, FixedRate=0.0), CLIENT_ID, mock_clock + ) mock_clock.add_time(seconds=2.0) sampled_count = 0 - for _ in range(0,reservoir_size + 10): + for _ in range(0, reservoir_size + 10): if rule_applier.should_sample(None, 0, "name").decision != Decision.DROP: sampled_count += 1 self.assertEqual(sampled_count, 1) # borrow means only 1 sampled target = _SamplingTarget( - FixedRate = 0.0, - Interval = 10, - ReservoirQuota = 10, - ReservoirQuotaTTL = mock_clock.now().timestamp() + 10, - RuleName = "test" + FixedRate=0.0, + Interval=10, + ReservoirQuota=10, + ReservoirQuotaTTL=mock_clock.now().timestamp() + 10, + RuleName="test", ) rule_applier.update_target(target) # Use only 100% of quota (10 out of 10), even if 2 seconds have passed mock_clock.add_time(seconds=2.0) sampled_count = 0 - for _ in range(0,reservoir_size + 10): + for _ in range(0, reservoir_size + 10): if rule_applier.should_sample(None, 0, "name").decision != Decision.DROP: sampled_count += 1 self.assertEqual(sampled_count, reservoir_size) @@ -475,7 +477,7 @@ def test_should_sample_logic_from_reservoir(self): # Use only 50% of quota (5 out of 10) mock_clock.add_time(seconds=0.5) sampled_count = 0 - for _ in range(0,reservoir_size + 10): + for _ in range(0, reservoir_size + 10): if rule_applier.should_sample(None, 0, "name").decision != Decision.DROP: sampled_count += 1 self.assertEqual(sampled_count, 5) @@ -483,7 +485,7 @@ def test_should_sample_logic_from_reservoir(self): # Expired, used borrowing logic again mock_clock.add_time(seconds=7.5) sampled_count = 0 - for _ in range(0,reservoir_size + 10): + for _ in range(0, reservoir_size + 10): if rule_applier.should_sample(None, 0, "name").decision != Decision.DROP: sampled_count += 1 - self.assertEqual(sampled_count, 1) \ No newline at end of file + self.assertEqual(sampled_count, 1) diff --git a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_sampling_statistics_document.py b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_sampling_statistics_document.py index 4f02e79d5..bf147ff1b 100644 --- a/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_sampling_statistics_document.py +++ b/aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/sampler/test_sampling_statistics_document.py @@ -32,4 +32,3 @@ def test_sampling_statistics_document_inputs(self): self.assertEqual(snapshot.get("RequestCount"), 1) self.assertEqual(snapshot.get("BorrowCount"), 2) self.assertEqual(snapshot.get("SampleCount"), 3) - \ No newline at end of file