Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cvise for openSUSE:Factory checked in at 2024-04-23 18:57:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cvise (Old) and /work/SRC/openSUSE:Factory/.cvise.new.27645 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cvise" Tue Apr 23 18:57:16 2024 rev:78 rq:1169838 version:2.10.0+git.20240415.00bdd8c Changes: -------- --- /work/SRC/openSUSE:Factory/cvise/cvise.changes 2024-03-17 22:17:40.432075155 +0100 +++ /work/SRC/openSUSE:Factory/.cvise.new.27645/cvise.changes 2024-04-23 18:57:43.190029043 +0200 @@ -1,0 +2,18 @@ +Tue Apr 23 08:30:30 UTC 2024 - martin.li...@hey.com + +- Update to version 2.10.0+git.20240415.00bdd8c: + * format: run ruff + * Implement a stopping threshold + * Revert removal of restore_mode + * format: use Ruff + * Make CVise understand files in a filesystem tree + * Refactor testing.py to pathlib module + * Write pass statistics and test-case to --log-file as well + * Show logs on stdout only when log-file arg is not provided + * Fixed ruff's warning about too many blank lines + * Removed basicConfig & fixed working of --log-file arg + * Drop -Wno-error=deprecated-declarations option + * fix deprecation warnings + * CI: Set default to LLVM 18 + +------------------------------------------------------------------- Old: ---- cvise-2.10.0+git.20240313.c860649.tar.xz New: ---- cvise-2.10.0+git.20240415.00bdd8c.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cvise.spec ++++++ --- /var/tmp/diff_new_pack.GW3Nuj/_old 2024-04-23 18:57:43.674046532 +0200 +++ /var/tmp/diff_new_pack.GW3Nuj/_new 2024-04-23 18:57:43.674046532 +0200 @@ -17,7 +17,7 @@ Name: cvise -Version: 2.10.0+git.20240313.c860649 +Version: 2.10.0+git.20240415.00bdd8c Release: 0 Summary: Super-parallel Python port of the C-Reduce License: BSD-3-Clause ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.GW3Nuj/_old 2024-04-23 18:57:43.714047977 +0200 +++ /var/tmp/diff_new_pack.GW3Nuj/_new 2024-04-23 18:57:43.714047977 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/marxin/cvise</param> - <param name="changesrevision">c8606497e354ddab273745cf823823bdd3e86bd8</param></service></servicedata> + <param name="changesrevision">00bdd8c1f9824002b10ac5fecd31dff6c5bef671</param></service></servicedata> (No newline at EOF) ++++++ cvise-2.10.0+git.20240313.c860649.tar.xz -> cvise-2.10.0+git.20240415.00bdd8c.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.10.0+git.20240313.c860649/.github/workflows/build.yml new/cvise-2.10.0+git.20240415.00bdd8c/.github/workflows/build.yml --- old/cvise-2.10.0+git.20240313.c860649/.github/workflows/build.yml 2024-03-13 21:19:48.000000000 +0100 +++ new/cvise-2.10.0+git.20240415.00bdd8c/.github/workflows/build.yml 2024-04-15 13:06:47.000000000 +0200 @@ -16,17 +16,17 @@ strategy: matrix: - llvm: [13, 14, 15, 16, 17] + llvm: [13, 14, 15, 16, 17, 18] build-type: [DEBUG] include: - - llvm: 17 + - llvm: 18 build-type: ASAN - - llvm: 17 + - llvm: 18 build-type: UBSAN - - llmv: 17 + - llmv: 18 build-type: RelWithDebInfo extra-flags: -flto=auto - - llmv: 17 + - llmv: 18 build-type: RelWithDebInfo env: CC=clang CXX=clang++ fail-fast: false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.10.0+git.20240313.c860649/.gitignore new/cvise-2.10.0+git.20240415.00bdd8c/.gitignore --- old/cvise-2.10.0+git.20240313.c860649/.gitignore 2024-03-13 21:19:48.000000000 +0100 +++ new/cvise-2.10.0+git.20240415.00bdd8c/.gitignore 2024-04-15 13:06:47.000000000 +0200 @@ -71,3 +71,5 @@ # pyenv files .python-version +compile_commands.json +.cache/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.10.0+git.20240313.c860649/CMakeLists.txt new/cvise-2.10.0+git.20240415.00bdd8c/CMakeLists.txt --- old/cvise-2.10.0+git.20240313.c860649/CMakeLists.txt 2024-03-13 21:19:48.000000000 +0100 +++ new/cvise-2.10.0+git.20240415.00bdd8c/CMakeLists.txt 2024-04-15 13:06:47.000000000 +0200 @@ -162,11 +162,6 @@ SUPPORTS_NON_TEMPLATE_FRIEND ) -check_cxx_compiler_flag( - "-Wdeprecated-declarations" - SUPPORTS_DEPRECATED_DECLARATIONS -) - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") # XXX figure out how to get "-std=c++17 -fno-rtti" from LLVM. That's how we @@ -192,10 +187,6 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=non-template-friend") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=non-template-friend") endif() - iF(SUPPORTS_DEPRECATED_DECLARATIONS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=deprecated-declarations") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=deprecated-declarations") - endif() set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -O3 -g") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.10.0+git.20240313.c860649/clang_delta/ExpressionDetector.cpp new/cvise-2.10.0+git.20240415.00bdd8c/clang_delta/ExpressionDetector.cpp --- old/cvise-2.10.0+git.20240313.c860649/clang_delta/ExpressionDetector.cpp 2024-03-13 21:19:48.000000000 +0100 +++ new/cvise-2.10.0+git.20240415.00bdd8c/clang_delta/ExpressionDetector.cpp 2024-04-15 13:06:47.000000000 +0200 @@ -142,7 +142,11 @@ const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()); if (!VD) return true; +#if LLVM_VERSION_MAJOR < 18 if (VD->getName().startswith(Prefix)) +#else + if (VD->getName().starts_with(Prefix)) +#endif TmpVars.push_back(VD); return true; } @@ -387,7 +391,11 @@ { if (!VD) return; +#if LLVM_VERSION_MAJOR < 18 if (!VD->getName().startswith(TmpVarNamePrefix)) +#else + if (!VD->getName().starts_with(TmpVarNamePrefix)) +#endif return; if (const Expr *E = VD->getInit()) ProcessedExprs[VD] = E->IgnoreParenImpCasts(); @@ -398,9 +406,15 @@ StringRef Name = ND->getName(); // We don't want to repeatly replace temporary variables // __cvise_expr_tmp_xxx, __cvise_printed_yy and __cvise_checked_zzz. +#if LLVM_VERSION_MAJOR < 18 return Name.startswith(TmpVarNamePrefix) || Name.startswith(PrintedVarNamePrefix) || Name.startswith(CheckedVarNamePrefix); +#else + return Name.starts_with(TmpVarNamePrefix) || + Name.starts_with(PrintedVarNamePrefix) || + Name.starts_with(CheckedVarNamePrefix); +#endif } // Reference: IdenticalExprChecker.cpp from Clang @@ -548,8 +562,13 @@ if (const DeclRefExpr *SubE = dyn_cast<DeclRefExpr>(UO->getSubExpr()->IgnoreParenCasts())) { StringRef SubEName = SubE->getDecl()->getName(); +#if LLVM_VERSION_MAJOR < 18 if (SubEName.startswith(PrintedVarNamePrefix) || SubEName.startswith(CheckedVarNamePrefix)) +#else + if (SubEName.starts_with(PrintedVarNamePrefix) || + SubEName.starts_with(CheckedVarNamePrefix)) +#endif return false; } } @@ -565,7 +584,11 @@ bool IsLit = SC == Stmt::IntegerLiteralClass || SC == Stmt::FloatingLiteralClass; if (IsLit && DRE && +#if LLVM_VERSION_MAJOR < 18 DRE->getDecl()->getName().startswith(TmpVarNamePrefix) && +#else + DRE->getDecl()->getName().starts_with(TmpVarNamePrefix) && +#endif S->getStmtClass() == Stmt::IfStmtClass) { return false; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.10.0+git.20240313.c860649/clang_delta/RemoveNamespace.cpp new/cvise-2.10.0+git.20240415.00bdd8c/clang_delta/RemoveNamespace.cpp --- old/cvise-2.10.0+git.20240313.c860649/clang_delta/RemoveNamespace.cpp 2024-03-13 21:19:48.000000000 +0100 +++ new/cvise-2.10.0+git.20240415.00bdd8c/clang_delta/RemoveNamespace.cpp 2024-04-15 13:06:47.000000000 +0200 @@ -969,7 +969,11 @@ TransAssert(IdInfo && "Invalid IdentifierInfo!"); NewName += IdInfo->getName(); // Make sure we have valid suffix for user literals +#if LLVM_VERSION_MAJOR < 18 if (IsUserLiteral && IdInfo->getName().startswith("_")) { +#else + if (IsUserLiteral && IdInfo->getName().starts_with("_")) { +#endif NewName = "_" + NewName; } NamedDeclToNewName[ND] = NewName; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.10.0+git.20240313.c860649/cvise/cvise.py new/cvise-2.10.0+git.20240415.00bdd8c/cvise/cvise.py --- old/cvise-2.10.0+git.20240313.c860649/cvise/cvise.py 2024-03-13 21:19:48.000000000 +0100 +++ new/cvise-2.10.0+git.20240415.00bdd8c/cvise/cvise.py 2024-04-15 13:06:47.000000000 +0200 @@ -189,7 +189,18 @@ while True: total_file_size = self.test_manager.total_file_size + met_stopping_threshold = False for p in passes: + # Exit early if we're already reduced enough + improvement = ( + self.test_manager.orig_total_file_size - total_file_size + ) / self.test_manager.orig_total_file_size + logging.info( + f'Termination check: stopping threshold is {self.test_manager.stopping_threshold}; current improvement is {improvement}' + ) + if improvement >= self.test_manager.stopping_threshold: + met_stopping_threshold = True + break if not p.check_prerequisites(): logging.error(f'Skipping pass {p}') else: @@ -197,5 +208,5 @@ logging.info(f'Termination check: size was {total_file_size}; now {self.test_manager.total_file_size}') - if self.test_manager.total_file_size >= total_file_size: + if (self.test_manager.total_file_size >= total_file_size) or met_stopping_threshold: break diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.10.0+git.20240313.c860649/cvise/utils/error.py new/cvise-2.10.0+git.20240415.00bdd8c/cvise/utils/error.py --- old/cvise-2.10.0+git.20240313.c860649/cvise/utils/error.py 2024-03-13 21:19:48.000000000 +0100 +++ new/cvise-2.10.0+git.20240415.00bdd8c/cvise/utils/error.py 2024-04-15 13:06:47.000000000 +0200 @@ -46,12 +46,12 @@ return f"The specified test case '{self.path}' cannot be {self._get_error_name()}!" -class FolderInPathTestCaseError(CViseError): +class AbsolutePathTestCaseError(CViseError): def __init__(self, path): self.path = path def __str__(self): - return f"Test case cannot contain a folder in path: '{self.path}'!" + return f"Test case path cannot be absolute: '{self.path}'!" class InvalidInterestingnessTestError(InvalidFileError): @@ -137,5 +137,7 @@ Please ensure that the test script takes no arguments; it should be hard-coded to refer to the same file that is passed as an argument to C-Vise. -See 'cvise.py --help' for more information.""".format(test_cases=' '.join(self.test_cases), test=self.test) +See 'cvise.py --help' for more information.""".format( + test_cases=' '.join([str(t) for t in self.test_cases]), test=self.test + ) return message diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.10.0+git.20240313.c860649/cvise/utils/testing.py new/cvise-2.10.0+git.20240415.00bdd8c/cvise/utils/testing.py --- old/cvise-2.10.0+git.20240313.c860649/cvise/utils/testing.py 2024-03-13 21:19:48.000000000 +0100 +++ new/cvise-2.10.0+git.20240415.00bdd8c/cvise/utils/testing.py 2024-04-15 13:06:47.000000000 +0200 @@ -5,7 +5,7 @@ import math from multiprocessing import Manager import os -import os.path +from pathlib import Path import platform import shutil import subprocess @@ -15,7 +15,7 @@ from cvise.cvise import CVise from cvise.passes.abstract import PassResult, ProcessEventNotifier, ProcessEventType -from cvise.utils.error import FolderInPathTestCaseError +from cvise.utils.error import AbsolutePathTestCaseError from cvise.utils.error import InsaneTestCaseError from cvise.utils.error import InvalidInterestingnessTestError from cvise.utils.error import InvalidTestCaseError @@ -32,7 +32,7 @@ def rmfolder(name): - assert 'cvise' in name + assert 'cvise' in str(name) try: shutil.rmtree(name) except OSError: @@ -47,12 +47,10 @@ test_script, folder, test_case, - additional_files, + all_test_cases, transform, pid_queue=None, ): - self.test_case = None - self.additional_files = set() self.state = state self.folder = folder self.base_size = None @@ -62,51 +60,40 @@ self.order = order self.transform = transform self.pid_queue = pid_queue - self.copy_files(test_case, additional_files) self.pwd = os.getcwd() - - def copy_files(self, test_case, additional_files): - if test_case is not None: - self.test_case = os.path.basename(test_case) - shutil.copy(test_case, self.folder) - self.base_size = os.path.getsize(test_case) - - for f in additional_files: - self.additional_files.add(os.path.basename(f)) - shutil.copy(f, self.folder) + self.test_case = test_case + self.base_size = test_case.stat().st_size + self.all_test_cases = all_test_cases + + # Copy files to the created folder + for test_case in all_test_cases: + (self.folder / test_case.parent).mkdir(parents=True, exist_ok=True) + shutil.copy2(test_case, self.folder / test_case.parent) @property def size_improvement(self): - if self.base_size is None: - return None - else: - return self.base_size - os.path.getsize(self.test_case_path) + return self.base_size - self.test_case_path.stat().st_size @property def test_case_path(self): - return os.path.join(self.folder, self.test_case) - - @property - def additional_files_paths(self): - return [os.path.join(self.folder, f) for f in self.additional_files] + return self.folder / self.test_case @property def success(self): return self.result == PassResult.OK and self.exitcode == 0 def dump(self, dst): - if self.test_case is not None: - shutil.copy(self.test_case_path, dst) - - for f in self.additional_files: - shutil.copy(f, dst) + for f in self.all_test_cases: + shutil.copy(self.folder / f, dst) shutil.copy(self.test_script, dst) def run(self): try: # transform by state - (result, self.state) = self.transform(self.test_case_path, self.state, ProcessEventNotifier(self.pid_queue)) + (result, self.state) = self.transform( + str(self.test_case_path), self.state, ProcessEventNotifier(self.pid_queue) + ) self.result = result if self.result != PassResult.OK: return self @@ -125,7 +112,9 @@ def run_test(self, verbose): try: os.chdir(self.folder) - stdout, stderr, returncode = ProcessEventNotifier(self.pid_queue).run_process(self.test_script, shell=True) + stdout, stderr, returncode = ProcessEventNotifier(self.pid_queue).run_process( + str(self.test_script), shell=True + ) if verbose and returncode != 0: logging.debug('stdout:\n' + stdout) logging.debug('stderr:\n' + stderr) @@ -159,8 +148,9 @@ also_interesting, start_with_pass, skip_after_n_transforms, + stopping_threshold, ): - self.test_script = os.path.abspath(test_script) + self.test_script = Path(test_script).absolute() self.timeout = timeout self.save_temps = save_temps self.pass_statistic = pass_statistic @@ -177,14 +167,15 @@ self.also_interesting = also_interesting self.start_with_pass = start_with_pass self.skip_after_n_transforms = skip_after_n_transforms + self.stopping_threshold = stopping_threshold for test_case in test_cases: + test_case = Path(test_case) + self.test_cases_modes[test_case] = test_case.stat().st_mode self.check_file_permissions(test_case, [os.F_OK, os.R_OK, os.W_OK], InvalidTestCaseError) - if os.path.split(test_case)[0]: - raise FolderInPathTestCaseError(test_case) - fullpath = os.path.abspath(test_case) - self.test_cases.add(fullpath) - self.test_cases_modes[fullpath] = os.stat(fullpath).st_mode + if test_case.parent.is_absolute(): + raise AbsolutePathTestCaseError(test_case) + self.test_cases.add(test_case) self.orig_total_file_size = self.total_file_size self.cache = {} @@ -214,7 +205,7 @@ def restore_mode(self): for test_case in self.test_cases: - os.chmod(test_case, self.test_cases_modes[test_case]) + test_case.chmod(self.test_cases_modes[test_case]) @classmethod def is_valid_test(cls, test_script): @@ -229,11 +220,11 @@ @property def sorted_test_cases(self): - return sorted(self.test_cases, key=os.path.getsize, reverse=True) + return sorted(self.test_cases, key=lambda x: x.stat().st_size, reverse=True) @staticmethod def get_file_size(files): - return sum(os.path.getsize(f) for f in files) + return sum(f.stat().st_size for f in files) @property def total_line_count(self): @@ -250,9 +241,9 @@ def backup_test_cases(self): for f in self.test_cases: - orig_file = f'{f}.orig' + orig_file = Path(f'{f}.orig') - if not os.path.exists(orig_file): + if not orig_file.exists(): # Copy file and preserve attributes shutil.copy2(f, orig_file) @@ -271,14 +262,14 @@ def get_extra_dir(prefix, max_number): for i in range(0, max_number + 1): digits = int(round(math.log10(max_number), 0)) - extra_dir = ('{0}{1:0' + str(digits) + 'd}').format(prefix, i) + extra_dir = Path(('{0}{1:0' + str(digits) + 'd}').format(prefix, i)) - if not os.path.exists(extra_dir): + if not extra_dir.exists(): break # just bail if we've already created enough of these dirs, no need to # clutter things up even more... - if os.path.exists(extra_dir): + if extra_dir.exists(): return None return extra_dir @@ -294,7 +285,7 @@ if crash_dir is None: return False - os.mkdir(crash_dir) + crash_dir.mkdir() test_env.dump(crash_dir) if not self.die_on_pass_bug: @@ -302,7 +293,7 @@ f'Please consider tarring up {crash_dir} and creating an issue at https://github.com/marxin/cvise/issues and we will try to fix the bug.' ) - with open(os.path.join(crash_dir, 'PASS_BUG_INFO.TXT'), mode='w') as info_file: + with (crash_dir / 'PASS_BUG_INFO.TXT').open(mode='w') as info_file: info_file.write('Package: %s\n' % CVise.Info.PACKAGE_STRING) info_file.write('Git version: %s\n' % CVise.Info.GIT_VERSION) info_file.write('LLVM version: %s\n' % CVise.Info.LLVM_VERSION) @@ -329,8 +320,8 @@ def check_sanity(self, verbose=False): logging.debug('perform sanity check... ') - folder = tempfile.mkdtemp(prefix=f'{self.TEMP_PREFIX}sanity-') - test_env = TestEnvironment(None, 0, self.test_script, folder, None, self.test_cases, None) + folder = Path(tempfile.mkdtemp(prefix=f'{self.TEMP_PREFIX}sanity-')) + test_env = TestEnvironment(None, 0, self.test_script, folder, list(self.test_cases)[0], self.test_cases, None) logging.debug(f'sanity check tmpdir = {test_env.folder}') returncode = test_env.run_test(verbose) @@ -479,14 +470,14 @@ self.terminate_all(pool) return success - folder = tempfile.mkdtemp(prefix=self.TEMP_PREFIX, dir=self.root) + folder = Path(tempfile.mkdtemp(prefix=self.TEMP_PREFIX, dir=self.root)) test_env = TestEnvironment( self.state, order, self.test_script, folder, self.current_test_case, - self.test_cases ^ {self.current_test_case}, + self.test_cases, self.current_pass.transform, self.pid_queue, ) @@ -531,7 +522,7 @@ try: for test_case in self.sorted_test_cases: self.current_test_case = test_case - starting_test_case_size = os.path.getsize(test_case) + starting_test_case_size = test_case.stat().st_size success_count = 0 if self.get_file_size([test_case]) == 0: @@ -571,7 +562,7 @@ success_count += 1 # if the file increases significantly, bail out the current pass - test_case_size = os.path.getsize(self.current_test_case) + test_case_size = self.current_test_case.stat().st_size if test_case_size >= MAX_PASS_INCREASEMENT_THRESHOLD * starting_test_case_size: logging.info( f'skipping the rest of the pass (huge file increasement ' @@ -631,6 +622,6 @@ if self.total_line_count: notes.append(f'{self.total_line_count} lines') if len(self.test_cases) > 1: - notes.append(test_env.test_case) + notes.append(str(test_env.test_case)) logging.info('(' + ', '.join(notes) + ')') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.10.0+git.20240313.c860649/cvise.py new/cvise-2.10.0+git.20240415.00bdd8c/cvise.py --- old/cvise-2.10.0+git.20240313.c860649/cvise.py 2024-03-13 21:19:48.000000000 +0100 +++ new/cvise-2.10.0+git.20240415.00bdd8c/cvise.py 2024-04-15 13:06:47.000000000 +0200 @@ -337,6 +337,12 @@ help='Executable to check interestingness of test cases', ) parser.add_argument('test_cases', metavar='TEST_CASE', nargs='+', help='Test cases') + parser.add_argument( + '--stopping-threshold', + default=1.0, + type=float, + help='CVise will stop reducing a test case once it has reduced by this fraction of its original size. Between 0.0 and 1.0.', + ) args = parser.parse_args() @@ -354,15 +360,18 @@ else: log_config['level'] = getattr(logging, args.log_level.upper()) - if args.log_file is not None: - log_config['filename'] = args.log_file - - logging.basicConfig(**log_config) - syslog = logging.StreamHandler() + logging.getLogger().setLevel(log_config['level']) formatter = DeltaTimeFormatter(log_format) - syslog.setFormatter(formatter) - logging.getLogger().handlers = [] - logging.getLogger().addHandler(syslog) + root_logger = logging.getLogger() + + if args.log_file is not None: + file_handler = logging.FileHandler(args.log_file) + file_handler.setFormatter(formatter) + root_logger.addHandler(file_handler) + else: + syslog = logging.StreamHandler() + syslog.setFormatter(formatter) + root_logger.addHandler(syslog) pass_options = set() @@ -461,6 +470,7 @@ args.also_interesting, args.start_with_pass, args.skip_after_n_transforms, + args.stopping_threshold, ) reducer = CVise(test_manager, args.skip_interestingness_test_check) @@ -477,43 +487,44 @@ print(err) else: time_stop = time.monotonic() - print('===< PASS statistics >===') - print( - ' %-60s %8s %8s %8s %8s %15s' - % ( - 'pass name', - 'time (s)', - 'time (%)', - 'worked', - 'failed', - 'total executed', - ) - ) - - for pass_name, pass_data in pass_statistic.sorted_results: - print( - ' %-60s %8.2f %8.2f %8d %8d %15d' + with open(args.log_file, 'a') if args.log_file else sys.stderr as fs: + fs.write('===< PASS statistics >===\n') + fs.write( + ' %-60s %8s %8s %8s %8s %15s\n' % ( - pass_name, - pass_data.total_seconds, - 100.0 * pass_data.total_seconds / (time_stop - time_start), - pass_data.worked, - pass_data.failed, - pass_data.totally_executed, + 'pass name', + 'time (s)', + 'time (%)', + 'worked', + 'failed', + 'total executed', ) ) - print() - if not args.no_timing: - print(f'Runtime: {round(time_stop - time_start)} seconds') + for pass_name, pass_data in pass_statistic.sorted_results: + fs.write( + ' %-60s %8.2f %8.2f %8d %8d %15d\n' + % ( + pass_name, + pass_data.total_seconds, + 100.0 * pass_data.total_seconds / (time_stop - time_start), + pass_data.worked, + pass_data.failed, + pass_data.totally_executed, + ) + ) + fs.write('\n') + + if not args.no_timing: + fs.write(f'Runtime: {round(time_stop - time_start)} seconds\n') - print('Reduced test-cases:\n') - for test_case in sorted(test_manager.test_cases): - if misc.is_readable_file(test_case): - print(f'--- {test_case} ---') - with open(test_case) as test_case_file: - print(test_case_file.read()) - if script: - os.unlink(script.name) + fs.write('Reduced test-cases:\n\n') + for test_case in sorted(test_manager.test_cases): + if misc.is_readable_file(test_case): + print(f'--- {test_case} ---') + with open(test_case) as test_case_file: + fs.write(test_case_file.read() + '\n') + if script: + os.unlink(script.name) logging.shutdown()