266 lines
9.4 KiB
Python
266 lines
9.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Unit tests for subset_data
|
|
|
|
You can run this by:
|
|
python -m unittest test_unit_subset_data.py
|
|
"""
|
|
|
|
import unittest
|
|
import configparser
|
|
import argparse
|
|
import os
|
|
import sys
|
|
|
|
# -- add python/ctsm to path (needed if we want to run the test stand-alone)
|
|
_CTSM_PYTHON = os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, os.pardir)
|
|
sys.path.insert(1, _CTSM_PYTHON)
|
|
|
|
# pylint: disable=wrong-import-position
|
|
from ctsm import unit_testing
|
|
from ctsm.subset_data import get_parser, setup_files, check_args
|
|
from ctsm.path_utils import path_to_ctsm_root
|
|
|
|
# pylint: disable=invalid-name
|
|
|
|
|
|
class TestSubsetData(unittest.TestCase):
|
|
"""
|
|
Basic class for testing SubsetData class in subset_data.py.
|
|
"""
|
|
|
|
def setUp(self):
|
|
sys.argv = ["subset_data", "point", "--create-surface"]
|
|
DEFAULTS_FILE = os.path.join(
|
|
os.getcwd(), "../tools/site_and_regional/default_data_2000.cfg"
|
|
)
|
|
self.parser = get_parser()
|
|
self.args = self.parser.parse_args()
|
|
self.cesmroot = path_to_ctsm_root()
|
|
self.defaults = configparser.ConfigParser()
|
|
self.defaults.read(os.path.join(self.cesmroot, "tools/site_and_regional", DEFAULTS_FILE))
|
|
|
|
def test_inputdata_setup_files_basic(self):
|
|
"""
|
|
Test
|
|
"""
|
|
check_args(self.args)
|
|
files = setup_files(self.args, self.defaults, self.cesmroot)
|
|
self.assertEqual(
|
|
files["fsurf_in"],
|
|
"surfdata_0.9x1.25_hist_2000_16pfts_c240216.nc",
|
|
"fsurf_in filename not whats expected",
|
|
)
|
|
self.assertEqual(
|
|
files["fsurf_out"],
|
|
None,
|
|
"fsurf_out filename not whats expected",
|
|
)
|
|
self.assertEqual(
|
|
files["main_dir"],
|
|
"/glade/campaign/cesm/cesmdata/cseg/inputdata",
|
|
"main_dir directory not whats expected",
|
|
)
|
|
|
|
def test_inputdata_setup_files_inputdata_dne(self):
|
|
"""
|
|
Test that inputdata directory does not exist
|
|
"""
|
|
check_args(self.args)
|
|
self.defaults.set("main", "clmforcingindir", "/zztop")
|
|
with self.assertRaisesRegex(SystemExit, "inputdata directory does not exist"):
|
|
setup_files(self.args, self.defaults, self.cesmroot)
|
|
|
|
def test_check_args_nooutput(self):
|
|
"""
|
|
Test that check args aborts when no-output is asked for
|
|
"""
|
|
sys.argv = ["subset_data", "point"]
|
|
self.args = self.parser.parse_args()
|
|
with self.assertRaisesRegex(argparse.ArgumentError, "Must supply one of"):
|
|
check_args(self.args)
|
|
|
|
def test_check_args_notype(self):
|
|
"""
|
|
Test that check args aborts when no type is asked for
|
|
"""
|
|
sys.argv = ["subset_data"]
|
|
self.args = self.parser.parse_args()
|
|
with self.assertRaisesRegex(argparse.ArgumentError, "Must supply a positional argument:"):
|
|
check_args(self.args)
|
|
|
|
def test_check_args_badconfig(self):
|
|
"""
|
|
Test that check args aborts when a config file is entered that doesn't exist
|
|
"""
|
|
sys.argv = ["subset_data", "point", "--create-surface", "--cfg-file", "zztop"]
|
|
self.args = self.parser.parse_args()
|
|
with self.assertRaisesRegex(
|
|
argparse.ArgumentError, "Entered default config file does not exist"
|
|
):
|
|
check_args(self.args)
|
|
|
|
def test_check_args_outsurfdat_provided(self):
|
|
"""
|
|
Test that check args allows an output surface dataset to be specified
|
|
when create-surface is on
|
|
"""
|
|
sys.argv = ["subset_data", "point", "--create-surface", "--out-surface", "outputsurface.nc"]
|
|
self.args = self.parser.parse_args()
|
|
check_args(self.args)
|
|
files = setup_files(self.args, self.defaults, self.cesmroot)
|
|
self.assertEqual(
|
|
files["fsurf_out"],
|
|
"outputsurface.nc",
|
|
"fsurf_out filename not whats expected",
|
|
)
|
|
|
|
def test_check_args_outsurfdat_fails_without_create_surface(self):
|
|
"""
|
|
Test that check args does not allow an output surface dataset to be specified
|
|
when create-surface is not on
|
|
"""
|
|
sys.argv = ["subset_data", "point", "--create-datm", "--out-surface", "outputsurface.nc"]
|
|
self.args = self.parser.parse_args()
|
|
with self.assertRaisesRegex(
|
|
argparse.ArgumentError,
|
|
"out-surface option is given without the --create-surface option",
|
|
):
|
|
check_args(self.args)
|
|
|
|
def test_check_args_fails_for_timeseries_without_correct_surface_year(self):
|
|
"""
|
|
Test that check args does not allow landuse-timeseries to be used
|
|
without providing the correct start surface year
|
|
"""
|
|
sys.argv = ["subset_data", "point", "--create-landuse", "--create-surface"]
|
|
self.args = self.parser.parse_args()
|
|
with self.assertRaisesRegex(
|
|
argparse.ArgumentError,
|
|
"--surf-year option is NOT set to 1850 and the --create-landuse option",
|
|
):
|
|
check_args(self.args)
|
|
|
|
def test_check_args_fails_for_surf_year_without_surface(self):
|
|
"""
|
|
Test that check args does not allow surf_year to be set
|
|
without the create-surface option
|
|
"""
|
|
sys.argv = ["subset_data", "point", "--create-datm", "--surf-year", "1850"]
|
|
self.args = self.parser.parse_args()
|
|
with self.assertRaisesRegex(
|
|
argparse.ArgumentError,
|
|
"--surf-year option is set to something besides the default of 2000",
|
|
):
|
|
check_args(self.args)
|
|
|
|
def test_check_args_fails_for_landuse_without_surface(self):
|
|
"""
|
|
Test that check args does not allow landuse to be set
|
|
without the create-surface option
|
|
"""
|
|
sys.argv = ["subset_data", "point", "--create-landuse"]
|
|
self.args = self.parser.parse_args()
|
|
with self.assertRaisesRegex(
|
|
argparse.ArgumentError,
|
|
"--create-landuse option requires the --create-surface option",
|
|
):
|
|
check_args(self.args)
|
|
|
|
def test_check_args_fails_bad_surface_year(self):
|
|
"""
|
|
Test that check args does not allow --surf-year to be bad
|
|
"""
|
|
sys.argv = ["subset_data", "point", "--create-surface", "--surf-year", "2305"]
|
|
self.args = self.parser.parse_args()
|
|
with self.assertRaisesRegex(
|
|
argparse.ArgumentError, "--surf-year option can only be set to 1850 or 2000"
|
|
):
|
|
check_args(self.args)
|
|
|
|
def test_check_args_outsurfdat_fails_without_overwrite(self):
|
|
"""
|
|
Test that check args does not allow an output surface dataset to be specified
|
|
for an existing dataset without the overwrite option
|
|
"""
|
|
outfile = os.path.join(
|
|
os.getcwd(),
|
|
"ctsm/test/testinputs/",
|
|
"surfdata_1x1_mexicocityMEX_hist_16pfts_CMIP6_2000_c231103.nc",
|
|
)
|
|
self.assertTrue(os.path.exists(outfile), str(outfile) + " outfile should exist")
|
|
|
|
sys.argv = ["subset_data", "point", "--create-surface", "--out-surface", outfile]
|
|
self.args = self.parser.parse_args()
|
|
with self.assertRaisesRegex(
|
|
argparse.ArgumentError,
|
|
"out-surface filename exists and the overwrite option was not also selected",
|
|
):
|
|
check_args(self.args)
|
|
|
|
def test_inputdata_setup_files_bad_inputdata_arg(self):
|
|
"""
|
|
Test that inputdata directory provided on command line does not exist if it's bad
|
|
"""
|
|
check_args(self.args)
|
|
self.args.inputdatadir = "/zztop"
|
|
with self.assertRaisesRegex(SystemExit, "inputdata directory does not exist"):
|
|
setup_files(self.args, self.defaults, self.cesmroot)
|
|
|
|
def test_create_user_mods_without_create_mesh(self):
|
|
"""
|
|
Test that you can't run create user mods without also doing create_mesh
|
|
"""
|
|
sys.argv = ["subset_data", "region", "--create-user-mods", "--create-surface"]
|
|
self.args = self.parser.parse_args()
|
|
with self.assertRaisesRegex(
|
|
argparse.ArgumentError, "For regional cases, you can not create user_mods"
|
|
):
|
|
check_args(self.args)
|
|
|
|
def test_create_mesh_without_domain(self):
|
|
"""
|
|
Test that you can't run create mesh without domain
|
|
"""
|
|
sys.argv = [
|
|
"subset_data",
|
|
"region",
|
|
"--create-user-mods",
|
|
"--create-surface",
|
|
"--create-mesh",
|
|
]
|
|
self.args = self.parser.parse_args()
|
|
with self.assertRaisesRegex(
|
|
argparse.ArgumentError, "For regional cases, you can not create mesh files"
|
|
):
|
|
check_args(self.args)
|
|
|
|
def test_complex_option_works(self):
|
|
"""
|
|
Test that check_args won't flag a set of complex options that is valid
|
|
Do user-mods, surface and landuse-timeseries, as well as DATM, for verbose with crop
|
|
"""
|
|
sys.argv = [
|
|
"subset_data",
|
|
"region",
|
|
"--reg",
|
|
"testname",
|
|
"--create-user-mods",
|
|
"--create-surface",
|
|
"--create-landuse",
|
|
"--surf-year",
|
|
"1850",
|
|
"--create-mesh",
|
|
"--create-domain",
|
|
"--create-datm",
|
|
"--verbose",
|
|
"--crop",
|
|
]
|
|
self.args = self.parser.parse_args()
|
|
check_args(self.args)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unit_testing.setup_for_tests()
|
|
unittest.main()
|