def test_should_reset_severity_according_to_rule( self, nested_severity_ruleset_source): rules = SeverityRules.load(nested_severity_ruleset_source) alert = Mock() alert.foo = "0xc0ffee" alert.bar = "0xbadc0de" assert rules.evaluate(alert) == 5
def test_should_add_to_severity_for_nested_rule( self, nested_severity_ruleset_source): rules = SeverityRules.load(nested_severity_ruleset_source) alert = Mock() alert.first = "level-one" alert.second = "level-two" assert rules.evaluate(alert) == 5
def test_should_properly_set_severity_based_on_nested_attributes( self, nested_severity_ruleset_source): rules = SeverityRules.load(nested_severity_ruleset_source) alert = Mock() alert.netbox.room.id = "Milliways" alert.netbox.room.location.id = "The end of the Universe" alert.netbox.category = "SW" assert rules.evaluate(alert) == 1
def test_should_parse_default_severity_correctly(self, simple_severity_ruleset): rules = SeverityRules._parse_raw_severity_rules( simple_severity_ruleset) expressions, modifier = next(rules) assert expressions == () assert modifier( None) == 2, "first rule isn't the default severity level"
def test_should_return_modifiers_that_take_int_and_return_int( self, nested_severity_ruleset): for expressions, modifier in SeverityRules._parse_raw_severity_rules( nested_severity_ruleset): assert callable( modifier), f"modifier isn't callable for rule {expressions!r}" assert isinstance( modifier(Severity(3)), int ), f"modifier does not follow protocol for rule {expressions!r}"
def test_should_ignore_broken_rules(self, broken_ruleset_source): rules = SeverityRules.load(broken_ruleset_source) class MockAlert: """Simple Alert mock that does NOT ignore illegal attribute accesses""" severity = 5 assert rules.evaluate(MockAlert()) == 5
def test_should_find_perfectly_cromulent_rule(self, simple_severity_ruleset): rules = SeverityRules._parse_raw_severity_rules( simple_severity_ruleset) _ = next(rules) # toss default severity level rule expressions, modifier = next(rules) assert expressions == ( Expression("foo", "perfectly-cromulent"), ), "the second rule in the ruleset was not parsed correctly" assert callable(modifier)
def test_should_parse_nested_rule_correctly(self, nested_severity_ruleset): rules = SeverityRules._parse_raw_severity_rules( nested_severity_ruleset) _ = next(rules), next(rules) # skip two first rules expressions, modifier = next(rules) assert expressions == ( Expression("first", "level-one"), Expression("second", "level-two"), ), "could not find a properly parsed nested rule" assert callable(modifier)
def test_should_parse_compound_rule_correctly(self, nested_severity_ruleset): rules = SeverityRules._parse_raw_severity_rules( nested_severity_ruleset) _ = next(rules), next(rules), next(rules) # skip first three expressions, modifier = next(rules) assert expressions == ( Expression("foo", "0xc0ffee"), Expression("bar", "0xbadc0de"), ), "could not find a properly parsed compound rule" assert callable(modifier)
def should_raise_value_error_on_invalid_value(self): with pytest.raises(ValueError): SeverityRules._parse_modifier("foo")
def test_should_evaluate_to_single_rule_on_empty_rulesets( self, empty_ruleset_source): """Tests that an empty ruleset is parsed into a single default-value rule """ rules = SeverityRules.load(empty_ruleset_source) assert len(rules) == 1
def test_should_set_default_severity(self, simple_severity_ruleset_source): rules = SeverityRules.load(simple_severity_ruleset_source) alert = Mock() assert rules.evaluate(alert) == 2
def test_should_translate_ruleset_without_errors( self, simple_severity_ruleset_source): assert SeverityRules.load(simple_severity_ruleset_source)
def test_should_load_simple_ruleset_without_error(self, simple_severity_ruleset): assert list( SeverityRules._parse_raw_severity_rules(simple_severity_ruleset))
def test_should_return_original_severity_on_empty_ruleset(self): rules = SeverityRules._parse_raw_severity_rules({}) expressions, modifier = next(rules) assert expressions == () assert modifier(5) == 5
def test_should_parse_addition_correctly(self): modifier = SeverityRules._parse_modifier("+2") assert modifier(1) == 1 + 2
def _load_severity_rules(): # Imbues the AlertGenerator class with user-defined severity rules AlertGenerator.severity_rules = SeverityRules.load_from_file()
def test_should_add_to_severity_for_simple_rule( self, simple_severity_ruleset_source): rules = SeverityRules.load(simple_severity_ruleset_source) alert = Mock() alert.foo = "perfectly-cromulent" assert rules.evaluate(alert) == 3
def test_should_parse_int_correctly(self): modifier = SeverityRules._parse_modifier(3) assert modifier(None) == 3
def test_should_return_original_severity_when_no_default_is_set( self, empty_ruleset_source): rules = SeverityRules.load(empty_ruleset_source) alert = Mock() alert.severity = 1 assert rules.evaluate(alert) == 1
def test_should_be_valid(self): full_path = find_config_file(CONFIG_FILE) assert full_path, f"Could not find severity rule config file {CONFIG_FILE}" assert SeverityRules.load_from_file(full_path)
def test_should_parse_subtraction_correctly(self): modifier = SeverityRules._parse_modifier("-2") assert modifier(5) == 5 - 2