Skip to content

Commit 16aaed1

Browse files
untitakersentry-bot
and
sentry-bot
authored
ref: Stop using Relay for event schema validation (getsentry#783)
Co-authored-by: sentry-bot <[email protected]>
1 parent 92e4c54 commit 16aaed1

26 files changed

+88
-160
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "checkouts/data-schemas"]
2+
path = checkouts/data-schemas
3+
url = https://github.com/getsentry/sentry-data-schemas

.travis.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ install:
5757
- pip install tox
5858
- pip install codecov
5959
- make install-zeus-cli
60-
- bash scripts/download-relay.sh
6160

6261
script:
6362
- coverage erase

checkouts/data-schemas

Submodule data-schemas added at 36c6664

scripts/download-relay.sh

Lines changed: 0 additions & 32 deletions
This file was deleted.

sentry_sdk/integrations/spark/spark_worker.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,15 @@ def process_event(event, hint):
8282
return event
8383

8484
event.setdefault("tags", {}).setdefault(
85-
"stageId", task_context.stageId()
85+
"stageId", str(task_context.stageId())
86+
)
87+
event["tags"].setdefault("partitionId", str(task_context.partitionId()))
88+
event["tags"].setdefault(
89+
"attemptNumber", str(task_context.attemptNumber())
90+
)
91+
event["tags"].setdefault(
92+
"taskAttemptId", str(task_context.taskAttemptId())
8693
)
87-
event["tags"].setdefault("partitionId", task_context.partitionId())
88-
event["tags"].setdefault("attemptNumber", task_context.attemptNumber())
89-
event["tags"].setdefault("taskAttemptId", task_context.taskAttemptId())
9094

9195
if task_context._localProperties:
9296
if "sentry_app_name" in task_context._localProperties:

sentry_sdk/scope.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,9 @@ def _drop(event, cause, ty):
312312
event["level"] = self._level
313313

314314
if event.get("type") != "transaction":
315-
event.setdefault("breadcrumbs", []).extend(self._breadcrumbs)
315+
event.setdefault("breadcrumbs", {}).setdefault("values", []).extend(
316+
self._breadcrumbs
317+
)
316318

317319
if event.get("user") is None and self._user is not None:
318320
event["user"] = self._user

