Просмотр исходного кода

feat(discover-snql): Add a check for retention (#27968)

- This checks that the start & end params are within retention and
  throws an error if they aren't
  - Mostly copied code from utils/snuba
William Mak 3 лет назад
Родитель
Сommit
0043929b50
2 измененных файлов с 22 добавлено и 3 удалено
  1. 11 2
      src/sentry/search/events/filter.py
  2. 11 1
      tests/sentry/search/events/test_builder.py

+ 11 - 2
src/sentry/search/events/filter.py

@@ -20,7 +20,7 @@ from sentry.api.event_search import (
 from sentry.api.release_search import INVALID_SEMVER_MESSAGE
 from sentry.constants import SEMVER_FAKE_PACKAGE
 from sentry.exceptions import InvalidSearchQuery
-from sentry.models import Project, Release, SemverFilter
+from sentry.models import Organization, Project, Release, SemverFilter
 from sentry.models.group import Group
 from sentry.search.events.constants import (
     ARRAY_FIELDS,
@@ -51,13 +51,14 @@ from sentry.search.events.fields import FIELD_ALIASES, FUNCTIONS, QueryFields, r
 from sentry.search.events.types import ParamsType, WhereType
 from sentry.search.utils import parse_release
 from sentry.utils.compat import filter
-from sentry.utils.dates import to_timestamp
+from sentry.utils.dates import outside_retention_with_modified_start, to_timestamp
 from sentry.utils.snuba import (
     FUNCTION_TO_OPERATOR,
     OPERATOR_TO_FUNCTION,
     SNUBA_AND,
     SNUBA_OR,
     Dataset,
+    QueryOutsideRetentionError,
 )
 from sentry.utils.validators import INVALID_EVENT_DETAILS
 
@@ -1214,6 +1215,10 @@ class QueryFilter(QueryFields):
         if "start" not in self.params or "end" not in self.params:
             raise InvalidSearchQuery("Cannot query without a valid date range")
         start, end = self.params["start"], self.params["end"]
+        # Update start to be within retention
+        expired, start = outside_retention_with_modified_start(
+            start, end, Organization(self.params.get("organization_id"))
+        )
 
         # TODO: this validation should be done when we create the params dataclass instead
         assert isinstance(start, datetime) and isinstance(
@@ -1222,6 +1227,10 @@ class QueryFilter(QueryFields):
         assert all(
             isinstance(project_id, int) for project_id in self.params.get("project_id", [])
         ), "All project id params must be ints"
+        if expired:
+            raise QueryOutsideRetentionError(
+                "Invalid date range. Please try a more recent date range."
+            )
 
         conditions.append(Condition(self.column("timestamp"), Op.GTE, start))
         conditions.append(Condition(self.column("timestamp"), Op.LT, end))

+ 11 - 1
tests/sentry/search/events/test_builder.py

@@ -10,7 +10,7 @@ from snuba_sdk.orderby import Direction, OrderBy
 from sentry.exceptions import InvalidSearchQuery
 from sentry.search.events.builder import QueryBuilder
 from sentry.testutils.cases import TestCase
-from sentry.utils.snuba import Dataset
+from sentry.utils.snuba import Dataset, QueryOutsideRetentionError
 
 
 class QueryBuilderTest(TestCase):
@@ -318,3 +318,13 @@ class QueryBuilderTest(TestCase):
                 ),
             ],
         )
+
+    def test_retention(self):
+        with self.options({"system.event-retention-days": 10}):
+            with self.assertRaises(QueryOutsideRetentionError):
+                QueryBuilder(
+                    Dataset.Discover,
+                    self.params,
+                    "",
+                    selected_columns=[],
+                )