messageSamplesPanel.spec.tsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import {OrganizationFixture} from 'sentry-fixture/organization';
  2. import {render, screen, waitForElementToBeRemoved} from 'sentry-test/reactTestingLibrary';
  3. import {useLocation} from 'sentry/utils/useLocation';
  4. import useOrganization from 'sentry/utils/useOrganization';
  5. import usePageFilters from 'sentry/utils/usePageFilters';
  6. import {MessageSamplesPanel} from 'sentry/views/performance/queues/messageSamplesPanel';
  7. jest.mock('sentry/utils/useLocation');
  8. jest.mock('sentry/utils/usePageFilters');
  9. jest.mock('sentry/utils/useOrganization');
  10. describe('messageSamplesPanel', () => {
  11. const organization = OrganizationFixture();
  12. let eventsRequestMock, eventsStatsRequestMock, samplesRequestMock;
  13. jest.mocked(usePageFilters).mockReturnValue({
  14. isReady: true,
  15. desyncedFilters: new Set(),
  16. pinnedFilters: new Set(),
  17. shouldPersist: true,
  18. selection: {
  19. datetime: {
  20. period: '10d',
  21. start: null,
  22. end: null,
  23. utc: false,
  24. },
  25. environments: [],
  26. projects: [],
  27. },
  28. });
  29. jest.mocked(useLocation).mockReturnValue({
  30. pathname: '',
  31. search: '',
  32. query: {transaction: 'sentry.tasks.store.save_event', destination: 'event-queue'},
  33. hash: '',
  34. state: undefined,
  35. action: 'PUSH',
  36. key: '',
  37. });
  38. jest.mocked(useOrganization).mockReturnValue(organization);
  39. beforeEach(() => {
  40. eventsStatsRequestMock = MockApiClient.addMockResponse({
  41. url: `/organizations/${organization.slug}/events-stats/`,
  42. method: 'GET',
  43. body: {
  44. data: [[1699907700, [{count: 7810}]]],
  45. meta: {},
  46. },
  47. });
  48. eventsRequestMock = MockApiClient.addMockResponse({
  49. url: `/organizations/${organization.slug}/events/`,
  50. method: 'GET',
  51. body: {
  52. data: [],
  53. meta: {},
  54. },
  55. });
  56. samplesRequestMock = MockApiClient.addMockResponse({
  57. url: `/api/0/organizations/${organization.slug}/spans-samples/`,
  58. method: 'GET',
  59. body: {
  60. data: [
  61. {
  62. span_id: '123',
  63. trace: 'abc',
  64. project: 'project',
  65. timestamp: '2024-03-25T20:31:36+00:00',
  66. 'span.duration': 320.300102,
  67. },
  68. ],
  69. },
  70. });
  71. });
  72. afterAll(() => {
  73. jest.resetAllMocks();
  74. });
  75. it('renders consumer panel', async () => {
  76. jest.mocked(useLocation).mockReturnValue({
  77. pathname: '',
  78. search: '',
  79. query: {
  80. transaction: 'sentry.tasks.store.save_event',
  81. destination: 'event-queue',
  82. 'span.op': 'queue.process',
  83. },
  84. hash: '',
  85. state: undefined,
  86. action: 'PUSH',
  87. key: '',
  88. });
  89. render(<MessageSamplesPanel />);
  90. await waitForElementToBeRemoved(() => screen.queryAllByTestId('loading-indicator'));
  91. expect(eventsStatsRequestMock).toHaveBeenCalled();
  92. expect(eventsRequestMock).toHaveBeenCalledWith(
  93. `/organizations/${organization.slug}/events/`,
  94. expect.objectContaining({
  95. method: 'GET',
  96. query: expect.objectContaining({
  97. dataset: 'spansMetrics',
  98. environment: [],
  99. field: [
  100. 'count()',
  101. 'count_op(queue.publish)',
  102. 'count_op(queue.process)',
  103. 'sum(span.duration)',
  104. 'avg(span.duration)',
  105. 'avg_if(span.duration,span.op,queue.publish)',
  106. 'avg_if(span.duration,span.op,queue.process)',
  107. 'avg(messaging.message.receive.latency)',
  108. ],
  109. per_page: 10,
  110. project: [],
  111. query:
  112. 'span.op:[queue.process,queue.publish] messaging.destination.name:event-queue transaction:sentry.tasks.store.save_event',
  113. statsPeriod: '10d',
  114. }),
  115. })
  116. );
  117. expect(samplesRequestMock).toHaveBeenCalledWith(
  118. `/api/0/organizations/${organization.slug}/spans-samples/`,
  119. expect.objectContaining({
  120. query: expect.objectContaining({
  121. additionalFields: [
  122. 'trace',
  123. 'transaction.id',
  124. 'span.description',
  125. 'measurements.messaging.message.body.size',
  126. 'measurements.messaging.message.receive.latency',
  127. 'measurements.messaging.message.retry.count',
  128. 'messaging.message.id',
  129. 'trace.status',
  130. 'span.duration',
  131. ],
  132. firstBound: 2666.6666666666665,
  133. lowerBound: 0,
  134. project: [],
  135. query:
  136. 'span.op:queue.process transaction:sentry.tasks.store.save_event messaging.destination.name:event-queue',
  137. referrer: undefined,
  138. secondBound: 5333.333333333333,
  139. statsPeriod: '10d',
  140. upperBound: 8000,
  141. }),
  142. })
  143. );
  144. expect(screen.getByRole('table', {name: 'Span Samples'})).toBeInTheDocument();
  145. });
  146. it('renders producer panel', async () => {
  147. jest.mocked(useLocation).mockReturnValue({
  148. pathname: '',
  149. search: '',
  150. query: {
  151. transaction: 'sentry.tasks.store.save_event',
  152. destination: 'event-queue',
  153. 'span.op': 'queue.publish',
  154. },
  155. hash: '',
  156. state: undefined,
  157. action: 'PUSH',
  158. key: '',
  159. });
  160. render(<MessageSamplesPanel />);
  161. await waitForElementToBeRemoved(() => screen.queryAllByTestId('loading-indicator'));
  162. expect(eventsStatsRequestMock).toHaveBeenCalled();
  163. expect(eventsRequestMock).toHaveBeenCalledWith(
  164. `/organizations/${organization.slug}/events/`,
  165. expect.objectContaining({
  166. method: 'GET',
  167. query: expect.objectContaining({
  168. dataset: 'spansMetrics',
  169. environment: [],
  170. field: [
  171. 'count()',
  172. 'count_op(queue.publish)',
  173. 'count_op(queue.process)',
  174. 'sum(span.duration)',
  175. 'avg(span.duration)',
  176. 'avg_if(span.duration,span.op,queue.publish)',
  177. 'avg_if(span.duration,span.op,queue.process)',
  178. 'avg(messaging.message.receive.latency)',
  179. ],
  180. per_page: 10,
  181. project: [],
  182. query:
  183. 'span.op:[queue.process,queue.publish] messaging.destination.name:event-queue transaction:sentry.tasks.store.save_event',
  184. statsPeriod: '10d',
  185. }),
  186. })
  187. );
  188. expect(samplesRequestMock).toHaveBeenCalledWith(
  189. `/api/0/organizations/${organization.slug}/spans-samples/`,
  190. expect.objectContaining({
  191. query: expect.objectContaining({
  192. additionalFields: [
  193. 'trace',
  194. 'transaction.id',
  195. 'span.description',
  196. 'measurements.messaging.message.body.size',
  197. 'measurements.messaging.message.receive.latency',
  198. 'measurements.messaging.message.retry.count',
  199. 'messaging.message.id',
  200. 'trace.status',
  201. 'span.duration',
  202. ],
  203. firstBound: 2666.6666666666665,
  204. lowerBound: 0,
  205. project: [],
  206. query:
  207. 'span.op:queue.publish transaction:sentry.tasks.store.save_event messaging.destination.name:event-queue',
  208. referrer: undefined,
  209. secondBound: 5333.333333333333,
  210. statsPeriod: '10d',
  211. upperBound: 8000,
  212. }),
  213. })
  214. );
  215. expect(screen.getByRole('table', {name: 'Span Samples'})).toBeInTheDocument();
  216. });
  217. });