Beispiel #1
0
def test_massage_no_timeseries():

    query = _make_query(
        "statsPeriod=1d&interval=6h&field=sum(session)&groupby=projects")
    result_totals = [{"sessions": 4}]
    # snuba returns the datetimes as strings for now
    result_timeseries = None

    expected_result = {
        "start":
        "2020-12-17T12:00:00Z",
        "end":
        "2020-12-18T11:15:00Z",
        "query":
        "",
        "intervals": [
            "2020-12-17T12:00:00Z",
            "2020-12-17T18:00:00Z",
            "2020-12-18T00:00:00Z",
            "2020-12-18T06:00:00Z",
        ],
        "groups": [{
            "by": {},
            "totals": {
                "sum(session)": 4
            }
        }],
    }

    actual_result = result_sorted(
        massage_sessions_result(query, result_totals, result_timeseries))

    assert actual_result == expected_result
Beispiel #2
0
def test_nan_duration():
    query = _make_query(
        "statsPeriod=1d&interval=6h&field=avg(session.duration)&field=p50(session.duration)"
    )

    result_totals = [
        {
            "duration_avg":
            math.nan,
            "duration_quantiles":
            [math.inf, math.inf, math.inf, math.inf, math.inf, math.inf],
        },
    ]
    result_timeseries = [
        {
            "duration_avg":
            math.nan,
            "duration_quantiles":
            [math.nan, math.nan, math.nan, math.nan, math.nan, math.nan],
            "bucketed_started":
            "2020-12-17T12:00:00+00:00",
        },
        {
            "duration_avg":
            math.inf,
            "duration_quantiles":
            [math.inf, math.inf, math.inf, math.inf, math.inf, math.inf],
            "bucketed_started":
            "2020-12-18T06:00:00+00:00",
        },
    ]

    expected_result = {
        "query":
        "",
        "intervals": [
            "2020-12-17T12:00:00Z",
            "2020-12-17T18:00:00Z",
            "2020-12-18T00:00:00Z",
            "2020-12-18T06:00:00Z",
        ],
        "groups": [
            {
                "by": {},
                "series": {
                    "avg(session.duration)": [None, None, None, None],
                    "p50(session.duration)": [None, None, None, None],
                },
                "totals": {
                    "avg(session.duration)": None,
                    "p50(session.duration)": None
                },
            },
        ],
    }

    actual_result = result_sorted(
        massage_sessions_result(query, result_totals, result_timeseries))

    assert actual_result == expected_result
Beispiel #3
0
def massage_outcomes_result(
    query: QueryDefinition,
    result_totals: ResultSet,
    result_timeseries: ResultSet,
) -> Dict[str, List[Any]]:
    result: Dict[str, List[Any]] = massage_sessions_result(
        query, result_totals, result_timeseries, ts_col=TS_COL
    )
    del result["query"]
    return result
Beispiel #4
0
def massage_outcomes_result(
    query: QueryDefinition,
    result_totals: ResultSet,
    result_timeseries: Optional[ResultSet],
) -> Dict[str, List[Any]]:
    result: Dict[str, List[Any]] = massage_sessions_result(
        query, result_totals, result_timeseries, ts_col=TS_COL
    )
    if result_timeseries is None:
        del result["intervals"]
    del result["query"]
    return result
Beispiel #5
0
def test_massage_unordered_timeseries():
    query = _make_query("statsPeriod=1d&interval=6h&field=sum(session)")
    result_totals = [{"sessions": 10}]
    # snuba returns the datetimes as strings for now
    result_timeseries = [
        {
            "sessions": 3,
            "bucketed_started": "2020-12-18T00:00:00+00:00"
        },
        {
            "sessions": 2,
            "bucketed_started": "2020-12-17T18:00:00+00:00"
        },
        {
            "sessions": 4,
            "bucketed_started": "2020-12-18T06:00:00+00:00"
        },
        {
            "sessions": 1,
            "bucketed_started": "2020-12-17T12:00:00+00:00"
        },
    ]

    expected_result = {
        "start":
        "2020-12-17T12:00:00Z",
        "end":
        "2020-12-18T11:15:00Z",
        "query":
        "",
        "intervals": [
            "2020-12-17T12:00:00Z",
            "2020-12-17T18:00:00Z",
            "2020-12-18T00:00:00Z",
            "2020-12-18T06:00:00Z",
        ],
        "groups": [{
            "by": {},
            "series": {
                "sum(session)": [1, 2, 3, 4]
            },
            "totals": {
                "sum(session)": 10
            }
        }],
    }

    actual_result = result_sorted(
        massage_sessions_result(query, result_totals, result_timeseries))

    assert actual_result == expected_result
