From 7619276d6a73982af33481ba85ae39effc8d6d11 Mon Sep 17 00:00:00 2001 From: John Sharples <41682323+John-Sharples@users.noreply.github.com> Date: Thu, 19 Oct 2023 02:44:38 +1100 Subject: [PATCH] Feature 2253 series analysis test (#2380) --- .../series_analysis/test_series_analysis.py | 76 ++++++++++++++++++- metplus/wrappers/series_analysis_wrapper.py | 2 +- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/internal/tests/pytests/wrappers/series_analysis/test_series_analysis.py b/internal/tests/pytests/wrappers/series_analysis/test_series_analysis.py index 4e7f002b1b..679f888f8f 100644 --- a/internal/tests/pytests/wrappers/series_analysis/test_series_analysis.py +++ b/internal/tests/pytests/wrappers/series_analysis/test_series_analysis.py @@ -1,10 +1,11 @@ import pytest - +from unittest import mock import os from datetime import datetime from dateutil.relativedelta import relativedelta from metplus.wrappers.series_analysis_wrapper import SeriesAnalysisWrapper +from metplus.wrappers import series_analysis_wrapper as saw fcst_dir = '/some/fcst/dir' obs_dir = '/some/obs/dir' @@ -1002,3 +1003,76 @@ def test_get_config_file(metplus_config): config.set('config', 'SERIES_ANALYSIS_CONFIG_FILE', fake_config_name) wrapper = SeriesAnalysisWrapper(config) assert wrapper.c_dict['CONFIG_FILE'] == fake_config_name + + +@pytest.mark.wrapper_a +def test_run_once_per_lead(metplus_config): + config = metplus_config + set_minimum_config_settings(config) + wrapper = SeriesAnalysisWrapper(config) + + # basic test + actual = wrapper.run_once_per_lead(None) + assert wrapper.isOK + assert actual is True + + # lead_hours = None + with mock.patch.object(saw, 'ti_get_hours_from_lead', return_value=None): + actual = wrapper.run_once_per_lead(None) + assert actual is True + + # run_at_time_once returns a failure + with mock.patch.object(wrapper, 'run_at_time_once', return_value=None): + actual = wrapper.run_once_per_lead(None) + assert actual is False + + +@pytest.mark.wrapper_a +def test_get_fcst_obs_not_embedding(metplus_config): + config = metplus_config + set_minimum_config_settings(config) + wrapper = SeriesAnalysisWrapper(config) + with mock.patch.object(wrapper, "_check_python_embedding", return_value=False): + actual = wrapper._get_fcst_and_obs_path({}, '*', None) + assert actual == (None, None) + + +@pytest.mark.parametrize( + 'lead_group, use_both, mock_exists, expected', [ + (('Group1', [0, 21600]), True, True, ('both_path', 'both_path')), + (('F012', [relativedelta(hours=12)]), True, False, (None, None)), + (('Group2', [0, 200]), False, True, ('fcst_path', 'obs_path')), + ((None, [0, 200]), False, False, (None, None)), + ] +) +@pytest.mark.wrapper_a +def test_get_fcst_and_obs_path(metplus_config, + lead_group, + use_both, + mock_exists, + expected): + config = metplus_config + set_minimum_config_settings(config) + wrapper = SeriesAnalysisWrapper(config) + wrapper.c_dict['EXPLICIT_FILE_LIST'] = True + wrapper.c_dict['FCST_INPUT_FILE_LIST'] = 'fcst_path' + wrapper.c_dict['OBS_INPUT_FILE_LIST'] = 'obs_path' + wrapper.c_dict['BOTH_INPUT_FILE_LIST'] = 'both_path' + wrapper.c_dict['USING_BOTH'] = use_both + + time_info = {'loop_by': 'init', + 'init': datetime(2005, 8, 7, 0, 0), + 'instance': '', + 'valid': '*', + 'lead': '*', + 'lead_string':'ALL', + 'date': datetime(2005, 8, 7, 0, 0), + 'storm_id': '*'} + + if mock_exists: + with mock.patch.object(os.path, "exists", return_value=True): + actual = wrapper._get_fcst_and_obs_path(time_info, '*', lead_group) + else: + actual = wrapper._get_fcst_and_obs_path(time_info, '*', lead_group) + assert actual == expected + diff --git a/metplus/wrappers/series_analysis_wrapper.py b/metplus/wrappers/series_analysis_wrapper.py index c33b4d6440..a16989416e 100755 --- a/metplus/wrappers/series_analysis_wrapper.py +++ b/metplus/wrappers/series_analysis_wrapper.py @@ -645,7 +645,7 @@ def _get_fcst_and_obs_path(self, time_info, storm_id, lead_group): @param time_info dictionary containing time information @param storm_id storm ID to process - @param lead_group dictionary where key is label and value is a + @param lead_group tuple where first value is label and second is a list of forecast leads to process. If no label was defined, the key will match the format "NoLabel_" and if no lead groups are defined, the dictionary should be replaced with None