123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- import time
- from datetime import timedelta
- from unittest import mock
- import pytz
- from django.utils import timezone
- from sentry.api.event_search import SearchFilter, SearchKey, SearchValue
- from sentry.api.serializers import serialize
- from sentry.api.serializers.models.group_stream import StreamGroupSerializerSnuba, snuba_tsdb
- from sentry.models import Environment
- from sentry.testutils import APITestCase, SnubaTestCase
- from sentry.testutils.helpers.datetime import before_now, iso_format
- from sentry.testutils.silo import region_silo_test
- from sentry.utils.cache import cache
- from sentry.utils.hashlib import hash_values
- @region_silo_test
- class StreamGroupSerializerTestCase(APITestCase, SnubaTestCase):
- def test_environment(self):
- group = self.group
- organization_id = group.project.organization_id
- environment = Environment.get_or_create(group.project, "production")
- with mock.patch(
- "sentry.api.serializers.models.group_stream.snuba_tsdb.get_range",
- side_effect=snuba_tsdb.get_range,
- ) as get_range:
- serialize(
- [group],
- serializer=StreamGroupSerializerSnuba(
- environment_ids=[environment.id],
- stats_period="14d",
- organization_id=organization_id,
- ),
- )
- assert get_range.call_count == 1
- for args, kwargs in get_range.call_args_list:
- assert kwargs["environment_ids"] == [environment.id]
- with mock.patch(
- "sentry.api.serializers.models.group.snuba_tsdb.get_range",
- side_effect=snuba_tsdb.get_range,
- ) as get_range:
- serialize(
- [group],
- serializer=StreamGroupSerializerSnuba(
- environment_ids=None, stats_period="14d", organization_id=organization_id
- ),
- )
- assert get_range.call_count == 1
- for args, kwargs in get_range.call_args_list:
- assert kwargs["environment_ids"] is None
- def test_session_count(self):
- group = self.group
- organization_id = group.project.organization_id
- environment = Environment.get_or_create(group.project, "prod")
- dev_environment = Environment.get_or_create(group.project, "dev")
- no_sessions_environment = Environment.get_or_create(group.project, "no_sessions")
- self.received = time.time()
- self.session_started = time.time() // 60 * 60
- self.session_release = "foo@1.0.0"
- self.session_crashed_release = "foo@2.0.0"
- self.store_session(
- {
- "session_id": "5d52fd05-fcc9-4bf3-9dc9-267783670341",
- "distinct_id": "39887d89-13b2-4c84-8c23-5d13d2102667",
- "status": "ok",
- "seq": 0,
- "release": self.session_release,
- "environment": "dev",
- "retention_days": 90,
- "org_id": self.project.organization_id,
- "project_id": self.project.id,
- "duration": 1,
- "errors": 0,
- "started": self.session_started - 120,
- "received": self.received - 120,
- }
- )
- self.store_session(
- {
- "session_id": "5e910c1a-6941-460e-9843-24103fb6a63c",
- "distinct_id": "39887d89-13b2-4c84-8c23-5d13d2102668",
- "status": "ok",
- "seq": 0,
- "release": self.session_release,
- "environment": "prod",
- "retention_days": 90,
- "org_id": self.project.organization_id,
- "project_id": self.project.id,
- "duration": 60.0,
- "errors": 0,
- "started": self.session_started - 240,
- "received": self.received - 240,
- }
- )
- self.store_session(
- {
- "session_id": "5e910c1a-6941-460e-9843-24103fb6a63c",
- "distinct_id": "39887d89-13b2-4c84-8c23-5d13d2102669",
- "status": "exited",
- "seq": 1,
- "release": self.session_release,
- "environment": "prod",
- "retention_days": 90,
- "org_id": self.project.organization_id,
- "project_id": self.project.id,
- "duration": 30.0,
- "errors": 0,
- "started": self.session_started,
- "received": self.received,
- }
- )
- self.store_session(
- {
- "session_id": "a148c0c5-06a2-423b-8901-6b43b812cf82",
- "distinct_id": "39887d89-13b2-4c84-8c23-5d13d2102660",
- "status": "crashed",
- "seq": 0,
- "release": self.session_crashed_release,
- "environment": "prod",
- "retention_days": 90,
- "org_id": self.project.organization_id,
- "project_id": self.project.id,
- "duration": 60.0,
- "errors": 0,
- "started": self.session_started,
- "received": self.received,
- }
- )
- result = serialize(
- [group],
- serializer=StreamGroupSerializerSnuba(
- stats_period="14d", organization_id=organization_id
- ),
- )
- assert "sessionCount" not in result[0]
- result = serialize(
- [group],
- serializer=StreamGroupSerializerSnuba(
- stats_period="14d", expand=["sessions"], organization_id=organization_id
- ),
- )
- assert result[0]["sessionCount"] == 3
- result = serialize(
- [group],
- serializer=StreamGroupSerializerSnuba(
- environment_ids=[environment.id],
- stats_period="14d",
- expand=["sessions"],
- organization_id=organization_id,
- ),
- )
- assert result[0]["sessionCount"] == 2
- result = serialize(
- [group],
- serializer=StreamGroupSerializerSnuba(
- environment_ids=[no_sessions_environment.id],
- stats_period="14d",
- expand=["sessions"],
- organization_id=organization_id,
- ),
- )
- assert result[0]["sessionCount"] is None
- result = serialize(
- [group],
- serializer=StreamGroupSerializerSnuba(
- environment_ids=[dev_environment.id],
- stats_period="14d",
- expand=["sessions"],
- organization_id=organization_id,
- ),
- )
- assert result[0]["sessionCount"] == 1
- self.store_session(
- {
- "session_id": "a148c0c5-06a2-423b-8901-6b43b812cf83",
- "distinct_id": "39887d89-13b2-4c84-8c23-5d13d2102627",
- "status": "ok",
- "seq": 0,
- "release": self.session_release,
- "environment": "dev",
- "retention_days": 90,
- "org_id": self.project.organization_id,
- "project_id": self.project.id,
- "duration": 60.0,
- "errors": 0,
- "started": self.session_started - 1590061, # approximately 18 days
- "received": self.received - 1590061, # approximately 18 days
- }
- )
- result = serialize(
- [group],
- serializer=StreamGroupSerializerSnuba(
- environment_ids=[dev_environment.id],
- stats_period="14d",
- expand=["sessions"],
- start=timezone.now() - timedelta(days=30),
- end=timezone.now() - timedelta(days=15),
- organization_id=organization_id,
- ),
- )
- assert result[0]["sessionCount"] == 1
- # Delete the cache from the query we did above, else this result comes back as 1 instead of 0.5
- key_hash = hash_values([group.project.id, "", "", f"{dev_environment.id}"])
- cache.delete(f"w-s:{key_hash}")
- project2 = self.create_project(
- organization=self.organization, teams=[self.team], name="Another project"
- )
- data = {
- "fingerprint": ["meow"],
- "timestamp": iso_format(timezone.now()),
- "type": "error",
- "exception": [{"type": "Foo"}],
- }
- event = self.store_event(data=data, project_id=project2.id)
- self.store_event(data=data, project_id=project2.id)
- self.store_event(data=data, project_id=project2.id)
- result = serialize(
- [group, event.group],
- serializer=StreamGroupSerializerSnuba(
- environment_ids=[dev_environment.id],
- stats_period="14d",
- expand=["sessions"],
- organization_id=organization_id,
- ),
- )
- assert result[0]["sessionCount"] == 2
- # No sessions in project2
- assert result[1]["sessionCount"] is None
- def test_skipped_date_timestamp_filters(self):
- group = self.create_group()
- serializer = StreamGroupSerializerSnuba(
- search_filters=[
- SearchFilter(
- SearchKey("timestamp"),
- ">",
- SearchValue(before_now(hours=1).replace(tzinfo=pytz.UTC)),
- ),
- SearchFilter(
- SearchKey("timestamp"),
- "<",
- SearchValue(before_now(seconds=1).replace(tzinfo=pytz.UTC)),
- ),
- SearchFilter(
- SearchKey("date"),
- ">",
- SearchValue(before_now(hours=1).replace(tzinfo=pytz.UTC)),
- ),
- SearchFilter(
- SearchKey("date"),
- "<",
- SearchValue(before_now(seconds=1).replace(tzinfo=pytz.UTC)),
- ),
- ]
- )
- assert not serializer.conditions
- result = serialize([group], self.user, serializer=serializer)
- assert result[0]["id"] == str(group.id)
|