|
@@ -1,8 +1,18 @@
|
|
|
import uuid
|
|
|
-from datetime import datetime
|
|
|
-from typing import Any
|
|
|
+from dataclasses import replace
|
|
|
+from datetime import datetime, timedelta
|
|
|
+from hashlib import md5
|
|
|
+from typing import Any, Optional, Sequence, Tuple
|
|
|
|
|
|
+from django.utils import timezone
|
|
|
+
|
|
|
+from sentry.event_manager import GroupInfo
|
|
|
+from sentry.eventstore.models import Event
|
|
|
+from sentry.issues.ingest import save_issue_occurrence
|
|
|
from sentry.issues.issue_occurrence import IssueEvidence, IssueOccurrence, IssueOccurrenceData
|
|
|
+from sentry.models import Group
|
|
|
+from sentry.testutils import SnubaTestCase
|
|
|
+from sentry.testutils.helpers.datetime import iso_format
|
|
|
from sentry.types.issues import GroupType
|
|
|
|
|
|
|
|
@@ -32,7 +42,7 @@ class OccurrenceTestMixin:
|
|
|
{"name": "hi", "value": "bye", "important": True},
|
|
|
{"name": "what", "value": "where", "important": False},
|
|
|
],
|
|
|
- "type": GroupType.PROFILE_BLOCKED_THREAD,
|
|
|
+ "type": GroupType.PROFILE_BLOCKED_THREAD.value,
|
|
|
"detection_time": datetime.now().timestamp(),
|
|
|
"level": "warning",
|
|
|
}
|
|
@@ -48,3 +58,66 @@ class OccurrenceTestMixin:
|
|
|
]
|
|
|
|
|
|
return IssueOccurrence.from_dict(self.build_occurrence_data(**overrides))
|
|
|
+
|
|
|
+
|
|
|
+class SearchIssueTestMixin(OccurrenceTestMixin):
|
|
|
+ def store_search_issue(
|
|
|
+ self: SnubaTestCase,
|
|
|
+ project_id: int,
|
|
|
+ user_id: int,
|
|
|
+ fingerprints: Sequence[str],
|
|
|
+ environment: Optional[str] = None,
|
|
|
+ insert_time: Optional[datetime] = None,
|
|
|
+ ) -> Tuple[Event, IssueOccurrence, Optional[GroupInfo]]:
|
|
|
+ from sentry.utils import snuba
|
|
|
+
|
|
|
+ insert_timestamp = (insert_time if insert_time else timezone.now()).replace(microsecond=0)
|
|
|
+ user_id_val = f"user_{user_id}"
|
|
|
+
|
|
|
+ event_data = {
|
|
|
+ "tags": [("sentry:user", user_id_val)],
|
|
|
+ "timestamp": iso_format(insert_timestamp),
|
|
|
+ }
|
|
|
+
|
|
|
+ if environment:
|
|
|
+ event_data["environment"] = environment
|
|
|
+ event_data["tags"].extend([("environment", environment)])
|
|
|
+
|
|
|
+ event = self.store_event(
|
|
|
+ data=event_data,
|
|
|
+ project_id=project_id,
|
|
|
+ )
|
|
|
+ occurrence = self.build_occurrence(event_id=event.event_id, fingerprint=fingerprints)
|
|
|
+ saved_occurrence, group_info = save_issue_occurrence(occurrence.to_dict(), event)
|
|
|
+ occurrence = replace(
|
|
|
+ occurrence,
|
|
|
+ fingerprint=[md5(fp.encode("utf-8")).hexdigest() for fp in occurrence.fingerprint],
|
|
|
+ )
|
|
|
+ self.assert_occurrences_identical(occurrence, saved_occurrence)
|
|
|
+
|
|
|
+ assert Group.objects.filter(grouphash__hash=saved_occurrence.fingerprint[0]).exists()
|
|
|
+
|
|
|
+ result = snuba.raw_query(
|
|
|
+ dataset=snuba.Dataset.IssuePlatform,
|
|
|
+ start=insert_timestamp - timedelta(days=1),
|
|
|
+ end=insert_timestamp + timedelta(days=1),
|
|
|
+ selected_columns=[
|
|
|
+ "event_id",
|
|
|
+ "project_id",
|
|
|
+ "environment",
|
|
|
+ "group_id",
|
|
|
+ "tags[sentry:user]",
|
|
|
+ "timestamp",
|
|
|
+ ],
|
|
|
+ groupby=None,
|
|
|
+ filter_keys={"project_id": [project_id], "event_id": [event.event_id]},
|
|
|
+ referrer="test_utils.store_search_issue",
|
|
|
+ )
|
|
|
+ assert len(result["data"]) == 1
|
|
|
+ assert result["data"][0]["project_id"] == project_id
|
|
|
+ assert result["data"][0]["group_id"] == group_info.group.id if group_info else None
|
|
|
+ assert result["data"][0]["tags[sentry:user]"] == user_id_val
|
|
|
+ assert result["data"][0]["environment"] == environment
|
|
|
+ assert result["data"][0]["timestamp"] == insert_timestamp.isoformat()
|
|
|
+
|
|
|
+ return event, saved_occurrence, group_info
|