2929# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3030import os
3131
32- import mock
3332import pytest
3433
34+ import elasticapm
3535from elasticapm .conf import constants
36- from elasticapm .instrumentation .packages .botocore import BotocoreInstrumentation
36+ from elasticapm .instrumentation .packages .botocore import SQS_MAX_ATTRIBUTES
3737from elasticapm .utils .compat import urlparse
38+ from tests .utils import assert_any_record_contains
3839
3940boto3 = pytest .importorskip ("boto3" )
4041
@@ -79,9 +80,7 @@ def dynamodb():
7980@pytest .fixture ()
8081def sqs_client_and_queue ():
8182 sqs = boto3 .client ("sqs" , endpoint_url = LOCALSTACK_ENDPOINT )
82- response = sqs .create_queue (
83- QueueName = "myqueue" , Attributes = {"DelaySeconds" : "60" , "MessageRetentionPeriod" : "86400" }
84- )
83+ response = sqs .create_queue (QueueName = "myqueue" , Attributes = {"MessageRetentionPeriod" : "86400" })
8584 queue_url = response ["QueueUrl" ]
8685 yield sqs , queue_url
8786 sqs .delete_queue (QueueUrl = queue_url )
@@ -213,7 +212,7 @@ def test_sqs_send(instrument, elasticapm_client, sqs_client_and_queue):
213212 },
214213 MessageBody = ("bar" ),
215214 )
216- elasticapm_client .end_transaction ("test" , "test" )
215+ transaction = elasticapm_client .end_transaction ("test" , "test" )
217216 span = elasticapm_client .events [constants .SPAN ][0 ]
218217 assert span ["name" ] == "SQS SEND to myqueue"
219218 assert span ["type" ] == "messaging"
@@ -224,6 +223,19 @@ def test_sqs_send(instrument, elasticapm_client, sqs_client_and_queue):
224223 assert span ["context" ]["destination" ]["service" ]["resource" ] == "sqs/myqueue"
225224 assert span ["context" ]["destination" ]["service" ]["type" ] == "messaging"
226225
226+ messages = sqs .receive_message (
227+ QueueUrl = queue_url ,
228+ AttributeNames = ["All" ],
229+ MessageAttributeNames = [
230+ "All" ,
231+ ],
232+ )
233+ message = messages ["Messages" ][0 ]
234+ assert "traceparent" in message ["MessageAttributes" ]
235+ traceparent = message ["MessageAttributes" ]["traceparent" ]["StringValue" ]
236+ assert transaction .trace_parent .trace_id in traceparent
237+ assert span ["id" ] in traceparent
238+
227239
228240def test_sqs_send_batch (instrument , elasticapm_client , sqs_client_and_queue ):
229241 sqs , queue_url = sqs_client_and_queue
@@ -234,12 +246,11 @@ def test_sqs_send_batch(instrument, elasticapm_client, sqs_client_and_queue):
234246 {
235247 "Id" : "foo" ,
236248 "MessageBody" : "foo" ,
237- "DelaySeconds" : 123 ,
238249 "MessageAttributes" : {"string" : {"StringValue" : "foo" , "DataType" : "String" }},
239250 },
240251 ],
241252 )
242- elasticapm_client .end_transaction ("test" , "test" )
253+ transaction = elasticapm_client .end_transaction ("test" , "test" )
243254 span = elasticapm_client .events [constants .SPAN ][0 ]
244255 assert span ["name" ] == "SQS SEND_BATCH to myqueue"
245256 assert span ["type" ] == "messaging"
@@ -249,6 +260,68 @@ def test_sqs_send_batch(instrument, elasticapm_client, sqs_client_and_queue):
249260 assert span ["context" ]["destination" ]["service" ]["name" ] == "sqs"
250261 assert span ["context" ]["destination" ]["service" ]["resource" ] == "sqs/myqueue"
251262 assert span ["context" ]["destination" ]["service" ]["type" ] == "messaging"
263+ messages = sqs .receive_message (
264+ QueueUrl = queue_url ,
265+ AttributeNames = ["All" ],
266+ MessageAttributeNames = [
267+ "All" ,
268+ ],
269+ )
270+ message = messages ["Messages" ][0 ]
271+ assert "traceparent" in message ["MessageAttributes" ]
272+ traceparent = message ["MessageAttributes" ]["traceparent" ]["StringValue" ]
273+ assert transaction .trace_parent .trace_id in traceparent
274+ assert span ["id" ] in traceparent
275+
276+
277+ def test_sqs_send_too_many_attributes_for_disttracing (instrument , elasticapm_client , sqs_client_and_queue , caplog ):
278+ sqs , queue_url = sqs_client_and_queue
279+ attributes = {str (i ): {"DataType" : "String" , "StringValue" : str (i )} for i in range (SQS_MAX_ATTRIBUTES )}
280+ elasticapm_client .begin_transaction ("test" )
281+ with caplog .at_level ("INFO" ):
282+ sqs .send_message (
283+ QueueUrl = queue_url ,
284+ MessageAttributes = attributes ,
285+ MessageBody = ("bar" ),
286+ )
287+ elasticapm_client .end_transaction ("test" , "test" )
288+ messages = sqs .receive_message (
289+ QueueUrl = queue_url ,
290+ AttributeNames = ["All" ],
291+ MessageAttributeNames = [
292+ "All" ,
293+ ],
294+ )
295+ message = messages ["Messages" ][0 ]
296+ assert "traceparent" not in message ["MessageAttributes" ]
297+ assert_any_record_contains (caplog .records , "Not adding disttracing headers" )
298+
299+
300+ def test_sqs_send_disttracing_dropped_span (instrument , elasticapm_client , sqs_client_and_queue ):
301+ sqs , queue_url = sqs_client_and_queue
302+ elasticapm_client .begin_transaction ("test" )
303+ with elasticapm .capture_span ("test" , leaf = True ):
304+ sqs .send_message (
305+ QueueUrl = queue_url ,
306+ MessageAttributes = {
307+ "Title" : {"DataType" : "String" , "StringValue" : "foo" },
308+ },
309+ MessageBody = ("bar" ),
310+ )
311+ transaction = elasticapm_client .end_transaction ("test" , "test" )
312+ assert len (elasticapm_client .events [constants .SPAN ]) == 1
313+ messages = sqs .receive_message (
314+ QueueUrl = queue_url ,
315+ AttributeNames = ["All" ],
316+ MessageAttributeNames = [
317+ "All" ,
318+ ],
319+ )
320+ message = messages ["Messages" ][0 ]
321+ assert "traceparent" in message ["MessageAttributes" ]
322+ traceparent = message ["MessageAttributes" ]["traceparent" ]["StringValue" ]
323+ assert transaction .trace_parent .trace_id in traceparent
324+ assert transaction .id in traceparent # due to DroppedSpan, transaction.id is used instead of span.id
252325
253326
254327def test_sqs_receive (instrument , elasticapm_client , sqs_client_and_queue ):
0 commit comments