def test_Parser_SwitchBranches_basic(mock_config, mock_cid_manager): """Test basic ternary expression detection""" # set source file path source_file_path = os.path.join(abs_path_current_dir, "input_files", "TernaryExpressions", "TernaryExpression_basic.c") with open(source_file_path) as input_file: source_code = input_file.read() # configure the CIDManager mock mock_cid_manager.source_file = SourceFile(source_file_path) # create the clang bridge clang_bridge = ClangBridge() # let the clang bridge parse the source file clang_cursor = clang_bridge.clang_parse(source_file_path, "") # Create the parser parser = Parser(mock_config, mock_cid_manager, clang_cursor, source_code) # traverse the given file parser.start_parser() # assert calls to add_ternary_expression_data and check evaluation and true/false code sections assert mock_cid_manager.add_ternary_expression_data.call_count == 1 ternary_call_args_list = mock_cid_manager.add_ternary_expression_data.call_args_list assert ternary_call_args_list[0] == call( ANY, ANY, ANY, CodeSectionData(CodePositionData(6, 9), CodePositionData(6, 16)), ANY, ANY, CodeSectionData(CodePositionData(6, 19), CodePositionData(6, 20)), CodeSectionData(CodePositionData(6, 23), CodePositionData(6, 24)))
def test_Parser_Goto_basic(mock_config, mock_cid_manager): # set source file path source_file_path = os.path.join(abs_path_current_dir, "input_files", "Goto", "Goto_basic.c") with open(source_file_path) as input_file: source_code = input_file.read() # configure the CIDManager mock mock_cid_manager.source_file = SourceFile(source_file_path) # create the clang bridge clang_bridge = ClangBridge() # let the clang bridge parse the source file clang_cursor = clang_bridge.clang_parse(source_file_path, "") # Create the parser parser = Parser(mock_config, mock_cid_manager, clang_cursor, source_code) # traverse the given file parser.start_parser() # assert calls to add_checkpoint_data checkpoint_call_args_list = mock_cid_manager.add_checkpoint_marker.call_args_list assert checkpoint_call_args_list[0] == call(ANY, CodePositionData(3, 5)) assert checkpoint_call_args_list[1] == call(ANY, CodePositionData(6, 9)) assert checkpoint_call_args_list[2] == call(ANY, CodePositionData(7, 9)) assert checkpoint_call_args_list[3] == call(ANY, CodePositionData(9, 5)) assert checkpoint_call_args_list[4] == call(ANY, CodePositionData(13, 5)) assert mock_cid_manager.add_checkpoint_marker.call_count == 5
def test_ClangBrigde(): clang_bridge = ClangBridge() # parse the base file base_file_path = os.path.join(abs_path_current_dir, "input_files", "base_file.c") clang_bridge.clang_parse(base_file_path, "") assert isinstance(clang_bridge, ClangBridge) == True
def test_Parser_Init(mock_config, mock_cid_manager): # create the clang bridge clang_bridge = ClangBridge() # let the clang bridge parse the base file base_file_path = os.path.join(abs_path_current_dir, "input_files", "base_file.c") with open(base_file_path) as input_file: source_code = input_file.read() clang_cursor = clang_bridge.clang_parse(base_file_path, "") # Create the parser parser = Parser(mock_config, mock_cid_manager, clang_cursor, source_code) assert isinstance(parser, Parser) == True
def test_Parser_IfBranches_basic(mock_config, mock_cid_manager): """Test basic If-Branch detection""" # set source file path source_file_path = os.path.join(abs_path_current_dir, "input_files", "IfBranches", "IfBranches_basic.c") with open(source_file_path) as input_file: source_code = input_file.read() # configure the CIDManager mock mock_cid_manager.source_file = SourceFile(source_file_path) # create the clang bridge clang_bridge = ClangBridge() # let the clang bridge parse the source file clang_cursor = clang_bridge.clang_parse(source_file_path, "") # Create the parser parser = Parser(mock_config, mock_cid_manager, clang_cursor, source_code) # traverse the given file parser.start_parser() # assert calls to add_if_branch_data and check branch_results assert mock_cid_manager.add_if_branch_data.call_count == 1 if_branch_call_args_list = mock_cid_manager.add_if_branch_data.call_args_list assert if_branch_call_args_list[0] == call(ANY, ANY, ANY) branch_results = if_branch_call_args_list[0][0][2] assert len(branch_results) == 2 # evaluate first branch result assert branch_results[0].result_evaluation_code_section == CodeSectionData( CodePositionData(5, 9), CodePositionData(5, 14)) assert branch_results[0].result_body_code_section == CodeSectionData( CodePositionData(6, 5), CodePositionData(8, 6)) # evaluate second branch result # evaluation_marker_id shall be -1, since it's a else branch assert branch_results[1].evaluation_marker_id == -1 assert branch_results[1].result_body_code_section == CodeSectionData( CodePositionData(10, 5), CodePositionData(12, 6))
def test_Parser_IfBranches_else_ifs(mock_config, mock_cid_manager): """Test handling of else-ifs""" # set source file path source_file_path = os.path.join(abs_path_current_dir, "input_files", "IfBranches", "IfBranches_else_ifs.c") with open(source_file_path) as input_file: source_code = input_file.read() # configure the CIDManager mock mock_cid_manager.source_file = SourceFile(source_file_path) # create the clang bridge clang_bridge = ClangBridge() # let the clang bridge parse the source file clang_cursor = clang_bridge.clang_parse(source_file_path, "") # Create the parser parser = Parser(mock_config, mock_cid_manager, clang_cursor, source_code) # traverse the given file parser.start_parser() # assert calls to add_if_branch_data and check branch_results assert mock_cid_manager.add_if_branch_data.call_count == 1 if_branch_call_args_list = mock_cid_manager.add_if_branch_data.call_args_list assert if_branch_call_args_list[0] == call(ANY, ANY, ANY) branch_results = if_branch_call_args_list[0][0][2] assert len(branch_results) == 6 # evaluate the evaluation code section of the first two branches to make sure that else if handling works assert branch_results[0].result_evaluation_code_section == CodeSectionData( CodePositionData(9, 9), CodePositionData(9, 14)) assert branch_results[1].result_evaluation_code_section == CodeSectionData( CodePositionData(13, 14), CodePositionData(13, 19)) # evaluate last branch result # evaluation_marker_id shall be -1, since it's a else branch assert branch_results[-1].evaluation_marker_id == -1
def test_Parser_Functions(mock_config, mock_cid_manager): # set seource file path source_file_path = os.path.join(abs_path_current_dir, "input_files", "Functions", "Functions_basic.c") with open(source_file_path) as input_file: source_code = input_file.read() # configure the CIDManager mock mock_cid_manager.source_file = SourceFile(source_file_path) # create the clang bridge clang_bridge = ClangBridge() # let the clang bridge parse the source file clang_cursor = clang_bridge.clang_parse(source_file_path, "") # Create the parser parser = Parser(mock_config, mock_cid_manager, clang_cursor, source_code) # traverse the given file parser.start_parser() # assert calls to add_function_data function_call_args_list = mock_cid_manager.add_function_data.call_args_list assert function_call_args_list[0] == call( ANY, 'main()', FunctionType.NORMAL, -1, ANY, CodeSectionData(CodePositionData(1, 1), CodePositionData(2, 1)), CodeSectionData(CodePositionData(2, 1), CodePositionData(4, 2))) assert function_call_args_list[1] == call( ANY, 'dummy_function(int)', FunctionType.NORMAL, -1, ANY, CodeSectionData(CodePositionData(6, 1), CodePositionData(7, 1)), CodeSectionData(CodePositionData(7, 1), CodePositionData(9, 2))) assert mock_cid_manager.add_function_data.call_count == 2 # assert calls to add_checkpoint_marker checkpoint_call_args_list = mock_cid_manager.add_checkpoint_marker.call_args_list assert checkpoint_call_args_list[0] == call(ANY, CodePositionData(3, 5)) assert checkpoint_call_args_list[1] == call(ANY, CodePositionData(8, 5))
def test_Parser_Loops_for(mock_config, mock_cid_manager): """Test basic for loop detection""" # set source file path source_file_path = os.path.join(abs_path_current_dir, "input_files", "Loops", "Loop_for.c") with open(source_file_path) as input_file: source_code = input_file.read() # configure the CIDManager mock mock_cid_manager.source_file = SourceFile(source_file_path) # create the clang bridge clang_bridge = ClangBridge() # let the clang bridge parse the source file clang_cursor = clang_bridge.clang_parse(source_file_path, "") # Create the parser parser = Parser(mock_config, mock_cid_manager, clang_cursor, source_code) # traverse the given file parser.start_parser() # assert calls to add_ternary_expression_data and check evaluation and true/false code sections assert mock_cid_manager.add_loop_data.call_count == 1 loop_call_args_list = mock_cid_manager.add_loop_data.call_args_list assert loop_call_args_list[0] == call( ANY, LoopType.FOR, ANY, ANY, CodeSectionData(CodePositionData(5, 21), CodePositionData(5, 27)), CodeSectionData(CodePositionData(6, 5), CodePositionData(13, 6)), ANY, ANY) # assert correct checkpoint marker inside for-loop checkpoint_call_args_list = mock_cid_manager.add_checkpoint_marker.call_args_list assert checkpoint_call_args_list[1] == call(ANY, CodePositionData(7, 9)) assert checkpoint_call_args_list[2] == call(ANY, CodePositionData(9, 13)) assert checkpoint_call_args_list[3] == call(ANY, CodePositionData(10, 13))
def test_Parser_CompoundStatements_nested(mock_config, mock_cid_manager): # set source file path source_file_path = os.path.join(abs_path_current_dir, "input_files", "CompoundStatements", "CompoundStatements_nested.c") with open(source_file_path) as input_file: source_code = input_file.read() # configure the CIDManager mock mock_cid_manager.source_file = SourceFile(source_file_path) # create the clang bridge clang_bridge = ClangBridge() # let the clang bridge parse the source file clang_cursor = clang_bridge.clang_parse(source_file_path, "") # Create the parser parser = Parser(mock_config, mock_cid_manager, clang_cursor, source_code) # traverse the given file parser.start_parser() # assert calls to add_statement_data statement_call_args_list = mock_cid_manager.add_statement_data.call_args_list assert statement_call_args_list[0] == call( ANY, StatementType.NORMAL, ANY, ANY, CodeSectionData(CodePositionData(3, 5), CodePositionData(3, 15))) assert statement_call_args_list[1] == call( ANY, StatementType.NORMAL, ANY, ANY, CodeSectionData(CodePositionData(5, 9), CodePositionData(5, 19))) assert statement_call_args_list[2] == call( ANY, StatementType.RETURN, ANY, ANY, CodeSectionData(CodePositionData(8, 17), CodePositionData(8, 25))) assert statement_call_args_list[3] == call( ANY, StatementType.NORMAL, ANY, ANY, CodeSectionData(CodePositionData(10, 13), CodePositionData(10, 23))) assert statement_call_args_list[4] == call( ANY, StatementType.RETURN, ANY, ANY, CodeSectionData(CodePositionData(13, 13), CodePositionData(13, 21))) assert statement_call_args_list[5] == call( ANY, StatementType.NORMAL, ANY, ANY, CodeSectionData(CodePositionData(15, 17), CodePositionData(15, 27))) assert statement_call_args_list[6] == call( ANY, StatementType.RETURN, ANY, ANY, CodeSectionData(CodePositionData(19, 13), CodePositionData(19, 21))) assert statement_call_args_list[7] == call( ANY, StatementType.NORMAL, ANY, ANY, CodeSectionData(CodePositionData(20, 13), CodePositionData(20, 23))) assert mock_cid_manager.add_statement_data.call_count == 8 # assert calls to add_checkpoint_data checkpoint_call_args_list = mock_cid_manager.add_checkpoint_marker.call_args_list assert checkpoint_call_args_list[0] == call(ANY, CodePositionData(3, 5)) assert checkpoint_call_args_list[1] == call(ANY, CodePositionData(10, 13)) assert checkpoint_call_args_list[2] == call(ANY, CodePositionData(12, 9)) assert checkpoint_call_args_list[3] == call(ANY, CodePositionData(14, 13)) assert checkpoint_call_args_list[4] == call(ANY, CodePositionData(18, 9)) assert checkpoint_call_args_list[5] == call(ANY, CodePositionData(20, 13)) assert mock_cid_manager.add_checkpoint_marker.call_count == 6
def test_Parser_SwitchBranches_combined_cases(mock_config, mock_cid_manager): """Test Switch-Branch detection with all kinds of case combinations""" # set source file path source_file_path = os.path.join(abs_path_current_dir, "input_files", "SwitchBranches", "SwitchBranches_combined_cases.c") with open(source_file_path) as input_file: source_code = input_file.read() # configure the CIDManager mock mock_cid_manager.source_file = SourceFile(source_file_path) # create the clang bridge clang_bridge = ClangBridge() # let the clang bridge parse the source file clang_cursor = clang_bridge.clang_parse(source_file_path, "") # Create the parser parser = Parser(mock_config, mock_cid_manager, clang_cursor, source_code) # traverse the given file parser.start_parser() # assert calls to add_switch_branch_data and check cases assert mock_cid_manager.add_switch_branch_data.call_count == 2 switch_branch_call_args_list = mock_cid_manager.add_switch_branch_data.call_args_list assert switch_branch_call_args_list[0] == call( ANY, ANY, CodeSectionData(CodePositionData(6, 5), CodePositionData(21, 6)), ANY) assert switch_branch_call_args_list[1] == call( ANY, ANY, CodeSectionData(CodePositionData(23, 5), CodePositionData(29, 6)), ANY) # assert first switch branch results first_switch_cases = switch_branch_call_args_list[0][0][3] assert len(first_switch_cases) == 6 # evaluate first case result assert first_switch_cases[0].case_type == CaseType.CASE assert first_switch_cases[0].evaluation_code_section == CodeSectionData( CodePositionData(8, 5), CodePositionData(8, 12)) assert first_switch_cases[0].body_code_section == CodeSectionData( CodePositionData(9, 9), CodePositionData(9, 15)) # evaluate second case result assert first_switch_cases[1].case_type == CaseType.CASE assert first_switch_cases[1].evaluation_code_section == CodeSectionData( CodePositionData(11, 5), CodePositionData(11, 11)) assert first_switch_cases[1].body_code_section == CodeSectionData( CodePositionData(12, 9), CodePositionData(12, 14)) # evaluate third case result assert first_switch_cases[2].case_type == CaseType.CASE assert first_switch_cases[2].evaluation_code_section == CodeSectionData( CodePositionData(13, 5), CodePositionData(13, 11)) assert first_switch_cases[2].body_code_section == CodeSectionData( CodePositionData(14, 9), CodePositionData(14, 14)) # evaluate fourth case result (cases 4 and 5 are switched beacuse of recursive behavior) assert first_switch_cases[4].case_type == CaseType.CASE assert first_switch_cases[4].evaluation_code_section == CodeSectionData( CodePositionData(16, 5), CodePositionData(16, 11)) # body code section should be equal to following case assert first_switch_cases[4].body_code_section == first_switch_cases[ 3].body_code_section # evaluate fifth case result assert first_switch_cases[3].case_type == CaseType.CASE assert first_switch_cases[3].evaluation_code_section == CodeSectionData( CodePositionData(17, 5), CodePositionData(17, 11)) assert first_switch_cases[3].body_code_section == CodeSectionData( CodePositionData(18, 9), CodePositionData(18, 14)) # evaluate last case result assert first_switch_cases[5].case_type == CaseType.DEFAULT assert first_switch_cases[5].evaluation_code_section == CodeSectionData( CodePositionData(19, 5), CodePositionData(19, 12)) assert first_switch_cases[5].body_code_section == CodeSectionData( CodePositionData(20, 9), CodePositionData(20, 14)) # assert second switch branch cases second_switch_cases = switch_branch_call_args_list[1][0][3] assert len(second_switch_cases) == 2 # evaluate first case result assert second_switch_cases[1].case_type == CaseType.DEFAULT assert second_switch_cases[1].evaluation_code_section == CodeSectionData( CodePositionData(25, 5), CodePositionData(25, 12)) assert second_switch_cases[1].body_code_section == second_switch_cases[ 0].body_code_section # evaluate second case result assert second_switch_cases[0].case_type == CaseType.CASE assert second_switch_cases[0].evaluation_code_section == CodeSectionData( CodePositionData(26, 5), CodePositionData(26, 12)) assert second_switch_cases[0].body_code_section == CodeSectionData( CodePositionData(27, 9), CodePositionData(27, 15)) # check additions to statement data checkpoint_call_args_list = mock_cid_manager.add_checkpoint_marker.call_args_list assert checkpoint_call_args_list[1] == call(ANY, CodePositionData(9, 9)) assert checkpoint_call_args_list[2] == call(ANY, CodePositionData(12, 9)) assert checkpoint_call_args_list[3] == call(ANY, CodePositionData(14, 9)) # switched up order for fourth and fifth evaluation statement because of recursive behavior assert checkpoint_call_args_list[5] == call(ANY, CodePositionData(16, 12)) assert checkpoint_call_args_list[4] == call(ANY, CodePositionData(18, 9)) assert checkpoint_call_args_list[6] == call(ANY, CodePositionData(20, 9)) # checkpoint after switch (caused by break) assert checkpoint_call_args_list[7] == call(ANY, CodePositionData(23, 5)) # checkpoints of next switch (switched up because of recursive behavior) assert checkpoint_call_args_list[9] == call(ANY, CodePositionData(25, 13)) assert checkpoint_call_args_list[8] == call(ANY, CodePositionData(27, 9))
def test_Parser_SwitchBranches_basic(mock_config, mock_cid_manager): """Test basic Switch-Branch detection""" # set source file path source_file_path = os.path.join(abs_path_current_dir, "input_files", "SwitchBranches", "SwitchBranches_basic.c") with open(source_file_path) as input_file: source_code = input_file.read() # configure the CIDManager mock mock_cid_manager.source_file = SourceFile(source_file_path) # create the clang bridge clang_bridge = ClangBridge() # let the clang bridge parse the source file clang_cursor = clang_bridge.clang_parse(source_file_path, "") # Create the parser parser = Parser(mock_config, mock_cid_manager, clang_cursor, source_code) # traverse the given file parser.start_parser() # assert calls to add_switch_branch_data and check cases assert mock_cid_manager.add_switch_branch_data.call_count == 1 switch_branch_call_args_list = mock_cid_manager.add_switch_branch_data.call_args_list assert switch_branch_call_args_list[0] == call(ANY, ANY, ANY, ANY) # check code section of whole case assert switch_branch_call_args_list[0][0][2] == CodeSectionData( CodePositionData(6, 5), CodePositionData(17, 6)) switch_cases = switch_branch_call_args_list[0][0][3] assert len(switch_cases) == 3 # evaluate first case result assert switch_cases[0].case_type == CaseType.CASE assert switch_cases[0].evaluation_code_section == CodeSectionData( CodePositionData(8, 5), CodePositionData(8, 11)) assert switch_cases[0].body_code_section == CodeSectionData( CodePositionData(9, 9), CodePositionData(9, 14)) # evaluate second case result assert switch_cases[1].case_type == CaseType.CASE assert switch_cases[1].evaluation_code_section == CodeSectionData( CodePositionData(11, 5), CodePositionData(11, 11)) assert switch_cases[1].body_code_section == CodeSectionData( CodePositionData(12, 9), CodePositionData(12, 14)) # evaluate last case result assert switch_cases[2].case_type == CaseType.DEFAULT assert switch_cases[2].evaluation_code_section == CodeSectionData( CodePositionData(14, 5), CodePositionData(14, 12)) assert switch_cases[2].body_code_section == CodeSectionData( CodePositionData(15, 9), CodePositionData(15, 14)) # check additions to statement data checkpoint_call_args_list = mock_cid_manager.add_checkpoint_marker.call_args_list assert checkpoint_call_args_list[1] == call(ANY, CodePositionData(9, 9)) assert checkpoint_call_args_list[2] == call(ANY, CodePositionData(12, 9)) assert checkpoint_call_args_list[3] == call(ANY, CodePositionData(15, 9))
def test_Parser_IfBranches_complex_decisions(mock_config, mock_cid_manager): """Test handling of complex decisions (testing of evaluation analysis)""" # set source file path source_file_path = os.path.join(abs_path_current_dir, "input_files", "IfBranches", "IfBranches_complex_decisions.c") with open(source_file_path) as input_file: source_code = input_file.read() # configure the CIDManager mock mock_cid_manager.source_file = SourceFile(source_file_path) mock_cid_manager.get_new_id.side_effect = itertools.count( start=1, step=1) # id generator for inifinite new ids # create the clang bridge clang_bridge = ClangBridge() # let the clang bridge parse the source file clang_cursor = clang_bridge.clang_parse(source_file_path, "") # Create the parser parser = Parser(mock_config, mock_cid_manager, clang_cursor, source_code) # traverse the given file parser.start_parser() # assert calls to add_if_branch_data and check branch_results assert mock_cid_manager.add_if_branch_data.call_count == 1 if_branch_call_args_list = mock_cid_manager.add_if_branch_data.call_args_list assert if_branch_call_args_list[0] == call(ANY, ANY, ANY) branch_results = if_branch_call_args_list[0][0][2] assert len(branch_results) == 1 conditions = branch_results[0].conditions condition_possibilities = branch_results[0].condition_possibilities # evaluate all the conditions in the list assert len(conditions) == 5 assert conditions[0].code_section == CodeSectionData( CodePositionData(9, 10), CodePositionData(9, 15)) assert conditions[1].code_section == CodeSectionData( CodePositionData(9, 19), CodePositionData(9, 24)) assert conditions[2].code_section == CodeSectionData( CodePositionData(9, 30), CodePositionData(9, 35)) assert conditions[3].code_section == CodeSectionData( CodePositionData(9, 39), CodePositionData(9, 44)) assert conditions[4].code_section == CodeSectionData( CodePositionData(9, 49), CodePositionData(9, 54)) # generate list of possible results for this complex decision # use data types inside DataTypes.py reference_results = [ ConditionPossibility(True, [ ConditionResult(conditions[0].evaluation_marker_id, True), ConditionResult(conditions[1].evaluation_marker_id, True) ]), ConditionPossibility(True, [ ConditionResult(conditions[0].evaluation_marker_id, True), ConditionResult(conditions[1].evaluation_marker_id, False), ConditionResult(conditions[2].evaluation_marker_id, True), ConditionResult(conditions[3].evaluation_marker_id, True) ]), ConditionPossibility(True, [ ConditionResult(conditions[0].evaluation_marker_id, True), ConditionResult(conditions[1].evaluation_marker_id, False), ConditionResult(conditions[2].evaluation_marker_id, True), ConditionResult(conditions[3].evaluation_marker_id, False), ConditionResult(conditions[4].evaluation_marker_id, True) ]), ConditionPossibility(False, [ ConditionResult(conditions[0].evaluation_marker_id, True), ConditionResult(conditions[1].evaluation_marker_id, False), ConditionResult(conditions[2].evaluation_marker_id, True), ConditionResult(conditions[3].evaluation_marker_id, False), ConditionResult(conditions[4].evaluation_marker_id, False) ]), ConditionPossibility(True, [ ConditionResult(conditions[0].evaluation_marker_id, True), ConditionResult(conditions[1].evaluation_marker_id, False), ConditionResult(conditions[2].evaluation_marker_id, False), ConditionResult(conditions[4].evaluation_marker_id, True) ]), ConditionPossibility(False, [ ConditionResult(conditions[0].evaluation_marker_id, True), ConditionResult(conditions[1].evaluation_marker_id, False), ConditionResult(conditions[2].evaluation_marker_id, False), ConditionResult(conditions[4].evaluation_marker_id, False) ]), ConditionPossibility(True, [ ConditionResult(conditions[0].evaluation_marker_id, False), ConditionResult(conditions[2].evaluation_marker_id, True), ConditionResult(conditions[3].evaluation_marker_id, True) ]), ConditionPossibility(True, [ ConditionResult(conditions[0].evaluation_marker_id, False), ConditionResult(conditions[2].evaluation_marker_id, True), ConditionResult(conditions[3].evaluation_marker_id, False), ConditionResult(conditions[4].evaluation_marker_id, True) ]), ConditionPossibility(False, [ ConditionResult(conditions[0].evaluation_marker_id, False), ConditionResult(conditions[2].evaluation_marker_id, True), ConditionResult(conditions[3].evaluation_marker_id, False), ConditionResult(conditions[4].evaluation_marker_id, False) ]), ConditionPossibility(True, [ ConditionResult(conditions[0].evaluation_marker_id, False), ConditionResult(conditions[2].evaluation_marker_id, False), ConditionResult(conditions[4].evaluation_marker_id, True) ]), ConditionPossibility(False, [ ConditionResult(conditions[0].evaluation_marker_id, False), ConditionResult(conditions[2].evaluation_marker_id, False), ConditionResult(conditions[4].evaluation_marker_id, False) ]), ] # compare length of condition possibilities and all possibilities with ref list assert len(condition_possibilities) == 11 for reference_result in reference_results: found_in_stored_results = False for stored_result in condition_possibilities: if stored_result.decision_result != reference_result.decision_result: # decision_result doesn't fit continue if len(stored_result.condition_combination) != len( reference_result.condition_combination): # condition count doesn't fit continue condition_did_not_match = False # check, if all conditions in reference result exist in stores result for reference_condition in reference_result.condition_combination: found_conditions = [ item for item in stored_result.condition_combination if (item.evaluation_marker_id == reference_condition. evaluation_marker_id and item.condition_result == reference_condition.condition_result) ] if len(found_conditions) != 1: condition_did_not_match = True break if condition_did_not_match is False: # all conditions matched and decision fits, so this condition_possibility was found! found_in_stored_results = True if found_in_stored_results is False: raise AssertionError("ConditionResult not found!")