Skip to content

Commit f84bffc

Browse files
[SVLS-5265] adding tests, and a temporary pin to a ddtrace branch
1 parent dd5d86b commit f84bffc

File tree

7 files changed

+263
-223
lines changed

7 files changed

+263
-223
lines changed

datadog_lambda/span_pointers.py

+18-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
from itertools import chain
2+
import logging
3+
from typing import List
4+
25
from ddtrace._trace.utils_botocore.span_pointers import _aws_s3_object_span_pointer_description
36
from ddtrace._trace._span_pointer import _SpanPointerDirection
47
from ddtrace._trace._span_pointer import _SpanPointerDescription
58
from datadog_lambda.trigger import EventTypes
6-
import logging
79

810

911
logger = logging.getLogger(__name__)
@@ -12,14 +14,21 @@
1214
def calculate_span_pointers(
1315
event_source,
1416
event,
15-
) -> list[_SpanPointerDescription]:
16-
if event_source.equals(EventTypes.S3):
17-
return _calculate_s3_span_pointers_for_event(event)
17+
) -> List[_SpanPointerDescription]:
18+
try:
19+
if event_source.equals(EventTypes.S3):
20+
return _calculate_s3_span_pointers_for_event(event)
21+
22+
except Exception as e:
23+
logger.warning(
24+
"failed to calculate span pointers for event: %s",
25+
str(e),
26+
)
1827

1928
return []
2029

2130

22-
def _calculate_s3_span_pointers_for_event(event) -> list[_SpanPointerDescription]:
31+
def _calculate_s3_span_pointers_for_event(event) -> List[_SpanPointerDescription]:
2332
# Example event:
2433
# https://docs.aws.amazon.com/lambda/latest/dg/with-s3.html
2534

@@ -31,7 +40,7 @@ def _calculate_s3_span_pointers_for_event(event) -> list[_SpanPointerDescription
3140
)
3241

3342

34-
def _calculate_s3_span_pointers_for_event_record(record) -> list[_SpanPointerDescription]:
43+
def _calculate_s3_span_pointers_for_event_record(record) -> List[_SpanPointerDescription]:
3544
# Event types:
3645
# https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-event-types-and-destinations.html
3746

@@ -43,7 +52,9 @@ def _calculate_s3_span_pointers_for_event_record(record) -> list[_SpanPointerDes
4352
return []
4453

4554

46-
def _calculate_s3_span_pointers_for_object_created_s3_information(s3_information) -> list[_SpanPointerDescription]:
55+
def _calculate_s3_span_pointers_for_object_created_s3_information(
56+
s3_information
57+
) -> List[_SpanPointerDescription]:
4758
try:
4859
bucket = s3_information["bucket"]["name"]
4960
key = s3_information["object"]["key"]

datadog_lambda/wrapper.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -308,13 +308,13 @@ def _before(self, event, context):
308308
event, context, event_source, self.decode_authorizer_context
309309
)
310310
self.span = create_function_execution_span(
311-
context,
312-
self.function_name,
313-
is_cold_start(),
314-
is_proactive_init(),
315-
trace_context_source,
316-
self.merge_xray_traces,
317-
self.trigger_tags,
311+
context=context,
312+
function_name=self.function_name,
313+
is_cold_start=is_cold_start(),
314+
is_proactive_init=is_proactive_init(),
315+
trace_context_source=trace_context_source,
316+
merge_xray_traces=self.merge_xray_traces,
317+
trigger_tags=self.trigger_tags,
318318
parent_span=self.inferred_span,
319319
span_pointers=calculate_span_pointers(event_source, event),
320320
)

poetry.lock