Beispiel #6
0
    def run_sessions_query(
        self,
        org_id: int,
        query: QueryDefinition,
        span_op: str,
    ) -> SessionsQueryResult:
        with sentry_sdk.start_span(op=span_op,
                                   description="run_sessions_query"):
            totals, series = _run_sessions_query(query)

        with sentry_sdk.start_span(op=span_op,
                                   description="massage_sessions_results"):
            return massage_sessions_result(query, totals,
                                           series)  # type: ignore
Beispiel #7
0
    def get(self, request, organization):
        with self.handle_query_errors():
            with sentry_sdk.start_span(op="sessions.endpoint",
                                       description="build_sessions_query"):
                query = self.build_sessions_query(request, organization)

            with sentry_sdk.start_span(op="sessions.endpoint",
                                       description="run_sessions_query"):
                result_totals, result_timeseries = run_sessions_query(query)

            with sentry_sdk.start_span(op="sessions.endpoint",
                                       description="massage_sessions_result"):
                result = massage_sessions_result(query, result_totals,
                                                 result_timeseries)
            return Response(result, status=200)
Beispiel #8
0
def test_massage_empty():
    query = _make_query("statsPeriod=1d&interval=1d&field=sum(session)")

    result_totals = []
    result_timeseries = []

    expected_result = {
        "query": "",
        "intervals": ["2020-12-18T00:00:00Z"],
        "groups": [],
    }

    actual_result = result_sorted(
        massage_sessions_result(query, result_totals, result_timeseries))

    assert actual_result == expected_result
Beispiel #9
0
def test_massage_simple_timeseries():
    """A timeseries is filled up when it only receives partial data"""

    query = _make_query("statsPeriod=1d&interval=6h&field=sum(session)")
    result_totals = [{"sessions": 4}]
    # snuba returns the datetimes as strings for now
    result_timeseries = [
        {
            "sessions": 2,
            "bucketed_started": "2020-12-18T06:00:00+00:00"
        },
        {
            "sessions": 2,
            "bucketed_started": "2020-12-17T12:00:00+00:00"
        },
    ]

    expected_result = {
        "start":
        "2020-12-17T12:00:00Z",
        "end":
        "2020-12-18T11:15:00Z",
        "query":
        "",
        "intervals": [
            "2020-12-17T12:00:00Z",
            "2020-12-17T18:00:00Z",
            "2020-12-18T00:00:00Z",
            "2020-12-18T06:00:00Z",
        ],
        "groups": [{
            "by": {},
            "series": {
                "sum(session)": [2, 0, 0, 2]
            },
            "totals": {
                "sum(session)": 4
            }
        }],
    }

    actual_result = result_sorted(
        massage_sessions_result(query, result_totals, result_timeseries))

    assert actual_result == expected_result
Beispiel #10
0
def test_massage_exact_timeseries():
    query = _make_query(
        "start=2020-12-17T15:12:34Z&end=2020-12-18T11:14:17Z&interval=6h&field=sum(session)"
    )
    result_totals = [{"sessions": 4}]
    result_timeseries = [
        {
            "sessions": 2,
            "bucketed_started": "2020-12-18T06:00:00+00:00"
        },
        {
            "sessions": 2,
            "bucketed_started": "2020-12-17T12:00:00+00:00"
        },
    ]

    expected_result = {
        "start":
        "2020-12-17T12:00:00Z",
        "end":
        "2020-12-18T12:00:00Z",
        "query":
        "",
        "intervals": [
            "2020-12-17T12:00:00Z",
            "2020-12-17T18:00:00Z",
            "2020-12-18T00:00:00Z",
            "2020-12-18T06:00:00Z",
        ],
        "groups": [{
            "by": {},
            "series": {
                "sum(session)": [2, 0, 0, 2]
            },
            "totals": {
                "sum(session)": 4
            }
        }],
    }

    actual_result = result_sorted(
        massage_sessions_result(query, result_totals, result_timeseries))

    assert actual_result == expected_result
Beispiel #11
0
    def run_sessions_query(
        self,
        org_id: int,
        query: QueryDefinition,
        span_op: str,
    ) -> SessionsQueryResult:
        # This is necessary because if we are running against the `DuplexReleaseHealthBackend`, the
        # `query` object gets mutated, and that in turn affects the query results in subsequent
        # backend calls
        query_clone = deepcopy(query)

        with sentry_sdk.start_span(op=span_op,
                                   description="run_sessions_query"):
            totals, series = _run_sessions_query(query_clone)

        with sentry_sdk.start_span(op=span_op,
                                   description="massage_sessions_results"):
            return massage_sessions_result(query_clone, totals,
                                           series)  # type: ignore
