From f2192beb4e9d8239a6433f813a6b602cc0625adb Mon Sep 17 00:00:00 2001 From: John Sharples Date: Tue, 10 Oct 2023 05:02:05 +0000 Subject: [PATCH 1/2] feature 2253: series_analysis_wrapper tests --- .../series_analysis/test_series_analysis.py | 77 ++++++++++++++++++- metplus/wrappers/series_analysis_wrapper.py | 2 +- 2 files changed, 77 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..26ae7c06bb 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,77 @@ 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)), + (('Group1', [0, 200]), False, True, ('fcst_path', 'obs_path')), + (('Group1', [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 From 17d4ea09fc83a00bc570ba36cdb70510d939ab96 Mon Sep 17 00:00:00 2001 From: John Sharples Date: Tue, 10 Oct 2023 05:47:15 +0000 Subject: [PATCH 2/2] feature 2253: series_analysis_wrapper tests --- .../pytests/wrappers/series_analysis/test_series_analysis.py | 5 ++--- 1 file changed, 2 insertions(+), 3 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 26ae7c06bb..679f888f8f 100644 --- a/internal/tests/pytests/wrappers/series_analysis/test_series_analysis.py +++ b/internal/tests/pytests/wrappers/series_analysis/test_series_analysis.py @@ -1005,7 +1005,6 @@ def test_get_config_file(metplus_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 @@ -1042,8 +1041,8 @@ def test_get_fcst_obs_not_embedding(metplus_config): 'lead_group, use_both, mock_exists, expected', [ (('Group1', [0, 21600]), True, True, ('both_path', 'both_path')), (('F012', [relativedelta(hours=12)]), True, False, (None, None)), - (('Group1', [0, 200]), False, True, ('fcst_path', 'obs_path')), - (('Group1', [0, 200]), False, False, (None, None)), + (('Group2', [0, 200]), False, True, ('fcst_path', 'obs_path')), + ((None, [0, 200]), False, False, (None, None)), ] ) @pytest.mark.wrapper_a