From 52213bf2de132151dfe7d6a1413c49c2d6bb4da2 Mon Sep 17 00:00:00 2001 From: nikkikapadia Date: Wed, 21 May 2025 16:27:16 -0400 Subject: [PATCH 1/6] migration for self hosted dashboards discover split --- migrations_lockfile.txt | 2 +- ...discover_dataset_dashboards_self_hosted.py | 83 +++++++++++++++++++ ...discover_dataset_dashboards_self_hosted.py | 78 +++++++++++++++++ 3 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 src/sentry/migrations/0905_split_discover_dataset_dashboards_self_hosted.py create mode 100644 tests/sentry/migrations/test_0905_split_discover_dataset_dashboards_self_hosted.py diff --git a/migrations_lockfile.txt b/migrations_lockfile.txt index c05013ffdd7c12..a4dcc4654e2abc 100644 --- a/migrations_lockfile.txt +++ b/migrations_lockfile.txt @@ -21,7 +21,7 @@ remote_subscriptions: 0003_drop_remote_subscription replays: 0005_drop_replay_index -sentry: 0904_onboarding_task_project_id_idx +sentry: 0905_split_discover_dataset_dashboards_self_hosted social_auth: 0002_default_auto_field diff --git a/src/sentry/migrations/0905_split_discover_dataset_dashboards_self_hosted.py b/src/sentry/migrations/0905_split_discover_dataset_dashboards_self_hosted.py new file mode 100644 index 00000000000000..9b15921fe20844 --- /dev/null +++ b/src/sentry/migrations/0905_split_discover_dataset_dashboards_self_hosted.py @@ -0,0 +1,83 @@ +# Generated by Django 5.2.1 on 2025-05-20 17:45 + +from django.db import migrations +from django.db.backends.base.schema import BaseDatabaseSchemaEditor +from django.db.migrations.state import StateApps +from django.db.models import Q + +from sentry.discover.dashboard_widget_split import _get_and_save_split_decision_for_dashboard_widget +from sentry.models.dashboard_widget import DashboardWidgetTypes, DatasetSourcesTypes +from sentry.new_migrations.migrations import CheckedMigration +from sentry.utils.query import RangeQuerySetWrapperWithProgressBar + + +def split_discover_dataset_dashboards_self_hosted( + apps: StateApps, schema_editor: BaseDatabaseSchemaEditor +) -> None: + DashboardWidgetQuery = apps.get_model("sentry", "DashboardWidgetQuery") + catch_all_unsplit_widgets = Q( + widget__widget_type=DashboardWidgetTypes.DISCOVER, + ) & ~Q( + widget__discover_widget_split__in=[ + DashboardWidgetTypes.ERROR_EVENTS, + DashboardWidgetTypes.TRANSACTION_LIKE, + ] + ) + + queryset = DashboardWidgetQuery.objects.filter( + catch_all_unsplit_widgets, + ).select_related("widget__dashboard__organization") + + for widget_query in RangeQuerySetWrapperWithProgressBar(queryset): + try: + _get_and_save_split_decision_for_dashboard_widget(widget_query, dry_run=False) + except Exception: + widget_query.widget.widget_type = DashboardWidgetTypes.ERROR_EVENTS + widget_query.widget.discover_widget_split = DashboardWidgetTypes.ERROR_EVENTS + widget_query.widget.dataset_source = DatasetSourcesTypes.UNKNOWN.value + widget_query.widget.save() + + +def reverse_split_discover_dataset_dashboards_self_hosted( + apps: StateApps, schema_editor: BaseDatabaseSchemaEditor +) -> None: + DashboardWidgetQuery = apps.get_model("sentry", "DashboardWidgetQuery") + + queryset = DashboardWidgetQuery.objects.filter( + widget__widget_type=DashboardWidgetTypes.ERROR_EVENTS, + widget__dataset_source=DatasetSourcesTypes.UNKNOWN.value, + ).select_related("widget__dashboard__organization") + + for widget_query in RangeQuerySetWrapperWithProgressBar(queryset): + widget_query.widget.widget_type = DashboardWidgetTypes.DISCOVER + widget_query.widget.discover_widget_split = None + widget_query.widget.dataset_source = DatasetSourcesTypes.UNKNOWN.value + widget_query.widget.save() + + +class Migration(CheckedMigration): + # This flag is used to mark that a migration shouldn't be automatically run in production. + # This should only be used for operations where it's safe to run the migration after your + # code has deployed. So this should not be used for most operations that alter the schema + # of a table. + # Here are some things that make sense to mark as post deployment: + # - Large data migrations. Typically we want these to be run manually so that they can be + # monitored and not block the deploy for a long period of time while they run. + # - Adding indexes to large tables. Since this can take a long time, we'd generally prefer to + # run this outside deployments so that we don't block them. Note that while adding an index + # is a schema change, it's completely safe to run the operation after the code has deployed. + # Once deployed, run these manually via: https://develop.sentry.dev/database-migrations/#migration-deployment + + is_post_deployment = True + + dependencies = [ + ("sentry", "0904_onboarding_task_project_id_idx"), + ] + + operations = [ + migrations.RunPython( + split_discover_dataset_dashboards_self_hosted, + reverse_code=reverse_split_discover_dataset_dashboards_self_hosted, + hints={"tables": ["sentry_dashboardwidget"]}, + ) + ] diff --git a/tests/sentry/migrations/test_0905_split_discover_dataset_dashboards_self_hosted.py b/tests/sentry/migrations/test_0905_split_discover_dataset_dashboards_self_hosted.py new file mode 100644 index 00000000000000..2c3a6ad1142d9c --- /dev/null +++ b/tests/sentry/migrations/test_0905_split_discover_dataset_dashboards_self_hosted.py @@ -0,0 +1,78 @@ +from sentry.hybridcloud.models.outbox import outbox_context +from sentry.models.dashboard_widget import DashboardWidgetTypes, DatasetSourcesTypes +from sentry.testutils.cases import SnubaTestCase, TestMigrations + + +class SplitDiscoverDatasetDashboardsSelfHostedTest(TestMigrations, SnubaTestCase): + migrate_from = "0904_onboarding_task_project_id_idx" + migrate_to = "0905_split_discover_dataset_dashboards_self_hosted" + + def setup_before_migration(self, apps): + Organization = apps.get_model("sentry", "Organization") + User = apps.get_model("sentry", "User") + Dashboard = apps.get_model("sentry", "Dashboard") + DashboardWidget = apps.get_model("sentry", "DashboardWidget") + DashboardWidgetQuery = apps.get_model("sentry", "DashboardWidgetQuery") + + with outbox_context(flush=False): + self.organization = Organization.objects.create(name="test", slug="test") + self.user = User.objects.create(email="test@test.com", is_superuser=False) + + self.dashboard = Dashboard.objects.create( + title="test", + organization=self.organization, + created_by=self.user, + ) + + self.discover_widget = DashboardWidget.objects.create( + dashboard=self.dashboard, + title="test discover widget", + widget_type=DashboardWidgetTypes.DISCOVER, + dataset_source=DatasetSourcesTypes.UNKNOWN, + ) + self.discover_widget_query = DashboardWidgetQuery.objects.create( + widget=self.discover_widget, + name="test discover widget query", + fields=["count()"], + aggregates=["count()"], + columns=[], + conditions=[], + limit=10, + orderby=["-count()"], + order=0, + ) + + self.migrated_discover_widget = DashboardWidget.objects.create( + dashboard=self.dashboard, + title="test migrated discover widget", + widget_type=DashboardWidgetTypes.DISCOVER, + dataset_source=DatasetSourcesTypes.UNKNOWN, + discover_widget_split=DashboardWidgetTypes.TRANSACTION_LIKE, + ) + + self.migrated_discover_widget_query = DashboardWidgetQuery.objects.create( + widget=self.migrated_discover_widget, + name="test migrated discover widget query", + fields=["count()"], + aggregates=["count()"], + columns=[], + conditions=[], + limit=10, + orderby=["-count()"], + order=0, + ) + + def test(self): + self.discover_widget.refresh_from_db() + self.migrated_discover_widget.refresh_from_db() + + assert self.discover_widget.discover_widget_split == DashboardWidgetTypes.ERROR_EVENTS + assert self.discover_widget.widget_type == DashboardWidgetTypes.ERROR_EVENTS + assert self.discover_widget.dataset_source == DatasetSourcesTypes.FORCED + + assert ( + self.migrated_discover_widget.discover_widget_split + == DashboardWidgetTypes.TRANSACTION_LIKE + ) + assert self.migrated_discover_widget.widget_type == DashboardWidgetTypes.DISCOVER + assert self.migrated_discover_widget.dataset_source == DatasetSourcesTypes.UNKNOWN From dfd9dd999bfa7e76036c2044100cd0a0b381c2a3 Mon Sep 17 00:00:00 2001 From: nikkikapadia Date: Thu, 22 May 2025 13:08:14 -0400 Subject: [PATCH 2/6] fix migration test --- ...discover_dataset_dashboards_self_hosted.py | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/tests/sentry/migrations/test_0905_split_discover_dataset_dashboards_self_hosted.py b/tests/sentry/migrations/test_0905_split_discover_dataset_dashboards_self_hosted.py index 2c3a6ad1142d9c..b556daf77edbcc 100644 --- a/tests/sentry/migrations/test_0905_split_discover_dataset_dashboards_self_hosted.py +++ b/tests/sentry/migrations/test_0905_split_discover_dataset_dashboards_self_hosted.py @@ -1,5 +1,10 @@ from sentry.hybridcloud.models.outbox import outbox_context -from sentry.models.dashboard_widget import DashboardWidgetTypes, DatasetSourcesTypes +from sentry.models.dashboard_widget import ( + DashboardWidgetDisplayTypes, + DashboardWidgetTypes, + DatasetSourcesTypes, +) +from sentry.models.organization import Organization from sentry.testutils.cases import SnubaTestCase, TestMigrations @@ -8,7 +13,6 @@ class SplitDiscoverDatasetDashboardsSelfHostedTest(TestMigrations, SnubaTestCase migrate_to = "0905_split_discover_dataset_dashboards_self_hosted" def setup_before_migration(self, apps): - Organization = apps.get_model("sentry", "Organization") User = apps.get_model("sentry", "User") Dashboard = apps.get_model("sentry", "Dashboard") DashboardWidget = apps.get_model("sentry", "DashboardWidget") @@ -20,46 +24,51 @@ def setup_before_migration(self, apps): self.dashboard = Dashboard.objects.create( title="test", - organization=self.organization, - created_by=self.user, + organization_id=self.organization.id, + created_by_id=self.user.id, ) self.discover_widget = DashboardWidget.objects.create( - dashboard=self.dashboard, + dashboard_id=self.dashboard.id, title="test discover widget", widget_type=DashboardWidgetTypes.DISCOVER, - dataset_source=DatasetSourcesTypes.UNKNOWN, + dataset_source=DatasetSourcesTypes.UNKNOWN.value, + display_type=DashboardWidgetDisplayTypes.LINE_CHART, + interval="1d", + order=0, ) + self.discover_widget_query = DashboardWidgetQuery.objects.create( - widget=self.discover_widget, + widget_id=self.discover_widget.id, name="test discover widget query", fields=["count()"], aggregates=["count()"], columns=[], conditions=[], - limit=10, orderby=["-count()"], order=0, ) self.migrated_discover_widget = DashboardWidget.objects.create( - dashboard=self.dashboard, + dashboard_id=self.dashboard.id, title="test migrated discover widget", widget_type=DashboardWidgetTypes.DISCOVER, - dataset_source=DatasetSourcesTypes.UNKNOWN, + dataset_source=DatasetSourcesTypes.UNKNOWN.value, discover_widget_split=DashboardWidgetTypes.TRANSACTION_LIKE, + display_type=DashboardWidgetDisplayTypes.LINE_CHART, + interval="1d", + order=1, ) self.migrated_discover_widget_query = DashboardWidgetQuery.objects.create( - widget=self.migrated_discover_widget, + widget_id=self.migrated_discover_widget.id, name="test migrated discover widget query", fields=["count()"], aggregates=["count()"], columns=[], conditions=[], - limit=10, orderby=["-count()"], - order=0, + order=1, ) def test(self): @@ -67,12 +76,12 @@ def test(self): self.migrated_discover_widget.refresh_from_db() assert self.discover_widget.discover_widget_split == DashboardWidgetTypes.ERROR_EVENTS - assert self.discover_widget.widget_type == DashboardWidgetTypes.ERROR_EVENTS - assert self.discover_widget.dataset_source == DatasetSourcesTypes.FORCED + assert self.discover_widget.widget_type == DashboardWidgetTypes.DISCOVER + assert self.discover_widget.dataset_source == DatasetSourcesTypes.FORCED.value assert ( self.migrated_discover_widget.discover_widget_split == DashboardWidgetTypes.TRANSACTION_LIKE ) assert self.migrated_discover_widget.widget_type == DashboardWidgetTypes.DISCOVER - assert self.migrated_discover_widget.dataset_source == DatasetSourcesTypes.UNKNOWN + assert self.migrated_discover_widget.dataset_source == DatasetSourcesTypes.UNKNOWN.value From 8a30842c947b825c1434fbdb911c6b1e0931d3af Mon Sep 17 00:00:00 2001 From: nikkikapadia Date: Thu, 22 May 2025 13:44:37 -0400 Subject: [PATCH 3/6] update migrations --- .../0912_split_discover_dataset_dashboards_self_hosted.py | 2 +- ...test_0912_split_discover_dataset_dashboards_self_hosted.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sentry/migrations/0912_split_discover_dataset_dashboards_self_hosted.py b/src/sentry/migrations/0912_split_discover_dataset_dashboards_self_hosted.py index 9b15921fe20844..3ceb117d527e1e 100644 --- a/src/sentry/migrations/0912_split_discover_dataset_dashboards_self_hosted.py +++ b/src/sentry/migrations/0912_split_discover_dataset_dashboards_self_hosted.py @@ -71,7 +71,7 @@ class Migration(CheckedMigration): is_post_deployment = True dependencies = [ - ("sentry", "0904_onboarding_task_project_id_idx"), + ("sentry", "0911_increase_email_model_email_field_length"), ] operations = [ diff --git a/tests/sentry/migrations/test_0912_split_discover_dataset_dashboards_self_hosted.py b/tests/sentry/migrations/test_0912_split_discover_dataset_dashboards_self_hosted.py index b556daf77edbcc..4d067973cf5c57 100644 --- a/tests/sentry/migrations/test_0912_split_discover_dataset_dashboards_self_hosted.py +++ b/tests/sentry/migrations/test_0912_split_discover_dataset_dashboards_self_hosted.py @@ -9,8 +9,8 @@ class SplitDiscoverDatasetDashboardsSelfHostedTest(TestMigrations, SnubaTestCase): - migrate_from = "0904_onboarding_task_project_id_idx" - migrate_to = "0905_split_discover_dataset_dashboards_self_hosted" + migrate_from = "0911_increase_email_model_email_field_length" + migrate_to = "0912_split_discover_dataset_dashboards_self_hosted" def setup_before_migration(self, apps): User = apps.get_model("sentry", "User") From e6f09d1decda7588f8d0ee97d12a6222fbc85aed Mon Sep 17 00:00:00 2001 From: nikkikapadia Date: Fri, 23 May 2025 15:30:00 -0400 Subject: [PATCH 4/6] fix migration conditions and add more test widgets --- ...discover_dataset_dashboards_self_hosted.py | 111 ++++++++++++++++-- ...discover_dataset_dashboards_self_hosted.py | 95 +++++++++++++-- 2 files changed, 187 insertions(+), 19 deletions(-) diff --git a/src/sentry/migrations/0913_split_discover_dataset_dashboards_self_hosted.py b/src/sentry/migrations/0913_split_discover_dataset_dashboards_self_hosted.py index 5773ca6fed6e41..cad40330b4dda5 100644 --- a/src/sentry/migrations/0913_split_discover_dataset_dashboards_self_hosted.py +++ b/src/sentry/migrations/0913_split_discover_dataset_dashboards_self_hosted.py @@ -1,16 +1,112 @@ # Generated by Django 5.2.1 on 2025-05-20 17:45 +from enum import Enum + from django.db import migrations from django.db.backends.base.schema import BaseDatabaseSchemaEditor from django.db.migrations.state import StateApps from django.db.models import Q from sentry.discover.dashboard_widget_split import _get_and_save_split_decision_for_dashboard_widget -from sentry.models.dashboard_widget import DashboardWidgetTypes, DatasetSourcesTypes +from sentry.models.dashboard_widget import TypesClass from sentry.new_migrations.migrations import CheckedMigration from sentry.utils.query import RangeQuerySetWrapperWithProgressBar +class DashboardWidgetTypes(TypesClass): + DISCOVER = 0 + """ + Old way of accessing error events and transaction events simultaneously @deprecated. Use ERROR_EVENTS or TRANSACTION_LIKE instead. + """ + ISSUE = 1 + RELEASE_HEALTH = 2 + METRICS = 3 + ERROR_EVENTS = 100 + """ + Error side of the split from Discover. + """ + TRANSACTION_LIKE = 101 + """ + This targets transaction-like data from the split from discover. Itt may either use 'Transactions' events or 'PerformanceMetrics' depending on on-demand, MEP metrics, etc. + """ + SPANS = 102 + """ + These represent the logs trace item type on the EAP dataset. + """ + LOGS = 103 + + TYPES = [ + (DISCOVER, "discover"), + (ISSUE, "issue"), + ( + RELEASE_HEALTH, + "metrics", + ), + (ERROR_EVENTS, "error-events"), + (TRANSACTION_LIKE, "transaction-like"), + (SPANS, "spans"), + (LOGS, "logs"), + ] + TYPE_NAMES = [t[1] for t in TYPES] + + +class DatasetSourcesTypes(Enum): + """ + Ambiguous queries that haven't been or couldn't be categorized into a + specific dataset. + """ + + UNKNOWN = 0 + """ + Dataset inferred by either running the query or using heuristics. + """ + INFERRED = 1 + """ + Canonical dataset, user explicitly selected it. + """ + USER = 2 + """ + Was an ambiguous dataset forced to split (i.e. we picked a default) + """ + FORCED = 3 + """ + Dataset inferred by split script, version 1 + """ + SPLIT_VERSION_1 = 4 + """ + Dataset inferred by split script, version 2 + """ + SPLIT_VERSION_2 = 5 + + @classmethod + def as_choices(cls): + return tuple((source.value, source.name.lower()) for source in cls) + + @classmethod + def as_text_choices(cls): + return tuple((source.name.lower(), source.value) for source in cls) + + +class DashboardWidgetDisplayTypes(TypesClass): + LINE_CHART = 0 + AREA_CHART = 1 + STACKED_AREA_CHART = 2 + BAR_CHART = 3 + TABLE = 4 + BIG_NUMBER = 6 + TOP_N = 7 + TYPES = [ + (LINE_CHART, "line"), + (AREA_CHART, "area"), + (STACKED_AREA_CHART, "stacked_area"), + (BAR_CHART, "bar"), + (TABLE, "table"), + (BIG_NUMBER, "big_number"), + (TOP_N, "top_n"), + ] + TYPE_NAMES = [t[1] for t in TYPES] + + def split_discover_dataset_dashboards_self_hosted( apps: StateApps, schema_editor: BaseDatabaseSchemaEditor ) -> None: @@ -32,7 +128,6 @@ def split_discover_dataset_dashboards_self_hosted( try: _get_and_save_split_decision_for_dashboard_widget(widget_query, dry_run=False) except Exception: - widget_query.widget.widget_type = DashboardWidgetTypes.ERROR_EVENTS widget_query.widget.discover_widget_split = DashboardWidgetTypes.ERROR_EVENTS widget_query.widget.dataset_source = DatasetSourcesTypes.UNKNOWN.value widget_query.widget.save() @@ -42,14 +137,16 @@ def reverse_split_discover_dataset_dashboards_self_hosted( apps: StateApps, schema_editor: BaseDatabaseSchemaEditor ) -> None: DashboardWidgetQuery = apps.get_model("sentry", "DashboardWidgetQuery") + all_split_widgets = Q( + widget__discover_widget_split__in=[ + DashboardWidgetTypes.ERROR_EVENTS, + DashboardWidgetTypes.TRANSACTION_LIKE, + ] + ) - queryset = DashboardWidgetQuery.objects.filter( - widget__widget_type=DashboardWidgetTypes.ERROR_EVENTS, - widget__dataset_source=DatasetSourcesTypes.UNKNOWN.value, - ).select_related("widget__dashboard__organization") + queryset = DashboardWidgetQuery.objects.filter(all_split_widgets) for widget_query in RangeQuerySetWrapperWithProgressBar(queryset): - widget_query.widget.widget_type = DashboardWidgetTypes.DISCOVER widget_query.widget.discover_widget_split = None widget_query.widget.dataset_source = DatasetSourcesTypes.UNKNOWN.value widget_query.widget.save() diff --git a/tests/sentry/migrations/test_0913_split_discover_dataset_dashboards_self_hosted.py b/tests/sentry/migrations/test_0913_split_discover_dataset_dashboards_self_hosted.py index 10558db924518c..ff0a8c421a91c8 100644 --- a/tests/sentry/migrations/test_0913_split_discover_dataset_dashboards_self_hosted.py +++ b/tests/sentry/migrations/test_0913_split_discover_dataset_dashboards_self_hosted.py @@ -6,6 +6,8 @@ ) from sentry.models.organization import Organization from sentry.testutils.cases import SnubaTestCase, TestMigrations +from sentry.testutils.helpers.datetime import before_now +from sentry.utils.samples import load_data class SplitDiscoverDatasetDashboardsSelfHostedTest(TestMigrations, SnubaTestCase): @@ -21,6 +23,12 @@ def setup_before_migration(self, apps): with outbox_context(flush=False): self.organization = Organization.objects.create(name="test", slug="test") self.user = User.objects.create(email="test@test.com", is_superuser=False) + self.project = self.create_project( + name="test_project", slug="test_project", organization=self.organization + ) + self.environment = self.create_environment( + name="test_environment", project=self.project, organization=self.organization + ) self.dashboard = Dashboard.objects.create( title="test", @@ -28,7 +36,7 @@ def setup_before_migration(self, apps): created_by_id=self.user.id, ) - self.discover_widget = DashboardWidget.objects.create( + self.discover_error_widget = DashboardWidget.objects.create( dashboard_id=self.dashboard.id, title="test discover widget", widget_type=DashboardWidgetTypes.DISCOVER, @@ -38,13 +46,13 @@ def setup_before_migration(self, apps): order=0, ) - self.discover_widget_query = DashboardWidgetQuery.objects.create( - widget_id=self.discover_widget.id, + self.discover_error_widget_query = DashboardWidgetQuery.objects.create( + widget_id=self.discover_error_widget.id, name="test discover widget query", fields=["count()"], aggregates=["count()"], columns=[], - conditions=[], + conditions="environment:foo", orderby=["-count()"], order=0, ) @@ -66,22 +74,85 @@ def setup_before_migration(self, apps): fields=["count()"], aggregates=["count()"], columns=[], - conditions=[], + conditions="environment:foo", orderby=["-count()"], order=1, ) + self.discover_transaction_widget = DashboardWidget.objects.create( + dashboard_id=self.dashboard.id, + title="test discover transaction widget", + widget_type=DashboardWidgetTypes.DISCOVER, + dataset_source=DatasetSourcesTypes.UNKNOWN.value, + display_type=DashboardWidgetDisplayTypes.LINE_CHART, + interval="1d", + order=2, + ) + + self.discover_transaction_widget_query = DashboardWidgetQuery.objects.create( + widget_id=self.discover_transaction_widget.id, + name="test discover transaction widget query", + fields=["count()", "transaction.duration"], + aggregates=["count()"], + columns=[], + conditions="environment:foo", + orderby=["-count()"], + order=2, + ) + + self.discover_ambiguous_widget = DashboardWidget.objects.create( + dashboard_id=self.dashboard.id, + title="test discover ambiguous widget", + widget_type=DashboardWidgetTypes.DISCOVER, + dataset_source=DatasetSourcesTypes.UNKNOWN.value, + display_type=DashboardWidgetDisplayTypes.LINE_CHART, + interval="1d", + order=3, + ) + + self.discover_ambiguous_widget_query = DashboardWidgetQuery.objects.create( + widget_id=self.discover_ambiguous_widget.id, + name="test discover ambiguous widget query", + fields=["count()", "transaction"], + aggregates=["count()"], + columns=[], + conditions="environment:test_environment", + orderby=["-count()"], + order=3, + ) + + # Now store test data that should only affect the ambiguous widget + self.nine_mins_ago = before_now(minutes=9) + self.ten_mins_ago = before_now(minutes=10) + + data = load_data("transaction", timestamp=self.ten_mins_ago) + data["transaction"] = "/to_other/" + data["environment"] = self.environment.name + data["transaction.duration"] = 1000 + self.store_event(data, project_id=self.project.id, assert_no_errors=False) + + data = load_data("transaction", timestamp=self.ten_mins_ago) + data["transaction"] = "/to_other/2" + data["environment"] = self.environment.name + data["transaction.duration"] = 2000 + self.store_event(data, project_id=self.project.id, assert_no_errors=False) + def test(self): - self.discover_widget.refresh_from_db() + self.discover_error_widget.refresh_from_db() self.migrated_discover_widget.refresh_from_db() + self.discover_transaction_widget.refresh_from_db() + self.discover_ambiguous_widget.refresh_from_db() - assert self.discover_widget.discover_widget_split == DashboardWidgetTypes.ERROR_EVENTS - assert self.discover_widget.widget_type == DashboardWidgetTypes.DISCOVER - assert self.discover_widget.dataset_source == DatasetSourcesTypes.FORCED.value - + assert self.discover_error_widget.discover_widget_split == DashboardWidgetTypes.ERROR_EVENTS assert ( self.migrated_discover_widget.discover_widget_split == DashboardWidgetTypes.TRANSACTION_LIKE ) - assert self.migrated_discover_widget.widget_type == DashboardWidgetTypes.DISCOVER - assert self.migrated_discover_widget.dataset_source == DatasetSourcesTypes.UNKNOWN.value + assert ( + self.discover_transaction_widget.discover_widget_split + == DashboardWidgetTypes.TRANSACTION_LIKE + ) + assert ( + self.discover_ambiguous_widget.discover_widget_split + == DashboardWidgetTypes.TRANSACTION_LIKE + ) From 358b26e9afc427746eb4949f014b111f9b45728f Mon Sep 17 00:00:00 2001 From: nikkikapadia Date: Mon, 26 May 2025 09:43:03 -0400 Subject: [PATCH 5/6] fix typing error --- .../0913_split_discover_dataset_dashboards_self_hosted.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sentry/migrations/0913_split_discover_dataset_dashboards_self_hosted.py b/src/sentry/migrations/0913_split_discover_dataset_dashboards_self_hosted.py index cad40330b4dda5..677bba1d10e331 100644 --- a/src/sentry/migrations/0913_split_discover_dataset_dashboards_self_hosted.py +++ b/src/sentry/migrations/0913_split_discover_dataset_dashboards_self_hosted.py @@ -79,11 +79,11 @@ class DatasetSourcesTypes(Enum): SPLIT_VERSION_2 = 5 @classmethod - def as_choices(cls): + def as_choices(cls) -> tuple[tuple[int, str], ...]: return tuple((source.value, source.name.lower()) for source in cls) @classmethod - def as_text_choices(cls): + def as_text_choices(cls) -> tuple[tuple[str, int], ...]: return tuple((source.name.lower(), source.value) for source in cls) From 658cb761cd592a19622df9908d0663c8f585af1f Mon Sep 17 00:00:00 2001 From: nikkikapadia Date: Mon, 26 May 2025 11:37:28 -0400 Subject: [PATCH 6/6] change comments --- .../0913_split_discover_dataset_dashboards_self_hosted.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sentry/migrations/0913_split_discover_dataset_dashboards_self_hosted.py b/src/sentry/migrations/0913_split_discover_dataset_dashboards_self_hosted.py index 677bba1d10e331..da67316396088e 100644 --- a/src/sentry/migrations/0913_split_discover_dataset_dashboards_self_hosted.py +++ b/src/sentry/migrations/0913_split_discover_dataset_dashboards_self_hosted.py @@ -27,13 +27,13 @@ class DashboardWidgetTypes(TypesClass): """ TRANSACTION_LIKE = 101 """ - This targets transaction-like data from the split from discover. Itt may either use 'Transactions' events or 'PerformanceMetrics' depending on on-demand, MEP metrics, etc. + This targets transaction-like data from the split from discover. It may either use 'Transactions' events or 'PerformanceMetrics' depending on on-demand, MEP metrics, etc. """ SPANS = 102 + LOGS = 103 """ These represent the logs trace item type on the EAP dataset. """ - LOGS = 103 TYPES = [ (DISCOVER, "discover"),