Skip to content

Commit 35b6377

Browse files
committed
Ensure that old mode_settings objects are cleared when a
simulated job finishes. Test that reloading with a new simulation config leads to a different outcome.
1 parent 6cd8f1f commit 35b6377

File tree

2 files changed

+103
-6
lines changed

2 files changed

+103
-6
lines changed

cylc/flow/simulation.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ def __init__(
9090

9191
self.timeout = started_time + self.simulated_run_length
9292

93+
9394
def configure_sim_modes(taskdefs, sim_mode):
9495
"""Adjust task defs for simulation and dummy mode.
9596
@@ -219,6 +220,7 @@ def sim_time_check(
219220
"""
220221
now = time()
221222
sim_task_state_changed: bool = False
223+
222224
for itask in itasks:
223225
if (
224226
itask.state.status != TASK_STATUS_RUNNING
@@ -228,8 +230,6 @@ def sim_time_check(
228230
):
229231
continue
230232

231-
232-
233233
if itask.mode_settings is None:
234234
itask.mode_settings = ModeSettings(itask, broadcast_mgr, db_mgr)
235235

@@ -251,6 +251,10 @@ def sim_time_check(
251251
message_queue.put(
252252
TaskMsg(job_d, now_str, 'DEBUG', msg)
253253
)
254+
255+
# We've finished this psuedojob, so delete all the mode settings,
256+
# we'll recalculate them for the next "submission"
257+
itask.mode_settings = None
254258
sim_task_state_changed = True
255259
return sim_task_state_changed
256260

tests/integration/test_simulation.py

+97-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#
1414
# You should have received a copy of the GNU General Public License
1515
# along with this program. If not, see <http://www.gnu.org/licenses/>.
16-
16+
from pathlib import Path
1717
import pytest
1818
from pytest import param
1919
from queue import Queue
@@ -239,7 +239,7 @@ def test_task_sped_up(sim_time_check_setup, monkeytime):
239239

240240

241241
async def test_simulation_mode_settings_restart(
242-
monkeytime, flow, scheduler, run, start
242+
monkeytime, flow, scheduler, start
243243
):
244244
"""Check that simulation mode settings are correctly restored
245245
upon restart.
@@ -258,8 +258,11 @@ async def test_simulation_mode_settings_restart(
258258
'runtime': {
259259
'one': {
260260
'execution time limit': 'PT1M',
261+
'execution retry delays': 'P0Y',
261262
'simulation': {
262-
'speedup factor': 1
263+
'speedup factor': 1,
264+
'fail cycle points': 'all',
265+
'fail try 1 only': True,
263266
}
264267
},
265268
}
@@ -292,8 +295,9 @@ async def test_simulation_mode_settings_restart(
292295
monkeytime(12)
293296
itask.state.status = 'running'
294297

295-
# Check that we haven't got started time back
298+
# Check that we haven't got started time & mode settings back:
296299
assert itask.summary['started_time'] is None
300+
assert itask.mode_settings is None
297301

298302
# Set the start time in the database to 0 to make the
299303
# test simpler:
@@ -308,9 +312,98 @@ async def test_simulation_mode_settings_restart(
308312
schd.workflow_db_mgr
309313
) is False
310314

315+
# Check that the itask.mode_settings is now re-created
316+
assert itask.mode_settings.__dict__ == {
317+
'simulated_run_length': 60.0,
318+
'sim_task_fails': False,
319+
'timeout': 60.0
320+
}
321+
311322
# Set the current time > timeout
312323
monkeytime(61)
313324
assert sim_time_check(
314325
msg_q, [itask], schd.task_events_mgr.broadcast_mgr,
315326
schd.workflow_db_mgr
316327
) is True
328+
329+
assert itask.mode_settings is None
330+
331+
schd.task_events_mgr.broadcast_mgr.put_broadcast(
332+
['1066'], ['one'], [{
333+
'execution time limit': 'PT1S'}])
334+
335+
assert itask.mode_settings is None
336+
337+
schd.task_job_mgr._simulation_submit_task_jobs(
338+
[itask], schd.workflow)
339+
340+
assert itask.submit_num == 2
341+
assert itask.mode_settings.__dict__ == {
342+
'simulated_run_length': 1.0,
343+
'sim_task_fails': False,
344+
'timeout': 62.0
345+
}
346+
347+
348+
async def test_simulation_mode_settings_reload(
349+
monkeytime, flow, scheduler, run, start
350+
):
351+
"""Check that simulation mode settings are changed for future
352+
pseudo jobs on reload.
353+
354+
We run a task twice
355+
"""
356+
id_ = flow({
357+
'scheduler': {'cycle point format': '%Y'},
358+
'scheduling': {
359+
'initial cycle point': '1066',
360+
'graph': {
361+
'R1': 'one'
362+
}
363+
},
364+
'runtime': {
365+
'one': {
366+
'execution time limit': 'PT1M',
367+
'execution retry delays': 'P0Y',
368+
'simulation': {
369+
'fail cycle points': 'all',
370+
'fail try 1 only': False,
371+
}
372+
},
373+
}
374+
})
375+
schd = scheduler(id_)
376+
async with start(schd) as log:
377+
itask = schd.pool.get_tasks()[0]
378+
itask.state.status = 'running'
379+
itask.state.is_queued = False
380+
itask.summary['started_time'] = 0
381+
382+
# Submit & fail:
383+
schd.task_job_mgr._simulation_submit_task_jobs(
384+
[itask], schd.workflow)
385+
monkeytime(61)
386+
itask.mode_settings.timeout = 60
387+
assert sim_time_check(
388+
schd.message_queue, [itask], schd.task_events_mgr.broadcast_mgr,
389+
schd.workflow_db_mgr
390+
) is True
391+
schd.process_queued_task_messages()
392+
393+
# Modify the config in place, reload workflow:
394+
conf_file = Path(schd.workflow_run_dir) / 'flow.cylc'
395+
conf_file.write_text(conf_file.read_text().replace('= all', '='))
396+
await schd.command_reload_workflow()
397+
398+
# The proxy representing 1066/one will be a different object:
399+
itask = schd.pool.get_tasks()[0]
400+
401+
# Mode settings have been cleared (it's a new task anyway):
402+
assert itask.mode_settings is None
403+
404+
# Submit again.
405+
schd.task_job_mgr._simulation_submit_task_jobs(
406+
[itask], schd.workflow)
407+
408+
# Mode settings have changed as per the new config:
409+
assert itask.mode_settings.sim_task_fails is False

0 commit comments

Comments
 (0)