123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- import uuid
- from datetime import timedelta
- from unittest.mock import patch
- import pytest
- from django.core.cache import cache
- from sentry.integrations.slack.message_builder.image_block_builder import ImageBlockBuilder
- from sentry.issues.grouptype import (
- PerformanceHTTPOverheadGroupType,
- PerformanceP95EndpointRegressionGroupType,
- ProfileFunctionRegressionType,
- )
- from sentry.models.group import Group
- from sentry.testutils.cases import (
- AcceptanceTestCase,
- MetricsEnhancedPerformanceTestCase,
- ProfilesSnubaTestCase,
- )
- from sentry.testutils.helpers.datetime import before_now
- from sentry.testutils.helpers.features import with_feature
- from tests.sentry.issues.test_utils import OccurrenceTestMixin
- pytestmark = pytest.mark.sentry_metrics
- class TestSlackImageBlockBuilder(
- AcceptanceTestCase,
- MetricsEnhancedPerformanceTestCase,
- ProfilesSnubaTestCase,
- OccurrenceTestMixin,
- ):
- def setUp(self):
- super().setUp()
- self.features = {
- "organizations:performance-use-metrics": True,
- "organizations:slack-endpoint-regression-image": True,
- "organizations:slack-function-regression-image": True,
- }
- cache.clear()
- def _create_endpoint_regression_issue(self):
- for i in range(10):
- event_id = uuid.uuid4().hex
- _ = self.process_occurrence(
- project_id=self.project.id,
- event_id=event_id,
- type=PerformanceP95EndpointRegressionGroupType.type_id,
- event_data={
- "fingerprint": ["group-1"],
- "timestamp": before_now(minutes=i + 10).isoformat(),
- "transaction": "/books/",
- },
- evidence_data={
- "breakpoint": before_now(minutes=i + 10).timestamp(),
- },
- )
- self.store_transaction_metric(
- metric="transaction.duration",
- tags={"transaction": "/books/"},
- value=1,
- timestamp=before_now(minutes=i + 10),
- project=self.project.id,
- )
- group = Group.objects.get()
- group.update(type=PerformanceP95EndpointRegressionGroupType.type_id)
- return group
- @with_feature("organizations:slack-endpoint-regression-image")
- def test_image_block_for_endpoint_regression(self):
- group = self._create_endpoint_regression_issue()
- with self.feature(self.features):
- image_block = ImageBlockBuilder(group=group).build_image_block()
- assert image_block and "type" in image_block and image_block["type"] == "image"
- assert "_media/" in image_block["image_url"]
- @patch("sentry.utils.performance_issues.detectors.utils.escape_transaction")
- @with_feature("organizations:slack-endpoint-regression-image")
- def test_caching(self, mock_escape_transaction):
- mock_escape_transaction.return_value = "Test Transaction"
- group = self._create_endpoint_regression_issue()
- image_blocks = []
- for _ in range(5):
- with self.feature(self.features):
- image_blocks.append(ImageBlockBuilder(group=group).build_image_block())
- assert mock_escape_transaction.call_count == 1
- assert len(image_blocks) == 5
- assert image_blocks[0]
- image_url = image_blocks[0]["image_url"]
- for image_block in image_blocks:
- assert image_block is not None
- assert image_block["image_url"] == image_url
- @with_feature("organizations:slack-function-regression-image")
- def test_image_block_for_function_regression(self):
- hour_ago = (before_now(minutes=10) - timedelta(hours=1)).replace(
- minute=0, second=0, microsecond=0
- )
- for i in range(10):
- event_id = uuid.uuid4().hex
- _ = self.process_occurrence(
- project_id=self.project.id,
- event_id=event_id,
- type=ProfileFunctionRegressionType.type_id,
- event_data={
- "fingerprint": ["group-1"],
- "timestamp": before_now(minutes=i + 10).isoformat(),
- "function": "foo",
- },
- evidence_data={
- "breakpoint": before_now(minutes=i + 10).timestamp(),
- "fingerprint": self.function_fingerprint({"package": "foo", "function": "foo"}),
- "aggregate_range_1": 51588984.199999996,
- "aggregate_range_2": 839118611.8535699,
- },
- )
- self.store_functions(
- [
- {
- "self_times_ns": [100 for _ in range(100)],
- "package": "foo",
- "function": "foo",
- # only in app functions should
- # appear in the results
- "in_app": True,
- },
- ],
- project=self.project,
- timestamp=hour_ago,
- )
- group = Group.objects.get()
- with self.feature(self.features):
- image_block = ImageBlockBuilder(group=group).build_image_block()
- assert image_block and "type" in image_block and image_block["type"] == "image"
- assert "_media/" in image_block["image_url"]
- @patch("sentry_sdk.capture_exception")
- @with_feature("organizations:slack-function-regression-image")
- def test_image_not_generated_for_unsupported_issues(self, mock_capture_exception):
- group = self.create_group()
- group.update(type=PerformanceHTTPOverheadGroupType.type_id)
- image_block = ImageBlockBuilder(group=group).build_image_block()
- assert image_block is None
- assert mock_capture_exception.call_count == 0
|