|
@@ -1,5 +1,8 @@
|
|
|
import math
|
|
|
+import pytest
|
|
|
+import pytz
|
|
|
|
|
|
+from datetime import datetime
|
|
|
from freezegun import freeze_time
|
|
|
from django.http import QueryDict
|
|
|
|
|
@@ -8,11 +11,13 @@ from sentry.snuba.sessions_v2 import (
|
|
|
QueryDefinition,
|
|
|
massage_sessions_result,
|
|
|
_get_timestamps,
|
|
|
+ InvalidParams,
|
|
|
+ _get_constrained_date_range,
|
|
|
)
|
|
|
|
|
|
|
|
|
-def _make_query(qs):
|
|
|
- return QueryDefinition(QueryDict(qs), {})
|
|
|
+def _make_query(qs, allow_minute_resolution=True):
|
|
|
+ return QueryDefinition(QueryDict(qs), {}, allow_minute_resolution)
|
|
|
|
|
|
|
|
|
def result_sorted(result):
|
|
@@ -25,6 +30,85 @@ def result_sorted(result):
|
|
|
return result
|
|
|
|
|
|
|
|
|
+@freeze_time("2018-12-11 03:21:34")
|
|
|
+def test_round_range():
|
|
|
+ start, end, interval = _get_constrained_date_range({"statsPeriod": "2d"})
|
|
|
+ assert start == datetime(2018, 12, 9, 4, tzinfo=pytz.utc)
|
|
|
+ assert end == datetime(2018, 12, 11, 4, tzinfo=pytz.utc)
|
|
|
+
|
|
|
+ start, end, interval = _get_constrained_date_range({"statsPeriod": "2d", "interval": "1d"})
|
|
|
+ assert start == datetime(2018, 12, 10, tzinfo=pytz.utc)
|
|
|
+ assert end == datetime(2018, 12, 12, tzinfo=pytz.utc)
|
|
|
+
|
|
|
+
|
|
|
+def test_invalid_interval():
|
|
|
+ with pytest.raises(InvalidParams):
|
|
|
+ start, end, interval = _get_constrained_date_range({"interval": "0d"})
|
|
|
+
|
|
|
+
|
|
|
+def test_round_exact():
|
|
|
+ start, end, interval = _get_constrained_date_range(
|
|
|
+ {"start": "2021-01-12T04:06:16", "end": "2021-01-17T08:26:13", "interval": "1d"},
|
|
|
+ )
|
|
|
+ assert start == datetime(2021, 1, 12, tzinfo=pytz.utc)
|
|
|
+ assert end == datetime(2021, 1, 18, tzinfo=pytz.utc)
|
|
|
+
|
|
|
+
|
|
|
+def test_inclusive_end():
|
|
|
+ start, end, interval = _get_constrained_date_range(
|
|
|
+ {"start": "2021-02-24T00:00:00", "end": "2021-02-25T00:00:00", "interval": "1h"},
|
|
|
+ )
|
|
|
+ assert start == datetime(2021, 2, 24, tzinfo=pytz.utc)
|
|
|
+ assert end == datetime(2021, 2, 25, 1, tzinfo=pytz.utc)
|
|
|
+
|
|
|
+
|
|
|
+@freeze_time("2021-03-05T11:14:17.105Z")
|
|
|
+def test_interval_restrictions():
|
|
|
+ # making sure intervals are cleanly divisible
|
|
|
+ with pytest.raises(InvalidParams, match="The interval has to be less than one day."):
|
|
|
+ _make_query("statsPeriod=4d&interval=2d&field=sum(session)")
|
|
|
+ with pytest.raises(
|
|
|
+ InvalidParams, match="The interval should divide one day without a remainder."
|
|
|
+ ):
|
|
|
+ _make_query("statsPeriod=6h&interval=59m&field=sum(session)")
|
|
|
+ with pytest.raises(
|
|
|
+ InvalidParams, match="The interval should divide one day without a remainder."
|
|
|
+ ):
|
|
|
+ _make_query("statsPeriod=4d&interval=5h&field=sum(session)")
|
|
|
+
|
|
|
+ _make_query("statsPeriod=6h&interval=90m&field=sum(session)")
|
|
|
+ with pytest.raises(
|
|
|
+ InvalidParams,
|
|
|
+ match="The interval has to be a multiple of the minimum interval of one hour.",
|
|
|
+ ):
|
|
|
+ _make_query("statsPeriod=6h&interval=90m&field=sum(session)", False)
|
|
|
+
|
|
|
+ with pytest.raises(
|
|
|
+ InvalidParams,
|
|
|
+ match="The interval has to be a multiple of the minimum interval of one minute.",
|
|
|
+ ):
|
|
|
+ _make_query("statsPeriod=1h&interval=90s&field=sum(session)")
|
|
|
+
|
|
|
+ # restrictions for minute resolution time range
|
|
|
+ with pytest.raises(
|
|
|
+ InvalidParams,
|
|
|
+ match="The time-range when using one-minute resolution intervals is restricted to 6 hours.",
|
|
|
+ ):
|
|
|
+ _make_query("statsPeriod=7h&interval=15m&field=sum(session)")
|
|
|
+ with pytest.raises(
|
|
|
+ InvalidParams,
|
|
|
+ match="The time-range when using one-minute resolution intervals is restricted to the last 30 days.",
|
|
|
+ ):
|
|
|
+ _make_query(
|
|
|
+ "start=2021-01-05T11:14:17&end=2021-01-05T12:14:17&interval=15m&field=sum(session)"
|
|
|
+ )
|
|
|
+
|
|
|
+ with pytest.raises(
|
|
|
+ InvalidParams, match="Your interval and date range would create too many results."
|
|
|
+ ):
|
|
|
+ _make_query("statsPeriod=90d&interval=1h&field=sum(session)")
|
|
|
+
|
|
|
+
|
|
|
@freeze_time("2020-12-18T11:14:17.105Z")
|
|
|
def test_timestamps():
|
|
|
query = _make_query("statsPeriod=1d&interval=12h&field=sum(session)")
|
|
@@ -35,6 +119,63 @@ def test_timestamps():
|
|
|
assert actual_timestamps == expected_timestamps
|
|
|
|
|
|
|
|
|
+@freeze_time("2021-03-08T09:34:00.000Z")
|
|
|
+def test_hourly_rounded_start():
|
|
|
+ query = _make_query("statsPeriod=30m&interval=1m&field=sum(session)")
|
|
|
+
|
|
|
+ actual_timestamps = _get_timestamps(query)
|
|
|
+
|
|
|
+ assert actual_timestamps[0] == "2021-03-08T09:00:00Z"
|
|
|
+ assert len(actual_timestamps) == 60
|
|
|
+
|
|
|
+ # in this case "45m" means from 08:49:00-09:34:00, but since we round start/end
|
|
|
+ # to hours, we extend the start time to 08:00:00.
|
|
|
+ query = _make_query("statsPeriod=45m&interval=1m&field=sum(session)")
|
|
|
+
|
|
|
+ actual_timestamps = _get_timestamps(query)
|
|
|
+
|
|
|
+ assert actual_timestamps[0] == "2021-03-08T08:00:00Z"
|
|
|
+ assert len(actual_timestamps) == 120
|
|
|
+
|
|
|
+
|
|
|
+def test_rounded_end():
|
|
|
+ query = _make_query(
|
|
|
+ "field=sum(session)&interval=1h&start=2021-02-24T00:00:00Z&end=2021-02-25T00:00:00Z"
|
|
|
+ )
|
|
|
+
|
|
|
+ expected_timestamps = [
|
|
|
+ "2021-02-24T00:00:00Z",
|
|
|
+ "2021-02-24T01:00:00Z",
|
|
|
+ "2021-02-24T02:00:00Z",
|
|
|
+ "2021-02-24T03:00:00Z",
|
|
|
+ "2021-02-24T04:00:00Z",
|
|
|
+ "2021-02-24T05:00:00Z",
|
|
|
+ "2021-02-24T06:00:00Z",
|
|
|
+ "2021-02-24T07:00:00Z",
|
|
|
+ "2021-02-24T08:00:00Z",
|
|
|
+ "2021-02-24T09:00:00Z",
|
|
|
+ "2021-02-24T10:00:00Z",
|
|
|
+ "2021-02-24T11:00:00Z",
|
|
|
+ "2021-02-24T12:00:00Z",
|
|
|
+ "2021-02-24T13:00:00Z",
|
|
|
+ "2021-02-24T14:00:00Z",
|
|
|
+ "2021-02-24T15:00:00Z",
|
|
|
+ "2021-02-24T16:00:00Z",
|
|
|
+ "2021-02-24T17:00:00Z",
|
|
|
+ "2021-02-24T18:00:00Z",
|
|
|
+ "2021-02-24T19:00:00Z",
|
|
|
+ "2021-02-24T20:00:00Z",
|
|
|
+ "2021-02-24T21:00:00Z",
|
|
|
+ "2021-02-24T22:00:00Z",
|
|
|
+ "2021-02-24T23:00:00Z",
|
|
|
+ "2021-02-25T00:00:00Z",
|
|
|
+ ]
|
|
|
+ actual_timestamps = _get_timestamps(query)
|
|
|
+
|
|
|
+ assert len(actual_timestamps) == 25
|
|
|
+ assert actual_timestamps == expected_timestamps
|
|
|
+
|
|
|
+
|
|
|
def test_simple_query():
|
|
|
query = _make_query("statsPeriod=1d&interval=12h&field=sum(session)")
|
|
|
|