From 120c3429e2bd3c34570a43d6b3d35fca19f16b6a Mon Sep 17 00:00:00 2001 From: iamashwin99 <ashwin-kumar.karnad@mpsd.mpg.de> Date: Fri, 4 Aug 2023 14:06:26 +0200 Subject: [PATCH] add tests for remove command - removed the old test_remove_environment - modified the create_fake_environment to current specs - add tests for removing package_sets and releases --- tests/test_mpsd_software.py | 188 +++++++++++++++++++++++++++--------- 1 file changed, 144 insertions(+), 44 deletions(-) diff --git a/tests/test_mpsd_software.py b/tests/test_mpsd_software.py index 2813417..f7ca722 100644 --- a/tests/test_mpsd_software.py +++ b/tests/test_mpsd_software.py @@ -8,8 +8,9 @@ from pathlib import Path import logging import datetime import sys - +import yaml import pytest +import copy mod = importlib.import_module("mpsd_software_manager.mpsd_software") @@ -468,8 +469,9 @@ def create_fake_environment(tmp_path, mpsd_release, expected_toolchain_map=None) toolchain_lmod_folder.mkdir(parents=True, exist_ok=True) spack_folder = tmp_path / mpsd_release / microarch / "spack" spack_folder.mkdir(parents=True, exist_ok=True) - logs_folder = tmp_path / mpsd_release / microarch / "logs" + logs_folder = tmp_path / mpsd_release / "logs" logs_folder.mkdir(parents=True, exist_ok=True) + (logs_folder / "test.log").touch() for toolchain in expected_toolchain_map[microarch]: toolchain_lua_file = toolchain_lmod_folder / f"{toolchain}.lua" toolchain_lua_file.touch() @@ -477,48 +479,6 @@ def create_fake_environment(tmp_path, mpsd_release, expected_toolchain_map=None) return expected_toolchain_map -def test_environment_status(tmp_path): - """Test that the environment status is correct.""" - toolchain_map = mod.environment_status("fake-release", tmp_path) - assert toolchain_map is None - mpsd_release = "dev-23a" - expected_toolchain_map = create_fake_environment(tmp_path, mpsd_release) - # check that the environment statuxis is correct - toolchain_map = mod.environment_status(mpsd_release, tmp_path) - # convert each list to a set to ensure that the order doesn't matter - for microarch in expected_toolchain_map.keys(): - assert set(toolchain_map[microarch]) == set(expected_toolchain_map[microarch]) - - -def test_remove_environment(tmp_path): - """Test that the remove_environment works as expected.""" - mpsd_release = "dev-23a" - # create a fake environment - create_fake_environment(tmp_path, mpsd_release) - # check that the environment status is correct - toolchain_map = mod.environment_status(mpsd_release, tmp_path) - assert toolchain_map is not None - - # test removal without arguments (should sys.exit(1)) - create_fake_environment(tmp_path, mpsd_release) - with pytest.raises(SystemExit) as pytest_wrapped_e: - mod.remove_environment(mpsd_release, tmp_path, force_remove=True) - assert pytest_wrapped_e.type == SystemExit - assert pytest_wrapped_e.value.code == 1 - - # test removal of the complete environment - create_fake_environment(tmp_path, mpsd_release) - mod.remove_environment(mpsd_release, tmp_path, ["ALL"], force_remove=True) - toolchain_map = mod.environment_status(mpsd_release, tmp_path) - assert toolchain_map is None - # ensure that logs folder remains - logs_folder = tmp_path / mpsd_release / mod.get_native_microarchitecture() / "logs" - assert logs_folder.exists() - - # test removal of a single toolchain - # done in test_install_environment_zlib - - def test_initialise_environment(tmp_path): """Test that init_file is created as expected.""" # test that the init file is created as expected @@ -658,6 +618,146 @@ def test_argument_parsing_logic(mocker): ### Copy from 'install' when the time has come.) +def test_remove_environment(tmp_path, mocker): + """Test that the remove_environment function works as expected.""" + + release_to_test = "dev-23a" + + # check exit 50 when no package_sets are provided + with pytest.raises(SystemExit) as pytest_wrapped_e: + mod.remove_environment("dev-23a", tmp_path) + assert pytest_wrapped_e.type == SystemExit + assert pytest_wrapped_e.value.code == 50 + + # Test case2 - remove entire release + ## exit with 60 when force is not set + ### patch the input function to return 'n' + mocker.patch("builtins.input", return_value="n") + with pytest.raises(SystemExit) as pytest_wrapped_e: + mod.remove_environment(release_to_test, tmp_path, "ALL") + assert pytest_wrapped_e.type == SystemExit + assert pytest_wrapped_e.value.code == 60 + ### patch the input function to return 'y' + mocker.patch("builtins.input", return_value="y") + # check that the release directory is removed and logs are kept + # create a release directory + create_fake_environment(tmp_path, release_to_test) + release_dir = tmp_path / release_to_test / mod.get_native_microarchitecture() + logs_dir = tmp_path / release_to_test / "logs" + + toolchain_map = mod.environment_status(release_to_test, tmp_path) + assert toolchain_map is not None + mod.remove_environment(release_to_test, tmp_path, "ALL") + + toolchain_map = mod.environment_status(release_to_test, tmp_path) + # check that no toolchain remains + assert toolchain_map is None + # check that the release directory is empty + assert len(list(release_dir.iterdir())) == 0 + # check that the logs directory is non-empty + assert len(list(logs_dir.iterdir())) == 1 + + # Test case3 - remove specific package_sets + # defined in test_remove_package_sets + + +@pytest.fixture +def simple_toolchain(): + """returns a dict for a simple toolchain""" + dict = { + "spack": { + "specs": ["zlib@1.2.13"], + "view": True, + "concretizer": {"reuse": False, "unify": True}, + } + } + return dict + + +def install_test_release(tmp_path, simple_toolchain): + """Install a test release + + with toolchain1 and toolchain2 to use for testing. + """ + + release_to_test = "dev-23a" + # prepare a release directory + mod.prepare_environment(mpsd_release=release_to_test, root_dir=tmp_path) + + tmp_path / release_to_test / mod.get_native_microarchitecture() + spe_dir = tmp_path / release_to_test / "spack-environments" + + # create sample toolchains + simple_toolchain_string = yaml.dump(simple_toolchain) + simple_toolchain_2 = copy.deepcopy(simple_toolchain) + simple_toolchain_2["spack"]["specs"] = ["zlib@1.2.13", "zstd@1.5.2"] + simple_toolchain2_string = yaml.dump(simple_toolchain_2) + toolchain1_dir = spe_dir / "toolchains" / "toolchain1" + toolchain2_dir = spe_dir / "toolchains" / "toolchain2" + toolchain1_dir.mkdir(parents=True) + toolchain2_dir.mkdir(parents=True) + (toolchain1_dir / "spack.yaml").write_text(simple_toolchain_string) + (toolchain2_dir / "spack.yaml").write_text(simple_toolchain2_string) + + # install the release + mod.install_environment( + mpsd_release=release_to_test, + package_sets=["toolchain1", "toolchain2"], + root_dir=tmp_path, + ) + + +def test_remove_package_sets(tmp_path, simple_toolchain): + """Test removal of package_sets via spack.""" + + release_to_test = "dev-23a" + + # Case1 - remove global / global_generic package_sets + + # Case2 - remove specific package_sets (toolchains) + # Create a test install + install_test_release(tmp_path, simple_toolchain) + # check that the installation went through + release_dir = tmp_path / release_to_test / mod.get_native_microarchitecture() + assert len(list(release_dir.iterdir())) == 2 # spack and lmod + # check that the two toolchains are installed + assert ( + len(list((release_dir / "spack" / "var" / "spack" / "environments").iterdir())) + == 2 + ) + + # remove toolchain2 + # toolchain1 contains - zlib@1.2 + # toolchain2 contains - zlib@1.2 and zstd@1.5 + # we check that removing toolchain2 removes zstd@1.5 but NOT zlib@1.2 + # and the environment toolchain2 is also removed + + mod.remove_environment( + mpsd_release=release_to_test, + root_dir=tmp_path, + package_sets=["toolchain2"], + force_remove=True, + ) + # now check that only toolchain1 is installed + assert ( + len(list((release_dir / "spack" / "var" / "spack" / "environments").iterdir())) + == 1 + ) + # check that zlib@1.2 is still installed + # spack location -i <package> exit 0 if installed and 1 if not installed + source_spack = ( + f'source {release_dir / "spack" / "share" / "spack" / "setup-env.sh"}' + ) + mod.run(f"{source_spack} && spack location -i zlib", shell=True, check=True) + # check that zstd@1.5 is not installed + # we are here flipping the exit code to check that it is not installed + mod.run( + f"{source_spack} && (spack location -i zstd && exit 1 || exit 0 )", + shell=True, + check=True, + ) + + def test_interface(tmp_path): """Test other things (not implemented yet).""" pass -- GitLab