mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
187 lines
6.5 KiB
Python
187 lines
6.5 KiB
Python
import pytest
|
|
|
|
from sentry.grouping.api import get_default_grouping_config_dict
|
|
from sentry.grouping.fingerprinting import FingerprintingRules, InvalidFingerprintingConfig
|
|
from tests.sentry.grouping import with_fingerprint_input
|
|
|
|
GROUPING_CONFIG = get_default_grouping_config_dict()
|
|
|
|
|
|
def test_basic_parsing(insta_snapshot):
|
|
rules = FingerprintingRules.from_config_string(
|
|
"""
|
|
# This is a config
|
|
type:DatabaseUnavailable -> DatabaseUnavailable
|
|
function:assertion_failed module:foo -> AssertionFailed, foo
|
|
app:true -> aha
|
|
app:true -> {{ default }}
|
|
!path:**/foo/** -> everything
|
|
!"path":**/foo/** -> everything
|
|
logger:sentry.* -> logger-, {{ logger }}
|
|
message:"\\x\\xff" -> stuff
|
|
logger:sentry.* -> logger-{{ logger }}, title="Message from {{ logger }}"
|
|
logger:sentry.* -> logger-{{ logger }} title="Message from {{ logger }}"
|
|
"""
|
|
)
|
|
assert rules._to_config_structure() == {
|
|
"rules": [
|
|
{
|
|
"matchers": [["type", "DatabaseUnavailable"]],
|
|
"fingerprint": ["DatabaseUnavailable"],
|
|
"attributes": {},
|
|
},
|
|
{
|
|
"matchers": [["function", "assertion_failed"], ["module", "foo"]],
|
|
"fingerprint": ["AssertionFailed", "foo"],
|
|
"attributes": {},
|
|
},
|
|
{"matchers": [["app", "true"]], "fingerprint": ["aha"], "attributes": {}},
|
|
{"matchers": [["app", "true"]], "fingerprint": ["{{ default }}"], "attributes": {}},
|
|
{"matchers": [["!path", "**/foo/**"]], "fingerprint": ["everything"], "attributes": {}},
|
|
{"matchers": [["!path", "**/foo/**"]], "fingerprint": ["everything"], "attributes": {}},
|
|
{
|
|
"matchers": [["logger", "sentry.*"]],
|
|
"fingerprint": ["logger-", "{{ logger }}"],
|
|
"attributes": {},
|
|
},
|
|
{"matchers": [["message", "\\x\xff"]], "fingerprint": ["stuff"], "attributes": {}},
|
|
{
|
|
"matchers": [["logger", "sentry.*"]],
|
|
"fingerprint": ["logger-", "{{ logger }}"],
|
|
"attributes": {"title": "Message from {{ logger }}"},
|
|
},
|
|
{
|
|
"matchers": [["logger", "sentry.*"]],
|
|
"fingerprint": ["logger-", "{{ logger }}"],
|
|
"attributes": {"title": "Message from {{ logger }}"},
|
|
},
|
|
],
|
|
"version": 1,
|
|
}
|
|
|
|
assert (
|
|
FingerprintingRules._from_config_structure(
|
|
rules._to_config_structure()
|
|
)._to_config_structure()
|
|
== rules._to_config_structure()
|
|
)
|
|
|
|
|
|
def test_rule_export():
|
|
rules = FingerprintingRules.from_config_string(
|
|
"""
|
|
logger:sentry.* -> logger, {{ logger }}, title="Message from {{ logger }}"
|
|
"""
|
|
)
|
|
assert rules.rules[0].to_json() == {
|
|
"attributes": {"title": "Message from {{ logger }}"},
|
|
"fingerprint": ["logger", "{{ logger }}"],
|
|
"matchers": [["logger", "sentry.*"]],
|
|
}
|
|
|
|
|
|
def test_parsing_errors():
|
|
with pytest.raises(InvalidFingerprintingConfig):
|
|
FingerprintingRules.from_config_string("invalid.message:foo -> bar")
|
|
|
|
|
|
def test_automatic_argument_splitting():
|
|
rules = FingerprintingRules.from_config_string(
|
|
"""
|
|
logger:test -> logger-{{ logger }}
|
|
logger:test -> logger-, {{ logger }}
|
|
logger:test2 -> logger-{{ logger }}-{{ level }}
|
|
logger:test2 -> logger-, {{ logger }}, -, {{ level }}
|
|
"""
|
|
)
|
|
assert rules._to_config_structure() == {
|
|
"rules": [
|
|
{
|
|
"matchers": [["logger", "test"]],
|
|
"fingerprint": ["logger-", "{{ logger }}"],
|
|
"attributes": {},
|
|
},
|
|
{
|
|
"matchers": [["logger", "test"]],
|
|
"fingerprint": ["logger-", "{{ logger }}"],
|
|
"attributes": {},
|
|
},
|
|
{
|
|
"matchers": [["logger", "test2"]],
|
|
"fingerprint": ["logger-", "{{ logger }}", "-", "{{ level }}"],
|
|
"attributes": {},
|
|
},
|
|
{
|
|
"matchers": [["logger", "test2"]],
|
|
"fingerprint": ["logger-", "{{ logger }}", "-", "{{ level }}"],
|
|
"attributes": {},
|
|
},
|
|
],
|
|
"version": 1,
|
|
}
|
|
|
|
|
|
def test_discover_field_parsing(insta_snapshot):
|
|
rules = FingerprintingRules.from_config_string(
|
|
"""
|
|
# This is a config
|
|
error.type:DatabaseUnavailable -> DatabaseUnavailable
|
|
stack.function:assertion_failed stack.module:foo -> AssertionFailed, foo
|
|
app:true -> aha
|
|
app:true -> {{ default }}
|
|
"""
|
|
)
|
|
assert rules._to_config_structure() == {
|
|
"rules": [
|
|
{
|
|
"matchers": [["type", "DatabaseUnavailable"]],
|
|
"fingerprint": ["DatabaseUnavailable"],
|
|
"attributes": {},
|
|
},
|
|
{
|
|
"matchers": [["function", "assertion_failed"], ["module", "foo"]],
|
|
"fingerprint": ["AssertionFailed", "foo"],
|
|
"attributes": {},
|
|
},
|
|
{"matchers": [["app", "true"]], "fingerprint": ["aha"], "attributes": {}},
|
|
{"matchers": [["app", "true"]], "fingerprint": ["{{ default }}"], "attributes": {}},
|
|
],
|
|
"version": 1,
|
|
}
|
|
|
|
assert (
|
|
FingerprintingRules._from_config_structure(
|
|
rules._to_config_structure()
|
|
)._to_config_structure()
|
|
== rules._to_config_structure()
|
|
)
|
|
|
|
|
|
@with_fingerprint_input("input")
|
|
def test_event_hash_variant(insta_snapshot, input):
|
|
config, evt = input.create_event()
|
|
|
|
def dump_variant(v):
|
|
rv = v.as_dict()
|
|
|
|
for key in "hash", "description", "config":
|
|
rv.pop(key, None)
|
|
|
|
if "component" in rv:
|
|
for key in "id", "name", "values":
|
|
rv["component"].pop(key, None)
|
|
|
|
return rv
|
|
|
|
insta_snapshot(
|
|
{
|
|
"config": config.to_json(),
|
|
"fingerprint": evt.data["fingerprint"],
|
|
"title": evt.data["title"],
|
|
"variants": {
|
|
k: dump_variant(v)
|
|
for (k, v) in evt.get_grouping_variants(force_config=GROUPING_CONFIG).items()
|
|
},
|
|
}
|
|
)
|