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_CIDManager_addConditionMarker(mock_config): # setup for configuration mock mock_config.checkpoint_markers_enabled = True mock_config.evaluation_markers_enabled = True cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') # add new marker new_code_section = CodeSectionData(CodePositionData(2, 1), CodePositionData(5, 3)) evaluation_marker_id = cid_manager.get_new_id() assert cid_manager.add_evaluation_marker(evaluation_marker_id, new_code_section, EvaluationType.CONDITION) # check data in new marker assert cid_manager.get_evaluation_markers( )[0].evaluation_marker_id == evaluation_marker_id assert cid_manager.get_evaluation_markers( )[0].code_section.start_position.line == 2 assert cid_manager.get_evaluation_markers( )[0].code_section.start_position.column == 1 assert cid_manager.get_evaluation_markers( )[0].code_section.end_position.line == 5 assert cid_manager.get_evaluation_markers( )[0].code_section.end_position.column == 3 assert cid_manager.get_evaluation_markers( )[0].evaluation_type == EvaluationType.CONDITION
def test_CIDManager_addStatementData(mock_config): # setup for configuration mock mock_config.checkpoint_markers_enabled = True mock_config.evaluation_markers_enabled = True cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') statement_id = 140 statement_type = StatementType.NORMAL function_id = 2 checkpoint_marker_id = 4 code_section = CodeSectionData(CodePositionData(4, 2), CodePositionData(10, 9)) cid_manager.add_statement_data(statement_id, statement_type, function_id, checkpoint_marker_id, code_section) # get stored element (access directly, although private element) element = cid_manager._cid_data.code_data.statements[0] assert element.statement_id == 140 assert element.statement_type == StatementType.NORMAL assert element.function_id == 2 assert element.checkpoint_marker_id == 4 assert element.code_section.start_position.line == 4 assert element.code_section.start_position.column == 2 assert element.code_section.end_position.line == 10 assert element.code_section.end_position.column == 9
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_CIDManager_addSwitchBranchData(mock_config): # setup for configuration mock mock_config.checkpoint_markers_enabled = True mock_config.evaluation_markers_enabled = True cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') switch_branch_id = 48 function_id = 92 switch_branch_code_section = CodeSectionData(CodePositionData(5, 2), CodePositionData(18, 5)) cases = [ CaseData( 18, CaseType.CASE, CodeSectionData(CodePositionData(21, 2), CodePositionData(21, 19)), CodeSectionData(CodePositionData(22, 5), CodePositionData(25, 9))) ] cid_manager.add_switch_branch_data(switch_branch_id, function_id, switch_branch_code_section, cases) # get stored element (access directly, although private element) element = cid_manager._cid_data.code_data.switch_branches[0] # assert, if data was stored correctly assert element.switch_branch_id == switch_branch_id assert element.function_id == function_id assert element.switch_branch_code_section == switch_branch_code_section assert element.cases == cases
def test_CIDManager_addDecisionMarker(mock_config): # setup for configuration mock mock_config.checkpoint_markers_enabled = True mock_config.evaluation_markers_enabled = True cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') # add new marker new_code_section = CodeSectionData(CodePositionData(2, 1), CodePositionData(5, 3)) evaluation_marker_id = cid_manager.get_new_id() assert cid_manager.add_evaluation_marker(evaluation_marker_id, new_code_section, EvaluationType.DECISION) # validate, if this indeed is a deepcopy, by modifying the id of the output data and checking it afterwards cid_manager.get_evaluation_markers()[0].evaluation_marker_id = 999 # check data in new marker assert cid_manager.get_evaluation_markers( )[0].evaluation_marker_id == evaluation_marker_id assert cid_manager.get_evaluation_markers( )[0].code_section.start_position.line == 2 assert cid_manager.get_evaluation_markers( )[0].code_section.start_position.column == 1 assert cid_manager.get_evaluation_markers( )[0].code_section.end_position.line == 5 assert cid_manager.get_evaluation_markers( )[0].code_section.end_position.column == 3 assert cid_manager.get_evaluation_markers( )[0].evaluation_type == EvaluationType.DECISION
def test_Instrumenter_writeMarkers(mock_config, mock_cid_manager, mock_cp_markers, mock_ev_markers, mock_ir, mock_sc_h, tmpdir): mock_config.runtime_helper_header_path = "C:\\testpath\\coveron_helper.h" mock_config.checkpoint_markers_enabled = True mock_config.evaluation_markers_enabled = True mock_config.output_abs_path = tmpdir source_file = SourceFile(os.path.join(tmpdir, 'test_file.c')) instrumenter = Instrumenter(mock_config, mock_cid_manager, source_file, dummySourceCode) # create dummy instrumentation random (in lower_case, to check if transform to uppercase works) mock_ir.return_value = "abcdefghijklmnopqrstuvwxyz123456" # create dummy source code hash mock_sc_h.return_value = "abcdefghijklmnopqrstuvwxyz123456abcdefghijklmnopqrstuvwxyz234567" # create dummy markers for return mock_cp_markers.return_value = [ CheckpointMarkerData(1, CodePositionData(2, 5)) ] mock_ev_markers.return_value = [ EvaluationMarkerData( 2, EvaluationType.DECISION, CodeSectionData(CodePositionData(3, 5), CodePositionData(3, 10))), EvaluationMarkerData( 3, EvaluationType.CONDITION, CodeSectionData(CodePositionData(4, 5), CodePositionData(4, 10))) ] # start instrumentation with marker instrumenter.start_instrumentation() # write output file instrumenter.write_output_file() # open output file and compare with reference string with open(tmpdir.join('test_file.instr.c'), 'r') as output_source_code_ptr: source_code_instr_string = output_source_code_ptr.read() print(source_code_instr_string) source_code_instr_ref_str = '''#include "C:\\testpath\\coveron_helper.h" ___COVERON_FILE_T ___COVERON_FILE_ABCDEFGHIJKLMNOPQRSTUVWXYZ123456 = { {0xAB, 0xCD, 0xEF, 0xGH, 0xIJ, 0xKL, 0xMN, 0xOP, 0xQR, 0xST, 0xUV, 0xWX, 0xYZ, 0x12, 0x34, 0x56, 0xAB, 0xCD, 0xEF, 0xGH, 0xIJ, 0xKL, 0xMN, 0xOP, 0xQR, 0xST, 0xUV, 0xWX, 0xYZ, 0x23, 0x45, 0x67}, {0xAB, 0xCD, 0xEF, 0xGH, 0xIJ, 0xKL, 0xMN, 0xOP, 0xQR, 0xST, 0xUV, 0xWX, 0xYZ, 0x12, 0x34, 0x56}, ___COVERON_BOOL_FALSE, (void *)0, "test_file.cri"}; int main() { ___COVERON_SET_CHECKPOINT_MARKER(0x00, 0x00, 0x00, 0x01, &___COVERON_FILE_ABCDEFGHIJKLMNOPQRSTUVWXYZ123456);test0; ___COVERON_SET_EVALUATION_MARKER(0x00, 0x00, 0x00, 0x02, &___COVERON_FILE_ABCDEFGHIJKLMNOPQRSTUVWXYZ123456, (int) (test1)); ___COVERON_SET_EVALUATION_MARKER(0x00, 0x00, 0x00, 0x03, &___COVERON_FILE_ABCDEFGHIJKLMNOPQRSTUVWXYZ123456, (int) (test2)); }''' assert source_code_instr_string == source_code_instr_ref_str
def test_CIDManager_init(mock_config): mock_config.checkpoint_markers_enabled = True mock_config.evaluation_markers_enabled = True cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') assert isinstance(cid_manager, CIDManager) == True
def test_Instrumenter_init(mock_config, mock_cid_manager, tmpdir): mock_config.checkpoint_markers_enabled = True mock_config.evaluation_markers_enabled = True mock_config.output_abs_path = tmpdir source_file = SourceFile('test_file.c') instrumenter = Instrumenter(mock_config, mock_cid_manager, source_file, dummySourceCode) assert isinstance(instrumenter, Instrumenter) == True
def test_CIDManager_getNewId(mock_config): # setup for configuration mock mock_config.checkpoint_markers_enabled = False mock_config.evaluation_markers_enabled = False cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') id_1 = cid_manager.get_new_id() id_2 = cid_manager.get_new_id() assert id_1 < id_2
def test_CIDManager_getSourceCodeHash(mock_config): # setup for configuration mock mock_config.checkpoint_markers_enabled = False mock_config.evaluation_markers_enabled = False cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') source_code_hash = cid_manager.get_source_code_hash() assert len(source_code_hash) == 64 # sha256 for 'test_code' assert source_code_hash == '3aa0041781f53f591089fa2aeed013200e54828311ae3f4f4f343edba87dc071'
def test_CIDManager_getInstrumentationRandom(mock_config): # setup for configuration mock mock_config.checkpoint_markers_enabled = False mock_config.evaluation_markers_enabled = False cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') instrumentation_random = cid_manager.get_instrumentation_random() assert len(instrumentation_random) == 32 assert (not bool( re.compile(r'[^a-fA-F0-9]').search(instrumentation_random))) == True
def test_CIDManager_addCheckpointMarker_badConfig(mock_config): # setup for configuration mock mock_config.checkpoint_markers_enabled = False mock_config.evaluation_markers_enabled = False cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') dummy_code_position = CodePositionData(1, 1) with pytest.raises(RuntimeError): cid_manager.add_checkpoint_marker(cid_manager.get_new_id(), dummy_code_position)
def test_CIDManager_addTernaryExpressionData(mock_config): # setup for configuration mock mock_config.checkpoint_markers_enabled = False mock_config.evaluation_markers_enabled = False cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') ternary_expression_id = 882 function_id = 428 evaluation_marker_id = 381 evaluation_code_section = CodeSectionData(CodePositionData(15, 10), CodePositionData(15, 16)) condition_possibilities = [ ConditionPossibility(True, [ConditionResult(5, True)]), ConditionPossibility(False, [ConditionResult(5, False)]) ] conditions = [ ConditionData( 28, CodeSectionData(CodePositionData(15, 11), CodePositionData(15, 15))) ] true_code_section = CodeSectionData(CodePositionData(15, 20), CodePositionData(15, 26)) false_code_section = CodeSectionData(CodePositionData(15, 30), CodePositionData(15, 42)) cid_manager.add_ternary_expression_data(ternary_expression_id, function_id, evaluation_marker_id, evaluation_code_section, condition_possibilities, conditions, true_code_section, false_code_section) # get stored element (access directly, although private element) element = cid_manager._cid_data.code_data.ternary_expressions[0] # assert, if data was stored correctly assert element.ternary_expression_id == ternary_expression_id assert element.function_id == function_id assert element.evaluation_marker_id == evaluation_marker_id assert element.evaluation_code_section == evaluation_code_section assert element.condition_possibilities == condition_possibilities assert element.conditions == conditions
def test_CIDManager_addLoopData(mock_config): # setup for configuration mock mock_config.checkpoint_markers_enabled = False mock_config.evaluation_markers_enabled = False cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') loop_id = 841 loop_type = LoopType.FOR function_id = 32 evaluation_marker_id = 48 evaluation_code_section = CodeSectionData(CodePositionData(19, 2), CodePositionData(19, 17)), body_code_section = CodeSectionData(CodePositionData(20, 2), CodePositionData(25, 3)) condition_possibilities = [ ConditionPossibility(True, [ConditionResult(5, True)]), ConditionPossibility(False, [ConditionResult(5, False)]) ] conditions = [ ConditionData( 29, CodeSectionData(CodePositionData(19, 3), CodePositionData(19, 16))) ] cid_manager.add_loop_data(loop_id, loop_type, function_id, evaluation_marker_id, evaluation_code_section, body_code_section, condition_possibilities, conditions) # get stored element (access directly, although private element) element = cid_manager._cid_data.code_data.loops[0] # assert, if data was stored correctly assert element.loop_id == loop_id assert element.loop_type == loop_type assert element.function_id == function_id assert element.evaluation_marker_id == evaluation_marker_id assert element.evaluation_code_section == evaluation_code_section assert element.body_code_section == body_code_section assert element.condition_possibilities == condition_possibilities assert element.conditions == conditions
def test_CIDManager_addClassData(mock_config): # setup for configuration mock mock_config.checkpoint_markers_enabled = True mock_config.evaluation_markers_enabled = True cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') class_id = 1 class_name = "test_class" cid_manager.add_class_data(class_id, class_name) # get stored element (access directly, although private element) element = cid_manager._cid_data.code_data.classes[0] assert element.class_id == 1 assert element.class_name == "test_class"
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_CIDManager_addIfBranchData(mock_config): # setup for configuration mock mock_config.checkpoint_markers_enabled = True mock_config.evaluation_markers_enabled = True cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') if_branch_id = 40 function_id = 18 branch_results = [ BranchResultData( 20, # dummy condition [ ConditionPossibility(True, [ConditionResult(5, True)]), ConditionPossibility(False, [ConditionResult(5, False)]) ], [ ConditionData( 95, CodeSectionData(CodePositionData(10, 2), CodePositionData(19, 8))) ], CodeSectionData(CodePositionData(10, 1), CodePositionData(19, 9)), # evaluation code section CodeSectionData(CodePositionData(20, 2), CodePositionData(29, 5))) # bode code section ] cid_manager.add_if_branch_data(if_branch_id, function_id, branch_results) # get stored element (access directly, although private element) element = cid_manager._cid_data.code_data.if_branches[0] # assert, if data was stored correctly assert element.if_branch_id == if_branch_id assert element.function_id == function_id assert element.branch_results == branch_results
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_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_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_CIDManager_addFunctionData(mock_config): # setup for configuration mock mock_config.checkpoint_markers_enabled = True mock_config.evaluation_markers_enabled = True cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') function_id = 10 function_name = "test_function" function_type = FunctionType.NORMAL parent_function_id = 55 checkpoint_marker_id = 4 header_code_section = CodeSectionData(CodePositionData(1, 5), CodePositionData(2, 4)) inner_code_section = CodeSectionData(CodePositionData(30, 5), CodePositionData(35, 9)) cid_manager.add_function_data(function_id, function_name, function_type, parent_function_id, checkpoint_marker_id, header_code_section, inner_code_section) # get stored element (access directly, although private element) element = cid_manager._cid_data.code_data.functions[0] assert element.function_id == 10 assert element.function_name == "test_function" assert element.function_type == FunctionType.NORMAL assert element.parent_function_id == 55 assert element.checkpoint_marker_id == 4 assert element.header_code_section.start_position.line == 1 assert element.header_code_section.start_position.column == 5 assert element.header_code_section.end_position.line == 2 assert element.header_code_section.end_position.column == 4 assert element.inner_code_section.start_position.line == 30 assert element.inner_code_section.start_position.column == 5 assert element.inner_code_section.end_position.line == 35 assert element.inner_code_section.end_position.column == 9
def test_CIDManager_addCheckpointMarker(mock_config): # setup for configuration mock mock_config.checkpoint_markers_enabled = True mock_config.evaluation_markers_enabled = True cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') # add new marker new_code_position = CodePositionData(5, 3) checkpoint_marker_id = cid_manager.get_new_id() assert cid_manager.add_checkpoint_marker(checkpoint_marker_id, new_code_position) # validate, if this indeed is a deepcopy, by modifying the id of the output data and checking it afterwards cid_manager.get_checkpoint_markers()[0].checkpoint_marker_id = 999 # check data in new marker assert cid_manager.get_checkpoint_markers( )[0].checkpoint_marker_id == checkpoint_marker_id assert cid_manager.get_checkpoint_markers()[0].code_position.line == 5 assert cid_manager.get_checkpoint_markers()[0].code_position.column == 3
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_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_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_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!")
def test_CIDManager_writeCidFile(mock_config, tmpdir): # setup for configuration mock mock_config.checkpoint_markers_enabled = True mock_config.evaluation_markers_enabled = True mock_config.output_abs_path = tmpdir cid_manager = CIDManager(mock_config, SourceFile('test_file.c'), 'test_code') # add checkpoint marker cid_manager.add_checkpoint_marker(4, CodePositionData(1, 6)) # add evaluation marker cid_manager.add_evaluation_marker( 5, CodeSectionData(CodePositionData(1, 5), CodePositionData(1, 15)), EvaluationType.DECISION) # add class cid_manager.add_class_data(483, 'test_class') # add function cid_manager.add_function_data( 10, "test_function", FunctionType.NORMAL, 55, 4, CodeSectionData(CodePositionData(1, 5), CodePositionData(2, 4)), CodeSectionData(CodePositionData(30, 5), CodePositionData(35, 9))) # add statement cid_manager.add_statement_data( 20, StatementType.NORMAL, 83, 844, CodeSectionData(CodePositionData(1, 5), CodePositionData(2, 4))) # add if-branch cid_manager.add_if_branch_data( 40, 18, [ BranchResultData( 20, # dummy condition [ ConditionPossibility(True, [ConditionResult(5, True)]), ConditionPossibility(False, [ConditionResult(5, False)]) ], [ ConditionData( 95, CodeSectionData(CodePositionData(10, 2), CodePositionData(19, 8))) ], CodeSectionData(CodePositionData(10, 1), CodePositionData( 19, 9)), # evaluation code section CodeSectionData(CodePositionData(20, 2), CodePositionData( 29, 5))) ]) # add switch-branch cid_manager.add_switch_branch_data( 48, 92, CodeSectionData(CodePositionData(5, 2), CodePositionData(18, 5)), [ CaseData( 18, CaseType.CASE, CodeSectionData(CodePositionData(21, 2), CodePositionData(21, 19)), CodeSectionData(CodePositionData(22, 5), CodePositionData( 25, 9))) ]) # add ternary-expression cid_manager.add_ternary_expression_data( 882, 428, 381, CodeSectionData(CodePositionData(15, 10), CodePositionData(15, 16)), [ ConditionPossibility(True, [ConditionResult(5, True)]), ConditionPossibility(False, [ConditionResult(5, False)]) ], [ ConditionData( 28, CodeSectionData(CodePositionData(15, 11), CodePositionData(15, 15))) ], CodeSectionData(CodePositionData(15, 20), CodePositionData(15, 26)), CodeSectionData(CodePositionData(15, 30), CodePositionData(15, 42))) # add loop cid_manager.add_loop_data( 841, LoopType.FOR, 32, 48, CodeSectionData(CodePositionData(19, 2), CodePositionData(19, 17)), CodeSectionData(CodePositionData(20, 2), CodePositionData(25, 3)), [ ConditionPossibility(True, [ConditionResult(5, True)]), ConditionPossibility(False, [ConditionResult(5, False)]) ], [ ConditionData( 29, CodeSectionData(CodePositionData(19, 3), CodePositionData(19, 16))) ]) # load JSON Validation Schema with open(os.path.join(os.path.dirname(__file__), 'CID_Schema.json'), 'r') as cid_schema_ptr: json_schema = json.loads(cid_schema_ptr.read()) # write non-compressed and check mock_config.nocomp_cid = True cid_manager.write_cid_file() with open(tmpdir.join('test_file.cid'), 'r') as output_cid_ptr: cid_data = json.loads(output_cid_ptr.read()) # validate the CID-File jsonschema.validate(cid_data, json_schema) # write compressed and check mock_config.nocomp_cid = False cid_manager.write_cid_file() with gzip.GzipFile(tmpdir.join('test_file.cid'), 'r') as output_cid_ptr: cid_data = json.loads(output_cid_ptr.read()) # validate the compressed CID-File jsonschema.validate(cid_data, json_schema)