+70-198
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ classifiers = [
2727
python = ">=3.8.0,<4"
2828
datadog = ">=0.41.0,<1.0.0"
2929
wrapt = "^1.11.2"
30-
ddtrace = ">=2.10.0"
30+
ddtrace = { git = "https://github.com/DataDog/dd-trace-py.git", branch = "aleksandr.pasechnik/svls-5262-5-botocore-api-success-pointers" }
3131
ujson = ">=5.9.0"
3232
boto3 = { version = "^1.34.0", optional = true }
3333
requests = { version ="^2.22.0", optional = true }

tests/Dockerfile

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ FROM python:$python_version
33

44
ENV PYTHONDONTWRITEBYTECODE True
55

6+
ENV CARGO_ROOT=/root/.cargo
7+
ENV PATH=$CARGO_ROOT/bin:$PATH
8+
RUN curl https://sh.rustup.rs -sSf | \
9+
sh -s -- --default-toolchain stable -y
10+
611
RUN mkdir -p /test/datadog_lambda
712
WORKDIR /test
813

tests/test_span_pointers.py

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
from typing import List
2+
from typing import NamedTuple
3+
4+
from ddtrace._trace._span_pointer import _SpanPointerDirection
5+
from ddtrace._trace._span_pointer import _SpanPointerDescription
6+
from datadog_lambda.trigger import _EventSource
7+
from datadog_lambda.trigger import EventTypes
8+
from datadog_lambda.span_pointers import calculate_span_pointers
9+
import pytest
10+
11+
12+
class TestCalculateSpanPointers:
13+
class SpanPointersCase(NamedTuple):
14+
name: str
15+
event_source: _EventSource
16+
event: dict
17+
span_pointers: List[_SpanPointerDescription]
18+
19+
@pytest.mark.parametrize(
20+
"test_case",
21+
[
22+
SpanPointersCase(
23+
name="some unsupported event",
24+
event_source=_EventSource(EventTypes.UNKNOWN),
25+
event={},
26+
span_pointers=[],
27+
),
28+
SpanPointersCase(
29+
name="empty s3 event",
30+
event_source=_EventSource(EventTypes.S3),
31+
event={},
32+
span_pointers=[],
33+
),
34+
SpanPointersCase(
35+
name="sensible s3 event",
36+
event_source=_EventSource(EventTypes.S3),
37+
event={
38+
"Records": [
39+
{
40+
"eventName": "ObjectCreated:Put",
41+
"s3": {
42+
"bucket": {
43+
"name": "mybucket",
44+
},
45+
"object": {
46+
"key": "mykey",
47+
"eTag": "123abc",
48+
},
49+
},
50+
},
51+
],
52+
},
53+
span_pointers=[
54+
_SpanPointerDescription(
55+
pointer_kind="aws.s3.object",
56+
pointer_direction=_SpanPointerDirection.UPSTREAM,
57+
pointer_hash="8d49f5b0b742484159d4cd572bae1ce5",
58+
extra_attributes={},
59+
),
60+
],
61+
),
62+
SpanPointersCase(
63+
name="malformed s3 event",
64+
event_source=_EventSource(EventTypes.S3),
65+
event={
66+
"Records": [
67+
{
68+
"eventName": "ObjectCreated:Put",
69+
"s3": {
70+
"bucket": {
71+
"name": "mybucket",
72+
},
73+
"object": {
74+
"key": "mykey",
75+
# missing eTag
76+
},
77+
},
78+
},
79+
],
80+
},
81+
span_pointers=[],
82+
),
83+
],
84+
ids=lambda test_case: test_case.name,
85+
)
86+
def test_calculate_span_pointers(self, test_case: SpanPointersCase):
87+
assert calculate_span_pointers(
88+
test_case.event_source, test_case.event,
89+
) == test_case.span_pointers

tests/test_tracing.py

+73-10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212

1313
from ddtrace import tracer
1414
from ddtrace.context import Context
15+
from ddtrace._trace._span_pointer import _SpanPointer
16+
from ddtrace._trace._span_pointer import _SpanPointerDirection
17+
from ddtrace._trace._span_pointer import _SpanPointerDescription
1518

1619
from datadog_lambda.constants import (
1720
SamplingPriority,
@@ -746,20 +749,34 @@ class TestFunctionSpanTags(unittest.TestCase):
746749
def test_function(self):
747750
ctx = get_mock_context()
748751
span = create_function_execution_span(
749-
ctx, "", False, False, {"source": ""}, False, {}
752+
context=ctx,
753+
function_name="",
754+
is_cold_start=False,
755+
is_proactive_init=False,
756+
trace_context_source={"source": ""},
757+
merge_xray_traces=False,
758+
trigger_tags={},
759+
span_pointers=None,
750760
)
751761
self.assertEqual(span.get_tag("function_arn"), function_arn)
752762
self.assertEqual(span.get_tag("function_version"), "$LATEST")
753763
self.assertEqual(span.get_tag("resource_names"), "Function")
754764
self.assertEqual(span.get_tag("functionname"), "function")
765+
self.assertEqual(span._links, [])
755766

756767
def test_function_with_version(self):
757768
function_version = "1"
758769
ctx = get_mock_context(
759770
invoked_function_arn=function_arn + ":" + function_version
760771
)
761772
span = create_function_execution_span(
762-
ctx, "", False, False, {"source": ""}, False, {}
773+
context=ctx,
774+
function_name="",
775+
is_cold_start=False,
776+
is_proactive_init=False,
777+
trace_context_source={"source": ""},
778+
merge_xray_traces=False,
779+
trigger_tags={},
763780
)
764781
self.assertEqual(span.get_tag("function_arn"), function_arn)
765782
self.assertEqual(span.get_tag("function_version"), function_version)
@@ -770,7 +787,13 @@ def test_function_with_alias(self):
770787
function_alias = "alias"
771788
ctx = get_mock_context(invoked_function_arn=function_arn + ":" + function_alias)
772789
span = create_function_execution_span(
773-
ctx, "", False, False, {"source": ""}, False, {}
790+
context=ctx,
791+
function_name="",
792+
is_cold_start=False,
793+
is_proactive_init=False,
794+
trace_context_source={"source": ""},
795+
merge_xray_traces=False,
796+
trigger_tags={},
774797
)
775798
self.assertEqual(span.get_tag("function_arn"), function_arn)
776799
self.assertEqual(span.get_tag("function_version"), function_alias)
@@ -780,13 +803,13 @@ def test_function_with_alias(self):
780803
def test_function_with_trigger_tags(self):
781804
ctx = get_mock_context()
782805
span = create_function_execution_span(
783-
ctx,
784-
"",
785-
False,
786-
False,
787-
{"source": ""},
788-
False,
789-
{"function_trigger.event_source": "cloudwatch-logs"},
806+
context=ctx,
807+
function_name="",
808+
is_cold_start=False,
809+
is_proactive_init=False,
810+
trace_context_source={"source": ""},
811+
merge_xray_traces=False,
812+
trigger_tags={"function_trigger.event_source": "cloudwatch-logs"},
790813
)
791814
self.assertEqual(span.get_tag("function_arn"), function_arn)
792815
self.assertEqual(span.get_tag("resource_names"), "Function")
@@ -795,6 +818,46 @@ def test_function_with_trigger_tags(self):
795818
span.get_tag("function_trigger.event_source"), "cloudwatch-logs"
796819
)
797820

821+
def test_function_with_span_pointers(self):
822+
ctx = get_mock_context()
823+
span = create_function_execution_span(
824+
context=ctx,
825+
function_name="",
826+
is_cold_start=False,
827+
is_proactive_init=False,
828+
trace_context_source={"source": ""},
829+
merge_xray_traces=False,
830+
trigger_tags={},
831+
span_pointers=[
832+
_SpanPointerDescription(
833+
pointer_kind="some.kind",
834+
pointer_direction=_SpanPointerDirection.UPSTREAM,
835+
pointer_hash="some.hash",
836+
extra_attributes={},
837+
),
838+
_SpanPointerDescription(
839+
pointer_kind="other.kind",
840+
pointer_direction=_SpanPointerDirection.DOWNSTREAM,
841+
pointer_hash="other.hash",
842+
extra_attributes={"extra": "stuff"},
843+
),
844+
],
845+
)
846+
self.assertEqual(span._links, [
847+
_SpanPointer(
848+
pointer_kind="some.kind",
849+
pointer_direction=_SpanPointerDirection.UPSTREAM,
850+
pointer_hash="some.hash",
851+
extra_attributes={},
852+
),
853+
_SpanPointer(
854+
pointer_kind="other.kind",
855+
pointer_direction=_SpanPointerDirection.DOWNSTREAM,
856+
pointer_hash="other.hash",
857+
extra_attributes={"extra": "stuff"},
858+
),
859+
])
860+
798861

799862
class TestSetTraceRootSpan(unittest.TestCase):
800863
def setUp(self):

0 commit comments

Comments
 (0)