Skip to content

Commit

Permalink
Remove clone step from cice setup tests
Browse files Browse the repository at this point in the history
  • Loading branch information
blimlim committed Sep 13, 2024
1 parent 10f5122 commit 58bf7d3
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 321 deletions.
304 changes: 122 additions & 182 deletions test/models/test_cice.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,11 @@
import f90nml

import payu
from payu.branch import clone
import git


from test.common import cd
from test.common import tmpdir, ctrldir, labdir, expt_workdir
from test.common import expt_archive_dir, ctrldir_basename
from test.common import write_config, write_metadata
from test.common import workdir, expt_archive_dir, ctrldir_basename
from test.common import write_config, config_path, write_metadata
from test.common import make_exe

verbose = True
Expand Down Expand Up @@ -65,16 +62,6 @@ def setup_module(module):
except Exception as e:
print(e)

config = {
"laboratory": "lab",
"jobname": "testrun",
"model": "cice",
"exe": "test.exe",
"experiment": ctrldir_basename,
"metadata": {"enable": False}
}
write_config(config)


def teardown_module(module):
"""
Expand All @@ -90,16 +77,55 @@ def teardown_module(module):
print(e)


DEFAULT_CONFIG = {
"laboratory": "lab",
"jobname": "testrun",
"model": "cice",
"exe": "test.exe",
"experiment": ctrldir_basename,
"metadata": {"enable": False}
}
RESTART_PATH = expt_archive_dir / "restartXYZ"

CONFIG_WITH_RESTART = {
"laboratory": "lab",
"jobname": "testrun",
"model": "cice",
"exe": "test.exe",
"experiment": ctrldir_basename,
"metadata": {"enable": False},
"restart": str(RESTART_PATH)
}


@pytest.fixture
def config(request):
"""
Write a specified dictionary to config.yaml.
Used to allow writing configs with and without
restarts.
"""
config = request.param
write_config(config, config_path)

yield config_path

os.remove(config_path)


@pytest.fixture(autouse=True)
def empty_workdir():
"""
Tests involving cloning + specified restarts require
a clean work directory
Model setup tests require a clean work directory and symlink from
the control directory.
"""
expt_workdir.mkdir(parents=True)
# Symlink must exist for setup to use correct locations
workdir.symlink_to(expt_workdir)

yield expt_workdir
shutil.rmtree(expt_workdir)
workdir.unlink()


# Important to test None case without separate ice history file
Expand Down Expand Up @@ -131,7 +157,9 @@ def cice_config_files(request):
os.remove(HIST_NML_NAME)


def test_setup(cice_config_files):
@pytest.mark.parametrize("config", [DEFAULT_CONFIG],
indirect=True)
def test_setup(config, cice_config_files):
"""
Confirm that
1: payu overwrites cice_in with ice_history
Expand Down Expand Up @@ -167,186 +195,98 @@ def test_setup(cice_config_files):
input_nml["setup_nml"]["dump_last"]


def test_no_restart_ptr(cice_config_files):
PREVIOUS_ISTEP0 = 0
PREVIOUS_NPT = 8760 # 1 year of 1hr timesteps


@pytest.fixture
def prior_restart_dir_cice4():
"""
Test that payu raises an error if no prior restart path is specified,
restart is `true` in cice_in.nml, and the restart pointer is missing.
Create fake prior restart files required by CICE4's setup.
This differs from CICE5, which doesn't require a cice_in.nml
file in the restart directory.
"""
cice_in_patch = {"setup_nml": {"restart": True}}
with cd(ctrldir):
cice_in_default = f90nml.read(CICE_NML_NAME)
cice_in_default.patch(cice_in_patch)
cice_in_default.write(CICE_NML_NAME, force=True)
prior_restart_path = RESTART_PATH
os.mkdir(prior_restart_path)

