def test_complex_limits_without_data_category(httpserver, capsys, caplog, response_code): client = Client( dict(dsn="http://foobar@{}/123".format( httpserver.url[len("http://"):]))) httpserver.serve_content( "hm", response_code, headers={"X-Sentry-Rate-Limit": "4711::organization"}, ) client.capture_event({"type": "transaction"}) client.flush() assert len(httpserver.requests) == 1 del httpserver.requests[:] assert set(client.transport._disabled_until) == set([None]) client.transport.capture_event({"type": "transaction"}) client.transport.capture_event({"type": "transaction"}) client.capture_event({"type": "event"}) client.flush() assert len(httpserver.requests) == 0
def test_transport_option(monkeypatch): dsn = "https://[email protected]/123" dsn2 = "https://[email protected]/124" assert str(Client(dsn=dsn).dsn) == dsn assert Client().dsn is None monkeypatch.setenv("SENTRY_DSN", dsn) transport = Transport({"dsn": dsn2}) assert text_type(transport.parsed_dsn) == dsn2 assert str(Client(transport=transport).dsn) == dsn
def test_transport_infinite_loop(httpserver, request): httpserver.serve_content("ok", 200) client = Client( "http://foobar@{}/123".format(httpserver.url[len("http://") :]), debug=True, # Make sure we cannot create events from our own logging integrations=[LoggingIntegration(event_level=logging.DEBUG)], ) with Hub(client): capture_message("hi") client.flush() assert len(httpserver.requests) == 1
def test_traceparent_header_wsgi(self): # Assert that posting something to store will not create another # (transaction) event under any circumstances. # # We use Werkzeug's test client because Django's test client bypasses a # lot of request handling code that we want to test implicitly (such as # all our WSGI middlewares and the entire Django instrumentation by # sentry-sdk). # # XXX(markus): Ideally methods such as `_postWithHeader` would always # call the WSGI application => swap out Django's test client with e.g. # Werkzeug's. client = WerkzeugClient(application) calls = [] def new_disable_transaction_events(): with configure_scope() as scope: assert scope.span.sampled assert scope.span.transaction disable_transaction_events() assert not scope.span.sampled calls.append(1) events = [] auth = get_auth_header("_postWithWerkzeug/0.0.0", self.projectkey.public_key, self.projectkey.secret_key, "7") with mock.patch("sentry.web.api.disable_transaction_events", new_disable_transaction_events): with self.tasks(): with Hub( Client( transport=events.append, integrations=[ CeleryIntegration(), DjangoIntegration() ], )): app_iter, status, headers = client.post( reverse("sentry-api-store"), data=b'{"message": "hello"}', headers={ "x-sentry-auth": auth, "sentry-trace": "1", "content-type": "application/octet-stream", }, environ_base={"REMOTE_ADDR": "127.0.0.1"}, ) body = "".join(app_iter) assert status == "200 OK", body assert set( (e.get("type"), e.get("transaction")) for e in events) == {("transaction", "rule_processor_apply")} assert calls == [1]
def test_basic(self, request): requests = [] def queue_event(method, url, body, headers): requests.append((method, url, body, headers)) request.side_effect = queue_event hub = Hub( Client( "http://%s:%s@localhost:8000/%s" % (self.pk.public_key, self.pk.secret_key, self.pk.project_id), default_integrations=False, )) hub.capture_message("foo") hub.client.close() for _request in requests: self.send_event(*_request) assert request.call_count == 1 assert Group.objects.count() == 1 group = Group.objects.get() assert group.data["title"] == "foo"
def test_proxy_httpsselect_bothenv_http(monkeypatch): monkeypatch.setenv("HTTP_PROXY", "http://localhost/123") monkeypatch.setenv("HTTPS_PROXY", "https://localhost/123") client = Client("http://[email protected]/123", http_proxy=None, https_proxy=None) assert client.transport._pool.proxy.scheme == "http"
def test_proxy_both_select_https(monkeypatch): client = Client( "https://[email protected]/123", https_proxy="https://localhost/123", http_proxy="http://localhost/123", ) assert client.transport._pool.proxy.scheme == "https"
def test_basic(self, request): requests = [] def queue_event(method, url, body, headers): requests.append((method, url, body, headers)) request.side_effect = queue_event hub = Hub(Client( 'http://%s:%s@localhost:8000/%s' % (self.pk.public_key, self.pk.secret_key, self.pk.project_id), default_integrations=False )) hub.capture_message('foo') hub.client.close() for _request in requests: self.send_event(*_request) assert request.call_count is 1 assert Group.objects.count() == 1 group = Group.objects.get() assert group.event_set.count() == 1 instance = group.event_set.get() assert instance.data['logentry']['formatted'] == 'foo'
def test_attach_stacktrace_disabled(): events = [] hub = Hub(Client(attach_stacktrace=False, transport=events.append)) hub.capture_message("HI") event, = events assert "threads" not in event
def test_transport_works(httpserver, request, capsys): httpserver.serve_content("ok", 200) client = Client("http://foobar@{}/123".format( httpserver.url[len("http://"):])) Hub.current.bind_client(client) request.addfinalizer(lambda: Hub.current.bind_client(None)) add_breadcrumb(level="info", message="i like bread", timestamp=datetime.now()) capture_message("löl") client.close() out, err = capsys.readouterr() assert not err and not out assert httpserver.requests
def test_exception_captured_by_sentry(self): events = [] with Hub(Client(transport=events.append)): # This endpoint should return 500 as it internally raises an exception response = self.app.get('/tests/error') assert response.status_code == 500 assert len(events) == 1 assert events[0]['exception']['values'][0]['type'] == 'ZeroDivisionError'
def test_transport_works(httpserver, request, capsys, caplog, debug): httpserver.serve_content("ok", 200) caplog.set_level(logging.DEBUG) client = Client( "http://foobar@{}/123".format(httpserver.url[len("http://") :]), debug=debug ) Hub.current.bind_client(client) request.addfinalizer(lambda: Hub.current.bind_client(None)) add_breadcrumb(level="info", message="i like bread", timestamp=datetime.now()) capture_message("löl") client.close() out, err = capsys.readouterr() assert not err and not out assert httpserver.requests assert any("Sending info event" in record.msg for record in caplog.records) == debug
def test_traceparent_header_wsgi(self): # Assert that posting something to store will not create another # (transaction) event under any circumstances. # # We use Werkzeug's test client because Django's test client bypasses a # lot of request handling code that we want to test implicitly (such as # all our WSGI middlewares and the entire Django instrumentation by # sentry-sdk). # # XXX(markus): Ideally methods such as `_postWithHeader` would always # call the WSGI application => swap out Django's test client with e.g. # Werkzeug's. client = WerkzeugClient(application) calls = [] def new_disable_transaction_events(): with configure_scope() as scope: assert scope.span.sampled assert scope.span.transaction disable_transaction_events() assert not scope.span.sampled calls.append(1) events = [] auth = get_auth_header('_postWithWerkzeug/0.0.0', self.projectkey.public_key, self.projectkey.secret_key, '7') with mock.patch('sentry.web.api.disable_transaction_events', new_disable_transaction_events): with self.tasks(): with Hub( Client(transport=events.append, integrations=[ CeleryIntegration(), DjangoIntegration() ])): app_iter, status, headers = client.post( reverse('sentry-api-store'), data=b'{"message": "hello"}', headers={ 'x-sentry-auth': auth, 'sentry-trace': '1', 'content-type': 'application/octet-stream', }, environ_base={'REMOTE_ADDR': '127.0.0.1'}) body = ''.join(app_iter) assert status == '200 OK', body assert not events assert calls == [1]
def test_integration_scoping(): logger = logging.getLogger("test_basics") events = [] logging_integration = LoggingIntegration(event_level=logging.WARNING) # This client uses the logging integration client_with_logging = Client( transport=events.append, default_integrations=False, integrations=[logging_integration], ) Hub.current.bind_client(client_with_logging) logger.warning("This is a warning") # This client does not client_without_logging = Client(transport=events.append, default_integrations=False) Hub.current.bind_client(client_without_logging) logger.warning("This is not a warning") assert len(events) == 1
def test_client_initialized_within_scope(sentry_init, caplog): caplog.set_level(logging.WARNING) sentry_init(debug=True) with push_scope(): Hub.current.bind_client(Client()) (record,) = (x for x in caplog.records if x.levelname == "WARNING") assert record.msg.startswith("init() called inside of pushed scope.")
def test_with_locals_disabled(): events = [] hub = Hub(Client(with_locals=False, transport=events.append)) try: 1 / 0 except Exception: hub.capture_exception() event, = events assert all( "vars" not in frame for frame in event["exception"]["values"][0]["stacktrace"]["frames"])
def test_with_locals_enabled(): events = [] hub = Hub(Client(with_locals=True, transport=events.append)) try: 1 / 0 except Exception: hub.capture_exception() (event, ) = events assert all( frame["vars"] for frame in event["exception"]["values"][0]["stacktrace"]["frames"])
def test_attach_stacktrace_enabled(): events = [] hub = Hub(Client(attach_stacktrace=True, transport=events.append)) def foo(): bar() def bar(): hub.capture_message("HI") foo() event, = events thread, = event["threads"]["values"] functions = [x["function"] for x in thread["stacktrace"]["frames"]] assert functions[-2:] == ["foo", "bar"]
def test_attach_stacktrace_enabled_no_locals(): events = [] hub = Hub( Client(attach_stacktrace=True, with_locals=False, transport=events.append) ) def foo(): bar() def bar(): hub.capture_message("HI") foo() (event,) = events (thread,) = event["threads"]["values"] local_vars = [x.get("vars") for x in thread["stacktrace"]["frames"]] assert local_vars[-2:] == [None, None]
def test_proxy(monkeypatch, testcase): if testcase["env_http_proxy"] is not None: monkeypatch.setenv("HTTP_PROXY", testcase["env_http_proxy"]) if testcase["env_https_proxy"] is not None: monkeypatch.setenv("HTTPS_PROXY", testcase["env_https_proxy"]) if testcase.get("env_no_proxy") is not None: monkeypatch.setenv("NO_PROXY", testcase["env_no_proxy"]) kwargs = {} if testcase["arg_http_proxy"] is not None: kwargs["http_proxy"] = testcase["arg_http_proxy"] if testcase["arg_https_proxy"] is not None: kwargs["https_proxy"] = testcase["arg_https_proxy"] client = Client(testcase["dsn"], **kwargs) if testcase["expected_proxy_scheme"] is None: assert client.transport._pool.proxy is None else: assert client.transport._pool.proxy.scheme == testcase[ "expected_proxy_scheme"]
def test_ignore_errors(): class MyDivisionError(ZeroDivisionError): pass def raise_it(exc_info): reraise(*exc_info) hub = Hub(Client(ignore_errors=[ZeroDivisionError], transport=_TestTransport())) hub._capture_internal_exception = raise_it def e(exc): try: raise exc except Exception: hub.capture_exception() e(ZeroDivisionError()) e(MyDivisionError()) pytest.raises(EventCaptured, lambda: e(ValueError()))
def test_envelope_types(): """ Tests for calling the right transport method (capture_event vs capture_envelope) from the SDK client for different data types. """ envelopes = [] events = [] class CustomTransport(Transport): def capture_envelope(self, envelope): envelopes.append(envelope) def capture_event(self, event): events.append(event) with Hub(Client(traces_sample_rate=1.0, transport=CustomTransport())): event_id = capture_message("hello") # Assert error events get passed in via capture_event assert not envelopes event = events.pop() assert event["event_id"] == event_id assert "type" not in event with start_transaction(name="foo"): pass # Assert transactions get passed in via capture_envelope assert not events envelope = envelopes.pop() (item, ) = envelope.items assert item.data_category == "transaction" assert item.headers.get("type") == "transaction" assert not envelopes assert not events
def test_proxy_http_fallback_http(monkeypatch): client = Client("https://[email protected]/123", http_proxy="http://localhost/123") assert client.transport._pool.proxy.scheme == "http"
def inner(**kwargs): return Client( "http://foobar@{}/132".format(httpserver.url[len("http://"):]), **kwargs)
def test_capture_event_works(): c = Client(transport=_TestTransport()) pytest.raises(EventCaptured, lambda: c.capture_event({})) pytest.raises(EventCaptured, lambda: c.capture_event({}))
def test_proxy_none_noenv(monkeypatch): client = Client("http://[email protected]/123") assert client.transport._pool.proxy is None
def test_proxy_httpselect_httpsenv(monkeypatch): monkeypatch.setenv("HTTPS_PROXY", "https://localhost/123") client = Client("https://[email protected]/123", http_proxy=None, https_proxy="") assert client.transport._pool.proxy is None
def test_simple_transport(): events = [] with Hub(Client(transport=events.append)): capture_message("Hello World!") assert events[0]["message"] == "Hello World!"
def test_proxy_none_httpenv_select(monkeypatch): monkeypatch.setenv("HTTP_PROXY", "http://localhost/123") client = Client("http://[email protected]/123") assert client.transport._pool.proxy.scheme == "http"
def inner(*a, **kw): hub = Hub.current client = Client(*a, **kw) hub.bind_client(client) monkeypatch.setattr(Hub.current.client, "transport", CustomTransport())