Skip to content

Commit

Permalink
Merge branch 'master' into antonpirker/missing-stack-trames
Browse files Browse the repository at this point in the history
  • Loading branch information
antonpirker authored Nov 4, 2024
2 parents 31d059c + 5e2d2cf commit 8d2490b
Show file tree
Hide file tree
Showing 25 changed files with 145 additions and 35 deletions.
10 changes: 6 additions & 4 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ on:
- master
- sentry-sdk-2.0
pull_request:
# The branches below must be a subset of the branches above
branches:
- master
- sentry-sdk-2.0
schedule:
- cron: '18 18 * * 3'

# Cancel in progress workflows on pull_requests.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

permissions:
contents: read

Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/enforce-license-compliance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ on:
- release/*
- sentry-sdk-2.0
pull_request:
branches:
- master
- main
- sentry-sdk-2.0

# Cancel in progress workflows on pull_requests.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}

jobs:
enforce-license-compliance:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-integrations-ai.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ jobs:
files: .junitxml
verbose: true
check_required_tests:
name: All AI tests passed
name: All pinned AI tests passed
needs: test-ai-pinned
# Always run this, even if a dependent job failed
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-integrations-aws-lambda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ jobs:
files: .junitxml
verbose: true
check_required_tests:
name: All AWS Lambda tests passed
name: All pinned AWS Lambda tests passed
needs: test-aws_lambda-pinned
# Always run this, even if a dependent job failed
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-integrations-cloud-computing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ jobs:
files: .junitxml
verbose: true
check_required_tests:
name: All Cloud Computing tests passed
name: All pinned Cloud Computing tests passed
needs: test-cloud_computing-pinned
# Always run this, even if a dependent job failed
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-integrations-common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ jobs:
files: .junitxml
verbose: true
check_required_tests:
name: All Common tests passed
name: All pinned Common tests passed
needs: test-common-pinned
# Always run this, even if a dependent job failed
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-integrations-data-processing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ jobs:
files: .junitxml
verbose: true
check_required_tests:
name: All Data Processing tests passed
name: All pinned Data Processing tests passed
needs: test-data_processing-pinned
# Always run this, even if a dependent job failed
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-integrations-databases.yml
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ jobs:
files: .junitxml
verbose: true
check_required_tests:
name: All Databases tests passed
name: All pinned Databases tests passed
needs: test-databases-pinned
# Always run this, even if a dependent job failed
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-integrations-graphql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ jobs:
files: .junitxml
verbose: true
check_required_tests:
name: All GraphQL tests passed
name: All pinned GraphQL tests passed
needs: test-graphql-pinned
# Always run this, even if a dependent job failed
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-integrations-miscellaneous.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ jobs:
files: .junitxml
verbose: true
check_required_tests:
name: All Miscellaneous tests passed
name: All pinned Miscellaneous tests passed
needs: test-miscellaneous-pinned
# Always run this, even if a dependent job failed
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-integrations-networking.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ jobs:
files: .junitxml
verbose: true
check_required_tests:
name: All Networking tests passed
name: All pinned Networking tests passed
needs: test-networking-pinned
# Always run this, even if a dependent job failed
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-integrations-web-frameworks-1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ jobs:
files: .junitxml
verbose: true
check_required_tests:
name: All Web Frameworks 1 tests passed
name: All pinned Web Frameworks 1 tests passed
needs: test-web_frameworks_1-pinned
# Always run this, even if a dependent job failed
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-integrations-web-frameworks-2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ jobs:
files: .junitxml
verbose: true
check_required_tests:
name: All Web Frameworks 2 tests passed
name: All pinned Web Frameworks 2 tests passed
needs: test-web_frameworks_2-pinned
# Always run this, even if a dependent job failed
if: always()
Expand Down
2 changes: 1 addition & 1 deletion requirements-devenv.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-r requirements-linting.txt
-r requirements-testing.txt
mockupdb # required by `pymongo` tests that are enabled by `pymongo` from linter requirements
pytest<7.0.0 # https://github.com/pytest-dev/pytest/issues/9621; see tox.ini
pytest
pytest-asyncio
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
check_required_tests:
name: All {{ group }} tests passed
name: All pinned {{ group }} tests passed
{% if "pinned" in categories %}
needs: test-{{ group | replace(" ", "_") | lower }}-pinned
{% endif %}
Expand Down
7 changes: 6 additions & 1 deletion sentry_sdk/integrations/starlette.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,12 @@

try:
# Optional dependency of Starlette to parse form data.
import multipart # type: ignore
try:
# python-multipart 0.0.13 and later
import python_multipart as multipart # type: ignore
except ImportError:
# python-multipart 0.0.12 and earlier
import multipart # type: ignore
except ImportError:
multipart = None

Expand Down
10 changes: 6 additions & 4 deletions sentry_sdk/integrations/stdlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,13 @@ def getresponse(self, *args, **kwargs):
if span is None:
return real_getresponse(self, *args, **kwargs)

rv = real_getresponse(self, *args, **kwargs)
try:
rv = real_getresponse(self, *args, **kwargs)

span.set_http_status(int(rv.status))
span.set_data("reason", rv.reason)
span.finish()
span.set_http_status(int(rv.status))
span.set_data("reason", rv.reason)
finally:
span.finish()

return rv

Expand Down
2 changes: 1 addition & 1 deletion sentry_sdk/profiler/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def get_frame_name(frame):
and co_varnames[0] == "self"
and "self" in frame.f_locals
):
for cls in frame.f_locals["self"].__class__.__mro__:
for cls in type(frame.f_locals["self"]).__mro__:
if name in cls.__dict__:
return "{}.{}".format(cls.__name__, name)
except (AttributeError, ValueError):
Expand Down
1 change: 1 addition & 0 deletions sentry_sdk/transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@ def _request(

try:
import httpcore
import h2 # type: ignore # noqa: F401
except ImportError:
# Sorry, no Http2Transport for you
class Http2Transport(HttpTransport):
Expand Down
8 changes: 8 additions & 0 deletions tests/integrations/celery/test_celery.py
Original file line number Diff line number Diff line change
Expand Up @@ -831,3 +831,11 @@ def test_send_task_wrapped(
assert span["description"] == "very_creative_task_name"
assert span["op"] == "queue.submit.celery"
assert span["trace_id"] == kwargs["headers"]["sentry-trace"].split("-")[0]


@pytest.mark.skip(reason="placeholder so that forked test does not come last")
def test_placeholder():
"""Forked tests must not come last in the module.
See https://github.com/pytest-dev/pytest-forked/issues/67#issuecomment-1964718720.
"""
pass
48 changes: 48 additions & 0 deletions tests/integrations/django/test_basic.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import inspect
import json
import os
import re
import sys
import pytest
from functools import partial
from unittest.mock import patch
Expand All @@ -12,6 +14,7 @@
from django.core.management import execute_from_command_line
from django.db.utils import OperationalError, ProgrammingError, DataError
from django.http.request import RawPostDataException
from django.utils.functional import SimpleLazyObject

try:
from django.urls import reverse
Expand All @@ -29,6 +32,7 @@
)
from sentry_sdk.integrations.django.signals_handlers import _get_receiver_name
from sentry_sdk.integrations.executing import ExecutingIntegration
from sentry_sdk.profiler.utils import get_frame_name
from sentry_sdk.tracing import Span
from tests.conftest import unpack_werkzeug_response
from tests.integrations.django.myapp.wsgi import application
Expand Down Expand Up @@ -1295,3 +1299,47 @@ def test_ensures_no_spotlight_middleware_when_no_spotlight(
added = frozenset(settings.MIDDLEWARE) ^ original_middleware

assert "sentry_sdk.spotlight.SpotlightMiddleware" not in added


def test_get_frame_name_when_in_lazy_object():
allowed_to_init = False

class SimpleLazyObjectWrapper(SimpleLazyObject):
def unproxied_method(self):
"""
For testing purposes. We inject a method on the SimpleLazyObject
class so if python is executing this method, we should get
this class instead of the wrapped class and avoid evaluating
the wrapped object too early.
"""
return inspect.currentframe()

class GetFrame:
def __init__(self):
assert allowed_to_init, "GetFrame not permitted to initialize yet"

def proxied_method(self):
"""
For testing purposes. We add an proxied method on the instance
class so if python is executing this method, we should get
this class instead of the wrapper class.
"""
return inspect.currentframe()

instance = SimpleLazyObjectWrapper(lambda: GetFrame())

assert get_frame_name(instance.unproxied_method()) == (
"SimpleLazyObjectWrapper.unproxied_method"
if sys.version_info < (3, 11)
else "test_get_frame_name_when_in_lazy_object.<locals>.SimpleLazyObjectWrapper.unproxied_method"
)

# Now that we're about to access an instance method on the wrapped class,
# we should permit initializing it
allowed_to_init = True

assert get_frame_name(instance.proxied_method()) == (
"GetFrame.proxied_method"
if sys.version_info < (3, 11)
else "test_get_frame_name_when_in_lazy_object.<locals>.GetFrame.proxied_method"
)
5 changes: 5 additions & 0 deletions tests/integrations/rq/test_rq.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,11 @@ def test_traces_sampler_gets_correct_values_in_sampling_context(
@pytest.mark.skipif(
parse_version(rq.__version__) < (1, 5), reason="At least rq-1.5 required"
)
@pytest.mark.skipif(
parse_version(rq.__version__) >= (2,),
reason="Test broke in RQ 2.0. Investigate and fix. "
"See https://github.com/getsentry/sentry-python/issues/3707.",
)
def test_job_with_retries(sentry_init, capture_events):
sentry_init(integrations=[RqIntegration()])
events = capture_events()
Expand Down
33 changes: 33 additions & 0 deletions tests/integrations/stdlib/test_httplib.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import random
from http.client import HTTPConnection, HTTPSConnection
from socket import SocketIO
from urllib.request import urlopen
from unittest import mock

Expand Down Expand Up @@ -342,3 +343,35 @@ def test_span_origin(sentry_init, capture_events):

assert event["spans"][0]["op"] == "http.client"
assert event["spans"][0]["origin"] == "auto.http.stdlib.httplib"


def test_http_timeout(monkeypatch, sentry_init, capture_envelopes):
mock_readinto = mock.Mock(side_effect=TimeoutError)
monkeypatch.setattr(SocketIO, "readinto", mock_readinto)

sentry_init(traces_sample_rate=1.0)

envelopes = capture_envelopes()

with start_transaction(op="op", name="name"):
try:
conn = HTTPSConnection("www.squirrelchasers.com")
conn.request("GET", "/top-chasers")
conn.getresponse()
except Exception:
pass

items = [
item
for envelope in envelopes
for item in envelope.items
if item.type == "transaction"
]
assert len(items) == 1

transaction = items[0].payload.json
assert len(transaction["spans"]) == 1

span = transaction["spans"][0]
assert span["op"] == "http.client"
assert span["description"] == "GET https://www.squirrelchasers.com/top-chasers"
4 changes: 2 additions & 2 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ def _normalize_distribution_name(name):
), # UTC time
(
"2021-01-01T00:00:00.000000",
datetime(2021, 1, 1, tzinfo=timezone.utc),
), # No TZ -- assume UTC
datetime(2021, 1, 1).astimezone(timezone.utc),
), # No TZ -- assume local but convert to UTC
(
"2021-01-01T00:00:00Z",
datetime(2021, 1, 1, tzinfo=timezone.utc),
Expand Down
Loading

0 comments on commit 8d2490b

Please sign in to comment.