with cd(ctrldir):
lab = payu.laboratory.Laboratory(lab_path=str(labdir))
expt = payu.experiment.Experiment(lab, reproduce=False)
model = expt.models[0]
# Previous cice_in namelist with time information
restart_cice_in = {"setup_nml": {
"istep0": PREVIOUS_ISTEP0,
"npt": PREVIOUS_NPT,
"dt": DEFAULT_DT
}}
f90nml.write(restart_cice_in, prior_restart_path/CICE_NML_NAME)

# Function to test
with pytest.raises(RuntimeError):
model.setup()
# Additional restart files required by CICE4 setup
(prior_restart_path/ICED_RESTART_NAME).touch()
(prior_restart_path/RESTART_POINTER_NAME).touch()

yield prior_restart_path

class TestClone:
"""
Test setting up the cice model in cloned control directories.
"""
PREVIOUS_ISTEP0 = 0
PREVIOUS_NPT = 8760 # 1 year of 1hr timesteps

@pytest.fixture
def prior_restart_dir_cice4(self, scope="class"):
"""
Create fake prior restart files required by CICE4's setup.
This differs from CICE5, which doesn't require a cice_in.nml
file in the restart directory.
"""
prior_restart_path = expt_archive_dir / "restartxyz"
os.mkdir(prior_restart_path)

# Previous cice_in namelist with time information
restart_cice_in = {"setup_nml": {
"istep0": self.PREVIOUS_ISTEP0,
"npt": self.PREVIOUS_NPT,
"dt": DEFAULT_DT
}}
f90nml.write(restart_cice_in, prior_restart_path/CICE_NML_NAME)

# Additional restart files required by CICE4 setup
(prior_restart_path/ICED_RESTART_NAME).touch()
(prior_restart_path/RESTART_POINTER_NAME).touch()

yield prior_restart_path

# Teardown
shutil.rmtree(prior_restart_path)

@pytest.fixture
def ctrldir_repo(self, cice_config_files):
"""
Initialise a git repository in the control directory.
"""
repo = git.Repo.init(ctrldir)
repo.index.add("*")

# Commit the changes
repo.index.commit("First commit - initialising repository")

yield repo

# Remove git from control dir after tests
git.rmtree(ctrldir/".git")

@pytest.fixture
def clone_control_dir(self, ctrldir_repo):
"""
Yield function for cloning the control directory. Cloning
is not done directly in fixture to allow for an optional
restart path to be supplied.
"""
cloned_repo_path = tmpdir / "clonedRepo"

def _clone_control_dir(restart_path=None):
clone(str(ctrldir),
cloned_repo_path,
lab_path=labdir,
restart_path=restart_path)
return cloned_repo_path

yield _clone_control_dir

# Teardown: Delete the cloned repository
try:
git.rmtree(cloned_repo_path)
except FileNotFoundError:
# Cloned repo won't exist if yielded function not called
pass

def test_clone(self, cice_config_files, ctrldir_repo,
clone_control_dir):
"""
Test that setting up cice from a cloned control directory works.
"""
source_main = str(ctrldir_repo.active_branch)

# Clone control directory
cloned_repo_path = clone_control_dir(restart_path=None)
cloned_repo = git.Repo(cloned_repo_path)
cloned_repo.git.checkout(source_main)

cloned_ctrl_dir_files = os.listdir(cloned_repo_path)
assert CICE_NML_NAME in cloned_ctrl_dir_files

if cice_config_files['ice_history']:
assert HIST_NML_NAME in cloned_ctrl_dir_files

# Set up experiment
with cd(cloned_repo_path):
lab = payu.laboratory.Laboratory(lab_path=str(labdir))
expt = payu.experiment.Experiment(lab, reproduce=False)
model = expt.models[0]

# Test that model setup runs without issue
model.setup()
# Teardown
shutil.rmtree(prior_restart_path)

work_path_files = os.listdir(model.work_path)
assert CICE_NML_NAME in work_path_files

