test_sdk.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import uuid
  2. from unittest import mock
  3. import pytest
  4. from django.test.utils import override_settings
  5. from sentry_sdk import Hub, push_scope
  6. from sentry import eventstore
  7. from sentry.eventstore.models import Event
  8. from sentry.testutils import assert_mock_called_once_with_partial
  9. from sentry.utils.pytest.relay import adjust_settings_for_relay_tests
  10. from sentry.utils.sdk import bind_organization_context, configure_sdk
  11. @pytest.fixture
  12. def post_event_with_sdk(settings, relay_server, wait_for_ingest_consumer):
  13. adjust_settings_for_relay_tests(settings)
  14. settings.SENTRY_ENDPOINT = relay_server["url"]
  15. settings.SENTRY_PROJECT = 1
  16. configure_sdk()
  17. hub = Hub.current # XXX: Hub.current gets reset, this is a workaround
  18. def bind_client(self, new, *, _orig=Hub.bind_client):
  19. if new is None:
  20. import sys
  21. import traceback
  22. print("!!! Hub client was reset to None !!!", file=sys.stderr) # noqa: S002
  23. traceback.print_stack()
  24. print("!!!", file=sys.stderr) # noqa: S002
  25. return _orig(self, new)
  26. # XXX: trying to figure out why it gets reset
  27. with mock.patch.object(Hub, "bind_client", bind_client):
  28. wait_for_ingest_consumer = wait_for_ingest_consumer(settings)
  29. def inner(*args, **kwargs):
  30. assert Hub.current.client is not None
  31. event_id = hub.capture_event(*args, **kwargs)
  32. hub.client.flush()
  33. with push_scope():
  34. return wait_for_ingest_consumer(
  35. lambda: eventstore.get_event_by_id(settings.SENTRY_PROJECT, event_id)
  36. )
  37. yield inner
  38. @override_settings(SENTRY_PROJECT=1)
  39. @pytest.mark.django_db
  40. def test_simple(settings, post_event_with_sdk):
  41. event = post_event_with_sdk({"message": "internal client test"})
  42. assert event
  43. assert event.data["project"] == settings.SENTRY_PROJECT
  44. assert event.data["logentry"]["formatted"] == "internal client test"
  45. @override_settings(SENTRY_PROJECT=1)
  46. @pytest.mark.django_db
  47. def test_recursion_breaker(settings, post_event_with_sdk):
  48. # If this test terminates at all then we avoided recursion.
  49. settings.SENTRY_INGEST_CONSUMER_APM_SAMPLING = 1.0
  50. settings.SENTRY_PROJECT = 1
  51. event_id = uuid.uuid4().hex
  52. with mock.patch(
  53. "sentry.event_manager.EventManager.save", spec=Event, side_effect=ValueError("oh no!")
  54. ) as save:
  55. with pytest.raises(ValueError):
  56. post_event_with_sdk({"message": "internal client test", "event_id": event_id})
  57. assert_mock_called_once_with_partial(save, settings.SENTRY_PROJECT, cache_key=f"e:{event_id}:1")
  58. @pytest.mark.django_db
  59. @override_settings(SENTRY_PROJECT=1)
  60. def test_encoding(settings, post_event_with_sdk):
  61. class NotJSONSerializable:
  62. pass
  63. with push_scope() as scope:
  64. scope.set_extra("request", NotJSONSerializable())
  65. event = post_event_with_sdk({"message": "check the req"})
  66. assert event.data["project"] == settings.SENTRY_PROJECT
  67. assert event.data["logentry"]["formatted"] == "check the req"
  68. assert "NotJSONSerializable" in event.data["extra"]["request"]
  69. @override_settings(SENTRY_PROJECT=1)
  70. @pytest.mark.django_db
  71. def test_bind_organization_context(default_organization):
  72. configure_sdk()
  73. bind_organization_context(default_organization)
  74. assert Hub.current.scope._tags["organization"] == default_organization.id
  75. assert Hub.current.scope._tags["organization.slug"] == default_organization.slug
  76. assert Hub.current.scope._contexts["organization"] == {
  77. "id": default_organization.id,
  78. "slug": default_organization.slug,
  79. }
  80. @override_settings(SENTRY_PROJECT=1)
  81. @pytest.mark.django_db
  82. def test_bind_organization_context_with_callback(settings, default_organization):
  83. configure_sdk()
  84. def add_context(scope, organization, **kwargs):
  85. scope.set_tag("organization.test", "1")
  86. settings.SENTRY_ORGANIZATION_CONTEXT_HELPER = add_context
  87. bind_organization_context(default_organization)
  88. assert Hub.current.scope._tags["organization.test"] == "1"
  89. @override_settings(SENTRY_PROJECT=1)
  90. @pytest.mark.django_db
  91. def test_bind_organization_context_with_callback_error(settings, default_organization):
  92. configure_sdk()
  93. def add_context(scope, organization, **kwargs):
  94. 1 / 0
  95. settings.SENTRY_ORGANIZATION_CONTEXT_HELPER = add_context
  96. bind_organization_context(default_organization)
  97. assert Hub.current.scope._tags["organization"] == default_organization.id