test_metrics_sessions_v2.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. from datetime import timedelta
  2. import pytest
  3. from django.urls import reverse
  4. from django.utils import timezone
  5. from snuba_sdk import Column, Condition, Function, Op
  6. from sentry.exceptions import InvalidParams
  7. from sentry.release_health.metrics_sessions_v2 import (
  8. SessionStatus,
  9. _extract_status_filter_from_conditions,
  10. )
  11. from sentry.testutils.cases import APITestCase, SnubaTestCase
  12. from sentry.testutils.helpers.datetime import freeze_time
  13. pytestmark = pytest.mark.sentry_metrics
  14. ONE_DAY_AGO = timezone.now() - timedelta(days=1)
  15. MOCK_DATETIME = ONE_DAY_AGO.replace(hour=10, minute=0, second=0, microsecond=0)
  16. @freeze_time(MOCK_DATETIME)
  17. class MetricsSessionsV2Test(APITestCase, SnubaTestCase):
  18. def setUp(self):
  19. super().setUp()
  20. self.setup_fixture()
  21. def setup_fixture(self):
  22. self.organization1 = self.organization
  23. self.project1 = self.project
  24. self.project2 = self.create_project(
  25. name="teletubbies", slug="teletubbies", teams=[self.team], fire_project_created=True
  26. )
  27. self.release1 = self.create_release(project=self.project1, version="hello")
  28. self.release2 = self.create_release(project=self.project1, version="hola")
  29. self.release3 = self.create_release(project=self.project2, version="hallo")
  30. self.environment1 = self.create_environment(self.project1, name="development")
  31. self.environment2 = self.create_environment(self.project1, name="production")
  32. self.environment3 = self.create_environment(self.project2, name="testing")
  33. def do_request(self, query, user=None, org=None):
  34. self.login_as(user=user or self.user)
  35. url = reverse(
  36. "sentry-api-0-organization-sessions",
  37. kwargs={"organization_id_or_slug": (org or self.organization1).slug},
  38. )
  39. return self.client.get(url, query, format="json")
  40. def get_sessions_data(self, groupby: list[str], interval):
  41. response = self.do_request(
  42. {
  43. "organization_id_or_slug": [self.organization1],
  44. "project": [self.project1.id],
  45. "field": ["sum(session)"],
  46. "groupBy": groupby,
  47. "interval": interval,
  48. }
  49. )
  50. assert response.status_code == 200
  51. return response.data
  52. @pytest.mark.parametrize(
  53. "input, expected_output, expected_status_filter",
  54. [
  55. (
  56. [
  57. Condition(Column("release"), Op.EQ, "foo"),
  58. Condition(Column("session.status"), Op.IN, ["abnormal", "errored"]),
  59. ],
  60. [Condition(Column("release"), Op.EQ, "foo")],
  61. {SessionStatus.ABNORMAL, SessionStatus.ERRORED},
  62. ),
  63. (
  64. [
  65. Condition(Column("release"), Op.EQ, "foo"),
  66. Condition(Column("session.status"), Op.EQ, "bogus"),
  67. ],
  68. [Condition(Column("release"), Op.EQ, "foo")],
  69. frozenset(),
  70. ),
  71. (
  72. [
  73. Condition(Column("release"), Op.EQ, "foo"),
  74. Condition(Column("session.status"), Op.NEQ, "abnormal"),
  75. ],
  76. [Condition(Column("release"), Op.EQ, "foo")],
  77. {SessionStatus.HEALTHY, SessionStatus.ERRORED, SessionStatus.CRASHED},
  78. ),
  79. (
  80. [
  81. Condition(Column("release"), Op.EQ, "foo"),
  82. Condition(Column("session.status"), Op.NOT_IN, ["abnormal", "bogus"]),
  83. ],
  84. [Condition(Column("release"), Op.EQ, "foo")],
  85. {SessionStatus.HEALTHY, SessionStatus.ERRORED, SessionStatus.CRASHED},
  86. ),
  87. (
  88. [
  89. Condition(Column("session.status"), Op.EQ, "abnormal"),
  90. Condition(Column("session.status"), Op.EQ, "errored"),
  91. ],
  92. [],
  93. frozenset(),
  94. ),
  95. ],
  96. )
  97. def test_transform_conditions(input, expected_output, expected_status_filter):
  98. output, status_filter = _extract_status_filter_from_conditions(input)
  99. assert output == expected_output
  100. assert status_filter == expected_status_filter
  101. @pytest.mark.parametrize("input", [[Condition(Column("release"), Op.EQ, "foo")]])
  102. def test_transform_conditions_nochange(input):
  103. output, status_filter = _extract_status_filter_from_conditions(input)
  104. assert input == output
  105. assert status_filter is None
  106. @pytest.mark.parametrize(
  107. "input",
  108. [
  109. [
  110. Condition(
  111. Function(
  112. "or",
  113. [
  114. Function("equals", ["release", "foo"]),
  115. Function("equals", ["session.status", "foo"]),
  116. ],
  117. ),
  118. Op.EQ,
  119. 1,
  120. )
  121. ],
  122. ],
  123. )
  124. def test_transform_conditions_illegal(input):
  125. pytest.raises(InvalidParams, _extract_status_filter_from_conditions, input)