Skip to content

Commit c8e8012

Browse files
committed
Add Serverless Framework Support Revision 3 (#127)
* Mimic Segments now perform no-op on segment-only methods. * Added comments to address this contract. * Unit tests to ensure segment-only methods don't add data to the mimic segment. Serialization methods are also tested to ensure this.
1 parent 88bf381 commit c8e8012

File tree

3 files changed

+52
-14
lines changed

3 files changed

+52
-14
lines changed

aws_xray_sdk/core/models/mimic_segment.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ class MimicSegment(Segment):
1818
as a node on the service graph. For all purposes, the MimicSegment can be interacted as if it's
1919
a real segment, meaning that all methods that exist only in a Segment but not a subsegment
2020
is available to be used.
21+
22+
The following methods are no-ops and will not be sent to the service:
23+
set_rule_name, set_service, and set_user
2124
"""
2225

2326
def __init__(self, facade_segment, original_segment):
@@ -28,10 +31,19 @@ def __init__(self, facade_segment, original_segment):
2831
traceid=facade_segment.trace_id, parent_id=facade_segment.id,
2932
sampled=facade_segment.sampled)
3033

34+
def set_rule_name(self, rule_name):
35+
pass
36+
37+
def set_service(self, service_info):
38+
pass
39+
40+
def set_user(self, user):
41+
pass
42+
3143
def __getstate__(self):
3244
"""
33-
Used during serialization. We mark the subsegment properties to let the dataplane know
34-
that we want the mimic segment to be transformed as a subsegment.
45+
Used during serialization. We mark the mimic segment as a subsegment to
46+
let the X-Ray service know to create this mimic segment as a subsegment.
3547
"""
3648
properties = super(MimicSegment, self).__getstate__()
3749
properties['type'] = 'subsegment'

aws_xray_sdk/core/serverless_lambda_context.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class ServerlessLambdaContext(LambdaContext):
1818
creates a Segment masked as a Subsegment known as a MimicSegment underneath
1919
the Lambda-generated Facade Segment. This ensures that middleware->recorder's
2020
consequent calls to "put_segment()" will not throw exceptions but instead create
21-
subsegments underneath the lambda-generated segment. This context also
21+
subsegments underneath the lambda-generated Facade Segment. This context also
2222
ensures that FacadeSegments exist through underlying calls to _refresh_context().
2323
"""
2424
def __init__(self, context_missing='RUNTIME_ERROR'):
@@ -31,7 +31,6 @@ def put_segment(self, segment):
3131
"""
3232
Convert the segment into a mimic segment and append it to FacadeSegment's subsegment list.
3333
:param Segment segment:
34-
:return:
3534
"""
3635
# When putting a segment, convert it to a mimic segment and make it a child of the Facade Segment.
3736
parent_facade_segment = self.__get_facade_entity() # type: FacadeSegment
@@ -102,8 +101,9 @@ def get_trace_entity(self):
102101

103102
def set_trace_entity(self, trace_entity):
104103
"""
105-
Store the input trace_entity to local context. It will overwrite all
106-
existing ones if there is any.
104+
Stores the input trace_entity to local context. It will overwrite all
105+
existing ones if there is any. If the entity passed in is a segment,
106+
it will automatically be converted to a mimic segment.
107107
"""
108108
if type(trace_entity) == Segment:
109109
# Convert to a mimic segment.

tests/test_mimic_segment.py

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ def test_facade_segment_properties():
7171

7272
def test_segment_methods_on_mimic():
7373
# Test to make sure that segment methods exist and function for the Mimic Segment
74+
# And ensure that the methods (other than get/set origin_trace_header) don't modify
75+
# the segment.
7476
mimic_segment = MimicSegment(facade_segment=facade_segment, original_segment=original_segment) # type: MimicSegment
7577
assert not getattr(mimic_segment, "service", None)
7678
assert not getattr(mimic_segment, "user", None)
@@ -82,20 +84,44 @@ def test_segment_methods_on_mimic():
8284
assert getattr(original_segment, "ref_counter", None)
8385
assert getattr(original_segment, "_subsegments_counter", None)
8486

85-
mimic_segment.set_service("SomeService")
86-
original_segment.set_service("SomeService")
87-
assert original_segment.service == original_segment.service
88-
8987
assert original_segment.get_origin_trace_header() == mimic_segment.get_origin_trace_header()
9088
mimic_segment.save_origin_trace_header("someheader")
9189
original_segment.save_origin_trace_header("someheader")
9290
assert original_segment.get_origin_trace_header() == mimic_segment.get_origin_trace_header()
9391

9492
# No exception is thrown
9593
test_dict = {"akey": "avalue"}
96-
original_segment.set_aws(test_dict)
97-
original_segment.set_rule_name(test_dict)
94+
test_rule_name = {"arule": "name"}
95+
original_segment.set_aws(test_dict.copy())
96+
original_segment.set_rule_name(test_rule_name.copy())
9897
original_segment.set_user("SomeUser")
99-
mimic_segment.set_aws(test_dict)
100-
mimic_segment.set_rule_name(test_dict)
98+
original_segment.set_service("SomeService")
99+
mimic_segment.set_aws(test_dict.copy())
100+
mimic_segment.set_rule_name(test_rule_name.copy())
101101
mimic_segment.set_user("SomeUser")
102+
mimic_segment.set_service("SomeService")
103+
104+
# Original segment should contain these properties
105+
# but not the mimic segment.
106+
assert getattr(original_segment, "service", None)
107+
assert getattr(original_segment, "user", None)
108+
assert 'xray' in getattr(original_segment, "aws", None)
109+
assert 'sampling_rule_name' in getattr(original_segment, "aws", None)['xray']
110+
111+
assert not getattr(mimic_segment, "service", None)
112+
assert not getattr(mimic_segment, "user", None)
113+
# Originally set by rule_name, but no-op so nothing is set.
114+
assert 'xray' not in getattr(mimic_segment, "aws", None)
115+
116+
# Ensure serialization also doesn't have those properties in mimic but do in original
117+
original_segment_serialized = original_segment.__getstate__()
118+
mimic_segment_serialized = mimic_segment.__getstate__()
119+
120+
assert 'service' in original_segment_serialized
121+
assert 'user' in original_segment_serialized
122+
assert 'xray' in original_segment_serialized['aws']
123+
assert 'sampling_rule_name' in original_segment_serialized['aws']['xray']
124+
125+
assert 'service' not in mimic_segment_serialized
126+
assert 'user' not in mimic_segment_serialized
127+
assert 'xray' not in mimic_segment_serialized['aws']

0 commit comments

Comments
 (0)