Skip to content

Commit 10967b1

Browse files
committed
added unit tests
1 parent bf2ae72 commit 10967b1

File tree

5 files changed

+99
-16
lines changed

5 files changed

+99
-16
lines changed

aws-opentelemetry-distro/src/amazon/opentelemetry/distro/_aws_attribute_keys.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
AWS_SDK_DESCENDANT: str = "aws.sdk.descendant"
1414
AWS_CONSUMER_PARENT_SPAN_KIND: str = "aws.consumer.parent.span.kind"
1515
AWS_TRACE_FLAG_SAMPLED: str = "aws.trace.flag.sampled"
16+
AWS_TRACE_LAMBDA_FLAG_MULTIPLE_SERVER: str = "aws.trace.lambda.multiple-server"
1617
AWS_CLOUDFORMATION_PRIMARY_IDENTIFIER: str = "aws.remote.resource.cfn.primary.identifier"
1718

1819
# AWS_#_NAME attributes are not supported in python as they are not part of the Semantic Conventions.

aws-opentelemetry-distro/src/amazon/opentelemetry/distro/aws_lambda_span_processor.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,14 @@
44

55
from typing_extensions import override
66

7+
from amazon.opentelemetry.distro._aws_attribute_keys import AWS_TRACE_LAMBDA_FLAG_MULTIPLE_SERVER
78
from opentelemetry.context import Context
89
from opentelemetry.sdk.trace import ReadableSpan, Span, SpanProcessor
910
from opentelemetry.trace import SpanKind
10-
from amazon.opentelemetry.distro._aws_attribute_keys import AWS_TRACE_LAMBDA_FLAG_MULTIPLE_SERVER
11+
1112

1213
class AwsLambdaSpanProcessor(SpanProcessor):
1314
def __init__(self, instrumentation_names=None):
14-
"""
15-
:param instrumentation_names: A set or list of instrumentation scope names
16-
for which we want to mark as SERVER spans if they are INTERNAL.
17-
"""
1815
self.instrumentation_names = set(instrumentation_names or ["opentelemetry.instrumentation.flask"])
1916
self.parent_lambda_span = None
2017

@@ -23,22 +20,25 @@ def on_start(self, span: Span, parent_context: Optional[Context] = None) -> None
2320
scope = getattr(span, "instrumentation_scope", None)
2421
if span.kind == SpanKind.SERVER and scope.name == "opentelemetry.instrumentation.aws_lambda":
2522
self.parent_lambda_span = span
26-
27-
if span.kind == SpanKind.INTERNAL and scope.name in self.instrumentation_names:
28-
span._kind = SpanKind.SERVER
23+
24+
if (
25+
scope.name in self.instrumentation_names
26+
and self.parent_lambda_span.get_span_context().span_id == span.parent.span_id
27+
):
28+
if span.kind == SpanKind.INTERNAL:
29+
span._kind = SpanKind.SERVER
2930
self.parent_lambda_span.set_attribute(AWS_TRACE_LAMBDA_FLAG_MULTIPLE_SERVER, True)
3031
return
3132

3233
@override
3334
def on_end(self, span: ReadableSpan) -> None:
3435
return
3536

36-
@override
37-
def force_flush(self, timeout_millis: int = 30000) -> bool:
38-
"""Flush any buffered data."""
39-
return True
40-
4137
@override
4238
def shutdown(self) -> None:
43-
"""Clean up."""
4439
self.force_flush()
40+
41+
# pylint: disable=no-self-use
42+
@override
43+
def force_flush(self, timeout_millis: int = None) -> bool:
44+
return True

