|
26 | 26 | from autosubmit.job.job_packages import JobPackageSimple, JobPackageVertical |
27 | 27 | from autosubmit.job.job_packages import jobs_in_wrapper_str |
28 | 28 | from autosubmit.config.yamlparser import YAMLParserFactory |
| 29 | +from autosubmit.log.log import AutosubmitError, AutosubmitCritical |
29 | 30 |
|
30 | 31 |
|
31 | 32 | @pytest.fixture |
@@ -199,43 +200,77 @@ def test_jobs_in_wrapper_str(autosubmit_config): |
199 | 200 | assert result == "job1_job2_job3" |
200 | 201 |
|
201 | 202 |
|
202 | | -def test_job_package_submission(mocker, local, tmp_path): |
203 | | - # N.B.: AS only calls ``_create_scripts`` if you have less jobs than threads. |
204 | | - # So we simply set threads to be greater than the amount of jobs. |
| 203 | +@pytest.mark.parametrize( |
| 204 | + "error, target_function", |
| 205 | + [ |
| 206 | + (None, None), |
| 207 | + (AutosubmitError, "_create_scripts"), |
| 208 | + (AutosubmitCritical, "_create_scripts"), |
| 209 | + (AutosubmitError, "_send_files"), |
| 210 | + (AutosubmitCritical, "_send_files"), |
| 211 | + (AutosubmitError, "_do_submission"), |
| 212 | + (AutosubmitCritical, "_do_submission"), |
| 213 | + ], |
| 214 | + ids=[ |
| 215 | + "no_error", |
| 216 | + "autosubmit_error_on_create_scripts", |
| 217 | + "autosubmit_critical_on_create_scripts", |
| 218 | + "autosubmit_error_on_send_files", |
| 219 | + "autosubmit_critical_on_send_files", |
| 220 | + "autosubmit_error_on_do_submission", |
| 221 | + "autosubmit_critical_on_do_submission", |
| 222 | + ], |
| 223 | +) |
| 224 | +def test_job_package_submission(mocker, local, tmp_path, error, target_function) -> None: |
| 225 | + """Verify submit succeeds normally and propagates AutosubmitError or AutosubmitCritical.""" |
205 | 226 | jobs = [ |
206 | 227 | Job("job1", "1", Status.READY, 0), |
207 | 228 | Job("job2", "2", Status.READY, 0), |
208 | | - Job("job3", "3", Status.READY, 0) |
| 229 | + Job("job3", "3", Status.READY, 0), |
209 | 230 | ] |
210 | 231 | for job in jobs: |
211 | 232 | job.platform = local |
212 | | - |
213 | | - mocker.patch('multiprocessing.cpu_count', return_value=len(jobs) + 1) |
214 | | - mocker.patch("autosubmit.job.job.Job.update_parameters", return_value={}) |
215 | | - mocker.patch('autosubmit.job.job.Job._get_paramiko_template', return_value="empty") |
216 | | - |
217 | | - for job in jobs: |
218 | 233 | job._tmp_path = tmp_path |
219 | 234 | job.file = tmp_path / "fake-file" |
220 | 235 | job.custom_directives = [] |
221 | 236 | job.file.write_text("echo 'Hello World'") |
222 | 237 |
|
| 238 | + mocker.patch("multiprocessing.cpu_count", return_value=len(jobs) + 1) |
| 239 | + mocker.patch("autosubmit.job.job.Job.update_parameters", return_value={}) |
| 240 | + mocker.patch("autosubmit.job.job.Job._get_paramiko_template", return_value="empty") |
223 | 241 |
|
224 | 242 | job_package = JobPackageSimple(jobs) |
| 243 | + mock_create_scripts = mocker.patch.object(job_package, "_create_scripts") |
| 244 | + mock_send_files = mocker.patch.object(job_package, "_send_files") |
| 245 | + mock_do_submission = mocker.patch.object(job_package, "_do_submission") |
| 246 | + |
| 247 | + method_mocks = { |
| 248 | + "_create_scripts": mock_create_scripts, |
| 249 | + "_send_files": mock_send_files, |
| 250 | + "_do_submission": mock_do_submission, |
| 251 | + } |
225 | 252 |
|
226 | | - job_package._create_scripts = MagicMock() |
227 | | - job_package._send_files = MagicMock() |
228 | | - job_package._do_submission = MagicMock() |
229 | | - configuration = MagicMock() |
230 | | - configuration.get_project_dir = MagicMock() |
| 253 | + configuration = mocker.MagicMock() |
231 | 254 | configuration.get_project_dir.return_value = "fake-proj-dir" |
232 | | - # act |
233 | | - job_package.submit(configuration, 'fake-params') |
234 | | - # assert |
235 | | - for job in jobs: |
236 | | - # Should be called once for each job, but currently it needs two calls (for additional files) to change the code |
237 | | - job.update_parameters.assert_called() |
238 | 255 |
|
239 | | - job_package._create_scripts.is_called_once_with() |
240 | | - job_package._send_files.is_called_once_with() |
241 | | - job_package._do_submission.is_called_once_with() |
| 256 | + if error: |
| 257 | + method_mocks[target_function].side_effect = error |
| 258 | + |
| 259 | + with pytest.raises(error): |
| 260 | + job_package.submit(configuration, "fake-params") |
| 261 | + |
| 262 | + methods_after_failure = { |
| 263 | + "_create_scripts": [], |
| 264 | + "_send_files": ["_create_scripts"], |
| 265 | + "_do_submission": ["_create_scripts", "_send_files"], |
| 266 | + } |
| 267 | + for skipped in methods_after_failure[target_function]: |
| 268 | + method_mocks[skipped].assert_called_once() |
| 269 | + for skipped in set(method_mocks) - set(methods_after_failure[target_function]) - {target_function}: |
| 270 | + method_mocks[skipped].assert_not_called() |
| 271 | + else: |
| 272 | + job_package.submit(configuration, "fake-params") |
| 273 | + |
| 274 | + mock_create_scripts.assert_called_once() |
| 275 | + mock_send_files.assert_called_once() |
| 276 | + mock_do_submission.assert_called_once() |
0 commit comments