test_stacktraces.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. from __future__ import annotations
  2. from typing import Any
  3. import pytest
  4. from sentry.stacktraces.processing import find_stacktraces_in_data, get_crash_frame_from_event_data
  5. from sentry.testutils.cases import TestCase
  6. class FindStacktracesTest(TestCase):
  7. def test_stacktraces_basics(self):
  8. data: dict[str, Any] = {
  9. "message": "hello",
  10. "platform": "javascript",
  11. "stacktrace": {
  12. "frames": [
  13. {
  14. "abs_path": "http://example.com/foo.js",
  15. "filename": "foo.js",
  16. "lineno": 4,
  17. "colno": 0,
  18. },
  19. {
  20. "abs_path": "http://example.com/foo.js",
  21. "filename": "foo.js",
  22. "lineno": 1,
  23. "colno": 0,
  24. "platform": "native",
  25. },
  26. ]
  27. },
  28. }
  29. infos = find_stacktraces_in_data(data)
  30. assert len(infos) == 1
  31. assert len(infos[0].stacktrace["frames"]) == 2
  32. assert infos[0].platforms == {"javascript", "native"}
  33. def test_stacktraces_exception(self):
  34. data: dict[str, Any] = {
  35. "message": "hello",
  36. "platform": "javascript",
  37. "exception": {
  38. "values": [
  39. {
  40. "type": "Error",
  41. "stacktrace": {
  42. "frames": [
  43. {
  44. "abs_path": "http://example.com/foo.js",
  45. "filename": "foo.js",
  46. "lineno": 4,
  47. "colno": 0,
  48. },
  49. {
  50. "abs_path": "http://example.com/foo.js",
  51. "filename": "foo.js",
  52. "lineno": 1,
  53. "colno": 0,
  54. },
  55. ]
  56. },
  57. }
  58. ]
  59. },
  60. }
  61. infos = find_stacktraces_in_data(data)
  62. assert len(infos) == 1
  63. assert len(infos[0].stacktrace["frames"]) == 2
  64. def test_stacktraces_threads(self):
  65. data: dict[str, Any] = {
  66. "message": "hello",
  67. "platform": "javascript",
  68. "threads": {
  69. "values": [
  70. {
  71. "id": "4711",
  72. "stacktrace": {
  73. "frames": [
  74. {
  75. "abs_path": "http://example.com/foo.js",
  76. "filename": "foo.js",
  77. "lineno": 4,
  78. "colno": 0,
  79. },
  80. {
  81. "abs_path": "http://example.com/foo.js",
  82. "filename": "foo.js",
  83. "lineno": 1,
  84. "colno": 0,
  85. },
  86. ]
  87. },
  88. }
  89. ]
  90. },
  91. }
  92. infos = find_stacktraces_in_data(data)
  93. assert len(infos) == 1
  94. assert len(infos[0].stacktrace["frames"]) == 2
  95. def test_find_stacktraces_skip_none(self):
  96. # This tests:
  97. # 1. exception is None
  98. # 2. stacktrace is None
  99. # 3. frames is None
  100. # 3. frames contains only None
  101. # 4. frame is None
  102. data: dict[str, Any] = {
  103. "message": "hello",
  104. "platform": "javascript",
  105. "exception": {
  106. "values": [
  107. None,
  108. {"type": "Error", "stacktrace": None},
  109. {"type": "Error", "stacktrace": {"frames": None}},
  110. {"type": "Error", "stacktrace": {"frames": [None]}},
  111. {
  112. "type": "Error",
  113. "stacktrace": {
  114. "frames": [
  115. None,
  116. {
  117. "abs_path": "http://example.com/foo.js",
  118. "filename": "foo.js",
  119. "lineno": 4,
  120. "colno": 0,
  121. },
  122. {
  123. "abs_path": "http://example.com/foo.js",
  124. "filename": "foo.js",
  125. "lineno": 1,
  126. "colno": 0,
  127. },
  128. ]
  129. },
  130. },
  131. ]
  132. },
  133. }
  134. infos = find_stacktraces_in_data(data, include_empty_exceptions=True)
  135. assert len(infos) == 4
  136. assert sum(1 for x in infos if x.stacktrace) == 3
  137. assert sum(1 for x in infos if x.is_exception) == 4
  138. # XXX: The null frame is still part of this stack trace!
  139. assert len(infos[3].stacktrace["frames"]) == 3
  140. infos = find_stacktraces_in_data(data)
  141. assert len(infos) == 1
  142. # XXX: The null frame is still part of this stack trace!
  143. assert len(infos[0].stacktrace["frames"]) == 3
  144. @pytest.mark.parametrize(
  145. "event",
  146. [
  147. {"threads": {"values": [{"stacktrace": {"frames": [{"in_app": True, "marco": "polo"}]}}]}},
  148. {
  149. "exception": {
  150. "values": [{"stacktrace": {"frames": [{"in_app": True, "marco": "polo"}]}}]
  151. }
  152. },
  153. {"stacktrace": {"frames": [{"in_app": True, "marco": "polo"}]}},
  154. ],
  155. )
  156. def test_get_crash_frame(event):
  157. assert get_crash_frame_from_event_data(event)["marco"] == "polo"