diff --git a/src/virtualship/make_realistic/problems/simulator.py b/src/virtualship/make_realistic/problems/simulator.py index 6a5e5778..b02486c5 100644 --- a/src/virtualship/make_realistic/problems/simulator.py +++ b/src/virtualship/make_realistic/problems/simulator.py @@ -285,7 +285,6 @@ def execute( continue self._log_problem(problem, wp_i, problem_hash, hash_fpath, log_delay) - self._cache_original_expedition(self.expedition) def _log_problem( self, @@ -352,6 +351,9 @@ def _log_problem( _save_checkpoint(checkpoint, self.expedition_dir) self.expedition.to_yaml(self.expedition_dir / CACHE / EXPEDITION_LATEST) + # cache original expedition for user reference + self._cache_original_expedition(self.expedition) + self._tabular_outputter( problem_str=problem.message, impact_str=impact_str, @@ -360,6 +362,7 @@ def _log_problem( ) if not has_contingency: + # exit simulation sys.exit(0) def _has_contingency(self, problem: ProblemType, problem_wp_i: int | None) -> bool: diff --git a/tests/make_realistic/problems/test_simulator.py b/tests/make_realistic/problems/test_simulator.py index c3b790b0..6432185d 100644 --- a/tests/make_realistic/problems/test_simulator.py +++ b/tests/make_realistic/problems/test_simulator.py @@ -1,7 +1,10 @@ import json import random +import time from datetime import datetime, timedelta +import pytest + from virtualship.instruments.types import InstrumentType from virtualship.make_realistic.problems.scenarios import ( GENERAL_PROBLEMS, @@ -18,7 +21,7 @@ ShipConfig, Waypoint, ) -from virtualship.utils import REPORT +from virtualship.utils import CACHE, EXPEDITION_ORIGINAL, REPORT def _make_simple_expedition( @@ -372,3 +375,38 @@ def test_instrument_not_present_doesnt_select_instrument_problem(tmp_path): # any incompatible waypoint x instrument problem combinations should have been replaced by a general problem else: assert isinstance(problem, GeneralProblem) + + +@pytest.mark.parametrize("halts_simulation", [True, False]) +def test_original_expedition_always_cached(tmp_path, monkeypatch, halts_simulation): + """The original expedition should be cached whenever a problem occurs.""" + monkeypatch.setattr(time, "sleep", lambda _: None) + + if halts_simulation: + # no contingency for a pre-departure problem, so simulation should halt + expedition = _make_simple_expedition(num_waypoints=2) + problem, problem_wp_i = _get_pre_departure_problem(), 0 + else: + # short distance between waypoints, so enough contingency to avoid the problem + expedition = _make_simple_expedition(num_waypoints=2, distance_scale=0.01) + problem = next( + c for c in GENERAL_PROBLEMS if not getattr(c, "pre_departure", False) + ) + problem_wp_i = 1 + + (tmp_path / CACHE).mkdir() + simulator = ProblemSimulator(expedition, str(tmp_path)) + log_problem_args = ( + problem, + problem_wp_i, + "sample", + tmp_path / "problem_sample.json", + ) + + if halts_simulation: + with pytest.raises(SystemExit): + simulator._log_problem(*log_problem_args, log_delay=0.0) + else: + simulator._log_problem(*log_problem_args, log_delay=0.0) + + assert (tmp_path / CACHE / EXPEDITION_ORIGINAL).exists()