Skip to content
Snippets Groups Projects

Remove cmd

Merged Ashwin Kumar Karnad requested to merge continue-with-remove-cmd into main
1 file
+ 13
0
Compare changes
  • Side-by-side
  • Inline
+ 231
32
"""Tests for mpsd-software-environment.py."""
"""Tests for mpsd-software-environment.py."""
 
import copy
 
import datetime
import importlib
import importlib
 
import logging
import os
import os
import shutil
import shutil
import subprocess
import subprocess
from pathlib import Path
import logging
import datetime
import sys
import sys
 
from pathlib import Path
import pytest
import pytest
 
import yaml
mod = importlib.import_module("mpsd_software_manager.mpsd_software")
mod = importlib.import_module("mpsd_software_manager.mpsd_software")
@@ -256,7 +258,7 @@ def test_install_environment_zlib():
@@ -256,7 +258,7 @@ def test_install_environment_zlib():
with open(
with open(
package_set_src_dir / "global_generic" / "global_packages.list", "w"
package_set_src_dir / "global_generic" / "global_packages.list", "w"
) as f:
) 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
# add zlib to whitelist of module creation file by replacing anaconda3%gcc@10.2.1
# with zlib@1.2.13
# with zlib@1.2.13
@@ -487,8 +489,11 @@ def create_fake_environment(tmp_path, mpsd_release, expected_toolchain_map=None)
@@ -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)
toolchain_lmod_folder.mkdir(parents=True, exist_ok=True)
spack_folder = tmp_path / mpsd_release / microarch / "spack"
spack_folder = tmp_path / mpsd_release / microarch / "spack"
spack_folder.mkdir(parents=True, exist_ok=True)
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.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]:
for toolchain in expected_toolchain_map[microarch]:
toolchain_lua_file = toolchain_lmod_folder / f"{toolchain}.lua"
toolchain_lua_file = toolchain_lmod_folder / f"{toolchain}.lua"
toolchain_lua_file.touch()
toolchain_lua_file.touch()
@@ -509,33 +514,6 @@ def test_environment_status(tmp_path):
@@ -509,33 +514,6 @@ def test_environment_status(tmp_path):
assert set(toolchain_map[microarch]) == set(expected_toolchain_map[microarch])
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):
def test_initialise_environment(tmp_path):
"""Test that init_file is created as expected."""
"""Test that init_file is created as expected."""
# test that the 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):
@@ -675,6 +653,227 @@ def test_argument_parsing_logic(mocker):
### Copy from 'install' when the time has come.)
### 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):
def test_interface(tmp_path):
"""Test other things (not implemented yet)."""
"""Test other things (not implemented yet)."""
pass
pass
Loading