Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "checkouts/data-schemas"]
path = checkouts/data-schemas
url = https://github.com/getsentry/sentry-data-schemas
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ install:
- pip install tox
- pip install codecov
- make install-zeus-cli
- bash scripts/download-relay.sh

script:
- coverage erase
Expand Down
1 change: 1 addition & 0 deletions checkouts/data-schemas
Submodule data-schemas added at 36c666
32 changes: 0 additions & 32 deletions scripts/download-relay.sh

This file was deleted.

12 changes: 8 additions & 4 deletions sentry_sdk/integrations/spark/spark_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,15 @@ def process_event(event, hint):
return event

event.setdefault("tags", {}).setdefault(
"stageId", task_context.stageId()
"stageId", str(task_context.stageId())
)
event["tags"].setdefault("partitionId", str(task_context.partitionId()))
event["tags"].setdefault(
"attemptNumber", str(task_context.attemptNumber())
)
event["tags"].setdefault(
"taskAttemptId", str(task_context.taskAttemptId())
)
event["tags"].setdefault("partitionId", task_context.partitionId())
event["tags"].setdefault("attemptNumber", task_context.attemptNumber())
event["tags"].setdefault("taskAttemptId", task_context.taskAttemptId())

if task_context._localProperties:
if "sentry_app_name" in task_context._localProperties:
Expand Down
4 changes: 3 additions & 1 deletion sentry_sdk/scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,9 @@ def _drop(event, cause, ty):
event["level"] = self._level

if event.get("type") != "transaction":
event.setdefault("breadcrumbs", []).extend(self._breadcrumbs)
event.setdefault("breadcrumbs", {}).setdefault("values", []).extend(
self._breadcrumbs
)

