Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

run_sys_tests: Check Python environment for FatesColdTwoStream tests #2326

Merged
merged 11 commits into from
Jan 25, 2024
1 change: 1 addition & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ e4d38681df23ccca0ae29581a45f8362574e0630
025d5e7c2e80263717fb029101d65cbbf261c3c4
a9d96219902cf609636886c7073a84407f450d9a
d866510188d26d51bcd6d37239283db690af7e82
0dcd0a3c1abcaffe5529f8d79a6bc34734b195c7
# Ran SystemTests and python/ctsm through black python formatter
5364ad66eaceb55dde2d3d598fe4ce37ac83a93c
8056ae649c1b37f5e10aaaac79005d6e3a8b2380
Expand Down
44 changes: 40 additions & 4 deletions python/ctsm/run_sys_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def run_sys_tests(
else:
raise RuntimeError("None of suite_name, testfile or testlist were provided")
if not running_ctsm_py_tests:
_try_systemtests(testname_list)
_check_py_env(testname_list)
_run_create_test(
cime_path=cime_path,
test_args=test_args,
Expand Down Expand Up @@ -708,20 +708,55 @@ def _run_test_suite(
)


def _try_systemtests(testname_list):
def _get_testmod_list(test_attributes, unique=False):
# Isolate testmods, producing a list like
# ["clm-test1mod1", "clm-test2mod1", "clm-test2mod2", ...]
# Handles test attributes passed in from run_sys_tests calls using -t, -f, or -s

testmods = []
for test_attribute in test_attributes:
for dot_split in test_attribute.split("."):
slash_replaced = dot_split.replace("/", "-")
for ddash_split in slash_replaced.split("--"):
if "clm-" in ddash_split and (ddash_split not in testmods or not unique):
testmods.append(ddash_split)

return testmods


def _check_py_env(test_attributes):
err_msg = " can't be loaded. Do you need to activate the ctsm_pylib conda environment?"
# Suppress pylint import-outside-toplevel warning because (a) we only want to import
# this when certain tests are requested, and (b) the import needs to be in a try-except
# block to produce a nice error message.
# pylint: disable=import-outside-toplevel disable
# Suppress pylint unused-import warning because the import itself IS the use.
# pylint: disable=unused-import disable
if any("FSURDATMODIFYCTSM" in t for t in testname_list):
# Suppress pylint import-error warning because the whole point here is to check
# whether import is possible.
# pylint: disable=import-error disable

# Check requirements for FSURDATMODIFYCTSM, if needed
if any("FSURDATMODIFYCTSM" in t for t in test_attributes):
try:
import ctsm.modify_input_files.modify_fsurdat
except ModuleNotFoundError as err:
raise ModuleNotFoundError("modify_fsurdat" + err_msg) from err

# Check that list for any testmods that use modify_fates_paramfile.py
testmods_to_check = ["clm-FatesColdTwoStream", "clm-FatesColdTwoStreamNoCompFixedBioGeo"]
testmods = _get_testmod_list(test_attributes)
if any(t in testmods_to_check for t in testmods):
# This bit is needed because it's outside the top-level python/ directory.
fates_dir = os.path.join(
os.path.dirname(os.path.realpath(__file__)), os.pardir, os.pardir, "src", "fates"
)
sys.path.insert(1, fates_dir)
try:
import tools.modify_fates_paramfile
except ModuleNotFoundError as err:
raise ModuleNotFoundError("modify_fates_paramfile" + err_msg) from err


def _get_compilers_for_suite(suite_name, machine_name, running_ctsm_py_tests):
test_data = get_tests_from_xml(xml_machine=machine_name, xml_category=suite_name)
Expand All @@ -730,7 +765,8 @@ def _get_compilers_for_suite(suite_name, machine_name, running_ctsm_py_tests):
"No tests found for suite {} on machine {}".format(suite_name, machine_name)
)
if not running_ctsm_py_tests:
_try_systemtests([t["testname"] for t in test_data])
_check_py_env([t["testname"] for t in test_data])
_check_py_env([t["testmods"] for t in test_data if "testmods" in t.keys()])
compilers = sorted({one_test["compiler"] for one_test in test_data})
logger.info("Running with compilers: %s", compilers)
return compilers
Expand Down
53 changes: 52 additions & 1 deletion python/ctsm/test/test_unit_run_sys_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

from ctsm import add_cime_to_path # pylint: disable=unused-import
from ctsm import unit_testing
from ctsm.run_sys_tests import run_sys_tests
from ctsm.run_sys_tests import run_sys_tests, _get_testmod_list
from ctsm.machine_defaults import MACHINE_DEFAULTS
from ctsm.machine import create_machine
from ctsm.joblauncher.job_launcher_factory import JOB_LAUNCHER_FAKE
Expand Down Expand Up @@ -269,6 +269,57 @@ def test_withDryRun_nothingDone(self):
self.assertEqual(os.listdir(self._scratch), [])
self.assertEqual(machine.job_launcher.get_commands(), [])

def test_getTestmodList_suite(self):
"""Ensure that _get_testmod_list() works correctly with suite-style input"""
input = [
"clm/default",
"clm/default",
"clm/crop",
"clm/cropMonthlyOutput",
]
target = [
"clm-default",
"clm-default",
"clm-crop",
"clm-cropMonthlyOutput",
]
output = _get_testmod_list(input, unique=False)
self.assertEqual(output, target)

def test_getTestmodList_suite_unique(self):
"""Ensure that _get_testmod_list() works correctly with unique=True"""
input = [
"clm/default",
"clm/default",
"clm/crop",
"clm/cropMonthlyOutput",
]
target = [
"clm-default",
"clm-crop",
"clm-cropMonthlyOutput",
]

output = _get_testmod_list(input, unique=True)
self.assertEqual(output, target)

def test_getTestmodList_testname(self):
"""Ensure that _get_testmod_list() works correctly with full test name(s) specified"""
input = [
"ERS_D_Ld15.f45_f45_mg37.I2000Clm50FatesRs.izumi_nag.clm-crop",
"ERS_D_Ld15.f45_f45_mg37.I2000Clm50FatesRs.izumi_nag.clm-default",
]
target = ["clm-crop", "clm-default"]
output = _get_testmod_list(input)
self.assertEqual(output, target)

def test_getTestmodList_twomods(self):
"""Ensure that _get_testmod_list() works correctly with full test name(s) specified and two mods in one test"""
input = ["ERS_D_Ld15.f45_f45_mg37.I2000Clm50FatesRs.izumi_nag.clm-default--clm-crop"]
target = ["clm-default", "clm-crop"]
output = _get_testmod_list(input)
self.assertEqual(output, target)


if __name__ == "__main__":
unit_testing.setup_for_tests()
Expand Down
Loading