304 lines
12 KiB
Python
304 lines
12 KiB
Python
#!/usr/bin/env python3
|
|
|
|
"""Unit tests for lilac_build_ctsm
|
|
"""
|
|
|
|
import unittest
|
|
from unittest.mock import patch
|
|
from io import StringIO
|
|
|
|
from ctsm import unit_testing
|
|
from ctsm.lilac_build_ctsm import _commandline_args, _check_and_transform_os
|
|
|
|
# Allow names that pylint doesn't like, because otherwise I find it hard
|
|
# to make readable unit test names
|
|
# pylint: disable=invalid-name
|
|
|
|
# pylint: disable=line-too-long
|
|
|
|
|
|
class TestBuildCtsm(unittest.TestCase):
|
|
"""Tests of lilac_build_ctsm"""
|
|
|
|
# ------------------------------------------------------------------------
|
|
# Tests of _commandline_args
|
|
# ------------------------------------------------------------------------
|
|
|
|
def test_commandlineArgs_rebuild_valid(self):
|
|
"""Test _commandline_args with --rebuild, with a valid argument list (no disallowed args)"""
|
|
# pylint: disable=no-self-use
|
|
_ = _commandline_args(args_to_parse=["build/directory", "--rebuild"])
|
|
|
|
@patch("sys.stderr", new_callable=StringIO)
|
|
def test_commandlineArgs_rebuild_invalid1(self, mock_stderr):
|
|
"""Test _commandline_args with --rebuild, with an argument that is invalid with this option
|
|
|
|
This tests an argument that is required for non-rebuilds, without a dash
|
|
"""
|
|
expected_re = r"--compiler cannot be provided if --rebuild is set"
|
|
with self.assertRaises(SystemExit):
|
|
_ = _commandline_args(
|
|
args_to_parse=["build/directory", "--rebuild", "--compiler", "intel"]
|
|
)
|
|
self.assertRegex(mock_stderr.getvalue(), expected_re)
|
|
|
|
@patch("sys.stderr", new_callable=StringIO)
|
|
def test_commandlineArgs_rebuild_invalid2(self, mock_stderr):
|
|
"""Test _commandline_args with --rebuild, with an argument that is invalid with this option
|
|
|
|
This tests an argument that is required for new machines, without a dash
|
|
"""
|
|
expected_re = r"--os cannot be provided if --rebuild is set"
|
|
with self.assertRaises(SystemExit):
|
|
_ = _commandline_args(args_to_parse=["build/directory", "--rebuild", "--os", "linux"])
|
|
self.assertRegex(mock_stderr.getvalue(), expected_re)
|
|
|
|
@patch("sys.stderr", new_callable=StringIO)
|
|
def test_commandlineArgs_rebuild_invalid3(self, mock_stderr):
|
|
"""Test _commandline_args with --rebuild, with an argument that is invalid with this option
|
|
|
|
This tests an argument that is required for new machines, with a dash
|
|
"""
|
|
expected_re = r"--netcdf-path cannot be provided if --rebuild is set"
|
|
with self.assertRaises(SystemExit):
|
|
_ = _commandline_args(
|
|
args_to_parse=[
|
|
"build/directory",
|
|
"--rebuild",
|
|
"--netcdf-path",
|
|
"/path/to/netcdf",
|
|
]
|
|
)
|
|
self.assertRegex(mock_stderr.getvalue(), expected_re)
|
|
|
|
@patch("sys.stderr", new_callable=StringIO)
|
|
def test_commandlineArgs_rebuild_invalid4(self, mock_stderr):
|
|
"""Test _commandline_args with --rebuild, with an argument that is invalid with this option
|
|
|
|
This tests an argument that is optional for new non-rebuild
|
|
that isn't None
|
|
"""
|
|
expected_re = r"--no-build cannot be provided if --rebuild is set"
|
|
with self.assertRaises(SystemExit):
|
|
_ = _commandline_args(args_to_parse=["build/directory", "--rebuild", "--no-build"])
|
|
self.assertRegex(mock_stderr.getvalue(), expected_re)
|
|
|
|
@patch("sys.stderr", new_callable=StringIO)
|
|
def test_commandlineArgs_rebuild_invalid5(self, mock_stderr):
|
|
"""Test _commandline_args with --rebuild, with an argument that is invalid with this option
|
|
|
|
This tests an argument that is optional for new machines, which also has a default
|
|
that isn't None
|
|
"""
|
|
expected_re = r"--gmake cannot be provided if --rebuild is set"
|
|
with self.assertRaises(SystemExit):
|
|
_ = _commandline_args(
|
|
args_to_parse=["build/directory", "--rebuild", "--gmake", "mymake"]
|
|
)
|
|
self.assertRegex(mock_stderr.getvalue(), expected_re)
|
|
|
|
def test_commandlineArgs_noRebuild_valid(self):
|
|
"""Test _commandline_args without --rebuild or --machine, with a valid argument list
|
|
|
|
(all required things present)
|
|
"""
|
|
# pylint: disable=no-self-use
|
|
_ = _commandline_args(
|
|
args_to_parse=[
|
|
"build/directory",
|
|
"--os",
|
|
"linux",
|
|
"--compiler",
|
|
"intel",
|
|
"--netcdf-path",
|
|
"/path/to/netcdf",
|
|
"--esmf-mkfile-path",
|
|
"/path/to/esmf/lib/esmf.mk",
|
|
"--max-mpitasks-per-node",
|
|
"16",
|
|
"--no-pnetcdf",
|
|
]
|
|
)
|
|
|
|
@patch("sys.stderr", new_callable=StringIO)
|
|
def test_commandlineArgs_noRebuild_invalid1(self, mock_stderr):
|
|
"""Test _commandline_args without --rebuild or --machine, with a missing required argument
|
|
|
|
This tests an argument in the non-rebuild-required list
|
|
"""
|
|
expected_re = r"--compiler must be provided if --rebuild is not set"
|
|
with self.assertRaises(SystemExit):
|
|
_ = _commandline_args(
|
|
args_to_parse=[
|
|
"build/directory",
|
|
"--os",
|
|
"linux",
|
|
"--netcdf-path",
|
|
"/path/to/netcdf",
|
|
"--esmf-mkfile-path",
|
|
"/path/to/esmf/lib/esmf.mk",
|
|
"--max-mpitasks-per-node",
|
|
"16",
|
|
"--no-pnetcdf",
|
|
]
|
|
)
|
|
self.assertRegex(mock_stderr.getvalue(), expected_re)
|
|
|
|
@patch("sys.stderr", new_callable=StringIO)
|
|
def test_commandlineArgs_noRebuild_invalid2(self, mock_stderr):
|
|
"""Test _commandline_args without --rebuild or --machine, with a missing required argument
|
|
|
|
This tests an argument in the new-machine-required list
|
|
"""
|
|
expected_re = r"--os must be provided if neither --machine nor --rebuild are set"
|
|
with self.assertRaises(SystemExit):
|
|
_ = _commandline_args(
|
|
args_to_parse=[
|
|
"build/directory",
|
|
"--compiler",
|
|
"intel",
|
|
"--netcdf-path",
|
|
"/path/to/netcdf",
|
|
"--esmf-mkfile-path",
|
|
"/path/to/esmf/lib/esmf.mk",
|
|
"--max-mpitasks-per-node",
|
|
"16",
|
|
"--no-pnetcdf",
|
|
]
|
|
)
|
|
self.assertRegex(mock_stderr.getvalue(), expected_re)
|
|
|
|
@patch("sys.stderr", new_callable=StringIO)
|
|
def test_commandlineArgs_noRebuild_invalidNeedToDictatePnetcdf(self, mock_stderr):
|
|
"""Test _commandline_args without --rebuild or --machine: invalid b/c nothing specified for pnetcdf"""
|
|
expected_re = (
|
|
r"For a user-defined machine, need to specify either --no-pnetcdf or --pnetcdf-path"
|
|
)
|
|
with self.assertRaises(SystemExit):
|
|
_ = _commandline_args(
|
|
args_to_parse=[
|
|
"build/directory",
|
|
"--os",
|
|
"linux",
|
|
"--compiler",
|
|
"intel",
|
|
"--netcdf-path",
|
|
"/path/to/netcdf",
|
|
"--esmf-mkfile-path",
|
|
"/path/to/esmf/lib/esmf.mk",
|
|
"--max-mpitasks-per-node",
|
|
"16",
|
|
]
|
|
)
|
|
self.assertRegex(mock_stderr.getvalue(), expected_re)
|
|
|
|
@patch("sys.stderr", new_callable=StringIO)
|
|
def test_commandlineArgs_noRebuild_invalidConflictingPnetcdf(self, mock_stderr):
|
|
"""Test _commandline_args without --rebuild or --machine: invalid b/c of conflicting specifications for pnetcdf"""
|
|
expected_re = r"--no-pnetcdf cannot be given if you set --pnetcdf-path"
|
|
with self.assertRaises(SystemExit):
|
|
_ = _commandline_args(
|
|
args_to_parse=[
|
|
"build/directory",
|
|
"--os",
|
|
"linux",
|
|
"--compiler",
|
|
"intel",
|
|
"--netcdf-path",
|
|
"/path/to/netcdf",
|
|
"--esmf-mkfile-path",
|
|
"/path/to/esmf/lib/esmf.mk",
|
|
"--max-mpitasks-per-node",
|
|
"16",
|
|
"--no-pnetcdf",
|
|
"--pnetcdf-path",
|
|
"/path/to/pnetcdf",
|
|
]
|
|
)
|
|
self.assertRegex(mock_stderr.getvalue(), expected_re)
|
|
|
|
def test_commandlineArgs_machine_valid(self):
|
|
"""Test _commandline_args with --machine, with a valid argument list
|
|
|
|
(all required things present)
|
|
"""
|
|
# pylint: disable=no-self-use
|
|
_ = _commandline_args(
|
|
args_to_parse=[
|
|
"build/directory",
|
|
"--machine",
|
|
"mymachine",
|
|
"--compiler",
|
|
"intel",
|
|
]
|
|
)
|
|
|
|
@patch("sys.stderr", new_callable=StringIO)
|
|
def test_commandlineArgs_machine_missingRequired(self, mock_stderr):
|
|
"""Test _commandline_args with --machine, with a missing required argument"""
|
|
expected_re = r"--compiler must be provided if --rebuild is not set"
|
|
with self.assertRaises(SystemExit):
|
|
_ = _commandline_args(args_to_parse=["build/directory", "--machine", "mymachine"])
|
|
self.assertRegex(mock_stderr.getvalue(), expected_re)
|
|
|
|
@patch("sys.stderr", new_callable=StringIO)
|
|
def test_commandlineArgs_machine_illegalArg1(self, mock_stderr):
|
|
"""Test _commandline_args with --rebuild, with an argument that is illegal with this option
|
|
|
|
This tests an argument that is required for new machines
|
|
"""
|
|
expected_re = r"--os cannot be provided if --machine is set"
|
|
with self.assertRaises(SystemExit):
|
|
_ = _commandline_args(
|
|
args_to_parse=[
|
|
"build/directory",
|
|
"--machine",
|
|
"mymachine",
|
|
"--compiler",
|
|
"intel",
|
|
"--os",
|
|
"linux",
|
|
]
|
|
)
|
|
self.assertRegex(mock_stderr.getvalue(), expected_re)
|
|
|
|
@patch("sys.stderr", new_callable=StringIO)
|
|
def test_commandlineArgs_machine_illegalArg2(self, mock_stderr):
|
|
"""Test _commandline_args with --rebuild, with an argument that is illegal with this option
|
|
|
|
This tests an argument that is optional for new machines
|
|
"""
|
|
expected_re = r"--gmake cannot be provided if --machine is set"
|
|
with self.assertRaises(SystemExit):
|
|
_ = _commandline_args(
|
|
args_to_parse=[
|
|
"build/directory",
|
|
"--machine",
|
|
"mymachine",
|
|
"--compiler",
|
|
"intel",
|
|
"--gmake",
|
|
"mymake",
|
|
]
|
|
)
|
|
self.assertRegex(mock_stderr.getvalue(), expected_re)
|
|
|
|
# ------------------------------------------------------------------------
|
|
# Tests of _check_and_transform_os
|
|
# ------------------------------------------------------------------------
|
|
|
|
def test_checkAndTransformOs_valid(self):
|
|
"""Test _check_and_transform_os with valid input"""
|
|
os = _check_and_transform_os("linux")
|
|
self.assertEqual(os, "LINUX")
|
|
|
|
def test_checkAndTransformOs_invalid(self):
|
|
"""Test _check_and_transform_os with invalid input"""
|
|
with self.assertRaises(ValueError):
|
|
_ = _check_and_transform_os("bad_os")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unit_testing.setup_for_tests()
|
|
unittest.main()
|