From 33fdce274c3ed45b7fec722d855b3c2113b1031c Mon Sep 17 00:00:00 2001 From: Sean Bryan Date: Tue, 21 May 2024 10:18:16 +1000 Subject: [PATCH] Add tests for state operations --- src/benchcab/comparison.py | 24 ++++++++++++++++------ src/benchcab/fluxsite.py | 5 +++-- tests/test_comparison.py | 41 +++++++++++++++++++++++++++++--------- tests/test_fluxsite.py | 7 +++++++ 4 files changed, 60 insertions(+), 17 deletions(-) diff --git a/src/benchcab/comparison.py b/src/benchcab/comparison.py index 5bf959be..df3da2bd 100644 --- a/src/benchcab/comparison.py +++ b/src/benchcab/comparison.py @@ -41,17 +41,30 @@ def __init__( self.state = State( state_dir=internal.STATE_DIR / "fluxsite" / "comparisons" / self.task_name ) + self.output_file = ( + internal.FLUXSITE_DIRS["BITWISE_CMP"] / f"{self.task_name}.txt" + ) def is_done(self) -> bool: """Return status of current task.""" return self.state.is_set("done") def run(self) -> None: + """Runs a single comparison task.""" + self.clean() + self.execute_comparison() + + def clean(self): + """Cleans output files if they exist and resets the task state.""" + if self.output_file.exists(): + self.output_file.unlink() + self.state.reset() + + def execute_comparison(self) -> None: """Executes `nccmp -df` on the NetCDF files pointed to by `self.files`.""" file_a, file_b = self.files self.logger.debug(f"Comparing files {file_a.name} and {file_b.name} bitwise...") - self.state.reset() try: self.subprocess_handler.run_cmd( f"nccmp -df {file_a} {file_b}", @@ -62,14 +75,13 @@ def run(self) -> None: ) self.state.set("done") except CalledProcessError as exc: - output_file = ( - internal.FLUXSITE_DIRS["BITWISE_CMP"] / f"{self.task_name}.txt" - ) - with output_file.open("w", encoding="utf-8") as file: + with self.output_file.open("w", encoding="utf-8") as file: file.write(exc.stdout) self.logger.error(f"Failure: files {file_a.name} {file_b.name} differ. ") - self.logger.error(f"Results of diff have been written to {output_file}") + self.logger.error( + f"Results of diff have been written to {self.output_file}" + ) sys.stdout.flush() diff --git a/src/benchcab/fluxsite.py b/src/benchcab/fluxsite.py index 907cc202..90e948bb 100644 --- a/src/benchcab/fluxsite.py +++ b/src/benchcab/fluxsite.py @@ -158,7 +158,7 @@ def setup_task(self): patch_remove_namelist(nml_path, self.model.patch_remove) def clean_task(self): - """Cleans output files, namelist files, log files and cable executables if they exist.""" + """Cleans output files, namelist files, log files and cable executables if they exist and resets the task state.""" self.logger.debug(" Cleaning task") task_dir = internal.FLUXSITE_DIRS["TASKS"] / self.get_task_name() @@ -187,6 +187,8 @@ def clean_task(self): if log_file.exists(): log_file.unlink() + self.state.reset() + return self def fetch_files(self): @@ -220,7 +222,6 @@ def run(self): self.logger.debug(f"Running task {task_name}... CABLE standard output ") self.logger.debug(f"saved in {task_dir / internal.CABLE_STDOUT_FILENAME}") - self.state.reset() try: self.run_cable() self.add_provenance_info() diff --git a/tests/test_comparison.py b/tests/test_comparison.py index ef0bdcfc..cec51255 100644 --- a/tests/test_comparison.py +++ b/tests/test_comparison.py @@ -8,7 +8,6 @@ from pathlib import Path import pytest - from benchcab import internal from benchcab.comparison import ComparisonTask @@ -30,21 +29,45 @@ def comparison_task(files, mock_subprocess_handler): return _comparison_task -class TestRun: - """Tests for `ComparisonTask.run()`.""" +@pytest.fixture(autouse=True) +def bitwise_cmp_dir(): + """Create and return the fluxsite bitwise comparison directory.""" + internal.FLUXSITE_DIRS["BITWISE_CMP"].mkdir(parents=True) + return internal.FLUXSITE_DIRS["BITWISE_CMP"] + + +class TestClean: + """Tests for `ComparisonTask.clean()`.""" + + def test_error_logs_are_removed(self, comparison_task): + """Success case: test error logs are removed.""" + output_file = comparison_task.output_file + output_file.touch() + comparison_task.clean() + assert not output_file.exists() - @pytest.fixture(autouse=True) - def bitwise_cmp_dir(self): - """Create and return the fluxsite bitwise comparison directory.""" - internal.FLUXSITE_DIRS["BITWISE_CMP"].mkdir(parents=True) - return internal.FLUXSITE_DIRS["BITWISE_CMP"] + def test_task_state_is_reset(self, comparison_task): + """Success case: test task state is reset.""" + state = comparison_task.state + state.set("dirty") + comparison_task.clean() + assert not state.is_set("dirty") + + +class TestExecuteComparison: + """Tests for `ComparisonTask.execute_comparison()`.""" def test_nccmp_execution(self, comparison_task, files, mock_subprocess_handler): """Success case: test nccmp is executed.""" file_a, file_b = files - comparison_task.run() + comparison_task.execute_comparison() assert f"nccmp -df {file_a} {file_b}" in mock_subprocess_handler.commands + def test_task_is_done_on_success(self, comparison_task): + """Success case: test task is done on success.""" + comparison_task.execute_comparison() + assert comparison_task.is_done() + def test_failed_comparison_check( self, comparison_task, mock_subprocess_handler, bitwise_cmp_dir ): diff --git a/tests/test_fluxsite.py b/tests/test_fluxsite.py index 41546322..e4732ba0 100644 --- a/tests/test_fluxsite.py +++ b/tests/test_fluxsite.py @@ -152,6 +152,13 @@ def test_clean_files(self, task): ).exists() assert not (internal.FLUXSITE_DIRS["LOG"] / task.get_log_filename()).exists() + def test_state_is_reset(self, task): + """Success case: test state is reset on clean.""" + state = task.state + state.set("foo") + task.clean_task() + assert not state.is_set("foo") + class TestSetupTask: """Tests for `FluxsiteTask.setup_task()`."""