fix(alerts): execute query as report executor (#22167)

This commit is contained in:
Ville Brofeldt 2022-11-18 14:22:56 +02:00 committed by GitHub
parent 25114a7b97
commit c3f9f0bf69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 6 deletions

View File

@ -25,7 +25,7 @@ import pandas as pd
from celery.exceptions import SoftTimeLimitExceeded
from flask_babel import lazy_gettext as _
from superset import app, jinja_context, security_manager
from superset import app, jinja_context
from superset.commands.base import BaseCommand
from superset.reports.commands.exceptions import (
AlertQueryError,
@ -36,6 +36,7 @@ from superset.reports.commands.exceptions import (
AlertValidatorConfigError,
)
from superset.reports.models import ReportSchedule, ReportScheduleValidatorType
from superset.reports.utils import get_executor
from superset.utils.core import override_user
from superset.utils.retries import retry_call
@ -148,11 +149,8 @@ class AlertCommand(BaseCommand):
rendered_sql, ALERT_SQL_LIMIT
)
with override_user(
security_manager.find_user(
username=app.config["THUMBNAIL_SELENIUM_USER"]
)
):
user = get_executor(self._report_schedule)
with override_user(user):
start = default_timer()
df = self._report_schedule.database.get_df(sql=limited_rendered_sql)
stop = default_timer()

View File

@ -15,10 +15,80 @@
# specific language governing permissions and limitations
# under the License.
# pylint: disable=invalid-name, unused-argument, import-outside-toplevel
from contextlib import nullcontext
from typing import List, Optional, Union
import pandas as pd
import pytest
from pytest_mock import MockFixture
from superset.reports.commands.exceptions import AlertQueryError
from superset.reports.models import ReportCreationMethod, ReportScheduleType
from superset.reports.types import ReportScheduleExecutor
from superset.utils.database import get_example_database
from tests.integration_tests.test_app import app
@pytest.mark.parametrize(
"owner_names,creator_name,config,expected_result",
[
(["gamma"], None, [ReportScheduleExecutor.SELENIUM], "admin"),
(["gamma"], None, [ReportScheduleExecutor.OWNER], "gamma"),
(["alpha", "gamma"], "gamma", [ReportScheduleExecutor.CREATOR_OWNER], "gamma"),
(["alpha", "gamma"], "alpha", [ReportScheduleExecutor.CREATOR_OWNER], "alpha"),
(
["alpha", "gamma"],
"admin",
[ReportScheduleExecutor.CREATOR_OWNER],
AlertQueryError(),
),
],
)
def test_execute_query_as_report_executor(
owner_names: List[str],
creator_name: Optional[str],
config: List[ReportScheduleExecutor],
expected_result: Union[str, Exception],
mocker: MockFixture,
app_context: None,
get_user,
) -> None:
from superset.reports.commands.alert import AlertCommand
from superset.reports.models import ReportSchedule
with app.app_context():
original_config = app.config["ALERT_REPORTS_EXECUTE_AS"]
app.config["ALERT_REPORTS_EXECUTE_AS"] = config
owners = [get_user(owner_name) for owner_name in owner_names]
report_schedule = ReportSchedule(
created_by=get_user(creator_name) if creator_name else None,
owners=owners,
type=ReportScheduleType.ALERT,
description="description",
crontab="0 9 * * *",
creation_method=ReportCreationMethod.ALERTS_REPORTS,
sql="SELECT 1",
grace_period=14400,
working_timeout=3600,
database=get_example_database(),
validator_config_json='{"op": "==", "threshold": 1}',
)
command = AlertCommand(report_schedule=report_schedule)
override_user_mock = mocker.patch(
"superset.reports.commands.alert.override_user"
)
cm = (
pytest.raises(type(expected_result))
if isinstance(expected_result, Exception)
else nullcontext()
)
with cm:
command.run()
assert override_user_mock.call_args[0][0].username == expected_result
app.config["ALERT_REPORTS_EXECUTE_AS"] = original_config
def test_execute_query_succeeded_no_retry(
mocker: MockFixture, app_context: None