Skip to content

Commit

Permalink
Refactor and add unit tests
Browse files Browse the repository at this point in the history
Move code that confirms obs file existence or creates symlink to fcst file to
a function so that it can be tested, and the rest of the module test suite can
run without access to the `ssh dir` path.
  • Loading branch information
douglatornell committed Oct 19, 2022
1 parent 612a28d commit 9318982
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 15 deletions.
34 changes: 19 additions & 15 deletions nowcast/workers/make_ssh_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,21 +180,7 @@ def make_ssh_file(parsed_args, config, *args):
else:
checklist[run_type].update({"obs": filepath})

# Confirm that obs files were created. If not, create them by symlinking to fcst file for date
earliest_obs_date = (
run_date.shift(days=-4) if run_type == "nowcast" else run_date.shift(days=-5)
)
obs_dates = arrow.Arrow.range("days", earliest_obs_date, run_date.shift(days=-1))
for obs_date in obs_dates:
obs_file = config["ssh"]["file template"].format(obs_date.datetime)
obs_path = ssh_dir / "obs" / obs_file
if not obs_path.exists():
fcst_relative_path = Path("..", "fcst", obs_file)
obs_path.symlink_to(fcst_relative_path)
logger.critical(
f"{obs_path} was not created; using {fcst_relative_path} instead via symlink"
)
checklist[run_type].update({"obs": os.fspath(fcst_relative_path)})
_ensure_all_files_created(run_date, run_type, ssh_dir, checklist, config)

if parsed_args.text_file is None:
_render_plot(fig, ax, config)
Expand Down Expand Up @@ -371,6 +357,24 @@ def _save_netcdf(day, tc, surges, forecast_flag, textfile, config, lats, lons):
return filepath


def _ensure_all_files_created(run_date, run_type, ssh_dir, checklist, config):
"""Confirm that obs files were created. If not, create them by symlinking to fcst file for date."""
earliest_obs_date = (
run_date.shift(days=-4) if run_type == "nowcast" else run_date.shift(days=-5)
)
obs_dates = arrow.Arrow.range("days", earliest_obs_date, run_date.shift(days=-1))
for obs_date in obs_dates:
obs_file = config["ssh"]["file template"].format(obs_date.datetime)
obs_path = ssh_dir / "obs" / obs_file
if not obs_path.exists():
fcst_relative_path = Path("..", "fcst", obs_file)
obs_path.symlink_to(fcst_relative_path)
logger.critical(
f"{obs_path} was not created; using {fcst_relative_path} instead via symlink"
)
checklist[run_type].update({"obs": os.fspath(fcst_relative_path)})


def _setup_plot():
fig = matplotlib.figure.Figure(figsize=(10, 4))
ax = fig.add_subplot(1, 1, 1)
Expand Down
54 changes: 54 additions & 0 deletions tests/workers/test_make_ssh_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,15 @@ def mock_get_lons_lats(config):

monkeypatch.setattr(make_ssh_files, "_get_lons_lats", mock_get_lons_lats)

def mock_ensure_all_files_created(
run_date, run_type, ssh_dir, checklist, config
):
pass

monkeypatch.setattr(
make_ssh_files, "_ensure_all_files_created", mock_ensure_all_files_created
)

def mock_render_plot(fig, ax, config):
pass

Expand All @@ -252,3 +261,48 @@ def mock_render_plot(fig, ax, config):
csv_file = Path(f"etss.{yyyymmdd}.t{forecast}z.csv")
expected = {run_type: {"csv": os.fspath(ssh_dir / "txt" / csv_file)}}
assert checklist == expected


@pytest.mark.parametrize(
"run_type, run_date",
(
("nowcast", arrow.get("2022-10-18")),
("forecast2", arrow.get("2022-10-18")),
),
)
class TestMakeSshFile:
"""Unit tests for _ensure_all_files_created() function."""

def test_ensure_all_files_created(
self, run_type, run_date, config, caplog, tmp_path
):
ssh_dir = tmp_path / "sshNeahBay"
ssh_dir.mkdir()
(ssh_dir / "obs").mkdir()
(ssh_dir / "fcst").mkdir()
obs_filename_tmpl = "ssh_{:y%Ym%md%d}.nc"
earliest_obs_date = (
run_date.shift(days=-4)
if run_type == "nowcast"
else run_date.shift(days=-5)
)
obs_dates = arrow.Arrow.range(
"days", earliest_obs_date, run_date.shift(days=-2)
)
for obs_date in obs_dates:
(ssh_dir / "obs" / obs_filename_tmpl.format(obs_date.datetime)).touch()
checklist = {run_type: {}}
caplog.set_level(logging.DEBUG)

make_ssh_files._ensure_all_files_created(
run_date, run_type, ssh_dir, checklist, config
)

expected_filename = obs_filename_tmpl.format(run_date.shift(days=-1).datetime)
expected_path = ssh_dir / "obs" / expected_filename
assert expected_path.is_symlink()
assert expected_path.resolve() == ssh_dir / "fcst" / expected_filename
assert caplog.records[0].levelname == "CRITICAL"
expected = f"{expected_path} was not created; using ../fcst/{expected_filename} instead via symlink"
assert caplog.messages[0] == expected
assert checklist[run_type]["obs"] == f"../fcst/{expected_filename}"

0 comments on commit 9318982

Please sign in to comment.