1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
from unittest import mock
import boto3
import pytest
import sentry_sdk
from sentry_sdk.integrations.boto3 import Boto3Integration
from tests.conftest import ApproxDict
from tests.integrations.boto3 import read_fixture
from tests.integrations.boto3.aws_mock import MockResponse
session = boto3.Session(
aws_access_key_id="-",
aws_secret_access_key="-",
)
def test_basic(sentry_init, capture_events):
sentry_init(traces_sample_rate=1.0, integrations=[Boto3Integration()])
events = capture_events()
s3 = session.resource("s3")
with sentry_sdk.start_transaction() as transaction, MockResponse(
s3.meta.client, 200, {}, read_fixture("s3_list.xml")
):
bucket = s3.Bucket("bucket")
items = [obj for obj in bucket.objects.all()]
assert len(items) == 2
assert items[0].key == "foo.txt"
assert items[1].key == "bar.txt"
transaction.finish()
(event,) = events
assert event["type"] == "transaction"
assert len(event["spans"]) == 1
(span,) = event["spans"]
assert span["op"] == "http.client"
assert span["description"] == "aws.s3.ListObjects"
def test_streaming(sentry_init, capture_events):
sentry_init(traces_sample_rate=1.0, integrations=[Boto3Integration()])
events = capture_events()
s3 = session.resource("s3")
with sentry_sdk.start_transaction() as transaction, MockResponse(
s3.meta.client, 200, {}, b"hello"
):
obj = s3.Bucket("bucket").Object("foo.pdf")
body = obj.get()["Body"]
assert body.read(1) == b"h"
assert body.read(2) == b"el"
assert body.read(3) == b"lo"
assert body.read(1) == b""
transaction.finish()
(event,) = events
assert event["type"] == "transaction"
assert len(event["spans"]) == 2
span1 = event["spans"][0]
assert span1["op"] == "http.client"
assert span1["description"] == "aws.s3.GetObject"
assert span1["data"] == ApproxDict(
{
"http.method": "GET",
"aws.request.url": "https://bucket.s3.amazonaws.com/foo.pdf",
"http.fragment": "",
"http.query": "",
}
)
span2 = event["spans"][1]
assert span2["op"] == "http.client.stream"
assert span2["description"] == "aws.s3.GetObject"
assert span2["parent_span_id"] == span1["span_id"]
def test_streaming_close(sentry_init, capture_events):
sentry_init(traces_sample_rate=1.0, integrations=[Boto3Integration()])
events = capture_events()
s3 = session.resource("s3")
with sentry_sdk.start_transaction() as transaction, MockResponse(
s3.meta.client, 200, {}, b"hello"
):
obj = s3.Bucket("bucket").Object("foo.pdf")
body = obj.get()["Body"]
assert body.read(1) == b"h"
body.close() # close partially-read stream
transaction.finish()
(event,) = events
assert event["type"] == "transaction"
assert len(event["spans"]) == 2
span1 = event["spans"][0]
assert span1["op"] == "http.client"
span2 = event["spans"][1]
assert span2["op"] == "http.client.stream"
@pytest.mark.tests_internal_exceptions
def test_omit_url_data_if_parsing_fails(sentry_init, capture_events):
sentry_init(traces_sample_rate=1.0, integrations=[Boto3Integration()])
events = capture_events()
s3 = session.resource("s3")
with mock.patch(
"sentry_sdk.integrations.boto3.parse_url",
side_effect=ValueError,
):
with sentry_sdk.start_transaction() as transaction, MockResponse(
s3.meta.client, 200, {}, read_fixture("s3_list.xml")
):
bucket = s3.Bucket("bucket")
items = [obj for obj in bucket.objects.all()]
assert len(items) == 2
assert items[0].key == "foo.txt"
assert items[1].key == "bar.txt"
transaction.finish()
(event,) = events
assert event["spans"][0]["data"] == ApproxDict(
{
"http.method": "GET",
# no url data
}
)
assert "aws.request.url" not in event["spans"][0]["data"]
assert "http.fragment" not in event["spans"][0]["data"]
assert "http.query" not in event["spans"][0]["data"]
def test_span_origin(sentry_init, capture_events):
sentry_init(traces_sample_rate=1.0, integrations=[Boto3Integration()])
events = capture_events()
s3 = session.resource("s3")
with sentry_sdk.start_transaction(), MockResponse(
s3.meta.client, 200, {}, read_fixture("s3_list.xml")
):
bucket = s3.Bucket("bucket")
_ = [obj for obj in bucket.objects.all()]
(event,) = events
assert event["contexts"]["trace"]["origin"] == "manual"
assert event["spans"][0]["origin"] == "auto.http.boto3"
|