sentry_sdk/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ def single_exception_from_error_tuple(
503503
errno = None
504504

505505
if errno is not None:
506-
mechanism = mechanism or {}
506+
mechanism = mechanism or {"type": "generic"}
507507
mechanism.setdefault("meta", {}).setdefault("errno", {}).setdefault(
508508
"number", errno
509509
)

test-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ tox==3.7.0
44
Werkzeug==0.15.5
55
pytest-localserver==0.5.0
66
pytest-cov==2.8.1
7+
jsonschema==3.2.0
78

89
gevent
910
eventlet

tests/conftest.py

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import os
2-
import subprocess
32
import json
4-
import uuid
53

64
import pytest
5+
import jsonschema
76

87
import gevent
98
import eventlet
@@ -16,11 +15,14 @@
1615

1716
from tests import _warning_recorder, _warning_recorder_mgr
1817

19-
SENTRY_RELAY = "./relay"
2018

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

21+
if not os.path.isfile(SENTRY_EVENT_SCHEMA):
22+
SENTRY_EVENT_SCHEMA = None
23+
else:
24+
with open(SENTRY_EVENT_SCHEMA) as f:
25+
SENTRY_EVENT_SCHEMA = json.load(f)
2426

2527
try:
2628
import pytest_benchmark
@@ -118,7 +120,7 @@ def _capture_internal_warnings():
118120

119121

120122
@pytest.fixture
121-
def monkeypatch_test_transport(monkeypatch, relay_normalize):
123+
def monkeypatch_test_transport(monkeypatch, validate_event_schema):
122124
def check_event(event):
123125
def check_string_keys(map):
124126
for key, value in iteritems(map):
@@ -128,54 +130,19 @@ def check_string_keys(map):
128130

129131
with capture_internal_exceptions():
130132
check_string_keys(event)
131-
relay_normalize(event)
133+
validate_event_schema(event)
132134

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

136138
return inner
137139

138140

139-
def _no_errors_in_relay_response(obj):
140-
"""Assert that relay didn't throw any errors when processing the
141-
event."""
142-
143-
def inner(obj):
144-
if not isinstance(obj, dict):
145-
return
146-
147-
assert "err" not in obj
148-
149-
for value in obj.values():
150-
inner(value)
151-
152-
try:
153-
inner(obj.get("_meta"))
154-
inner(obj.get(""))
155-
except AssertionError:
156-
raise AssertionError(obj)
157-
158-
159141
@pytest.fixture
160-
def relay_normalize(tmpdir):
142+
def validate_event_schema(tmpdir):
161143
def inner(event):
162-
if not SENTRY_RELAY:
163-
return
164-
165-
# Disable subprocess integration
166-
with sentry_sdk.Hub(None):
167-
# not dealing with the subprocess API right now
168-
file = tmpdir.join("event-{}".format(uuid.uuid4().hex))
169-
file.write(json.dumps(dict(event)))
170-
with file.open() as f:
171-
output = json.loads(
172-
subprocess.check_output(
173-
[SENTRY_RELAY, "process-event"], stdin=f
174-
).decode("utf-8")
175-
)
176-
_no_errors_in_relay_response(output)
177-
output.pop("_meta", None)
178-
return output
144+
if SENTRY_EVENT_SCHEMA:
145+
jsonschema.validate(instance=event, schema=SENTRY_EVENT_SCHEMA)
179146

180147
return inner
181148

tests/integrations/django/test_basic.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
except ImportError:
1717
from django.core.urlresolvers import reverse
1818

19-
from sentry_sdk import capture_message, capture_exception
19+
from sentry_sdk import capture_message, capture_exception, configure_scope
2020
from sentry_sdk.integrations.django import DjangoIntegration
2121

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

183183
from django.db import connection
184184

185-
sentry_init(
186-
integrations=[DjangoIntegration()],
187-
send_default_pii=True,
188-
_experiments={"record_sql_params": True},
189-
)
190-
191185
events = capture_events()
192186

193187
sql = connection.cursor()
194188

189+
with configure_scope() as scope:
190+
scope.clear_breadcrumbs()
191+
195192
with pytest.raises(OperationalError):
196193
# table doesn't even exist
197194
sql.execute("""SELECT count(*) FROM people_person WHERE foo = %s""", [123])
@@ -201,7 +198,7 @@ def test_sql_queries(sentry_init, capture_events, with_integration):
201198
(event,) = events
202199

203200
if with_integration:
204-
crumb = event["breadcrumbs"][-1]
201+
crumb = event["breadcrumbs"]["values"][-1]
205202

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

226223
events = capture_events()
224+
with configure_scope() as scope:
225+
scope.clear_breadcrumbs()
226+
227227
with pytest.raises(ProgrammingError):
228228
sql.execute(
229229
"""SELECT count(*) FROM people_person WHERE foo = %(my_foo)s""",
@@ -233,7 +233,7 @@ def test_sql_dict_query_params(sentry_init, capture_events):
233233
capture_message("HI")
234234
(event,) = events
235235

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

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

269+
with configure_scope() as scope:
270+
scope.clear_breadcrumbs()
271+
269272
events = capture_events()
273+
270274
with pytest.raises(ProgrammingError):
271275
sql.execute(query(psycopg2.sql), {"my_param": 10})
272276

273277
capture_message("HI")
274278

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

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

298302
events = capture_events()
303+
with configure_scope() as scope:
304+
scope.clear_breadcrumbs()
305+
299306
with pytest.raises(DataError):
300307
names = ["foo", "bar"]
301308
identifiers = [psycopg2.sql.Identifier(name) for name in names]
@@ -313,10 +320,10 @@ def test_sql_psycopg2_placeholders(sentry_init, capture_events):
313320
capture_message("HI")
314321

315322
(event,) = events
316-
for crumb in event["breadcrumbs"]:
323+
for crumb in event["breadcrumbs"]["values"]:
317324
del crumb["timestamp"]
318325

319-
assert event["breadcrumbs"][-2:] == [
326+
assert event["breadcrumbs"]["values"][-2:] == [
320327
{
321328
"category": "query",
322329
"data": {"db.paramstyle": "format"},

tests/integrations/flask/test_flask.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ def test_flask_session_tracking(sentry_init, capture_envelopes, app):
255255
@app.route("/")
256256
def index():
257257
with configure_scope() as scope:
258-
scope.set_user({"ip_address": "1.2.3.4", "id": 42})
258+
scope.set_user({"ip_address": "1.2.3.4", "id": "42"})
259259
try:
260260
raise ValueError("stuff")
261261
except Exception:

tests/integrations/logging/test_logging.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def test_logging_works_with_many_loggers(sentry_init, capture_events, logger):
2626
assert event["level"] == "fatal"
2727
assert not event["logentry"]["params"]
2828
assert event["logentry"]["message"] == "LOL"
29-
assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"])
29+
assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"]["values"])
3030

3131

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

4141
assert event["level"] == "fatal"
42-
assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"])
43-
assert not any(crumb["message"] == "LOL" for crumb in event["breadcrumbs"])
42+
assert any(crumb["message"] == "bread" for crumb in event["breadcrumbs"]["values"])
43+
assert not any(
44+
crumb["message"] == "LOL" for crumb in event["breadcrumbs"]["values"]
45+
)
4446
assert "threads" not in event
4547

4648

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

6365

tests/integrations/pyramid/test_pyramid.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def errors(request):
8080
assert isinstance(error, ZeroDivisionError)
8181

8282
(event,) = events
83-
(breadcrumb,) = event["breadcrumbs"]
83+
(breadcrumb,) = event["breadcrumbs"]["values"]
8484
assert breadcrumb["message"] == "hi2"
8585
assert event["exception"]["values"][0]["mechanism"]["type"] == "pyramid"
8686

tests/integrations/redis/test_redis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def test_basic(sentry_init, capture_events):
1414
capture_message("hi")
1515

1616
(event,) = events
17-
(crumb,) = event["breadcrumbs"]
17+
(crumb,) = event["breadcrumbs"]["values"]
1818

1919
assert crumb == {
2020
"category": "redis",

tests/integrations/rediscluster/test_rediscluster.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def test_rediscluster_basic(rediscluster_cls, sentry_init, capture_events):
2626
capture_message("hi")
2727

2828
(event,) = events
29-
(crumb,) = event["breadcrumbs"]
29+
(crumb,) = event["breadcrumbs"]["values"]
3030

3131
assert crumb == {
3232
"category": "redis",

tests/integrations/requests/test_requests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def test_crumb_capture(sentry_init, capture_events):
1414
capture_message("Testing!")
1515

1616
(event,) = events
17-
(crumb,) = event["breadcrumbs"]
17+
(crumb,) = event["breadcrumbs"]["values"]
1818
assert crumb["type"] == "http"
1919
assert crumb["category"] == "httplib"
2020
assert crumb["data"] == {

tests/integrations/spark/test_spark.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ def mock_main():
235235
assert events[0]["exception"]["values"][0]["type"] == "ZeroDivisionError"
236236

237237
assert events[0]["tags"] == {
238-
"stageId": 0,
239-
"attemptNumber": 1,
240-
"partitionId": 2,
241-
"taskAttemptId": 3,
238+
"stageId": "0",
239+
"attemptNumber": "1",
240+
"partitionId": "2",
241+
"taskAttemptId": "3",
242242
}

tests/integrations/sqlalchemy/test_sqlalchemy.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ class Address(Base):
4949

5050
(event,) = events
5151

52-
for crumb in event["breadcrumbs"]:
52+
for crumb in event["breadcrumbs"]["values"]:
5353
del crumb["timestamp"]
5454

55-
assert event["breadcrumbs"][-2:] == [
55+
assert event["breadcrumbs"]["values"][-2:] == [
5656
{
5757
"category": "query",
5858
"data": {"db.params": ["Bob"], "db.paramstyle": "qmark"},

0 commit comments

Comments
 (0)