aws-opentelemetry-distro/src/amazon/opentelemetry/distro/aws_opentelemetry_configurator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
AttributePropagatingSpanProcessorBuilder,
1717
)
1818
from amazon.opentelemetry.distro.aws_batch_unsampled_span_processor import BatchUnsampledSpanProcessor
19+
from amazon.opentelemetry.distro.aws_lambda_span_processor import AwsLambdaSpanProcessor
1920
from amazon.opentelemetry.distro.aws_metric_attributes_span_exporter_builder import (
2021
AwsMetricAttributesSpanExporterBuilder,
2122
)
@@ -24,7 +25,6 @@
2425
from amazon.opentelemetry.distro.otlp_udp_exporter import OTLPUdpSpanExporter
2526
from amazon.opentelemetry.distro.sampler.aws_xray_remote_sampler import AwsXRayRemoteSampler
2627
from amazon.opentelemetry.distro.scope_based_exporter import ScopeBasedPeriodicExportingMetricReader
27-
from amazon.opentelemetry.distro.aws_lambda_span_processor import AwsLambdaSpanProcessor
2828
from amazon.opentelemetry.distro.scope_based_filtering_view import ScopeBasedRetainingView
2929
from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter as OTLPHttpOTLPMetricExporter
3030
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
from unittest import TestCase
4+
from unittest.mock import MagicMock, patch
5+
6+
from amazon.opentelemetry.distro._aws_attribute_keys import AWS_TRACE_LAMBDA_FLAG_MULTIPLE_SERVER
7+
from amazon.opentelemetry.distro.aws_lambda_span_processor import AwsLambdaSpanProcessor
8+
from opentelemetry.trace import Span, SpanContext, SpanKind, TraceFlags
9+
10+
11+
class TestAwsLambdaSpanProcessor(TestCase):
12+
13+
def setUp(self):
14+
self.processor = AwsLambdaSpanProcessor()
15+
self.lambda_span: Span = MagicMock()
16+
self.lambda_span.instrumentation_scope.name = "opentelemetry.instrumentation.aws_lambda"
17+
self.lambda_span.kind = SpanKind.SERVER
18+
19+
self.lambda_span_context: SpanContext = MagicMock()
20+
self.lambda_span_context.trace_id = "ABC"
21+
self.lambda_span_context.span_id = "lambda_id"
22+
23+
self.lambda_span.get_span_context.return_value = self.lambda_span_context
24+
self.processor.on_start(self.lambda_span)
25+
26+
def tearDown(self):
27+
self.processor.on_end(self.lambda_span)
28+
self.processor.shutdown()
29+
30+
@patch("opentelemetry.sdk.trace.Span")
31+
def test_lambda_span_multiple_server_flag_internal_api(self, mock_span_class):
32+
33+
flask_span = mock_span_class.return_value
34+
flask_span.instrumentation_scope.name = "opentelemetry.instrumentation.flask"
35+
flask_span.kind = SpanKind.INTERNAL
36+
flask_span.parent = self.lambda_span_context
37+
38+
self.processor.on_start(flask_span)
39+
40+
self.assertEqual(flask_span._kind, SpanKind.SERVER)
41+
self.assertIn(AWS_TRACE_LAMBDA_FLAG_MULTIPLE_SERVER, self.lambda_span.set_attribute.call_args_list[0][0][0])
42+
43+
self.processor.on_end(flask_span)
44+
self.processor.on_end(self.lambda_span)
45+
46+
self.processor.shutdown()
47+
48+
@patch("opentelemetry.sdk.trace.Span")
49+
def test_lambda_span_multiple_server_flag_server_api(self, mock_span_class):
50+
51+
flask_span = mock_span_class.return_value
52+
flask_span.instrumentation_scope.name = "opentelemetry.instrumentation.flask"
53+
flask_span.kind = SpanKind.SERVER
54+
flask_span.parent = self.lambda_span_context
55+
56+
self.processor.on_start(flask_span)
57+
58+
self.assertEqual(flask_span.kind, SpanKind.SERVER)
59+
self.assertIn(AWS_TRACE_LAMBDA_FLAG_MULTIPLE_SERVER, self.lambda_span.set_attribute.call_args_list[0][0][0])
60+
61+
self.processor.on_end(flask_span)
62+
self.processor.on_end(self.lambda_span)
63+
64+
self.processor.shutdown()
65+
66+
@patch("opentelemetry.sdk.trace.Span")
67+
def test_lambda_span_single_server_span(self, mock_span_class):
68+
69+
flask_span = mock_span_class.return_value
70+
flask_span.instrumentation_scope.name = "opentelemetry.instrumentation.http"
71+
flask_span.kind = SpanKind.CLIENT
72+
flask_span.parent = self.lambda_span_context
73+
74+
self.processor.on_start(flask_span, self.lambda_span_context)
75+
76+
self.assertEqual(flask_span.kind, SpanKind.CLIENT)
77+
flask_span.set_attribute.assert_not_called()
78+
79+
self.processor.on_end(flask_span)
80+
self.processor.on_end(self.lambda_span)
81+
82+
self.processor.shutdown()

aws-opentelemetry-distro/tests/amazon/opentelemetry/distro/test_aws_opentelementry_configurator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ def test_customize_span_processors_lambda(self):
318318
os.environ.setdefault("OTEL_AWS_APPLICATION_SIGNALS_ENABLED", "True")
319319
os.environ.setdefault("AWS_LAMBDA_FUNCTION_NAME", "myLambdaFunc")
320320
_customize_span_processors(mock_tracer_provider, Resource.get_empty())
321-
self.assertEqual(mock_tracer_provider.add_span_processor.call_count, 2)
321+
self.assertEqual(mock_tracer_provider.add_span_processor.call_count, 3)
322322
first_processor: SpanProcessor = mock_tracer_provider.add_span_processor.call_args_list[0].args[0]
323323
self.assertIsInstance(first_processor, AttributePropagatingSpanProcessor)
324324
second_processor: SpanProcessor = mock_tracer_provider.add_span_processor.call_args_list[1].args[0]

0 commit comments

Comments
 (0)