test_utils.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import types
  2. from sentry.issues.grouptype import (
  3. PerformanceNPlusOneAPICallsGroupType,
  4. PerformanceNPlusOneGroupType,
  5. PerformanceRenderBlockingAssetSpanGroupType,
  6. )
  7. from sentry.notifications.utils import (
  8. NPlusOneAPICallProblemContext,
  9. PerformanceProblemContext,
  10. RenderBlockingAssetProblemContext,
  11. )
  12. from sentry.testutils.cases import TestCase
  13. from sentry.utils.performance_issues.performance_problem import PerformanceProblem
  14. def mock_event(*, transaction, data=None):
  15. return types.SimpleNamespace(data=data or {}, transaction=transaction)
  16. class PerformanceProblemContextTestCase(TestCase):
  17. def test_creates_correct_context(self):
  18. assert (
  19. PerformanceProblemContext.from_problem_and_spans(
  20. PerformanceProblem(
  21. fingerprint="",
  22. op="",
  23. desc="",
  24. type=PerformanceNPlusOneGroupType,
  25. parent_span_ids=[],
  26. cause_span_ids=[],
  27. offender_span_ids=[],
  28. evidence_data={},
  29. evidence_display=[],
  30. ),
  31. [],
  32. ).__class__
  33. == PerformanceProblemContext
  34. )
  35. assert (
  36. PerformanceProblemContext.from_problem_and_spans(
  37. PerformanceProblem(
  38. fingerprint="",
  39. op="",
  40. desc="",
  41. type=PerformanceNPlusOneAPICallsGroupType,
  42. parent_span_ids=[],
  43. cause_span_ids=[],
  44. offender_span_ids=[],
  45. evidence_data={},
  46. evidence_display=[],
  47. ),
  48. [],
  49. ).__class__
  50. == NPlusOneAPICallProblemContext
  51. )
  52. def test_returns_n_plus_one_db_query_context(self):
  53. event = mock_event(transaction="sentry transaction")
  54. context = PerformanceProblemContext(
  55. PerformanceProblem(
  56. fingerprint=f"1-{PerformanceNPlusOneGroupType.type_id}-153198dd61706844cf3d9a922f6f82543df8125f",
  57. op="db",
  58. desc="SELECT * FROM table",
  59. type=PerformanceNPlusOneGroupType,
  60. parent_span_ids=["b93d2be92cd64fd5"],
  61. cause_span_ids=[],
  62. offender_span_ids=["054ba3a374d543eb"],
  63. evidence_data={},
  64. evidence_display=[],
  65. ),
  66. [
  67. {"span_id": "b93d2be92cd64fd5", "description": "SELECT * FROM parent_table"},
  68. {"span_id": "054ba3a374d543eb", "description": "SELECT * FROM table WHERE id=%s"},
  69. ],
  70. event,
  71. )
  72. assert context.to_dict() == {
  73. "transaction_name": "sentry transaction",
  74. "parent_span": "SELECT * FROM parent_table",
  75. "repeating_spans": "SELECT * FROM table WHERE id=%s",
  76. "num_repeating_spans": "1",
  77. }
  78. def test_returns_n_plus_one_api_call_context(self):
  79. event = mock_event(transaction="/resources")
  80. context = NPlusOneAPICallProblemContext(
  81. PerformanceProblem(
  82. fingerprint=f"1-{PerformanceNPlusOneAPICallsGroupType.type_id}-153198dd61706844cf3d9a922f6f82543df8125f",
  83. op="http.client",
  84. desc="/resources",
  85. type=PerformanceNPlusOneAPICallsGroupType,
  86. parent_span_ids=[],
  87. cause_span_ids=[],
  88. offender_span_ids=["b93d2be92cd64fd5", "054ba3a374d543eb", "563712f9722fb09"],
  89. evidence_data={},
  90. evidence_display=[],
  91. ),
  92. [
  93. {
  94. "span_id": "b93d2be92cd64fd5",
  95. "description": "GET https://resource.io/resource?id=1",
  96. },
  97. {
  98. "span_id": "054ba3a374d543eb",
  99. "description": "GET https://resource.io/resource?id=2",
  100. },
  101. {"span_id": "563712f9722fb09", "description": "GET https://resource.io/resource"},
  102. ],
  103. event,
  104. )
  105. assert context.to_dict() == {
  106. "transaction_name": "/resources",
  107. "repeating_spans": "/resource",
  108. "parameters": ["{id: 1,2}"],
  109. "num_repeating_spans": "3",
  110. }
  111. def test_returns_render_blocking_asset_context(self):
  112. event = mock_event(
  113. transaction="/details",
  114. data={
  115. "start_timestamp": 0,
  116. "timestamp": 3,
  117. "measurements": {"fcp": {"value": 1500, "unit": "milliseconds"}},
  118. },
  119. )
  120. context = RenderBlockingAssetProblemContext(
  121. PerformanceProblem(
  122. fingerprint=f"1-{PerformanceRenderBlockingAssetSpanGroupType.type_id}-153198dd61706844cf3d9a922f6f82543df8125f",
  123. op="http.client",
  124. desc="/details",
  125. type=PerformanceRenderBlockingAssetSpanGroupType,
  126. parent_span_ids=[],
  127. cause_span_ids=[],
  128. offender_span_ids=["b93d2be92cd64fd5"],
  129. evidence_data={},
  130. evidence_display=[],
  131. ),
  132. [
  133. {
  134. "op": "resource.script",
  135. "span_id": "b93d2be92cd64fd5",
  136. "description": "/assets/script.js",
  137. "start_timestamp": 1677078164.09656,
  138. "timestamp": 1677078165.09656,
  139. },
  140. ],
  141. event,
  142. )
  143. assert context.to_dict() == {
  144. "transaction_name": "/details",
  145. "slow_span_description": "/assets/script.js",
  146. "slow_span_duration": 1000,
  147. "transaction_duration": 3000,
  148. "fcp": 1500,
  149. }