From 50cc1625422ab7cf4cf135c04f5edea021e6af7f Mon Sep 17 00:00:00 2001 From: Praveen K Pandey Date: Tue, 4 Aug 2026 13:40:15 +0530 Subject: [PATCH 1/4] avocado-setup: replace job_id hash extraction with os.path.abspath() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Short 7-char hash suffix extracted from the job dir name is not unique enough when multiple prior jobs share the same suffix — avocado raises ValueError: 'hash is not unique enough'. Switch to passing the full absolute path directly. avocado's get_job_results_dir() accepts a direct path when the directory exists and contains an 'id' file, so no hash lookup is needed at all. Signed-off-by: Praveen K Pandey --- avocado-setup.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/avocado-setup.py b/avocado-setup.py index ae09f76..6800c16 100644 --- a/avocado-setup.py +++ b/avocado-setup.py @@ -393,10 +393,12 @@ def run_test(testsuite, avocado_bin, runner, linux_src_path, resume_job_dir=None :param resume_job_dir: Prior avocado job dir for resume mode (or None) """ if resume_job_dir: - # avocado replay re-runs only not-passed tests from that job. - # The job_id is the trailing hex in the job dir name e.g. - # job-2026-07-28T04.29-07add70 → job_id = 07add70 - job_id = os.path.basename(resume_job_dir).rsplit('-', 1)[-1] + # Pass the full absolute path so avocado can resolve the job directory + # unambiguously without hash prefix matching (which raises ValueError + # "hash is not unique enough" when multiple jobs share the same 7-char + # suffix). avocado's get_job_results_dir() accepts a direct path when + # the directory exists and contains an 'id' file. + replay_path = os.path.abspath(resume_job_dir) logger.info("Resuming suite %s via avocado replay %s", testsuite.name, job_id) cmd = "%s replay %s" % (avocado_bin, job_id) From 139047a7c539eb4b5e49ecb02b749edae483147c Mon Sep 17 00:00:00 2001 From: Praveen K Pandey Date: Tue, 4 Aug 2026 13:40:40 +0530 Subject: [PATCH 2/4] avocado-setup: use replay_path and add --resume flag to avocado replay cmd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wire up replay_path (introduced in the previous commit) into both the logger.info call and the avocado replay command string. Add --resume so avocado skips tests that already PASS/SKIP in the source job and only re-runs the remaining/interrupted tests — without it avocado replays the entire job from scratch. Signed-off-by: Praveen K Pandey --- avocado-setup.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/avocado-setup.py b/avocado-setup.py index 6800c16..bc1ffe2 100644 --- a/avocado-setup.py +++ b/avocado-setup.py @@ -399,9 +399,11 @@ def run_test(testsuite, avocado_bin, runner, linux_src_path, resume_job_dir=None # suffix). avocado's get_job_results_dir() accepts a direct path when # the directory exists and contains an 'id' file. replay_path = os.path.abspath(resume_job_dir) + # --resume tells avocado to skip tests that already passed/were skipped + # in the source job, so only the remaining/interrupted tests are re-run. logger.info("Resuming suite %s via avocado replay %s", - testsuite.name, job_id) - cmd = "%s replay %s" % (avocado_bin, job_id) + testsuite.name, replay_path) + cmd = "%s replay %s --resume" % (avocado_bin, replay_path) else: nrun = True if runner: From 71f5f08f1f4efd59d64c81a83351d6836463deba Mon Sep 17 00:00:00 2001 From: Praveen K Pandey Date: Tue, 4 Aug 2026 13:41:09 +0530 Subject: [PATCH 3/4] avocado-setup: expand _suite_replay_dir() docstring with priority order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old two-line docstring did not explain the three decision cases or why the __interrupted__ key is treated differently from a normal suite match. Replace it with an explicit numbered priority list so future readers understand the logic without having to trace through the code. No functional change — docstring only. Signed-off-by: Praveen K Pandey --- avocado-setup.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/avocado-setup.py b/avocado-setup.py index bc1ffe2..ceb9558 100644 --- a/avocado-setup.py +++ b/avocado-setup.py @@ -970,8 +970,13 @@ def _suite_completed(suite_name): def _suite_replay_dir(suite_name): """Return the prior job dir to replay for this suite, or None. - Returns None when suite has no prior job dir (never ran) - so it gets a normal fresh run instead of a replay. + + Priority order: + 1. Suite has its own matched job dir and it is not complete → replay it. + 2. An unmatched interrupted job dir exists and this suite has no own + job dir (i.e. it was the suite running when the job was killed and + no results.json was written) → claim that dir for replay. + 3. Otherwise return None so the suite gets a normal fresh run. """ if suite_name in suite_job_map and not _suite_completed(suite_name): return suite_job_map[suite_name] From 8a1c03e2ed4106d4b879cf6801dffec8898b9628 Mon Sep 17 00:00:00 2001 From: Praveen K Pandey Date: Tue, 4 Aug 2026 13:41:37 +0530 Subject: [PATCH 4/4] =?UTF-8?q?avocado-setup:=20fix=20=5Fsuite=5Freplay=5F?= =?UTF-8?q?dir()=20interrupted=20job=20condition=20(in=20=E2=86=92=20not?= =?UTF-8?q?=20in)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous condition: if '__interrupted__' in suite_job_map and suite_name in suite_job_map: ...required suite_name to already be present in suite_job_map, which is the exact opposite of the intended logic. The __interrupted__ dir should be claimed by the suite that has NO own entry in suite_job_map — i.e. the suite that was actively running when the process was killed and never wrote results.json. Fix: change 'suite_name in suite_job_map' to 'suite_name not in suite_job_map'. Symptom fixed: avocado-setup.py --run-suite host_rasci --resume restarted hwinfo from test 01/12 instead of resuming from 07/12. Signed-off-by: Praveen K Pandey --- avocado-setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avocado-setup.py b/avocado-setup.py index ceb9558..4c08b31 100644 --- a/avocado-setup.py +++ b/avocado-setup.py @@ -980,7 +980,7 @@ def _suite_replay_dir(suite_name): """ if suite_name in suite_job_map and not _suite_completed(suite_name): return suite_job_map[suite_name] - if "__interrupted__" in suite_job_map and suite_name in suite_job_map: + if "__interrupted__" in suite_job_map and suite_name not in suite_job_map: return suite_job_map.pop("__interrupted__") return None