|
@@ -0,0 +1,154 @@
|
|
|
+from datetime import UTC, datetime, timedelta
|
|
|
+from unittest import mock
|
|
|
+
|
|
|
+from django.utils import timezone
|
|
|
+
|
|
|
+from sentry.monitors.models import (
|
|
|
+ CheckInStatus,
|
|
|
+ Monitor,
|
|
|
+ MonitorCheckIn,
|
|
|
+ MonitorEnvironment,
|
|
|
+ MonitorStatus,
|
|
|
+ MonitorType,
|
|
|
+ ScheduleType,
|
|
|
+)
|
|
|
+from sentry.testutils.cases import AcceptanceTestCase
|
|
|
+from sentry.testutils.silo import no_silo_test
|
|
|
+
|
|
|
+
|
|
|
+@no_silo_test
|
|
|
+class OrganizationMontorsTest(AcceptanceTestCase):
|
|
|
+ def setUp(self):
|
|
|
+ super().setUp()
|
|
|
+ self.features = ["organizations:issue-platform"]
|
|
|
+ self.path = f"/organizations/{self.organization.slug}/crons/"
|
|
|
+ self.team = self.create_team(organization=self.organization, name="Mariachi Band")
|
|
|
+
|
|
|
+ self.project = self.create_project(
|
|
|
+ organization=self.organization, teams=[self.team], name="Bengal"
|
|
|
+ )
|
|
|
+ self.create_team_membership(self.team, user=self.user)
|
|
|
+ self.login_as(self.user)
|
|
|
+
|
|
|
+ def test_empty_crons_page(self):
|
|
|
+ self.browser.get(self.path)
|
|
|
+ self.browser.wait_until_not('[data-test-id="loading-indicator"]')
|
|
|
+ assert self.browser.element_exists(xpath="//h3[text()='Monitor Your Cron Jobs']")
|
|
|
+
|
|
|
+ def test_quick_start_flow(self):
|
|
|
+ self.browser.get(self.path)
|
|
|
+ self.browser.wait_until_not('[data-test-id="loading-indicator"]')
|
|
|
+ self.browser.click_when_visible("[aria-label='Create php Monitor']")
|
|
|
+ self.browser.click_when_visible(xpath="//li[@role='tab']//*[text()='Manual']")
|
|
|
+
|
|
|
+ name_input = self.browser.find_element_by_name("name")
|
|
|
+ name_input.send_keys("My Monitor")
|
|
|
+
|
|
|
+ schedule_input = self.browser.find_element_by_name("config.schedule")
|
|
|
+ schedule_input.clear()
|
|
|
+ schedule_input.send_keys("10 0 * * *")
|
|
|
+
|
|
|
+ self.browser.click_when_visible('button[aria-label="Create"]')
|
|
|
+ self.browser.wait_until(xpath="//h1[text()='My Monitor']")
|
|
|
+
|
|
|
+ def test_create_cron_monitor(self):
|
|
|
+ self.browser.get(self.path)
|
|
|
+ self.browser.wait_until_not('[data-test-id="loading-indicator"]')
|
|
|
+ self.browser.click_when_visible("a[aria-label='Add Monitor']")
|
|
|
+
|
|
|
+ name_input = self.browser.find_element_by_name("name")
|
|
|
+ name_input.send_keys("My Monitor")
|
|
|
+
|
|
|
+ schedule_input = self.browser.find_element_by_name("config.schedule")
|
|
|
+ schedule_input.clear()
|
|
|
+ schedule_input.send_keys("10 0 * * *")
|
|
|
+
|
|
|
+ margin = self.browser.find_element_by_name("config.checkinMargin")
|
|
|
+ margin.send_keys("5")
|
|
|
+
|
|
|
+ max_runtime = self.browser.find_element_by_name("config.maxRuntime")
|
|
|
+ max_runtime.send_keys("10")
|
|
|
+
|
|
|
+ self.browser.click_when_visible('button[aria-label="Create"]')
|
|
|
+ self.browser.wait_until(xpath="//h1[text()='My Monitor']")
|
|
|
+ self.browser.element_exists(xpath="//*[text()='At 12:10 AM']")
|
|
|
+ self.browser.element_exists(xpath="//*[text()='Check-ins missed after 5 mins']")
|
|
|
+ self.browser.element_exists(xpath="//*[text()='Check-ins longer than 10 mins or errors']")
|
|
|
+
|
|
|
+ def test_list_monitors(self):
|
|
|
+ monitor = Monitor.objects.create(
|
|
|
+ organization_id=self.organization.id,
|
|
|
+ project_id=self.project.id,
|
|
|
+ type=MonitorType.CRON_JOB,
|
|
|
+ name="My Monitor",
|
|
|
+ config={
|
|
|
+ "schedule": "0 0 * * *",
|
|
|
+ "schedule_type": ScheduleType.CRONTAB,
|
|
|
+ "max_runtime": None,
|
|
|
+ "checkin_margin": None,
|
|
|
+ },
|
|
|
+ )
|
|
|
+
|
|
|
+ with mock.patch(
|
|
|
+ "django.utils.timezone.now",
|
|
|
+ return_value=(datetime.now(tz=UTC)),
|
|
|
+ ):
|
|
|
+ ts = timezone.now() - timedelta(days=1)
|
|
|
+
|
|
|
+ monitor_environment = MonitorEnvironment.objects.create(
|
|
|
+ monitor=monitor,
|
|
|
+ environment_id=self.environment.id,
|
|
|
+ status=MonitorStatus.OK,
|
|
|
+ last_checkin=ts,
|
|
|
+ )
|
|
|
+ MonitorCheckIn.objects.create(
|
|
|
+ monitor=monitor,
|
|
|
+ monitor_environment=monitor_environment,
|
|
|
+ project_id=self.project.id,
|
|
|
+ status=CheckInStatus.OK,
|
|
|
+ date_added=ts,
|
|
|
+ )
|
|
|
+
|
|
|
+ self.browser.get(self.path)
|
|
|
+ self.browser.wait_until_not('[data-test-id="loading-indicator"]')
|
|
|
+ self.browser.wait_until(xpath="//a//*[text()='My Monitor']")
|
|
|
+
|
|
|
+ assert self.browser.element_exists_by_test_id("monitor-checkin-tick")
|
|
|
+
|
|
|
+ def test_edit_monitor(self):
|
|
|
+ Monitor.objects.create(
|
|
|
+ organization_id=self.organization.id,
|
|
|
+ project_id=self.project.id,
|
|
|
+ type=MonitorType.CRON_JOB,
|
|
|
+ name="My Monitor",
|
|
|
+ config={
|
|
|
+ "schedule": "0 0 * * *",
|
|
|
+ "schedule_type": ScheduleType.CRONTAB,
|
|
|
+ "max_runtime": None,
|
|
|
+ "checkin_margin": None,
|
|
|
+ },
|
|
|
+ )
|
|
|
+
|
|
|
+ self.browser.get(self.path)
|
|
|
+ self.browser.wait_until_not('[data-test-id="loading-indicator"]')
|
|
|
+ self.browser.click_when_visible(xpath="//a//*[text()='My Monitor']")
|
|
|
+ self.browser.click_when_visible('a[aria-label="Edit"]')
|
|
|
+ self.browser.wait_until_not('[data-test-id="loading-indicator"]')
|
|
|
+
|
|
|
+ name_input = self.browser.find_element_by_name("name")
|
|
|
+ name_input.clear()
|
|
|
+ name_input.send_keys("My Edited Monitor")
|
|
|
+
|
|
|
+ slug_input = self.browser.find_element_by_name("slug")
|
|
|
+ slug_input.clear()
|
|
|
+ slug_input.send_keys("my-monitor-edited-slug")
|
|
|
+
|
|
|
+ schedule_input = self.browser.find_element_by_name("config.schedule")
|
|
|
+ schedule_input.clear()
|
|
|
+ schedule_input.send_keys("5 0 * * *")
|
|
|
+
|
|
|
+ self.browser.click_when_visible('button[aria-label="Save Changes"]')
|
|
|
+
|
|
|
+ self.browser.wait_until(xpath="//h1[text()='My Edited Monitor']")
|
|
|
+ assert self.browser.element_exists(xpath="//*[text()='At 12:05 AM']")
|
|
|
+ assert "my-monitor-edited-slug" in self.browser.current_url
|