if event.get("user") is None and self._user is not None:
event["user"] = self._user
Expand Down
2 changes: 1 addition & 1 deletion sentry_sdk/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ def single_exception_from_error_tuple(
errno = None

if errno is not None:
mechanism = mechanism or {}
mechanism = mechanism or {"type": "generic"}
mechanism.setdefault("meta", {}).setdefault("errno", {}).setdefault(
"number", errno
)
Expand Down
1 change: 1 addition & 0 deletions test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ tox==3.7.0
Werkzeug==0.15.5
pytest-localserver==0.5.0
pytest-cov==2.8.1
jsonschema==3.2.0

gevent
eventlet
Expand Down
57 changes: 12 additions & 45 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import os
import subprocess
import json
import uuid

import pytest
import jsonschema

import gevent
import eventlet
Expand All @@ -16,11 +15,14 @@

from tests import _warning_recorder, _warning_recorder_mgr

SENTRY_RELAY = "./relay"

if not os.path.isfile(SENTRY_RELAY):
SENTRY_RELAY = None
SENTRY_EVENT_SCHEMA = "./checkouts/data-schemas/relay/event.schema.json"

if not os.path.isfile(SENTRY_EVENT_SCHEMA):
SENTRY_EVENT_SCHEMA = None
else:
with open(SENTRY_EVENT_SCHEMA) as f:
SENTRY_EVENT_SCHEMA = json.load(f)

try:
import pytest_benchmark
Expand Down Expand Up @@ -118,7 +120,7 @@ def _capture_internal_warnings():


@pytest.fixture
def monkeypatch_test_transport(monkeypatch, relay_normalize):
def monkeypatch_test_transport(monkeypatch, validate_event_schema):
def check_event(event):
def check_string_keys(map):
for key, value in iteritems(map):
Expand All @@ -128,54 +130,19 @@ def check_string_keys(map):

with capture_internal_exceptions():
check_string_keys(event)
relay_normalize(event)
validate_event_schema(event)

def inner(client):
monkeypatch.setattr(client, "transport", TestTransport(check_event))

return inner


def _no_errors_in_relay_response(obj):
"""Assert that relay didn't throw any errors when processing the
event."""

def inner(obj):
if not isinstance(obj, dict):
return

assert "err" not in obj

for value in obj.values():
inner(value)

try:
inner(obj.get("_meta"))
inner(obj.get(""))
except AssertionError:
raise AssertionError(obj)


@pytest.fixture
def relay_normalize(tmpdir):
def validate_event_schema(tmpdir):
def inner(event):
if not SENTRY_RELAY:
return

# Disable subprocess integration
with sentry_sdk.Hub(None):
# not dealing with the subprocess API right now
file = tmpdir.join("event-{}".format(uuid.uuid4().hex))
file.write(json.dumps(dict(event)))
with file.open() as f:
output = json.loads(
subprocess.check_output(
[SENTRY_RELAY, "process-event"], stdin=f
).decode("utf-8")
)
_no_errors_in_relay_response(output)
output.pop("_meta", None)
return output
if SENTRY_EVENT_SCHEMA:
jsonschema.validate(instance=event, schema=SENTRY_EVENT_SCHEMA)

return inner

Expand Down
31 changes: 19 additions & 12 deletions tests/integrations/django/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
except ImportError:
from django.core.urlresolvers import reverse

from sentry_sdk import capture_message, capture_exception
from sentry_sdk import capture_message, capture_exception, configure_scope
from sentry_sdk.integrations.django import DjangoIntegration

from tests.integrations.django.myapp.wsgi import application
Expand Down Expand Up @@ -182,16 +182,13 @@ def test_sql_queries(sentry_init, capture_events, with_integration):

from django.db import connection

sentry_init(
integrations=[DjangoIntegration()],
send_default_pii=True,
_experiments={"record_sql_params": True},
)

events = capture_events()

sql = connection.cursor()

with configure_scope() as scope:
scope.clear_breadcrumbs()

with pytest.raises(OperationalError):
# table doesn't even exist
sql.execute("""SELECT count(*) FROM people_person WHERE foo = %s""", [123])
Expand All @@ -201,7 +198,7 @@ def test_sql_queries(sentry_init, capture_events, with_integration):
(event,) = events

if with_integration:
crumb = event["breadcrumbs"][-1]
crumb = event["breadcrumbs"]["values"][-1]

assert crumb["message"] == "SELECT count(*) FROM people_person WHERE foo = %s"
assert crumb["data"]["db.params"] == [123]
Expand All @@ -224,6 +221,9 @@ def test_sql_dict_query_params(sentry_init, capture_events):
sql = connections["postgres"].cursor()

events = capture_events()
with configure_scope() as scope:
scope.clear_breadcrumbs()

with pytest.raises(ProgrammingError):
sql.execute(
"""SELECT count(*) FROM people_person WHERE foo = %(my_foo)s""",
Expand All @@ -233,7 +233,7 @@ def test_sql_dict_query_params(sentry_init, capture_events):
capture_message("HI")
(event,) = events

crumb = event["breadcrumbs"][-1]
crumb = event["breadcrumbs"]["values"][-1]
assert crumb["message"] == (
"SELECT count(*) FROM people_person WHERE foo = %(my_foo)s"
)
Expand Down Expand Up @@ -266,14 +266,18 @@ def test_sql_psycopg2_string_composition(sentry_init, capture_events, query):

sql = connections["postgres"].cursor()

with configure_scope() as scope:
scope.clear_breadcrumbs()

events = capture_events()

with pytest.raises(ProgrammingError):
sql.execute(query(psycopg2.sql), {"my_param": 10})

capture_message("HI")

(event,) = events
crumb = event["breadcrumbs"][-1]
crumb = event["breadcrumbs"]["values"][-1]
assert crumb["message"] == ('SELECT %(my_param)s FROM "foobar"')
assert crumb["data"]["db.params"] == {"my_param": 10}

Expand All @@ -296,6 +300,9 @@ def test_sql_psycopg2_placeholders(sentry_init, capture_events):
sql = connections["postgres"].cursor()

events = capture_events()
with configure_scope() as scope:
scope.clear_breadcrumbs()

with pytest.raises(DataError):
names = ["foo", "bar"]
identifiers = [psycopg2.sql.Identifier(name) for name in names]
Expand All @@ -313,10 +320,10 @@ def test_sql_psycopg2_placeholders(sentry_init, capture_events):
capture_message("HI")

(event,) = events
for crumb in event["breadcrumbs"]:
for crumb in event["breadcrumbs"]["values"]:
del crumb["timestamp"]

assert event["breadcrumbs"][-2:] == [
assert event["breadcrumbs"]["values"][-2:] == [
{
"category": "query",
"data": {"db.paramstyle": "format"},
Expand Down
2 changes: 1 addition & 1 deletion tests/integrations/flask/test_flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ def test_flask_session_tracking(sentry_init, capture_envelopes, app):
@app.route("/")
def index():
with configure_scope() as scope:
scope.set_user({"ip_address": "1.2.3.4", "id": 42})
scope.set_user({"ip_address": "1.2.3.4", "id": "42"})
try:
raise ValueError("stuff")
except Exception:
Expand Down
10 changes: 6 additions & 4 deletions tests/integrations/logging/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def test_logging_works_with_many_loggers(sentry_init, capture_events, logger):
assert event["level"] == "fatal"
assert not event["logentry"]["params"]
assert event["logentry"]["message"] == "LOL"
assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"])
assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"]["values"])


@pytest.mark.parametrize("integrations", [None, [], [LoggingIntegration()]])
Expand All @@ -39,8 +39,10 @@ def test_logging_defaults(integrations, sentry_init, capture_events):
(event,) = events

assert event["level"] == "fatal"
assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"])
assert not any(crumb["message"] == "LOL" for crumb in event["breadcrumbs"])
assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"]["values"])
assert not any(
crumb["message"] == "LOL" for crumb in event["breadcrumbs"]["values"]
)
assert "threads" not in event


Expand All @@ -57,7 +59,7 @@ def test_logging_extra_data(sentry_init, capture_events):
assert event["extra"] == {"bar": 69}
assert any(
crumb["message"] == "bread" and crumb["data"] == {"foo": 42}
for crumb in event["breadcrumbs"]
for crumb in event["breadcrumbs"]["values"]
)


Expand Down
2 changes: 1 addition & 1 deletion tests/integrations/pyramid/test_pyramid.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def errors(request):
assert isinstance(error, ZeroDivisionError)

(event,) = events
(breadcrumb,) = event["breadcrumbs"]
(breadcrumb,) = event["breadcrumbs"]["values"]
assert breadcrumb["message"] == "hi2"
assert event["exception"]["values"][0]["mechanism"]["type"] == "pyramid"

Expand Down
2 changes: 1 addition & 1 deletion tests/integrations/redis/test_redis.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def test_basic(sentry_init, capture_events):
capture_message("hi")

(event,) = events
(crumb,) = event["breadcrumbs"]
(crumb,) = event["breadcrumbs"]["values"]

assert crumb == {
"category": "redis",
Expand Down
2 changes: 1 addition & 1 deletion tests/integrations/rediscluster/test_rediscluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def test_rediscluster_basic(rediscluster_cls, sentry_init, capture_events):
capture_message("hi")

(event,) = events
(crumb,) = event["breadcrumbs"]
(crumb,) = event["breadcrumbs"]["values"]

assert crumb == {
"category": "redis",
Expand Down
2 changes: 1 addition & 1 deletion tests/integrations/requests/test_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def test_crumb_capture(sentry_init, capture_events):
capture_message("Testing!")

(event,) = events
(crumb,) = event["breadcrumbs"]
(crumb,) = event["breadcrumbs"]["values"]
assert crumb["type"] == "http"
assert crumb["category"] == "httplib"
assert crumb["data"] == {
Expand Down
8 changes: 4 additions & 4 deletions tests/integrations/spark/test_spark.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,8 @@ def mock_main():
assert events[0]["exception"]["values"][0]["type"] == "ZeroDivisionError"

assert events[0]["tags"] == {
"stageId": 0,
"attemptNumber": 1,
"partitionId": 2,
"taskAttemptId": 3,
"stageId": "0",
"attemptNumber": "1",
"partitionId": "2",
"taskAttemptId": "3",
}
4 changes: 2 additions & 2 deletions tests/integrations/sqlalchemy/test_sqlalchemy.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ class Address(Base):

(event,) = events

for crumb in event["breadcrumbs"]:
for crumb in event["breadcrumbs"]["values"]:
del crumb["timestamp"]

assert event["breadcrumbs"][-2:] == [
assert event["breadcrumbs"]["values"][-2:] == [
{
"category": "query",
"data": {"db.params": ["Bob"], "db.paramstyle": "qmark"},
Expand Down
Loading