def test_restart_clone(self, cice_config_files, ctrldir_repo,
clone_control_dir, prior_restart_dir_cice4):
"""
Test that seting up an experiment from a cloned control directory
works when a restart directory is specified.
@pytest.mark.parametrize("config", [CONFIG_WITH_RESTART],
indirect=True)
def test_restart_setup(config, cice_config_files, prior_restart_dir_cice4):
"""
Test that seting up an experiment from a cloned control directory
works when a restart directory is specified.
Use a restart directory mimicking the CICE4 files required by setup.
"""
source_main = str(ctrldir_repo.active_branch)
Use a restart directory mimicking the CICE4 files required by setup.
"""

# Clone control directory
cloned_repo_path = clone_control_dir(
restart_path=prior_restart_dir_cice4
)
cloned_repo = git.Repo(cloned_repo_path)
cloned_repo.git.checkout(source_main)
# Setup experiment
with cd(ctrldir):
lab = payu.laboratory.Laboratory(lab_path=str(labdir))
expt = payu.experiment.Experiment(lab, reproduce=False)

cloned_ctrl_dir_files = os.listdir(cloned_repo_path)
# Add a runtime to test calculated cice runtime values
expt.runtime = {"years": 0,
"months": 0,
"days": 2}
model = expt.models[0]

assert CICE_NML_NAME in cloned_ctrl_dir_files
if cice_config_files['ice_history']:
assert HIST_NML_NAME in cloned_ctrl_dir_files
# Function to test
model.setup()

# Setup experiment
with cd(cloned_repo_path):
lab = payu.laboratory.Laboratory(lab_path=str(labdir))
expt = payu.experiment.Experiment(lab, reproduce=False)
# Check correct run time values written to work namelist
work_cice_nml = f90nml.read(
os.path.join(model.work_path, CICE_NML_NAME)
)
assert work_cice_nml["setup_nml"]["istep0"] == (
PREVIOUS_ISTEP0 + PREVIOUS_NPT
)
assert work_cice_nml["setup_nml"]["npt"] == (
48
)

# Add a runtime to test calculated cice runtime values
expt.runtime = {"years": 0,
"months": 0,
"days": 2}
model = expt.models[0]
# Check restart files were copied to work directory.
cice_work_restart_files = os.listdir(model.work_restart_path)

# Test that model setup runs without issue
model.setup()
for file in [CICE_NML_NAME, ICED_RESTART_NAME, RESTART_POINTER_NAME]:
assert file in cice_work_restart_files

work_path_files = os.listdir(model.work_path)
assert CICE_NML_NAME in work_path_files

# Check correct run time values written to work namelist
work_cice_nml = f90nml.read(
os.path.join(model.work_path, CICE_NML_NAME)
)
assert work_cice_nml["setup_nml"]["istep0"] == (
self.PREVIOUS_ISTEP0 + self.PREVIOUS_NPT
)
assert work_cice_nml["setup_nml"]["npt"] == (
48
)
@pytest.mark.parametrize("config", [DEFAULT_CONFIG],
indirect=True)
def test_no_restart_ptr(config, cice_config_files):
"""
Test that payu raises an error if no prior restart path is specified,
restart is `true` in cice_in.nml, and the restart pointer is missing.
"""
cice_in_patch = {"setup_nml": {"restart": True}}
with cd(ctrldir):
cice_in_default = f90nml.read(CICE_NML_NAME)
cice_in_default.patch(cice_in_patch)
cice_in_default.write(CICE_NML_NAME, force=True)

# Check restart files were copied to cloned experiment's
# work directory.
cice_work_restart_files = os.listdir(model.work_restart_path)
with cd(ctrldir):
lab = payu.laboratory.Laboratory(lab_path=str(labdir))
expt = payu.experiment.Experiment(lab, reproduce=False)
model = expt.models[0]

for file in [CICE_NML_NAME, ICED_RESTART_NAME, RESTART_POINTER_NAME]:
assert file in cice_work_restart_files
# Function to test
with pytest.raises(RuntimeError):
model.setup()
Loading

0 comments on commit 58bf7d3

Please sign in to comment.