Пример #1
0
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 }}
''')
    assert rules._to_config_structure() == {
        'rules': [
            {'matchers': [['type', 'DatabaseUnavailable']],
             'fingerprint': ['DatabaseUnavailable']},
            {'matchers': [['function', 'assertion_failed'],
                          ['module', 'foo']],
             'fingerprint': ['AssertionFailed', 'foo']},
            {'matchers': [['app', 'true']],
             'fingerprint': ['aha']},
            {'matchers': [['app', 'true']],
             'fingerprint': ['{{ default }}']},
        ],
        'version': 1
    }

    assert FingerprintingRules._from_config_structure(
        rules._to_config_structure())._to_config_structure() == rules._to_config_structure()
Пример #2
0
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"]
            },
            {
                "matchers": [["function", "assertion_failed"],
                             ["module", "foo"]],
                "fingerprint": ["AssertionFailed", "foo"],
            },
            {
                "matchers": [["app", "true"]],
                "fingerprint": ["aha"]
            },
            {
                "matchers": [["app", "true"]],
                "fingerprint": ["{{ default }}"]
            },
        ],
        "version":
        1,
    }

    assert (FingerprintingRules._from_config_structure(
        rules._to_config_structure())._to_config_structure() ==
            rules._to_config_structure())
Пример #3
0
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 }}
"""
    )
    assert rules._to_config_structure() == {
        "rules": [
            {"matchers": [["type", "DatabaseUnavailable"]], "fingerprint": ["DatabaseUnavailable"]},
            {
                "matchers": [["function", "assertion_failed"], ["module", "foo"]],
                "fingerprint": ["AssertionFailed", "foo"],
            },
            {"matchers": [["app", "true"]], "fingerprint": ["aha"]},
            {"matchers": [["app", "true"]], "fingerprint": ["{{ default }}"]},
            {"matchers": [["!path", "**/foo/**"]], "fingerprint": ["everything"]},
            {"matchers": [["!path", "**/foo/**"]], "fingerprint": ["everything"]},
            {"matchers": [["logger", "sentry.*"]], "fingerprint": ["logger-", "{{ logger }}"]},
        ],
        "version": 1,
    }

    assert (
        FingerprintingRules._from_config_structure(
            rules._to_config_structure()
        )._to_config_structure()
        == rules._to_config_structure()
    )
Пример #4
0
    def validate_fingerprintingRules(self, value):
        if not value:
            return value

        try:
            FingerprintingRules.from_config_string(value)
        except InvalidFingerprintingConfig as e:
            raise serializers.ValidationError(str(e))

        return value
Пример #5
0
    def validate_fingerprintingRules(self, attrs, source):
        if not attrs[source]:
            return attrs

        try:
            FingerprintingRules.from_config_string(attrs[source])
        except InvalidFingerprintingConfig as e:
            raise serializers.ValidationError(e.message)

        return attrs
Пример #6
0
    def validate_fingerprintingRules(self, attrs, source):
        if not attrs[source]:
            return attrs

        try:
            FingerprintingRules.from_config_string(attrs[source])
        except InvalidFingerprintingConfig as e:
            raise serializers.ValidationError(e.message)

        return attrs
Пример #7
0
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 }}"]
            },
            {
                "matchers": [["logger", "test"]],
                "fingerprint": ["logger-", "{{ logger }}"]
            },
            {
                "matchers": [["logger", "test2"]],
                "fingerprint": ["logger-", "{{ logger }}", "-", "{{ level }}"],
            },
            {
                "matchers": [["logger", "test2"]],
                "fingerprint": ["logger-", "{{ logger }}", "-", "{{ level }}"],
            },
        ],
        "version":
        1,
    }
Пример #8
0
def test_event_hash_variant(insta_snapshot, testcase):
    with open(os.path.join(_fixture_path, testcase + '.json')) as f:
        input = json.load(f)

    config = FingerprintingRules.from_json({
        'rules': input.pop('_fingerprinting_rules'),
        'version': 1,
    })
    mgr = EventManager(data=input)
    mgr.normalize()
    data = mgr.get_data()

    data.setdefault('fingerprint', ['{{ default }}'])
    apply_server_fingerprinting(data, config)

    evt = Event(data=data, platform=data['platform'])

    def dump_variant(v):
        rv = v.as_dict()
        for key in 'component', 'description', 'hash', 'config':
            rv.pop(key, None)
        return rv

    insta_snapshot({
        'config': config.to_json(),
        'fingerprint': data['fingerprint'],
        'variants': {k: dump_variant(v)
                     for (k, v) in evt.get_grouping_variants().items()},
    })
Пример #9
0
def test_event_hash_variant(insta_snapshot, testcase):
    with open(os.path.join(_fixture_path, testcase + ".json")) as f:
        input = json.load(f)

    config = FingerprintingRules.from_json(
        {"rules": input.pop("_fingerprinting_rules"), "version": 1}
    )
    mgr = EventManager(data=input)
    mgr.normalize()
    data = mgr.get_data()

    data.setdefault("fingerprint", ["{{ default }}"])
    apply_server_fingerprinting(data, config)

    evt = Event(data=data, platform=data["platform"])

    def dump_variant(v):
        rv = v.as_dict()
        for key in "component", "description", "hash", "config":
            rv.pop(key, None)
        return rv

    insta_snapshot(
        {
            "config": config.to_json(),
            "fingerprint": data["fingerprint"],
            "variants": {k: dump_variant(v) for (k, v) in evt.get_grouping_variants().items()},
        }
    )
Пример #10
0
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.*"]],
    }
Пример #11
0
def get_fingerprinting_config_for_project(project):
    from sentry.grouping.fingerprinting import FingerprintingRules, \
        InvalidFingerprintingConfig
    rules = project.get_option('sentry:fingerprinting_rules')
    if not rules:
        return FingerprintingRules([])

    from sentry.utils.cache import cache
    from sentry.utils.hashlib import md5_text
    cache_key = 'fingerprinting-rules:' + md5_text(rules).hexdigest()
    rv = cache.get(cache_key)
    if rv is not None:
        return FingerprintingRules.from_json(rv)

    try:
        rv = FingerprintingRules.from_config_string(
            rules or '')
    except InvalidFingerprintingConfig:
        rv = FingerprintingRules([])
    cache.set(cache_key, rv.to_json())
    return rv
Пример #12
0
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
''')
    assert rules._to_config_structure() == {
        'rules': [
            {'matchers': [['type', 'DatabaseUnavailable']],
             'fingerprint': ['DatabaseUnavailable']},
            {'matchers': [['function', 'assertion_failed'],
                          ['module', 'foo']],
             'fingerprint': ['AssertionFailed', 'foo']},
            {'matchers': [['app', 'true']],
             'fingerprint': ['aha']},
        ],
        'version': 1
    }

    assert FingerprintingRules._from_config_structure(
        rules._to_config_structure())._to_config_structure() == rules._to_config_structure()
