From 3d276e878a4eb9b293201c33731c356154ed6580 Mon Sep 17 00:00:00 2001 From: Cathy Teng <70817427+cathyteng17@users.noreply.github.com> Date: Thu, 15 Dec 2022 09:25:13 -0800 Subject: [PATCH 1/2] update monitor tests --- .../api/endpoints/test_monitor_checkins.py | 10 ++++++ .../api/endpoints/test_monitor_details.py | 32 +++++++++---------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/tests/sentry/api/endpoints/test_monitor_checkins.py b/tests/sentry/api/endpoints/test_monitor_checkins.py index 117458e749953e..a30566cf51c862 100644 --- a/tests/sentry/api/endpoints/test_monitor_checkins.py +++ b/tests/sentry/api/endpoints/test_monitor_checkins.py @@ -166,3 +166,13 @@ def test_with_dsn_auth_invalid_project(self): ) assert resp.status_code == 400, resp.content + + def test_mismatched_org_slugs(self): + monitor = self._create_monitor() + path = f"/api/0/monitors/asdf/{monitor.guid}/checkins/" + self.login_as(user=self.user) + + with self.feature("organizations:monitors"): + resp = self.client.post(path) + + assert resp.status_code == 400 diff --git a/tests/sentry/api/endpoints/test_monitor_details.py b/tests/sentry/api/endpoints/test_monitor_details.py index 387b268e0d6d04..7801716a1899dd 100644 --- a/tests/sentry/api/endpoints/test_monitor_details.py +++ b/tests/sentry/api/endpoints/test_monitor_details.py @@ -15,7 +15,7 @@ def test_simple(self): self.login_as(user=self.user) monitor = self._create_monitor() - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): for path_func in self._get_path_functions(): path = path_func(monitor) resp = self.client.get(path) @@ -47,7 +47,7 @@ def setUp(self): def test_name(self): monitor = self._create_monitor() - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): for i, path_func in enumerate(self._get_path_functions()): monitor = self._create_monitor() path = path_func(monitor) @@ -60,7 +60,7 @@ def test_name(self): assert monitor.name == f"Monitor Name {i}" def test_can_disable(self): - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): for path_func in self._get_path_functions(): monitor = self._create_monitor() path = path_func(monitor) @@ -73,7 +73,7 @@ def test_can_disable(self): assert monitor.status == MonitorStatus.DISABLED def test_can_enable(self): - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): for path_func in self._get_path_functions(): monitor = self._create_monitor() path = path_func(monitor) @@ -89,7 +89,7 @@ def test_can_enable(self): assert monitor.status == MonitorStatus.ACTIVE def test_cannot_enable_if_enabled(self): - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): for path_func in self._get_path_functions(): monitor = self._create_monitor() path = path_func(monitor) @@ -105,7 +105,7 @@ def test_cannot_enable_if_enabled(self): assert monitor.status == MonitorStatus.OK def test_checkin_margin(self): - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): for path_func in self._get_path_functions(): monitor = self._create_monitor() path = path_func(monitor) @@ -119,7 +119,7 @@ def test_checkin_margin(self): assert monitor.config["checkin_margin"] == 30 def test_max_runtime(self): - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): for path_func in self._get_path_functions(): monitor = self._create_monitor() path = path_func(monitor) @@ -133,7 +133,7 @@ def test_max_runtime(self): assert monitor.config["max_runtime"] == 30 def test_invalid_config_param(self): - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): for path_func in self._get_path_functions(): monitor = self._create_monitor() path = path_func(monitor) @@ -147,7 +147,7 @@ def test_invalid_config_param(self): assert "invalid" not in monitor.config def test_cronjob_crontab(self): - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): for path_func in self._get_path_functions(): monitor = self._create_monitor() path = path_func(monitor) @@ -172,7 +172,7 @@ def test_cronjob_crontab(self): # ['@hourly', '0 * * * *'], # )) def test_cronjob_nonstandard(self): - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): for path_func in self._get_path_functions(): monitor = self._create_monitor() path = path_func(monitor) @@ -187,7 +187,7 @@ def test_cronjob_nonstandard(self): assert monitor.config["schedule"] == "0 0 1 * *" def test_cronjob_crontab_invalid(self): - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): for path_func in self._get_path_functions(): monitor = self._create_monitor() path = path_func(monitor) @@ -201,7 +201,7 @@ def test_cronjob_crontab_invalid(self): assert resp.status_code == 400, resp.content def test_cronjob_interval(self): - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): for path_func in self._get_path_functions(): monitor = self._create_monitor() path = path_func(monitor) @@ -218,7 +218,7 @@ def test_cronjob_interval(self): assert monitor.config["schedule"] == [1, "month"] def test_cronjob_interval_invalid_inteval(self): - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): for path_func in self._get_path_functions(): monitor = self._create_monitor() path = path_func(monitor) @@ -247,7 +247,7 @@ def test_mismatched_org_slugs(self): path = f"/api/0/monitors/asdf/{monitor.guid}/" self.login_as(user=self.user) - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): resp = self.client.put( path, data={"config": {"schedule_type": "interval", "schedule": [1, "month"]}} ) @@ -265,7 +265,7 @@ def setUp(self): def test_simple(self): self.login_as(user=self.user) - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): for path_func in self._get_path_functions(): monitor = self._create_monitor() path = path_func(monitor) @@ -286,7 +286,7 @@ def test_mismatched_org_slugs(self): path = f"/api/0/monitors/asdf/{monitor.guid}/" self.login_as(user=self.user) - with self.feature({"organizations:monitors": True}): + with self.feature("organizations:monitors"): resp = self.client.delete(path) assert resp.status_code == 400 From f4873bc4beb97f2afbd73b21f6758fe8d9438440 Mon Sep 17 00:00:00 2001 From: Cathy Teng <70817427+cathyteng17@users.noreply.github.com> Date: Thu, 15 Dec 2022 09:25:46 -0800 Subject: [PATCH 2/2] convert MonitorStats endpoint --- src/sentry/api/endpoints/monitor_stats.py | 14 +++++++++++--- src/sentry/api/urls.py | 5 +++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/sentry/api/endpoints/monitor_stats.py b/src/sentry/api/endpoints/monitor_stats.py index 32bf7642dad608..28eb8f68c6ab3d 100644 --- a/src/sentry/api/endpoints/monitor_stats.py +++ b/src/sentry/api/endpoints/monitor_stats.py @@ -1,16 +1,24 @@ +from __future__ import annotations + from rest_framework.request import Request from rest_framework.response import Response from sentry import tsdb -from sentry.api.base import StatsMixin, pending_silo_endpoint +from sentry.api.base import StatsMixin, region_silo_endpoint from sentry.api.bases.monitor import MonitorEndpoint from sentry.models import CheckInStatus, MonitorCheckIn -@pending_silo_endpoint +@region_silo_endpoint class MonitorStatsEndpoint(MonitorEndpoint, StatsMixin): # TODO(dcramer): probably convert to tsdb - def get(self, request: Request, project, monitor) -> Response: + def get( + self, request: Request, project, monitor, organization_slug: str | None = None + ) -> Response: + if organization_slug: + if project.organization.slug != organization_slug: + return self.respond_invalid() + args = self._parse_args(request) stats = {} diff --git a/src/sentry/api/urls.py b/src/sentry/api/urls.py index e4361d163371e0..de0d188b9a4816 100644 --- a/src/sentry/api/urls.py +++ b/src/sentry/api/urls.py @@ -704,6 +704,11 @@ MonitorStatsEndpoint.as_view(), name="sentry-api-0-monitor-stats", ), + url( + r"^(?P[^\/]+)/(?P[^\/]+)/stats/$", + MonitorStatsEndpoint.as_view(), + name="sentry-api-0-monitor-stats-with-org", + ), ] ), ),