def test_clang37_plist(self): """ Check plist generated by clang 3.7 checker name should be in the plist file. """ clang37_plist = os.path.join( self.__plist_test_files, 'clang-3.7.plist') files, bugs = plist_parser.parse_plist(clang37_plist) self.assertEquals(files, self.__found_file_names) self.assertEquals(len(bugs), 3) valid_checker_names = [] valid_checker_names.extend(self.__found_checker_names) for bug in bugs: # Checker name should be in the plist file. self.assertNotEqual(bug.checker_name, 'NOT FOUND') self.assertIn(bug.checker_name, valid_checker_names) if bug.checker_name == 'core.DivideZero': self.__core_div_bug_event(bug.get_last_event()) if bug.checker_name == 'core.StackAddressEscape': self.__core_stack_addr_esc_event(bug.get_last_event()) self.assertNotEquals(bug.hash_value, '')
def handle_results(self): source = self.analyzed_source_file _, source_file_name = ntpath.split(source) plist = self.get_analyzer_result_file() try: _, bugs = plist_parser.parse_plist(plist) except Exception as ex: LOG.error('The generated plist is not valid!') LOG.error(ex) return 1 err_code = self.analyzer_returncode if err_code == 0: if len(bugs) > 0: self.__output.write( '%s found %d defect(s) while analyzing %s\n\n' % (self.buildaction.analyzer_type, len(bugs), source_file_name)) self.__print_bugs(bugs) else: self.__output.write('%s found no defects while analyzing %s\n' % (self.buildaction.analyzer_type, source_file_name)) return err_code else: self.__output.write('Analyzing %s with %s failed.\n' % (source_file_name, self.buildaction.analyzer_type)) return err_code
def handle_results(self): source = self.analyzed_source_file _, source_file_name = ntpath.split(source) plist = self.get_analyzer_result_file() try: _, bugs = plist_parser.parse_plist(plist) except Exception as ex: LOG.error('The generated plist is not valid!') LOG.error(ex) return 1 err_code = self.analyzer_returncode if err_code == 0: if len(bugs) > 0: self.__output.write( '%s found %d defect(s) while analyzing %s\n\n' % (self.buildaction.analyzer_type, len(bugs), source_file_name)) self.__print_bugs(bugs) else: self.__output.write( '%s found no defects while analyzing %s\n' % (self.buildaction.analyzer_type, source_file_name)) return err_code else: self.__output.write( 'Analyzing %s with %s failed.\n' % (source_file_name, self.buildaction.analyzer_type)) return err_code
def test_no_bug_file(self): """There was no bug in the checked file.""" no_bug_plist = os.path.join(self.__plist_test_files, 'clang-3.7-noerror.plist') files, bugs = plist_parser.parse_plist(no_bug_plist) self.assertEquals(files, []) self.assertEquals(bugs, [])
def test_no_bug_file(self): """There was no bug in the checked file.""" no_bug_plist = os.path.join( self.__plist_test_files, 'clang-3.7-noerror.plist') files, bugs = plist_parser.parse_plist(no_bug_plist) self.assertEquals(files, []) self.assertEquals(bugs, [])
def test_clang38_trunk_plist(self): """ Check plist generated by clang 3.8 trunk checker name and bug hash should be in the plist file. """ clang38_plist = os.path.join( self.__plist_test_files, 'clang-3.8-trunk.plist') files, bugs = plist_parser.parse_plist(clang38_plist) self.assertEquals(files, self.__found_file_names) self.assertEquals(len(bugs), 3) valid_checker_names = [] valid_checker_names.extend(self.__found_checker_names) for bug in bugs: # Checker name should be in the plist file. self.assertNotEqual(bug.checker_name, 'NOT FOUND') self.assertIn(bug.checker_name, valid_checker_names) if bug.checker_name == 'core.DivideZero': self.__core_div_bug_event(bug.get_last_event()) self.assertEquals( bug.hash_value, '79e31a6ba028f0b7d9779faf4a6cb9cf') if bug.checker_name == 'core.StackAddressEscape': self.__core_stack_addr_esc_event(bug.get_last_event()) self.assertEquals( bug.hash_value, 'f7b5072d428e890f2d309217f3ead16f') if bug.checker_name == 'deadcode.DeadStores': self.assertEquals( bug.hash_value, '8714f42d8328bc78d5d7bff6ced918cc')
def test_clang38_trunk_plist(self): """ Check plist generated by clang 3.8 trunk checker name and bug hash should be in the plist file. """ clang38_plist = os.path.join(self.__plist_test_files, 'clang-3.8-trunk.plist') files, bugs = plist_parser.parse_plist(clang38_plist) self.assertEquals(files, self.__found_file_names) self.assertEquals(len(bugs), 3) valid_checker_names = [] valid_checker_names.extend(self.__found_checker_names) for bug in bugs: # Checker name should be in the plist file. self.assertNotEqual(bug.checker_name, 'NOT FOUND') self.assertIn(bug.checker_name, valid_checker_names) if bug.checker_name == 'core.DivideZero': self.__core_div_bug_event(bug.get_last_event()) self.assertEquals(bug.hash_value, '79e31a6ba028f0b7d9779faf4a6cb9cf') if bug.checker_name == 'core.StackAddressEscape': self.__core_stack_addr_esc_event(bug.get_last_event()) self.assertEquals(bug.hash_value, 'f7b5072d428e890f2d309217f3ead16f') if bug.checker_name == 'deadcode.DeadStores': self.assertEquals(bug.hash_value, '8714f42d8328bc78d5d7bff6ced918cc')
def test_clang37_plist(self): """ Check plist generated by clang 3.7 checker name should be in the plist file. """ clang37_plist = os.path.join(self.__plist_test_files, 'clang-3.7.plist') files, bugs = plist_parser.parse_plist(clang37_plist) self.assertEquals(files, self.__found_file_names) self.assertEquals(len(bugs), 3) valid_checker_names = [] valid_checker_names.extend(self.__found_checker_names) for bug in bugs: # Checker name should be in the plist file. self.assertNotEqual(bug.checker_name, 'NOT FOUND') self.assertIn(bug.checker_name, valid_checker_names) if bug.checker_name == 'core.DivideZero': self.__core_div_bug_event(bug.get_last_event()) if bug.checker_name == 'core.StackAddressEscape': self.__core_stack_addr_esc_event(bug.get_last_event()) self.assertNotEquals(bug.hash_value, '')
def handle_plist(self, plist): try: _, bugs = plist_parser.parse_plist(plist) except Exception as ex: LOG.error('The generated plist is not valid!') LOG.debug(ex) return 1 self.__print_bugs(bugs)
def handle_plist(self, plist): try: _, bugs = plist_parser.parse_plist(plist) except Exception as ex: LOG.error('The generated plist is not valid!') LOG.error(ex) return 1 if len(bugs) > 0: self.__output.write("%s contains %d defect(s)\n\n" % (plist, len(bugs))) self.__print_bugs(bugs) else: self.__output.write("%s doesn't contain any defects\n" % plist)
def handle_results(self): """ send the plist content to the database server API calls should be used in one connection - addBuildAction - addReport - needFileContent - addFileContent - finishBuildAction """ with client.get_connection() as connection: LOG.debug('Storing original build and analyzer command to the database') _, source_file_name = ntpath.split(self.analyzed_source_file) analisys_id = connection.add_build_action(self.__run_id, self.buildaction.original_command, ' '.join(self.analyzer_cmd), self.buildaction.analyzer_type, source_file_name) # store buildaction and analyzer command to the database if self.analyzer_returncode == 0: LOG.info(self.buildaction.analyzer_type + ' analyzed ' + source_file_name + ' successfully.') plist_file = self.get_analyzer_result_file() try: files, bugs = plist_parser.parse_plist(plist_file) except Exception as ex: LOG.debug(str(ex)) msg = 'Parsing the generated result file failed' LOG.error(msg + ' ' + plist_file) connection.finish_build_action(analisys_id, msg) return 1 self.__store_bugs(files, bugs, connection, analisys_id) else: LOG.info('Analysing ' + source_file_name + ' with ' + self.buildaction.analyzer_type + ' failed.') connection.finish_build_action(analisys_id, self.analyzer_stderr)
def handle_results(self): source = self.analyzed_source_file _, source_file_name = ntpath.split(source) plist = self.get_analyzer_result_file() try: _, bugs = plist_parser.parse_plist(plist) except Exception as ex: LOG.error('The generated plist is not valid!') LOG.error(ex) return 1 err_code = self.analyzer_returncode if err_code == 0: if len(bugs) > 0: self.__output.write( '%s found %d defect(s) while analyzing %s\n\n' % (self.buildaction.analyzer_type, len(bugs), source_file_name)) else: self.__output.write( '%s found no defects while analyzing %s\n' % (self.buildaction.analyzer_type, source_file_name)) return err_code index_format = ' %%%dd, ' % int( math.floor(math.log10(len(bugs))) + 1) for bug in bugs: last_event = bug.get_last_event() self.__output.write(self.__format_bug_event(last_event)) self.__output.write('\n') self.__output.write(self.__format_location(last_event)) self.__output.write('\n') if self.__print_steps: self.__output.write(' Steps:\n') for index, event in enumerate(bug.events()): self.__output.write(index_format % (index + 1)) self.__output.write(self.__format_bug_event(event)) self.__output.write('\n') self.__output.write('\n') else: self.__output.write( 'Analyzing %s with %s failed.\n' % (source_file_name, self.buildaction.analyzer_type)) return err_code
def handle_results(self): """ Send the plist content to the database. Server API calls should be used in one connection. - addBuildAction - addReport - needFileContent - addFileContent - finishBuildAction """ with client.get_connection() as connection: LOG.debug('Storing original build and analyzer command ' 'to the database.') _, source_file_name = ntpath.split(self.analyzed_source_file) if LoggerFactory.get_log_level() == logger.DEBUG: analyzer_cmd = ' '.join(self.analyzer_cmd) else: analyzer_cmd = '' build_cmd_hash = self.buildaction.original_command_hash analysis_id = \ connection.add_build_action(self.__run_id, build_cmd_hash, analyzer_cmd, self.buildaction.analyzer_type, source_file_name) assert self.analyzer_returncode == 0 plist_file = self.analyzer_result_file try: files, bugs = plist_parser.parse_plist(plist_file) except Exception as ex: LOG.debug(str(ex)) msg = 'Parsing the generated result file failed.' LOG.error(msg + ' ' + plist_file) connection.finish_build_action(analysis_id, msg) return 1 self.__store_bugs(files, bugs, connection, analysis_id) connection.finish_build_action(analysis_id, self.analyzer_stderr)
def handle_plist(self, plist): with client.get_connection() as connection: # TODO: When the analyzer name can be read from PList, then it # should be passed too. # TODO: File name should be read from the PList and passed. analysis_id = connection.add_build_action( self.__run_id, plist, 'Build action from plist', '', '') try: files, bugs = plist_parser.parse_plist(plist) except Exception as ex: msg = 'Parsing the generated result file failed' LOG.error(msg + ' ' + plist) LOG.error(str(ex)) connection.finish_build_action(analysis_id, msg) return 1 self.__store_bugs(files, bugs, connection, analysis_id) connection.finish_build_action(analysis_id, self.analyzer_stderr)
def on_result(**args): LOG.debug(args['check_command']) source = args['source_file'] plist = args['report_plist'] if not os.path.isfile(plist): LOG.info('Checking %s failed!' % (source)) return 1 try: _, bugs = plist_parser.parse_plist(plist) except Exception: LOG.error('The generated plist is not valid!') return 1 err_code = args['err_code'] if len(bugs) > 0: output.write('%d defect(s) found while checking %s:\n\n' % (len(bugs), source)) else: output.write('No defects found in %s :-)\n' % source) return err_code index_format = ' %%%dd, ' % int(math.floor(math.log10(len(bugs)))+1) for bug in bugs: last_event = bug.get_last_event() output.write(format_bug_event(last_event)) output.write('\n') output.write(format_location(last_event)) output.write('\n') if print_steps: output.write(' Steps:\n') for index, event in enumerate(bug.events()): output.write(index_format % (index + 1)) output.write(format_bug_event(event)) output.write('\n') output.write('\n') return err_code
def handle_plist(self, plist): with client.get_connection() as connection: # TODO: When the analyzer name can be read from PList, then it # should be passed too. # TODO: File name should be read from the PList and passed. analisys_id = connection.add_build_action(self.__run_id, plist, 'Build action from plist', '', '') try: files, bugs = plist_parser.parse_plist(plist) except Exception as ex: msg = 'Parsing the generated result file failed' LOG.error(msg + ' ' + plist) connection.finish_build_action(analysis_id, msg) return 1 self.__store_bugs(files, bugs, connection, analisys_id) connection.finish_build_action(analisys_id, self.analyzer_stderr)
def test_clang35_plist(self): """ Check plist generated by clang 3.5 checker name is not in the plist file plist parser tries to find out the name. """ clang35_plist = os.path.join(self.__plist_test_files, 'clang-3.5.plist') files, bugs = plist_parser.parse_plist(clang35_plist) self.assertEquals(files, self.__found_file_names) self.assertEquals(len(bugs), 3) valid_checker_names = [] valid_checker_names.extend(self.__found_checker_names) valid_checker_names.extend(self.__not_found_checker_names) for bug in bugs: self.assertIn(bug.checker_name, valid_checker_names) if bug.checker_name == 'core.DivideZero': self.__core_div_bug_event(bug.get_last_event()) if bug.checker_name == 'NOT FOUND': self.__core_stack_addr_esc_event(bug.get_last_event()) self.assertIn(bug.hash_value, self.__framework_generated_hashes)
def test_clang34_plist(self): """ Check plist generated by clang 3.4 checker name is not in the plist file plist parser tries to find out the name. """ clang34_plist = os.path.join( self.__plist_test_files, 'clang-3.4.plist') files, bugs = plist_parser.parse_plist(clang34_plist) self.assertEquals(files, self.__found_file_names) self.assertEquals(len(bugs), 3) valid_checker_names = [] valid_checker_names.extend(self.__found_checker_names) valid_checker_names.extend(self.__not_found_checker_names) for bug in bugs: self.assertIn(bug.checker_name, valid_checker_names) if bug.checker_name == 'core.DivideZero': self.__core_div_bug_event(bug.get_last_event()) if bug.checker_name == 'NOT FOUND': self.__core_stack_addr_esc_event(bug.get_last_event()) self.assertIn(bug.hash_value, self.__framework_generated_hashes)
def handle_results(self): plist = self.analyzer_result_file try: _, bugs = plist_parser.parse_plist(plist) except Exception as ex: LOG.error('The generated plist is not valid!') LOG.error(ex) return 1 err_code = self.analyzer_returncode if err_code == 0: try: # No lock when consuming plist. self.__lock.acquire() if self.__lock else None self.__print_bugs(bugs) finally: self.__lock.release() if self.__lock else None else: self.__output.write('Analyzing %s with %s failed.\n' % (ntpath.basename(self.analyzed_source_file), self.buildaction.analyzer_type)) return err_code
def send_plist_content(connection, plist_file, build_action_id, run_id, severity_map, should_skip): try: files, bugs = plist_parser.parse_plist(plist_file) except Exception: LOG.info('The generated plist is not valid, so parsing failed.') return file_ids = {} # Send content of file to the server if needed for file_name in files: file_descriptor = connection.need_file_content(file_name) file_ids[file_name] = file_descriptor.fileId if file_descriptor.needed: with open(file_name, 'r') as source_file: file_content = source_file.read() compressed_file = zlib.compress(file_content, zlib.Z_BEST_COMPRESSION) # TODO: we may not use the file content in the end # depending on skippaths connection.add_file_content(file_descriptor.fileId, compressed_file) report_ids = [] for bug in bugs: events = bug.events() if events and should_skip(events[-1].start_pos.file_path): # Issue #20: this bug is in a file which should be skipped LOG.debug(bug.hash_value + ' is skipped (in ' + events[-1].start_pos.file_path + ")") continue # create remaining data for bugs and send them to the server bug_paths = [] for path in bug.paths(): bug_paths.append(shared.ttypes.BugPathPos(path.start_pos.line, path.start_pos.col, path.end_pos.line, path.end_pos.col, file_ids[path.start_pos.file_path])) bug_events = [] for event in bug.events(): bug_events.append(shared.ttypes.BugPathEvent(event.start_pos.line, event.start_pos.col, event.end_pos.line, event.end_pos.col, event.msg, file_ids[event.start_pos.file_path])) bug_hash = bug.hash_value LOG.debug('Bug hash: ' + bug_hash) severity_name = severity_map.get(bug.checker_name, 'UNSPECIFIED') severity = shared.ttypes.Severity._NAMES_TO_VALUES[severity_name] suppress = False source_file = bug.file_path last_bug_event = bug.events()[-1] bug_line = last_bug_event.start_pos.line LOG.debug('Checking source for suppress comment') sp_handler = suppress_handler.SourceSuppressHandler(source_file, bug_line) LOG.debug(source_file) LOG.debug(bug_line) LOG.debug(bug.checker_name) # check for suppress comment supp = sp_handler.check_source_suppress() if supp: # something shoud be suppressed suppress_checkers = sp_handler.suppressed_checkers() if bug.checker_name in suppress_checkers or \ suppress_checkers == ['all']: suppress = True file_path, file_name = ntpath.split(source_file) # checker_hash, file_name, comment to_suppress = (bug_hash, file_name, sp_handler.suppress_comment()) LOG.debug(to_suppress) connection.add_suppress_bug([to_suppress]) report_id = connection.add_report(build_action_id, file_ids[bug.file_path], bug_hash, bug.msg, bug_paths, bug_events, bug.checker_name, bug.category, bug.type, severity, suppress) report_ids.append(report_id)
def test_empty_file(self): """Plist file is empty.""" empty_plist = os.path.join(self.__plist_test_files, 'empty_file') files, bugs = plist_parser.parse_plist(empty_plist) self.assertEquals(files, []) self.assertEquals(bugs, [])
def handle_results(self): """ send the plist content to the database server API calls should be used in one connection - addBuildAction - addReport - needFileContent - addFileContent - finishBuildAction """ with client.get_connection() as connection: LOG.debug( 'Storing original build and analyzer command to the database') analisys_id = connection.add_build_action( self.__run_id, self.buildaction.original_command, ' '.join(self.analyzer_cmd)) # store buildaction and analyzer command to the database _, source_file_name = ntpath.split(self.analyzed_source_file) if self.analyzer_returncode == 0: LOG.info(self.buildaction.analyzer_type + ' analyzed ' + source_file_name + ' successfully.') plist_file = self.get_analyzer_result_file() try: files, bugs = plist_parser.parse_plist(plist_file) except Exception as ex: LOG.debug(str(ex)) msg = 'Parsing the generated result file failed' LOG.error(msg + ' ' + plist_file) connection.finish_build_action(analisys_id, msg) return 1 file_ids = {} # Send content of file to the server if needed for file_name in files: file_descriptor = connection.need_file_content( self.__run_id, file_name) file_ids[file_name] = file_descriptor.fileId if file_descriptor.needed: with open(file_name, 'r') as source_file: file_content = source_file.read() compressed_file = zlib.compress( file_content, zlib.Z_BEST_COMPRESSION) # TODO: we may not use the file content in the end # depending on skippaths LOG.debug('storing file content to the database') connection.add_file_content(file_descriptor.fileId, compressed_file) # skipping bugs in header files handled here report_ids = [] for bug in bugs: events = bug.events() # skip list handler can be None if no config file is set if self.skiplist_handler: if events and self.skiplist_handler.should_skip( events[-1].start_pos.file_path): # Issue #20: this bug is in a file which should be skipped LOG.debug(bug.hash_value + ' is skipped (in ' + events[-1].start_pos.file_path + ")") continue # create remaining data for bugs and send them to the server bug_paths = [] for path in bug.paths(): bug_paths.append( shared.ttypes.BugPathPos( path.start_pos.line, path.start_pos.col, path.end_pos.line, path.end_pos.col, file_ids[path.start_pos.file_path])) bug_events = [] for event in bug.events(): bug_events.append( shared.ttypes.BugPathEvent( event.start_pos.line, event.start_pos.col, event.end_pos.line, event.end_pos.col, event.msg, file_ids[event.start_pos.file_path])) bug_hash = bug.hash_value severity_name = self.severity_map.get( bug.checker_name, 'UNSPECIFIED') severity = shared.ttypes.Severity._NAMES_TO_VALUES[ severity_name] suppress = False source_file = bug.file_path last_bug_event = bug.events()[-1] bug_line = last_bug_event.start_pos.line sp_handler = suppress_handler.SourceSuppressHandler( source_file, bug_line) # check for suppress comment supp = sp_handler.check_source_suppress() if supp: # something shoud be suppressed suppress_checkers = sp_handler.suppressed_checkers() if bug.checker_name in suppress_checkers or \ suppress_checkers == ['all']: suppress = True file_path, file_name = ntpath.split(source_file) # checker_hash, file_name, comment to_suppress = (bug_hash, file_name, sp_handler.suppress_comment()) LOG.debug(to_suppress) connection.add_suppress_bug( self.__run_id, [to_suppress]) LOG.debug('Storing check results to the database') report_id = connection.add_report( analisys_id, file_ids[bug.file_path], bug_hash, bug.msg, bug_paths, bug_events, bug.checker_name, bug.category, bug.type, severity, suppress) report_ids.append(report_id) else: LOG.info('Analysing ' + source_file_name + ' with ' + self.buildaction.analyzer_type + ' failed.') connection.finish_build_action(analisys_id, self.analyzer_stderr)
def send_plist_content(connection, plist_file, build_action_id, run_id, severity_map, should_skip): try: files, bugs = plist_parser.parse_plist(plist_file) except Exception as ex: LOG.info('The generated plist is not valid, so parsing failed.') return file_ids = {} # Send content of file to the server if needed for file_name in files: file_descriptor = connection.need_file_content(file_name) file_ids[file_name] = file_descriptor.fileId if file_descriptor.needed: with open(file_name, 'r') as source_file: file_content = source_file.read() compressed_file = zlib.compress(file_content, zlib.Z_BEST_COMPRESSION) # TODO: we may not use the file content in the end # depending on skippaths connection.add_file_content(file_descriptor.fileId, compressed_file) report_ids = [] for bug in bugs: events = bug.events() if events and should_skip(events[-1].start_pos.file_path): # Issue #20: this bug is in a file which should be skipped LOG.debug(bug.hash_value + ' is skipped (in ' + events[-1].start_pos.file_path + ")") continue # create remaining data for bugs and send them to the server bug_paths = [] for path in bug.paths(): bug_paths.append(shared.ttypes.BugPathPos(path.start_pos.line, path.start_pos.col, path.end_pos.line, path.end_pos.col, file_ids[path.start_pos.file_path])) bug_events = [] for event in bug.events(): bug_events.append(shared.ttypes.BugPathEvent(event.start_pos.line, event.start_pos.col, event.end_pos.line, event.end_pos.col, event.msg, file_ids[event.start_pos.file_path])) bug_hash = bug.hash_value bug_hash_type = bug.hash_type LOG.debug('Bug hash: ' + bug_hash) LOG.debug('Bug hash type: ' + str(bug_hash_type)) severity_name = severity_map.get(bug.checker_name, 'UNSPECIFIED') severity = shared.ttypes.Severity._NAMES_TO_VALUES[severity_name] report_id = connection.add_report(build_action_id, file_ids[bug.file_path], bug_hash, bug_hash_type, bug.msg, bug_paths, bug_events, bug.checker_name, bug.category, bug.type, severity) report_ids.append(report_id)