fix(alerts): void query with numeric comparison (#13090)

* fix(alerts): void query with numeric comparison

* remove config changes

* fix tests

* better logic

* fix logic

* fix logic

* Improve test readability
This commit is contained in:
Daniel Vaz Gaspar 2021-02-15 17:09:47 +00:00 committed by GitHub
parent 613945a200
commit 2e6ea76631
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 6 deletions

View File

@ -47,15 +47,16 @@ class AlertCommand(BaseCommand):
def run(self) -> bool:
self.validate()
if self._report_schedule.validator_type == ReportScheduleValidatorType.NOT_NULL:
if self._is_validator_not_null:
self._report_schedule.last_value_row_json = str(self._result)
return self._result not in (0, None, np.nan)
return self._result is not None
self._report_schedule.last_value = self._result
try:
operator = json.loads(self._report_schedule.validator_config_json)["op"]
threshold = json.loads(self._report_schedule.validator_config_json)[
"threshold"
]
return OPERATOR_FUNCTIONS[operator](self._result, threshold)
except (KeyError, json.JSONDecodeError):
raise AlertValidatorConfigError()
@ -95,6 +96,18 @@ class AlertCommand(BaseCommand):
except (AssertionError, TypeError, ValueError):
raise AlertQueryInvalidTypeError()
@property
def _is_validator_not_null(self) -> bool:
return (
self._report_schedule.validator_type == ReportScheduleValidatorType.NOT_NULL
)
@property
def _is_validator_operator(self) -> bool:
return (
self._report_schedule.validator_type == ReportScheduleValidatorType.OPERATOR
)
def validate(self) -> None:
"""
Validate the query result as a Pandas DataFrame
@ -108,10 +121,14 @@ class AlertCommand(BaseCommand):
except Exception as ex:
raise AlertQueryError(message=str(ex))
if df.empty:
if df.empty and self._is_validator_not_null:
self._result = None
return
if df.empty and self._is_validator_operator:
self._result = 0.0
return
rows = df.to_records()
if self._report_schedule.validator_type == ReportScheduleValidatorType.NOT_NULL:
if self._is_validator_not_null:
self._validate_not_null(rows)
return
self._validate_operator(rows)

View File

@ -308,7 +308,7 @@ def create_test_table_context(database: Database):
@pytest.yield_fixture(
params=["alert1", "alert2", "alert3", "alert4", "alert5", "alert6"]
params=["alert1", "alert2", "alert3", "alert4", "alert5", "alert6", "alert7"]
)
def create_no_alert_email_chart(request):
param_config = {
@ -338,10 +338,15 @@ def create_no_alert_email_chart(request):
"validator_config_json": '{"op": "!=", "threshold": 10}',
},
"alert6": {
"sql": "SELECT first from test_table where first=0",
"sql": "SELECT first from test_table where 1=0",
"validator_type": ReportScheduleValidatorType.NOT_NULL,
"validator_config_json": "{}",
},
"alert7": {
"sql": "SELECT first from test_table where 1=0",
"validator_type": ReportScheduleValidatorType.OPERATOR,
"validator_config_json": '{"op": ">", "threshold": 0}',
},
}
with app.app_context():
chart = db.session.query(Slice).first()