Пример #13
0
    def create_event(self, grouping_config=None):
        input = dict(self.data)

        config = FingerprintingRules.from_json(
            {"rules": input.pop("_fingerprinting_rules"), "version": 1}
        )
        mgr = EventManager(data=input, grouping_config=grouping_config)
        mgr.normalize()
        data = mgr.get_data()

        data.setdefault("fingerprint", ["{{ default }}"])
        apply_server_fingerprinting(data, config)
        data.update(materialize_metadata(data))

        evt = eventstore.create_event(data=data)
        return config, evt
Пример #14
0
def test_event_hash_variant(insta_snapshot, testcase):
    with open(os.path.join(_fixture_path, testcase + '.json')) as f:
        input = json.load(f)

    config = FingerprintingRules.from_json({
        'rules': input.pop('_fingerprinting_rules'),
        'version': 1,
    })
    mgr = EventManager(data=input)
    mgr.normalize()
    data = mgr.get_data()

    data.setdefault('fingerprint', ['{{ default }}'])
    apply_server_fingerprinting(data, config)

    insta_snapshot({
        'config': config.to_json(),
        'fingerprint': data['fingerprint'],
    })
Пример #15
0
def get_fingerprinting_config_for_project(project):
    from sentry.grouping.fingerprinting import FingerprintingRules, \
        InvalidFingerprintingConfig
    rules = project.get_option('sentry:fingerprinting_rules')
    if not rules:
        return FingerprintingRules([])

    from sentry.utils.cache import cache
    from sentry.utils.hashlib import md5_text
    cache_key = 'fingerprinting-rules:' + md5_text(rules).hexdigest()
    rv = cache.get(cache_key)
    if rv is not None:
        return FingerprintingRules.from_json(rv)

    try:
        rv = FingerprintingRules.from_config_string(rules)
    except InvalidFingerprintingConfig:
        rv = FingerprintingRules([])
    cache.set(cache_key, rv.to_json())
    return rv
Пример #16
0
def test_parsing_errors():
    with pytest.raises(InvalidFingerprintingConfig):
        FingerprintingRules.from_config_string("invalid.message:foo -> bar")