Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ref: prevent cross-db transactions for sending account emails (#56110)
prior to this fix: ```console $ pytest tests/sentry/web/frontend/test_accounts.py::TestAccounts::test_leaking_recovery_hash ============================= test session starts ============================== platform darwin -- Python 3.8.16, pytest-7.2.1, pluggy-0.13.1 rootdir: /Users/asottile/workspace/sentry, configfile: pyproject.toml plugins: fail-slow-0.3.0, rerunfailures-11.0, sentry-0.1.11, xdist-3.0.2, cov-4.0.0, repeat-0.9.1, django-4.4.0 collected 1 item tests/sentry/web/frontend/test_accounts.py F [100%] =================================== FAILURES =================================== ___________________ TestAccounts.test_leaking_recovery_hash ____________________ tests/sentry/web/frontend/test_accounts.py:71: in test_leaking_recovery_hash resp = self.client.post( .venv/lib/python3.8/site-packages/django/test/client.py:751: in post response = super().post(path, data=data, content_type=content_type, secure=secure, **extra) .venv/lib/python3.8/site-packages/django/test/client.py:407: in post return self.generic('POST', path, post_data, content_type, .venv/lib/python3.8/site-packages/django/test/client.py:473: in generic return self.request(**r) .venv/lib/python3.8/site-packages/django/test/client.py:719: in request self.check_exception(response) .venv/lib/python3.8/site-packages/django/test/client.py:580: in check_exception raise exc_value .venv/lib/python3.8/site-packages/django/core/handlers/exception.py:47: in inner response = get_response(request) .venv/lib/python3.8/site-packages/django/core/handlers/base.py:181: in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) src/sentry/web/decorators.py:51: in wrapped response = func(request, *args, **kwargs) src/sentry/web/frontend/accounts.py:122: in recover_confirm if not user.has_2fa(): src/sentry/models/user.py:207: in has_2fa user_id=self.id, type__in=[a.type for a in available_authenticators(ignore_backup=True)] src/sentry/auth/authenticators/__init__.py:23: in available_authenticators return [v for v in interfaces if not v.is_backup_interface and v.is_available] src/sentry/auth/authenticators/__init__.py:23: in <listcomp> return [v for v in interfaces if not v.is_backup_interface and v.is_available] src/sentry/utils/decorators.py:8: in __get__ return self.fget(owner) src/sentry/auth/authenticators/sms.py:46: in is_available return sms_available() src/sentry/utils/sms.py:54: in sms_available return bool(options.get("sms.twilio-account")) src/sentry/options/manager.py:285: in get result = self.store.get(opt, silent=silent) src/sentry/options/store.py:96: in get result = self.get_store(key, silent=silent) src/sentry/options/store.py:187: in get_store value = self.model.objects.get(key=key.name).value src/sentry/db/models/manager/base.py:255: in get return super().get(*args, **kwargs) .venv/lib/python3.8/site-packages/django/db/models/manager.py:85: in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) .venv/lib/python3.8/site-packages/django/db/models/query.py:431: in get num = len(clone) .venv/lib/python3.8/site-packages/django/db/models/query.py:262: in __len__ self._fetch_all() .venv/lib/python3.8/site-packages/django/db/models/query.py:1324: in _fetch_all self._result_cache = list(self._iterable_class(self)) .venv/lib/python3.8/site-packages/django/db/models/query.py:51: in __iter__ results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size) .venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py:1175: in execute_sql cursor.execute(sql, params) .venv/lib/python3.8/site-packages/django/db/backends/utils.py:98: in execute return super().execute(sql, params) .venv/lib/python3.8/site-packages/sentry_sdk/integrations/django/__init__.py:610: in execute return real_execute(self, sql, params) .venv/lib/python3.8/site-packages/django/db/backends/utils.py:66: in execute return self._execute_with_wrappers(sql, params, many=False, executor=self._execute) .venv/lib/python3.8/site-packages/django/db/backends/utils.py:75: in _execute_with_wrappers return executor(sql, params, many, context) src/sentry/testutils/hybrid_cloud.py:116: in __call__ assert ( E AssertionError: Transaction opened for db {'control'}, but command running against db default E assert 'default' in {'control'} E + where 'default' = <sentry.testutils.hybrid_cloud.EnforceNoCrossTransactionWrapper object at 0x12898c460>.alias ``` ```console $ pytest tests/sentry/mediators/sentry_app_installations/test_installation_notifier.py::TestInstallationNotifier::test_task_enqueued ============================= test session starts ============================== platform darwin -- Python 3.8.16, pytest-7.2.1, pluggy-0.13.1 rootdir: /Users/asottile/workspace/sentry, configfile: pyproject.toml plugins: fail-slow-0.3.0, rerunfailures-11.0, sentry-0.1.11, xdist-3.0.2, cov-4.0.0, repeat-0.9.1, django-4.4.0 collected 1 item tests/sentry/mediators/sentry_app_installations/test_installation_notifier.py F [100%] =================================== FAILURES =================================== _________________ TestInstallationNotifier.test_task_enqueued __________________ tests/sentry/mediators/sentry_app_installations/test_installation_notifier.py:45: in test_task_enqueued InstallationNotifier.run(install=self.install, user=self.user, action="created") src/sentry/mediators/mediator.py:155: in run return _inner() src/sentry/mediators/mediator.py:147: in _inner result = obj.call() src/sentry/mediators/sentry_app_installations/installation_notifier.py:20: in call self._send_webhook() src/sentry/mediators/sentry_app_installations/installation_notifier.py:27: in _send_webhook return send_and_save_webhook_request(self.sentry_app, self.request) src/sentry/utils/sentry_apps/webhooks.py:34: in wrapper return func(sentry_app, app_platform_event, url) src/sentry/utils/sentry_apps/webhooks.py:126: in send_and_save_webhook_request timeout=options.get("sentry-apps.webhook.timeout.sec"), src/sentry/options/manager.py:285: in get result = self.store.get(opt, silent=silent) src/sentry/options/store.py:96: in get result = self.get_store(key, silent=silent) src/sentry/options/store.py:187: in get_store value = self.model.objects.get(key=key.name).value src/sentry/db/models/manager/base.py:255: in get return super().get(*args, **kwargs) .venv/lib/python3.8/site-packages/django/db/models/manager.py:85: in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) .venv/lib/python3.8/site-packages/django/db/models/query.py:431: in get num = len(clone) .venv/lib/python3.8/site-packages/django/db/models/query.py:262: in __len__ self._fetch_all() .venv/lib/python3.8/site-packages/django/db/models/query.py:1324: in _fetch_all self._result_cache = list(self._iterable_class(self)) .venv/lib/python3.8/site-packages/django/db/models/query.py:51: in __iter__ results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size) .venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py:1175: in execute_sql cursor.execute(sql, params) .venv/lib/python3.8/site-packages/django/db/backends/utils.py:98: in execute return super().execute(sql, params) .venv/lib/python3.8/site-packages/sentry_sdk/integrations/django/__init__.py:610: in execute return real_execute(self, sql, params) .venv/lib/python3.8/site-packages/django/db/backends/utils.py:66: in execute return self._execute_with_wrappers(sql, params, many=False, executor=self._execute) .venv/lib/python3.8/site-packages/django/db/backends/utils.py:75: in _execute_with_wrappers return executor(sql, params, many, context) src/sentry/testutils/hybrid_cloud.py:116: in __call__ assert ( E AssertionError: Transaction opened for db {'control'}, but command running against db default E assert 'default' in {'control'} E + where 'default' = <sentry.testutils.hybrid_cloud.EnforceNoCrossTransactionWrapper object at 0x13b3e0d60>.alias =========================== short test summary info ============================ FAILED tests/sentry/mediators/sentry_app_installations/test_installation_notifier.py::TestInstallationNotifier::test_task_enqueued - AssertionError: Transaction opened for db {'control'}, but command running ... ============================== 1 failed in 4.50s ============================ ``` --------- Co-authored-by: Zachary Collins <zachary.collins@sentry.io> Co-authored-by: Ryan Skonnord <ryan.skonnord@sentry.io>
- Loading branch information