|
1 | 1 | import math
|
2 | 2 | import uuid
|
3 |
| -from datetime import timedelta |
| 3 | +from datetime import UTC, timedelta |
4 | 4 | from typing import Any
|
5 | 5 | from unittest import mock
|
6 | 6 |
|
7 | 7 | import pytest
|
| 8 | +from dateutil import parser |
8 | 9 | from django.test import override_settings
|
9 | 10 | from django.urls import reverse
|
10 | 11 | from django.utils import timezone
|
| 12 | +from rest_framework.response import Response |
| 13 | +from sentry_kafka_schemas.schema_types.uptime_results_v1 import CheckStatus, CheckStatusReason |
11 | 14 | from snuba_sdk.column import Column
|
12 | 15 | from snuba_sdk.function import Function
|
13 | 16 |
|
|
35 | 38 | ProfilesSnubaTestCase,
|
36 | 39 | SnubaTestCase,
|
37 | 40 | SpanTestCase,
|
| 41 | + UptimeCheckSnubaTestCase, |
38 | 42 | )
|
39 | 43 | from sentry.testutils.helpers import parse_link_header
|
40 | 44 | from sentry.testutils.helpers.datetime import before_now, freeze_time
|
41 | 45 | from sentry.testutils.helpers.discover import user_misery_formula
|
42 | 46 | from sentry.types.group import GroupSubStatus
|
| 47 | +from sentry.uptime.types import IncidentStatus |
43 | 48 | from sentry.utils import json
|
44 | 49 | from sentry.utils.samples import load_data
|
45 | 50 | from tests.sentry.issues.test_utils import SearchIssueTestMixin
|
@@ -6870,3 +6875,114 @@ def test_remapping(self):
|
6870 | 6875 | assert meta["fields"]["transaction.duration"] == "duration"
|
6871 | 6876 | assert meta["units"]["span.duration"] == "millisecond"
|
6872 | 6877 | assert meta["units"]["transaction.duration"] == "millisecond"
|
| 6878 | + |
| 6879 | + |
| 6880 | +class OrganizationEventsUptimeDatasetEndpointTest( |
| 6881 | + OrganizationEventsEndpointTestBase, UptimeCheckSnubaTestCase |
| 6882 | +): |
| 6883 | + def coerce_response(self, response: Response) -> None: |
| 6884 | + for item in response.data["data"]: |
| 6885 | + for field in ("uptime_subscription_id", "uptime_check_id", "trace_id"): |
| 6886 | + if field in item: |
| 6887 | + item[field] = uuid.UUID(item[field]) |
| 6888 | + |
| 6889 | + for field in ("timestamp", "scheduled_check_time"): |
| 6890 | + if field in item: |
| 6891 | + item[field] = parser.parse(item[field]).replace(tzinfo=UTC) |
| 6892 | + |
| 6893 | + for field in ("duration_ms", "http_status_code"): |
| 6894 | + if field in item: |
| 6895 | + item[field] = int(item[field]) |
| 6896 | + |
| 6897 | + def test_basic(self): |
| 6898 | + subscription_id = uuid.uuid4().hex |
| 6899 | + check_id = uuid.uuid4() |
| 6900 | + self.store_snuba_uptime_check( |
| 6901 | + subscription_id=subscription_id, check_status="success", check_id=check_id |
| 6902 | + ) |
| 6903 | + query = { |
| 6904 | + "field": ["uptime_subscription_id", "uptime_check_id"], |
| 6905 | + "statsPeriod": "2h", |
| 6906 | + "query": "", |
| 6907 | + "dataset": "uptimeChecks", |
| 6908 | + "orderby": ["uptime_subscription_id"], |
| 6909 | + } |
| 6910 | + |
| 6911 | + response = self.do_request(query) |
| 6912 | + self.coerce_response(response) |
| 6913 | + assert response.status_code == 200, response.content |
| 6914 | + assert response.data["data"] == [ |
| 6915 | + { |
| 6916 | + "uptime_subscription_id": uuid.UUID(subscription_id), |
| 6917 | + "uptime_check_id": check_id, |
| 6918 | + } |
| 6919 | + ] |
| 6920 | + |
| 6921 | + def test_all_fields(self): |
| 6922 | + subscription_id = uuid.uuid4().hex |
| 6923 | + check_id = uuid.uuid4() |
| 6924 | + scheduled_check_time = before_now(minutes=5) |
| 6925 | + actual_check_time = before_now(minutes=2) |
| 6926 | + duration_ms = 100 |
| 6927 | + region = "us" |
| 6928 | + check_status: CheckStatus = "failure" |
| 6929 | + check_status_reason: CheckStatusReason = { |
| 6930 | + "type": "timeout", |
| 6931 | + "description": "Request timed out", |
| 6932 | + } |
| 6933 | + http_status = 200 |
| 6934 | + trace_id = uuid.uuid4() |
| 6935 | + environment = "test" |
| 6936 | + self.store_snuba_uptime_check( |
| 6937 | + environment=environment, |
| 6938 | + subscription_id=subscription_id, |
| 6939 | + check_status=check_status, |
| 6940 | + check_id=check_id, |
| 6941 | + incident_status=IncidentStatus.NO_INCIDENT, |
| 6942 | + scheduled_check_time=scheduled_check_time, |
| 6943 | + http_status=http_status, |
| 6944 | + actual_check_time=actual_check_time, |
| 6945 | + duration_ms=duration_ms, |
| 6946 | + region=region, |
| 6947 | + check_status_reason=check_status_reason, |
| 6948 | + trace_id=trace_id, |
| 6949 | + ) |
| 6950 | + |
| 6951 | + query = { |
| 6952 | + "field": [ |
| 6953 | + "environment", |
| 6954 | + "uptime_subscription_id", |
| 6955 | + "uptime_check_id", |
| 6956 | + "scheduled_check_time", |
| 6957 | + "timestamp", |
| 6958 | + "duration_ms", |
| 6959 | + "region", |
| 6960 | + "check_status", |
| 6961 | + "check_status_reason", |
| 6962 | + "http_status_code", |
| 6963 | + "trace_id", |
| 6964 | + ], |
| 6965 | + "statsPeriod": "1h", |
| 6966 | + "query": "", |
| 6967 | + "dataset": "uptimeChecks", |
| 6968 | + } |
| 6969 | + |
| 6970 | + response = self.do_request(query) |
| 6971 | + self.coerce_response(response) |
| 6972 | + assert response.status_code == 200, response.content |
| 6973 | + assert response.data["data"] == [ |
| 6974 | + { |
| 6975 | + "environment": environment, |
| 6976 | + "uptime_subscription_id": uuid.UUID(subscription_id), |
| 6977 | + "uptime_check_id": check_id, |
| 6978 | + "environment": environment, |
| 6979 | + "scheduled_check_time": scheduled_check_time.replace(microsecond=0), |
| 6980 | + "timestamp": actual_check_time, |
| 6981 | + "duration_ms": duration_ms, |
| 6982 | + "region": region, |
| 6983 | + "check_status": check_status, |
| 6984 | + "check_status_reason": check_status_reason["type"], |
| 6985 | + "http_status_code": http_status, |
| 6986 | + "trace_id": trace_id, |
| 6987 | + } |
| 6988 | + ] |
0 commit comments