def test_constraints_check_same_cause_parser_as_effect(self): rule = Rule( [self.cause_a], self.cause_a, [ { 'clues_groups': [[0, 1], [1, 1]], 'name': 'identical', 'params': {} } ], Rule.LINKAGE_AND ) # yapf: disable effect_clues_dict = { 'cause_a': Clue((42, ), '42 carrots', 1420, self.line_source) } clues = { # it's dictionary of the same type as clues dict collected in SearchManager 'cause_a': [ Clue((40,), '40 carrots', 400, self.line_source), Clue((42,), '42 carrots', 420, self.line_source), Clue((44,), '44 carrots', 440, self.line_source) ], 'dummy': [ Clue((98,), '98 foo bar', 980, self.line_source), Clue((99,), '99 foo bar', 990, self.line_source) ] } # yapf: disable results = rule.constraints_check(clues, effect_clues_dict) assert len(results) == 1 assert results[0].lines == [ FrontInput.from_clue( Clue((42,), '42 carrots', 420, self.line_source)) ] # yapf: disable
def test_one_matched_line_when_two_occurrences_requested(self): rule = Rule( [self.cause_a, self.cause_a], self.effect, [ { 'clues_groups': [[0, 1], [1, 1], [2, 1]], 'name': 'identical', 'params': {} } ], Rule.LINKAGE_AND ) # yapf: disable effect_clues_dict = { 'effect': Clue((42, ), '42 dinners', 1420, self.line_source) } clues = { # it's dictionary of the same type as clues dict collected in SearchManager 'cause_a': [ Clue((42,), '42 carrots', 420, self.line_source), ], 'dummy': [ Clue((98,), '98 foo bar', 980, self.line_source), Clue((99,), '99 foo bar', 990, self.line_source) ] } # yapf: disable results = rule.constraints_check(clues, effect_clues_dict) assert effect_clues_dict['effect'].regex_parameters[0] == \ clues['cause_a'][0].regex_parameters[0] assert not results
def test_not_one_constraint_something_matched_but_constraint_rejected_it(self): rule = Rule( [self.cause_a], self.effect, [ { 'clues_groups': [[0, 1], [1, 1]], 'name': 'identical', 'params': {} } ], Rule.LINKAGE_NOT ) # yapf: disable effect_clues_dict = {'effect': Clue((42,), '42 dinners', 1420, self.line_source)} clues = { 'cause_a': [ Clue((13,), '13 carrots', 130, self.line_source), ], 'dummy': [ Clue((98,), '98 foo bar', 980, self.line_source), Clue((99,), '99 foo bar', 990, self.line_source) ] } # yapf: disable results = rule.constraints_check(clues, effect_clues_dict) assert results assert len(results) == 1 assert results[0].lines == [] assert results[0].constraints_linkage == InvestigationResult.NOT
def test_not_one_constraint_something_matched_but_constraint_rejected_it( self): rule = Rule( [self.cause_a], self.effect, [ { 'clues_groups': [[0, 1], [1, 1]], 'name': 'identical', 'params': {} } ], Rule.LINKAGE_NOT ) # yapf: disable effect_clues_dict = { 'effect': Clue((42, ), '42 dinners', 1420, self.line_source) } clues = { 'cause_a': [ Clue((13,), '13 carrots', 130, self.line_source), ], 'dummy': [ Clue((98,), '98 foo bar', 980, self.line_source), Clue((99,), '99 foo bar', 990, self.line_source) ] } # yapf: disable results = rule.constraints_check(clues, effect_clues_dict) assert results assert len(results) == 1 assert results[0].lines == [] assert results[0].constraints_linkage == InvestigationResult.NOT
def test_constraints_check_same_cause_parser_as_effect(self): rule = Rule( [self.cause_a], self.cause_a, [ { 'clues_groups': [[0, 1], [1, 1]], 'name': 'identical', 'params': {} } ], Rule.LINKAGE_AND ) # yapf: disable effect_clues_dict = {'cause_a': Clue((42,), '42 carrots', 1420, self.line_source)} clues = { # it's dictionary of the same type as clues dict collected in SearchManager 'cause_a': [ Clue((40,), '40 carrots', 400, self.line_source), Clue((42,), '42 carrots', 420, self.line_source), Clue((44,), '44 carrots', 440, self.line_source) ], 'dummy': [ Clue((98,), '98 foo bar', 980, self.line_source), Clue((99,), '99 foo bar', 990, self.line_source) ] } # yapf: disable results = rule.constraints_check(clues, effect_clues_dict) assert len(results) == 1 assert results[0].lines == [ FrontInput.from_clue( Clue((42,), '42 carrots', 420, self.line_source)) ] # yapf: disable
def test_search_range_two_constraints_on_one_group(self): constraints1 = [ { 'clues_groups': [[1, 1], [0, 1]], 'name': ConstraintType.TIME_DELTA, 'params': { 'max_delta': 100, 'min_delta': 10 } }, { 'clues_groups': [[2, 1], [0, 1]], 'name': ConstraintType.TIME_DELTA, 'params': { 'max_delta': 100, } }, { 'clues_groups': [[2, 3], [0, 2]], 'name': 'identical', 'params': {} }, ] # yapf: disable rule = Rule([self.cause2, self.cause2], self.effect, constraints1, Rule.LINKAGE_AND) calculated_ranges = self.calculate_range([rule]) expected_ranges = { 'apache': { 'date': { InvestigationStep.LEFT_BOUND: self.one_hundred_second_earlier, InvestigationStep.RIGHT_BOUND: self.effect_time } } } # yapf: disable assert calculated_ranges == expected_ranges rule = Rule([self.cause2, self.cause2], self.effect, constraints1, Rule.LINKAGE_OR) calculated_ranges = self.calculate_range([rule]) expected_ranges = { 'apache': { 'date': { InvestigationStep.LEFT_BOUND: self.earliest_date, InvestigationStep.RIGHT_BOUND: self.effect_time } } } # yapf: disable assert calculated_ranges == expected_ranges
def test_search_range_reasoning_on_not_only_effect(self): constraints1 = [ { 'clues_groups': [[1, 1], [0, 1]], 'name': ConstraintType.TIME_DELTA, 'params': { 'max_delta': 75, 'min_delta': 10 } }, { 'clues_groups': [[2, 1], [1, 1]], 'name': ConstraintType.TIME_DELTA, 'params': {'max_delta': 25} }, ] # yapf: disable rule = Rule([self.cause2, self.cause2], self.effect, constraints1, Rule.LINKAGE_AND) calculated_ranges = self.calculate_range([rule]) expected_ranges = { 'apache': { 'date': { InvestigationStep.LEFT_BOUND: self.one_hundred_second_earlier, InvestigationStep.RIGHT_BOUND: self.ten_second_earlier } } } # yapf: disable assert calculated_ranges == expected_ranges
def test_search_range_two_log_types(self): constraints1 = [ { 'clues_groups': [[1, 1], [0, 1]], 'name': 'time', 'params': { 'max_delta': 100, 'min_delta': 10 } }, { 'clues_groups': [[2, 1], [0, 1]], 'name': 'time', 'params': {'max_delta': 10} } ] # yapf: disable rule = Rule([self.cause1, self.cause2], self.effect, constraints1, Rule.LINKAGE_AND) calculated_ranges = self.calculate_range([rule]) expected_ranges = { 'database': { 'date': { InvestigationStep.LEFT_BOUND: self.one_hundred_second_earlier, InvestigationStep.RIGHT_BOUND: self.ten_second_earlier } }, 'apache': { 'date': { InvestigationStep.LEFT_BOUND: self.ten_second_earlier, InvestigationStep.RIGHT_BOUND: self.effect_time } } } # yapf: disable raise SkipTest('Not implemented yet') assert calculated_ranges == expected_ranges
def mocked_investigation_plan(): super_parser = RegexSuperParser('^(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d).*', [1], {1: 'date'}) matcher = WildCardFilenameMatcher('localhost', 'node_1.log', 'default', super_parser) default_log_type = LogType('default', [matcher]) cause = RegexParser( 'cause', '2015-12-03 12:08:08 root cause', '^(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d) root cause$', [1], 'default', {1: 'date'} ) effect = RegexParser( 'effect', '2015-12-03 12:08:09 visible effect', '^(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d) visible effect$', [1], 'default', {1: 'date'} ) concatenated = ConcatenatedRegexParser([cause]) effect_time = datetime(2015, 12, 3, 12, 8, 9) search_range = { 'default': { 'date': { 'left_bound': datetime(2015, 12, 3, 12, 8, 8), 'right_bound': effect_time } } } default_investigation_step = InvestigationStep(concatenated, search_range) rule = Rule( [cause], effect, [ { 'clues_groups': [[1, 1], [0, 1]], 'name': 'time', 'params': {'max_delta': 1} } ], Rule.LINKAGE_AND ) # yapf: disable line_source = LineSource('localhost', 'node_1.log') effect_clues = {'effect': Clue((effect_time,), 'visible effect', 40, line_source)} return InvestigationPlan([rule], [(default_investigation_step, default_log_type)], effect_clues)
def test_search_range_multiple_rules(self): constraints1 = [ { 'clues_groups': [[1, 1], [0, 1]], 'name': ConstraintType.TIME_DELTA, 'params': {'max_delta': 10} } ] # yapf: disable rule1 = Rule([self.cause2], self.effect, constraints1, Rule.LINKAGE_AND) constraints2 = [ { 'clues_groups': [[1, 1], [0, 1]], 'name': ConstraintType.TIME_DELTA, 'params': { 'max_delta': 100, 'min_delta': 10 } }, { 'clues_groups': [[2, 1], [0, 1]], 'name': ConstraintType.TIME_DELTA, 'params': {'max_delta': 100} } ] # yapf: disable rule2 = Rule([self.cause1, self.cause2], self.effect, constraints2, Rule.LINKAGE_AND) calculated_ranges = self.calculate_range([rule1, rule2]) expected_ranges = { 'database': { 'date': { InvestigationStep.LEFT_BOUND: self.one_hundred_second_earlier, InvestigationStep.RIGHT_BOUND: self.ten_second_earlier } }, 'apache': { 'date': { InvestigationStep.LEFT_BOUND: self.one_hundred_second_earlier, InvestigationStep.RIGHT_BOUND: self.effect_time } } } # yapf: disable assert calculated_ranges == expected_ranges
def test_empty_clues_going_to_verify(self): rule = Rule( [self.cause_a, self.cause_a], self.effect, [ { 'clues_groups': [[0, 1], [1, 1], [2, 1]], 'name': 'identical', 'params': {} } ], Rule.LINKAGE_AND ) # yapf: disable effect_clues_dict = {'effect': Clue((42,), '42 dinners', 1420, self.line_source)} clues = { # it's dictionary of the same type as clues dict collected in SearchManager 'cause_a': [], 'dummy': [ Clue((98,), '98 foo bar', 980, self.line_source), Clue((99,), '99 foo bar', 990, self.line_source) ] } # yapf: disable results = rule.constraints_check(clues, effect_clues_dict) assert not results
def test_not_one_constraint_something_matched_but_constraint_approves(self): rule = Rule( [self.cause_a], self.effect, [ { 'clues_groups': [[0, 1], [1, 1]], 'name': 'identical', 'params': {} } ], Rule.LINKAGE_NOT ) # yapf: disable effect_clues_dict = {'effect': Clue((42,), '42 dinners', 1420, self.line_source)} clues = { 'cause_a': [ Clue((42,), '42 carrots', 420, self.line_source), ], 'dummy': [ Clue((98,), '98 foo bar', 980, self.line_source), Clue((99,), '99 foo bar', 990, self.line_source) ] } # yapf: disable results = rule.constraints_check(clues, effect_clues_dict) assert not results
def test_constraints_check_basic(self): rule = Rule( [self.cause_a, self.cause_b], self.effect, [ { 'clues_groups': [[0, 1], [1, 1], [2, 1]], 'name': 'identical', 'params': {} } ], Rule.LINKAGE_AND ) # yapf: disable effect_clues_dict = { 'effect': Clue((42, ), '42 dinners', 1420, self.line_source) } clues = { # it's dictionary of the same type as clues dict collected in SearchManager 'cause_a': [ Clue((40,), '40 carrots', 400, self.line_source), Clue((42,), '42 carrots', 420, self.line_source), Clue((44,), '44 carrots', 440, self.line_source) ], 'cause_b': [ Clue((32,), '32 broccoli', 100, self.line_source), Clue((42,), '42 broccoli', 120, self.line_source), Clue((52,), '52 broccoli', 140, self.line_source) ], 'dummy': [ Clue((42,), '42 foo bar', 980, self.line_source), Clue((84,), '84 foo bar', 990, self.line_source) ] } # yapf: disable results = rule.constraints_check(clues, effect_clues_dict) assert len(results) == 1 assert results[0].lines == [ FrontInput.from_clue( Clue((42,), '42 carrots', 420, self.line_source)), FrontInput.from_clue( Clue((42,), '42 broccoli', 120, self.line_source)) ] # yapf: disable
def test_empty_clues_going_to_verify(self): rule = Rule( [self.cause_a, self.cause_a], self.effect, [ { 'clues_groups': [[0, 1], [1, 1], [2, 1]], 'name': 'identical', 'params': {} } ], Rule.LINKAGE_AND ) # yapf: disable effect_clues_dict = { 'effect': Clue((42, ), '42 dinners', 1420, self.line_source) } clues = { # it's dictionary of the same type as clues dict collected in SearchManager 'cause_a': [], 'dummy': [ Clue((98,), '98 foo bar', 980, self.line_source), Clue((99,), '99 foo bar', 990, self.line_source) ] } # yapf: disable results = rule.constraints_check(clues, effect_clues_dict) assert not results
def test_constraints_check_basic(self): rule = Rule( [self.cause_a, self.cause_b], self.effect, [ { 'clues_groups': [[0, 1], [1, 1], [2, 1]], 'name': 'identical', 'params': {} } ], Rule.LINKAGE_AND ) # yapf: disable effect_clues_dict = {'effect': Clue((42,), '42 dinners', 1420, self.line_source)} clues = { # it's dictionary of the same type as clues dict collected in SearchManager 'cause_a': [ Clue((40,), '40 carrots', 400, self.line_source), Clue((42,), '42 carrots', 420, self.line_source), Clue((44,), '44 carrots', 440, self.line_source) ], 'cause_b': [ Clue((32,), '32 broccoli', 100, self.line_source), Clue((42,), '42 broccoli', 120, self.line_source), Clue((52,), '52 broccoli', 140, self.line_source) ], 'dummy': [ Clue((42,), '42 foo bar', 980, self.line_source), Clue((84,), '84 foo bar', 990, self.line_source) ] } # yapf: disable results = rule.constraints_check(clues, effect_clues_dict) assert len(results) == 1 assert results[0].lines == [ FrontInput.from_clue( Clue((42,), '42 carrots', 420, self.line_source)), FrontInput.from_clue( Clue((42,), '42 broccoli', 120, self.line_source)) ] # yapf: disable
def test_one_matched_line_when_two_occurrences_requested(self): rule = Rule( [self.cause_a, self.cause_a], self.effect, [ { 'clues_groups': [[0, 1], [1, 1], [2, 1]], 'name': 'identical', 'params': {} } ], Rule.LINKAGE_AND ) # yapf: disable effect_clues_dict = {'effect': Clue((42,), '42 dinners', 1420, self.line_source)} clues = { # it's dictionary of the same type as clues dict collected in SearchManager 'cause_a': [ Clue((42,), '42 carrots', 420, self.line_source), ], 'dummy': [ Clue((98,), '98 foo bar', 980, self.line_source), Clue((99,), '99 foo bar', 990, self.line_source) ] } # yapf: disable results = rule.constraints_check(clues, effect_clues_dict) assert effect_clues_dict['effect'].regex_parameters[0] == \ clues['cause_a'][0].regex_parameters[0] assert not results
def test_search_range_lack_of_right_bound(self): constraints1 = [ { 'clues_groups': [[1, 1], [0, 1]], 'name': ConstraintType.TIME_DELTA, 'params': {'max_delta': 10} }, ] # yapf: disable rule = Rule([self.cause1], self.effect, constraints1, Rule.LINKAGE_AND) calculated_ranges = self.calculate_range([rule]) expected_ranges = { 'database': { 'date': { InvestigationStep.LEFT_BOUND: self.ten_second_earlier, InvestigationStep.RIGHT_BOUND: self.effect_time } }, } # yapf: disable assert calculated_ranges == expected_ranges
def test_search_range_single_log_types(self): constraints = [ { 'clues_groups': [[1, 1], [0, 1]], 'name': ConstraintType.TIME_DELTA, 'params': {'max_delta': 10} } ] # yapf: disable rule = Rule([self.cause2], self.effect, constraints, Rule.LINKAGE_AND) calculated_ranges = self.calculate_range([rule]) expected_ranges = { 'apache': { 'date': { InvestigationStep.LEFT_BOUND: self.ten_second_earlier, InvestigationStep.RIGHT_BOUND: self.effect_time } } } # yapf: disable assert calculated_ranges == expected_ranges
def test_search_range_no_constraints_on_primary_values(self): rule = Rule([self.cause1, self.cause2], self.effect, [], Rule.LINKAGE_AND) calculated_ranges = self.calculate_range([rule]) expected_ranges = { 'apache': { 'date': { InvestigationStep.LEFT_BOUND: self.earliest_date, InvestigationStep.RIGHT_BOUND: self.effect_time } }, 'database': { 'date': { InvestigationStep.LEFT_BOUND: self.earliest_date, InvestigationStep.RIGHT_BOUND: self.effect_time } } } # yapf: disable assert calculated_ranges == expected_ranges
def test_search_range_lack_of_left_bound(self): constraints1 = [ { 'clues_groups': [[1, 1], [0, 1]], 'name': 'time', 'params': {'min_delta': 10} }, ] # yapf: disable rule = Rule([self.cause1], self.effect, constraints1, Rule.LINKAGE_AND) calculated_ranges = self.calculate_range([rule]) expected_ranges = { 'database': { 'date': { InvestigationStep.LEFT_BOUND: self.earliest_date, InvestigationStep.RIGHT_BOUND: self.ten_second_earlier } }, } # yapf: disable raise SkipTest('Not implemented yet') assert calculated_ranges == expected_ranges
def test_search_range_no_constraints_on_primary_values(self): rule = Rule([self.cause1, self.cause2], self.effect, [], Rule.LINKAGE_AND) calculated_ranges = self.calculate_range([rule]) raise SkipTest('Not implemented yet') assert calculated_ranges == {}