2727 _HANDLER ,
2828 _X_AMZN_TRACE_ID ,
2929 OTEL_INSTRUMENTATION_AWS_LAMBDA_FLUSH_TIMEOUT ,
30- OTEL_LAMBDA_DISABLE_AWS_CONTEXT_PROPAGATION ,
3130 AwsLambdaInstrumentor ,
3231)
3332from opentelemetry .propagate import get_global_textmap
@@ -138,7 +137,9 @@ def test_active_tracing(self):
138137 self .assertEqual (len (spans ), 1 )
139138 span = spans [0 ]
140139 self .assertEqual (span .name , os .environ [_HANDLER ])
141- self .assertEqual (span .get_span_context ().trace_id , MOCK_XRAY_TRACE_ID )
140+ self .assertNotEqual (
141+ span .get_span_context ().trace_id , MOCK_XRAY_TRACE_ID
142+ )
142143 self .assertEqual (span .kind , SpanKind .SERVER )
143144 self .assertSpanHasAttributes (
144145 span ,
@@ -149,11 +150,7 @@ def test_active_tracing(self):
149150 )
150151
151152 parent_context = span .parent
152- self .assertEqual (
153- parent_context .trace_id , span .get_span_context ().trace_id
154- )
155- self .assertEqual (parent_context .span_id , MOCK_XRAY_PARENT_SPAN_ID )
156- self .assertTrue (parent_context .is_remote )
153+ self .assertEqual (None , parent_context )
157154
158155 test_env_patch .stop ()
159156
@@ -165,11 +162,8 @@ class TestCase:
165162 context : Dict
166163 expected_traceid : int
167164 expected_parentid : int
168- xray_traceid : str
169165 expected_state_value : str = None
170166 expected_trace_state_len : int = 0
171- disable_aws_context_propagation : bool = False
172- disable_aws_context_propagation_envvar : str = ""
173167
174168 def custom_event_context_extractor (lambda_event ):
175169 return get_global_textmap ().extract (lambda_event ["foo" ]["headers" ])
@@ -188,42 +182,9 @@ def custom_event_context_extractor(lambda_event):
188182 expected_parentid = MOCK_W3C_PARENT_SPAN_ID ,
189183 expected_trace_state_len = 3 ,
190184 expected_state_value = MOCK_W3C_TRACE_STATE_VALUE ,
191- xray_traceid = MOCK_XRAY_TRACE_CONTEXT_NOT_SAMPLED ,
192- ),
193- TestCase (
194- name = "custom_extractor_not_sampled_xray" ,
195- custom_extractor = custom_event_context_extractor ,
196- context = {
197- "foo" : {
198- "headers" : {
199- TraceContextTextMapPropagator ._TRACEPARENT_HEADER_NAME : MOCK_W3C_TRACE_CONTEXT_SAMPLED ,
200- TraceContextTextMapPropagator ._TRACESTATE_HEADER_NAME : f"{ MOCK_W3C_TRACE_STATE_KEY } ={ MOCK_W3C_TRACE_STATE_VALUE } ,foo=1,bar=2" ,
201- }
202- }
203- },
204- expected_traceid = MOCK_W3C_TRACE_ID ,
205- expected_parentid = MOCK_W3C_PARENT_SPAN_ID ,
206- expected_trace_state_len = 3 ,
207- expected_state_value = MOCK_W3C_TRACE_STATE_VALUE ,
208- xray_traceid = MOCK_XRAY_TRACE_CONTEXT_NOT_SAMPLED ,
209- ),
210- TestCase (
211- name = "custom_extractor_sampled_xray" ,
212- custom_extractor = custom_event_context_extractor ,
213- context = {
214- "foo" : {
215- "headers" : {
216- TraceContextTextMapPropagator ._TRACEPARENT_HEADER_NAME : MOCK_W3C_TRACE_CONTEXT_SAMPLED ,
217- TraceContextTextMapPropagator ._TRACESTATE_HEADER_NAME : f"{ MOCK_W3C_TRACE_STATE_KEY } ={ MOCK_W3C_TRACE_STATE_VALUE } ,foo=1,bar=2" ,
218- }
219- }
220- },
221- expected_traceid = MOCK_XRAY_TRACE_ID ,
222- expected_parentid = MOCK_XRAY_PARENT_SPAN_ID ,
223- xray_traceid = MOCK_XRAY_TRACE_CONTEXT_SAMPLED ,
224185 ),
225186 TestCase (
226- name = "custom_extractor_sampled_xray_disable_aws_propagation " ,
187+ name = "custom_extractor " ,
227188 custom_extractor = custom_event_context_extractor ,
228189 context = {
229190 "foo" : {
@@ -233,47 +194,24 @@ def custom_event_context_extractor(lambda_event):
233194 }
234195 }
235196 },
236- disable_aws_context_propagation = True ,
237197 expected_traceid = MOCK_W3C_TRACE_ID ,
238198 expected_parentid = MOCK_W3C_PARENT_SPAN_ID ,
239199 expected_trace_state_len = 3 ,
240200 expected_state_value = MOCK_W3C_TRACE_STATE_VALUE ,
241- xray_traceid = MOCK_XRAY_TRACE_CONTEXT_SAMPLED ,
242- ),
243- TestCase (
244- name = "no_custom_extractor_xray_disable_aws_propagation_via_env_var" ,
245- custom_extractor = None ,
246- context = {
247- "headers" : {
248- TraceContextTextMapPropagator ._TRACEPARENT_HEADER_NAME : MOCK_W3C_TRACE_CONTEXT_SAMPLED ,
249- TraceContextTextMapPropagator ._TRACESTATE_HEADER_NAME : f"{ MOCK_W3C_TRACE_STATE_KEY } ={ MOCK_W3C_TRACE_STATE_VALUE } ,foo=1,bar=2" ,
250- }
251- },
252- disable_aws_context_propagation = False ,
253- disable_aws_context_propagation_envvar = "true" ,
254- expected_traceid = MOCK_W3C_TRACE_ID ,
255- expected_parentid = MOCK_W3C_PARENT_SPAN_ID ,
256- expected_trace_state_len = 3 ,
257- expected_state_value = MOCK_W3C_TRACE_STATE_VALUE ,
258- xray_traceid = MOCK_XRAY_TRACE_CONTEXT_SAMPLED ,
259201 ),
260202 ]
261203 for test in tests :
262204 test_env_patch = mock .patch .dict (
263205 "os.environ" ,
264206 {
265207 ** os .environ ,
266- # NOT Active Tracing
267- _X_AMZN_TRACE_ID : test .xray_traceid ,
268- OTEL_LAMBDA_DISABLE_AWS_CONTEXT_PROPAGATION : test .disable_aws_context_propagation_envvar ,
269208 # NOT using the X-Ray Propagator
270209 OTEL_PROPAGATORS : "tracecontext" ,
271210 },
272211 )
273212 test_env_patch .start ()
274213 AwsLambdaInstrumentor ().instrument (
275- event_context_extractor = test .custom_extractor ,
276- disable_aws_context_propagation = test .disable_aws_context_propagation ,
214+ event_context_extractor = test .custom_extractor
277215 )
278216 mock_execute_lambda (test .context )
279217 spans = self .memory_exporter .get_finished_spans ()
@@ -301,6 +239,65 @@ def custom_event_context_extractor(lambda_event):
301239 AwsLambdaInstrumentor ().uninstrument ()
302240 test_env_patch .stop ()
303241
242+ def test_links_from_lambda_event (self ):
243+ @dataclass
244+ class TestCase :
245+ name : str
246+ context : Dict
247+ expected_link_trace_id : int
248+ expected_link_attributes : dict
249+ xray_traceid : str
250+
251+ tests = [
252+ TestCase (
253+ name = "valid_xray_trace" ,
254+ context = {},
255+ expected_link_trace_id = MOCK_XRAY_TRACE_ID ,
256+ expected_link_attributes = {"source" : "x-ray-env" },
257+ xray_traceid = MOCK_XRAY_TRACE_CONTEXT_SAMPLED ,
258+ ),
259+ TestCase (
260+ name = "invalid_xray_trace" ,
261+ context = {},
262+ expected_link_trace_id = None ,
263+ expected_link_attributes = {},
264+ xray_traceid = "0" ,
265+ ),
266+ ]
267+ for test in tests :
268+ test_env_patch = mock .patch .dict (
269+ "os.environ" ,
270+ {
271+ ** os .environ ,
272+ # NOT Active Tracing
273+ _X_AMZN_TRACE_ID : test .xray_traceid ,
274+ # NOT using the X-Ray Propagator
275+ OTEL_PROPAGATORS : "tracecontext" ,
276+ },
277+ )
278+ test_env_patch .start ()
279+ AwsLambdaInstrumentor ().instrument ()
280+ mock_execute_lambda (test .context )
281+ spans = self .memory_exporter .get_finished_spans ()
282+ assert spans
283+ self .assertEqual (len (spans ), 1 )
284+ span = spans [0 ]
285+
286+ if test .expected_link_trace_id is None :
287+ self .assertEqual (0 , len (span .links ))
288+ else :
289+ link = span .links [0 ]
290+ self .assertEqual (
291+ link .context .trace_id , test .expected_link_trace_id
292+ )
293+ self .assertEqual (
294+ link .attributes , test .expected_link_attributes
295+ )
296+
297+ self .memory_exporter .clear ()
298+ AwsLambdaInstrumentor ().uninstrument ()
299+ test_env_patch .stop ()
300+
304301 def test_lambda_no_error_with_invalid_flush_timeout (self ):
305302 test_env_patch = mock .patch .dict (
306303 "os.environ" ,
0 commit comments