From beb211c92cc9282030662ea86e41669a94e29bf0 Mon Sep 17 00:00:00 2001 From: Evan Purkhiser Date: Fri, 25 Apr 2025 15:44:10 -0400 Subject: [PATCH] ref(uptime): Read uptime_status from uptime_subscription --- .../endpoints/organization_alert_rule_index.py | 5 ++++- src/sentry/testutils/factories.py | 4 ---- src/sentry/testutils/fixtures.py | 4 ---- src/sentry/uptime/consumers/results_consumer.py | 13 ++++++++----- src/sentry/uptime/endpoints/serializers.py | 2 +- src/sentry/uptime/subscriptions/subscriptions.py | 6 +++--- .../uptime/consumers/test_results_consumer.py | 6 ------ tests/sentry/uptime/endpoints/test_serializers.py | 6 +++--- .../uptime/subscriptions/test_subscriptions.py | 2 +- tests/sentry/uptime/subscriptions/test_tasks.py | 1 - 10 files changed, 20 insertions(+), 29 deletions(-) diff --git a/src/sentry/incidents/endpoints/organization_alert_rule_index.py b/src/sentry/incidents/endpoints/organization_alert_rule_index.py index 18f05ac008033a..6fd2c9807f8e28 100644 --- a/src/sentry/incidents/endpoints/organization_alert_rule_index.py +++ b/src/sentry/incidents/endpoints/organization_alert_rule_index.py @@ -325,7 +325,10 @@ def get(self, request: Request, organization) -> Response: incident_status=Case( # If an uptime monitor is failing we want to treat it the same as if an alert is failing, so sort # by the critical status - When(uptime_status=UptimeStatus.FAILED, then=IncidentStatus.CRITICAL.value), + When( + uptime_subscription__uptime_status=UptimeStatus.FAILED, + then=IncidentStatus.CRITICAL.value, + ), default=-2, ) ) diff --git a/src/sentry/testutils/factories.py b/src/sentry/testutils/factories.py index a97cec94cda1d5..e49c062dff8191 100644 --- a/src/sentry/testutils/factories.py +++ b/src/sentry/testutils/factories.py @@ -2048,8 +2048,6 @@ def create_project_uptime_subscription( mode: ProjectUptimeSubscriptionMode, name: str | None, owner: Actor | None, - uptime_status: UptimeStatus, - uptime_status_update_date: datetime, id: int | None, ): if name is None: @@ -2071,8 +2069,6 @@ def create_project_uptime_subscription( name=name, owner_team_id=owner_team_id, owner_user_id=owner_user_id, - uptime_status=uptime_status, - uptime_status_update_date=uptime_status_update_date, pk=id, ) diff --git a/src/sentry/testutils/fixtures.py b/src/sentry/testutils/fixtures.py index 461d50642cd837..4a316c56641a89 100644 --- a/src/sentry/testutils/fixtures.py +++ b/src/sentry/testutils/fixtures.py @@ -771,8 +771,6 @@ def create_project_uptime_subscription( project = self.project if env is None: env = self.environment - if uptime_status_update_date is None: - uptime_status_update_date = timezone.now() if uptime_subscription is None: uptime_subscription = self.create_uptime_subscription( @@ -787,8 +785,6 @@ def create_project_uptime_subscription( mode, name, Actor.from_object(owner) if owner else None, - uptime_status, - uptime_status_update_date, id, ) # TODO(epurkhiser): Dual create a detector as well, can be removed diff --git a/src/sentry/uptime/consumers/results_consumer.py b/src/sentry/uptime/consumers/results_consumer.py index 8471a1b09bce1d..0e4fc4b4c1711b 100644 --- a/src/sentry/uptime/consumers/results_consumer.py +++ b/src/sentry/uptime/consumers/results_consumer.py @@ -186,10 +186,12 @@ def produce_snuba_uptime_result( result: The check result to be sent to Snuba """ try: + uptime_subscription = project_subscription.uptime_subscription project = project_subscription.project + retention_days = quotas.backend.get_event_retention(organization=project.organization) or 90 - if project_subscription.uptime_status == UptimeStatus.FAILED: + if uptime_subscription.uptime_status == UptimeStatus.FAILED: incident_status = IncidentStatus.IN_INCIDENT else: incident_status = IncidentStatus.NO_INCIDENT @@ -300,7 +302,8 @@ def handle_active_result( result: CheckResult, metric_tags: dict[str, str], ): - uptime_status = project_subscription.uptime_status + uptime_subscription = project_subscription.uptime_subscription + uptime_status = uptime_subscription.uptime_status result_status = result["status"] redis = _get_cluster() @@ -322,7 +325,7 @@ def handle_active_result( restricted_host_provider_ids = options.get( "uptime.restrict-issue-creation-by-hosting-provider-id" ) - host_provider_id = project_subscription.uptime_subscription.host_provider_id + host_provider_id = uptime_subscription.host_provider_id issue_creation_restricted_by_provider = host_provider_id in restricted_host_provider_ids if issue_creation_restricted_by_provider: @@ -346,7 +349,7 @@ def handle_active_result( "uptime_active_sent_occurrence", extra={ "project_id": project_subscription.project_id, - "url": project_subscription.uptime_subscription.url, + "url": uptime_subscription.url, **result, }, ) @@ -378,7 +381,7 @@ def handle_active_result( "uptime_active_resolved", extra={ "project_id": project_subscription.project_id, - "url": project_subscription.uptime_subscription.url, + "url": uptime_subscription.url, **result, }, ) diff --git a/src/sentry/uptime/endpoints/serializers.py b/src/sentry/uptime/endpoints/serializers.py index 94f32a5e6103ba..e2f747e9ab2390 100644 --- a/src/sentry/uptime/endpoints/serializers.py +++ b/src/sentry/uptime/endpoints/serializers.py @@ -64,7 +64,7 @@ def serialize( "environment": obj.environment.name if obj.environment else None, "name": obj.name or f"Uptime Monitoring for {obj.uptime_subscription.url}", "status": obj.get_status_display(), - "uptimeStatus": obj.uptime_status, + "uptimeStatus": obj.uptime_subscription.uptime_status, "mode": obj.mode, "url": obj.uptime_subscription.url, "headers": obj.uptime_subscription.headers, diff --git a/src/sentry/uptime/subscriptions/subscriptions.py b/src/sentry/uptime/subscriptions/subscriptions.py index 2bceb52c122da6..453fba1885da0f 100644 --- a/src/sentry/uptime/subscriptions/subscriptions.py +++ b/src/sentry/uptime/subscriptions/subscriptions.py @@ -345,15 +345,15 @@ def disable_uptime_detector(detector: Detector): also be disabled. """ uptime_monitor = get_project_subscription(detector) + uptime_subscription = uptime_monitor.uptime_subscription + if uptime_monitor.status == ObjectStatus.DISABLED: return - if uptime_monitor.uptime_status == UptimeStatus.FAILED: + if uptime_subscription.uptime_status == UptimeStatus.FAILED: # Resolve the issue so that we don't see it in the ui anymore resolve_uptime_issue(uptime_monitor) - uptime_subscription = uptime_monitor.uptime_subscription - uptime_monitor.update( status=ObjectStatus.DISABLED, # We set the status back to ok here so that if we re-enable we'll start diff --git a/tests/sentry/uptime/consumers/test_results_consumer.py b/tests/sentry/uptime/consumers/test_results_consumer.py index 14374f9ef56800..37bd6947278e4e 100644 --- a/tests/sentry/uptime/consumers/test_results_consumer.py +++ b/tests/sentry/uptime/consumers/test_results_consumer.py @@ -156,7 +156,6 @@ def test(self): assignee = group.get_assignee() assert assignee and (assignee.id == self.user.id) self.project_subscription.refresh_from_db() - assert self.project_subscription.uptime_status == UptimeStatus.FAILED assert self.project_subscription.uptime_subscription.uptime_status == UptimeStatus.FAILED def test_does_nothing_when_missing_project_subscription(self): @@ -221,7 +220,6 @@ def test_restricted_host_provider_id(self): # subscription status is still updated self.project_subscription.refresh_from_db() - assert self.project_subscription.uptime_status == UptimeStatus.FAILED assert self.project_subscription.uptime_subscription.uptime_status == UptimeStatus.FAILED def test_reset_fail_count(self): @@ -318,7 +316,6 @@ def test_reset_fail_count(self): with pytest.raises(Group.DoesNotExist): Group.objects.get(grouphash__hash=hashed_fingerprint) self.project_subscription.refresh_from_db() - assert self.project_subscription.uptime_status == UptimeStatus.OK assert self.project_subscription.uptime_subscription.uptime_status == UptimeStatus.OK def test_no_create_issues_feature(self): @@ -351,7 +348,6 @@ def test_no_create_issues_feature(self): with pytest.raises(Group.DoesNotExist): Group.objects.get(grouphash__hash=hashed_fingerprint) self.project_subscription.refresh_from_db() - assert self.project_subscription.uptime_status == UptimeStatus.FAILED assert self.project_subscription.uptime_subscription.uptime_status == UptimeStatus.FAILED def test_resolve(self): @@ -412,7 +408,6 @@ def test_resolve(self): assert group.issue_type == UptimeDomainCheckFailure assert group.status == GroupStatus.UNRESOLVED self.project_subscription.refresh_from_db() - assert self.project_subscription.uptime_status == UptimeStatus.FAILED assert self.project_subscription.uptime_subscription.uptime_status == UptimeStatus.FAILED result = self.create_uptime_result( @@ -443,7 +438,6 @@ def test_resolve(self): group.refresh_from_db() assert group.status == GroupStatus.RESOLVED self.project_subscription.refresh_from_db() - assert self.project_subscription.uptime_status == UptimeStatus.OK assert self.project_subscription.uptime_subscription.uptime_status == UptimeStatus.OK def test_no_subscription(self): diff --git a/tests/sentry/uptime/endpoints/test_serializers.py b/tests/sentry/uptime/endpoints/test_serializers.py index b247d796c20261..6bb953c55bc0aa 100644 --- a/tests/sentry/uptime/endpoints/test_serializers.py +++ b/tests/sentry/uptime/endpoints/test_serializers.py @@ -13,7 +13,7 @@ def test(self): "name": uptime_monitor.name, "environment": uptime_monitor.environment.name if uptime_monitor.environment else None, "status": uptime_monitor.get_status_display(), - "uptimeStatus": uptime_monitor.uptime_status, + "uptimeStatus": uptime_monitor.uptime_subscription.uptime_status, "mode": uptime_monitor.mode, "url": uptime_monitor.uptime_subscription.url, "method": uptime_monitor.uptime_subscription.method, @@ -38,7 +38,7 @@ def test_default_name(self): "name": f"Uptime Monitoring for {uptime_monitor.uptime_subscription.url}", "environment": uptime_monitor.environment.name if uptime_monitor.environment else None, "status": uptime_monitor.get_status_display(), - "uptimeStatus": uptime_monitor.uptime_status, + "uptimeStatus": uptime_monitor.uptime_subscription.uptime_status, "mode": uptime_monitor.mode, "url": uptime_monitor.uptime_subscription.url, "method": uptime_monitor.uptime_subscription.method, @@ -60,7 +60,7 @@ def test_owner(self): "name": uptime_monitor.name, "environment": uptime_monitor.environment.name if uptime_monitor.environment else None, "status": uptime_monitor.get_status_display(), - "uptimeStatus": uptime_monitor.uptime_status, + "uptimeStatus": uptime_monitor.uptime_subscription.uptime_status, "mode": uptime_monitor.mode, "url": uptime_monitor.uptime_subscription.url, "method": uptime_monitor.uptime_subscription.method, diff --git a/tests/sentry/uptime/subscriptions/test_subscriptions.py b/tests/sentry/uptime/subscriptions/test_subscriptions.py index d1398288c80107..f60b17234a523c 100644 --- a/tests/sentry/uptime/subscriptions/test_subscriptions.py +++ b/tests/sentry/uptime/subscriptions/test_subscriptions.py @@ -759,7 +759,7 @@ def test_disable_failed(self, mock_remove_seat): proj_sub.refresh_from_db() assert proj_sub.status == ObjectStatus.DISABLED - assert proj_sub.uptime_status == UptimeStatus.OK + assert proj_sub.uptime_subscription.uptime_status == UptimeStatus.OK assert proj_sub.uptime_subscription.status == UptimeSubscription.Status.DISABLED.value mock_remove_seat.assert_called_with(DataCategory.UPTIME, proj_sub) diff --git a/tests/sentry/uptime/subscriptions/test_tasks.py b/tests/sentry/uptime/subscriptions/test_tasks.py index 904d8786fdf271..736505439ca545 100644 --- a/tests/sentry/uptime/subscriptions/test_tasks.py +++ b/tests/sentry/uptime/subscriptions/test_tasks.py @@ -523,7 +523,6 @@ def run_test( proj_sub.refresh_from_db() assert proj_sub.status == expected_status - assert proj_sub.uptime_status == expected_uptime_status assert proj_sub.uptime_subscription.uptime_status == expected_uptime_status detector = get_detector(proj_sub.uptime_subscription)