-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(aci): schema validation for DataCondition.comparison #83457
Conversation
src/sentry/workflow_engine/types.py
Outdated
@@ -55,6 +55,11 @@ def bulk_get_query_object(data_sources) -> dict[int, T | None]: | |||
|
|||
|
|||
class DataConditionHandler(Generic[T]): | |||
@staticmethod | |||
def comparison_json_schema() -> dict[str, Any]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure how to have an abstract static property 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 does it need to be static? could we do something like this: https://github.com/getsentry/sentry/pull/83276/files#diff-3f0b18159f9863fd3bbfdce5d8d8374a8a7473fc4808031dd520f4a83e75dd66R65-R67 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think i assumed we don't want to initialize the handler, but we can! added abstract property
❌ 3 Tests Failed:
View the top 2 failed tests by shortest run time
View the full list of 1 ❄️ flaky tests
To view more test analytics, go to the Test Analytics Dashboard |
@receiver(pre_save, sender=DataCondition) | ||
def enforce_comparison_schema(sender, instance: DataCondition, **kwargs): | ||
from jsonschema import ValidationError, validate | ||
|
||
condition_type = Condition(instance.type) | ||
if condition_type in condition_ops: | ||
# don't enforce schema for default ops, this can be any type | ||
return | ||
|
||
try: | ||
handler = condition_handler_registry.get(instance.type) | ||
except NoRegistrationExistsError: | ||
logger.exception( | ||
"No registration exists for condition", | ||
extra={"type": instance.type, "id": instance.id}, | ||
) | ||
return None | ||
|
||
schema = handler.comparison_json_schema | ||
|
||
try: | ||
validate(instance.comparison, schema) | ||
except ValidationError as e: | ||
raise ValidationError(f"Invalid config: {e.message}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the important part
"time": "hour", | ||
} | ||
assert dc.condition_result is True | ||
assert dc.condition_group == dcg | ||
|
||
def test_json_schema(self): | ||
with pytest.raises(ValidationError): | ||
self.dc.comparison.update({"time": "asdf"}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the validation error is raised on save, right? maybe you can put the update outside of the pytest raise here to make that more clear
from jsonschema import ValidationError, validate | ||
|
||
condition_type = Condition(instance.type) | ||
if condition_type in condition_ops: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit but it would be nice for condition ops to be capitalized
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm - agree with colleen's nits :)
Add schema validation for
DataCondition
'scomparison
JSONField
. We need this to be absolutely sure the comparison field contains the correct information to be able to evaluate the condition in processors.This PR adds the schema validation for the
AgeComparison
condition as an example.