clm5/python/ctsm/test/test_unit_path_utils.py
2024-05-09 15:14:01 +08:00

151 lines
5.5 KiB
Python

#!/usr/bin/env python3
"""Unit tests for path_utils
"""
import unittest
import tempfile
import shutil
import os
import six
from six_additions import mock
from ctsm import unit_testing
from ctsm import path_utils
# Allow names that pylint doesn't like, because otherwise I find it hard
# to make readable unit test names
# pylint: disable=invalid-name
class TestPathUtils(unittest.TestCase):
"""Tests of path_utils"""
def setUp(self):
self._previous_dir = os.getcwd()
self._testdir = tempfile.mkdtemp()
def tearDown(self):
os.chdir(self._previous_dir)
shutil.rmtree(self._testdir, ignore_errors=True)
def _ctsm_path_in_cesm(self):
"""Returns the path to a ctsm directory nested inside a typical cesm
directory structure, where self._testdir is the root of the cesm
checkout
"""
return os.path.join(self._testdir, "components", "clm")
def _cime_path_in_cesm(self):
"""Returns the path to a cime directory nested inside a typical
cesm directory structure, where self._testdir is the root of the
cesm checkout
"""
return os.path.join(self._testdir, "cime")
def _make_cesm_dirs(self):
"""Makes a directory structure for a typical CESM layout, where
self._testdir is the root of the CESM checkout.
This makes the ctsm directory and the cime directory.
Returns a tuple, (ctsm_path, cime_path)
"""
ctsm_path = self._ctsm_path_in_cesm()
cime_path = self._cime_path_in_cesm()
os.makedirs(ctsm_path)
os.makedirs(cime_path)
return (ctsm_path, cime_path)
def test_pathToCime_standaloneOnlyWithCime(self):
"""Test path_to_cime with standalone_only, where cime is in the location
it should be with a standalone checkout
"""
ctsm_path = os.path.join(self._testdir, "ctsm")
actual_path_to_cime = os.path.join(ctsm_path, "cime")
os.makedirs(actual_path_to_cime)
with mock.patch("ctsm.path_utils.path_to_ctsm_root", return_value=ctsm_path):
path_to_cime = path_utils.path_to_cime(standalone_only=True)
self.assertEqual(path_to_cime, actual_path_to_cime)
def test_pathToCime_standaloneOnlyWithoutCime(self):
"""Test path_to_cime with standalone_only, where cime is missing"""
ctsm_path = os.path.join(self._testdir, "ctsm")
os.makedirs(ctsm_path)
with mock.patch("ctsm.path_utils.path_to_ctsm_root", return_value=ctsm_path):
with six.assertRaisesRegex(self, RuntimeError, "Cannot find cime"):
_ = path_utils.path_to_cime(standalone_only=True)
def test_pathToCime_standaloneOnlyWithCimeInCesm(self):
"""Test path_to_cime with standalone_only, where cime is missing from
the standalone structure, but cime is present in the CESM
directory structure: should raise an exception rather than
finding that cime
"""
ctsm_path, _ = self._make_cesm_dirs()
with mock.patch("ctsm.path_utils.path_to_ctsm_root", return_value=ctsm_path):
with six.assertRaisesRegex(self, RuntimeError, "Cannot find cime"):
_ = path_utils.path_to_cime(standalone_only=True)
def test_pathToCime_cimeInCesm(self):
"""Test path_to_cime, where cime is not in the standalone directory but
is present in the CESM directory structure
"""
ctsm_path, actual_path_to_cime = self._make_cesm_dirs()
with mock.patch("ctsm.path_utils.path_to_ctsm_root", return_value=ctsm_path):
path_to_cime = path_utils.path_to_cime()
self.assertEqual(path_to_cime, actual_path_to_cime)
def test_pathToCime_notInCesmCheckout(self):
"""Test path_to_cime, where cime is not in the standalone directory, and
we don't appear to be in a CESM checkout
"""
ctsm_path = os.path.join(self._testdir, "components", "foo")
os.makedirs(ctsm_path)
os.makedirs(self._cime_path_in_cesm())
with mock.patch("ctsm.path_utils.path_to_ctsm_root", return_value=ctsm_path):
with six.assertRaisesRegex(
self,
RuntimeError,
"Cannot find cime.*don't seem to be within a CESM checkout",
):
_ = path_utils.path_to_cime()
def test_pathToCime_noCimeInCesm(self):
"""Test path_to_cime, where we appear to be within a CESM checkout, but
there is no cime directory"""
ctsm_path = self._ctsm_path_in_cesm()
os.makedirs(ctsm_path)
with mock.patch("ctsm.path_utils.path_to_ctsm_root", return_value=ctsm_path):
with six.assertRaisesRegex(
self, RuntimeError, "Cannot find cime.*or within CESM checkout"
):
_ = path_utils.path_to_cime()
def test_pathToCime_cimeInStandaloneAndCesm(self):
"""Test path_to_cime, where there is a cime directory both in the
standalone checkout and in the enclosing CESM checkout. Should
give us the cime in the standalone checkout.
"""
ctsm_path, _ = self._make_cesm_dirs()
actual_path_to_cime = os.path.join(ctsm_path, "cime")
os.makedirs(actual_path_to_cime)
with mock.patch("ctsm.path_utils.path_to_ctsm_root", return_value=ctsm_path):
path_to_cime = path_utils.path_to_cime()
self.assertEqual(path_to_cime, actual_path_to_cime)
if __name__ == "__main__":
unit_testing.setup_for_tests()
unittest.main()