Skip to content
Snippets Groups Projects

Remove cmd

Merged Ashwin Kumar Karnad requested to merge continue-with-remove-cmd into main
+ 231
32
"""Tests for mpsd-software-environment.py."""
import copy
import datetime
import importlib
import logging
import os
import shutil
import subprocess
from pathlib import Path
import logging
import datetime
import sys
from pathlib import Path
import pytest
import yaml
mod = importlib.import_module("mpsd_software_manager.mpsd_software")
@@ -256,7 +258,7 @@ def test_install_environment_zlib():
with open(
package_set_src_dir / "global_generic" / "global_packages.list", "w"
) as f:
f.write("zlib@1.2.13 \n")
f.write("zlib@1.2.13 \nzstd@1.5.2\n")
# add zlib to whitelist of module creation file by replacing anaconda3%gcc@10.2.1
# with zlib@1.2.13
@@ -487,8 +489,11 @@ 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)
# Simulate the creation of APEX.log
# (which is created by the main function)
(logs_folder / "APEX.log").touch()
for toolchain in expected_toolchain_map[microarch]:
toolchain_lua_file = toolchain_lmod_folder / f"{toolchain}.lua"
toolchain_lua_file.touch()
@@ -509,33 +514,6 @@ def test_environment_status(tmp_path):
assert set(toolchain_map[microarch]) == set(expected_toolchain_map[microarch])
@pytest.mark.skip(reason="not implemented yet")
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):
mod.remove_environment(mpsd_release, tmp_path, force_remove=True)
# test removal of the complete environment
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 / "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
@@ -675,6 +653,227 @@ 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
list_of_logs = list(logs_dir.iterdir())
assert len(list_of_logs) == 2 # APEX + remove_build_log
# check that one of the log has 'remove.log' as part of the name
assert "BUILD_ALL_remove.log" in ",".join([str(x) for x in list_of_logs])
# 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
environments_dir = release_dir / "spack" / "var" / "spack" / "environments"
set([environment.name for environment in environments_dir.iterdir()]) == set(
["toolchain1", "toolchain2"]
)
# check that the two toolchains have the "handmade" module files
toolchains_list = list(mod.environment_status(release_to_test, tmp_path).values())[
0
]
assert set(toolchains_list) == set(["toolchain1", "toolchain2"])
# 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 in environments_dir
assert set([environment.name for environment in environments_dir.iterdir()]) == set(
["toolchain1"]
)
# check that the only one toolchains has the "handmade" module files
toolchains_list = list(mod.environment_status(release_to_test, tmp_path).values())[
0
]
assert set(toolchains_list) == set(["toolchain1"])
# check that zlib@1.2 is still installed
# spack location -i <package> exit 0 if installed and 1 if not installed
source_spack = (
f"export SPACK_ROOT={release_dir} &&"
f'. {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,
)
# check that the logs directory contains a build log for remove cmd
# dev-23a_zen3_2023-08-11T15-55-54_BUILD_toolchain2_remove.log
logs_dir = tmp_path / release_to_test / "logs"
# remove_build_log is the last log file in the list
remove_build_log = sorted(list(logs_dir.iterdir()))[-1]
assert "toolchain2_remove.log" in remove_build_log.name
with open(remove_build_log, "r") as f:
logs = f.read()
assert "==> Will not uninstall zlib@" in logs
assert "==> Successfully removed environment 'toolchain2'" in logs
def test_remove_global_package_sets():
"""Test removal of global package_sets via spack."""
root_dir = Path("/tmp/test_global_generic")
release_to_test = "dev-23a"
if not root_dir.exists():
# we need the sample spack instance with global_generic
# this is already done in test_install_environment_zlib
# so we just need to call it
test_install_environment_zlib()
# check that zlib and zstd are installed
spack_dir = (
root_dir / release_to_test / mod.get_native_microarchitecture() / "spack"
)
source_spack = (
f"export SPACK_ROOT={spack_dir} &&"
f'. {spack_dir / "share" / "spack" / "setup-env.sh"}'
)
# check that zlib is installed
# location commands exits with non zero if not installed thus
# breaking failing test
mod.run(f"{source_spack} && spack location -i zlib", shell=True, check=True)
# check that zstd is installed
mod.run(f"{source_spack} && spack location -i zstd", shell=True, check=True)
# remove global_generic
mod.remove_environment(
mpsd_release=release_to_test,
root_dir=root_dir,
package_sets=["global_generic"],
force_remove=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,
)
# check that zlib is not installed
mod.run(
f"{source_spack} && (spack location -i zlib && exit 1 || exit 0 )",
shell=True,
check=True,
)
# check that the logs directory contains a build log for remove cmd
# dev-23a_zen3_2023-08-11T15-55-54_BUILD_toolchain2_remove.log
logs_dir = root_dir / release_to_test / "logs"
# remove_build_log is the last log file in the list
remove_build_log = sorted(list(logs_dir.iterdir()))[-1]
assert "global_generic_remove.log" in remove_build_log.name
with open(remove_build_log, "r") as f:
logs = f.read()
assert "==> Successfully uninstalled zstd" in logs
assert "==> Successfully uninstalled zlib" in logs
def test_interface(tmp_path):
"""Test other things (not implemented yet)."""
pass
Loading