From 665aba410a0b1d027436a190601e38df084a002b Mon Sep 17 00:00:00 2001 From: Ryan Forsyth Date: Mon, 25 Nov 2024 19:36:57 -0600 Subject: [PATCH] Test fixes --- README.md | 5 +- docs/source/dev_guide/new_glb_plot.rst | 2 +- docs/source/dev_guide/release_testing.rst | 4 +- docs/source/dev_guide/testing.rst | 4 +- .../tutorial_testing_e3sm_unified.rst | 4 +- .../generated/directions_chrysalis.md | 2 +- ..._comprehensive_v3_setup_only_chrysalis.cfg | 64 ++++++ ...ash_generation_expected_files_chrysalis.sh | 2 +- ...pdate_campaign_expected_files_chrysalis.sh | 2 +- ...pdate_defaults_expected_files_chrysalis.sh | 2 +- .../update_weekly_expected_files_chrysalis.sh | 2 +- tests/integration/template_directions.md | 2 +- ...ime_series_comprehensive_v3_setup_only.cfg | 64 ++++++ ...e_update_bash_generation_expected_files.sh | 2 +- ...template_update_campaign_expected_files.sh | 2 +- ...template_update_defaults_expected_files.sh | 2 +- .../template_update_weekly_expected_files.sh | 2 +- tests/integration/test_bash_generation.py | 29 +-- tests/integration/test_campaign.py | 193 ++++++++---------- tests/integration/test_defaults.py | 39 ++-- tests/integration/test_last_year.py | 57 +++--- tests/integration/test_weekly.py | 164 ++++++++------- tests/integration/utils.py | 14 +- zppy/global_time_series.py | 3 + 24 files changed, 371 insertions(+), 295 deletions(-) create mode 100644 tests/integration/generated/test_min_case_global_time_series_comprehensive_v3_setup_only_chrysalis.cfg create mode 100644 tests/integration/template_min_case_global_time_series_comprehensive_v3_setup_only.cfg diff --git a/README.md b/README.md index 35935801..f158e5b2 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,8 @@ simulations by automating commonly performed tasks. See [documentation](https://e3sm-project.github.io/zppy) for more details. -- Run `python -m unittest discover -s tests -p "test_*.py"` to run all tests. -- Run `python -m unittest tests/test_*.py` to run only unit tests. -- Run `python -m unittest tests/integration/test_*.py` to run only integration tests (on server). +- Run `pytest tests/test_*.py` to run only unit tests. +- Run `pytest tests/integration/test_*.py` to run only integration tests (on server). ## License diff --git a/docs/source/dev_guide/new_glb_plot.rst b/docs/source/dev_guide/new_glb_plot.rst index 18aee675..4ab8fd45 100644 --- a/docs/source/dev_guide/new_glb_plot.rst +++ b/docs/source/dev_guide/new_glb_plot.rst @@ -10,4 +10,4 @@ Note that unlike E3SM Diags and MPAS-Analysis which are packages called by ``zpp - In `coupled_global.py `_: Add variables under "# Variables to extract". Add the code for your new plot under "Plotting functions"; the name of your function should start with ``plot_``. In ``PLOT_DICT``, add ``"function name without plot_" : function name``. - If this plot should be added to the defaults, then complete this step: for ``plot_names`` under ``[global_time_series]`` in `default.ini `_, add the function name without plot to the string. - Optionally, after making your edits, you can run ``pre-commit run --all-files`` to clean up your code and check for any obvious errors. -- Run the `integration tests `_ and examine the differences from the expected files. If they match what you expect, update the expected files following "Commands to run to replace outdated expected files" on the machine-specific directions. (The commands to run all the integration tests are ``pip install .`` followed by ``python -u -m unittest tests/integration/test_*.py``). +- Run the `integration tests `_ and examine the differences from the expected files. If they match what you expect, update the expected files following "Commands to run to replace outdated expected files" on the machine-specific directions. (The commands to run all the integration tests are ``pip install .`` followed by ``pytest tests/integration/test_*.py``). diff --git a/docs/source/dev_guide/release_testing.rst b/docs/source/dev_guide/release_testing.rst index 787bf605..7f0f5a84 100644 --- a/docs/source/dev_guide/release_testing.rst +++ b/docs/source/dev_guide/release_testing.rst @@ -83,7 +83,7 @@ Testing directions for making a release * Compy: ``source /share/apps/E3SM/conda_envs/load_latest_e3sm_unified_compy.sh`` * Perlmutter: ``source /global/common/software/e3sm/anaconda_envs/load_latest_e3sm_unified_pm-cpu.sh`` -7. Run the unit tests with ``python -u -m unittest tests/test_*.py``. +7. Run the unit tests with ``pytest tests/test_*.py``. a. test dev (run before making a new zppy RC): @@ -107,7 +107,7 @@ Testing directions for making a release * `Compy `_ * `Perlmutter `_ -9. Run the integration tests with ``python -u -m unittest tests/integration/test_*.py``. Note that ``test_complete_run.py`` takes approximately 75 minutes to run on Compy. +9. Run the integration tests with ``pytest tests/integration/test_*.py``. Note that ``test_complete_run.py`` takes approximately 75 minutes to run on Compy. a. test dev (run before making a new zppy RC): diff --git a/docs/source/dev_guide/testing.rst b/docs/source/dev_guide/testing.rst index e17116f3..fa9a6c46 100644 --- a/docs/source/dev_guide/testing.rst +++ b/docs/source/dev_guide/testing.rst @@ -10,7 +10,7 @@ Run all unit tests by doing the following: .. code:: pip install . # Install your changes (`python -m pip install .` also works) - python -u -m unittest tests/test_*.py # Run all unit tests + pytest tests/test_*.py # Run all unit tests Integration tests ================= @@ -24,7 +24,7 @@ Run all integration tests by doing the following: pip install . # Install your changes (`python -m pip install .` also works) - python -u -m unittest tests/integration/test_*.py # Run all integration tests + pytest tests/integration/test_*.py # Run all integration tests Automated tests =============== diff --git a/docs/source/dev_guide/tutorial_testing_e3sm_unified.rst b/docs/source/dev_guide/tutorial_testing_e3sm_unified.rst index 868534a8..ab59386d 100644 --- a/docs/source/dev_guide/tutorial_testing_e3sm_unified.rst +++ b/docs/source/dev_guide/tutorial_testing_e3sm_unified.rst @@ -368,5 +368,5 @@ Run the unit tests and integration tests on Chrysalis: git fetch upstream git rebase upstream/main # Load the appropriate environment - python -u -m unittest tests/test_*.py # Run unit tests - python -u -m unittest tests/integration/test_*.py # Run integration tests + pytest tests/test_*.py # Run unit tests + pytest tests/integration/test_*.py # Run integration tests diff --git a/tests/integration/generated/directions_chrysalis.md b/tests/integration/generated/directions_chrysalis.md index 4472d828..bc546f4d 100644 --- a/tests/integration/generated/directions_chrysalis.md +++ b/tests/integration/generated/directions_chrysalis.md @@ -38,7 +38,7 @@ Changing `UNIQUE_ID` allows you to simultaneously run jobs launched from `zppy` on different branches, without worrying about overwriting results. -NOTE: Actually running the tests (e.g., `python -u -m unittest tests/integration/test_*.py`) +NOTE: Actually running the tests (e.g., `pytest tests/integration/test_*.py`) can not be done from two different branches simultaneously (since files in the `zppy` directory rather than an external directory get changed). diff --git a/tests/integration/generated/test_min_case_global_time_series_comprehensive_v3_setup_only_chrysalis.cfg b/tests/integration/generated/test_min_case_global_time_series_comprehensive_v3_setup_only_chrysalis.cfg new file mode 100644 index 00000000..51d80069 --- /dev/null +++ b/tests/integration/generated/test_min_case_global_time_series_comprehensive_v3_setup_only_chrysalis.cfg @@ -0,0 +1,64 @@ +[default] +case = "v3.LR.historical_0051" +constraint = "" +dry_run = "False" +environment_commands = "" +fail_on_dependency_skip = True +guess_path_parameters = False +guess_section_parameters = False +input = /lcrc/group/e3sm2/ac.wlin/E3SMv3/v3.LR.historical_0051 +input_subdir = archive/atm/hist +mapping_file = "map_ne30pg2_to_cmip6_180x360_aave.20200201.nc" +output = "/lcrc/group/e3sm/ac.forsyth2/zppy_min_case_global_time_series_comprehensive_v3_setup_only_output/unique_id/v3.LR.historical_0051" +partition = "debug" +qos = "regular" +www = "/lcrc/group/e3sm/public_html/diagnostic_output/ac.forsyth2/zppy_min_case_global_time_series_comprehensive_v3_setup_only_www/unique_id" +years = "1985:1989:2", + +[ts] +active = True +e3sm_to_cmip_environment_commands = "" +walltime = "00:30:00" + + [[ atm_monthly_glb ]] + # Note global average won't work for 3D variables. + frequency = "monthly" + input_files = "eam.h0" + input_subdir = "archive/atm/hist" + mapping_file = "glb" + years = "1985:1995:5", + + [[ lnd_monthly_glb ]] + frequency = "monthly" + input_files = "elm.h0" + input_subdir = "archive/lnd/hist" + mapping_file = "glb" + vars = "FSH,RH2M,LAISHA,LAISUN,QINTR,QOVER,QRUNOFF,QSOIL,QVEGE,QVEGT,SOILWATER_10CM,TSA,H2OSNO,TOTLITC,CWDC,SOIL1C,SOIL2C,SOIL3C,SOIL4C,WOOD_HARVESTC,TOTVEGC,NBP,GPP,AR,HR" + years = "1985:1995:5", + +[mpas_analysis] +active = True +anomalyRefYear = 1985 +climo_years = "1985-1989", "1990-1995", +enso_years = "1985-1989", "1990-1995", +mesh = "IcoswISC30E3r5" +parallelTaskCount = 6 +partition = "compute" +qos = "regular" +shortTermArchive = True +ts_years = "1985-1989", "1985-1995", +walltime = "00:30:00" + +# (This cfg is the setup portion only) +# [global_time_series] +# active = True +# climo_years = "1985-1989", "1990-1995", +# environment_commands = "source /conda.sh; conda activate " +# experiment_name = "v3.LR.historical_0051" +# figstr = "v3.LR.historical_0051" +# moc_file=mocTimeSeries_1985-1995.nc +# plots_lnd = "FSH,RH2M,LAISHA,LAISUN,QINTR,QOVER,QRUNOFF,QSOIL,QVEGE,QVEGT,SOILWATER_10CM,TSA,H2OSNO,TOTLITC,CWDC,SOIL1C,SOIL2C,SOIL3C,SOIL4C,WOOD_HARVESTC,TOTVEGC,NBP,GPP,AR,HR" +# ts_num_years = 5 +# ts_years = "1985-1989", "1985-1995", +# walltime = "00:30:00" +# years = "1985-1995", diff --git a/tests/integration/generated/update_bash_generation_expected_files_chrysalis.sh b/tests/integration/generated/update_bash_generation_expected_files_chrysalis.sh index e0e0d73b..38d4ae48 100755 --- a/tests/integration/generated/update_bash_generation_expected_files_chrysalis.sh +++ b/tests/integration/generated/update_bash_generation_expected_files_chrysalis.sh @@ -7,4 +7,4 @@ rm -rf /lcrc/group/e3sm/public_html/zppy_test_resources/expected_bash_files # You can just move (i.e., not copy) the output since re-running this test will re-generate the output. mv test_bash_generation_output/post/scripts /lcrc/group/e3sm/public_html/zppy_test_resources/expected_bash_files # Rerun test -python -u -m unittest tests/integration/test_bash_generation.py +pytest tests/integration/test_bash_generation.py diff --git a/tests/integration/generated/update_campaign_expected_files_chrysalis.sh b/tests/integration/generated/update_campaign_expected_files_chrysalis.sh index e207eafc..cf1fbdb3 100755 --- a/tests/integration/generated/update_campaign_expected_files_chrysalis.sh +++ b/tests/integration/generated/update_campaign_expected_files_chrysalis.sh @@ -13,4 +13,4 @@ do done # Rerun test -python -m unittest tests/integration/test_campaign.py +pytest tests/integration/test_campaign.py diff --git a/tests/integration/generated/update_defaults_expected_files_chrysalis.sh b/tests/integration/generated/update_defaults_expected_files_chrysalis.sh index 0d67d663..366dda16 100755 --- a/tests/integration/generated/update_defaults_expected_files_chrysalis.sh +++ b/tests/integration/generated/update_defaults_expected_files_chrysalis.sh @@ -8,4 +8,4 @@ mkdir -p /lcrc/group/e3sm/public_html/zppy_test_resources/test_defaults_expected # You can just move (i.e., not copy) the output since re-running this test will re-generate the output. mv test_defaults_output/post/scripts/*.settings /lcrc/group/e3sm/public_html/zppy_test_resources/test_defaults_expected_files # Rerun test -python -u -m unittest tests/integration/test_defaults.py +pytest tests/integration/test_defaults.py diff --git a/tests/integration/generated/update_weekly_expected_files_chrysalis.sh b/tests/integration/generated/update_weekly_expected_files_chrysalis.sh index a2967214..7efea25b 100755 --- a/tests/integration/generated/update_weekly_expected_files_chrysalis.sh +++ b/tests/integration/generated/update_weekly_expected_files_chrysalis.sh @@ -27,4 +27,4 @@ do done # Rerun test -python -u -m unittest tests/integration/test_weekly.py +pytest tests/integration/test_weekly.py diff --git a/tests/integration/template_directions.md b/tests/integration/template_directions.md index a84edf93..193ec00b 100644 --- a/tests/integration/template_directions.md +++ b/tests/integration/template_directions.md @@ -38,7 +38,7 @@ Changing `UNIQUE_ID` allows you to simultaneously run jobs launched from `zppy` on different branches, without worrying about overwriting results. -NOTE: Actually running the tests (e.g., `python -u -m unittest tests/integration/test_*.py`) +NOTE: Actually running the tests (e.g., `pytest tests/integration/test_*.py`) can not be done from two different branches simultaneously (since files in the `zppy` directory rather than an external directory get changed). diff --git a/tests/integration/template_min_case_global_time_series_comprehensive_v3_setup_only.cfg b/tests/integration/template_min_case_global_time_series_comprehensive_v3_setup_only.cfg new file mode 100644 index 00000000..87ee6999 --- /dev/null +++ b/tests/integration/template_min_case_global_time_series_comprehensive_v3_setup_only.cfg @@ -0,0 +1,64 @@ +[default] +case = "#expand case_name#" +constraint = "#expand constraint#" +dry_run = "#expand dry_run#" +environment_commands = "#expand environment_commands#" +fail_on_dependency_skip = True +guess_path_parameters = False +guess_section_parameters = False +input = /lcrc/group/e3sm2/ac.wlin/E3SMv3/#expand case_name# +input_subdir = archive/atm/hist +mapping_file = "map_ne30pg2_to_cmip6_180x360_aave.20200201.nc" +output = "#expand user_output#zppy_min_case_global_time_series_comprehensive_v3_setup_only_output/#expand unique_id#/#expand case_name#" +partition = "#expand partition_short#" +qos = "#expand qos_short#" +www = "#expand user_www#zppy_min_case_global_time_series_comprehensive_v3_setup_only_www/#expand unique_id#" +years = "1985:1989:2", + +[ts] +active = True +e3sm_to_cmip_environment_commands = "#expand e3sm_to_cmip_environment_commands#" +walltime = "00:30:00" + + [[ atm_monthly_glb ]] + # Note global average won't work for 3D variables. + frequency = "monthly" + input_files = "eam.h0" + input_subdir = "archive/atm/hist" + mapping_file = "glb" + years = "1985:1995:5", + + [[ lnd_monthly_glb ]] + frequency = "monthly" + input_files = "elm.h0" + input_subdir = "archive/lnd/hist" + mapping_file = "glb" + vars = "FSH,RH2M,LAISHA,LAISUN,QINTR,QOVER,QRUNOFF,QSOIL,QVEGE,QVEGT,SOILWATER_10CM,TSA,H2OSNO,TOTLITC,CWDC,SOIL1C,SOIL2C,SOIL3C,SOIL4C,WOOD_HARVESTC,TOTVEGC,NBP,GPP,AR,HR" + years = "1985:1995:5", + +[mpas_analysis] +active = True +anomalyRefYear = 1985 +climo_years = "1985-1989", "1990-1995", +enso_years = "1985-1989", "1990-1995", +mesh = "IcoswISC30E3r5" +parallelTaskCount = 6 +partition = "#expand partition_long#" +qos = "#expand qos_long#" +shortTermArchive = True +ts_years = "1985-1989", "1985-1995", +walltime = "#expand mpas_analysis_walltime#" + +# (This cfg is the setup portion only) +# [global_time_series] +# active = True +# climo_years = "1985-1989", "1990-1995", +# environment_commands = "#expand global_time_series_environment_commands#" +# experiment_name = "#expand case_name#" +# figstr = "#expand case_name#" +# moc_file=mocTimeSeries_1985-1995.nc +# plots_lnd = "FSH,RH2M,LAISHA,LAISUN,QINTR,QOVER,QRUNOFF,QSOIL,QVEGE,QVEGT,SOILWATER_10CM,TSA,H2OSNO,TOTLITC,CWDC,SOIL1C,SOIL2C,SOIL3C,SOIL4C,WOOD_HARVESTC,TOTVEGC,NBP,GPP,AR,HR" +# ts_num_years = 5 +# ts_years = "1985-1989", "1985-1995", +# walltime = "00:30:00" +# years = "1985-1995", diff --git a/tests/integration/template_update_bash_generation_expected_files.sh b/tests/integration/template_update_bash_generation_expected_files.sh index 8d21e2c6..1b7fdff4 100755 --- a/tests/integration/template_update_bash_generation_expected_files.sh +++ b/tests/integration/template_update_bash_generation_expected_files.sh @@ -7,4 +7,4 @@ rm -rf #expand expected_dir#expected_bash_files # You can just move (i.e., not copy) the output since re-running this test will re-generate the output. mv test_bash_generation_output/post/scripts #expand expected_dir#expected_bash_files # Rerun test -python -u -m unittest tests/integration/test_bash_generation.py +pytest tests/integration/test_bash_generation.py diff --git a/tests/integration/template_update_campaign_expected_files.sh b/tests/integration/template_update_campaign_expected_files.sh index f709d542..261b6fce 100755 --- a/tests/integration/template_update_campaign_expected_files.sh +++ b/tests/integration/template_update_campaign_expected_files.sh @@ -13,4 +13,4 @@ do done # Rerun test -python -m unittest tests/integration/test_campaign.py +pytest tests/integration/test_campaign.py diff --git a/tests/integration/template_update_defaults_expected_files.sh b/tests/integration/template_update_defaults_expected_files.sh index e4cec07a..d0f18957 100755 --- a/tests/integration/template_update_defaults_expected_files.sh +++ b/tests/integration/template_update_defaults_expected_files.sh @@ -8,4 +8,4 @@ mkdir -p #expand expected_dir#test_defaults_expected_files # You can just move (i.e., not copy) the output since re-running this test will re-generate the output. mv test_defaults_output/post/scripts/*.settings #expand expected_dir#test_defaults_expected_files # Rerun test -python -u -m unittest tests/integration/test_defaults.py +pytest tests/integration/test_defaults.py diff --git a/tests/integration/template_update_weekly_expected_files.sh b/tests/integration/template_update_weekly_expected_files.sh index f50c945d..b3ac4bf2 100755 --- a/tests/integration/template_update_weekly_expected_files.sh +++ b/tests/integration/template_update_weekly_expected_files.sh @@ -27,4 +27,4 @@ do done # Rerun test -python -u -m unittest tests/integration/test_weekly.py +pytest tests/integration/test_weekly.py diff --git a/tests/integration/test_bash_generation.py b/tests/integration/test_bash_generation.py index b8c4dff2..d8083ed8 100644 --- a/tests/integration/test_bash_generation.py +++ b/tests/integration/test_bash_generation.py @@ -1,25 +1,16 @@ import os -import unittest from tests.integration.utils import get_expansions -class TestBashGeneration(unittest.TestCase): - def test_bash_generation(self): - # cfg is not machine-specific - self.assertEqual( - os.system("zppy -c tests/integration/test_bash_generation.cfg"), 0 +def test_bash_generation(): + # cfg is not machine-specific + assert os.system("zppy -c tests/integration/test_bash_generation.cfg") == 0 + expected_dir = get_expansions()["expected_dir"] + assert ( + os.system( + f"diff -bur -I 'templateDir' test_bash_generation_output/post/scripts {expected_dir}expected_bash_files" ) - expected_dir = get_expansions()["expected_dir"] - self.assertEqual( - os.system( - f"diff -bur -I 'templateDir' test_bash_generation_output/post/scripts {expected_dir}expected_bash_files" - ), - 0, - ) - self.assertEqual(os.system("rm -r test_bash_generation_output"), 0) - - -if __name__ == "__main__": - # Run from top level of repo - unittest.main() + == 0 + ) + assert os.system("rm -r test_bash_generation_output") == 0 diff --git a/tests/integration/test_campaign.py b/tests/integration/test_campaign.py index dd5d8fe5..b49e58a4 100644 --- a/tests/integration/test_campaign.py +++ b/tests/integration/test_campaign.py @@ -1,124 +1,97 @@ import os -import unittest from tests.integration.utils import get_expansions # cfgs are not machine-specific -class TestCampaign(unittest.TestCase): - def test_campaign_cryosphere(self): - self.assertEqual( - os.system("zppy -c tests/integration/test_campaign_cryosphere.cfg"), 0 - ) - self.assertEqual( - os.system("rm test_campaign_cryosphere_output/post/scripts/*.bash"), 0 - ) - expected_dir = get_expansions()["expected_dir"] - self.assertEqual( - os.system( - f"diff -u -I 'templateDir' test_campaign_cryosphere_output/post/scripts {expected_dir}test_campaign_cryosphere_expected_files" - ), - 0, - ) - self.assertEqual(os.system("rm -r test_campaign_cryosphere_output"), 0) +def test_campaign_cryosphere(): + assert os.system("zppy -c tests/integration/test_campaign_cryosphere.cfg") == 0 + assert os.system("rm test_campaign_cryosphere_output/post/scripts/*.bash") == 0 + expected_dir = get_expansions()["expected_dir"] + assert ( + os.system( + f"diff -u -I 'templateDir' test_campaign_cryosphere_output/post/scripts {expected_dir}test_campaign_cryosphere_expected_files" + ) + == 0 + ) + assert os.system("rm -r test_campaign_cryosphere_output") == 0 - def test_campaign_cryosphere_override(self): - self.assertEqual( - os.system( - "zppy -c tests/integration/test_campaign_cryosphere_override.cfg" - ), - 0, - ) - self.assertEqual( - os.system( - "rm test_campaign_cryosphere_override_output/post/scripts/*.bash" - ), - 0, - ) - expected_dir = get_expansions()["expected_dir"] - self.assertEqual( - os.system( - f"diff -u -I 'templateDir' test_campaign_cryosphere_override_output/post/scripts {expected_dir}test_campaign_cryosphere_override_expected_files" - ), - 0, - ) - self.assertEqual(os.system("rm -r test_campaign_cryosphere_override_output"), 0) - def test_campaign_high_res_v1(self): - self.assertEqual( - os.system("zppy -c tests/integration/test_campaign_high_res_v1.cfg"), 0 - ) - self.assertEqual( - os.system("rm test_campaign_high_res_v1_output/post/scripts/*.bash"), 0 - ) - expected_dir = get_expansions()["expected_dir"] - self.assertEqual( - os.system( - f"diff -u -I 'templateDir' test_campaign_high_res_v1_output/post/scripts {expected_dir}test_campaign_high_res_v1_expected_files" - ), - 0, - ) - self.assertEqual(os.system("rm -r test_campaign_high_res_v1_output"), 0) +def test_campaign_cryosphere_override(): + assert ( + os.system("zppy -c tests/integration/test_campaign_cryosphere_override.cfg") + == 0 + ) + assert ( + os.system("rm test_campaign_cryosphere_override_output/post/scripts/*.bash") + == 0 + ) + expected_dir = get_expansions()["expected_dir"] + assert ( + os.system( + f"diff -u -I 'templateDir' test_campaign_cryosphere_override_output/post/scripts {expected_dir}test_campaign_cryosphere_override_expected_files" + ) + == 0 + ) + assert os.system("rm -r test_campaign_cryosphere_override_output") == 0 - def test_campaign_none(self): - self.assertEqual( - os.system("zppy -c tests/integration/test_campaign_none.cfg"), 0 - ) - self.assertEqual( - os.system("rm test_campaign_none_output/post/scripts/*.bash"), 0 - ) - expected_dir = get_expansions()["expected_dir"] - self.assertEqual( - os.system( - f"diff -u -I 'templateDir' test_campaign_none_output/post/scripts {expected_dir}test_campaign_none_expected_files" - ), - 0, - ) - self.assertEqual(os.system("rm -r test_campaign_none_output"), 0) - def test_campaign_water_cycle(self): - self.assertEqual( - os.system("zppy -c tests/integration/test_campaign_water_cycle.cfg"), 0 - ) - self.assertEqual( - os.system("rm test_campaign_water_cycle_output/post/scripts/*.bash"), 0 - ) - expected_dir = get_expansions()["expected_dir"] - self.assertEqual( - os.system( - f"diff -u -I 'templateDir' test_campaign_water_cycle_output/post/scripts {expected_dir}test_campaign_water_cycle_expected_files" - ), - 0, - ) - self.assertEqual(os.system("rm -r test_campaign_water_cycle_output"), 0) +def test_campaign_high_res_v1(): + assert os.system("zppy -c tests/integration/test_campaign_high_res_v1.cfg") == 0 + assert os.system("rm test_campaign_high_res_v1_output/post/scripts/*.bash") == 0 + expected_dir = get_expansions()["expected_dir"] + assert ( + os.system( + f"diff -u -I 'templateDir' test_campaign_high_res_v1_output/post/scripts {expected_dir}test_campaign_high_res_v1_expected_files" + ) + == 0 + ) + assert os.system("rm -r test_campaign_high_res_v1_output") == 0 + + +def test_campaign_none(): + assert os.system("zppy -c tests/integration/test_campaign_none.cfg") == 0 + assert os.system("rm test_campaign_none_output/post/scripts/*.bash") == 0 + expected_dir = get_expansions()["expected_dir"] + assert ( + os.system( + f"diff -u -I 'templateDir' test_campaign_none_output/post/scripts {expected_dir}test_campaign_none_expected_files" + ) + == 0 + ) + assert os.system("rm -r test_campaign_none_output") == 0 + + +def test_campaign_water_cycle(): + assert os.system("zppy -c tests/integration/test_campaign_water_cycle.cfg") == 0 + assert os.system("rm test_campaign_water_cycle_output/post/scripts/*.bash") == 0 + expected_dir = get_expansions()["expected_dir"] + assert ( + os.system( + f"diff -u -I 'templateDir' test_campaign_water_cycle_output/post/scripts {expected_dir}test_campaign_water_cycle_expected_files" + ) + == 0 + ) + assert os.system("rm -r test_campaign_water_cycle_output") == 0 - def test_campaign_water_cycle_override(self): - self.assertEqual( - os.system( - "zppy -c tests/integration/test_campaign_water_cycle_override.cfg" - ), - 0, - ) - self.assertEqual( - os.system( - "rm test_campaign_water_cycle_override_output/post/scripts/*.bash" - ), - 0, - ) - expected_dir = get_expansions()["expected_dir"] - self.assertEqual( - os.system( - f"diff -u -I 'templateDir' test_campaign_water_cycle_override_output/post/scripts {expected_dir}/test_campaign_water_cycle_override_expected_files" - ), - 0, - ) - self.assertEqual( - os.system("rm -r test_campaign_water_cycle_override_output"), 0 - ) - # test_bash_generation.py covers the case of an unspecified campaign. +def test_campaign_water_cycle_override(): + assert ( + os.system("zppy -c tests/integration/test_campaign_water_cycle_override.cfg") + == 0 + ) + assert ( + os.system("rm test_campaign_water_cycle_override_output/post/scripts/*.bash") + == 0 + ) + expected_dir = get_expansions()["expected_dir"] + assert ( + os.system( + f"diff -u -I 'templateDir' test_campaign_water_cycle_override_output/post/scripts {expected_dir}test_campaign_water_cycle_override_expected_files" + ) + == 0 + ) + assert os.system("rm -r test_campaign_water_cycle_override_output") == 0 -if __name__ == "__main__": - # Run from top level of repo - unittest.main() +# test_bash_generation.py covers the case of an unspecified campaign. diff --git a/tests/integration/test_defaults.py b/tests/integration/test_defaults.py index 90b4b866..ee934d4f 100644 --- a/tests/integration/test_defaults.py +++ b/tests/integration/test_defaults.py @@ -1,30 +1,23 @@ import os -import unittest from tests.integration.utils import get_expansions -class TestDefaults(unittest.TestCase): - def test_defaults(self): - # cfg is not machine-specific - self.assertEqual(os.system("zppy -c tests/integration/test_defaults.cfg"), 0) - self.assertEqual(os.system("rm test_defaults_output/post/scripts/*.bash"), 0) - self.assertEqual( - os.system( - "rm -rf test_defaults_output/post/scripts/global_time_series_0001-0020_dir" - ), - 0, +def test_defaults(): + # cfg is not machine-specific + assert os.system("zppy -c tests/integration/test_defaults.cfg") == 0 + assert os.system("rm test_defaults_output/post/scripts/*.bash") == 0 + assert ( + os.system( + "rm -rf test_defaults_output/post/scripts/global_time_series_0001-0020_dir" ) - expected_dir = get_expansions()["expected_dir"] - self.assertEqual( - os.system( - f"diff -bur -I 'templateDir' test_defaults_output/post/scripts {expected_dir}test_defaults_expected_files" - ), - 0, + == 0 + ) + expected_dir = get_expansions()["expected_dir"] + assert ( + os.system( + f"diff -bur -I 'templateDir' test_defaults_output/post/scripts {expected_dir}test_defaults_expected_files" ) - self.assertEqual(os.system("rm -r test_defaults_output"), 0) - - -if __name__ == "__main__": - # Run from top level of repo - unittest.main() + == 0 + ) + assert os.system("rm -r test_defaults_output") == 0 diff --git a/tests/integration/test_last_year.py b/tests/integration/test_last_year.py index 0a96352d..f6ebad33 100644 --- a/tests/integration/test_last_year.py +++ b/tests/integration/test_last_year.py @@ -1,37 +1,26 @@ import os -import unittest -class TestLastYear(unittest.TestCase): - def test_last_year(self): - # Note that this integration test does not have any expected files in `tests.integration.utils.get_expansions()["expected_dir"]` - # cfg is not machine-specific - self.assertEqual( - os.system("zppy -c tests/integration/test_last_year.cfg --last-year 12"), 0 - ) - self.assertEqual( - os.system("rm test_last_year_output/post/scripts/*.settings"), 0 - ) - actual_files = sorted(os.listdir("test_last_year_output/post/scripts")) - expected_files = [ - "climo_atm_monthly_180x360_aave_0001-0010.bash", - "climo_atm_monthly_diurnal_8xdaily_180x360_aave_0001-0010.bash", - "e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_0001-0010.bash", - "mpas_analysis_ts_0001-0010_climo_0001-0010.bash", - "tc_analysis_0001-0010.bash", - "ts_atm_daily_180x360_aave_0001-0010-0010.bash", - "ts_atm_monthly_180x360_aave_0001-0010-0010.bash", - "ts_atm_monthly_glb_0001-0010-0010.bash", - "ts_land_monthly_0001-0010-0010.bash", - "ts_rof_monthly_0001-0010-0010.bash", - ] - if actual_files != expected_files: - print(actual_files) - print(expected_files) - self.assertEqual(actual_files, expected_files) - self.assertEqual(os.system("rm -r test_last_year_output"), 0) - - -if __name__ == "__main__": - # Run from top level of repo - unittest.main() +def test_last_year(): + # Note that this integration test does not have any expected files in `tests.integration.utils.get_expansions()["expected_dir"]` + # cfg is not machine-specific + assert os.system("zppy -c tests/integration/test_last_year.cfg --last-year 12") == 0 + assert os.system("rm test_last_year_output/post/scripts/*.settings") == 0 + actual_files = sorted(os.listdir("test_last_year_output/post/scripts")) + expected_files = [ + "climo_atm_monthly_180x360_aave_0001-0010.bash", + "climo_atm_monthly_diurnal_8xdaily_180x360_aave_0001-0010.bash", + "e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_0001-0010.bash", + "mpas_analysis_ts_0001-0010_climo_0001-0010.bash", + "tc_analysis_0001-0010.bash", + "ts_atm_daily_180x360_aave_0001-0010-0010.bash", + "ts_atm_monthly_180x360_aave_0001-0010-0010.bash", + "ts_atm_monthly_glb_0001-0010-0010.bash", + "ts_land_monthly_0001-0010-0010.bash", + "ts_rof_monthly_0001-0010-0010.bash", + ] + if actual_files != expected_files: + print(actual_files) + print(expected_files) + assert actual_files == expected_files + assert os.system("rm -r test_last_year_output") == 0 diff --git a/tests/integration/test_weekly.py b/tests/integration/test_weekly.py index d919cafc..5ee8f827 100644 --- a/tests/integration/test_weekly.py +++ b/tests/integration/test_weekly.py @@ -1,5 +1,4 @@ import os -import unittest from tests.integration.utils import check_mismatched_images, get_expansions @@ -7,7 +6,7 @@ V2_CASE_NAME = "v2.LR.historical_0201" -def test_images(tester, test_name, case_name): +def check_images(test_name, case_name): # See docs/source/dev_guide/testing.rst for steps to run before running this test. expansions = get_expansions() expected_dir = expansions["expected_dir"] @@ -25,90 +24,89 @@ def test_images(tester, test_name, case_name): diff_dir = f"{actual_images_dir}image_check_failures_{test_name}" check_mismatched_images( - tester, actual_images_dir, expected_images_file, expected_images_dir, diff_dir + actual_images_dir, expected_images_file, expected_images_dir, diff_dir ) -# To run just one test: -# python -u -m unittest tests/integration/test_weekly.py TestWeekly.test_{name} -class TestWeekly(unittest.TestCase): - def test_comprehensive_v2_images(self): - test_images(self, "comprehensive_v2", V2_CASE_NAME) - - def test_comprehensive_v3_images(self): - test_images(self, "comprehensive_v3", V3_CASE_NAME) - - def test_bundles_images(self): - test_images(self, "bundles", V3_CASE_NAME) - - def test_bundles_bash_file_list(self): - # Check that the correct bash files are generated - expansions = get_expansions() - user_output = expansions["user_output"] - unique_id = expansions["unique_id"] - directory = f"{user_output}zppy_weekly_bundles_output/{unique_id}/{V3_CASE_NAME}/post/scripts" - bash_file_list = f"{directory}/bash_file_list.txt" - cmd = f"cd {directory} && find . -type f -name '*.bash' > {bash_file_list}" - os.system(cmd) - actual_bash_files = set() - with open(bash_file_list, "r") as f: - for line in f: - actual_bash_files.add(line.lstrip("./").rstrip("\n")) - expected_bash_files = set( - [ - "bundle1.bash", - "bundle2.bash", - "bundle3.bash", - "climo_atm_monthly_180x360_aave_1985-1986.bash", - "climo_atm_monthly_180x360_aave_1987-1988.bash", - "climo_atm_monthly_diurnal_8xdaily_180x360_aave_1985-1986.bash", - "climo_atm_monthly_diurnal_8xdaily_180x360_aave_1987-1988.bash", - "e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_1985-1986.bash", - "e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_1987-1988.bash", - "e3sm_diags_atm_monthly_180x360_aave_mvm_model_vs_model_1987-1988_vs_1985-1986.bash", - "global_time_series_1985-1995.bash", - "ilamb_1985-1986.bash", - # "tc_analysis_1985-1986.bash", - # "tc_analysis_1987-1988.bash", - "ts_atm_monthly_180x360_aave_1985-1986-0002.bash", - "ts_atm_monthly_180x360_aave_1987-1988-0002.bash", - "ts_atm_monthly_glb_1985-1989-0005.bash", - "ts_atm_monthly_glb_1990-1994-0005.bash", - "ts_land_monthly_1985-1986-0002.bash", - "ts_land_monthly_1987-1988-0002.bash", - "ts_rof_monthly_1985-1986-0002.bash", - "ts_rof_monthly_1987-1988-0002.bash", - ] - ) - self.assertEqual(actual_bash_files, expected_bash_files) - - def test_bundles_bash_file_content(self): - expansions = get_expansions() - user_output = expansions["user_output"] - expected_dir = expansions["expected_dir"] - unique_id = expansions["unique_id"] - actual_directory = f"{user_output}zppy_weekly_bundles_output/{unique_id}/{V3_CASE_NAME}/post/scripts" - expected_directory = f"{expected_dir}expected_bundles/bundle_files" - # Check that bundle files are correct - self.assertEqual( - os.system( - f"diff -bu -I 'zppy_weekly_bundles_output/' {actual_directory}/bundle1.bash {expected_directory}/bundle1.bash" - ), - 0, +# Run with: +# pytest tests/integration/test_weekly.py +def test_comprehensive_v2_images(): + check_images("comprehensive_v2", V2_CASE_NAME) + + +def test_comprehensive_v3_images(): + check_images("comprehensive_v3", V3_CASE_NAME) + + +def test_bundles_images(): + check_images("bundles", V3_CASE_NAME) + + +def test_bundles_bash_file_list(): + # Check that the correct bash files are generated + expansions = get_expansions() + user_output = expansions["user_output"] + unique_id = expansions["unique_id"] + directory = f"{user_output}zppy_weekly_bundles_output/{unique_id}/{V3_CASE_NAME}/post/scripts" + bash_file_list = f"{directory}/bash_file_list.txt" + cmd = f"cd {directory} && find . -type f -name '*.bash' > {bash_file_list}" + os.system(cmd) + actual_bash_files = set() + with open(bash_file_list, "r") as f: + for line in f: + actual_bash_files.add(line.lstrip("./").rstrip("\n")) + expected_bash_files = set( + [ + "bundle1.bash", + "bundle2.bash", + "bundle3.bash", + "climo_atm_monthly_180x360_aave_1985-1986.bash", + "climo_atm_monthly_180x360_aave_1987-1988.bash", + "climo_atm_monthly_diurnal_8xdaily_180x360_aave_1985-1986.bash", + "climo_atm_monthly_diurnal_8xdaily_180x360_aave_1987-1988.bash", + "e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_1985-1986.bash", + "e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_1987-1988.bash", + "e3sm_diags_atm_monthly_180x360_aave_mvm_model_vs_model_1987-1988_vs_1985-1986.bash", + "global_time_series_1985-1995.bash", + "ilamb_1985-1986.bash", + # "tc_analysis_1985-1986.bash", + # "tc_analysis_1987-1988.bash", + "ts_atm_monthly_180x360_aave_1985-1986-0002.bash", + "ts_atm_monthly_180x360_aave_1987-1988-0002.bash", + "ts_atm_monthly_glb_1985-1989-0005.bash", + "ts_atm_monthly_glb_1990-1994-0005.bash", + "ts_land_monthly_1985-1986-0002.bash", + "ts_land_monthly_1987-1988-0002.bash", + "ts_rof_monthly_1985-1986-0002.bash", + "ts_rof_monthly_1987-1988-0002.bash", + ] + ) + assert actual_bash_files == expected_bash_files + + +def test_bundles_bash_file_content(): + expansions = get_expansions() + user_output = expansions["user_output"] + expected_dir = expansions["expected_dir"] + unique_id = expansions["unique_id"] + actual_directory = f"{user_output}zppy_weekly_bundles_output/{unique_id}/{V3_CASE_NAME}/post/scripts" + expected_directory = f"{expected_dir}expected_bundles/bundle_files" + # Check that bundle files are correct + assert ( + os.system( + f"diff -bu -I 'zppy_weekly_bundles_output/' {actual_directory}/bundle1.bash {expected_directory}/bundle1.bash" ) - self.assertEqual( - os.system( - f"diff -bu -I 'zppy_weekly_bundles_output/' {actual_directory}/bundle2.bash {expected_directory}/bundle2.bash" - ), - 0, + == 0 + ) + assert ( + os.system( + f"diff -bu -I 'zppy_weekly_bundles_output/' {actual_directory}/bundle2.bash {expected_directory}/bundle2.bash" ) - self.assertEqual( - os.system( - f"diff -bu -I 'zppy_weekly_bundles_output/' {actual_directory}/bundle3.bash {expected_directory}/bundle3.bash" - ), - 0, + == 0 + ) + assert ( + os.system( + f"diff -bu -I 'zppy_weekly_bundles_output/' {actual_directory}/bundle3.bash {expected_directory}/bundle3.bash" ) - - -if __name__ == "__main__": - unittest.main() + == 0 + ) diff --git a/tests/integration/utils.py b/tests/integration/utils.py index 7d47c49d..58d353c6 100644 --- a/tests/integration/utils.py +++ b/tests/integration/utils.py @@ -14,7 +14,6 @@ # Copied from E3SM Diags def compare_images( - test, missing_images, mismatched_images, image_name, @@ -37,7 +36,7 @@ def compare_images( bbox = diff.getbbox() if not bbox: # If `diff.getbbox()` is None, then the images are in theory equal - test.assertIsNone(diff.getbbox()) + assert diff.getbbox() is None else: # Sometimes, a few pixels will differ, but the two images appear identical. # https://codereview.stackexchange.com/questions/55902/fastest-way-to-count-non-zero-pixels-using-python-and-pillow @@ -91,7 +90,7 @@ def compare_images( def check_mismatched_images( - test, actual_images_dir, expected_images_file, expected_images_dir, diff_dir + actual_images_dir, expected_images_file, expected_images_dir, diff_dir ): missing_images: List[str] = [] mismatched_images: List[str] = [] @@ -107,7 +106,6 @@ def check_mismatched_images( path_to_expected_png = os.path.join(expected_images_dir, image_name) compare_images( - test, missing_images, mismatched_images, image_name, @@ -128,8 +126,8 @@ def check_mismatched_images( # Make diff_dir readable os.system(f"chmod -R 755 {diff_dir}") - test.assertEqual(missing_images, []) - test.assertEqual(mismatched_images, []) + assert missing_images == [] + assert mismatched_images == [] # Multi-machine testing ########################################################## @@ -309,6 +307,7 @@ def generate_cfgs(unified_testing=False, dry_run=False): "min_case_e3sm_diags_tropical_subseasonal_mvm_1", "min_case_e3sm_diags_tropical_subseasonal_mvm_2", "min_case_e3sm_diags_tropical_subseasonal", + "min_case_global_time_series_comprehensive_v3_setup_only", "min_case_global_time_series_custom", "min_case_global_time_series_original_8_no_ocn", "min_case_global_time_series_original_8", @@ -347,6 +346,9 @@ def generate_cfgs(unified_testing=False, dry_run=False): print(f"UNIQUE_ID={UNIQUE_ID}") print(f"unified_testing={unified_testing}") print(f"diags_environment_commands={expansions['diags_environment_commands']}") + print( + f"global_time_series_environment_commands={expansions['global_time_series_environment_commands']}" + ) print( f"e3sm_to_cmip_environment_commands={expansions['e3sm_to_cmip_environment_commands']}" ) diff --git a/zppy/global_time_series.py b/zppy/global_time_series.py index e6883c15..183de780 100644 --- a/zppy/global_time_series.py +++ b/zppy/global_time_series.py @@ -134,6 +134,9 @@ def determine_components(c: Dict[str, Any]) -> None: else: # For better string processing in global_time_series.bash c["plots_ocn"] = "None" + if ("moc_file" not in c.keys()) or (not c["moc_file"]): + # For better string processing in global_time_series.bash + c["moc_file"] = "None" def determine_and_add_dependencies(