Beispiel #12
0
def test_massage_virtual_groupby_timeseries():
    query = _make_query(
        "statsPeriod=1d&interval=6h&field=sum(session)&field=count_unique(user)&groupBy=session.status"
    )
    result_totals = [{
        "users": 1,
        "users_crashed": 1,
        "sessions": 6,
        "sessions_errored": 1,
        "users_errored": 1,
        "sessions_abnormal": 0,
        "sessions_crashed": 1,
        "users_abnormal": 0,
    }]
    # snuba returns the datetimes as strings for now
    result_timeseries = [
        {
            "sessions_errored": 1,
            "users": 1,
            "users_crashed": 1,
            "sessions_abnormal": 0,
            "sessions": 3,
            "users_errored": 1,
            "users_abnormal": 0,
            "sessions_crashed": 1,
            "bucketed_started": "2020-12-18T12:00:00+00:00",
        },
        {
            "sessions_errored": 0,
            "users": 1,
            "users_crashed": 0,
            "sessions_abnormal": 0,
            "sessions": 3,
            "users_errored": 0,
            "users_abnormal": 0,
            "sessions_crashed": 0,
            "bucketed_started": "2020-12-18T06:00:00+00:00",
        },
    ]

    expected_result = {
        "query":
        "",
        "intervals": [
            "2020-12-17T18:00:00Z",
            "2020-12-18T00:00:00Z",
            "2020-12-18T06:00:00Z",
            "2020-12-18T12:00:00Z",
        ],
        "groups": [
            {
                "by": {
                    "session.status": "abnormal"
                },
                "series": {
                    "count_unique(user)": [0, 0, 0, 0],
                    "sum(session)": [0, 0, 0, 0]
                },
                "totals": {
                    "count_unique(user)": 0,
                    "sum(session)": 0
                },
            },
            {
                "by": {
                    "session.status": "crashed"
                },
                "series": {
                    "count_unique(user)": [0, 0, 0, 1],
                    "sum(session)": [0, 0, 0, 1]
                },
                "totals": {
                    "count_unique(user)": 1,
                    "sum(session)": 1
                },
            },
            {
                "by": {
                    "session.status": "errored"
                },
                "series": {
                    "count_unique(user)": [0, 0, 0, 1],
                    "sum(session)": [0, 0, 0, 1]
                },
                "totals": {
                    "count_unique(user)": 1,
                    "sum(session)": 1
                },
            },
            {
                "by": {
                    "session.status": "healthy"
                },
                "series": {
                    "count_unique(user)": [0, 0, 1, 0],
                    "sum(session)": [0, 0, 3, 2]
                },
                # while in one of the time slots, we have a healthy user, it is
                # the *same* user as the one experiencing a crash later on,
                # so in the *whole* time window, that one user is not counted as healthy,
                # so the `0` here is expected, as thats an example of the `count_unique` behavior.
                "totals": {
                    "count_unique(user)": 0,
                    "sum(session)": 5
                },
            },
        ],
    }

    actual_result = result_sorted(
        massage_sessions_result(query, result_totals, result_timeseries))

    assert actual_result == expected_result
Beispiel #13
0
def test_massage_groupby_timeseries():
    query = _make_query(
        "statsPeriod=1d&interval=6h&field=sum(session)&groupBy=release")

    result_totals = [
        {
            "release": "test-example-release",
            "sessions": 4
        },
        {
            "release": "test-example-release-2",
            "sessions": 1
        },
    ]
    # snuba returns the datetimes as strings for now
    result_timeseries = [
        {
            "release": "test-example-release",
            "sessions": 2,
            "bucketed_started": "2020-12-17T12:00:00+00:00",
        },
        {
            "release": "test-example-release",
            "sessions": 2,
            "bucketed_started": "2020-12-18T06:00:00+00:00",
        },
        {
            "release": "test-example-release-2",
            "sessions": 1,
            "bucketed_started": "2020-12-18T06:00:00+00:00",
        },
    ]

    expected_result = {
        "query":
        "",
        "intervals": [
            "2020-12-17T12:00:00Z",
            "2020-12-17T18:00:00Z",
            "2020-12-18T00:00:00Z",
            "2020-12-18T06:00:00Z",
        ],
        "groups": [
            {
                "by": {
                    "release": "test-example-release"
                },
                "series": {
                    "sum(session)": [2, 0, 0, 2]
                },
                "totals": {
                    "sum(session)": 4
                },
            },
            {
                "by": {
                    "release": "test-example-release-2"
                },
                "series": {
                    "sum(session)": [0, 0, 0, 1]
                },
                "totals": {
                    "sum(session)": 1
                },
            },
        ],
    }

    actual_result = result_sorted(
        massage_sessions_result(query, result_totals, result_timeseries))

    assert actual_result == expected_result
