Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix AWS tests in POTel #3879

Merged
merged 13 commits into from
Jan 14, 2025
17 changes: 13 additions & 4 deletions sentry_sdk/integrations/aws_lambda.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from copy import deepcopy
from datetime import datetime, timedelta, timezone
from os import environ
from urllib.parse import urlencode

import sentry_sdk
from sentry_sdk.consts import OP
Expand Down Expand Up @@ -120,6 +121,9 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs):
configured_time = aws_context.get_remaining_time_in_millis()

with sentry_sdk.isolation_scope() as scope:
scope.set_transaction_name(
aws_context.function_name, source=TRANSACTION_SOURCE_COMPONENT
)
timeout_thread = None
with capture_internal_exceptions():
scope.clear_breadcrumbs()
Expand Down Expand Up @@ -333,7 +337,7 @@ def event_processor(sentry_event, hint, start_time=start_time):
request["url"] = _get_url(aws_event, aws_context)

if "queryStringParameters" in aws_event:
request["query_string"] = aws_event["queryStringParameters"]
request["query_string"] = urlencode(aws_event["queryStringParameters"])

if "headers" in aws_event:
request["headers"] = _filter_headers(aws_event["headers"])
Expand Down Expand Up @@ -373,7 +377,9 @@ def _get_url(aws_event, aws_context):
path = aws_event.get("path", None)

headers = aws_event.get("headers")
if headers is None:
# Some AWS Services (ie. EventBridge) set headers as a list
# or None, so we must ensure it is a dict
if not isinstance(headers, dict):
headers = {}

host = headers.get("Host", None)
Expand Down Expand Up @@ -478,7 +484,10 @@ def _prepopulate_attributes(aws_event, aws_context):

for prop, attr in EVENT_TO_ATTRIBUTES.items():
if aws_event.get(prop) is not None:
attributes[attr] = aws_event[prop]
if prop == "queryStringParameters":
attributes[attr] = urlencode(aws_event[prop])
else:
attributes[attr] = aws_event[prop]

for prop, attr in CONTEXT_TO_ATTRIBUTES.items():
if getattr(aws_context, prop, None) is not None:
Expand All @@ -487,7 +496,7 @@ def _prepopulate_attributes(aws_event, aws_context):
url = _get_url(aws_event, aws_context)
if url:
if aws_event.get("queryStringParameters"):
url += f"?{aws_event['queryStringParameters']}"
url += f"?{urlencode(aws_event['queryStringParameters'])}"
attributes["url.full"] = url

headers = {}
Expand Down
33 changes: 24 additions & 9 deletions tests/integrations/aws_lambda/test_aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ def truncate_data(data):

if data["contexts"].get("trace") is not None:
cleaned_data["contexts"]["trace"] = data["contexts"].get("trace")
if cleaned_data["contexts"]["trace"].get("data", {}) != {}:
cleaned_data["contexts"]["trace"]["data"] = {"removed": "by truncate_data()"}

if data.get("transaction") is not None:
cleaned_data["transaction"] = data.get("transaction")
Expand Down Expand Up @@ -287,7 +289,8 @@ def test_handler(event, context):
"X-Forwarded-Proto": "https"
},
"queryStringParameters": {
"bonkers": "true"
"bonkers": "true",
"wild": "false"
},
"pathParameters": null,
"stageVariables": null,
Expand All @@ -312,7 +315,7 @@ def test_handler(event, context):
"X-Forwarded-Proto": "https",
},
"method": "GET",
"query_string": {"bonkers": "true"},
"query_string": "bonkers=true&wild=false",
"url": "https://iwsz2c7uwi.execute-api.us-east-1.amazonaws.com/asd",
}

Expand Down Expand Up @@ -487,6 +490,15 @@ def test_handler(event, context):
),
(b"[]", False, 1),
],
ids=[
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't understand what this is for

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those are just some identifiers for the pytest output. so it is easier to see which ones are failing.

"int",
"float",
"string",
"bool",
"list",
"list_with_request_data",
"empty_list",
],
)
def test_non_dict_event(
run_lambda_function,
Expand Down Expand Up @@ -539,9 +551,7 @@ def test_handler(event, context):
"headers": {"Host": "x1.io", "X-Forwarded-Proto": "https"},
"method": "GET",
"url": "https://x1.io/1",
"query_string": {
"done": "f",
},
"query_string": "done=f",
}
else:
request_data = {"url": "awslambda:///{}".format(function_name)}
Expand Down Expand Up @@ -590,7 +600,7 @@ def test_traces_sampler_gets_correct_values_in_sampling_context(

import inspect

_, response = run_lambda_function(
function_code = (
LAMBDA_PRELUDE
+ dedent(inspect.getsource(StringContaining))
+ dedent(inspect.getsource(DictionaryContaining))
Expand Down Expand Up @@ -621,7 +631,7 @@ def test_handler(event, context):
{
"http.request.method": "GET",
"url.path": "/sit/stay/rollover",
"url.query": "repeat=again",
"url.query": "repeat=twice",
"url.full": "http://x.io/sit/stay/rollover?repeat=twice",
"network.protocol.name": "http",
"server.address": "x.io",
Expand All @@ -643,10 +653,15 @@ def test_handler(event, context):
traces_sampler=traces_sampler,
)
"""
),
b'{"httpMethod": "GET", "path": "/sit/stay/rollover", "query_string": {"repeat": "again"}, "headers": {"Host": "x.io", "X-Forwarded-Proto": "http", "Custom-Header": "Custom Value"}}',
)
)

payload = b'{"httpMethod": "GET", "path": "/sit/stay/rollover", "queryStringParameters": {"repeat": "twice"}, "headers": {"Host": "x.io", "X-Forwarded-Proto": "http", "Custom-Header": "Custom Value"}}'

_, response = run_lambda_function(
code=function_code,
payload=payload,
)
assert response["Payload"]["AssertionError raised"] is False


Expand Down
Loading