From 9eccb5290f5f79abece986e8b9f5cbdda2f414f2 Mon Sep 17 00:00:00 2001 From: Gernot Maier Date: Wed, 6 May 2026 11:01:57 +0200 Subject: [PATCH 1/5] layout name (no more test_layout) --- .../simulate_prod_htcondor_generator_gamma_20_deg_north.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/integration_tests/config/simulate_prod_htcondor_generator_gamma_20_deg_north.yml b/tests/integration_tests/config/simulate_prod_htcondor_generator_gamma_20_deg_north.yml index 9e1bc46663..2e87d64ca1 100644 --- a/tests/integration_tests/config/simulate_prod_htcondor_generator_gamma_20_deg_north.yml +++ b/tests/integration_tests/config/simulate_prod_htcondor_generator_gamma_20_deg_north.yml @@ -3,7 +3,10 @@ applications: - application: simtools-simulate-prod-htcondor-generator configuration: apptainer_image: test.sif - array_layout_name: test_layout + array_layout_name: + by_version: + "<7.0.0": alpha + ">=7.0.0": CTAO-North-Alpha azimuth_angle: North core_scatter: 10 500 m corsika_he_interaction: epos From fea9ef1350102594c2e22c14aeb96fbe2ca7946b Mon Sep 17 00:00:00 2001 From: Gernot Maier Date: Wed, 6 May 2026 12:38:47 +0200 Subject: [PATCH 2/5] check that apptainer image exists before submitting jobs --- .../job_execution/htcondor_script_generator.py | 6 +++++- .../test_htcondor_script_generator.py | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/simtools/job_execution/htcondor_script_generator.py b/src/simtools/job_execution/htcondor_script_generator.py index 32dd430a72..433c54a4e9 100644 --- a/src/simtools/job_execution/htcondor_script_generator.py +++ b/src/simtools/job_execution/htcondor_script_generator.py @@ -17,6 +17,10 @@ def generate_submission_script(args_dict): args_dict: dict Arguments dictionary. """ + apptainer_image = Path(args_dict["apptainer_image"]) + if not apptainer_image.is_file(): + raise FileNotFoundError(f"Apptainer image file not found: {apptainer_image}") + work_dir = Path(args_dict["output_path"]) log_dir = work_dir / "logs" work_dir.mkdir(parents=True, exist_ok=True) @@ -28,7 +32,7 @@ def generate_submission_script(args_dict): submit_file_handle.write( _get_submit_file( f"{submit_file_name}.sh", - args_dict["apptainer_image"], + apptainer_image, args_dict["priority"], +args_dict["number_of_runs"], ) diff --git a/tests/unit_tests/job_execution/test_htcondor_script_generator.py b/tests/unit_tests/job_execution/test_htcondor_script_generator.py index f7dd154dd9..b57b787e08 100644 --- a/tests/unit_tests/job_execution/test_htcondor_script_generator.py +++ b/tests/unit_tests/job_execution/test_htcondor_script_generator.py @@ -38,12 +38,14 @@ def args_dict(): @mock.patch("simtools.job_execution.htcondor_script_generator.Path.mkdir") @mock.patch("simtools.job_execution.htcondor_script_generator.open", new_callable=mock.mock_open) @mock.patch("simtools.job_execution.htcondor_script_generator.Path.chmod") -def test_generate_submission_script(mock_chmod, mock_open, mock_mkdir, args_dict): +@mock.patch("simtools.job_execution.htcondor_script_generator.Path.is_file", return_value=True) +def test_generate_submission_script(mock_is_file, mock_chmod, mock_open, mock_mkdir, args_dict): generate_submission_script(args_dict) work_dir = Path(args_dict["output_path"]) submit_file_name = "simulate_prod.submit" + mock_is_file.assert_called_once() mock_mkdir.assert_any_call(parents=True, exist_ok=True) # Check if files are created and written @@ -54,6 +56,18 @@ def test_generate_submission_script(mock_chmod, mock_open, mock_mkdir, args_dict mock_chmod.assert_called_once_with(0o755) +@mock.patch("simtools.job_execution.htcondor_script_generator.Path.is_file", return_value=False) +@mock.patch("simtools.job_execution.htcondor_script_generator.open", new_callable=mock.mock_open) +def test_generate_submission_script_raises_for_missing_apptainer_image( + mock_open, mock_is_file, args_dict +): + with pytest.raises(FileNotFoundError, match="Apptainer image file not found"): + generate_submission_script(args_dict) + + mock_is_file.assert_called_once() + mock_open.assert_not_called() + + def test_get_submit_script(args_dict): # Use abbreviated argument names to avoid overly long lines e_range_low = args_dict["energy_range"][0].to(u.GeV).value From bead02646df13380f6c4ab2bd9e26799dfc0791f Mon Sep 17 00:00:00 2001 From: Gernot Maier Date: Wed, 6 May 2026 13:56:22 +0200 Subject: [PATCH 3/5] changelog --- docs/changes/2170.maintenance.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/changes/2170.maintenance.md diff --git a/docs/changes/2170.maintenance.md b/docs/changes/2170.maintenance.md new file mode 100644 index 0000000000..d9d03403be --- /dev/null +++ b/docs/changes/2170.maintenance.md @@ -0,0 +1 @@ +Ensure that Apptainer image exist for HTCondor submission scripts. From 297e3d1cde241639d73fa43507ba4ab42ec41211 Mon Sep 17 00:00:00 2001 From: Gernot Maier Date: Wed, 6 May 2026 14:17:38 +0200 Subject: [PATCH 4/5] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/simtools/job_execution/htcondor_script_generator.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/simtools/job_execution/htcondor_script_generator.py b/src/simtools/job_execution/htcondor_script_generator.py index 433c54a4e9..1b143e6c30 100644 --- a/src/simtools/job_execution/htcondor_script_generator.py +++ b/src/simtools/job_execution/htcondor_script_generator.py @@ -17,7 +17,13 @@ def generate_submission_script(args_dict): args_dict: dict Arguments dictionary. """ - apptainer_image = Path(args_dict["apptainer_image"]) + apptainer_image_arg = args_dict["apptainer_image"] + if apptainer_image_arg is None or ( + isinstance(apptainer_image_arg, str) and not apptainer_image_arg.strip() + ): + raise ValueError("Missing required apptainer_image path.") + + apptainer_image = Path(apptainer_image_arg) if not apptainer_image.is_file(): raise FileNotFoundError(f"Apptainer image file not found: {apptainer_image}") From bba13c89c7a434c1051573174da81a70f898c336 Mon Sep 17 00:00:00 2001 From: Gernot Maier Date: Wed, 6 May 2026 14:25:18 +0200 Subject: [PATCH 5/5] fix tests --- src/simtools/job_execution/htcondor_script_generator.py | 2 +- .../simulate_prod_htcondor_generator_gamma_20_deg_north.yml | 2 +- tests/resources/dummy_apptainer_image.sif | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 tests/resources/dummy_apptainer_image.sif diff --git a/src/simtools/job_execution/htcondor_script_generator.py b/src/simtools/job_execution/htcondor_script_generator.py index 1b143e6c30..756cab0550 100644 --- a/src/simtools/job_execution/htcondor_script_generator.py +++ b/src/simtools/job_execution/htcondor_script_generator.py @@ -60,7 +60,7 @@ def _get_submit_file(executable, apptainer_image, priority, n_jobs): ---------- executable: str Name of the executable script. - apptainer_image: str + apptainer_image: Path Path to the Apptainer image. priority: int Priority of the job. diff --git a/tests/integration_tests/config/simulate_prod_htcondor_generator_gamma_20_deg_north.yml b/tests/integration_tests/config/simulate_prod_htcondor_generator_gamma_20_deg_north.yml index 2e87d64ca1..d09ae47867 100644 --- a/tests/integration_tests/config/simulate_prod_htcondor_generator_gamma_20_deg_north.yml +++ b/tests/integration_tests/config/simulate_prod_htcondor_generator_gamma_20_deg_north.yml @@ -2,7 +2,7 @@ applications: - application: simtools-simulate-prod-htcondor-generator configuration: - apptainer_image: test.sif + apptainer_image: tests/resources/dummy_apptainer_image.sif array_layout_name: by_version: "<7.0.0": alpha diff --git a/tests/resources/dummy_apptainer_image.sif b/tests/resources/dummy_apptainer_image.sif new file mode 100644 index 0000000000..008b0d41f1 --- /dev/null +++ b/tests/resources/dummy_apptainer_image.sif @@ -0,0 +1 @@ +This is a dummy apptainer image file used for tests.