Beispiel #14
0
def test_clamping_in_massage_sessions_results_with_groupby_timeseries():
    query = _make_query(
        "statsPeriod=12h&interval=6h&field=sum(session)&field=count_unique(user)&groupBy=session.status"
    )
    # snuba returns the datetimes as strings for now
    result_timeseries = [
        {
            "sessions": 7,
            "sessions_errored": 3,
            "sessions_crashed": 2,
            "sessions_abnormal": 2,
            "users": 7,
            "users_errored": 3,
            "users_crashed": 2,
            "users_abnormal": 2,
            "bucketed_started": "2020-12-18T12:00:00+00:00",
        },
        {
            "sessions": 5,
            "sessions_errored": 10,
            "sessions_crashed": 0,
            "sessions_abnormal": 0,
            "users": 5,
            "users_errored": 10,
            "users_crashed": 0,
            "users_abnormal": 0,
            "bucketed_started": "2020-12-18T06:00:00+00:00",
        },
    ]
    expected_result = {
        "start":
        "2020-12-18T06:00:00Z",
        "end":
        "2020-12-18T13:26:00Z",
        "query":
        "",
        "intervals": [
            "2020-12-18T06:00:00Z",
            "2020-12-18T12:00:00Z",
        ],
        "groups": [
            {
                "by": {
                    "session.status": "abnormal"
                },
                "series": {
                    "count_unique(user)": [0, 2],
                    "sum(session)": [0, 2]
                },
                "totals": {
                    "count_unique(user)": 0,
                    "sum(session)": 0
                },
            },
            {
                "by": {
                    "session.status": "crashed"
                },
                "series": {
                    "count_unique(user)": [0, 2],
                    "sum(session)": [0, 2]
                },
                "totals": {
                    "count_unique(user)": 0,
                    "sum(session)": 0
                },
            },
            {
                "by": {
                    "session.status": "errored"
                },
                "series": {
                    "count_unique(user)": [10, 0],
                    "sum(session)": [10, 0]
                },
                "totals": {
                    "count_unique(user)": 0,
                    "sum(session)": 0
                },
            },
            {
                "by": {
                    "session.status": "healthy"
                },
                "series": {
                    "count_unique(user)": [0, 4],
                    "sum(session)": [0, 4]
                },
                "totals": {
                    "count_unique(user)": 0,
                    "sum(session)": 0
                },
            },
        ],
    }

    actual_result = result_sorted(
        massage_sessions_result(query, [], result_timeseries))

    assert actual_result == expected_result
Beispiel #15
0
def test_massage_unbalanced_results():
    query = _make_query(
        "statsPeriod=1d&interval=1d&field=sum(session)&groupBy=release")

    result_totals = [
        {
            "release": "test-example-release",
            "sessions": 1
        },
    ]
    result_timeseries = []

    expected_result = {
        "start":
        "2020-12-18T00:00:00Z",
        "end":
        "2020-12-18T11:15:00Z",
        "query":
        "",
        "intervals": ["2020-12-18T00:00:00Z"],
        "groups": [{
            "by": {
                "release": "test-example-release"
            },
            "series": {
                "sum(session)": [0]
            },
            "totals": {
                "sum(session)": 1
            },
        }],
    }

    actual_result = result_sorted(
        massage_sessions_result(query, result_totals, result_timeseries))

    assert actual_result == expected_result

    result_totals = []
    result_timeseries = [
        {
            "release": "test-example-release",
            "sessions": 1,
            "bucketed_started": "2020-12-18T00:00:00+00:00",
        },
    ]

    expected_result = {
        "start":
        "2020-12-18T00:00:00Z",
        "end":
        "2020-12-18T11:15:00Z",
        "query":
        "",
        "intervals": ["2020-12-18T00:00:00Z"],
        "groups": [{
            "by": {
                "release": "test-example-release"
            },
            "series": {
                "sum(session)": [1]
            },
            "totals": {
                "sum(session)": 0
            },
        }],
    }

    actual_result = result_sorted(
        massage_sessions_result(query, result_totals, result_timeseries))

    assert actual_result == expected_result