def loop_check(): write_log_info("Run database cleanup before start") drop_ids = database_cleanup() write_log_info("Abandoned items: {%s}" % ", ".join(drop_ids)) loop_check_func = multi_thread_check if ENABLE_MULTI_THREAD else single_thread_check check_list = [cls for cls in CHECK_LIST if not cls._skip] while True: start_time = _get_time_str() print(" - " + start_time) print(" - Start...") write_log_info("=" * 64) write_log_info("Start checking at %s" % start_time) # loop_check_func必须返回两个值, # 检查失败的项目的列表, 以及是否为网络错误或代理错误的Bool值 check_failed_list, is_network_error = loop_check_func(check_list) if is_network_error: print_and_log("Network or proxy error! Sleep...", level="warning") else: # 对于检查失败的项目, 强制单线程检查 print_and_log("Check again for failed items") for cls in check_failed_list: check_one(cls) PAGE_CACHE.clear() print(" - The next check will start at %s\n" % _get_time_str(offset=LOOP_CHECK_INTERVAL)) write_log_info("End of check") _sleep(LOOP_CHECK_INTERVAL)
def run_unit_tests(pytest_command, logger): """ Perform an initial run of the unit test suite using 'py.test -v' """ last_line = '' for line in run_command(pytest_command): last_line = line test_result = last_line.replace("=", "").strip() print_and_log(logger, 'Test Results : %s\n' % test_result) # Simple logic will need to be adapted depending on test runner if ('passed' in test_result) and ('failed' not in test_result): return True else: return False
def run_unit_tests(pytest_command, logger): ''' Perform an initial run of the unit tests using 'py.test -v' ''' last_line = '' for line in run_command(pytest_command): last_line = line test_result = last_line.replace("=", "").strip() print_and_log(logger, 'Test Results : %s\n' % test_result) # Simple logic will need to be adapted depending on test runner if ('passed' in test_result) and ('failed' not in test_result): return True else: return False
def mutation_tester(file_under_test, unit_test_suite, mutation_log_file): # Construct command for running pytest pytest_command = 'py.test -v ' + unit_test_suite # Set the log file path/name (should be OS independent) if not os.path.exists('mutate_logs'): os.mkdir('mutate_logs') if mutation_log_file is not None: log_file = os.path.join('mutate_logs', mutation_log_file) else: log_file = os.path.join('mutate_logs', extract_file_name(file_under_test).replace('.py', '.log')) logger = initialise_logger(log_file) print_and_log(logger, 'Mutation Tester Run : %s' % str(time.strftime("%d-%m-%Y %H:%M"))) print_and_log(logger, 'File Under Test : %s' % file_under_test) print_and_log(logger, 'Compiled File Under Test : %s' % file_under_test.replace('.py', '.pyc')) print_and_log(logger, 'Unit Test Suite : %s' % unit_test_suite) print_and_log(logger, 'Log File : %s' % log_file) sample_source = get_file_as_string(file_under_test) initial_tree = ast.parse(sample_source) compiled = compile(initial_tree, '<ast>', 'exec') compile_to_file(filename=file_under_test.replace('.py', '.pyc'), compiled_code=compiled) original_pass = run_unit_tests(pytest_command, logger) file_under_test_backup = file_under_test.replace(".py", ".txt") ast_visitor = AstVisitor(filename=file_under_test) if original_pass: print_and_log(logger, 'Original tests passed, commencing mutations') else: print_and_log(logger, 'Original test failed, exiting\n') quit() rename_file(file_under_test, file_under_test_backup) mutant_count = 0 for mutator in ast_visitor.mutators: mutant_count += mutator.mutations_count() print_and_log(logger, '{0} mutant{1} generated (s denotes survived, k denotes killed)\n'.format(mutant_count, 's' if mutant_count != 1 else '')) killed = 0 survived = 0 for mutator in ast_visitor.mutators: for x in range(0, mutator.mutations_count()): mutator.mutate(x) compiled = compile(ast_visitor.initial_tree, '<ast>', 'exec') compile_to_file(file_under_test.replace('.py', '.pyc'), compiled) failures = unit_test_failures(pytest_command) if not failures: survived += 1 logger.info('-' * 50 + '\n' + "Mutant SURVIVED\n" + '-' * 50) mutator.log_mutant(file_under_test, logger) sys.stdout.write('s') logger.info('\n') else: killed += 1 logger.info('-' * 50 + '\n' + "Mutant KILLED\n" + '-' * 50) mutator.log_mutant(file_under_test, logger) sys.stdout.write('k') logger.info(failures) mutator.reset() if mutant_count != 0: print_and_log(logger, '\n\n' + '-' * 50) print_and_log(logger, 'Mutants survived : {0}/{1}'.format(survived, mutant_count)) print_and_log(logger, 'Mutants killed : {0}/{1}'.format(killed, mutant_count)) print_and_log(logger, 'Mutant kill rate : {0}%'.format(int(float(killed * 100) / float(mutant_count)))) print_and_log(logger, '-' * 50) else: print_and_log(logger, 'No mutants generated') rename_file(file_under_test_backup, file_under_test)
def check_one(cls, disable_pagecache=False): if isinstance(cls, str): cls_str = cls cls = {cls_.__name__: cls_ for cls_ in CHECK_LIST}.get(cls_str) if not cls: raise Exception("Can not found '%s' from CHECK_LIST!" % cls_str) cls_obj = cls() if disable_pagecache: cls_obj.enable_pagecache = False try: cls_obj.do_check() except exceptions.ReadTimeout: print_and_log("%s check failed! Timeout." % cls_obj.fullname, level="warning") except (exceptions.SSLError, exceptions.ProxyError): print_and_log("%s check failed! Proxy error." % cls_obj.fullname, level="warning") except exceptions.ConnectionError: print_and_log("%s check failed! Connection error." % cls_obj.fullname, level="warning") except exceptions.HTTPError as error: print_and_log("%s check failed! %s." % (cls_obj.fullname, error), level="warning") except: traceback_string = traceback.format_exc() print(traceback_string) write_log_warning(*traceback_string.splitlines()) print_and_log("%s check failed!" % cls_obj.fullname, level="warning") else: if cls_obj.is_updated() or FORCE_UPDATE: print_and_log( "%s has update: %s" % (cls_obj.fullname, cls_obj.info_dic["LATEST_VERSION"]), custom_prefix=">", ) try: cls_obj.after_check() except: traceback_string = traceback.format_exc() print("\n%s\n! Something wrong when running after_check!" % traceback_string) write_log_warning(*traceback_string.splitlines()) write_log_warning( "%s: Something wrong when running after_check!" % cls_obj.fullname) cls_obj.write_to_database() if ENABLE_SENDMESSAGE: cls_obj.send_message() else: print("- %s no update" % cls_obj.fullname) if not LESS_LOG: write_log_info("%s no update" % cls_obj.fullname) return True
def _abort(text): print_and_log(str(text), level="warning", custom_prefix="-") sys.exit(1)
def mutation_tester(file_under_test, unit_test_suite, mutation_log_file): # Construct command for running pytest pytest_command = 'py.test -v ' + unit_test_suite # Set the log file path/name (should be OS independent) if not os.path.exists('logs'): os.mkdir('logs') if (mutation_log_file is not None): log_file = os.path.join('logs', mutation_log_file) else: log_file = os.path.join( 'logs', extract_fut_name(file_under_test).replace('.py', '.log')) logger = initialise_logger(log_file) print_and_log( logger, 'Mutation Tester Run : %s' % str(time.strftime("%d-%m-%Y %H:%M"))) print_and_log(logger, 'File Under Test : %s' % file_under_test) print_and_log( logger, 'Compiled File Under Test : %s' % file_under_test.replace('.py', '.pyc')) print_and_log(logger, 'Unit Test Suite : %s' % unit_test_suite) print_and_log(logger, 'Log File : %s' % log_file) sample_source = get_file_as_string(file_under_test) initial_tree = ast.parse(sample_source) compiled = compile(initial_tree, '<ast>', 'exec') compile_to_file(filename=file_under_test.replace('.py', '.pyc'), compiled_code=compiled) original_pass = run_unit_tests(pytest_command, logger) file_under_test_backup = file_under_test.replace(".py", ".txt") ast_visitor = AstVisitor(filename=file_under_test) if original_pass: print_and_log(logger, 'Original tests passed, commencing mutations') else: print_and_log(logger, 'Original test failed, exiting\n') quit() rename_file(file_under_test, file_under_test_backup) mutant_count = 0 for mutator in ast_visitor.mutators: mutant_count += mutator.mutations_count() print_and_log( logger, '{0} mutant{1} generated (s denotes survived, k denotes killed)\n'. format(mutant_count, 's' if mutant_count != 1 else '')) killed = 0 survived = 0 for mutator in ast_visitor.mutators: for x in range(0, mutator.mutations_count()): mutator.mutate(x) compiled = compile(ast_visitor.initial_tree, '<ast>', 'exec') compile_to_file(file_under_test.replace('.py', '.pyc'), compiled) failures = unit_test_failures(pytest_command) if not failures: survived += 1 logger.info('-' * 50 + '\n' + "Mutant SURVIVED\n" + '-' * 50) mutator.log_mutant(file_under_test, logger) sys.stdout.write('s') logger.info('\n') else: killed += 1 logger.info('-' * 50 + '\n' + "Mutant KILLED\n" + '-' * 50) mutator.log_mutant(file_under_test, logger) sys.stdout.write('k') logger.info(failures) mutator.reset() if mutant_count != 0: print_and_log(logger, '\n\n' + '-' * 50) print_and_log( logger, 'Mutants survived : {0}/{1}'.format( survived, mutant_count)) print_and_log( logger, 'Mutants killed : {0}/{1}'.format(killed, mutant_count)) print_and_log( logger, 'Mutant kill rate : {0}%'.format( int(float(killed * 100) / float(mutant_count)))) print_and_log(logger, '-' * 50) else: print_and_log(logger, 'No mutants generated') rename_file(file_under_test_backup, file_under_test)