From 5cfdfd1817119fe4ccf9037d60efa1c063ee192b Mon Sep 17 00:00:00 2001 From: Georgios Kafanas Date: Wed, 11 Sep 2024 12:17:23 +0200 Subject: [PATCH] [bugfix] Cover edge cases with indistinguishable error log paths - In testing multiple failures can occur in quick succession resulting in the same time stamp, and as a result in the same base error log path. Extent the path stamp with an increasing number (naive O(n^2) algorithm used at the moment, should be sufficient). - In case the user provides the same error log path as the build directory log path, add a check to prevent copying the files to prevent errors in the copying functions. --- easybuild/framework/easyblock.py | 11 +++++++++-- easybuild/tools/config.py | 10 +++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/easybuild/framework/easyblock.py b/easybuild/framework/easyblock.py index 6a940b795e..cb21c1d3c4 100644 --- a/easybuild/framework/easyblock.py +++ b/easybuild/framework/easyblock.py @@ -4198,6 +4198,13 @@ def print_dry_run_note(loc, silent=True): def persists_failed_compilation_log_and_artifacts(build_successful, application_log, silent, app, err_log_path): + def do_if_paths_distinct(operation, source, destination): + if not os.path.exists(source): + return + if os.path.realpath(source) == os.path.realpath(destination): + return + operation(source, destination) + if application_log: # there may be multiple log files, or the file name may be different due to zipping logs = glob.glob('%s*' % application_log) @@ -4210,12 +4217,12 @@ def persists_failed_compilation_log_and_artifacts(build_successful, application_ if err_log_path and not build_successful: for log_file in logs: target_file = os.path.join(err_log_path, os.path.basename(log_file)) - copy_file(log_file, target_file) + do_if_paths_distinct(copy_file, log_file, target_file) builddir = app.builddir if is_readable(builddir): build_artifact_log_path = os.path.join(err_log_path, app.get_relative_builddir_base_path()) - copy_dir(builddir, build_artifact_log_path) + do_if_paths_distinct(copy_dir, builddir, build_artifact_log_path) print_msg( "Build log and any output artifacts copied to permanent storage: %s" % err_log_path, diff --git a/easybuild/tools/config.py b/easybuild/tools/config.py index eea0baf55d..cdfcde2f22 100644 --- a/easybuild/tools/config.py +++ b/easybuild/tools/config.py @@ -861,7 +861,15 @@ def error_log_path(ec=None): date = time.strftime("%Y%m%d") timestamp = time.strftime("%H%M%S") - return '/'.join([error_log_path, name + '-' + version, date + '-' + timestamp]) + base_path = '/'.join([error_log_path, name + '-' + version, date + '-' + timestamp]) + + path = base_path + inc_no = 1 + while os.path.exists(path): + path = base_path + '_' + str(inc_no) + inc_no += 1 + + return path def get_build_log_path():