unit-tests: fix most unit tests to account for the new model
Signed-off-by: Massimiliano Culpo <massimiliano.culpo@gmail.com>
This commit is contained in:
@@ -23,7 +23,7 @@
|
|||||||
from spack.error import SpackError
|
from spack.error import SpackError
|
||||||
|
|
||||||
default_projections = {
|
default_projections = {
|
||||||
"all": "{architecture}/{compiler.name}-{compiler.version}/{name}-{version}-{hash}"
|
"all": "{architecture.platform}/{architecture.target}/{name}-{version}-{hash}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ def build_report_for_package(self, report_dir, package, duration):
|
|||||||
# something went wrong pre-cdash "configure" phase b/c we have an exception and only
|
# something went wrong pre-cdash "configure" phase b/c we have an exception and only
|
||||||
# "update" was encounterd.
|
# "update" was encounterd.
|
||||||
# dump the report in the configure line so teams can see what the issue is
|
# dump the report in the configure line so teams can see what the issue is
|
||||||
if len(phases_encountered) == 1 and package["exception"]:
|
if len(phases_encountered) == 1 and package.get("exception"):
|
||||||
# TODO this mapping is not ideal since these are pre-configure errors
|
# TODO this mapping is not ideal since these are pre-configure errors
|
||||||
# we need to determine if a more appropriate cdash phase can be utilized
|
# we need to determine if a more appropriate cdash phase can be utilized
|
||||||
# for now we will add a message to the log explaining this
|
# for now we will add a message to the log explaining this
|
||||||
|
|||||||
@@ -392,7 +392,7 @@ def test_spec_needs_rebuild(monkeypatch, tmpdir):
|
|||||||
s = Spec("libdwarf").concretized()
|
s = Spec("libdwarf").concretized()
|
||||||
|
|
||||||
# Install a package
|
# Install a package
|
||||||
install_cmd(s.name)
|
install_cmd("--fake", s.name)
|
||||||
|
|
||||||
# Put installed package in the buildcache
|
# Put installed package in the buildcache
|
||||||
buildcache_cmd("push", "-u", mirror_dir.strpath, s.name)
|
buildcache_cmd("push", "-u", mirror_dir.strpath, s.name)
|
||||||
@@ -421,7 +421,7 @@ def test_generate_index_missing(monkeypatch, tmpdir, mutable_config):
|
|||||||
s = Spec("libdwarf").concretized()
|
s = Spec("libdwarf").concretized()
|
||||||
|
|
||||||
# Install a package
|
# Install a package
|
||||||
install_cmd("--no-cache", s.name)
|
install_cmd("--fake", "--no-cache", s.name)
|
||||||
|
|
||||||
# Create a buildcache and update index
|
# Create a buildcache and update index
|
||||||
buildcache_cmd("push", "-u", mirror_dir.strpath, s.name)
|
buildcache_cmd("push", "-u", mirror_dir.strpath, s.name)
|
||||||
@@ -573,11 +573,8 @@ def test_install_legacy_buildcache_layout(mutable_config, compiler_factory, inst
|
|||||||
where the .spack file contained a repeated spec.json and another
|
where the .spack file contained a repeated spec.json and another
|
||||||
compressed archive file containing the install tree. This test
|
compressed archive file containing the install tree. This test
|
||||||
makes sure we can still read that layout."""
|
makes sure we can still read that layout."""
|
||||||
mutable_config.set(
|
|
||||||
"compilers", [compiler_factory(spec="gcc@4.5.0", operating_system="debian6")]
|
|
||||||
)
|
|
||||||
legacy_layout_dir = os.path.join(test_path, "data", "mirrors", "legacy_layout")
|
legacy_layout_dir = os.path.join(test_path, "data", "mirrors", "legacy_layout")
|
||||||
mirror_url = "file://{0}".format(legacy_layout_dir)
|
mirror_url = f"file://{legacy_layout_dir}"
|
||||||
filename = (
|
filename = (
|
||||||
"test-debian6-core2-gcc-4.5.0-archive-files-2.0-"
|
"test-debian6-core2-gcc-4.5.0-archive-files-2.0-"
|
||||||
"l3vdiqvbobmspwyb4q2b62fz6nitd4hk.spec.json"
|
"l3vdiqvbobmspwyb4q2b62fz6nitd4hk.spec.json"
|
||||||
@@ -586,9 +583,7 @@ def test_install_legacy_buildcache_layout(mutable_config, compiler_factory, inst
|
|||||||
mirror_cmd("add", "--scope", "site", "test-legacy-layout", mirror_url)
|
mirror_cmd("add", "--scope", "site", "test-legacy-layout", mirror_url)
|
||||||
output = install_cmd("--no-check-signature", "--cache-only", "-f", spec_json_path, output=str)
|
output = install_cmd("--no-check-signature", "--cache-only", "-f", spec_json_path, output=str)
|
||||||
mirror_cmd("rm", "--scope=site", "test-legacy-layout")
|
mirror_cmd("rm", "--scope=site", "test-legacy-layout")
|
||||||
expect_line = (
|
expect_line = "Extracting archive-files-2.0-l3vdiqvbobmspwyb4q2b62fz6nitd4hk from binary cache"
|
||||||
"Extracting archive-files-2.0-" "l3vdiqvbobmspwyb4q2b62fz6nitd4hk from binary cache"
|
|
||||||
)
|
|
||||||
assert expect_line in output
|
assert expect_line in output
|
||||||
|
|
||||||
|
|
||||||
@@ -1190,10 +1185,11 @@ def test_get_valid_spec_file_no_json(tmp_path, filename):
|
|||||||
bindist._get_valid_spec_file(str(tmp_path / filename), max_supported_layout=1)
|
bindist._get_valid_spec_file(str(tmp_path / filename), max_supported_layout=1)
|
||||||
|
|
||||||
|
|
||||||
def test_download_tarball_with_unsupported_layout_fails(tmp_path, mutable_config, capsys):
|
def test_download_tarball_with_unsupported_layout_fails(
|
||||||
|
tmp_path, mock_packages, mutable_config, capsys
|
||||||
|
):
|
||||||
layout_version = bindist.CURRENT_BUILD_CACHE_LAYOUT_VERSION + 1
|
layout_version = bindist.CURRENT_BUILD_CACHE_LAYOUT_VERSION + 1
|
||||||
spec = Spec("gmake@4.4.1%gcc@13.1.0 arch=linux-ubuntu23.04-zen2")
|
spec = Spec("pkg-c").concretized()
|
||||||
spec._mark_concrete()
|
|
||||||
spec_dict = spec.to_dict()
|
spec_dict = spec.to_dict()
|
||||||
spec_dict["buildcache_layout_version"] = layout_version
|
spec_dict["buildcache_layout_version"] = layout_version
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
import spack.store
|
import spack.store
|
||||||
import spack.util.path
|
import spack.util.path
|
||||||
|
|
||||||
|
from .conftest import _true
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def active_mock_environment(mutable_config, mutable_mock_env_path):
|
def active_mock_environment(mutable_config, mutable_mock_env_path):
|
||||||
@@ -94,12 +96,14 @@ def test_raising_exception_if_bootstrap_disabled(mutable_config):
|
|||||||
spack.bootstrap.config.store_path()
|
spack.bootstrap.config.store_path()
|
||||||
|
|
||||||
|
|
||||||
def test_raising_exception_module_importable():
|
def test_raising_exception_module_importable(config, monkeypatch):
|
||||||
|
monkeypatch.setattr(spack.bootstrap.core, "source_is_enabled", _true)
|
||||||
with pytest.raises(ImportError, match='cannot bootstrap the "asdf" Python module'):
|
with pytest.raises(ImportError, match='cannot bootstrap the "asdf" Python module'):
|
||||||
spack.bootstrap.core.ensure_module_importable_or_raise("asdf")
|
spack.bootstrap.core.ensure_module_importable_or_raise("asdf")
|
||||||
|
|
||||||
|
|
||||||
def test_raising_exception_executables_in_path():
|
def test_raising_exception_executables_in_path(config, monkeypatch):
|
||||||
|
monkeypatch.setattr(spack.bootstrap.core, "source_is_enabled", _true)
|
||||||
with pytest.raises(RuntimeError, match="cannot bootstrap any of the asdf, fdsa executables"):
|
with pytest.raises(RuntimeError, match="cannot bootstrap any of the asdf, fdsa executables"):
|
||||||
spack.bootstrap.core.ensure_executables_in_path_or_raise(["asdf", "fdsa"], "python")
|
spack.bootstrap.core.ensure_executables_in_path_or_raise(["asdf", "fdsa"], "python")
|
||||||
|
|
||||||
@@ -219,16 +223,12 @@ def test_source_is_disabled(mutable_config):
|
|||||||
# Get the configuration dictionary of the current bootstrapping source
|
# Get the configuration dictionary of the current bootstrapping source
|
||||||
conf = next(iter(spack.bootstrap.core.bootstrapping_sources()))
|
conf = next(iter(spack.bootstrap.core.bootstrapping_sources()))
|
||||||
|
|
||||||
# The source is not explicitly enabled or disabled, so the following
|
# The source is not explicitly enabled or disabled, so the following should return False
|
||||||
# call should raise to skip using it for bootstrapping
|
assert not spack.bootstrap.core.source_is_enabled(conf)
|
||||||
with pytest.raises(ValueError):
|
|
||||||
spack.bootstrap.core.source_is_enabled_or_raise(conf)
|
|
||||||
|
|
||||||
# Try to explicitly disable the source and verify that the behavior
|
# Try to explicitly disable the source and verify that the behavior is the same as above
|
||||||
# is the same as above
|
|
||||||
spack.config.add("bootstrap:trusted:{0}:{1}".format(conf["name"], False))
|
spack.config.add("bootstrap:trusted:{0}:{1}".format(conf["name"], False))
|
||||||
with pytest.raises(ValueError):
|
assert not spack.bootstrap.core.source_is_enabled(conf)
|
||||||
spack.bootstrap.core.source_is_enabled_or_raise(conf)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.regression("45247")
|
@pytest.mark.regression("45247")
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import posixpath
|
import posixpath
|
||||||
import sys
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -15,7 +14,6 @@
|
|||||||
from llnl.util.filesystem import HeaderList, LibraryList
|
from llnl.util.filesystem import HeaderList, LibraryList
|
||||||
|
|
||||||
import spack.build_environment
|
import spack.build_environment
|
||||||
import spack.compiler
|
|
||||||
import spack.compilers
|
import spack.compilers
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.deptypes as dt
|
import spack.deptypes as dt
|
||||||
@@ -97,7 +95,7 @@ def build_environment(working_env):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def ensure_env_variables(config, mock_packages, monkeypatch, working_env):
|
def ensure_env_variables(mutable_config, mock_packages, monkeypatch, working_env):
|
||||||
"""Returns a function that takes a dictionary and updates os.environ
|
"""Returns a function that takes a dictionary and updates os.environ
|
||||||
for the test lifetime accordingly. Plugs-in mock config and repo.
|
for the test lifetime accordingly. Plugs-in mock config and repo.
|
||||||
"""
|
"""
|
||||||
@@ -162,20 +160,24 @@ def test_static_to_shared_library(build_environment):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.regression("8345")
|
@pytest.mark.regression("8345")
|
||||||
@pytest.mark.usefixtures("config", "mock_packages")
|
@pytest.mark.usefixtures("mock_packages")
|
||||||
def test_cc_not_changed_by_modules(monkeypatch, working_env):
|
@pytest.mark.not_on_windows("Module files are not supported on Windows")
|
||||||
s = spack.spec.Spec("cmake")
|
def test_cc_not_changed_by_modules(monkeypatch, mutable_config, working_env, compiler_factory):
|
||||||
s.concretize()
|
"""Tests that external module files that are loaded cannot change the
|
||||||
pkg = s.package
|
CC environment variable.
|
||||||
|
"""
|
||||||
|
gcc_entry = compiler_factory(spec="gcc@14.0.1 languages=c,c++")
|
||||||
|
gcc_entry["modules"] = ["some_module"]
|
||||||
|
mutable_config.set("packages", {"gcc": {"externals": [gcc_entry]}})
|
||||||
|
|
||||||
def _set_wrong_cc(x):
|
def _set_wrong_cc(x):
|
||||||
os.environ["CC"] = "NOT_THIS_PLEASE"
|
os.environ["CC"] = "NOT_THIS_PLEASE"
|
||||||
os.environ["ANOTHER_VAR"] = "THIS_IS_SET"
|
os.environ["ANOTHER_VAR"] = "THIS_IS_SET"
|
||||||
|
|
||||||
monkeypatch.setattr(spack.build_environment, "load_module", _set_wrong_cc)
|
monkeypatch.setattr(spack.build_environment, "load_module", _set_wrong_cc)
|
||||||
monkeypatch.setattr(pkg.compiler, "modules", ["some_module"])
|
|
||||||
|
|
||||||
spack.build_environment.setup_package(pkg, False)
|
s = spack.spec.Spec("cmake %gcc@14").concretized()
|
||||||
|
spack.build_environment.setup_package(s.package, dirty=False)
|
||||||
|
|
||||||
assert os.environ["CC"] != "NOT_THIS_PLEASE"
|
assert os.environ["CC"] != "NOT_THIS_PLEASE"
|
||||||
assert os.environ["ANOTHER_VAR"] == "THIS_IS_SET"
|
assert os.environ["ANOTHER_VAR"] == "THIS_IS_SET"
|
||||||
@@ -186,7 +188,7 @@ def test_setup_dependent_package_inherited_modules(
|
|||||||
):
|
):
|
||||||
# This will raise on regression
|
# This will raise on regression
|
||||||
s = spack.spec.Spec("cmake-client-inheritor").concretized()
|
s = spack.spec.Spec("cmake-client-inheritor").concretized()
|
||||||
PackageInstaller([s.package]).install()
|
PackageInstaller([s.package], fake=True).install()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
@@ -266,22 +268,30 @@ def test_setup_dependent_package_inherited_modules(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_compiler_config_modifications(
|
def test_compiler_config_modifications(
|
||||||
initial, modifications, expected, ensure_env_variables, monkeypatch
|
initial,
|
||||||
|
modifications,
|
||||||
|
expected,
|
||||||
|
ensure_env_variables,
|
||||||
|
compiler_factory,
|
||||||
|
mutable_config,
|
||||||
|
monkeypatch,
|
||||||
):
|
):
|
||||||
# Set the environment as per prerequisites
|
# Set the environment as per prerequisites
|
||||||
ensure_env_variables(initial)
|
ensure_env_variables(initial)
|
||||||
|
|
||||||
|
gcc_entry = compiler_factory(spec="gcc@14.0.1 languages=c,c++")
|
||||||
|
gcc_entry["extra_attributes"]["environment"] = modifications
|
||||||
|
mutable_config.set("packages", {"gcc": {"externals": [gcc_entry]}})
|
||||||
|
|
||||||
def platform_pathsep(pathlist):
|
def platform_pathsep(pathlist):
|
||||||
if Path.platform_path == Path.windows:
|
if Path.platform_path == Path.windows:
|
||||||
pathlist = pathlist.replace(":", ";")
|
pathlist = pathlist.replace(":", ";")
|
||||||
|
|
||||||
return convert_to_platform_path(pathlist)
|
return convert_to_platform_path(pathlist)
|
||||||
|
|
||||||
# Monkeypatch a pkg.compiler.environment with the required modifications
|
pkg = spack.spec.Spec("cmake %gcc@14").concretized().package
|
||||||
pkg = spack.spec.Spec("cmake").concretized().package
|
|
||||||
monkeypatch.setattr(pkg.compiler, "environment", modifications)
|
|
||||||
# Trigger the modifications
|
# Trigger the modifications
|
||||||
spack.build_environment.setup_package(pkg, False)
|
spack.build_environment.setup_package(pkg, dirty=False)
|
||||||
|
|
||||||
# Check they were applied
|
# Check they were applied
|
||||||
for name, value in expected.items():
|
for name, value in expected.items():
|
||||||
@@ -292,25 +302,6 @@ def platform_pathsep(pathlist):
|
|||||||
assert name not in os.environ
|
assert name not in os.environ
|
||||||
|
|
||||||
|
|
||||||
def test_compiler_custom_env(config, mock_packages, monkeypatch, working_env):
|
|
||||||
if sys.platform == "win32":
|
|
||||||
test_path = r"C:\test\path\element\custom-env" + "\\"
|
|
||||||
else:
|
|
||||||
test_path = r"/test/path/element/custom-env/"
|
|
||||||
|
|
||||||
def custom_env(pkg, env):
|
|
||||||
env.prepend_path("PATH", test_path)
|
|
||||||
env.append_flags("ENV_CUSTOM_CC_FLAGS", "--custom-env-flag1")
|
|
||||||
|
|
||||||
pkg = spack.spec.Spec("cmake").concretized().package
|
|
||||||
monkeypatch.setattr(pkg.compiler, "setup_custom_environment", custom_env)
|
|
||||||
spack.build_environment.setup_package(pkg, False)
|
|
||||||
|
|
||||||
# Note: trailing slash may be stripped by internal logic
|
|
||||||
assert test_path[:-1] in os.environ["PATH"]
|
|
||||||
assert "--custom-env-flag1" in os.environ["ENV_CUSTOM_CC_FLAGS"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_external_config_env(mock_packages, mutable_config, working_env):
|
def test_external_config_env(mock_packages, mutable_config, working_env):
|
||||||
cmake_config = {
|
cmake_config = {
|
||||||
"externals": [
|
"externals": [
|
||||||
@@ -330,25 +321,27 @@ def test_external_config_env(mock_packages, mutable_config, working_env):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.regression("9107")
|
@pytest.mark.regression("9107")
|
||||||
def test_spack_paths_before_module_paths(config, mock_packages, monkeypatch, working_env):
|
@pytest.mark.not_on_windows("Windows does not support module files")
|
||||||
s = spack.spec.Spec("cmake")
|
def test_spack_paths_before_module_paths(
|
||||||
s.concretize()
|
mutable_config, mock_packages, compiler_factory, monkeypatch, working_env
|
||||||
pkg = s.package
|
):
|
||||||
|
gcc_entry = compiler_factory(spec="gcc@14.0.1 languages=c,c++")
|
||||||
|
gcc_entry["modules"] = ["some_module"]
|
||||||
|
mutable_config.set("packages", {"gcc": {"externals": [gcc_entry]}})
|
||||||
|
|
||||||
module_path = os.path.join("path", "to", "module")
|
module_path = os.path.join("path", "to", "module")
|
||||||
|
spack_path = os.path.join(spack.paths.prefix, os.path.join("lib", "spack", "env"))
|
||||||
|
|
||||||
def _set_wrong_cc(x):
|
def _set_wrong_cc(x):
|
||||||
os.environ["PATH"] = module_path + os.pathsep + os.environ["PATH"]
|
os.environ["PATH"] = module_path + os.pathsep + os.environ["PATH"]
|
||||||
|
|
||||||
monkeypatch.setattr(spack.build_environment, "load_module", _set_wrong_cc)
|
monkeypatch.setattr(spack.build_environment, "load_module", _set_wrong_cc)
|
||||||
monkeypatch.setattr(pkg.compiler, "modules", ["some_module"])
|
|
||||||
|
|
||||||
spack.build_environment.setup_package(pkg, False)
|
s = spack.spec.Spec("cmake").concretized()
|
||||||
|
|
||||||
spack_path = os.path.join(spack.paths.prefix, os.path.join("lib", "spack", "env"))
|
spack.build_environment.setup_package(s.package, dirty=False)
|
||||||
|
|
||||||
paths = os.environ["PATH"].split(os.pathsep)
|
paths = os.environ["PATH"].split(os.pathsep)
|
||||||
|
|
||||||
assert paths.index(spack_path) < paths.index(module_path)
|
assert paths.index(spack_path) < paths.index(module_path)
|
||||||
|
|
||||||
|
|
||||||
@@ -499,15 +492,13 @@ def test_parallel_false_is_not_propagating(default_mock_concretization):
|
|||||||
("rpath", "" if platform.system() == "Darwin" else "--disable-new-dtags"),
|
("rpath", "" if platform.system() == "Darwin" else "--disable-new-dtags"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_setting_dtags_based_on_config(config_setting, expected_flag, config, mock_packages):
|
def test_setting_dtags_based_on_config(
|
||||||
|
config_setting, expected_flag, config, mock_packages, working_env
|
||||||
|
):
|
||||||
# Pick a random package to be able to set compiler's variables
|
# Pick a random package to be able to set compiler's variables
|
||||||
s = spack.spec.Spec("cmake")
|
s = spack.spec.Spec("cmake").concretized()
|
||||||
s.concretize()
|
|
||||||
pkg = s.package
|
|
||||||
|
|
||||||
env = EnvironmentModifications()
|
|
||||||
with spack.config.override("config:shared_linking", {"type": config_setting, "bind": False}):
|
with spack.config.override("config:shared_linking", {"type": config_setting, "bind": False}):
|
||||||
spack.build_environment.set_compiler_environment_variables(pkg, env)
|
env = spack.build_environment.setup_package(s.package, dirty=False)
|
||||||
modifications = env.group_by_name()
|
modifications = env.group_by_name()
|
||||||
assert "SPACK_DTAGS_TO_STRIP" in modifications
|
assert "SPACK_DTAGS_TO_STRIP" in modifications
|
||||||
assert "SPACK_DTAGS_TO_ADD" in modifications
|
assert "SPACK_DTAGS_TO_ADD" in modifications
|
||||||
@@ -770,59 +761,24 @@ def test_rpath_with_duplicate_link_deps():
|
|||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"compiler_spec,target_name,expected_flags",
|
"compiler_spec,target_name,expected_flags",
|
||||||
[
|
[
|
||||||
# Homogeneous compilers
|
# Semver versions
|
||||||
("gcc@4.7.2", "ivybridge", "-march=core-avx-i -mtune=core-avx-i"),
|
("gcc@4.7.2", "ivybridge", "-march=core-avx-i -mtune=core-avx-i"),
|
||||||
("clang@3.5", "x86_64", "-march=x86-64 -mtune=generic"),
|
("clang@3.5", "x86_64", "-march=x86-64 -mtune=generic"),
|
||||||
("apple-clang@9.1.0", "x86_64", "-march=x86-64"),
|
("apple-clang@9.1.0", "x86_64", "-march=x86-64"),
|
||||||
# Mixed toolchain
|
("gcc@=9.2.0", "haswell", "-march=haswell -mtune=haswell"),
|
||||||
("clang@8.0.0", "broadwell", ""),
|
# Check that custom string versions are accepted
|
||||||
|
("gcc@=9.2.0-foo", "icelake", "-march=icelake-client -mtune=icelake-client"),
|
||||||
|
# Check that the special case for Apple's clang is treated correctly
|
||||||
|
# i.e. it won't try to detect the version again
|
||||||
|
("apple-clang@=9.1.0", "x86_64", "-march=x86-64"),
|
||||||
|
# FIXME (compiler as nodes): Check mixed toolchain
|
||||||
|
# ("clang@8.0.0", "broadwell", ""),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.filterwarnings("ignore:microarchitecture specific")
|
@pytest.mark.filterwarnings("ignore:microarchitecture specific")
|
||||||
@pytest.mark.not_on_windows("Windows doesn't support the compiler wrapper")
|
@pytest.mark.not_on_windows("Windows doesn't support the compiler wrapper")
|
||||||
def test_optimization_flags(compiler_spec, target_name, expected_flags, compiler_factory):
|
def test_optimization_flags(compiler_spec, target_name, expected_flags, compiler_factory):
|
||||||
target = archspec.cpu.TARGETS[target_name]
|
target = archspec.cpu.TARGETS[target_name]
|
||||||
compiler_dict = compiler_factory(spec=compiler_spec, operating_system="")["compiler"]
|
compiler = spack.spec.parse_with_version_concrete(compiler_spec)
|
||||||
if compiler_spec == "clang@8.0.0":
|
|
||||||
compiler_dict["paths"] = {
|
|
||||||
"cc": "/path/to/clang-8",
|
|
||||||
"cxx": "/path/to/clang++-8",
|
|
||||||
"f77": "/path/to/gfortran-9",
|
|
||||||
"fc": "/path/to/gfortran-9",
|
|
||||||
}
|
|
||||||
compiler = spack.compilers.compiler_from_dict(compiler_dict)
|
|
||||||
opt_flags = spack.build_environment.optimization_flags(compiler, target)
|
|
||||||
assert opt_flags == expected_flags
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"compiler_str,real_version,target_str,expected_flags",
|
|
||||||
[
|
|
||||||
("gcc@=9.2.0", None, "haswell", "-march=haswell -mtune=haswell"),
|
|
||||||
# Check that custom string versions are accepted
|
|
||||||
("gcc@=10foo", "9.2.0", "icelake", "-march=icelake-client -mtune=icelake-client"),
|
|
||||||
# Check that we run version detection (4.4.0 doesn't support icelake)
|
|
||||||
("gcc@=4.4.0-special", "9.2.0", "icelake", "-march=icelake-client -mtune=icelake-client"),
|
|
||||||
# Check that the special case for Apple's clang is treated correctly
|
|
||||||
# i.e. it won't try to detect the version again
|
|
||||||
("apple-clang@=9.1.0", None, "x86_64", "-march=x86-64"),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_optimization_flags_with_custom_versions(
|
|
||||||
compiler_str,
|
|
||||||
real_version,
|
|
||||||
target_str,
|
|
||||||
expected_flags,
|
|
||||||
monkeypatch,
|
|
||||||
mutable_config,
|
|
||||||
compiler_factory,
|
|
||||||
):
|
|
||||||
target = archspec.cpu.TARGETS[target_str]
|
|
||||||
compiler_dict = compiler_factory(spec=compiler_str, operating_system="redhat6")
|
|
||||||
mutable_config.set("compilers", [compiler_dict])
|
|
||||||
if real_version:
|
|
||||||
monkeypatch.setattr(spack.compiler.Compiler, "get_real_version", lambda x: real_version)
|
|
||||||
compiler = spack.compilers.compiler_from_dict(compiler_dict["compiler"])
|
|
||||||
|
|
||||||
opt_flags = spack.build_environment.optimization_flags(compiler, target)
|
opt_flags = spack.build_environment.optimization_flags(compiler, target)
|
||||||
assert opt_flags == expected_flags
|
assert opt_flags == expected_flags
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
build_env = SpackCommand("build-env")
|
build_env = SpackCommand("build-env")
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("pkg", [("zlib",), ("zlib", "--")])
|
@pytest.mark.parametrize("pkg", [("pkg-c",), ("pkg-c", "--")])
|
||||||
@pytest.mark.usefixtures("config", "mock_packages", "working_env")
|
@pytest.mark.usefixtures("config", "mock_packages", "working_env")
|
||||||
def test_it_just_runs(pkg):
|
def test_it_just_runs(pkg):
|
||||||
build_env(*pkg)
|
build_env(*pkg)
|
||||||
@@ -39,7 +39,7 @@ def test_build_env_requires_a_spec(args):
|
|||||||
@pytest.mark.usefixtures("config", "mock_packages", "working_env")
|
@pytest.mark.usefixtures("config", "mock_packages", "working_env")
|
||||||
def test_dump(shell_as, shell, tmpdir):
|
def test_dump(shell_as, shell, tmpdir):
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
build_env("--dump", _out_file, "zlib")
|
build_env("--dump", _out_file, "pkg-c")
|
||||||
with open(_out_file) as f:
|
with open(_out_file) as f:
|
||||||
if shell == "pwsh":
|
if shell == "pwsh":
|
||||||
assert any(line.startswith("$Env:PATH") for line in f.readlines())
|
assert any(line.startswith("$Env:PATH") for line in f.readlines())
|
||||||
@@ -52,7 +52,7 @@ def test_dump(shell_as, shell, tmpdir):
|
|||||||
@pytest.mark.usefixtures("config", "mock_packages", "working_env")
|
@pytest.mark.usefixtures("config", "mock_packages", "working_env")
|
||||||
def test_pickle(tmpdir):
|
def test_pickle(tmpdir):
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
build_env("--pickle", _out_file, "zlib")
|
build_env("--pickle", _out_file, "pkg-c")
|
||||||
environment = pickle.load(open(_out_file, "rb"))
|
environment = pickle.load(open(_out_file, "rb"))
|
||||||
assert isinstance(environment, dict)
|
assert isinstance(environment, dict)
|
||||||
assert "PATH" in environment
|
assert "PATH" in environment
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ def test_update_key_index(
|
|||||||
s = Spec("libdwarf").concretized()
|
s = Spec("libdwarf").concretized()
|
||||||
|
|
||||||
# Install a package
|
# Install a package
|
||||||
install(s.name)
|
install("--fake", s.name)
|
||||||
|
|
||||||
# Put installed package in the buildcache, which, because we're signing
|
# Put installed package in the buildcache, which, because we're signing
|
||||||
# it, should result in the public key getting pushed to the buildcache
|
# it, should result in the public key getting pushed to the buildcache
|
||||||
@@ -179,7 +179,7 @@ def test_buildcache_autopush(tmp_path, install_mockery, mock_fetch):
|
|||||||
s = Spec("libdwarf").concretized()
|
s = Spec("libdwarf").concretized()
|
||||||
|
|
||||||
# Install and generate build cache index
|
# Install and generate build cache index
|
||||||
PackageInstaller([s.package], explicit=True).install()
|
PackageInstaller([s.package], fake=True, explicit=True).install()
|
||||||
|
|
||||||
metadata_file = spack.binary_distribution.tarball_name(s, ".spec.json")
|
metadata_file = spack.binary_distribution.tarball_name(s, ".spec.json")
|
||||||
|
|
||||||
@@ -221,7 +221,7 @@ def verify_mirror_contents():
|
|||||||
|
|
||||||
# Install a package and put it in the buildcache
|
# Install a package and put it in the buildcache
|
||||||
s = Spec(out_env_pkg).concretized()
|
s = Spec(out_env_pkg).concretized()
|
||||||
install(s.name)
|
install("--fake", s.name)
|
||||||
buildcache("push", "-u", "-f", src_mirror_url, s.name)
|
buildcache("push", "-u", "-f", src_mirror_url, s.name)
|
||||||
|
|
||||||
env("create", "test")
|
env("create", "test")
|
||||||
|
|||||||
@@ -232,9 +232,9 @@ def test_ci_generate_with_env(ci_generate_test, tmp_path, mock_binary_index):
|
|||||||
assert yaml_contents["workflow"]["rules"] == [{"when": "always"}]
|
assert yaml_contents["workflow"]["rules"] == [{"when": "always"}]
|
||||||
|
|
||||||
assert "stages" in yaml_contents
|
assert "stages" in yaml_contents
|
||||||
assert len(yaml_contents["stages"]) == 5
|
assert len(yaml_contents["stages"]) == 6
|
||||||
assert yaml_contents["stages"][0] == "stage-0"
|
assert yaml_contents["stages"][0] == "stage-0"
|
||||||
assert yaml_contents["stages"][4] == "stage-rebuild-index"
|
assert yaml_contents["stages"][5] == "stage-rebuild-index"
|
||||||
|
|
||||||
assert "rebuild-index" in yaml_contents
|
assert "rebuild-index" in yaml_contents
|
||||||
rebuild_job = yaml_contents["rebuild-index"]
|
rebuild_job = yaml_contents["rebuild-index"]
|
||||||
@@ -1112,7 +1112,7 @@ def test_ci_rebuild_index(
|
|||||||
with open(tmp_path / "spec.json", "w") as f:
|
with open(tmp_path / "spec.json", "w") as f:
|
||||||
f.write(concrete_spec.to_json(hash=ht.dag_hash))
|
f.write(concrete_spec.to_json(hash=ht.dag_hash))
|
||||||
|
|
||||||
install_cmd("--add", "-f", str(tmp_path / "spec.json"))
|
install_cmd("--fake", "--add", "-f", str(tmp_path / "spec.json"))
|
||||||
buildcache_cmd("push", "-u", "-f", mirror_url, "callpath")
|
buildcache_cmd("push", "-u", "-f", mirror_url, "callpath")
|
||||||
ci_cmd("rebuild-index")
|
ci_cmd("rebuild-index")
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
import spack.compilers.config
|
import spack.compilers.config
|
||||||
import spack.config
|
import spack.config
|
||||||
import spack.main
|
import spack.main
|
||||||
import spack.spec
|
|
||||||
import spack.util.pattern
|
import spack.util.pattern
|
||||||
import spack.version
|
import spack.version
|
||||||
|
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ def test_config_add_override_leaf_from_file(mutable_empty_config, tmpdir):
|
|||||||
|
|
||||||
|
|
||||||
def test_config_add_update_dict_from_file(mutable_empty_config, tmpdir):
|
def test_config_add_update_dict_from_file(mutable_empty_config, tmpdir):
|
||||||
config("add", "packages:all:compiler:[gcc]")
|
config("add", "packages:all:require:['%gcc']")
|
||||||
|
|
||||||
# contents to add to file
|
# contents to add to file
|
||||||
contents = """spack:
|
contents = """spack:
|
||||||
@@ -358,7 +358,7 @@ def test_config_add_update_dict_from_file(mutable_empty_config, tmpdir):
|
|||||||
expected = """packages:
|
expected = """packages:
|
||||||
all:
|
all:
|
||||||
target: [x86_64]
|
target: [x86_64]
|
||||||
compiler: [gcc]
|
require: ['%gcc']
|
||||||
"""
|
"""
|
||||||
|
|
||||||
assert expected == output
|
assert expected == output
|
||||||
@@ -608,7 +608,6 @@ def test_config_prefer_upstream(
|
|||||||
packages = syaml.load(open(cfg_file))["packages"]
|
packages = syaml.load(open(cfg_file))["packages"]
|
||||||
|
|
||||||
# Make sure only the non-default variants are set.
|
# Make sure only the non-default variants are set.
|
||||||
assert packages["all"] == {"compiler": ["gcc@=10.2.1"]}
|
|
||||||
assert packages["boost"] == {"variants": "+debug +graph", "version": ["1.63.0"]}
|
assert packages["boost"] == {"variants": "+debug +graph", "version": ["1.63.0"]}
|
||||||
assert packages["dependency-install"] == {"version": ["2.0"]}
|
assert packages["dependency-install"] == {"version": ["2.0"]}
|
||||||
# Ensure that neither variant gets listed for hdf5, since they conflict
|
# Ensure that neither variant gets listed for hdf5, since they conflict
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
dependencies = SpackCommand("dependencies")
|
dependencies = SpackCommand("dependencies")
|
||||||
|
|
||||||
mpis = [
|
MPIS = [
|
||||||
"intel-parallel-studio",
|
"intel-parallel-studio",
|
||||||
"low-priority-provider",
|
"low-priority-provider",
|
||||||
"mpich",
|
"mpich",
|
||||||
@@ -22,20 +22,21 @@
|
|||||||
"multi-provider-mpi",
|
"multi-provider-mpi",
|
||||||
"zmpi",
|
"zmpi",
|
||||||
]
|
]
|
||||||
mpi_deps = ["fake"]
|
COMPILERS = ["gcc", "llvm"]
|
||||||
|
MPI_DEPS = ["fake"]
|
||||||
|
|
||||||
|
|
||||||
def test_direct_dependencies(mock_packages):
|
def test_direct_dependencies(mock_packages):
|
||||||
out = dependencies("mpileaks")
|
out = dependencies("mpileaks")
|
||||||
actual = set(re.split(r"\s+", out.strip()))
|
actual = set(re.split(r"\s+", out.strip()))
|
||||||
expected = set(["callpath"] + mpis)
|
expected = set(["callpath"] + MPIS + COMPILERS)
|
||||||
assert expected == actual
|
assert expected == actual
|
||||||
|
|
||||||
|
|
||||||
def test_transitive_dependencies(mock_packages):
|
def test_transitive_dependencies(mock_packages):
|
||||||
out = dependencies("--transitive", "mpileaks")
|
out = dependencies("--transitive", "mpileaks")
|
||||||
actual = set(re.split(r"\s+", out.strip()))
|
actual = set(re.split(r"\s+", out.strip()))
|
||||||
expected = set(["callpath", "dyninst", "libdwarf", "libelf"] + mpis + mpi_deps)
|
expected = set(["callpath", "dyninst", "libdwarf", "libelf"] + MPIS + MPI_DEPS + COMPILERS)
|
||||||
assert expected == actual
|
assert expected == actual
|
||||||
|
|
||||||
|
|
||||||
@@ -58,12 +59,11 @@ def test_direct_installed_dependencies(mock_packages, database):
|
|||||||
with color_when(False):
|
with color_when(False):
|
||||||
out = dependencies("--installed", "mpileaks^mpich")
|
out = dependencies("--installed", "mpileaks^mpich")
|
||||||
|
|
||||||
lines = [line for line in out.strip().split("\n") if not line.startswith("--")]
|
root = spack.store.STORE.db.query_one("mpileaks ^mpich")
|
||||||
hashes = set([re.split(r"\s+", line)[0] for line in lines])
|
|
||||||
|
|
||||||
expected = set(
|
lines = [line for line in out.strip().split("\n") if line and not line.startswith("--")]
|
||||||
[spack.store.STORE.db.query_one(s).dag_hash(7) for s in ["mpich", "callpath^mpich"]]
|
hashes = {re.split(r"\s+", line)[0] for line in lines}
|
||||||
)
|
expected = {s.dag_hash(7) for s in root.dependencies()}
|
||||||
|
|
||||||
assert expected == hashes
|
assert expected == hashes
|
||||||
|
|
||||||
@@ -73,14 +73,10 @@ def test_transitive_installed_dependencies(mock_packages, database):
|
|||||||
with color_when(False):
|
with color_when(False):
|
||||||
out = dependencies("--installed", "--transitive", "mpileaks^zmpi")
|
out = dependencies("--installed", "--transitive", "mpileaks^zmpi")
|
||||||
|
|
||||||
lines = [line for line in out.strip().split("\n") if not line.startswith("--")]
|
root = spack.store.STORE.db.query_one("mpileaks ^zmpi")
|
||||||
hashes = set([re.split(r"\s+", line)[0] for line in lines])
|
|
||||||
|
|
||||||
expected = set(
|
lines = [line for line in out.strip().split("\n") if line and not line.startswith("--")]
|
||||||
[
|
hashes = {re.split(r"\s+", line)[0] for line in lines}
|
||||||
spack.store.STORE.db.query_one(s).dag_hash(7)
|
expected = {s.dag_hash(7) for s in root.traverse(root=False)}
|
||||||
for s in ["zmpi", "callpath^zmpi", "fake", "dyninst", "libdwarf", "libelf"]
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
assert expected == hashes
|
assert expected == hashes
|
||||||
|
|||||||
@@ -17,16 +17,16 @@
|
|||||||
|
|
||||||
|
|
||||||
def test_deprecate(mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_deprecate(mock_packages, mock_archive, mock_fetch, install_mockery):
|
||||||
install("libelf@0.8.13")
|
install("--fake", "libelf@0.8.13")
|
||||||
install("libelf@0.8.10")
|
install("--fake", "libelf@0.8.10")
|
||||||
|
|
||||||
all_installed = spack.store.STORE.db.query()
|
all_installed = spack.store.STORE.db.query("libelf")
|
||||||
assert len(all_installed) == 2
|
assert len(all_installed) == 2
|
||||||
|
|
||||||
deprecate("-y", "libelf@0.8.10", "libelf@0.8.13")
|
deprecate("-y", "libelf@0.8.10", "libelf@0.8.13")
|
||||||
|
|
||||||
non_deprecated = spack.store.STORE.db.query()
|
non_deprecated = spack.store.STORE.db.query("libelf")
|
||||||
all_available = spack.store.STORE.db.query(installed=InstallRecordStatus.ANY)
|
all_available = spack.store.STORE.db.query("libelf", installed=InstallRecordStatus.ANY)
|
||||||
assert all_available == all_installed
|
assert all_available == all_installed
|
||||||
assert non_deprecated == spack.store.STORE.db.query("libelf@0.8.13")
|
assert non_deprecated == spack.store.STORE.db.query("libelf@0.8.13")
|
||||||
|
|
||||||
@@ -39,24 +39,24 @@ def test_deprecate_fails_no_such_package(mock_packages, mock_archive, mock_fetch
|
|||||||
output = deprecate("-y", "libelf@0.8.10", "libelf@0.8.13", fail_on_error=False)
|
output = deprecate("-y", "libelf@0.8.10", "libelf@0.8.13", fail_on_error=False)
|
||||||
assert "Spec 'libelf@0.8.10' matches no installed packages" in output
|
assert "Spec 'libelf@0.8.10' matches no installed packages" in output
|
||||||
|
|
||||||
install("libelf@0.8.10")
|
install("--fake", "libelf@0.8.10")
|
||||||
|
|
||||||
output = deprecate("-y", "libelf@0.8.10", "libelf@0.8.13", fail_on_error=False)
|
output = deprecate("-y", "libelf@0.8.10", "libelf@0.8.13", fail_on_error=False)
|
||||||
assert "Spec 'libelf@0.8.13' matches no installed packages" in output
|
assert "Spec 'libelf@0.8.13' matches no installed packages" in output
|
||||||
|
|
||||||
|
|
||||||
def test_deprecate_install(mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_deprecate_install(mock_packages, mock_archive, mock_fetch, install_mockery, monkeypatch):
|
||||||
"""Tests that the ```-i`` option allows us to deprecate in favor of a spec
|
"""Tests that the -i option allows us to deprecate in favor of a spec
|
||||||
that is not yet installed."""
|
that is not yet installed.
|
||||||
install("libelf@0.8.10")
|
"""
|
||||||
|
install("--fake", "libelf@0.8.10")
|
||||||
to_deprecate = spack.store.STORE.db.query()
|
to_deprecate = spack.store.STORE.db.query("libelf")
|
||||||
assert len(to_deprecate) == 1
|
assert len(to_deprecate) == 1
|
||||||
|
|
||||||
deprecate("-y", "-i", "libelf@0.8.10", "libelf@0.8.13")
|
deprecate("-y", "-i", "libelf@0.8.10", "libelf@0.8.13")
|
||||||
|
|
||||||
non_deprecated = spack.store.STORE.db.query()
|
non_deprecated = spack.store.STORE.db.query("libelf")
|
||||||
deprecated = spack.store.STORE.db.query(installed=InstallRecordStatus.DEPRECATED)
|
deprecated = spack.store.STORE.db.query("libelf", installed=InstallRecordStatus.DEPRECATED)
|
||||||
assert deprecated == to_deprecate
|
assert deprecated == to_deprecate
|
||||||
assert len(non_deprecated) == 1
|
assert len(non_deprecated) == 1
|
||||||
assert non_deprecated[0].satisfies("libelf@0.8.13")
|
assert non_deprecated[0].satisfies("libelf@0.8.13")
|
||||||
@@ -64,8 +64,8 @@ def test_deprecate_install(mock_packages, mock_archive, mock_fetch, install_mock
|
|||||||
|
|
||||||
def test_deprecate_deps(mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_deprecate_deps(mock_packages, mock_archive, mock_fetch, install_mockery):
|
||||||
"""Test that the deprecate command deprecates all dependencies properly."""
|
"""Test that the deprecate command deprecates all dependencies properly."""
|
||||||
install("libdwarf@20130729 ^libelf@0.8.13")
|
install("--fake", "libdwarf@20130729 ^libelf@0.8.13")
|
||||||
install("libdwarf@20130207 ^libelf@0.8.10")
|
install("--fake", "libdwarf@20130207 ^libelf@0.8.10")
|
||||||
|
|
||||||
new_spec = spack.spec.Spec("libdwarf@20130729^libelf@0.8.13").concretized()
|
new_spec = spack.spec.Spec("libdwarf@20130729^libelf@0.8.13").concretized()
|
||||||
old_spec = spack.spec.Spec("libdwarf@20130207^libelf@0.8.10").concretized()
|
old_spec = spack.spec.Spec("libdwarf@20130207^libelf@0.8.10").concretized()
|
||||||
@@ -81,14 +81,14 @@ def test_deprecate_deps(mock_packages, mock_archive, mock_fetch, install_mockery
|
|||||||
assert all_available == all_installed
|
assert all_available == all_installed
|
||||||
assert sorted(all_available) == sorted(deprecated + non_deprecated)
|
assert sorted(all_available) == sorted(deprecated + non_deprecated)
|
||||||
|
|
||||||
assert sorted(non_deprecated) == sorted(list(new_spec.traverse()))
|
assert sorted(non_deprecated) == sorted(new_spec.traverse())
|
||||||
assert sorted(deprecated) == sorted(list(old_spec.traverse()))
|
assert sorted(deprecated) == sorted([old_spec, old_spec["libelf"]])
|
||||||
|
|
||||||
|
|
||||||
def test_uninstall_deprecated(mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_uninstall_deprecated(mock_packages, mock_archive, mock_fetch, install_mockery):
|
||||||
"""Tests that we can still uninstall deprecated packages."""
|
"""Tests that we can still uninstall deprecated packages."""
|
||||||
install("libelf@0.8.13")
|
install("--fake", "libelf@0.8.13")
|
||||||
install("libelf@0.8.10")
|
install("--fake", "libelf@0.8.10")
|
||||||
|
|
||||||
deprecate("-y", "libelf@0.8.10", "libelf@0.8.13")
|
deprecate("-y", "libelf@0.8.10", "libelf@0.8.13")
|
||||||
|
|
||||||
@@ -104,9 +104,9 @@ def test_uninstall_deprecated(mock_packages, mock_archive, mock_fetch, install_m
|
|||||||
|
|
||||||
def test_deprecate_already_deprecated(mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_deprecate_already_deprecated(mock_packages, mock_archive, mock_fetch, install_mockery):
|
||||||
"""Tests that we can re-deprecate a spec to change its deprecator."""
|
"""Tests that we can re-deprecate a spec to change its deprecator."""
|
||||||
install("libelf@0.8.13")
|
install("--fake", "libelf@0.8.13")
|
||||||
install("libelf@0.8.12")
|
install("--fake", "libelf@0.8.12")
|
||||||
install("libelf@0.8.10")
|
install("--fake", "libelf@0.8.10")
|
||||||
|
|
||||||
deprecated_spec = spack.spec.Spec("libelf@0.8.10").concretized()
|
deprecated_spec = spack.spec.Spec("libelf@0.8.10").concretized()
|
||||||
|
|
||||||
@@ -117,8 +117,8 @@ def test_deprecate_already_deprecated(mock_packages, mock_archive, mock_fetch, i
|
|||||||
|
|
||||||
deprecate("-y", "libelf@0.8.10", "libelf@0.8.13")
|
deprecate("-y", "libelf@0.8.10", "libelf@0.8.13")
|
||||||
|
|
||||||
non_deprecated = spack.store.STORE.db.query()
|
non_deprecated = spack.store.STORE.db.query("libelf")
|
||||||
all_available = spack.store.STORE.db.query(installed=InstallRecordStatus.ANY)
|
all_available = spack.store.STORE.db.query("libelf", installed=InstallRecordStatus.ANY)
|
||||||
assert len(non_deprecated) == 2
|
assert len(non_deprecated) == 2
|
||||||
assert len(all_available) == 3
|
assert len(all_available) == 3
|
||||||
|
|
||||||
@@ -129,9 +129,9 @@ def test_deprecate_already_deprecated(mock_packages, mock_archive, mock_fetch, i
|
|||||||
def test_deprecate_deprecator(mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_deprecate_deprecator(mock_packages, mock_archive, mock_fetch, install_mockery):
|
||||||
"""Tests that when a deprecator spec is deprecated, its deprecatee specs
|
"""Tests that when a deprecator spec is deprecated, its deprecatee specs
|
||||||
are updated to point to the new deprecator."""
|
are updated to point to the new deprecator."""
|
||||||
install("libelf@0.8.13")
|
install("--fake", "libelf@0.8.13")
|
||||||
install("libelf@0.8.12")
|
install("--fake", "libelf@0.8.12")
|
||||||
install("libelf@0.8.10")
|
install("--fake", "libelf@0.8.10")
|
||||||
|
|
||||||
first_deprecated_spec = spack.spec.Spec("libelf@0.8.10").concretized()
|
first_deprecated_spec = spack.spec.Spec("libelf@0.8.10").concretized()
|
||||||
second_deprecated_spec = spack.spec.Spec("libelf@0.8.12").concretized()
|
second_deprecated_spec = spack.spec.Spec("libelf@0.8.12").concretized()
|
||||||
@@ -144,8 +144,8 @@ def test_deprecate_deprecator(mock_packages, mock_archive, mock_fetch, install_m
|
|||||||
|
|
||||||
deprecate("-y", "libelf@0.8.12", "libelf@0.8.13")
|
deprecate("-y", "libelf@0.8.12", "libelf@0.8.13")
|
||||||
|
|
||||||
non_deprecated = spack.store.STORE.db.query()
|
non_deprecated = spack.store.STORE.db.query("libelf")
|
||||||
all_available = spack.store.STORE.db.query(installed=InstallRecordStatus.ANY)
|
all_available = spack.store.STORE.db.query("libelf", installed=InstallRecordStatus.ANY)
|
||||||
assert len(non_deprecated) == 1
|
assert len(non_deprecated) == 1
|
||||||
assert len(all_available) == 3
|
assert len(all_available) == 3
|
||||||
|
|
||||||
@@ -158,8 +158,8 @@ def test_deprecate_deprecator(mock_packages, mock_archive, mock_fetch, install_m
|
|||||||
def test_concretize_deprecated(mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_concretize_deprecated(mock_packages, mock_archive, mock_fetch, install_mockery):
|
||||||
"""Tests that the concretizer throws an error if we concretize to a
|
"""Tests that the concretizer throws an error if we concretize to a
|
||||||
deprecated spec"""
|
deprecated spec"""
|
||||||
install("libelf@0.8.13")
|
install("--fake", "libelf@0.8.13")
|
||||||
install("libelf@0.8.10")
|
install("--fake", "libelf@0.8.10")
|
||||||
|
|
||||||
deprecate("-y", "libelf@0.8.10", "libelf@0.8.13")
|
deprecate("-y", "libelf@0.8.10", "libelf@0.8.13")
|
||||||
|
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ def test_diff_cmd(install_mockery, mock_fetch, mock_archive, mock_packages):
|
|||||||
|
|
||||||
def test_load_first(install_mockery, mock_fetch, mock_archive, mock_packages):
|
def test_load_first(install_mockery, mock_fetch, mock_archive, mock_packages):
|
||||||
"""Test with and without the --first option"""
|
"""Test with and without the --first option"""
|
||||||
install_cmd("mpileaks")
|
install_cmd("--fake", "mpileaks")
|
||||||
|
|
||||||
# Only one version of mpileaks will work
|
# Only one version of mpileaks will work
|
||||||
diff_cmd("mpileaks", "mpileaks")
|
diff_cmd("mpileaks", "mpileaks")
|
||||||
@@ -224,14 +224,12 @@ def test_load_first(install_mockery, mock_fetch, mock_archive, mock_packages):
|
|||||||
for dep in ("mpileaks", "callpath", "dyninst", "libelf", "libdwarf", "mpich")
|
for dep in ("mpileaks", "callpath", "dyninst", "libelf", "libdwarf", "mpich")
|
||||||
)
|
)
|
||||||
assert all(
|
assert all(
|
||||||
len([diff for diff in result["intersect"] if diff[0] == attr]) == 6
|
len([diff for diff in result["intersect"] if diff[0] == attr]) == 7
|
||||||
for attr in (
|
for attr in (
|
||||||
"version",
|
"version",
|
||||||
"node_target",
|
"node_target",
|
||||||
"node_platform",
|
"node_platform",
|
||||||
"node_os",
|
"node_os",
|
||||||
"node_compiler",
|
|
||||||
"node_compiler_version",
|
|
||||||
"node",
|
"node",
|
||||||
"package_hash",
|
"package_hash",
|
||||||
"hash",
|
"hash",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
import contextlib
|
||||||
import filecmp
|
import filecmp
|
||||||
import glob
|
import glob
|
||||||
import io
|
import io
|
||||||
@@ -210,6 +211,49 @@ def test_env_untrack_managed(tmp_path, capfd):
|
|||||||
assert f"'{env_name}' is not a tracked env" in out
|
assert f"'{env_name}' is not a tracked env" in out
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def installed_environment(tmp_path, mock_fetch, mock_packages, mock_archive, install_mockery):
|
||||||
|
spack_yaml = tmp_path / "spack.yaml"
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def _installed_environment(content):
|
||||||
|
spack_yaml.write_text(content)
|
||||||
|
with fs.working_dir(tmp_path):
|
||||||
|
env("create", "test", "./spack.yaml")
|
||||||
|
with ev.read("test"):
|
||||||
|
install("--fake")
|
||||||
|
|
||||||
|
test = ev.read("test")
|
||||||
|
yield test
|
||||||
|
|
||||||
|
return _installed_environment
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def template_combinatorial_env(tmp_path):
|
||||||
|
"""Returns a template base environment for tests. Since the environment configuration is
|
||||||
|
extended using str.format, we need double '{' escaping for the projections.
|
||||||
|
"""
|
||||||
|
view_dir = tmp_path / "view"
|
||||||
|
return f"""\
|
||||||
|
spack:
|
||||||
|
definitions:
|
||||||
|
- packages: [mpileaks, callpath]
|
||||||
|
- targets: ['target=x86_64', 'target=core2']
|
||||||
|
specs:
|
||||||
|
- matrix:
|
||||||
|
- [$packages]
|
||||||
|
- [$targets]
|
||||||
|
|
||||||
|
view:
|
||||||
|
combinatorial:
|
||||||
|
root: {view_dir}
|
||||||
|
{{view_config}}
|
||||||
|
projections:
|
||||||
|
'all': '{{{{architecture.target}}}}/{{{{name}}}}-{{{{version}}}}'
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
def test_add():
|
def test_add():
|
||||||
e = ev.create("test")
|
e = ev.create("test")
|
||||||
e.add("mpileaks")
|
e.add("mpileaks")
|
||||||
@@ -455,7 +499,7 @@ def test_env_specs_partition(install_mockery, mock_fetch):
|
|||||||
assert roots_to_install[0].name == "cmake-client"
|
assert roots_to_install[0].name == "cmake-client"
|
||||||
|
|
||||||
# Single installed root.
|
# Single installed root.
|
||||||
e.install_all()
|
e.install_all(fake=True)
|
||||||
roots_already_installed, roots_to_install = e._partition_roots_by_install_status()
|
roots_already_installed, roots_to_install = e._partition_roots_by_install_status()
|
||||||
assert len(roots_already_installed) == 1
|
assert len(roots_already_installed) == 1
|
||||||
assert roots_already_installed[0].name == "cmake-client"
|
assert roots_already_installed[0].name == "cmake-client"
|
||||||
@@ -475,7 +519,7 @@ def test_env_install_all(install_mockery, mock_fetch):
|
|||||||
e = ev.create("test")
|
e = ev.create("test")
|
||||||
e.add("cmake-client")
|
e.add("cmake-client")
|
||||||
e.concretize()
|
e.concretize()
|
||||||
e.install_all()
|
e.install_all(fake=True)
|
||||||
env_specs = e._get_environment_specs()
|
env_specs = e._get_environment_specs()
|
||||||
spec = next(x for x in env_specs if x.name == "cmake-client")
|
spec = next(x for x in env_specs if x.name == "cmake-client")
|
||||||
assert spec.installed
|
assert spec.installed
|
||||||
@@ -487,7 +531,7 @@ def test_env_install_single_spec(install_mockery, mock_fetch):
|
|||||||
|
|
||||||
e = ev.read("test")
|
e = ev.read("test")
|
||||||
with e:
|
with e:
|
||||||
install("--add", "cmake-client")
|
install("--fake", "--add", "cmake-client")
|
||||||
|
|
||||||
e = ev.read("test")
|
e = ev.read("test")
|
||||||
assert e.user_specs[0].name == "cmake-client"
|
assert e.user_specs[0].name == "cmake-client"
|
||||||
@@ -508,7 +552,7 @@ def test_env_install_include_concrete_env(unify, install_mockery, mock_fetch, mu
|
|||||||
combined.write()
|
combined.write()
|
||||||
|
|
||||||
with combined:
|
with combined:
|
||||||
install()
|
install("--fake")
|
||||||
|
|
||||||
test1_roots = test1.concretized_order
|
test1_roots = test1.concretized_order
|
||||||
test2_roots = test2.concretized_order
|
test2_roots = test2.concretized_order
|
||||||
@@ -556,7 +600,7 @@ def test_env_modifications_error_on_activate(install_mockery, mock_fetch, monkey
|
|||||||
|
|
||||||
e = ev.read("test")
|
e = ev.read("test")
|
||||||
with e:
|
with e:
|
||||||
install("--add", "cmake-client")
|
install("--fake", "--add", "cmake-client")
|
||||||
|
|
||||||
def setup_error(pkg, env):
|
def setup_error(pkg, env):
|
||||||
raise RuntimeError("cmake-client had issues!")
|
raise RuntimeError("cmake-client had issues!")
|
||||||
@@ -625,12 +669,12 @@ def test_env_install_two_specs_same_dep(install_mockery, mock_fetch, tmpdir, cap
|
|||||||
|
|
||||||
with ev.read("test"):
|
with ev.read("test"):
|
||||||
with capsys.disabled():
|
with capsys.disabled():
|
||||||
out = install()
|
out = install("--fake")
|
||||||
|
|
||||||
# Ensure both packages reach install phase processing and are installed
|
# Ensure both packages reach install phase processing and are installed
|
||||||
out = str(out)
|
out = str(out)
|
||||||
assert "depb: Executing phase:" in out
|
assert "depb: Successfully installed" in out
|
||||||
assert "a: Executing phase:" in out
|
assert "pkg-a: Successfully installed" in out
|
||||||
|
|
||||||
depb = spack.store.STORE.db.query_one("depb", installed=True)
|
depb = spack.store.STORE.db.query_one("depb", installed=True)
|
||||||
assert depb, "Expected depb to be installed"
|
assert depb, "Expected depb to be installed"
|
||||||
@@ -1649,9 +1693,7 @@ def test_stage(mock_stage, mock_fetch, install_mockery):
|
|||||||
def check_stage(spec):
|
def check_stage(spec):
|
||||||
spec = Spec(spec).concretized()
|
spec = Spec(spec).concretized()
|
||||||
for dep in spec.traverse():
|
for dep in spec.traverse():
|
||||||
stage_name = "{0}{1}-{2}-{3}".format(
|
stage_name = f"{stage_prefix}{dep.name}-{dep.version}-{dep.dag_hash()}"
|
||||||
stage_prefix, dep.name, dep.version, dep.dag_hash()
|
|
||||||
)
|
|
||||||
assert os.path.isdir(os.path.join(root, stage_name))
|
assert os.path.isdir(os.path.join(root, stage_name))
|
||||||
|
|
||||||
check_stage("mpileaks")
|
check_stage("mpileaks")
|
||||||
@@ -2821,207 +2863,75 @@ def test_stack_definition_conditional_add_write(tmpdir):
|
|||||||
assert "zmpi" not in packages_lists[1]["packages"]
|
assert "zmpi" not in packages_lists[1]["packages"]
|
||||||
|
|
||||||
|
|
||||||
def test_stack_combinatorial_view(
|
def test_stack_combinatorial_view(installed_environment, template_combinatorial_env, tmp_path):
|
||||||
tmpdir, mock_fetch, mock_packages, mock_archive, install_mockery
|
"""Tests creating a default view for a combinatorial stack."""
|
||||||
):
|
view_dir = tmp_path / "view"
|
||||||
filename = str(tmpdir.join("spack.yaml"))
|
with installed_environment(template_combinatorial_env.format(view_config="")) as test:
|
||||||
viewdir = str(tmpdir.join("view"))
|
|
||||||
with open(filename, "w") as f:
|
|
||||||
f.write(
|
|
||||||
"""\
|
|
||||||
spack:
|
|
||||||
definitions:
|
|
||||||
- packages: [mpileaks, callpath]
|
|
||||||
- compilers: ['%%gcc', '%%clang']
|
|
||||||
specs:
|
|
||||||
- matrix:
|
|
||||||
- [$packages]
|
|
||||||
- [$compilers]
|
|
||||||
|
|
||||||
view:
|
|
||||||
combinatorial:
|
|
||||||
root: %s
|
|
||||||
projections:
|
|
||||||
'all': '{name}/{version}-{compiler.name}'"""
|
|
||||||
% viewdir
|
|
||||||
)
|
|
||||||
with tmpdir.as_cwd():
|
|
||||||
env("create", "test", "./spack.yaml")
|
|
||||||
with ev.read("test"):
|
|
||||||
install()
|
|
||||||
|
|
||||||
test = ev.read("test")
|
|
||||||
for spec in test._get_environment_specs():
|
for spec in test._get_environment_specs():
|
||||||
assert os.path.exists(
|
if spec.name == "gcc-runtime":
|
||||||
os.path.join(viewdir, spec.name, "%s-%s" % (spec.version, spec.compiler.name))
|
continue
|
||||||
)
|
current_dir = view_dir / f"{spec.architecture.target}" / f"{spec.name}-{spec.version}"
|
||||||
|
assert current_dir.exists() and current_dir.is_dir()
|
||||||
|
|
||||||
|
|
||||||
def test_stack_view_select(tmpdir, mock_fetch, mock_packages, mock_archive, install_mockery):
|
def test_stack_view_select(installed_environment, template_combinatorial_env, tmp_path):
|
||||||
filename = str(tmpdir.join("spack.yaml"))
|
view_dir = tmp_path / "view"
|
||||||
viewdir = str(tmpdir.join("view"))
|
content = template_combinatorial_env.format(view_config="select: ['target=x86_64']\n")
|
||||||
with open(filename, "w") as f:
|
with installed_environment(content) as test:
|
||||||
f.write(
|
|
||||||
"""\
|
|
||||||
spack:
|
|
||||||
definitions:
|
|
||||||
- packages: [mpileaks, callpath]
|
|
||||||
- compilers: ['%%gcc', '%%clang']
|
|
||||||
specs:
|
|
||||||
- matrix:
|
|
||||||
- [$packages]
|
|
||||||
- [$compilers]
|
|
||||||
|
|
||||||
view:
|
|
||||||
combinatorial:
|
|
||||||
root: %s
|
|
||||||
select: ['%%gcc']
|
|
||||||
projections:
|
|
||||||
'all': '{name}/{version}-{compiler.name}'"""
|
|
||||||
% viewdir
|
|
||||||
)
|
|
||||||
with tmpdir.as_cwd():
|
|
||||||
env("create", "test", "./spack.yaml")
|
|
||||||
with ev.read("test"):
|
|
||||||
install()
|
|
||||||
|
|
||||||
test = ev.read("test")
|
|
||||||
for spec in test._get_environment_specs():
|
for spec in test._get_environment_specs():
|
||||||
if spec.satisfies("%gcc"):
|
if spec.name == "gcc-runtime":
|
||||||
assert os.path.exists(
|
continue
|
||||||
os.path.join(viewdir, spec.name, "%s-%s" % (spec.version, spec.compiler.name))
|
current_dir = view_dir / f"{spec.architecture.target}" / f"{spec.name}-{spec.version}"
|
||||||
)
|
assert current_dir.exists() is spec.satisfies("target=x86_64")
|
||||||
else:
|
|
||||||
assert not os.path.exists(
|
|
||||||
os.path.join(viewdir, spec.name, "%s-%s" % (spec.version, spec.compiler.name))
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_stack_view_exclude(tmpdir, mock_fetch, mock_packages, mock_archive, install_mockery):
|
def test_stack_view_exclude(installed_environment, template_combinatorial_env, tmp_path):
|
||||||
filename = str(tmpdir.join("spack.yaml"))
|
view_dir = tmp_path / "view"
|
||||||
viewdir = str(tmpdir.join("view"))
|
content = template_combinatorial_env.format(view_config="exclude: [callpath]\n")
|
||||||
with open(filename, "w") as f:
|
with installed_environment(content) as test:
|
||||||
f.write(
|
|
||||||
"""\
|
|
||||||
spack:
|
|
||||||
definitions:
|
|
||||||
- packages: [mpileaks, callpath]
|
|
||||||
- compilers: ['%%gcc', '%%clang']
|
|
||||||
specs:
|
|
||||||
- matrix:
|
|
||||||
- [$packages]
|
|
||||||
- [$compilers]
|
|
||||||
|
|
||||||
view:
|
|
||||||
combinatorial:
|
|
||||||
root: %s
|
|
||||||
exclude: [callpath]
|
|
||||||
projections:
|
|
||||||
'all': '{name}/{version}-{compiler.name}'"""
|
|
||||||
% viewdir
|
|
||||||
)
|
|
||||||
with tmpdir.as_cwd():
|
|
||||||
env("create", "test", "./spack.yaml")
|
|
||||||
with ev.read("test"):
|
|
||||||
install()
|
|
||||||
|
|
||||||
test = ev.read("test")
|
|
||||||
for spec in test._get_environment_specs():
|
for spec in test._get_environment_specs():
|
||||||
if not spec.satisfies("callpath"):
|
if spec.name == "gcc-runtime":
|
||||||
assert os.path.exists(
|
continue
|
||||||
os.path.join(viewdir, spec.name, "%s-%s" % (spec.version, spec.compiler.name))
|
current_dir = view_dir / f"{spec.architecture.target}" / f"{spec.name}-{spec.version}"
|
||||||
)
|
assert current_dir.exists() is not spec.satisfies("callpath")
|
||||||
else:
|
|
||||||
assert not os.path.exists(
|
|
||||||
os.path.join(viewdir, spec.name, "%s-%s" % (spec.version, spec.compiler.name))
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_stack_view_select_and_exclude(
|
def test_stack_view_select_and_exclude(
|
||||||
tmpdir, mock_fetch, mock_packages, mock_archive, install_mockery
|
installed_environment, template_combinatorial_env, tmp_path
|
||||||
):
|
):
|
||||||
filename = str(tmpdir.join("spack.yaml"))
|
view_dir = tmp_path / "view"
|
||||||
viewdir = str(tmpdir.join("view"))
|
content = template_combinatorial_env.format(
|
||||||
with open(filename, "w") as f:
|
view_config="""select: ['target=x86_64']
|
||||||
f.write(
|
exclude: [callpath]
|
||||||
"""\
|
"""
|
||||||
spack:
|
)
|
||||||
definitions:
|
with installed_environment(content) as test:
|
||||||
- packages: [mpileaks, callpath]
|
|
||||||
- compilers: ['%%gcc', '%%clang']
|
|
||||||
specs:
|
|
||||||
- matrix:
|
|
||||||
- [$packages]
|
|
||||||
- [$compilers]
|
|
||||||
|
|
||||||
view:
|
|
||||||
combinatorial:
|
|
||||||
root: %s
|
|
||||||
select: ['%%gcc']
|
|
||||||
exclude: [callpath]
|
|
||||||
projections:
|
|
||||||
'all': '{name}/{version}-{compiler.name}'"""
|
|
||||||
% viewdir
|
|
||||||
)
|
|
||||||
with tmpdir.as_cwd():
|
|
||||||
env("create", "test", "./spack.yaml")
|
|
||||||
with ev.read("test"):
|
|
||||||
install()
|
|
||||||
|
|
||||||
test = ev.read("test")
|
|
||||||
for spec in test._get_environment_specs():
|
for spec in test._get_environment_specs():
|
||||||
if spec.satisfies("%gcc") and not spec.satisfies("callpath"):
|
if spec.name == "gcc-runtime":
|
||||||
assert os.path.exists(
|
continue
|
||||||
os.path.join(viewdir, spec.name, "%s-%s" % (spec.version, spec.compiler.name))
|
current_dir = view_dir / f"{spec.architecture.target}" / f"{spec.name}-{spec.version}"
|
||||||
)
|
assert current_dir.exists() is (
|
||||||
else:
|
spec.satisfies("target=x86_64") and not spec.satisfies("callpath")
|
||||||
assert not os.path.exists(
|
)
|
||||||
os.path.join(viewdir, spec.name, "%s-%s" % (spec.version, spec.compiler.name))
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_view_link_roots(tmpdir, mock_fetch, mock_packages, mock_archive, install_mockery):
|
def test_view_link_roots(installed_environment, template_combinatorial_env, tmp_path):
|
||||||
filename = str(tmpdir.join("spack.yaml"))
|
view_dir = tmp_path / "view"
|
||||||
viewdir = str(tmpdir.join("view"))
|
content = template_combinatorial_env.format(
|
||||||
with open(filename, "w") as f:
|
view_config="""select: ['target=x86_64']
|
||||||
f.write(
|
exclude: [callpath]
|
||||||
"""\
|
link: 'roots'
|
||||||
spack:
|
"""
|
||||||
definitions:
|
)
|
||||||
- packages: [mpileaks, callpath]
|
with installed_environment(content) as test:
|
||||||
- compilers: ['%%gcc', '%%clang']
|
|
||||||
specs:
|
|
||||||
- matrix:
|
|
||||||
- [$packages]
|
|
||||||
- [$compilers]
|
|
||||||
|
|
||||||
view:
|
|
||||||
combinatorial:
|
|
||||||
root: %s
|
|
||||||
select: ['%%gcc']
|
|
||||||
exclude: [callpath]
|
|
||||||
link: 'roots'
|
|
||||||
projections:
|
|
||||||
'all': '{name}/{version}-{compiler.name}'"""
|
|
||||||
% viewdir
|
|
||||||
)
|
|
||||||
with tmpdir.as_cwd():
|
|
||||||
env("create", "test", "./spack.yaml")
|
|
||||||
with ev.read("test"):
|
|
||||||
install()
|
|
||||||
|
|
||||||
test = ev.read("test")
|
|
||||||
for spec in test._get_environment_specs():
|
for spec in test._get_environment_specs():
|
||||||
if spec in test.roots() and (
|
if spec.name == "gcc-runtime":
|
||||||
spec.satisfies("%gcc") and not spec.satisfies("callpath")
|
continue
|
||||||
):
|
current_dir = view_dir / f"{spec.architecture.target}" / f"{spec.name}-{spec.version}"
|
||||||
assert os.path.exists(
|
expected_exists = spec in test.roots() and (
|
||||||
os.path.join(viewdir, spec.name, "%s-%s" % (spec.version, spec.compiler.name))
|
spec.satisfies("target=x86_64") and not spec.satisfies("callpath")
|
||||||
)
|
)
|
||||||
else:
|
assert current_dir.exists() == expected_exists
|
||||||
assert not os.path.exists(
|
|
||||||
os.path.join(viewdir, spec.name, "%s-%s" % (spec.version, spec.compiler.name))
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_view_link_run(tmpdir, mock_fetch, mock_packages, mock_archive, install_mockery):
|
def test_view_link_run(tmpdir, mock_fetch, mock_packages, mock_archive, install_mockery):
|
||||||
@@ -3065,169 +2975,84 @@ def test_view_link_run(tmpdir, mock_fetch, mock_packages, mock_archive, install_
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("link_type", ["hardlink", "copy", "symlink"])
|
@pytest.mark.parametrize("link_type", ["hardlink", "copy", "symlink"])
|
||||||
def test_view_link_type(
|
def test_view_link_type(link_type, installed_environment, tmp_path):
|
||||||
link_type, tmpdir, mock_fetch, mock_packages, mock_archive, install_mockery
|
view_dir = tmp_path / "view"
|
||||||
):
|
with installed_environment(
|
||||||
filename = str(tmpdir.join("spack.yaml"))
|
f"""\
|
||||||
viewdir = str(tmpdir.join("view"))
|
|
||||||
with open(filename, "w") as f:
|
|
||||||
f.write(
|
|
||||||
"""\
|
|
||||||
spack:
|
spack:
|
||||||
specs:
|
specs:
|
||||||
- mpileaks
|
- mpileaks
|
||||||
view:
|
view:
|
||||||
default:
|
default:
|
||||||
root: %s
|
root: {view_dir}
|
||||||
link_type: %s"""
|
link_type: {link_type}"""
|
||||||
% (viewdir, link_type)
|
) as test:
|
||||||
)
|
|
||||||
with tmpdir.as_cwd():
|
|
||||||
env("create", "test", "./spack.yaml")
|
|
||||||
with ev.read("test"):
|
|
||||||
install()
|
|
||||||
|
|
||||||
test = ev.read("test")
|
|
||||||
|
|
||||||
for spec in test.roots():
|
for spec in test.roots():
|
||||||
file_path = test.default_view.view()._root
|
# Assertions are based on the behavior of the "--fake" install
|
||||||
file_to_test = os.path.join(file_path, spec.name)
|
bin_file = pathlib.Path(test.default_view.view()._root) / "bin" / spec.name
|
||||||
assert os.path.isfile(file_to_test)
|
assert bin_file.exists()
|
||||||
assert os.path.islink(file_to_test) == (link_type == "symlink")
|
assert bin_file.is_symlink() == (link_type == "symlink")
|
||||||
|
|
||||||
|
|
||||||
def test_view_link_all(tmpdir, mock_fetch, mock_packages, mock_archive, install_mockery):
|
def test_view_link_all(installed_environment, template_combinatorial_env, tmp_path):
|
||||||
filename = str(tmpdir.join("spack.yaml"))
|
view_dir = tmp_path / "view"
|
||||||
viewdir = str(tmpdir.join("view"))
|
content = template_combinatorial_env.format(
|
||||||
with open(filename, "w") as f:
|
view_config="""select: ['target=x86_64']
|
||||||
f.write(
|
exclude: [callpath]
|
||||||
"""\
|
link: 'all'
|
||||||
spack:
|
"""
|
||||||
definitions:
|
)
|
||||||
- packages: [mpileaks, callpath]
|
|
||||||
- compilers: ['%%gcc', '%%clang']
|
|
||||||
specs:
|
|
||||||
- matrix:
|
|
||||||
- [$packages]
|
|
||||||
- [$compilers]
|
|
||||||
|
|
||||||
view:
|
with installed_environment(content) as test:
|
||||||
combinatorial:
|
|
||||||
root: %s
|
|
||||||
select: ['%%gcc']
|
|
||||||
exclude: [callpath]
|
|
||||||
link: 'all'
|
|
||||||
projections:
|
|
||||||
'all': '{name}/{version}-{compiler.name}'"""
|
|
||||||
% viewdir
|
|
||||||
)
|
|
||||||
with tmpdir.as_cwd():
|
|
||||||
env("create", "test", "./spack.yaml")
|
|
||||||
with ev.read("test"):
|
|
||||||
install()
|
|
||||||
|
|
||||||
test = ev.read("test")
|
|
||||||
for spec in test._get_environment_specs():
|
for spec in test._get_environment_specs():
|
||||||
if spec.satisfies("%gcc") and not spec.satisfies("callpath"):
|
if spec.name == "gcc-runtime":
|
||||||
assert os.path.exists(
|
continue
|
||||||
os.path.join(viewdir, spec.name, "%s-%s" % (spec.version, spec.compiler.name))
|
current_dir = view_dir / f"{spec.architecture.target}" / f"{spec.name}-{spec.version}"
|
||||||
)
|
assert current_dir.exists() == (
|
||||||
else:
|
spec.satisfies("target=x86_64") and not spec.satisfies("callpath")
|
||||||
assert not os.path.exists(
|
)
|
||||||
os.path.join(viewdir, spec.name, "%s-%s" % (spec.version, spec.compiler.name))
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_stack_view_activate_from_default(
|
def test_stack_view_activate_from_default(
|
||||||
tmpdir, mock_fetch, mock_packages, mock_archive, install_mockery
|
installed_environment, template_combinatorial_env, tmp_path
|
||||||
):
|
):
|
||||||
filename = str(tmpdir.join("spack.yaml"))
|
view_dir = tmp_path / "view"
|
||||||
viewdir = str(tmpdir.join("view"))
|
content = template_combinatorial_env.format(view_config="select: ['target=x86_64']")
|
||||||
with open(filename, "w") as f:
|
# Replace the name of the view
|
||||||
f.write(
|
content = content.replace("combinatorial:", "default:")
|
||||||
"""\
|
with installed_environment(content):
|
||||||
spack:
|
|
||||||
definitions:
|
|
||||||
- packages: [mpileaks, cmake]
|
|
||||||
- compilers: ['%%gcc', '%%clang']
|
|
||||||
specs:
|
|
||||||
- matrix:
|
|
||||||
- [$packages]
|
|
||||||
- [$compilers]
|
|
||||||
|
|
||||||
view:
|
|
||||||
default:
|
|
||||||
root: %s
|
|
||||||
select: ['%%gcc']"""
|
|
||||||
% viewdir
|
|
||||||
)
|
|
||||||
with tmpdir.as_cwd():
|
|
||||||
env("create", "test", "./spack.yaml")
|
|
||||||
with ev.read("test"):
|
|
||||||
install()
|
|
||||||
|
|
||||||
shell = env("activate", "--sh", "test")
|
shell = env("activate", "--sh", "test")
|
||||||
|
assert "PATH" in shell, shell
|
||||||
assert "PATH" in shell
|
assert str(view_dir / "bin") in shell
|
||||||
assert os.path.join(viewdir, "bin") in shell
|
|
||||||
assert "FOOBAR=mpileaks" in shell
|
assert "FOOBAR=mpileaks" in shell
|
||||||
|
|
||||||
|
|
||||||
def test_stack_view_no_activate_without_default(
|
def test_stack_view_no_activate_without_default(
|
||||||
tmpdir, mock_fetch, mock_packages, mock_archive, install_mockery
|
installed_environment, template_combinatorial_env, tmp_path
|
||||||
):
|
):
|
||||||
filename = str(tmpdir.join("spack.yaml"))
|
view_dir = tmp_path / "view"
|
||||||
viewdir = str(tmpdir.join("view"))
|
content = template_combinatorial_env.format(view_config="select: ['target=x86_64']")
|
||||||
with open(filename, "w") as f:
|
with installed_environment(content):
|
||||||
f.write(
|
|
||||||
"""\
|
|
||||||
spack:
|
|
||||||
definitions:
|
|
||||||
- packages: [mpileaks, cmake]
|
|
||||||
- compilers: ['%%gcc', '%%clang']
|
|
||||||
specs:
|
|
||||||
- matrix:
|
|
||||||
- [$packages]
|
|
||||||
- [$compilers]
|
|
||||||
|
|
||||||
view:
|
|
||||||
not-default:
|
|
||||||
root: %s
|
|
||||||
select: ['%%gcc']"""
|
|
||||||
% viewdir
|
|
||||||
)
|
|
||||||
with tmpdir.as_cwd():
|
|
||||||
env("create", "test", "./spack.yaml")
|
|
||||||
with ev.read("test"):
|
|
||||||
install()
|
|
||||||
|
|
||||||
shell = env("activate", "--sh", "test")
|
shell = env("activate", "--sh", "test")
|
||||||
assert "PATH" not in shell
|
assert "PATH" not in shell
|
||||||
assert viewdir not in shell
|
assert str(view_dir) not in shell
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("include_views", [True, False, "split"])
|
@pytest.mark.parametrize("include_views", [True, False, "split"])
|
||||||
def test_stack_view_multiple_views(
|
def test_stack_view_multiple_views(installed_environment, tmp_path, include_views):
|
||||||
tmp_path,
|
|
||||||
mock_fetch,
|
|
||||||
mock_packages,
|
|
||||||
mock_archive,
|
|
||||||
install_mockery,
|
|
||||||
mutable_config,
|
|
||||||
include_views,
|
|
||||||
):
|
|
||||||
"""Test multiple views as both included views (True), as both environment
|
"""Test multiple views as both included views (True), as both environment
|
||||||
views (False), or as one included and the other in the environment."""
|
views (False), or as one included and the other in the environment.
|
||||||
|
"""
|
||||||
# Write the view configuration and or manifest file
|
# Write the view configuration and or manifest file
|
||||||
view_filename = tmp_path / "view.yaml"
|
view_filename = tmp_path / "view.yaml"
|
||||||
base_content = """\
|
base_content = """\
|
||||||
definitions:
|
definitions:
|
||||||
- packages: [mpileaks, cmake]
|
- packages: [mpileaks, cmake]
|
||||||
- compilers: ['%gcc', '%clang']
|
- targets: ['target=x86_64', 'target=core2']
|
||||||
specs:
|
specs:
|
||||||
- matrix:
|
- matrix:
|
||||||
- [$packages]
|
- [$packages]
|
||||||
- [$compilers]
|
- [$targets]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
include_content = f" include:\n - {view_filename}\n"
|
include_content = f" include:\n - {view_filename}\n"
|
||||||
@@ -3237,17 +3062,17 @@ def test_stack_view_multiple_views(
|
|||||||
comb_view = """\
|
comb_view = """\
|
||||||
{0}combinatorial:
|
{0}combinatorial:
|
||||||
{0} root: {1}
|
{0} root: {1}
|
||||||
{0} exclude: [callpath%gcc]
|
{0} exclude: [target=core2]
|
||||||
{0} projections:
|
{0} projections:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
projection = " 'all': '{name}/{version}-{compiler.name}'"
|
projection = " 'all': '{architecture.target}/{name}-{version}'"
|
||||||
|
|
||||||
default_dir = tmp_path / "default-view"
|
default_dir = tmp_path / "default-view"
|
||||||
default_view = """\
|
default_view = """\
|
||||||
{0}default:
|
{0}default:
|
||||||
{0} root: {1}
|
{0} root: {1}
|
||||||
{0} select: ['%gcc']
|
{0} select: ['target=x86_64']
|
||||||
"""
|
"""
|
||||||
|
|
||||||
content = "spack:\n"
|
content = "spack:\n"
|
||||||
@@ -3272,22 +3097,13 @@ def test_stack_view_multiple_views(
|
|||||||
content += default_view.format(indent, str(default_dir))
|
content += default_view.format(indent, str(default_dir))
|
||||||
content += comb_view.format(indent, str(comb_dir)) + indent + projection
|
content += comb_view.format(indent, str(comb_dir)) + indent + projection
|
||||||
|
|
||||||
filename = tmp_path / ev.manifest_name
|
with installed_environment(content) as e:
|
||||||
filename.write_text(content)
|
|
||||||
|
|
||||||
env("create", "test", str(filename))
|
|
||||||
with ev.read("test"):
|
|
||||||
install()
|
|
||||||
|
|
||||||
with ev.read("test") as e:
|
|
||||||
assert os.path.exists(str(default_dir / "bin"))
|
assert os.path.exists(str(default_dir / "bin"))
|
||||||
for spec in e._get_environment_specs():
|
for spec in e._get_environment_specs():
|
||||||
spec_subdir = f"{spec.version}-{spec.compiler.name}"
|
if spec.name == "gcc-runtime":
|
||||||
comb_spec_dir = str(comb_dir / spec.name / spec_subdir)
|
continue
|
||||||
if not spec.satisfies("callpath%gcc"):
|
current_dir = comb_dir / f"{spec.architecture.target}" / f"{spec.name}-{spec.version}"
|
||||||
assert os.path.exists(comb_spec_dir)
|
assert current_dir.exists() is not spec.satisfies("target=core2")
|
||||||
else:
|
|
||||||
assert not os.path.exists(comb_spec_dir)
|
|
||||||
|
|
||||||
|
|
||||||
def test_env_activate_sh_prints_shell_output(tmpdir, mock_stage, mock_fetch, install_mockery):
|
def test_env_activate_sh_prints_shell_output(tmpdir, mock_stage, mock_fetch, install_mockery):
|
||||||
@@ -3656,12 +3472,10 @@ def test_modules_relative_to_views(environment_from_manifest, install_mockery, m
|
|||||||
assert spec.prefix not in contents
|
assert spec.prefix not in contents
|
||||||
|
|
||||||
|
|
||||||
def test_modules_exist_after_env_install(
|
def test_modules_exist_after_env_install(installed_environment, monkeypatch):
|
||||||
environment_from_manifest, install_mockery, mock_fetch, monkeypatch
|
|
||||||
):
|
|
||||||
# Some caching issue
|
# Some caching issue
|
||||||
monkeypatch.setattr(spack.modules.tcl, "configuration_registry", {})
|
monkeypatch.setattr(spack.modules.tcl, "configuration_registry", {})
|
||||||
environment_from_manifest(
|
with installed_environment(
|
||||||
"""
|
"""
|
||||||
spack:
|
spack:
|
||||||
specs:
|
specs:
|
||||||
@@ -3677,16 +3491,15 @@ def test_modules_exist_after_env_install(
|
|||||||
roots:
|
roots:
|
||||||
tcl: without_view
|
tcl: without_view
|
||||||
"""
|
"""
|
||||||
)
|
) as e:
|
||||||
|
|
||||||
with ev.read("test") as e:
|
|
||||||
install()
|
|
||||||
specs = e.all_specs()
|
specs = e.all_specs()
|
||||||
|
|
||||||
for module_set in ("uses_view", "without_view"):
|
for module_set in ("uses_view", "without_view"):
|
||||||
modules = glob.glob(f"{e.path}/{module_set}/**/*/*")
|
modules = glob.glob(f"{e.path}/{module_set}/**/*/*")
|
||||||
assert len(modules) == len(specs), "Not all modules were generated"
|
assert len(modules) == len(specs), "Not all modules were generated"
|
||||||
for spec in specs:
|
for spec in specs:
|
||||||
|
if spec.external:
|
||||||
|
continue
|
||||||
|
|
||||||
module = next((m for m in modules if os.path.dirname(m).endswith(spec.name)), None)
|
module = next((m for m in modules if os.path.dirname(m).endswith(spec.name)), None)
|
||||||
assert module, f"Module for {spec} not found"
|
assert module, f"Module for {spec} not found"
|
||||||
|
|
||||||
@@ -3728,7 +3541,7 @@ def test_install_develop_keep_stage(
|
|||||||
(mpileaks_spec,) = e.all_matching_specs("mpileaks")
|
(mpileaks_spec,) = e.all_matching_specs("mpileaks")
|
||||||
assert not os.path.exists(libelf_spec.package.stage.path)
|
assert not os.path.exists(libelf_spec.package.stage.path)
|
||||||
assert not os.path.exists(mpileaks_spec.package.stage.path)
|
assert not os.path.exists(mpileaks_spec.package.stage.path)
|
||||||
install()
|
install("--fake")
|
||||||
assert os.path.exists(libelf_spec.package.stage.path)
|
assert os.path.exists(libelf_spec.package.stage.path)
|
||||||
assert not os.path.exists(mpileaks_spec.package.stage.path)
|
assert not os.path.exists(mpileaks_spec.package.stage.path)
|
||||||
|
|
||||||
@@ -3938,7 +3751,7 @@ def test_environment_query_spec_by_hash(mock_stage, mock_fetch, install_mockery)
|
|||||||
concretize()
|
concretize()
|
||||||
with ev.read("test") as e:
|
with ev.read("test") as e:
|
||||||
spec = e.matching_spec("libelf")
|
spec = e.matching_spec("libelf")
|
||||||
install("/{0}".format(spec.dag_hash()))
|
install("--fake", f"/{spec.dag_hash()}")
|
||||||
with ev.read("test") as e:
|
with ev.read("test") as e:
|
||||||
assert not e.matching_spec("libdwarf").installed
|
assert not e.matching_spec("libdwarf").installed
|
||||||
assert e.matching_spec("libelf").installed
|
assert e.matching_spec("libelf").installed
|
||||||
@@ -4401,7 +4214,7 @@ def test_env_include_packages_url(
|
|||||||
ev.activate(env)
|
ev.activate(env)
|
||||||
|
|
||||||
cfg = spack.config.get("packages")
|
cfg = spack.config.get("packages")
|
||||||
assert "openmpi" in cfg["all"]["providers"]["mpi"]
|
assert "mpich" in cfg["all"]["providers"]["mpi"]
|
||||||
|
|
||||||
|
|
||||||
def test_relative_view_path_on_command_line_is_made_absolute(tmp_path):
|
def test_relative_view_path_on_command_line_is_made_absolute(tmp_path):
|
||||||
@@ -4525,7 +4338,7 @@ def test_env_include_mixed_views(tmp_path, mutable_mock_env_path, mutable_config
|
|||||||
|
|
||||||
|
|
||||||
def test_stack_view_multiple_views_same_name(
|
def test_stack_view_multiple_views_same_name(
|
||||||
tmp_path, mock_fetch, mock_packages, mock_archive, install_mockery, mutable_config
|
installed_environment, template_combinatorial_env, tmp_path
|
||||||
):
|
):
|
||||||
"""Test multiple views with the same name combine settings with precedence
|
"""Test multiple views with the same name combine settings with precedence
|
||||||
given to the options in spack.yaml."""
|
given to the options in spack.yaml."""
|
||||||
@@ -4537,58 +4350,52 @@ def test_stack_view_multiple_views_same_name(
|
|||||||
view:
|
view:
|
||||||
default:
|
default:
|
||||||
root: {default_dir}
|
root: {default_dir}
|
||||||
select: ['%gcc']
|
select: ['target=x86_64']
|
||||||
projections:
|
projections:
|
||||||
all: '{{name}}/{{version}}-{{compiler.name}}'
|
all: '{{architecture.target}}/{{name}}-{{version}}-from-view'
|
||||||
"""
|
"""
|
||||||
view_filename.write_text(default_view)
|
view_filename.write_text(default_view)
|
||||||
|
|
||||||
view_dir = tmp_path / "view"
|
view_dir = tmp_path / "view"
|
||||||
content = f"""\
|
with installed_environment(
|
||||||
|
f"""\
|
||||||
spack:
|
spack:
|
||||||
include:
|
include:
|
||||||
- {view_filename}
|
- {view_filename}
|
||||||
definitions:
|
definitions:
|
||||||
- packages: [mpileaks, cmake]
|
- packages: [mpileaks, cmake]
|
||||||
- compilers: ['%gcc', '%clang']
|
- targets: ['target=x86_64', 'target=core2']
|
||||||
|
|
||||||
specs:
|
specs:
|
||||||
- matrix:
|
- matrix:
|
||||||
- [$packages]
|
- [$packages]
|
||||||
- [$compilers]
|
- [$targets]
|
||||||
|
|
||||||
view:
|
view:
|
||||||
default:
|
default:
|
||||||
root: {view_dir}
|
root: {view_dir}
|
||||||
exclude: ['cmake']
|
exclude: ['cmake']
|
||||||
projections:
|
projections:
|
||||||
all: '{{name}}/{{compiler.name}}-{{version}}'
|
all: '{{architecture.target}}/{{name}}-{{version}}'
|
||||||
"""
|
"""
|
||||||
|
) as e:
|
||||||
filename = tmp_path / ev.manifest_name
|
|
||||||
filename.write_text(content)
|
|
||||||
|
|
||||||
env("create", "test", str(filename))
|
|
||||||
with ev.read("test"):
|
|
||||||
install()
|
|
||||||
|
|
||||||
with ev.read("test") as e:
|
|
||||||
# the view root in the included view should NOT exist
|
# the view root in the included view should NOT exist
|
||||||
assert not os.path.exists(str(default_dir))
|
assert not os.path.exists(str(default_dir))
|
||||||
|
|
||||||
for spec in e._get_environment_specs():
|
for spec in e._get_environment_specs():
|
||||||
# no specs will exist in the included view projection
|
# no specs will exist in the included view projection
|
||||||
included_spec_subdir = f"{spec.version}-{spec.compiler.name}"
|
base_dir = view_dir / f"{spec.architecture.target}"
|
||||||
included_spec_dir = str(view_dir / spec.name / included_spec_subdir)
|
included_dir = base_dir / f"{spec.name}-{spec.version}-from-view"
|
||||||
assert not os.path.exists(included_spec_dir)
|
assert not included_dir.exists()
|
||||||
|
|
||||||
# only specs compiled with %gcc (selected in the included view) that
|
# only target=x86_64 specs (selected in the included view) that
|
||||||
# are also not cmake (excluded in the environment view) should exist
|
# are also not cmake (excluded in the environment view) should exist
|
||||||
env_spec_subdir = f"{spec.compiler.name}-{spec.version}"
|
if spec.name == "gcc-runtime":
|
||||||
env_spec_dir = str(view_dir / spec.name / env_spec_subdir)
|
continue
|
||||||
if spec.satisfies("cmake") or spec.satisfies("%clang"):
|
current_dir = view_dir / f"{spec.architecture.target}" / f"{spec.name}-{spec.version}"
|
||||||
assert not os.path.exists(env_spec_dir)
|
assert current_dir.exists() is not (
|
||||||
else:
|
spec.satisfies("cmake") or spec.satisfies("target=core2")
|
||||||
assert os.path.exists(env_spec_dir)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_env_view_resolves_identical_file_conflicts(tmp_path, install_mockery, mock_fetch):
|
def test_env_view_resolves_identical_file_conflicts(tmp_path, install_mockery, mock_fetch):
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ def _check_json_output(spec_list):
|
|||||||
|
|
||||||
|
|
||||||
def _check_json_output_deps(spec_list):
|
def _check_json_output_deps(spec_list):
|
||||||
assert len(spec_list) == 13
|
assert len(spec_list) == 15
|
||||||
|
|
||||||
names = [spec["name"] for spec in spec_list]
|
names = [spec["name"] for spec in spec_list]
|
||||||
assert names.count("mpileaks") == 3
|
assert names.count("mpileaks") == 3
|
||||||
@@ -232,21 +232,28 @@ def test_display_json_deps(database, capsys):
|
|||||||
@pytest.mark.db
|
@pytest.mark.db
|
||||||
def test_find_format(database, config):
|
def test_find_format(database, config):
|
||||||
output = find("--format", "{name}-{^mpi.name}", "mpileaks")
|
output = find("--format", "{name}-{^mpi.name}", "mpileaks")
|
||||||
assert set(output.strip().split("\n")) == set(
|
assert set(output.strip().split("\n")) == {
|
||||||
["mpileaks-zmpi", "mpileaks-mpich", "mpileaks-mpich2"]
|
"mpileaks-zmpi",
|
||||||
)
|
"mpileaks-mpich",
|
||||||
|
"mpileaks-mpich2",
|
||||||
|
}
|
||||||
|
|
||||||
output = find("--format", "{name}-{version}-{compiler.name}-{^mpi.name}", "mpileaks")
|
# FIXME (compiler as nodes): recover the {compiler} in Spec.format
|
||||||
assert "installed package" not in output
|
# output = find("--format", "{name}-{version}-{compiler.name}-{^mpi.name}", "mpileaks")
|
||||||
assert set(output.strip().split("\n")) == set(
|
# assert "installed package" not in output
|
||||||
["mpileaks-2.3-gcc-zmpi", "mpileaks-2.3-gcc-mpich", "mpileaks-2.3-gcc-mpich2"]
|
# assert set(output.strip().split("\n")) == {
|
||||||
)
|
# "mpileaks-2.3-gcc-zmpi",
|
||||||
|
# "mpileaks-2.3-gcc-mpich",
|
||||||
|
# "mpileaks-2.3-gcc-mpich2",
|
||||||
|
# }
|
||||||
|
|
||||||
output = find("--format", "{name}-{^mpi.name}-{hash:7}", "mpileaks")
|
output = find("--format", "{name}-{^mpi.name}-{hash:7}", "mpileaks")
|
||||||
elements = output.strip().split("\n")
|
elements = output.strip().split("\n")
|
||||||
assert set(e[:-7] for e in elements) == set(
|
assert set(e[:-7] for e in elements) == {
|
||||||
["mpileaks-zmpi-", "mpileaks-mpich-", "mpileaks-mpich2-"]
|
"mpileaks-zmpi-",
|
||||||
)
|
"mpileaks-mpich-",
|
||||||
|
"mpileaks-mpich2-",
|
||||||
|
}
|
||||||
|
|
||||||
# hashes are in base32
|
# hashes are in base32
|
||||||
for e in elements:
|
for e in elements:
|
||||||
@@ -265,6 +272,8 @@ def test_find_format_deps(database, config):
|
|||||||
dyninst-8.2
|
dyninst-8.2
|
||||||
libdwarf-20130729
|
libdwarf-20130729
|
||||||
libelf-0.8.13
|
libelf-0.8.13
|
||||||
|
gcc-10.2.1
|
||||||
|
gcc-runtime-10.2.1
|
||||||
zmpi-1.0
|
zmpi-1.0
|
||||||
fake-1.0
|
fake-1.0
|
||||||
|
|
||||||
@@ -275,24 +284,21 @@ def test_find_format_deps(database, config):
|
|||||||
@pytest.mark.db
|
@pytest.mark.db
|
||||||
def test_find_format_deps_paths(database, config):
|
def test_find_format_deps_paths(database, config):
|
||||||
output = find("-dp", "--format", "{name}-{version}", "mpileaks", "^zmpi")
|
output = find("-dp", "--format", "{name}-{version}", "mpileaks", "^zmpi")
|
||||||
|
mpileaks = Spec("mpileaks ^zmpi").concretized()
|
||||||
spec = Spec("mpileaks ^zmpi").concretized()
|
|
||||||
prefixes = [s.prefix for s in spec.traverse()]
|
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
output
|
output
|
||||||
== """\
|
== f"""\
|
||||||
mpileaks-2.3 {0}
|
mpileaks-2.3 {mpileaks.prefix}
|
||||||
callpath-1.0 {1}
|
callpath-1.0 {mpileaks['callpath'].prefix}
|
||||||
dyninst-8.2 {2}
|
dyninst-8.2 {mpileaks['dyninst'].prefix}
|
||||||
libdwarf-20130729 {3}
|
libdwarf-20130729 {mpileaks['libdwarf'].prefix}
|
||||||
libelf-0.8.13 {4}
|
libelf-0.8.13 {mpileaks['libelf'].prefix}
|
||||||
zmpi-1.0 {5}
|
gcc-10.2.1 {mpileaks['gcc'].prefix}
|
||||||
fake-1.0 {6}
|
gcc-runtime-10.2.1 {mpileaks['gcc-runtime'].prefix}
|
||||||
|
zmpi-1.0 {mpileaks['zmpi'].prefix}
|
||||||
|
fake-1.0 {mpileaks['fake'].prefix}
|
||||||
|
|
||||||
""".format(
|
"""
|
||||||
*prefixes
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -309,12 +315,6 @@ def test_find_very_long(database, config):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.db
|
|
||||||
def test_find_show_compiler(database, config):
|
|
||||||
output = find("--no-groups", "--show-full-compiler", "mpileaks")
|
|
||||||
assert "mpileaks@2.3%gcc@10.2.1" in output
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.db
|
@pytest.mark.db
|
||||||
def test_find_not_found(database, config, capsys):
|
def test_find_not_found(database, config, capsys):
|
||||||
with capsys.disabled():
|
with capsys.disabled():
|
||||||
@@ -346,7 +346,7 @@ def test_find_prefix_in_env(
|
|||||||
"""Test `find` formats requiring concrete specs work in environments."""
|
"""Test `find` formats requiring concrete specs work in environments."""
|
||||||
env("create", "test")
|
env("create", "test")
|
||||||
with ev.read("test"):
|
with ev.read("test"):
|
||||||
install("--add", "mpileaks")
|
install("--fake", "--add", "mpileaks")
|
||||||
find("-p")
|
find("-p")
|
||||||
find("-l")
|
find("-l")
|
||||||
find("-L")
|
find("-L")
|
||||||
@@ -456,7 +456,7 @@ def test_environment_with_version_range_in_compiler_doesnt_fail(tmp_path):
|
|||||||
|
|
||||||
with test_environment:
|
with test_environment:
|
||||||
output = find()
|
output = find()
|
||||||
assert "zlib%gcc@12.1.0" in output
|
assert "zlib" in output
|
||||||
|
|
||||||
|
|
||||||
_pkga = (
|
_pkga = (
|
||||||
|
|||||||
@@ -21,7 +21,8 @@
|
|||||||
@pytest.mark.db
|
@pytest.mark.db
|
||||||
def test_gc_without_build_dependency(mutable_database):
|
def test_gc_without_build_dependency(mutable_database):
|
||||||
assert "There are no unused specs." in gc("-yb")
|
assert "There are no unused specs." in gc("-yb")
|
||||||
assert "There are no unused specs." in gc("-y")
|
# 'gcc' is a pure build dependency in the DB
|
||||||
|
assert "There are no unused specs." not in gc("-y")
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.db
|
@pytest.mark.db
|
||||||
@@ -62,7 +63,7 @@ def test_gc_with_environment(mutable_database, mutable_mock_env_path):
|
|||||||
add("cmake")
|
add("cmake")
|
||||||
install()
|
install()
|
||||||
assert mutable_database.query_local("cmake")
|
assert mutable_database.query_local("cmake")
|
||||||
output = gc("-y")
|
output = gc("-by")
|
||||||
assert "Restricting garbage collection" in output
|
assert "Restricting garbage collection" in output
|
||||||
assert "There are no unused specs" in output
|
assert "There are no unused specs" in output
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,16 @@
|
|||||||
find = SpackCommand("find")
|
find = SpackCommand("find")
|
||||||
|
|
||||||
|
|
||||||
|
# @pytest.fixture(autouse=True)
|
||||||
|
# def gcc_runtime_mock_install(mock_packages, monkeypatch):
|
||||||
|
# import spack.pkg.builtin.mock.gcc_runtime
|
||||||
|
#
|
||||||
|
# def _mock_install(self, spec, prefix):
|
||||||
|
# mkdir(prefix.lib)
|
||||||
|
#
|
||||||
|
# monkeypatch.setattr(spack.pkg.builtin.mock.gcc_runtime.GccRuntime, "install", _mock_install)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def noop_install(monkeypatch):
|
def noop_install(monkeypatch):
|
||||||
def noop(*args, **kwargs):
|
def noop(*args, **kwargs):
|
||||||
@@ -54,14 +64,14 @@ def test_install_package_and_dependency(
|
|||||||
):
|
):
|
||||||
log = "test"
|
log = "test"
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
install("--log-format=junit", "--log-file={0}".format(log), "libdwarf")
|
install("--fake", "--log-format=junit", f"--log-file={log}", "libdwarf")
|
||||||
|
|
||||||
files = tmpdir.listdir()
|
files = tmpdir.listdir()
|
||||||
filename = tmpdir.join("{0}.xml".format(log))
|
filename = tmpdir.join(f"{log}.xml")
|
||||||
assert filename in files
|
assert filename in files
|
||||||
|
|
||||||
content = filename.open().read()
|
content = filename.open().read()
|
||||||
assert 'tests="2"' in content
|
assert 'tests="3"' in content
|
||||||
assert 'failures="0"' in content
|
assert 'failures="0"' in content
|
||||||
assert 'errors="0"' in content
|
assert 'errors="0"' in content
|
||||||
|
|
||||||
@@ -97,20 +107,21 @@ def test_install_package_already_installed(
|
|||||||
tmpdir, mock_packages, mock_archive, mock_fetch, install_mockery
|
tmpdir, mock_packages, mock_archive, mock_fetch, install_mockery
|
||||||
):
|
):
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
install("libdwarf")
|
install("--fake", "libdwarf")
|
||||||
install("--log-format=junit", "--log-file=test.xml", "libdwarf")
|
install("--fake", "--log-format=junit", "--log-file=test.xml", "libdwarf")
|
||||||
|
|
||||||
files = tmpdir.listdir()
|
files = tmpdir.listdir()
|
||||||
filename = tmpdir.join("test.xml")
|
filename = tmpdir.join("test.xml")
|
||||||
assert filename in files
|
assert filename in files
|
||||||
|
|
||||||
content = filename.open().read()
|
content = filename.open().read()
|
||||||
assert 'tests="2"' in content
|
print(content)
|
||||||
|
assert 'tests="4"' in content
|
||||||
assert 'failures="0"' in content
|
assert 'failures="0"' in content
|
||||||
assert 'errors="0"' in content
|
assert 'errors="0"' in content
|
||||||
|
|
||||||
skipped = [line for line in content.split("\n") if "skipped" in line]
|
skipped = [line for line in content.split("\n") if "skipped" in line]
|
||||||
assert len(skipped) == 2
|
assert len(skipped) == 4
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
@@ -183,9 +194,8 @@ def test_install_with_source(mock_packages, mock_archive, mock_fetch, install_mo
|
|||||||
|
|
||||||
|
|
||||||
def test_install_env_variables(mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_install_env_variables(mock_packages, mock_archive, mock_fetch, install_mockery):
|
||||||
spec = Spec("libdwarf")
|
spec = Spec("pkg-c").concretized()
|
||||||
spec.concretize()
|
install("pkg-c")
|
||||||
install("libdwarf")
|
|
||||||
assert os.path.isfile(spec.package.install_env_path)
|
assert os.path.isfile(spec.package.install_env_path)
|
||||||
|
|
||||||
|
|
||||||
@@ -204,11 +214,9 @@ def test_show_log_on_error(mock_packages, mock_archive, mock_fetch, install_mock
|
|||||||
|
|
||||||
|
|
||||||
def test_install_overwrite(mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_install_overwrite(mock_packages, mock_archive, mock_fetch, install_mockery):
|
||||||
# Try to install a spec and then to reinstall it.
|
"""Tests installing a spec, and then re-installing it in the same prefix."""
|
||||||
spec = Spec("libdwarf")
|
spec = Spec("pkg-c").concretized()
|
||||||
spec.concretize()
|
install("pkg-c")
|
||||||
|
|
||||||
install("libdwarf")
|
|
||||||
|
|
||||||
# Ignore manifest and install times
|
# Ignore manifest and install times
|
||||||
manifest = os.path.join(
|
manifest = os.path.join(
|
||||||
@@ -230,7 +238,7 @@ def test_install_overwrite(mock_packages, mock_archive, mock_fetch, install_mock
|
|||||||
|
|
||||||
assert bad_md5 != expected_md5
|
assert bad_md5 != expected_md5
|
||||||
|
|
||||||
install("--overwrite", "-y", "libdwarf")
|
install("--overwrite", "-y", "pkg-c")
|
||||||
|
|
||||||
assert os.path.exists(spec.prefix)
|
assert os.path.exists(spec.prefix)
|
||||||
assert fs.hash_directory(spec.prefix, ignore=ignores) == expected_md5
|
assert fs.hash_directory(spec.prefix, ignore=ignores) == expected_md5
|
||||||
@@ -238,13 +246,10 @@ def test_install_overwrite(mock_packages, mock_archive, mock_fetch, install_mock
|
|||||||
|
|
||||||
|
|
||||||
def test_install_overwrite_not_installed(mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_install_overwrite_not_installed(mock_packages, mock_archive, mock_fetch, install_mockery):
|
||||||
# Try to install a spec and then to reinstall it.
|
"""Tests that overwrite doesn't fail if the package is not installed"""
|
||||||
spec = Spec("libdwarf")
|
spec = Spec("pkg-c").concretized()
|
||||||
spec.concretize()
|
|
||||||
|
|
||||||
assert not os.path.exists(spec.prefix)
|
assert not os.path.exists(spec.prefix)
|
||||||
|
install("--overwrite", "-y", "pkg-c")
|
||||||
install("--overwrite", "-y", "libdwarf")
|
|
||||||
assert os.path.exists(spec.prefix)
|
assert os.path.exists(spec.prefix)
|
||||||
|
|
||||||
|
|
||||||
@@ -274,15 +279,11 @@ def test_install_commit(mock_git_version_info, install_mockery, mock_packages, m
|
|||||||
|
|
||||||
def test_install_overwrite_multiple(mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_install_overwrite_multiple(mock_packages, mock_archive, mock_fetch, install_mockery):
|
||||||
# Try to install a spec and then to reinstall it.
|
# Try to install a spec and then to reinstall it.
|
||||||
libdwarf = Spec("libdwarf")
|
libdwarf = Spec("libdwarf").concretized()
|
||||||
libdwarf.concretize()
|
cmake = Spec("cmake").concretized()
|
||||||
|
|
||||||
install("libdwarf")
|
install("--fake", "libdwarf")
|
||||||
|
install("--fake", "cmake")
|
||||||
cmake = Spec("cmake")
|
|
||||||
cmake.concretize()
|
|
||||||
|
|
||||||
install("cmake")
|
|
||||||
|
|
||||||
ld_manifest = os.path.join(
|
ld_manifest = os.path.join(
|
||||||
libdwarf.prefix,
|
libdwarf.prefix,
|
||||||
@@ -318,7 +319,7 @@ def test_install_overwrite_multiple(mock_packages, mock_archive, mock_fetch, ins
|
|||||||
assert bad_libdwarf_md5 != expected_libdwarf_md5
|
assert bad_libdwarf_md5 != expected_libdwarf_md5
|
||||||
assert bad_cmake_md5 != expected_cmake_md5
|
assert bad_cmake_md5 != expected_cmake_md5
|
||||||
|
|
||||||
install("--overwrite", "-y", "libdwarf", "cmake")
|
install("--fake", "--overwrite", "-y", "libdwarf", "cmake")
|
||||||
assert os.path.exists(libdwarf.prefix)
|
assert os.path.exists(libdwarf.prefix)
|
||||||
assert os.path.exists(cmake.prefix)
|
assert os.path.exists(cmake.prefix)
|
||||||
|
|
||||||
@@ -555,10 +556,10 @@ def test_cdash_upload_build_error(tmpdir, mock_fetch, install_mockery, capfd):
|
|||||||
def test_cdash_upload_clean_build(tmpdir, mock_fetch, install_mockery, capfd):
|
def test_cdash_upload_clean_build(tmpdir, mock_fetch, install_mockery, capfd):
|
||||||
# capfd interferes with Spack's capturing of e.g., Build.xml output
|
# capfd interferes with Spack's capturing of e.g., Build.xml output
|
||||||
with capfd.disabled(), tmpdir.as_cwd():
|
with capfd.disabled(), tmpdir.as_cwd():
|
||||||
install("--log-file=cdash_reports", "--log-format=cdash", "pkg-a")
|
install("--log-file=cdash_reports", "--log-format=cdash", "pkg-c")
|
||||||
report_dir = tmpdir.join("cdash_reports")
|
report_dir = tmpdir.join("cdash_reports")
|
||||||
assert report_dir in tmpdir.listdir()
|
assert report_dir in tmpdir.listdir()
|
||||||
report_file = report_dir.join("pkg-a_Build.xml")
|
report_file = report_dir.join("Build.xml")
|
||||||
assert report_file in report_dir.listdir()
|
assert report_file in report_dir.listdir()
|
||||||
content = report_file.open().read()
|
content = report_file.open().read()
|
||||||
assert "</Build>" in content
|
assert "</Build>" in content
|
||||||
@@ -575,14 +576,14 @@ def test_cdash_upload_extra_params(tmpdir, mock_fetch, install_mockery, capfd):
|
|||||||
"--cdash-build=my_custom_build",
|
"--cdash-build=my_custom_build",
|
||||||
"--cdash-site=my_custom_site",
|
"--cdash-site=my_custom_site",
|
||||||
"--cdash-track=my_custom_track",
|
"--cdash-track=my_custom_track",
|
||||||
"pkg-a",
|
"pkg-c",
|
||||||
)
|
)
|
||||||
report_dir = tmpdir.join("cdash_reports")
|
report_dir = tmpdir.join("cdash_reports")
|
||||||
assert report_dir in tmpdir.listdir()
|
assert report_dir in tmpdir.listdir()
|
||||||
report_file = report_dir.join("pkg-a_Build.xml")
|
report_file = report_dir.join("Build.xml")
|
||||||
assert report_file in report_dir.listdir()
|
assert report_file in report_dir.listdir()
|
||||||
content = report_file.open().read()
|
content = report_file.open().read()
|
||||||
assert 'Site BuildName="my_custom_build - pkg-a"' in content
|
assert 'Site BuildName="my_custom_build"' in content
|
||||||
assert 'Name="my_custom_site"' in content
|
assert 'Name="my_custom_site"' in content
|
||||||
assert "-my_custom_track" in content
|
assert "-my_custom_track" in content
|
||||||
|
|
||||||
@@ -592,17 +593,17 @@ def test_cdash_buildstamp_param(tmpdir, mock_fetch, install_mockery, capfd):
|
|||||||
# capfd interferes with Spack's capture of e.g., Build.xml output
|
# capfd interferes with Spack's capture of e.g., Build.xml output
|
||||||
with capfd.disabled(), tmpdir.as_cwd():
|
with capfd.disabled(), tmpdir.as_cwd():
|
||||||
cdash_track = "some_mocked_track"
|
cdash_track = "some_mocked_track"
|
||||||
buildstamp_format = "%Y%m%d-%H%M-{0}".format(cdash_track)
|
buildstamp_format = f"%Y%m%d-%H%M-{cdash_track}"
|
||||||
buildstamp = time.strftime(buildstamp_format, time.localtime(int(time.time())))
|
buildstamp = time.strftime(buildstamp_format, time.localtime(int(time.time())))
|
||||||
install(
|
install(
|
||||||
"--log-file=cdash_reports",
|
"--log-file=cdash_reports",
|
||||||
"--log-format=cdash",
|
"--log-format=cdash",
|
||||||
"--cdash-buildstamp={0}".format(buildstamp),
|
f"--cdash-buildstamp={buildstamp}",
|
||||||
"pkg-a",
|
"pkg-c",
|
||||||
)
|
)
|
||||||
report_dir = tmpdir.join("cdash_reports")
|
report_dir = tmpdir.join("cdash_reports")
|
||||||
assert report_dir in tmpdir.listdir()
|
assert report_dir in tmpdir.listdir()
|
||||||
report_file = report_dir.join("pkg-a_Build.xml")
|
report_file = report_dir.join("Build.xml")
|
||||||
assert report_file in report_dir.listdir()
|
assert report_file in report_dir.listdir()
|
||||||
content = report_file.open().read()
|
content = report_file.open().read()
|
||||||
assert buildstamp in content
|
assert buildstamp in content
|
||||||
@@ -616,9 +617,7 @@ def test_cdash_install_from_spec_json(
|
|||||||
with capfd.disabled(), tmpdir.as_cwd():
|
with capfd.disabled(), tmpdir.as_cwd():
|
||||||
spec_json_path = str(tmpdir.join("spec.json"))
|
spec_json_path = str(tmpdir.join("spec.json"))
|
||||||
|
|
||||||
pkg_spec = Spec("pkg-a")
|
pkg_spec = Spec("pkg-c").concretized()
|
||||||
pkg_spec.concretize()
|
|
||||||
|
|
||||||
with open(spec_json_path, "w") as fd:
|
with open(spec_json_path, "w") as fd:
|
||||||
fd.write(pkg_spec.to_json(hash=ht.dag_hash))
|
fd.write(pkg_spec.to_json(hash=ht.dag_hash))
|
||||||
|
|
||||||
@@ -634,7 +633,7 @@ def test_cdash_install_from_spec_json(
|
|||||||
|
|
||||||
report_dir = tmpdir.join("cdash_reports")
|
report_dir = tmpdir.join("cdash_reports")
|
||||||
assert report_dir in tmpdir.listdir()
|
assert report_dir in tmpdir.listdir()
|
||||||
report_file = report_dir.join("pkg-a_Configure.xml")
|
report_file = report_dir.join("Configure.xml")
|
||||||
assert report_file in report_dir.listdir()
|
assert report_file in report_dir.listdir()
|
||||||
content = report_file.open().read()
|
content = report_file.open().read()
|
||||||
install_command_regex = re.compile(
|
install_command_regex = re.compile(
|
||||||
@@ -643,7 +642,7 @@ def test_cdash_install_from_spec_json(
|
|||||||
m = install_command_regex.search(content)
|
m = install_command_regex.search(content)
|
||||||
assert m
|
assert m
|
||||||
install_command = m.group(1)
|
install_command = m.group(1)
|
||||||
assert "pkg-a@" in install_command
|
assert "pkg-c@" in install_command
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.disable_clean_stage_check
|
@pytest.mark.disable_clean_stage_check
|
||||||
@@ -680,7 +679,7 @@ def test_cache_only_fails(tmpdir, mock_fetch, install_mockery, capfd):
|
|||||||
with capfd.disabled():
|
with capfd.disabled():
|
||||||
out = install("--cache-only", "libdwarf", fail_on_error=False)
|
out = install("--cache-only", "libdwarf", fail_on_error=False)
|
||||||
|
|
||||||
assert "Failed to install libelf" in out
|
assert "Failed to install gcc-runtime" in out
|
||||||
assert "Skipping build of libdwarf" in out
|
assert "Skipping build of libdwarf" in out
|
||||||
assert "was not installed" in out
|
assert "was not installed" in out
|
||||||
|
|
||||||
@@ -814,12 +813,12 @@ def test_install_no_add_in_env(tmpdir, mock_fetch, install_mockery, mutable_mock
|
|||||||
# Activate the environment
|
# Activate the environment
|
||||||
with e:
|
with e:
|
||||||
# Assert using --no-add with a spec not in the env fails
|
# Assert using --no-add with a spec not in the env fails
|
||||||
inst_out = install("--no-add", "boost", fail_on_error=False, output=str)
|
inst_out = install("--fake", "--no-add", "boost", fail_on_error=False, output=str)
|
||||||
|
|
||||||
assert "You can add specs to the environment with 'spack add " in inst_out
|
assert "You can add specs to the environment with 'spack add " in inst_out
|
||||||
|
|
||||||
# Without --add, ensure that two packages "a" get installed
|
# Without --add, ensure that two packages "a" get installed
|
||||||
inst_out = install("pkg-a", output=str)
|
inst_out = install("--fake", "pkg-a", output=str)
|
||||||
assert len([x for x in e.all_specs() if x.installed and x.name == "pkg-a"]) == 2
|
assert len([x for x in e.all_specs() if x.installed and x.name == "pkg-a"]) == 2
|
||||||
|
|
||||||
# Install an unambiguous dependency spec (that already exists as a dep
|
# Install an unambiguous dependency spec (that already exists as a dep
|
||||||
@@ -853,14 +852,14 @@ def test_install_no_add_in_env(tmpdir, mock_fetch, install_mockery, mutable_mock
|
|||||||
# root of the environment as well as installed.
|
# root of the environment as well as installed.
|
||||||
assert b_spec not in e.roots()
|
assert b_spec not in e.roots()
|
||||||
|
|
||||||
install("--add", "pkg-b")
|
install("--fake", "--add", "pkg-b")
|
||||||
|
|
||||||
assert b_spec in e.roots()
|
assert b_spec in e.roots()
|
||||||
assert b_spec not in e.uninstalled_specs()
|
assert b_spec not in e.uninstalled_specs()
|
||||||
|
|
||||||
# Install a novel spec with --add and make sure it is added as a root
|
# Install a novel spec with --add and make sure it is added as a root
|
||||||
# and installed.
|
# and installed.
|
||||||
install("--add", "bowtie")
|
install("--fake", "--add", "bowtie")
|
||||||
|
|
||||||
assert any([s.name == "bowtie" for s in e.roots()])
|
assert any([s.name == "bowtie" for s in e.roots()])
|
||||||
assert not any([s.name == "bowtie" for s in e.uninstalled_specs()])
|
assert not any([s.name == "bowtie" for s in e.uninstalled_specs()])
|
||||||
@@ -888,7 +887,7 @@ def test_cdash_auth_token(tmpdir, mock_fetch, install_mockery, monkeypatch, capf
|
|||||||
# capfd interferes with Spack's capturing
|
# capfd interferes with Spack's capturing
|
||||||
with tmpdir.as_cwd(), capfd.disabled():
|
with tmpdir.as_cwd(), capfd.disabled():
|
||||||
monkeypatch.setenv("SPACK_CDASH_AUTH_TOKEN", "asdf")
|
monkeypatch.setenv("SPACK_CDASH_AUTH_TOKEN", "asdf")
|
||||||
out = install("-v", "--log-file=cdash_reports", "--log-format=cdash", "pkg-a")
|
out = install("--fake", "-v", "--log-file=cdash_reports", "--log-format=cdash", "pkg-a")
|
||||||
assert "Using CDash auth token from environment" in out
|
assert "Using CDash auth token from environment" in out
|
||||||
|
|
||||||
|
|
||||||
@@ -949,7 +948,7 @@ def test_install_env_with_tests_all(
|
|||||||
with ev.read("test"):
|
with ev.read("test"):
|
||||||
test_dep = Spec("test-dependency").concretized()
|
test_dep = Spec("test-dependency").concretized()
|
||||||
add("depb")
|
add("depb")
|
||||||
install("--test", "all")
|
install("--fake", "--test", "all")
|
||||||
assert os.path.exists(test_dep.prefix)
|
assert os.path.exists(test_dep.prefix)
|
||||||
|
|
||||||
|
|
||||||
@@ -961,7 +960,7 @@ def test_install_env_with_tests_root(
|
|||||||
with ev.read("test"):
|
with ev.read("test"):
|
||||||
test_dep = Spec("test-dependency").concretized()
|
test_dep = Spec("test-dependency").concretized()
|
||||||
add("depb")
|
add("depb")
|
||||||
install("--test", "root")
|
install("--fake", "--test", "root")
|
||||||
assert not os.path.exists(test_dep.prefix)
|
assert not os.path.exists(test_dep.prefix)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ def test_manpath_trailing_colon(
|
|||||||
"""Test that the commands generated by load add the MANPATH prefix
|
"""Test that the commands generated by load add the MANPATH prefix
|
||||||
inspections. Also test that Spack correctly preserves the default/existing
|
inspections. Also test that Spack correctly preserves the default/existing
|
||||||
manpath search path via a trailing colon"""
|
manpath search path via a trailing colon"""
|
||||||
install("mpileaks")
|
install("--fake", "mpileaks")
|
||||||
|
|
||||||
sh_out = load(shell, "mpileaks")
|
sh_out = load(shell, "mpileaks")
|
||||||
lines = [line.strip("\n") for line in sh_out.split(commandsep)]
|
lines = [line.strip("\n") for line in sh_out.split(commandsep)]
|
||||||
@@ -49,7 +49,7 @@ def test_load_recursive(install_mockery, mock_fetch, mock_archive, mock_packages
|
|||||||
def test_load_shell(shell, set_command):
|
def test_load_shell(shell, set_command):
|
||||||
"""Test that `spack load` applies prefix inspections of its required runtime deps in
|
"""Test that `spack load` applies prefix inspections of its required runtime deps in
|
||||||
topo-order"""
|
topo-order"""
|
||||||
install("mpileaks")
|
install("--fake", "mpileaks")
|
||||||
mpileaks_spec = spack.spec.Spec("mpileaks").concretized()
|
mpileaks_spec = spack.spec.Spec("mpileaks").concretized()
|
||||||
|
|
||||||
# Ensure our reference variable is clean.
|
# Ensure our reference variable is clean.
|
||||||
@@ -116,7 +116,7 @@ def test_load_includes_run_env(
|
|||||||
"""Tests that environment changes from the package's
|
"""Tests that environment changes from the package's
|
||||||
`setup_run_environment` method are added to the user environment in
|
`setup_run_environment` method are added to the user environment in
|
||||||
addition to the prefix inspections"""
|
addition to the prefix inspections"""
|
||||||
install("mpileaks")
|
install("--fake", "mpileaks")
|
||||||
|
|
||||||
shell_out = load(shell, "mpileaks")
|
shell_out = load(shell, "mpileaks")
|
||||||
|
|
||||||
@@ -126,8 +126,8 @@ def test_load_includes_run_env(
|
|||||||
def test_load_first(install_mockery, mock_fetch, mock_archive, mock_packages):
|
def test_load_first(install_mockery, mock_fetch, mock_archive, mock_packages):
|
||||||
"""Test with and without the --first option"""
|
"""Test with and without the --first option"""
|
||||||
shell = "--bat" if sys.platform == "win32" else "--sh"
|
shell = "--bat" if sys.platform == "win32" else "--sh"
|
||||||
install("libelf@0.8.12")
|
install("--fake", "libelf@0.8.12")
|
||||||
install("libelf@0.8.13")
|
install("--fake", "libelf@0.8.13")
|
||||||
|
|
||||||
# Now there are two versions of libelf, which should cause an error
|
# Now there are two versions of libelf, which should cause an error
|
||||||
out = load(shell, "libelf", fail_on_error=False)
|
out = load(shell, "libelf", fail_on_error=False)
|
||||||
@@ -140,7 +140,7 @@ def test_load_first(install_mockery, mock_fetch, mock_archive, mock_packages):
|
|||||||
|
|
||||||
def test_load_fails_no_shell(install_mockery, mock_fetch, mock_archive, mock_packages):
|
def test_load_fails_no_shell(install_mockery, mock_fetch, mock_archive, mock_packages):
|
||||||
"""Test that spack load prints an error message without a shell."""
|
"""Test that spack load prints an error message without a shell."""
|
||||||
install("mpileaks")
|
install("--fake", "mpileaks")
|
||||||
|
|
||||||
out = load("mpileaks", fail_on_error=False)
|
out = load("mpileaks", fail_on_error=False)
|
||||||
assert "To set up shell support" in out
|
assert "To set up shell support" in out
|
||||||
@@ -166,7 +166,7 @@ def test_unload(
|
|||||||
):
|
):
|
||||||
"""Tests that any variables set in the user environment are undone by the
|
"""Tests that any variables set in the user environment are undone by the
|
||||||
unload command"""
|
unload command"""
|
||||||
install("mpileaks")
|
install("--fake", "mpileaks")
|
||||||
mpileaks_spec = spack.spec.Spec("mpileaks").concretized()
|
mpileaks_spec = spack.spec.Spec("mpileaks").concretized()
|
||||||
|
|
||||||
# Set so unload has something to do
|
# Set so unload has something to do
|
||||||
@@ -187,7 +187,7 @@ def test_unload_fails_no_shell(
|
|||||||
install_mockery, mock_fetch, mock_archive, mock_packages, working_env
|
install_mockery, mock_fetch, mock_archive, mock_packages, working_env
|
||||||
):
|
):
|
||||||
"""Test that spack unload prints an error message without a shell."""
|
"""Test that spack unload prints an error message without a shell."""
|
||||||
install("mpileaks")
|
install("--fake", "mpileaks")
|
||||||
mpileaks_spec = spack.spec.Spec("mpileaks").concretized()
|
mpileaks_spec = spack.spec.Spec("mpileaks").concretized()
|
||||||
os.environ[uenv.spack_loaded_hashes_var] = mpileaks_spec.dag_hash()
|
os.environ[uenv.spack_loaded_hashes_var] = mpileaks_spec.dag_hash()
|
||||||
|
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ def mock_spec():
|
|||||||
def test_location_first(install_mockery, mock_fetch, mock_archive, mock_packages):
|
def test_location_first(install_mockery, mock_fetch, mock_archive, mock_packages):
|
||||||
"""Test with and without the --first option"""
|
"""Test with and without the --first option"""
|
||||||
install = SpackCommand("install")
|
install = SpackCommand("install")
|
||||||
install("libelf@0.8.12")
|
install("--fake", "libelf@0.8.12")
|
||||||
install("libelf@0.8.13")
|
install("--fake", "libelf@0.8.13")
|
||||||
# This would normally return an error without --first
|
# This would normally return an error without --first
|
||||||
assert location("--first", "--install-dir", "libelf")
|
assert location("--first", "--install-dir", "libelf")
|
||||||
|
|
||||||
|
|||||||
@@ -54,19 +54,19 @@ def disable_capture(capfd):
|
|||||||
|
|
||||||
|
|
||||||
def test_logs_cmd_errors(install_mockery, mock_fetch, mock_archive, mock_packages):
|
def test_logs_cmd_errors(install_mockery, mock_fetch, mock_archive, mock_packages):
|
||||||
spec = spack.spec.Spec("libelf").concretized()
|
spec = spack.spec.Spec("pkg-c").concretized()
|
||||||
assert not spec.installed
|
assert not spec.installed
|
||||||
|
|
||||||
with pytest.raises(spack.main.SpackCommandError, match="is not installed or staged"):
|
with pytest.raises(spack.main.SpackCommandError, match="is not installed or staged"):
|
||||||
logs("libelf")
|
logs("pkg-c")
|
||||||
|
|
||||||
with pytest.raises(spack.main.SpackCommandError, match="Too many specs"):
|
with pytest.raises(spack.main.SpackCommandError, match="Too many specs"):
|
||||||
logs("libelf mpi")
|
logs("pkg-c mpi")
|
||||||
|
|
||||||
install("libelf")
|
install("pkg-c")
|
||||||
os.remove(spec.package.install_log_path)
|
os.remove(spec.package.install_log_path)
|
||||||
with pytest.raises(spack.main.SpackCommandError, match="No logs are available"):
|
with pytest.raises(spack.main.SpackCommandError, match="No logs are available"):
|
||||||
logs("libelf")
|
logs("pkg-c")
|
||||||
|
|
||||||
|
|
||||||
def _write_string_to_path(string, path):
|
def _write_string_to_path(string, path):
|
||||||
@@ -98,7 +98,7 @@ def test_dump_logs(install_mockery, mock_fetch, mock_archive, mock_packages, dis
|
|||||||
spack.cmd.logs._logs(cmdline_spec, concrete_spec)
|
spack.cmd.logs._logs(cmdline_spec, concrete_spec)
|
||||||
assert _rewind_collect_and_decode(redirected_stdout) == stage_log_content
|
assert _rewind_collect_and_decode(redirected_stdout) == stage_log_content
|
||||||
|
|
||||||
install("libelf")
|
install("--fake", "libelf")
|
||||||
|
|
||||||
# Sanity check: make sure a path is recorded, regardless of whether
|
# Sanity check: make sure a path is recorded, regardless of whether
|
||||||
# it exists (if it does exist, we will overwrite it with content
|
# it exists (if it does exist, we will overwrite it with content
|
||||||
|
|||||||
@@ -12,7 +12,13 @@
|
|||||||
|
|
||||||
maintainers = spack.main.SpackCommand("maintainers")
|
maintainers = spack.main.SpackCommand("maintainers")
|
||||||
|
|
||||||
MAINTAINED_PACKAGES = ["maintainers-1", "maintainers-2", "maintainers-3", "py-extension1"]
|
MAINTAINED_PACKAGES = [
|
||||||
|
"gcc-runtime",
|
||||||
|
"maintainers-1",
|
||||||
|
"maintainers-2",
|
||||||
|
"maintainers-3",
|
||||||
|
"py-extension1",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def split(output):
|
def split(output):
|
||||||
@@ -35,6 +41,8 @@ def test_all(mock_packages, capfd):
|
|||||||
with capfd.disabled():
|
with capfd.disabled():
|
||||||
out = split(maintainers("--all"))
|
out = split(maintainers("--all"))
|
||||||
assert out == [
|
assert out == [
|
||||||
|
"gcc-runtime:",
|
||||||
|
"haampie",
|
||||||
"maintainers-1:",
|
"maintainers-1:",
|
||||||
"user1,",
|
"user1,",
|
||||||
"user2",
|
"user2",
|
||||||
@@ -60,6 +68,8 @@ def test_all_by_user(mock_packages, capfd):
|
|||||||
with capfd.disabled():
|
with capfd.disabled():
|
||||||
out = split(maintainers("--all", "--by-user"))
|
out = split(maintainers("--all", "--by-user"))
|
||||||
assert out == [
|
assert out == [
|
||||||
|
"haampie:",
|
||||||
|
"gcc-runtime",
|
||||||
"user0:",
|
"user0:",
|
||||||
"maintainers-3",
|
"maintainers-3",
|
||||||
"user1:",
|
"user1:",
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ def test_mark_all_explicit(mutable_database):
|
|||||||
mark("-e", "-a")
|
mark("-e", "-a")
|
||||||
gc("-y")
|
gc("-y")
|
||||||
all_specs = spack.store.STORE.layout.all_specs()
|
all_specs = spack.store.STORE.layout.all_specs()
|
||||||
assert len(all_specs) == 15
|
assert len(all_specs) == 16
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.db
|
@pytest.mark.db
|
||||||
@@ -48,7 +48,7 @@ def test_mark_one_explicit(mutable_database):
|
|||||||
uninstall("-y", "-a", "mpileaks")
|
uninstall("-y", "-a", "mpileaks")
|
||||||
gc("-y")
|
gc("-y")
|
||||||
all_specs = spack.store.STORE.layout.all_specs()
|
all_specs = spack.store.STORE.layout.all_specs()
|
||||||
assert len(all_specs) == 3
|
assert len(all_specs) == 4
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.db
|
@pytest.mark.db
|
||||||
@@ -56,7 +56,7 @@ def test_mark_one_implicit(mutable_database):
|
|||||||
mark("-i", "externaltest")
|
mark("-i", "externaltest")
|
||||||
gc("-y")
|
gc("-y")
|
||||||
all_specs = spack.store.STORE.layout.all_specs()
|
all_specs = spack.store.STORE.layout.all_specs()
|
||||||
assert len(all_specs) == 14
|
assert len(all_specs) == 15
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.db
|
@pytest.mark.db
|
||||||
@@ -65,4 +65,4 @@ def test_mark_all_implicit_then_explicit(mutable_database):
|
|||||||
mark("-e", "-a")
|
mark("-e", "-a")
|
||||||
gc("-y")
|
gc("-y")
|
||||||
all_specs = spack.store.STORE.layout.all_specs()
|
all_specs = spack.store.STORE.layout.all_specs()
|
||||||
assert len(all_specs) == 15
|
assert len(all_specs) == 16
|
||||||
|
|||||||
@@ -351,7 +351,7 @@ def test_mirror_destroy(
|
|||||||
spec_name = "libdwarf"
|
spec_name = "libdwarf"
|
||||||
|
|
||||||
# Put a binary package in a buildcache
|
# Put a binary package in a buildcache
|
||||||
install("--no-cache", spec_name)
|
install("--fake", "--no-cache", spec_name)
|
||||||
buildcache("push", "-u", "-f", mirror_dir.strpath, spec_name)
|
buildcache("push", "-u", "-f", mirror_dir.strpath, spec_name)
|
||||||
|
|
||||||
contents = os.listdir(mirror_dir.strpath)
|
contents = os.listdir(mirror_dir.strpath)
|
||||||
|
|||||||
@@ -15,13 +15,10 @@
|
|||||||
|
|
||||||
|
|
||||||
def test_reindex_basic(mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_reindex_basic(mock_packages, mock_archive, mock_fetch, install_mockery):
|
||||||
install("libelf@0.8.13")
|
install("--fake", "libelf@0.8.13")
|
||||||
install("libelf@0.8.12")
|
install("--fake", "libelf@0.8.12")
|
||||||
|
|
||||||
all_installed = spack.store.STORE.db.query()
|
all_installed = spack.store.STORE.db.query()
|
||||||
|
|
||||||
reindex()
|
reindex()
|
||||||
|
|
||||||
assert spack.store.STORE.db.query() == all_installed
|
assert spack.store.STORE.db.query() == all_installed
|
||||||
|
|
||||||
|
|
||||||
@@ -36,23 +33,19 @@ def _clear_db(tmp_path):
|
|||||||
|
|
||||||
|
|
||||||
def test_reindex_db_deleted(mock_packages, mock_archive, mock_fetch, install_mockery, tmp_path):
|
def test_reindex_db_deleted(mock_packages, mock_archive, mock_fetch, install_mockery, tmp_path):
|
||||||
install("libelf@0.8.13")
|
install("--fake", "libelf@0.8.13")
|
||||||
install("libelf@0.8.12")
|
install("--fake", "libelf@0.8.12")
|
||||||
|
|
||||||
all_installed = spack.store.STORE.db.query()
|
all_installed = spack.store.STORE.db.query()
|
||||||
|
|
||||||
_clear_db(tmp_path)
|
_clear_db(tmp_path)
|
||||||
|
|
||||||
reindex()
|
reindex()
|
||||||
|
|
||||||
assert spack.store.STORE.db.query() == all_installed
|
assert spack.store.STORE.db.query() == all_installed
|
||||||
|
|
||||||
|
|
||||||
def test_reindex_with_deprecated_packages(
|
def test_reindex_with_deprecated_packages(
|
||||||
mock_packages, mock_archive, mock_fetch, install_mockery, tmp_path
|
mock_packages, mock_archive, mock_fetch, install_mockery, tmp_path
|
||||||
):
|
):
|
||||||
install("libelf@0.8.13")
|
install("--fake", "libelf@0.8.13")
|
||||||
install("libelf@0.8.12")
|
install("--fake", "libelf@0.8.12")
|
||||||
|
|
||||||
deprecate("-y", "libelf@0.8.12", "libelf@0.8.13")
|
deprecate("-y", "libelf@0.8.12", "libelf@0.8.13")
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ def test_test_dup_alias(
|
|||||||
mock_test_stage, mock_packages, mock_archive, mock_fetch, install_mockery, capfd
|
mock_test_stage, mock_packages, mock_archive, mock_fetch, install_mockery, capfd
|
||||||
):
|
):
|
||||||
"""Ensure re-using an alias fails with suggestion to change."""
|
"""Ensure re-using an alias fails with suggestion to change."""
|
||||||
install("libdwarf")
|
install("--fake", "libdwarf")
|
||||||
|
|
||||||
# Run the (no) tests with the alias once
|
# Run the (no) tests with the alias once
|
||||||
spack_test("run", "--alias", "libdwarf", "libdwarf")
|
spack_test("run", "--alias", "libdwarf", "libdwarf")
|
||||||
|
|||||||
@@ -78,9 +78,8 @@ def test_recursive_uninstall(mutable_database):
|
|||||||
"""Test recursive uninstall."""
|
"""Test recursive uninstall."""
|
||||||
uninstall("-y", "-a", "--dependents", "callpath")
|
uninstall("-y", "-a", "--dependents", "callpath")
|
||||||
|
|
||||||
all_specs = spack.store.STORE.layout.all_specs()
|
|
||||||
assert len(all_specs) == 9
|
|
||||||
# query specs with multiple configurations
|
# query specs with multiple configurations
|
||||||
|
all_specs = spack.store.STORE.layout.all_specs()
|
||||||
mpileaks_specs = [s for s in all_specs if s.satisfies("mpileaks")]
|
mpileaks_specs = [s for s in all_specs if s.satisfies("mpileaks")]
|
||||||
callpath_specs = [s for s in all_specs if s.satisfies("callpath")]
|
callpath_specs = [s for s in all_specs if s.satisfies("callpath")]
|
||||||
mpi_specs = [s for s in all_specs if s.satisfies("mpi")]
|
mpi_specs = [s for s in all_specs if s.satisfies("mpi")]
|
||||||
@@ -92,23 +91,21 @@ def test_recursive_uninstall(mutable_database):
|
|||||||
|
|
||||||
@pytest.mark.db
|
@pytest.mark.db
|
||||||
@pytest.mark.regression("3690")
|
@pytest.mark.regression("3690")
|
||||||
@pytest.mark.parametrize("constraint,expected_number_of_specs", [("dyninst", 8), ("libelf", 6)])
|
@pytest.mark.parametrize("constraint,expected_number_of_specs", [("dyninst", 9), ("libelf", 7)])
|
||||||
def test_uninstall_spec_with_multiple_roots(
|
def test_uninstall_spec_with_multiple_roots(
|
||||||
constraint, expected_number_of_specs, mutable_database
|
constraint, expected_number_of_specs, mutable_database
|
||||||
):
|
):
|
||||||
uninstall("-y", "-a", "--dependents", constraint)
|
uninstall("-y", "-a", "--dependents", constraint)
|
||||||
|
|
||||||
all_specs = spack.store.STORE.layout.all_specs()
|
all_specs = spack.store.STORE.layout.all_specs()
|
||||||
assert len(all_specs) == expected_number_of_specs
|
assert len(all_specs) == expected_number_of_specs
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.db
|
@pytest.mark.db
|
||||||
@pytest.mark.parametrize("constraint,expected_number_of_specs", [("dyninst", 14), ("libelf", 14)])
|
@pytest.mark.parametrize("constraint,expected_number_of_specs", [("dyninst", 15), ("libelf", 15)])
|
||||||
def test_force_uninstall_spec_with_ref_count_not_zero(
|
def test_force_uninstall_spec_with_ref_count_not_zero(
|
||||||
constraint, expected_number_of_specs, mutable_database
|
constraint, expected_number_of_specs, mutable_database
|
||||||
):
|
):
|
||||||
uninstall("-f", "-y", constraint)
|
uninstall("-f", "-y", constraint)
|
||||||
|
|
||||||
all_specs = spack.store.STORE.layout.all_specs()
|
all_specs = spack.store.STORE.layout.all_specs()
|
||||||
assert len(all_specs) == expected_number_of_specs
|
assert len(all_specs) == expected_number_of_specs
|
||||||
|
|
||||||
@@ -174,7 +171,7 @@ def db_specs():
|
|||||||
|
|
||||||
all_specs, mpileaks_specs, callpath_specs, mpi_specs = db_specs()
|
all_specs, mpileaks_specs, callpath_specs, mpi_specs = db_specs()
|
||||||
total_specs = len(all_specs)
|
total_specs = len(all_specs)
|
||||||
assert total_specs == 14
|
assert total_specs == 15
|
||||||
assert len(mpileaks_specs) == 3
|
assert len(mpileaks_specs) == 3
|
||||||
assert len(callpath_specs) == 2
|
assert len(callpath_specs) == 2
|
||||||
assert len(mpi_specs) == 3
|
assert len(mpi_specs) == 3
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ def test_single_file_verify_cmd(tmpdir):
|
|||||||
|
|
||||||
def test_single_spec_verify_cmd(tmpdir, mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_single_spec_verify_cmd(tmpdir, mock_packages, mock_archive, mock_fetch, install_mockery):
|
||||||
# Test the verify command interface to verify a single spec
|
# Test the verify command interface to verify a single spec
|
||||||
install("libelf")
|
install("--fake", "libelf")
|
||||||
s = spack.spec.Spec("libelf").concretized()
|
s = spack.spec.Spec("libelf").concretized()
|
||||||
prefix = s.prefix
|
prefix = s.prefix
|
||||||
hash = s.dag_hash()
|
hash = s.dag_hash()
|
||||||
|
|||||||
@@ -31,26 +31,26 @@
|
|||||||
commands = ["hardlink", "symlink", "hard", "add", "copy", "relocate"]
|
commands = ["hardlink", "symlink", "hard", "add", "copy", "relocate"]
|
||||||
|
|
||||||
|
|
||||||
def create_projection_file(tmpdir, projection):
|
def create_projection_file(tmp_path, projection):
|
||||||
if "projections" not in projection:
|
if "projections" not in projection:
|
||||||
projection = {"projections": projection}
|
projection = {"projections": projection}
|
||||||
|
projection_file = tmp_path / "projection" / "projection.yaml"
|
||||||
projection_file = tmpdir.mkdir("projection").join("projection.yaml")
|
projection_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
projection_file.write(s_yaml.dump(projection))
|
projection_file.write_text(s_yaml.dump(projection))
|
||||||
return projection_file
|
return projection_file
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("cmd", commands)
|
@pytest.mark.parametrize("cmd", commands)
|
||||||
def test_view_link_type(tmpdir, mock_packages, mock_archive, mock_fetch, install_mockery, cmd):
|
def test_view_link_type(tmp_path, mock_packages, mock_archive, mock_fetch, install_mockery, cmd):
|
||||||
install("libdwarf")
|
install("--fake", "libdwarf")
|
||||||
viewpath = str(tmpdir.mkdir("view_{0}".format(cmd)))
|
view_dir = tmp_path / f"view_{cmd}"
|
||||||
view(cmd, viewpath, "libdwarf")
|
view(cmd, str(view_dir), "libdwarf")
|
||||||
package_prefix = os.path.join(viewpath, "libdwarf")
|
package_bin = view_dir / "bin" / "libdwarf"
|
||||||
assert os.path.exists(package_prefix)
|
assert package_bin.exists()
|
||||||
|
|
||||||
# Check that we use symlinks for and only for the appropriate subcommands
|
# Check that we use symlinks for and only for the appropriate subcommands
|
||||||
is_link_cmd = cmd in ("symlink", "add")
|
is_link_cmd = cmd in ("symlink", "add")
|
||||||
assert os.path.islink(package_prefix) == is_link_cmd
|
assert os.path.islink(str(package_bin)) == is_link_cmd
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("add_cmd", commands)
|
@pytest.mark.parametrize("add_cmd", commands)
|
||||||
@@ -68,60 +68,60 @@ def test_view_link_type_remove(
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("cmd", commands)
|
@pytest.mark.parametrize("cmd", commands)
|
||||||
def test_view_projections(tmpdir, mock_packages, mock_archive, mock_fetch, install_mockery, cmd):
|
def test_view_projections(tmp_path, mock_packages, mock_archive, mock_fetch, install_mockery, cmd):
|
||||||
install("libdwarf@20130207")
|
install("--fake", "libdwarf@20130207")
|
||||||
|
view_dir = tmp_path / f"view_{cmd}"
|
||||||
|
|
||||||
viewpath = str(tmpdir.mkdir("view_{0}".format(cmd)))
|
|
||||||
view_projection = {"projections": {"all": "{name}-{version}"}}
|
view_projection = {"projections": {"all": "{name}-{version}"}}
|
||||||
projection_file = create_projection_file(tmpdir, view_projection)
|
projection_file = create_projection_file(tmp_path, view_projection)
|
||||||
view(cmd, viewpath, "--projection-file={0}".format(projection_file), "libdwarf")
|
view(cmd, str(view_dir), f"--projection-file={projection_file}", "libdwarf")
|
||||||
|
|
||||||
package_prefix = os.path.join(viewpath, "libdwarf-20130207/libdwarf")
|
package_bin = view_dir / "libdwarf-20130207" / "bin" / "libdwarf"
|
||||||
assert os.path.exists(package_prefix)
|
assert package_bin.exists()
|
||||||
|
|
||||||
# Check that we use symlinks for and only for the appropriate subcommands
|
# Check that we use symlinks for and only for the appropriate subcommands
|
||||||
is_symlink_cmd = cmd in ("symlink", "add")
|
is_symlink_cmd = cmd in ("symlink", "add")
|
||||||
assert os.path.islink(package_prefix) == is_symlink_cmd
|
assert package_bin.is_symlink() == is_symlink_cmd
|
||||||
|
|
||||||
|
|
||||||
def test_view_multiple_projections(
|
def test_view_multiple_projections(
|
||||||
tmpdir, mock_packages, mock_archive, mock_fetch, install_mockery
|
tmp_path, mock_packages, mock_archive, mock_fetch, install_mockery
|
||||||
):
|
):
|
||||||
install("libdwarf@20130207")
|
install("--fake", "libdwarf@20130207")
|
||||||
install("extendee@1.0%gcc")
|
install("--fake", "extendee@1.0")
|
||||||
|
view_dir = tmp_path / "view"
|
||||||
|
|
||||||
viewpath = str(tmpdir.mkdir("view"))
|
|
||||||
view_projection = s_yaml.syaml_dict(
|
view_projection = s_yaml.syaml_dict(
|
||||||
[("extendee", "{name}-{compiler.name}"), ("all", "{name}-{version}")]
|
[("extendee", "{name}-{architecture.platform}"), ("all", "{name}-{version}")]
|
||||||
)
|
)
|
||||||
|
|
||||||
projection_file = create_projection_file(tmpdir, view_projection)
|
projection_file = create_projection_file(tmp_path, view_projection)
|
||||||
view("add", viewpath, "--projection-file={0}".format(projection_file), "libdwarf", "extendee")
|
view("add", str(view_dir), f"--projection-file={projection_file}", "libdwarf", "extendee")
|
||||||
|
|
||||||
libdwarf_prefix = os.path.join(viewpath, "libdwarf-20130207/libdwarf")
|
libdwarf_prefix = view_dir / "libdwarf-20130207" / "bin"
|
||||||
extendee_prefix = os.path.join(viewpath, "extendee-gcc/bin")
|
extendee_prefix = view_dir / "extendee-test" / "bin"
|
||||||
assert os.path.exists(libdwarf_prefix)
|
assert libdwarf_prefix.exists()
|
||||||
assert os.path.exists(extendee_prefix)
|
assert extendee_prefix.exists()
|
||||||
|
|
||||||
|
|
||||||
def test_view_multiple_projections_all_first(
|
def test_view_multiple_projections_all_first(
|
||||||
tmpdir, mock_packages, mock_archive, mock_fetch, install_mockery
|
tmp_path, mock_packages, mock_archive, mock_fetch, install_mockery
|
||||||
):
|
):
|
||||||
install("libdwarf@20130207")
|
install("--fake", "libdwarf@20130207")
|
||||||
install("extendee@1.0%gcc")
|
install("--fake", "extendee@1.0")
|
||||||
|
view_dir = tmp_path / "view"
|
||||||
|
|
||||||
viewpath = str(tmpdir.mkdir("view"))
|
|
||||||
view_projection = s_yaml.syaml_dict(
|
view_projection = s_yaml.syaml_dict(
|
||||||
[("all", "{name}-{version}"), ("extendee", "{name}-{compiler.name}")]
|
[("all", "{name}-{version}"), ("extendee", "{name}-{architecture.platform}")]
|
||||||
)
|
)
|
||||||
|
|
||||||
projection_file = create_projection_file(tmpdir, view_projection)
|
projection_file = create_projection_file(tmp_path, view_projection)
|
||||||
view("add", viewpath, "--projection-file={0}".format(projection_file), "libdwarf", "extendee")
|
view("add", str(view_dir), f"--projection-file={projection_file}", "libdwarf", "extendee")
|
||||||
|
|
||||||
libdwarf_prefix = os.path.join(viewpath, "libdwarf-20130207/libdwarf")
|
libdwarf_prefix = view_dir / "libdwarf-20130207" / "bin"
|
||||||
extendee_prefix = os.path.join(viewpath, "extendee-gcc/bin")
|
extendee_prefix = view_dir / "extendee-test" / "bin"
|
||||||
assert os.path.exists(libdwarf_prefix)
|
assert libdwarf_prefix.exists()
|
||||||
assert os.path.exists(extendee_prefix)
|
assert extendee_prefix.exists()
|
||||||
|
|
||||||
|
|
||||||
def test_view_external(tmpdir, mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_view_external(tmpdir, mock_packages, mock_archive, mock_fetch, install_mockery):
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ def test_compile_dummy_c_source_no_verbose_flags(self, mock_gcc, monkeypatch):
|
|||||||
detector = spack.compilers.libraries.CompilerPropertyDetector(mock_gcc)
|
detector = spack.compilers.libraries.CompilerPropertyDetector(mock_gcc)
|
||||||
assert detector._compile_dummy_c_source() is None
|
assert detector._compile_dummy_c_source() is None
|
||||||
|
|
||||||
|
@pytest.mark.not_on_windows("Module files are not supported on Windows")
|
||||||
def test_compile_dummy_c_source_load_env(self, mock_gcc, monkeypatch, tmp_path):
|
def test_compile_dummy_c_source_load_env(self, mock_gcc, monkeypatch, tmp_path):
|
||||||
gcc = tmp_path / "gcc"
|
gcc = tmp_path / "gcc"
|
||||||
gcc.write_text(
|
gcc.write_text(
|
||||||
@@ -104,10 +105,13 @@ def module(*args):
|
|||||||
@pytest.mark.not_on_windows("Not supported on Windows")
|
@pytest.mark.not_on_windows("Not supported on Windows")
|
||||||
def test_implicit_rpaths(self, mock_gcc, dirs_with_libfiles, monkeypatch):
|
def test_implicit_rpaths(self, mock_gcc, dirs_with_libfiles, monkeypatch):
|
||||||
lib_to_dirs, all_dirs = dirs_with_libfiles
|
lib_to_dirs, all_dirs = dirs_with_libfiles
|
||||||
monkeypatch.setattr(spack.compilers.libraries.CompilerPropertyDetector, "_CACHE", {})
|
|
||||||
|
|
||||||
detector = spack.compilers.libraries.CompilerPropertyDetector(mock_gcc)
|
detector = spack.compilers.libraries.CompilerPropertyDetector(mock_gcc)
|
||||||
detector._CACHE[mock_gcc.dag_hash()] = "ld " + " ".join(f"-L{d}" for d in all_dirs)
|
monkeypatch.setattr(
|
||||||
|
spack.compilers.libraries.CompilerPropertyDetector,
|
||||||
|
"_compile_dummy_c_source",
|
||||||
|
lambda self: "ld " + " ".join(f"-L{d}" for d in all_dirs),
|
||||||
|
)
|
||||||
|
|
||||||
retrieved_rpaths = detector.implicit_rpaths()
|
retrieved_rpaths = detector.implicit_rpaths()
|
||||||
assert set(retrieved_rpaths) == set(lib_to_dirs["libstdc++"] + lib_to_dirs["libgfortran"])
|
assert set(retrieved_rpaths) == set(lib_to_dirs["libstdc++"] + lib_to_dirs["libgfortran"])
|
||||||
|
|||||||
@@ -17,8 +17,6 @@
|
|||||||
from spack.environment.environment import ViewDescriptor
|
from spack.environment.environment import ViewDescriptor
|
||||||
from spack.version import Version
|
from spack.version import Version
|
||||||
|
|
||||||
pytestmark = [pytest.mark.usefixtures("enable_runtimes")]
|
|
||||||
|
|
||||||
|
|
||||||
def _concretize_with_reuse(*, root_str, reused_str):
|
def _concretize_with_reuse(*, root_str, reused_str):
|
||||||
reused_spec = spack.spec.Spec(reused_str).concretized()
|
reused_spec = spack.spec.Spec(reused_str).concretized()
|
||||||
@@ -36,14 +34,6 @@ def runtime_repo(mutable_config):
|
|||||||
yield mock_repo
|
yield mock_repo
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def enable_runtimes():
|
|
||||||
original = spack.solver.asp.WITH_RUNTIME
|
|
||||||
spack.solver.asp.WITH_RUNTIME = True
|
|
||||||
yield
|
|
||||||
spack.solver.asp.WITH_RUNTIME = original
|
|
||||||
|
|
||||||
|
|
||||||
def test_correct_gcc_runtime_is_injected_as_dependency(runtime_repo):
|
def test_correct_gcc_runtime_is_injected_as_dependency(runtime_repo):
|
||||||
s = spack.spec.Spec("pkg-a%gcc@10.2.1 ^pkg-b%gcc@9.4.0").concretized()
|
s = spack.spec.Spec("pkg-a%gcc@10.2.1 ^pkg-b%gcc@9.4.0").concretized()
|
||||||
a, b = s["pkg-a"], s["pkg-b"]
|
a, b = s["pkg-a"], s["pkg-b"]
|
||||||
|
|||||||
@@ -458,11 +458,13 @@ def test_compiler_flag_propagation(self, spec_str, expected, not_expected):
|
|||||||
for constraint in not_expected:
|
for constraint in not_expected:
|
||||||
assert not root.satisfies(constraint)
|
assert not root.satisfies(constraint)
|
||||||
|
|
||||||
|
@pytest.mark.xfail(reason="FIXME (compiler as nodes): flaky test, revisit")
|
||||||
def test_mixing_compilers_only_affects_subdag(self):
|
def test_mixing_compilers_only_affects_subdag(self):
|
||||||
"""Tests that, when we mix compilers, the one with lower penalty is used for nodes
|
"""Tests that, when we mix compilers, the one with lower penalty is used for nodes
|
||||||
where the compiler is not forced.
|
where the compiler is not forced.
|
||||||
"""
|
"""
|
||||||
spec = Spec("dt-diamond%clang ^dt-diamond-bottom%gcc").concretized()
|
spec = Spec("dt-diamond%clang ^dt-diamond-bottom%gcc").concretized()
|
||||||
|
|
||||||
for x in spec.traverse(deptype=("link", "run")):
|
for x in spec.traverse(deptype=("link", "run")):
|
||||||
if "c" not in x or not x.name.startswith("dt-diamond"):
|
if "c" not in x or not x.name.startswith("dt-diamond"):
|
||||||
continue
|
continue
|
||||||
@@ -470,8 +472,7 @@ def test_mixing_compilers_only_affects_subdag(self):
|
|||||||
assert bool(x.dependencies(name="llvm", deptype="build")) is not expected_gcc
|
assert bool(x.dependencies(name="llvm", deptype="build")) is not expected_gcc
|
||||||
assert bool(x.dependencies(name="gcc", deptype="build")) is expected_gcc
|
assert bool(x.dependencies(name="gcc", deptype="build")) is expected_gcc
|
||||||
assert x.satisfies("%clang") is not expected_gcc
|
assert x.satisfies("%clang") is not expected_gcc
|
||||||
# FIXME (compiler as nodes): satisfies semantic should be only for direct build deps
|
assert x.satisfies("%gcc") is expected_gcc
|
||||||
# assert x.satisfies("%gcc") is expected_gcc
|
|
||||||
|
|
||||||
def test_compiler_inherited_upwards(self):
|
def test_compiler_inherited_upwards(self):
|
||||||
spec = Spec("dt-diamond ^dt-diamond-bottom%clang").concretized()
|
spec = Spec("dt-diamond ^dt-diamond-bottom%clang").concretized()
|
||||||
@@ -936,13 +937,13 @@ def test_noversion_pkg(self, spec):
|
|||||||
[
|
[
|
||||||
(
|
(
|
||||||
"mpileaks%gcc@=4.4.7 ^dyninst@=10.2.1 target=x86_64:",
|
"mpileaks%gcc@=4.4.7 ^dyninst@=10.2.1 target=x86_64:",
|
||||||
"gcc@4.4.7 languages=c,cxx,fortran",
|
"gcc@4.4.7 languages=c,c++,fortran",
|
||||||
"core2",
|
"core2",
|
||||||
),
|
),
|
||||||
("mpileaks%gcc@=4.8 target=x86_64:", "gcc@4.8 languages=c,cxx,fortran", "haswell"),
|
("mpileaks%gcc@=4.8 target=x86_64:", "gcc@4.8 languages=c,c++,fortran", "haswell"),
|
||||||
(
|
(
|
||||||
"mpileaks%gcc@=5.3.0 target=x86_64:",
|
"mpileaks%gcc@=5.3.0 target=x86_64:",
|
||||||
"gcc@5.3.0 languages=c,cxx,fortran",
|
"gcc@5.3.0 languages=c,c++,fortran",
|
||||||
"broadwell",
|
"broadwell",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -989,7 +990,6 @@ def test_concretize_anonymous_dep(self, spec_str):
|
|||||||
("bowtie@1.4.0", "%gcc@10.2.1"),
|
("bowtie@1.4.0", "%gcc@10.2.1"),
|
||||||
# Version with conflicts and no valid gcc select another compiler
|
# Version with conflicts and no valid gcc select another compiler
|
||||||
("bowtie@1.3.0", "%clang@15.0.0"),
|
("bowtie@1.3.0", "%clang@15.0.0"),
|
||||||
# FIXME (compiler as nodes): does this make sense?
|
|
||||||
# If a higher gcc is available, with a worse os, still prefer that
|
# If a higher gcc is available, with a worse os, still prefer that
|
||||||
("bowtie@1.2.2", "%gcc@11.1.0"),
|
("bowtie@1.2.2", "%gcc@11.1.0"),
|
||||||
],
|
],
|
||||||
@@ -1456,31 +1456,6 @@ def test_external_with_non_default_variant_as_dependency(self):
|
|||||||
assert "~bar" in s["external-non-default-variant"]
|
assert "~bar" in s["external-non-default-variant"]
|
||||||
assert s["external-non-default-variant"].external
|
assert s["external-non-default-variant"].external
|
||||||
|
|
||||||
# FIXME (compiler as nodes): revisit this test
|
|
||||||
# @pytest.mark.regression("22871")
|
|
||||||
# @pytest.mark.parametrize(
|
|
||||||
# "spec_str,expected_os",
|
|
||||||
# [
|
|
||||||
# ("mpileaks", "os=debian6"),
|
|
||||||
# # To trigger the bug in 22871 we need to have the same compiler
|
|
||||||
# # spec available on both operating systems
|
|
||||||
# ("mpileaks%gcc@10.2.1 platform=test os=debian6", "os=debian6"),
|
|
||||||
# ("mpileaks%gcc@10.2.1 platform=test os=redhat6", "os=redhat6"),
|
|
||||||
# ],
|
|
||||||
# )
|
|
||||||
# def test_os_selection_when_multiple_choices_are_possible(
|
|
||||||
# self, spec_str, expected_os, compiler_factory
|
|
||||||
# ):
|
|
||||||
# # GCC 10.2.1 is defined both for debian and for redhat
|
|
||||||
# with spack.config.override(
|
|
||||||
# "packages", {"gcc": {"externals": [compiler_factory(spec="gcc@10.2.1 os=redhat6")]}}
|
|
||||||
# ):
|
|
||||||
# s = Spec(spec_str).concretized()
|
|
||||||
# for node in s.traverse():
|
|
||||||
# if node.name == "glibc":
|
|
||||||
# continue
|
|
||||||
# assert node.satisfies(expected_os)
|
|
||||||
|
|
||||||
@pytest.mark.regression("22718")
|
@pytest.mark.regression("22718")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"spec_str,expected_compiler",
|
"spec_str,expected_compiler",
|
||||||
@@ -1778,12 +1753,11 @@ def test_reuse_with_unknown_package_dont_raise(self, tmpdir, temporary_store, mo
|
|||||||
(["libdwarf%gcc", "libelf%clang"], {"libdwarf": 1, "libelf": 1}),
|
(["libdwarf%gcc", "libelf%clang"], {"libdwarf": 1, "libelf": 1}),
|
||||||
(["libdwarf%gcc", "libdwarf%clang"], {"libdwarf": 2, "libelf": 1}),
|
(["libdwarf%gcc", "libdwarf%clang"], {"libdwarf": 2, "libelf": 1}),
|
||||||
(["libdwarf^libelf@0.8.12", "libdwarf^libelf@0.8.13"], {"libdwarf": 2, "libelf": 2}),
|
(["libdwarf^libelf@0.8.12", "libdwarf^libelf@0.8.13"], {"libdwarf": 2, "libelf": 2}),
|
||||||
# FIXME (compiler as nodes): fix these
|
(["hdf5", "zmpi"], {"zmpi": 1, "fake": 1}),
|
||||||
# (["hdf5", "zmpi"], 3, 1),
|
(["hdf5", "mpich"], {"mpich": 1}),
|
||||||
# (["hdf5", "mpich"], 2, 1),
|
(["hdf5^zmpi", "mpich"], {"mpi": 2, "mpich": 1, "zmpi": 1, "fake": 1}),
|
||||||
# (["hdf5^zmpi", "mpich"], 4, 1),
|
(["mpi", "zmpi"], {"mpi": 1, "mpich": 0, "zmpi": 1, "fake": 1}),
|
||||||
# (["mpi", "zmpi"], 2, 1),
|
(["mpi", "mpich"], {"mpi": 1, "mpich": 1, "zmpi": 0}),
|
||||||
# (["mpi", "mpich"], 1, 1),
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_best_effort_coconcretize(self, specs, checks):
|
def test_best_effort_coconcretize(self, specs, checks):
|
||||||
@@ -1795,9 +1769,13 @@ def test_best_effort_coconcretize(self, specs, checks):
|
|||||||
for s in result.specs:
|
for s in result.specs:
|
||||||
concrete_specs.update(s.traverse())
|
concrete_specs.update(s.traverse())
|
||||||
|
|
||||||
|
for x in concrete_specs:
|
||||||
|
print(x.tree(hashes=True))
|
||||||
|
print()
|
||||||
|
|
||||||
for matching_spec, expected_count in checks.items():
|
for matching_spec, expected_count in checks.items():
|
||||||
matches = [x for x in concrete_specs if x.satisfies(matching_spec)]
|
matches = [x for x in concrete_specs if x.satisfies(matching_spec)]
|
||||||
assert len(matches) == expected_count, matching_spec
|
assert len(matches) == expected_count
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"specs,expected_spec,occurances",
|
"specs,expected_spec,occurances",
|
||||||
@@ -2211,10 +2189,19 @@ def test_unsolved_specs_raises_error(self, monkeypatch, mock_packages):
|
|||||||
solver.driver.solve(setup, specs, reuse=[])
|
solver.driver.solve(setup, specs, reuse=[])
|
||||||
|
|
||||||
@pytest.mark.regression("43141")
|
@pytest.mark.regression("43141")
|
||||||
def test_clear_error_when_unknown_compiler_requested(self, mock_packages):
|
@pytest.mark.parametrize(
|
||||||
|
"spec_str,expected_match",
|
||||||
|
[
|
||||||
|
# A package does not exist
|
||||||
|
("pkg-a ^foo", "since 'foo' does not exist"),
|
||||||
|
# Request a compiler for a package that doesn't need it
|
||||||
|
("pkg-c %gcc", "according to its recipe"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_errors_on_statically_checked_preconditions(self, spec_str, expected_match):
|
||||||
"""Tests that the solver can report a case where the compiler cannot be set"""
|
"""Tests that the solver can report a case where the compiler cannot be set"""
|
||||||
with pytest.raises(spack.error.UnsatisfiableSpecError, match="since 'foo' does not exist"):
|
with pytest.raises(spack.error.UnsatisfiableSpecError, match=expected_match):
|
||||||
Spec("pkg-a %foo").concretized()
|
Spec(spec_str).concretized()
|
||||||
|
|
||||||
@pytest.mark.regression("36339")
|
@pytest.mark.regression("36339")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
|||||||
@@ -494,7 +494,7 @@ def test_default_requirements_with_all(spec_str, requirement_str, concretize_sco
|
|||||||
spec = Spec(spec_str).concretized()
|
spec = Spec(spec_str).concretized()
|
||||||
assert "c" in spec
|
assert "c" in spec
|
||||||
for s in spec.traverse():
|
for s in spec.traverse():
|
||||||
if "c" in s:
|
if "c" in s and s.name not in ("gcc", "llvm"):
|
||||||
assert s.satisfies(requirement_str)
|
assert s.satisfies(requirement_str)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -274,10 +274,10 @@ def test_add_config_path(mutable_config):
|
|||||||
assert set_value == "/path/to/config.yaml"
|
assert set_value == "/path/to/config.yaml"
|
||||||
|
|
||||||
# Now a package:all setting
|
# Now a package:all setting
|
||||||
path = "packages:all:compiler:[gcc]"
|
path = "packages:all:target:[x86_64]"
|
||||||
spack.config.add(path)
|
spack.config.add(path)
|
||||||
compilers = spack.config.get("packages")["all"]["compiler"]
|
targets = spack.config.get("packages")["all"]["target"]
|
||||||
assert "gcc" in compilers
|
assert "x86_64" in targets
|
||||||
|
|
||||||
# Try quotes to escape brackets
|
# Try quotes to escape brackets
|
||||||
path = "config:install_tree:projections:cmake:\
|
path = "config:install_tree:projections:cmake:\
|
||||||
@@ -1014,7 +1014,6 @@ def test_single_file_scope(config, env_yaml):
|
|||||||
# from the single-file config
|
# from the single-file config
|
||||||
assert spack.config.get("config:verify_ssl") is False
|
assert spack.config.get("config:verify_ssl") is False
|
||||||
assert spack.config.get("config:dirty") is False
|
assert spack.config.get("config:dirty") is False
|
||||||
assert spack.config.get("packages:all:compiler") == ["gcc@4.5.3", "gcc", "clang"]
|
|
||||||
|
|
||||||
# from the lower config scopes
|
# from the lower config scopes
|
||||||
assert spack.config.get("config:checksum") is True
|
assert spack.config.get("config:checksum") is True
|
||||||
@@ -1038,7 +1037,7 @@ def test_single_file_scope_section_override(tmpdir, config):
|
|||||||
verify_ssl: False
|
verify_ssl: False
|
||||||
packages::
|
packages::
|
||||||
all:
|
all:
|
||||||
compiler: [ 'gcc@4.5.3' ]
|
target: [ x86_64 ]
|
||||||
repos:
|
repos:
|
||||||
- /x/y/z
|
- /x/y/z
|
||||||
"""
|
"""
|
||||||
@@ -1051,7 +1050,7 @@ def test_single_file_scope_section_override(tmpdir, config):
|
|||||||
with spack.config.override(scope):
|
with spack.config.override(scope):
|
||||||
# from the single-file config
|
# from the single-file config
|
||||||
assert spack.config.get("config:verify_ssl") is False
|
assert spack.config.get("config:verify_ssl") is False
|
||||||
assert spack.config.get("packages:all:compiler") == ["gcc@4.5.3"]
|
assert spack.config.get("packages:all:target") == ["x86_64"]
|
||||||
|
|
||||||
# from the lower config scopes
|
# from the lower config scopes
|
||||||
assert spack.config.get("config:checksum") is True
|
assert spack.config.get("config:checksum") is True
|
||||||
@@ -1316,10 +1315,10 @@ def test_user_config_path_is_default_when_env_var_is_empty(working_env):
|
|||||||
|
|
||||||
|
|
||||||
def test_default_install_tree(monkeypatch, default_config):
|
def test_default_install_tree(monkeypatch, default_config):
|
||||||
s = spack.spec.Spec("nonexistent@x.y.z %none@a.b.c arch=foo-bar-baz")
|
s = spack.spec.Spec("nonexistent@x.y.z arch=foo-bar-baz")
|
||||||
monkeypatch.setattr(s, "dag_hash", lambda length: "abc123")
|
monkeypatch.setattr(s, "dag_hash", lambda length: "abc123")
|
||||||
_, _, projections = spack.store.parse_install_tree(spack.config.get("config"))
|
_, _, projections = spack.store.parse_install_tree(spack.config.get("config"))
|
||||||
assert s.format(projections["all"]) == "foo-bar-baz/none-a.b.c/nonexistent-x.y.z-abc123"
|
assert s.format(projections["all"]) == "foo/baz/nonexistent-x.y.z-abc123"
|
||||||
|
|
||||||
|
|
||||||
def test_local_config_can_be_disabled(working_env):
|
def test_local_config_can_be_disabled(working_env):
|
||||||
@@ -1390,7 +1389,7 @@ def test_config_collect_urls(mutable_empty_config, mock_spider_configs, url, isf
|
|||||||
(github_url.format("tree"), False, False),
|
(github_url.format("tree"), False, False),
|
||||||
(gitlab_url, False, False),
|
(gitlab_url, False, False),
|
||||||
("{0}/README.md".format(github_url.format("blob")), True, True),
|
("{0}/README.md".format(github_url.format("blob")), True, True),
|
||||||
("{0}/compilers.yaml".format(gitlab_url), True, False),
|
("{0}/packages.yaml".format(gitlab_url), True, False),
|
||||||
(None, False, True),
|
(None, False, True),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -65,11 +65,11 @@ def upstream_and_downstream_db(tmpdir, gen_mock_layout):
|
|||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"install_tree,result",
|
"install_tree,result",
|
||||||
[
|
[
|
||||||
("all", ["pkg-b", "pkg-c"]),
|
("all", ["pkg-b", "pkg-c", "gcc-runtime", "gcc"]),
|
||||||
("upstream", ["pkg-c"]),
|
("upstream", ["pkg-c"]),
|
||||||
("local", ["pkg-b"]),
|
("local", ["pkg-b", "gcc-runtime", "gcc"]),
|
||||||
("{u}", ["pkg-c"]),
|
("{u}", ["pkg-c"]),
|
||||||
("{d}", ["pkg-b"]),
|
("{d}", ["pkg-b", "gcc-runtime", "gcc"]),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_query_by_install_tree(
|
def test_query_by_install_tree(
|
||||||
@@ -85,7 +85,7 @@ def test_query_by_install_tree(
|
|||||||
down_db.add(b)
|
down_db.add(b)
|
||||||
|
|
||||||
specs = down_db.query(install_tree=install_tree.format(u=up_db.root, d=down_db.root))
|
specs = down_db.query(install_tree=install_tree.format(u=up_db.root, d=down_db.root))
|
||||||
assert [s.name for s in specs] == result
|
assert {s.name for s in specs} == set(result)
|
||||||
|
|
||||||
|
|
||||||
def test_spec_installed_upstream(
|
def test_spec_installed_upstream(
|
||||||
@@ -454,7 +454,7 @@ def test_005_db_exists(database):
|
|||||||
def test_010_all_install_sanity(database):
|
def test_010_all_install_sanity(database):
|
||||||
"""Ensure that the install layout reflects what we think it does."""
|
"""Ensure that the install layout reflects what we think it does."""
|
||||||
all_specs = spack.store.STORE.layout.all_specs()
|
all_specs = spack.store.STORE.layout.all_specs()
|
||||||
assert len(all_specs) == 15
|
assert len(all_specs) == 16
|
||||||
|
|
||||||
# Query specs with multiple configurations
|
# Query specs with multiple configurations
|
||||||
mpileaks_specs = [s for s in all_specs if s.satisfies("mpileaks")]
|
mpileaks_specs = [s for s in all_specs if s.satisfies("mpileaks")]
|
||||||
@@ -571,7 +571,7 @@ def test_050_basic_query(database):
|
|||||||
"""Ensure querying database is consistent with what is installed."""
|
"""Ensure querying database is consistent with what is installed."""
|
||||||
# query everything
|
# query everything
|
||||||
total_specs = len(spack.store.STORE.db.query())
|
total_specs = len(spack.store.STORE.db.query())
|
||||||
assert total_specs == 17
|
assert total_specs == 19
|
||||||
|
|
||||||
# query specs with multiple configurations
|
# query specs with multiple configurations
|
||||||
mpileaks_specs = database.query("mpileaks")
|
mpileaks_specs = database.query("mpileaks")
|
||||||
@@ -793,11 +793,11 @@ def check_unused(roots, deptype, expected):
|
|||||||
assert set(u.name for u in unused) == set(expected)
|
assert set(u.name for u in unused) == set(expected)
|
||||||
|
|
||||||
default_dt = dt.LINK | dt.RUN
|
default_dt = dt.LINK | dt.RUN
|
||||||
check_unused(None, default_dt, ["cmake"])
|
check_unused(None, default_dt, ["cmake", "gcc"])
|
||||||
check_unused(
|
check_unused(
|
||||||
[si, ml_mpich, ml_mpich2, ml_zmpi, externaltest],
|
[si, ml_mpich, ml_mpich2, ml_zmpi, externaltest],
|
||||||
default_dt,
|
default_dt,
|
||||||
["trivial-smoke-test", "cmake"],
|
["trivial-smoke-test", "cmake", "gcc"],
|
||||||
)
|
)
|
||||||
check_unused(
|
check_unused(
|
||||||
[si, ml_mpich, ml_mpich2, ml_zmpi, externaltest],
|
[si, ml_mpich, ml_mpich2, ml_zmpi, externaltest],
|
||||||
@@ -812,7 +812,7 @@ def check_unused(roots, deptype, expected):
|
|||||||
check_unused(
|
check_unused(
|
||||||
[si, ml_mpich, ml_mpich2, ml_zmpi],
|
[si, ml_mpich, ml_mpich2, ml_zmpi],
|
||||||
default_dt,
|
default_dt,
|
||||||
["trivial-smoke-test", "cmake", "externaltest", "externaltool", "externalvirtual"],
|
["trivial-smoke-test", "cmake", "externaltest", "externaltool", "externalvirtual", "gcc"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -1047,7 +1047,7 @@ def test_check_parents(spec_str, parent_name, expected_nparents, database):
|
|||||||
def test_db_all_hashes(database):
|
def test_db_all_hashes(database):
|
||||||
# ensure we get the right number of hashes without a read transaction
|
# ensure we get the right number of hashes without a read transaction
|
||||||
hashes = database.all_hashes()
|
hashes = database.all_hashes()
|
||||||
assert len(hashes) == 17
|
assert len(hashes) == 19
|
||||||
|
|
||||||
# and make sure the hashes match
|
# and make sure the hashes match
|
||||||
with database.read_transaction():
|
with database.read_transaction():
|
||||||
|
|||||||
@@ -35,11 +35,7 @@ def test_yaml_directory_layout_parameters(tmpdir, default_mock_concretization):
|
|||||||
layout_default = DirectoryLayout(str(tmpdir))
|
layout_default = DirectoryLayout(str(tmpdir))
|
||||||
path_default = layout_default.relative_path_for_spec(spec)
|
path_default = layout_default.relative_path_for_spec(spec)
|
||||||
assert path_default == str(
|
assert path_default == str(
|
||||||
Path(
|
Path(spec.format("{architecture.platform}/{architecture.target}/{name}-{version}-{hash}"))
|
||||||
spec.format(
|
|
||||||
"{architecture}/" "{compiler.name}-{compiler.version}/" "{name}-{version}-{hash}"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test hash_length parameter works correctly
|
# Test hash_length parameter works correctly
|
||||||
|
|||||||
@@ -47,44 +47,63 @@ def test_ascii_graph_mpileaks(config, mock_packages, monkeypatch):
|
|||||||
graph_str = stream.getvalue()
|
graph_str = stream.getvalue()
|
||||||
graph_str = "\n".join([line.rstrip() for line in graph_str.split("\n")])
|
graph_str = "\n".join([line.rstrip() for line in graph_str.split("\n")])
|
||||||
|
|
||||||
|
print(graph_str)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
graph_str
|
graph_str
|
||||||
== r"""o mpileaks
|
== r"""o mpileaks
|
||||||
|\
|
|\
|
||||||
| o callpath
|
|
||||||
|/|
|
|
||||||
o | mpich
|
|
||||||
/
|
|
||||||
o dyninst
|
|
||||||
|\
|
|
||||||
| o libdwarf
|
|
||||||
|/
|
|
||||||
o libelf
|
|
||||||
"""
|
|
||||||
or graph_str
|
|
||||||
== r"""o mpileaks
|
|
||||||
|\
|
|
||||||
o | callpath
|
|
||||||
|\|
|
|
||||||
| o mpich
|
|
||||||
|
|
|
||||||
o dyninst
|
|
||||||
|\
|
|
||||||
o | libdwarf
|
|
||||||
|/
|
|
||||||
o libelf
|
|
||||||
"""
|
|
||||||
or graph_str
|
|
||||||
== r"""o mpileaks
|
|
||||||
|\
|
|
||||||
| o callpath
|
|
||||||
|/|
|
|
||||||
| o dyninst
|
|
||||||
| |\
|
| |\
|
||||||
o | | mpich
|
| | |\
|
||||||
/ /
|
| | | o callpath
|
||||||
| o libdwarf
|
| |_|/|
|
||||||
|
|/| |/|
|
||||||
|
| |/|/|
|
||||||
|
o | | | mpich
|
||||||
|
|\| | |
|
||||||
|
| |/ /
|
||||||
|
|/| |
|
||||||
|
| | o dyninst
|
||||||
|
| |/|
|
||||||
|
|/|/|
|
||||||
|
| | |\
|
||||||
|
| | | o libdwarf
|
||||||
|
| |_|/|
|
||||||
|
|/| |/|
|
||||||
|
| |/|/
|
||||||
|
| | o libelf
|
||||||
|
| |/|
|
||||||
|
|/|/
|
||||||
|
| o gcc-runtime
|
||||||
|/
|
|/
|
||||||
o libelf
|
o gcc
|
||||||
|
"""
|
||||||
|
or graph_str
|
||||||
|
== r"""o mpileaks
|
||||||
|
|\
|
||||||
|
| |\
|
||||||
|
| | |\
|
||||||
|
| | | o callpath
|
||||||
|
| |_|/|
|
||||||
|
|/| |/|
|
||||||
|
| |/|/|
|
||||||
|
| | | o dyninst
|
||||||
|
| | |/|
|
||||||
|
| |/|/|
|
||||||
|
| | | |\
|
||||||
|
o | | | | mpich
|
||||||
|
|\| | | |
|
||||||
|
| |/ / /
|
||||||
|
|/| | |
|
||||||
|
| | | o libdwarf
|
||||||
|
| |_|/|
|
||||||
|
|/| |/|
|
||||||
|
| |/|/
|
||||||
|
| | o libelf
|
||||||
|
| |/|
|
||||||
|
|/|/
|
||||||
|
| o gcc-runtime
|
||||||
|
|/
|
||||||
|
o gcc
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1025,6 +1025,7 @@ def test_install_fail_multi(install_mockery, mock_fetch, monkeypatch):
|
|||||||
|
|
||||||
def test_install_fail_fast_on_detect(install_mockery, monkeypatch, capsys):
|
def test_install_fail_fast_on_detect(install_mockery, monkeypatch, capsys):
|
||||||
"""Test fail_fast install when an install failure is detected."""
|
"""Test fail_fast install when an install failure is detected."""
|
||||||
|
# Note: this test depends on the order of the installations
|
||||||
b, c = spack.spec.Spec("pkg-b").concretized(), spack.spec.Spec("pkg-c").concretized()
|
b, c = spack.spec.Spec("pkg-b").concretized(), spack.spec.Spec("pkg-c").concretized()
|
||||||
b_id, c_id = inst.package_id(b), inst.package_id(c)
|
b_id, c_id = inst.package_id(b), inst.package_id(c)
|
||||||
|
|
||||||
@@ -1037,9 +1038,9 @@ def test_install_fail_fast_on_detect(install_mockery, monkeypatch, capsys):
|
|||||||
with pytest.raises(spack.error.InstallError, match="after first install failure"):
|
with pytest.raises(spack.error.InstallError, match="after first install failure"):
|
||||||
installer.install()
|
installer.install()
|
||||||
|
|
||||||
assert b_id in installer.failed, "Expected b to be marked as failed"
|
assert c_id in installer.failed, "Expected b to be marked as failed"
|
||||||
assert c_id not in installer.failed, "Expected no attempt to install pkg-c"
|
assert b_id not in installer.failed, "Expected no attempt to install pkg-c"
|
||||||
assert f"{b_id} failed to install" in capsys.readouterr().err
|
assert f"{c_id} failed to install" in capsys.readouterr().err
|
||||||
|
|
||||||
|
|
||||||
def _test_install_fail_fast_on_except_patch(installer, **kwargs):
|
def _test_install_fail_fast_on_except_patch(installer, **kwargs):
|
||||||
@@ -1072,10 +1073,11 @@ def test_install_fail_fast_on_except(install_mockery, monkeypatch, capsys):
|
|||||||
def test_install_lock_failures(install_mockery, monkeypatch, capfd):
|
def test_install_lock_failures(install_mockery, monkeypatch, capfd):
|
||||||
"""Cover basic install lock failure handling in a single pass."""
|
"""Cover basic install lock failure handling in a single pass."""
|
||||||
|
|
||||||
|
# Note: this test relies on installing a package with no dependencies
|
||||||
def _requeued(installer, task, install_status):
|
def _requeued(installer, task, install_status):
|
||||||
tty.msg("requeued {0}".format(task.pkg.spec.name))
|
tty.msg("requeued {0}".format(task.pkg.spec.name))
|
||||||
|
|
||||||
installer = create_installer(["pkg-b"], {})
|
installer = create_installer(["pkg-c"], {})
|
||||||
|
|
||||||
# Ensure never acquire a lock
|
# Ensure never acquire a lock
|
||||||
monkeypatch.setattr(inst.PackageInstaller, "_ensure_locked", _not_locked)
|
monkeypatch.setattr(inst.PackageInstaller, "_ensure_locked", _not_locked)
|
||||||
@@ -1094,13 +1096,14 @@ def _requeued(installer, task, install_status):
|
|||||||
|
|
||||||
def test_install_lock_installed_requeue(install_mockery, monkeypatch, capfd):
|
def test_install_lock_installed_requeue(install_mockery, monkeypatch, capfd):
|
||||||
"""Cover basic install handling for installed package."""
|
"""Cover basic install handling for installed package."""
|
||||||
b = spack.spec.Spec("pkg-b").concretized()
|
# Note: this test relies on installing a package with no dependencies
|
||||||
b_pkg_id = inst.package_id(b)
|
concrete_spec = spack.spec.Spec("pkg-c").concretized()
|
||||||
installer = create_installer([b])
|
pkg_id = inst.package_id(concrete_spec)
|
||||||
|
installer = create_installer([concrete_spec])
|
||||||
|
|
||||||
def _prep(installer, task):
|
def _prep(installer, task):
|
||||||
installer.installed.add(b_pkg_id)
|
installer.installed.add(pkg_id)
|
||||||
tty.msg(f"{b_pkg_id} is installed")
|
tty.msg(f"{pkg_id} is installed")
|
||||||
|
|
||||||
# also do not allow the package to be locked again
|
# also do not allow the package to be locked again
|
||||||
monkeypatch.setattr(inst.PackageInstaller, "_ensure_locked", _not_locked)
|
monkeypatch.setattr(inst.PackageInstaller, "_ensure_locked", _not_locked)
|
||||||
@@ -1117,7 +1120,7 @@ def _requeued(installer, task, install_status):
|
|||||||
with pytest.raises(spack.error.InstallError, match="request failed"):
|
with pytest.raises(spack.error.InstallError, match="request failed"):
|
||||||
installer.install()
|
installer.install()
|
||||||
|
|
||||||
assert b_pkg_id not in installer.installed
|
assert pkg_id not in installer.installed
|
||||||
|
|
||||||
expected = ["is installed", "read locked", "requeued"]
|
expected = ["is installed", "read locked", "requeued"]
|
||||||
for exp, ln in zip(expected, capfd.readouterr().out.splitlines()):
|
for exp, ln in zip(expected, capfd.readouterr().out.splitlines()):
|
||||||
@@ -1126,6 +1129,7 @@ def _requeued(installer, task, install_status):
|
|||||||
|
|
||||||
def test_install_read_locked_requeue(install_mockery, monkeypatch, capfd):
|
def test_install_read_locked_requeue(install_mockery, monkeypatch, capfd):
|
||||||
"""Cover basic read lock handling for uninstalled package with requeue."""
|
"""Cover basic read lock handling for uninstalled package with requeue."""
|
||||||
|
# Note: this test relies on installing a package with no dependencies
|
||||||
orig_fn = inst.PackageInstaller._ensure_locked
|
orig_fn = inst.PackageInstaller._ensure_locked
|
||||||
|
|
||||||
def _read(installer, lock_type, pkg):
|
def _read(installer, lock_type, pkg):
|
||||||
@@ -1148,7 +1152,7 @@ def _requeued(installer, task, install_status):
|
|||||||
# Ensure don't continually requeue the task
|
# Ensure don't continually requeue the task
|
||||||
monkeypatch.setattr(inst.PackageInstaller, "_requeue_task", _requeued)
|
monkeypatch.setattr(inst.PackageInstaller, "_requeue_task", _requeued)
|
||||||
|
|
||||||
installer = create_installer(["pkg-b"], {})
|
installer = create_installer(["pkg-c"], {})
|
||||||
|
|
||||||
with pytest.raises(spack.error.InstallError, match="request failed"):
|
with pytest.raises(spack.error.InstallError, match="request failed"):
|
||||||
installer.install()
|
installer.install()
|
||||||
@@ -1163,7 +1167,8 @@ def _requeued(installer, task, install_status):
|
|||||||
|
|
||||||
def test_install_skip_patch(install_mockery, mock_fetch):
|
def test_install_skip_patch(install_mockery, mock_fetch):
|
||||||
"""Test the path skip_patch install path."""
|
"""Test the path skip_patch install path."""
|
||||||
installer = create_installer(["pkg-b"], {"fake": False, "skip_patch": True})
|
# Note: this test relies on installing a package with no dependencies
|
||||||
|
installer = create_installer(["pkg-c"], {"fake": False, "skip_patch": True})
|
||||||
installer.install()
|
installer.install()
|
||||||
assert inst.package_id(installer.build_requests[0].pkg.spec) in installer.installed
|
assert inst.package_id(installer.build_requests[0].pkg.spec) in installer.installed
|
||||||
|
|
||||||
@@ -1183,8 +1188,9 @@ def test_overwrite_install_backup_success(temporary_store, config, mock_packages
|
|||||||
When doing an overwrite install that fails, Spack should restore the backup
|
When doing an overwrite install that fails, Spack should restore the backup
|
||||||
of the original prefix, and leave the original spec marked installed.
|
of the original prefix, and leave the original spec marked installed.
|
||||||
"""
|
"""
|
||||||
|
# Note: this test relies on installing a package with no dependencies
|
||||||
# Get a build task. TODO: refactor this to avoid calling internal methods
|
# Get a build task. TODO: refactor this to avoid calling internal methods
|
||||||
installer = create_installer(["pkg-b"])
|
installer = create_installer(["pkg-c"])
|
||||||
installer._init_queue()
|
installer._init_queue()
|
||||||
task = installer._pop_task()
|
task = installer._pop_task()
|
||||||
|
|
||||||
@@ -1225,6 +1231,7 @@ def test_overwrite_install_backup_failure(temporary_store, config, mock_packages
|
|||||||
original prefix. If that fails, the spec is lost, and it should be removed
|
original prefix. If that fails, the spec is lost, and it should be removed
|
||||||
from the database.
|
from the database.
|
||||||
"""
|
"""
|
||||||
|
# Note: this test relies on installing a package with no dependencies
|
||||||
|
|
||||||
class InstallerThatAccidentallyDeletesTheBackupDir:
|
class InstallerThatAccidentallyDeletesTheBackupDir:
|
||||||
def _install_task(self, task, install_status):
|
def _install_task(self, task, install_status):
|
||||||
@@ -1244,7 +1251,7 @@ def remove(self, spec):
|
|||||||
self.called = True
|
self.called = True
|
||||||
|
|
||||||
# Get a build task. TODO: refactor this to avoid calling internal methods
|
# Get a build task. TODO: refactor this to avoid calling internal methods
|
||||||
installer = create_installer(["pkg-b"])
|
installer = create_installer(["pkg-c"])
|
||||||
installer._init_queue()
|
installer._init_queue()
|
||||||
task = installer._pop_task()
|
task = installer._pop_task()
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
import spack.compilers.libraries
|
||||||
import spack.paths
|
import spack.paths
|
||||||
from spack.compilers.libraries import parse_non_system_link_dirs
|
from spack.compilers.libraries import parse_non_system_link_dirs
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from textwrap import dedent
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@@ -291,37 +290,6 @@ def inner():
|
|||||||
with h.forward("top-level"):
|
with h.forward("top-level"):
|
||||||
raise TypeError("ok")
|
raise TypeError("ok")
|
||||||
|
|
||||||
assert h.grouped_message(with_tracebacks=False) == dedent(
|
|
||||||
"""\
|
|
||||||
due to the following failures:
|
|
||||||
inner method raised ValueError: wow!
|
|
||||||
top-level raised TypeError: ok"""
|
|
||||||
)
|
|
||||||
|
|
||||||
full_message = h.grouped_message(with_tracebacks=True)
|
|
||||||
no_line_numbers = re.sub(r"line [0-9]+,", "line xxx,", full_message)
|
|
||||||
|
|
||||||
assert (
|
|
||||||
no_line_numbers
|
|
||||||
== dedent(
|
|
||||||
"""\
|
|
||||||
due to the following failures:
|
|
||||||
inner method raised ValueError: wow!
|
|
||||||
File "{0}", \
|
|
||||||
line xxx, in test_grouped_exception
|
|
||||||
inner()
|
|
||||||
File "{0}", \
|
|
||||||
line xxx, in inner
|
|
||||||
raise ValueError("wow!")
|
|
||||||
|
|
||||||
top-level raised TypeError: ok
|
|
||||||
File "{0}", \
|
|
||||||
line xxx, in test_grouped_exception
|
|
||||||
raise TypeError("ok")
|
|
||||||
"""
|
|
||||||
).format(__file__)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_grouped_exception_base_type():
|
def test_grouped_exception_base_type():
|
||||||
h = llnl.util.lang.GroupedExceptionHandler()
|
h = llnl.util.lang.GroupedExceptionHandler()
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ def test_compilers_provided_different_name(
|
|||||||
self, factory, module_configuration, compiler_factory
|
self, factory, module_configuration, compiler_factory
|
||||||
):
|
):
|
||||||
with spack.config.override(
|
with spack.config.override(
|
||||||
"compilers", [compiler_factory(spec="clang@3.3", operating_system="debian6")]
|
"packages", {"llvm": {"externals": [compiler_factory(spec="llvm@3.3")]}}
|
||||||
):
|
):
|
||||||
module_configuration("complex_hierarchy")
|
module_configuration("complex_hierarchy")
|
||||||
module, spec = factory("intel-oneapi-compilers%clang@3.3")
|
module, spec = factory("intel-oneapi-compilers%clang@3.3")
|
||||||
@@ -120,7 +120,7 @@ def test_compilers_provided_different_name(
|
|||||||
provides = module.conf.provides
|
provides = module.conf.provides
|
||||||
|
|
||||||
assert "compiler" in provides
|
assert "compiler" in provides
|
||||||
assert provides["compiler"] == spack.spec.CompilerSpec("oneapi@=3.0")
|
assert provides["compiler"] == spack.spec.Spec("intel-oneapi-compilers@=3.0")
|
||||||
|
|
||||||
def test_simple_case(self, modulefile_content, module_configuration):
|
def test_simple_case(self, modulefile_content, module_configuration):
|
||||||
"""Tests the generation of a simple Lua module file."""
|
"""Tests the generation of a simple Lua module file."""
|
||||||
@@ -139,7 +139,7 @@ def test_autoload_direct(self, modulefile_content, module_configuration):
|
|||||||
module_configuration("autoload_direct")
|
module_configuration("autoload_direct")
|
||||||
content = modulefile_content(mpileaks_spec_string)
|
content = modulefile_content(mpileaks_spec_string)
|
||||||
|
|
||||||
assert len([x for x in content if "depends_on(" in x]) == 2
|
assert len([x for x in content if "depends_on(" in x]) == 3
|
||||||
|
|
||||||
def test_autoload_all(self, modulefile_content, module_configuration):
|
def test_autoload_all(self, modulefile_content, module_configuration):
|
||||||
"""Tests the automatic loading of all dependencies."""
|
"""Tests the automatic loading of all dependencies."""
|
||||||
@@ -147,7 +147,7 @@ def test_autoload_all(self, modulefile_content, module_configuration):
|
|||||||
module_configuration("autoload_all")
|
module_configuration("autoload_all")
|
||||||
content = modulefile_content(mpileaks_spec_string)
|
content = modulefile_content(mpileaks_spec_string)
|
||||||
|
|
||||||
assert len([x for x in content if "depends_on(" in x]) == 5
|
assert len([x for x in content if "depends_on(" in x]) == 6
|
||||||
|
|
||||||
def test_alter_environment(self, modulefile_content, module_configuration):
|
def test_alter_environment(self, modulefile_content, module_configuration):
|
||||||
"""Tests modifications to run-time environment."""
|
"""Tests modifications to run-time environment."""
|
||||||
@@ -265,7 +265,7 @@ def test_exclude(self, modulefile_content, module_configuration):
|
|||||||
module_configuration("exclude")
|
module_configuration("exclude")
|
||||||
content = modulefile_content(mpileaks_spec_string)
|
content = modulefile_content(mpileaks_spec_string)
|
||||||
|
|
||||||
assert len([x for x in content if "depends_on(" in x]) == 1
|
assert len([x for x in content if "depends_on(" in x]) == 2
|
||||||
|
|
||||||
def test_no_hash(self, factory, module_configuration):
|
def test_no_hash(self, factory, module_configuration):
|
||||||
"""Makes sure that virtual providers (in the hierarchy) always
|
"""Makes sure that virtual providers (in the hierarchy) always
|
||||||
@@ -372,7 +372,7 @@ def test_guess_core_compilers(self, factory, module_configuration, monkeypatch):
|
|||||||
module_configuration("missing_core_compilers")
|
module_configuration("missing_core_compilers")
|
||||||
|
|
||||||
# Our mock paths must be detected as system paths
|
# Our mock paths must be detected as system paths
|
||||||
monkeypatch.setattr(spack.util.environment, "SYSTEM_DIRS", ["/path/to"])
|
monkeypatch.setattr(spack.util.environment, "SYSTEM_DIRS", ["/path/bin"])
|
||||||
|
|
||||||
# We don't want to really write into user configuration
|
# We don't want to really write into user configuration
|
||||||
# when running tests
|
# when running tests
|
||||||
@@ -434,7 +434,7 @@ def test_modules_relative_to_view(
|
|||||||
):
|
):
|
||||||
with ev.create_in_dir(str(tmpdir), with_view=True) as e:
|
with ev.create_in_dir(str(tmpdir), with_view=True) as e:
|
||||||
module_configuration("with_view")
|
module_configuration("with_view")
|
||||||
install("--add", "cmake")
|
install("--fake", "--add", "cmake")
|
||||||
|
|
||||||
spec = spack.spec.Spec("cmake").concretized()
|
spec = spack.spec.Spec("cmake").concretized()
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ def test_autoload_direct(self, modulefile_content, module_configuration):
|
|||||||
len([x for x in content if "if {![info exists ::env(LMOD_VERSION_MAJOR)]} {" in x])
|
len([x for x in content if "if {![info exists ::env(LMOD_VERSION_MAJOR)]} {" in x])
|
||||||
== 1
|
== 1
|
||||||
)
|
)
|
||||||
assert len([x for x in content if "depends-on " in x]) == 2
|
assert len([x for x in content if "depends-on " in x]) == 3
|
||||||
assert len([x for x in content if "module load " in x]) == 2
|
assert len([x for x in content if "module load " in x]) == 3
|
||||||
|
|
||||||
# dtbuild1 has
|
# dtbuild1 has
|
||||||
# - 1 ('run',) dependency
|
# - 1 ('run',) dependency
|
||||||
@@ -77,8 +77,8 @@ def test_autoload_all(self, modulefile_content, module_configuration):
|
|||||||
len([x for x in content if "if {![info exists ::env(LMOD_VERSION_MAJOR)]} {" in x])
|
len([x for x in content if "if {![info exists ::env(LMOD_VERSION_MAJOR)]} {" in x])
|
||||||
== 1
|
== 1
|
||||||
)
|
)
|
||||||
assert len([x for x in content if "depends-on " in x]) == 5
|
assert len([x for x in content if "depends-on " in x]) == 6
|
||||||
assert len([x for x in content if "module load " in x]) == 5
|
assert len([x for x in content if "module load " in x]) == 6
|
||||||
|
|
||||||
# dtbuild1 has
|
# dtbuild1 has
|
||||||
# - 1 ('run',) dependency
|
# - 1 ('run',) dependency
|
||||||
@@ -102,7 +102,7 @@ def test_prerequisites_direct(
|
|||||||
module_configuration("prerequisites_direct")
|
module_configuration("prerequisites_direct")
|
||||||
content = modulefile_content(f"mpileaks target={host_architecture_str}")
|
content = modulefile_content(f"mpileaks target={host_architecture_str}")
|
||||||
|
|
||||||
assert len([x for x in content if "prereq" in x]) == 2
|
assert len([x for x in content if "prereq" in x]) == 3
|
||||||
|
|
||||||
def test_prerequisites_all(
|
def test_prerequisites_all(
|
||||||
self, modulefile_content, module_configuration, host_architecture_str
|
self, modulefile_content, module_configuration, host_architecture_str
|
||||||
@@ -112,7 +112,7 @@ def test_prerequisites_all(
|
|||||||
module_configuration("prerequisites_all")
|
module_configuration("prerequisites_all")
|
||||||
content = modulefile_content(f"mpileaks target={host_architecture_str}")
|
content = modulefile_content(f"mpileaks target={host_architecture_str}")
|
||||||
|
|
||||||
assert len([x for x in content if "prereq" in x]) == 5
|
assert len([x for x in content if "prereq" in x]) == 6
|
||||||
|
|
||||||
def test_alter_environment(self, modulefile_content, module_configuration):
|
def test_alter_environment(self, modulefile_content, module_configuration):
|
||||||
"""Tests modifications to run-time environment."""
|
"""Tests modifications to run-time environment."""
|
||||||
@@ -237,7 +237,7 @@ def test_exclude(self, modulefile_content, module_configuration, host_architectu
|
|||||||
module_configuration("exclude")
|
module_configuration("exclude")
|
||||||
content = modulefile_content("mpileaks ^zmpi")
|
content = modulefile_content("mpileaks ^zmpi")
|
||||||
|
|
||||||
assert len([x for x in content if "module load " in x]) == 1
|
assert len([x for x in content if "module load " in x]) == 2
|
||||||
|
|
||||||
# Catch "Exception" to avoid using FileNotFoundError on Python 3
|
# Catch "Exception" to avoid using FileNotFoundError on Python 3
|
||||||
# and IOError on Python 2 or common bases like EnvironmentError
|
# and IOError on Python 2 or common bases like EnvironmentError
|
||||||
@@ -247,7 +247,7 @@ def test_exclude(self, modulefile_content, module_configuration, host_architectu
|
|||||||
|
|
||||||
content = modulefile_content(f"zmpi target={host_architecture_str}")
|
content = modulefile_content(f"zmpi target={host_architecture_str}")
|
||||||
|
|
||||||
assert len([x for x in content if "module load " in x]) == 1
|
assert len([x for x in content if "module load " in x]) == 2
|
||||||
|
|
||||||
def test_naming_scheme_compat(self, factory, module_configuration):
|
def test_naming_scheme_compat(self, factory, module_configuration):
|
||||||
"""Tests backwards compatibility for naming_scheme key"""
|
"""Tests backwards compatibility for naming_scheme key"""
|
||||||
@@ -488,8 +488,8 @@ def test_autoload_with_constraints(self, modulefile_content, module_configuratio
|
|||||||
|
|
||||||
# Test the mpileaks that should have the autoloaded dependencies
|
# Test the mpileaks that should have the autoloaded dependencies
|
||||||
content = modulefile_content("mpileaks ^mpich2")
|
content = modulefile_content("mpileaks ^mpich2")
|
||||||
assert len([x for x in content if "depends-on " in x]) == 2
|
assert len([x for x in content if "depends-on " in x]) == 3
|
||||||
assert len([x for x in content if "module load " in x]) == 2
|
assert len([x for x in content if "module load " in x]) == 3
|
||||||
|
|
||||||
# Test the mpileaks that should NOT have the autoloaded dependencies
|
# Test the mpileaks that should NOT have the autoloaded dependencies
|
||||||
content = modulefile_content("mpileaks ^mpich")
|
content = modulefile_content("mpileaks ^mpich")
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
import spack.config
|
|
||||||
import spack.platforms
|
import spack.platforms
|
||||||
import spack.spec
|
import spack.spec
|
||||||
from spack.multimethod import NoSuchMethodError
|
from spack.multimethod import NoSuchMethodError
|
||||||
@@ -54,7 +53,7 @@ def test_no_version_match(pkg_name):
|
|||||||
# Constraints on compilers with a default
|
# Constraints on compilers with a default
|
||||||
("%gcc", "has_a_default", "gcc"),
|
("%gcc", "has_a_default", "gcc"),
|
||||||
("%clang", "has_a_default", "clang"),
|
("%clang", "has_a_default", "clang"),
|
||||||
("%apple-clang os=elcapitan", "has_a_default", "default"),
|
("%gcc@9", "has_a_default", "default"),
|
||||||
# Constraints on dependencies
|
# Constraints on dependencies
|
||||||
("^zmpi", "different_by_dep", "zmpi"),
|
("^zmpi", "different_by_dep", "zmpi"),
|
||||||
("^mpich", "different_by_dep", "mpich"),
|
("^mpich", "different_by_dep", "mpich"),
|
||||||
@@ -69,13 +68,9 @@ def test_no_version_match(pkg_name):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_multimethod_calls(
|
def test_multimethod_calls(
|
||||||
pkg_name, constraint_str, method_name, expected_result, compiler_factory
|
pkg_name, constraint_str, method_name, expected_result, default_mock_concretization
|
||||||
):
|
):
|
||||||
# Add apple-clang, as it is required by one of the tests
|
s = default_mock_concretization(f"{pkg_name}{constraint_str}")
|
||||||
with spack.config.override(
|
|
||||||
"compilers", [compiler_factory(spec="apple-clang@9.1.0", operating_system="elcapitan")]
|
|
||||||
):
|
|
||||||
s = spack.spec.Spec(pkg_name + constraint_str).concretized()
|
|
||||||
msg = f"Method {method_name} from {s} is giving a wrong result"
|
msg = f"Method {method_name} from {s} is giving a wrong result"
|
||||||
assert getattr(s.package, method_name)() == expected_result, msg
|
assert getattr(s.package, method_name)() == expected_result, msg
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,6 @@
|
|||||||
|
|
||||||
import llnl.util.filesystem as fs
|
import llnl.util.filesystem as fs
|
||||||
|
|
||||||
import spack.compilers.config
|
|
||||||
import spack.config
|
|
||||||
import spack.deptypes as dt
|
import spack.deptypes as dt
|
||||||
import spack.error
|
import spack.error
|
||||||
import spack.install_test
|
import spack.install_test
|
||||||
@@ -35,21 +33,28 @@ def mpi_names(mock_repo_path):
|
|||||||
return [spec.name for spec in mock_repo_path.providers_for("mpi")]
|
return [spec.name for spec in mock_repo_path.providers_for("mpi")]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def compiler_names(mock_repo_path):
|
||||||
|
return [spec.name for spec in mock_repo_path.providers_for("c")]
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def mpileaks_possible_deps(mock_packages, mpi_names):
|
def mpileaks_possible_deps(mock_packages, mpi_names, compiler_names):
|
||||||
possible = {
|
possible = {
|
||||||
"callpath": set(["dyninst"] + mpi_names),
|
"callpath": set(["dyninst"] + mpi_names + compiler_names),
|
||||||
"low-priority-provider": set(),
|
"low-priority-provider": set(),
|
||||||
"dyninst": set(["libdwarf", "libelf"]),
|
"dyninst": set(["libdwarf", "libelf"] + compiler_names),
|
||||||
"fake": set(),
|
"fake": set(),
|
||||||
|
"gcc": set(),
|
||||||
"intel-parallel-studio": set(),
|
"intel-parallel-studio": set(),
|
||||||
"libdwarf": set(["libelf"]),
|
"libdwarf": set(["libelf"] + compiler_names),
|
||||||
"libelf": set(),
|
"libelf": set(compiler_names),
|
||||||
"mpich": set(),
|
"llvm": set(),
|
||||||
"mpich2": set(),
|
"mpich": set(compiler_names),
|
||||||
"mpileaks": set(["callpath"] + mpi_names),
|
"mpich2": set(compiler_names),
|
||||||
|
"mpileaks": set(["callpath"] + mpi_names + compiler_names),
|
||||||
"multi-provider-mpi": set(),
|
"multi-provider-mpi": set(),
|
||||||
"zmpi": set(["fake"]),
|
"zmpi": set(["fake"] + compiler_names),
|
||||||
}
|
}
|
||||||
return possible
|
return possible
|
||||||
|
|
||||||
@@ -59,32 +64,39 @@ def test_possible_dependencies(mock_packages, mpileaks_possible_deps):
|
|||||||
expanded_possible_deps = pkg_cls.possible_dependencies(expand_virtuals=True)
|
expanded_possible_deps = pkg_cls.possible_dependencies(expand_virtuals=True)
|
||||||
assert mpileaks_possible_deps == expanded_possible_deps
|
assert mpileaks_possible_deps == expanded_possible_deps
|
||||||
assert {
|
assert {
|
||||||
"callpath": {"dyninst", "mpi"},
|
"c": set(),
|
||||||
"dyninst": {"libdwarf", "libelf"},
|
"callpath": {"dyninst", "mpi", "c"},
|
||||||
"libdwarf": {"libelf"},
|
"cxx": set(),
|
||||||
"libelf": set(),
|
"dyninst": {"libdwarf", "libelf", "c"},
|
||||||
|
"libdwarf": {"libelf", "c", "cxx"},
|
||||||
|
"libelf": {"c"},
|
||||||
"mpi": set(),
|
"mpi": set(),
|
||||||
"mpileaks": {"callpath", "mpi"},
|
"mpileaks": {"c", "callpath", "mpi"},
|
||||||
} == pkg_cls.possible_dependencies(expand_virtuals=False)
|
} == pkg_cls.possible_dependencies(expand_virtuals=False)
|
||||||
|
|
||||||
|
|
||||||
def test_possible_direct_dependencies(mock_packages, mpileaks_possible_deps):
|
def test_possible_direct_dependencies(mock_packages, mpileaks_possible_deps):
|
||||||
pkg_cls = spack.repo.PATH.get_pkg_class("mpileaks")
|
pkg_cls = spack.repo.PATH.get_pkg_class("mpileaks")
|
||||||
deps = pkg_cls.possible_dependencies(transitive=False, expand_virtuals=False)
|
deps = pkg_cls.possible_dependencies(transitive=False, expand_virtuals=False)
|
||||||
assert {"callpath": set(), "mpi": set(), "mpileaks": {"callpath", "mpi"}} == deps
|
assert {
|
||||||
|
"c": set(),
|
||||||
|
"callpath": set(),
|
||||||
|
"mpi": set(),
|
||||||
|
"mpileaks": {"callpath", "mpi", "c"},
|
||||||
|
} == deps
|
||||||
|
|
||||||
|
|
||||||
def test_possible_dependencies_virtual(mock_packages, mpi_names):
|
def test_possible_dependencies_virtual(mock_packages, mpi_names, compiler_names):
|
||||||
expected = dict(
|
expected = {
|
||||||
(name, set(dep for dep in spack.repo.PATH.get_pkg_class(name).dependencies_by_name()))
|
name: set(spack.repo.PATH.get_pkg_class(name).dependencies_by_name()) for name in mpi_names
|
||||||
for name in mpi_names
|
}
|
||||||
|
|
||||||
|
# One mock MPI has a dependency, and they depend on C, C++, and Fortran
|
||||||
|
expected.update({"fake": set(), "c": set(), "cxx": set(), "fortran": set()})
|
||||||
|
assert expected == spack.package_base.possible_dependencies(
|
||||||
|
"mpi", expand_virtuals=False, transitive=False
|
||||||
)
|
)
|
||||||
|
|
||||||
# only one mock MPI has a dependency
|
|
||||||
expected["fake"] = set()
|
|
||||||
|
|
||||||
assert expected == spack.package_base.possible_dependencies("mpi", transitive=False)
|
|
||||||
|
|
||||||
|
|
||||||
def test_possible_dependencies_missing(mock_packages):
|
def test_possible_dependencies_missing(mock_packages):
|
||||||
pkg_cls = spack.repo.PATH.get_pkg_class("missing-dependency")
|
pkg_cls = spack.repo.PATH.get_pkg_class("missing-dependency")
|
||||||
@@ -118,10 +130,10 @@ def test_possible_dependencies_with_multiple_classes(mock_packages, mpileaks_pos
|
|||||||
expected = mpileaks_possible_deps.copy()
|
expected = mpileaks_possible_deps.copy()
|
||||||
expected.update(
|
expected.update(
|
||||||
{
|
{
|
||||||
"dt-diamond": set(["dt-diamond-left", "dt-diamond-right"]),
|
"dt-diamond": {"dt-diamond-left", "dt-diamond-right", "gcc", "llvm"},
|
||||||
"dt-diamond-left": set(["dt-diamond-bottom"]),
|
"dt-diamond-left": {"dt-diamond-bottom", "gcc", "llvm"},
|
||||||
"dt-diamond-right": set(["dt-diamond-bottom"]),
|
"dt-diamond-right": {"dt-diamond-bottom", "gcc", "llvm"},
|
||||||
"dt-diamond-bottom": set(),
|
"dt-diamond-bottom": {"gcc", "llvm"},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ def test_inheritance_of_directives(self):
|
|||||||
|
|
||||||
# Check dictionaries that should have been filled by directives
|
# Check dictionaries that should have been filled by directives
|
||||||
dependencies = pkg_cls.dependencies_by_name()
|
dependencies = pkg_cls.dependencies_by_name()
|
||||||
assert len(dependencies) == 3
|
assert len(dependencies) == 4
|
||||||
assert "cmake" in dependencies
|
assert "cmake" in dependencies
|
||||||
assert "openblas" in dependencies
|
assert "openblas" in dependencies
|
||||||
assert "mpi" in dependencies
|
assert "mpi" in dependencies
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
import spack.deptypes as dt
|
import spack.deptypes as dt
|
||||||
import spack.error
|
import spack.error
|
||||||
|
import spack.installer
|
||||||
import spack.repo
|
import spack.repo
|
||||||
import spack.util.hash as hashutil
|
import spack.util.hash as hashutil
|
||||||
import spack.version
|
import spack.version
|
||||||
@@ -80,8 +81,7 @@ def test_test_deptype(tmpdir):
|
|||||||
assert "z" not in spec
|
assert "z" not in spec
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("config")
|
def test_installed_deps(monkeypatch, install_mockery):
|
||||||
def test_installed_deps(monkeypatch, mock_packages):
|
|
||||||
"""Ensure that concrete specs and their build deps don't constrain solves.
|
"""Ensure that concrete specs and their build deps don't constrain solves.
|
||||||
|
|
||||||
Preinstall a package ``c`` that has a constrained build dependency on ``d``, then
|
Preinstall a package ``c`` that has a constrained build dependency on ``d``, then
|
||||||
@@ -101,28 +101,21 @@ def test_installed_deps(monkeypatch, mock_packages):
|
|||||||
# |/ \| c --> d build
|
# |/ \| c --> d build
|
||||||
# d e c --> e build/link
|
# d e c --> e build/link
|
||||||
#
|
#
|
||||||
a, b, c, d, e = ["installed-deps-%s" % s for s in "abcde"]
|
a, b, c, d, e = [f"installed-deps-{s}" for s in "abcde"]
|
||||||
|
|
||||||
# install C, which will force d's version to be 2
|
# install C, which will force d's version to be 2
|
||||||
# BUT d is only a build dependency of C, so it won't constrain
|
# BUT d is only a build dependency of C, so it won't constrain
|
||||||
# link/run dependents of C when C is depended on as an existing
|
# link/run dependents of C when C is depended on as an existing
|
||||||
# (concrete) installation.
|
# (concrete) installation.
|
||||||
c_spec = Spec(c)
|
c_spec = Spec(c).concretized()
|
||||||
c_spec.concretize()
|
|
||||||
assert c_spec[d].version == spack.version.Version("2")
|
assert c_spec[d].version == spack.version.Version("2")
|
||||||
|
|
||||||
installed_names = [s.name for s in c_spec.traverse()]
|
spack.installer.PackageInstaller([c_spec.package], fake=True, explicit=True).install()
|
||||||
|
|
||||||
def _mock_installed(self):
|
|
||||||
return self.name in installed_names
|
|
||||||
|
|
||||||
monkeypatch.setattr(Spec, "installed", _mock_installed)
|
|
||||||
|
|
||||||
# install A, which depends on B, C, D, and E, and force A to
|
# install A, which depends on B, C, D, and E, and force A to
|
||||||
# use the installed C. It should *not* force A to use the installed D
|
# use the installed C. It should *not* force A to use the installed D
|
||||||
# *if* we're doing a fresh installation.
|
# *if* we're doing a fresh installation.
|
||||||
a_spec = Spec(a)
|
a_spec = Spec(f"{a} ^/{c_spec.dag_hash()}")
|
||||||
a_spec._add_dependency(c_spec, depflag=dt.BUILD | dt.LINK, virtuals=())
|
|
||||||
a_spec.concretize()
|
a_spec.concretize()
|
||||||
assert spack.version.Version("2") == a_spec[c][d].version
|
assert spack.version.Version("2") == a_spec[c][d].version
|
||||||
assert spack.version.Version("2") == a_spec[e].version
|
assert spack.version.Version("2") == a_spec[e].version
|
||||||
@@ -184,120 +177,231 @@ def test_conflicting_package_constraints(self, set_dependency):
|
|||||||
with pytest.raises(spack.error.UnsatisfiableSpecError):
|
with pytest.raises(spack.error.UnsatisfiableSpecError):
|
||||||
spec.concretize()
|
spec.concretize()
|
||||||
|
|
||||||
def test_preorder_node_traversal(self):
|
@pytest.mark.parametrize(
|
||||||
dag = Spec("mpileaks ^zmpi").concretized()
|
"pairs,traverse_kwargs",
|
||||||
|
[
|
||||||
|
# Preorder node traversal
|
||||||
|
(
|
||||||
|
[
|
||||||
|
(0, "mpileaks"),
|
||||||
|
(1, "callpath"),
|
||||||
|
(2, "dyninst"),
|
||||||
|
(3, "gcc"),
|
||||||
|
(3, "gcc-runtime"),
|
||||||
|
(3, "libdwarf"),
|
||||||
|
(4, "libelf"),
|
||||||
|
(2, "zmpi"),
|
||||||
|
(3, "fake"),
|
||||||
|
],
|
||||||
|
{},
|
||||||
|
),
|
||||||
|
# Preorder edge traversal
|
||||||
|
(
|
||||||
|
[
|
||||||
|
(0, "mpileaks"),
|
||||||
|
(1, "callpath"),
|
||||||
|
(2, "dyninst"),
|
||||||
|
(3, "gcc"),
|
||||||
|
(3, "gcc-runtime"),
|
||||||
|
(4, "gcc"),
|
||||||
|
(3, "libdwarf"),
|
||||||
|
(4, "gcc"),
|
||||||
|
(4, "gcc-runtime"),
|
||||||
|
(4, "libelf"),
|
||||||
|
(5, "gcc"),
|
||||||
|
(5, "gcc-runtime"),
|
||||||
|
(3, "libelf"),
|
||||||
|
(2, "gcc"),
|
||||||
|
(2, "gcc-runtime"),
|
||||||
|
(2, "zmpi"),
|
||||||
|
(3, "fake"),
|
||||||
|
(3, "gcc"),
|
||||||
|
(3, "gcc-runtime"),
|
||||||
|
(1, "gcc"),
|
||||||
|
(1, "gcc-runtime"),
|
||||||
|
(1, "zmpi"),
|
||||||
|
],
|
||||||
|
{"cover": "edges"},
|
||||||
|
),
|
||||||
|
# Preorder path traversal
|
||||||
|
(
|
||||||
|
[
|
||||||
|
(0, "mpileaks"),
|
||||||
|
(1, "callpath"),
|
||||||
|
(2, "dyninst"),
|
||||||
|
(3, "gcc"),
|
||||||
|
(3, "gcc-runtime"),
|
||||||
|
(4, "gcc"),
|
||||||
|
(3, "libdwarf"),
|
||||||
|
(4, "gcc"),
|
||||||
|
(4, "gcc-runtime"),
|
||||||
|
(5, "gcc"),
|
||||||
|
(4, "libelf"),
|
||||||
|
(5, "gcc"),
|
||||||
|
(5, "gcc-runtime"),
|
||||||
|
(6, "gcc"),
|
||||||
|
(3, "libelf"),
|
||||||
|
(4, "gcc"),
|
||||||
|
(4, "gcc-runtime"),
|
||||||
|
(5, "gcc"),
|
||||||
|
(2, "gcc"),
|
||||||
|
(2, "gcc-runtime"),
|
||||||
|
(3, "gcc"),
|
||||||
|
(2, "zmpi"),
|
||||||
|
(3, "fake"),
|
||||||
|
(3, "gcc"),
|
||||||
|
(3, "gcc-runtime"),
|
||||||
|
(4, "gcc"),
|
||||||
|
(1, "gcc"),
|
||||||
|
(1, "gcc-runtime"),
|
||||||
|
(2, "gcc"),
|
||||||
|
(1, "zmpi"),
|
||||||
|
(2, "fake"),
|
||||||
|
(2, "gcc"),
|
||||||
|
(2, "gcc-runtime"),
|
||||||
|
(3, "gcc"),
|
||||||
|
],
|
||||||
|
{"cover": "paths"},
|
||||||
|
),
|
||||||
|
# Postorder node traversal
|
||||||
|
(
|
||||||
|
[
|
||||||
|
(3, "gcc"),
|
||||||
|
(3, "gcc-runtime"),
|
||||||
|
(4, "libelf"),
|
||||||
|
(3, "libdwarf"),
|
||||||
|
(2, "dyninst"),
|
||||||
|
(3, "fake"),
|
||||||
|
(2, "zmpi"),
|
||||||
|
(1, "callpath"),
|
||||||
|
(0, "mpileaks"),
|
||||||
|
],
|
||||||
|
{"order": "post"},
|
||||||
|
),
|
||||||
|
# Postorder edge traversal
|
||||||
|
(
|
||||||
|
[
|
||||||
|
(3, "gcc"),
|
||||||
|
(4, "gcc"),
|
||||||
|
(3, "gcc-runtime"),
|
||||||
|
(4, "gcc"),
|
||||||
|
(4, "gcc-runtime"),
|
||||||
|
(5, "gcc"),
|
||||||
|
(5, "gcc-runtime"),
|
||||||
|
(4, "libelf"),
|
||||||
|
(3, "libdwarf"),
|
||||||
|
(3, "libelf"),
|
||||||
|
(2, "dyninst"),
|
||||||
|
(2, "gcc"),
|
||||||
|
(2, "gcc-runtime"),
|
||||||
|
(3, "fake"),
|
||||||
|
(3, "gcc"),
|
||||||
|
(3, "gcc-runtime"),
|
||||||
|
(2, "zmpi"),
|
||||||
|
(1, "callpath"),
|
||||||
|
(1, "gcc"),
|
||||||
|
(1, "gcc-runtime"),
|
||||||
|
(1, "zmpi"),
|
||||||
|
(0, "mpileaks"),
|
||||||
|
],
|
||||||
|
{"cover": "edges", "order": "post"},
|
||||||
|
),
|
||||||
|
# Postorder path traversal
|
||||||
|
(
|
||||||
|
[
|
||||||
|
(3, "gcc"),
|
||||||
|
(4, "gcc"),
|
||||||
|
(3, "gcc-runtime"),
|
||||||
|
(4, "gcc"),
|
||||||
|
(5, "gcc"),
|
||||||
|
(4, "gcc-runtime"),
|
||||||
|
(5, "gcc"),
|
||||||
|
(6, "gcc"),
|
||||||
|
(5, "gcc-runtime"),
|
||||||
|
(4, "libelf"),
|
||||||
|
(3, "libdwarf"),
|
||||||
|
(4, "gcc"),
|
||||||
|
(5, "gcc"),
|
||||||
|
(4, "gcc-runtime"),
|
||||||
|
(3, "libelf"),
|
||||||
|
(2, "dyninst"),
|
||||||
|
(2, "gcc"),
|
||||||
|
(3, "gcc"),
|
||||||
|
(2, "gcc-runtime"),
|
||||||
|
(3, "fake"),
|
||||||
|
(3, "gcc"),
|
||||||
|
(4, "gcc"),
|
||||||
|
(3, "gcc-runtime"),
|
||||||
|
(2, "zmpi"),
|
||||||
|
(1, "callpath"),
|
||||||
|
(1, "gcc"),
|
||||||
|
(2, "gcc"),
|
||||||
|
(1, "gcc-runtime"),
|
||||||
|
(2, "fake"),
|
||||||
|
(2, "gcc"),
|
||||||
|
(3, "gcc"),
|
||||||
|
(2, "gcc-runtime"),
|
||||||
|
(1, "zmpi"),
|
||||||
|
(0, "mpileaks"),
|
||||||
|
],
|
||||||
|
{"cover": "paths", "order": "post"},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_traversal(self, pairs, traverse_kwargs, default_mock_concretization):
|
||||||
|
r"""Tests different traversals of the following graph
|
||||||
|
|
||||||
names = ["mpileaks", "callpath", "dyninst", "libdwarf", "libelf", "zmpi", "fake"]
|
o mpileaks
|
||||||
pairs = list(zip([0, 1, 2, 3, 4, 2, 3], names))
|
|\
|
||||||
|
| |\
|
||||||
|
| | |\
|
||||||
|
| | | |\
|
||||||
|
| | | | o callpath
|
||||||
|
| |_|_|/|
|
||||||
|
|/| |_|/|
|
||||||
|
| |/| |/|
|
||||||
|
| | |/|/|
|
||||||
|
o | | | | zmpi
|
||||||
|
|\| | | |
|
||||||
|
|\ \ \ \ \
|
||||||
|
| |_|/ / /
|
||||||
|
|/| | | |
|
||||||
|
| |\ \ \ \
|
||||||
|
| | |_|/ /
|
||||||
|
| |/| | |
|
||||||
|
| | o | | fake
|
||||||
|
| | / /
|
||||||
|
| | | o dyninst
|
||||||
|
| |_|/|
|
||||||
|
|/| |/|
|
||||||
|
| |/|/|
|
||||||
|
| | | |\
|
||||||
|
| | | | o libdwarf
|
||||||
|
| |_|_|/|
|
||||||
|
|/| |_|/|
|
||||||
|
| |/| |/|
|
||||||
|
| | |/|/
|
||||||
|
| | | o libel
|
||||||
|
| |_|/|
|
||||||
|
|/| |/|
|
||||||
|
| |/|/
|
||||||
|
o | | gcc-runtime
|
||||||
|
|\| |
|
||||||
|
| |/
|
||||||
|
|/|
|
||||||
|
o | glibc
|
||||||
|
/
|
||||||
|
o gcc
|
||||||
|
"""
|
||||||
|
dag = default_mock_concretization("mpileaks ^zmpi")
|
||||||
|
names = [x for _, x in pairs]
|
||||||
|
|
||||||
traversal = dag.traverse()
|
traversal = dag.traverse(**traverse_kwargs, depth=True)
|
||||||
assert [x.name for x in traversal] == names
|
|
||||||
|
|
||||||
traversal = dag.traverse(depth=True)
|
|
||||||
assert [(x, y.name) for x, y in traversal] == pairs
|
assert [(x, y.name) for x, y in traversal] == pairs
|
||||||
|
|
||||||
def test_preorder_edge_traversal(self):
|
traversal = dag.traverse(**traverse_kwargs)
|
||||||
dag = Spec("mpileaks ^zmpi").concretized()
|
|
||||||
|
|
||||||
names = [
|
|
||||||
"mpileaks",
|
|
||||||
"callpath",
|
|
||||||
"dyninst",
|
|
||||||
"libdwarf",
|
|
||||||
"libelf",
|
|
||||||
"libelf",
|
|
||||||
"zmpi",
|
|
||||||
"fake",
|
|
||||||
"zmpi",
|
|
||||||
]
|
|
||||||
pairs = list(zip([0, 1, 2, 3, 4, 3, 2, 3, 1], names))
|
|
||||||
|
|
||||||
traversal = dag.traverse(cover="edges")
|
|
||||||
assert [x.name for x in traversal] == names
|
assert [x.name for x in traversal] == names
|
||||||
|
|
||||||
traversal = dag.traverse(cover="edges", depth=True)
|
|
||||||
assert [(x, y.name) for x, y in traversal] == pairs
|
|
||||||
|
|
||||||
def test_preorder_path_traversal(self):
|
|
||||||
dag = Spec("mpileaks ^zmpi").concretized()
|
|
||||||
|
|
||||||
names = [
|
|
||||||
"mpileaks",
|
|
||||||
"callpath",
|
|
||||||
"dyninst",
|
|
||||||
"libdwarf",
|
|
||||||
"libelf",
|
|
||||||
"libelf",
|
|
||||||
"zmpi",
|
|
||||||
"fake",
|
|
||||||
"zmpi",
|
|
||||||
"fake",
|
|
||||||
]
|
|
||||||
pairs = list(zip([0, 1, 2, 3, 4, 3, 2, 3, 1, 2], names))
|
|
||||||
|
|
||||||
traversal = dag.traverse(cover="paths")
|
|
||||||
assert [x.name for x in traversal] == names
|
|
||||||
|
|
||||||
traversal = dag.traverse(cover="paths", depth=True)
|
|
||||||
assert [(x, y.name) for x, y in traversal] == pairs
|
|
||||||
|
|
||||||
def test_postorder_node_traversal(self):
|
|
||||||
dag = Spec("mpileaks ^zmpi").concretized()
|
|
||||||
|
|
||||||
names = ["libelf", "libdwarf", "dyninst", "fake", "zmpi", "callpath", "mpileaks"]
|
|
||||||
pairs = list(zip([4, 3, 2, 3, 2, 1, 0], names))
|
|
||||||
|
|
||||||
traversal = dag.traverse(order="post")
|
|
||||||
assert [x.name for x in traversal] == names
|
|
||||||
|
|
||||||
traversal = dag.traverse(depth=True, order="post")
|
|
||||||
assert [(x, y.name) for x, y in traversal] == pairs
|
|
||||||
|
|
||||||
def test_postorder_edge_traversal(self):
|
|
||||||
dag = Spec("mpileaks ^zmpi").concretized()
|
|
||||||
|
|
||||||
names = [
|
|
||||||
"libelf",
|
|
||||||
"libdwarf",
|
|
||||||
"libelf",
|
|
||||||
"dyninst",
|
|
||||||
"fake",
|
|
||||||
"zmpi",
|
|
||||||
"callpath",
|
|
||||||
"zmpi",
|
|
||||||
"mpileaks",
|
|
||||||
]
|
|
||||||
pairs = list(zip([4, 3, 3, 2, 3, 2, 1, 1, 0], names))
|
|
||||||
|
|
||||||
traversal = dag.traverse(cover="edges", order="post")
|
|
||||||
assert [x.name for x in traversal] == names
|
|
||||||
|
|
||||||
traversal = dag.traverse(cover="edges", depth=True, order="post")
|
|
||||||
assert [(x, y.name) for x, y in traversal] == pairs
|
|
||||||
|
|
||||||
def test_postorder_path_traversal(self):
|
|
||||||
dag = Spec("mpileaks ^zmpi").concretized()
|
|
||||||
|
|
||||||
names = [
|
|
||||||
"libelf",
|
|
||||||
"libdwarf",
|
|
||||||
"libelf",
|
|
||||||
"dyninst",
|
|
||||||
"fake",
|
|
||||||
"zmpi",
|
|
||||||
"callpath",
|
|
||||||
"fake",
|
|
||||||
"zmpi",
|
|
||||||
"mpileaks",
|
|
||||||
]
|
|
||||||
pairs = list(zip([4, 3, 3, 2, 3, 2, 1, 2, 1, 0], names))
|
|
||||||
|
|
||||||
traversal = dag.traverse(cover="paths", order="post")
|
|
||||||
assert [x.name for x in traversal] == names
|
|
||||||
|
|
||||||
traversal = dag.traverse(cover="paths", depth=True, order="post")
|
|
||||||
assert [(x, y.name) for x, y in traversal] == pairs
|
|
||||||
|
|
||||||
def test_dependents_and_dependencies_are_correct(self):
|
def test_dependents_and_dependencies_are_correct(self):
|
||||||
spec = Spec.from_literal(
|
spec = Spec.from_literal(
|
||||||
{
|
{
|
||||||
@@ -593,7 +697,9 @@ def test_construct_spec_with_deptypes(self):
|
|||||||
assert s["d"].edges_to_dependencies(name="e")[0].depflag == dt.BUILD | dt.LINK
|
assert s["d"].edges_to_dependencies(name="e")[0].depflag == dt.BUILD | dt.LINK
|
||||||
assert s["e"].edges_to_dependencies(name="f")[0].depflag == dt.RUN
|
assert s["e"].edges_to_dependencies(name="f")[0].depflag == dt.RUN
|
||||||
|
|
||||||
assert s["c"].edges_from_dependents(name="b")[0].depflag == dt.BUILD
|
# The subscript follows link/run transitive deps or direct build deps, therefore
|
||||||
|
# we need an extra step to get to "c"
|
||||||
|
assert s["b"]["c"].edges_from_dependents(name="b")[0].depflag == dt.BUILD
|
||||||
assert s["e"].edges_from_dependents(name="d")[0].depflag == dt.BUILD | dt.LINK
|
assert s["e"].edges_from_dependents(name="d")[0].depflag == dt.BUILD | dt.LINK
|
||||||
assert s["f"].edges_from_dependents(name="e")[0].depflag == dt.RUN
|
assert s["f"].edges_from_dependents(name="e")[0].depflag == dt.RUN
|
||||||
|
|
||||||
@@ -760,10 +866,10 @@ def test_spec_tree_respect_deptypes(self):
|
|||||||
"query,expected_length,expected_satisfies",
|
"query,expected_length,expected_satisfies",
|
||||||
[
|
[
|
||||||
({"virtuals": ["mpi"]}, 1, ["mpich", "mpi"]),
|
({"virtuals": ["mpi"]}, 1, ["mpich", "mpi"]),
|
||||||
({"depflag": dt.BUILD}, 2, ["mpich", "mpi", "callpath"]),
|
({"depflag": dt.BUILD}, 3, ["mpich", "mpi", "callpath"]),
|
||||||
({"depflag": dt.BUILD, "virtuals": ["mpi"]}, 1, ["mpich", "mpi"]),
|
({"depflag": dt.BUILD, "virtuals": ["mpi"]}, 1, ["mpich", "mpi"]),
|
||||||
({"depflag": dt.LINK}, 2, ["mpich", "mpi", "callpath"]),
|
({"depflag": dt.LINK}, 3, ["mpich", "mpi", "callpath"]),
|
||||||
({"depflag": dt.BUILD | dt.LINK}, 2, ["mpich", "mpi", "callpath"]),
|
({"depflag": dt.BUILD | dt.LINK}, 4, ["mpich", "mpi", "callpath"]),
|
||||||
({"virtuals": ["lapack"]}, 0, []),
|
({"virtuals": ["lapack"]}, 0, []),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@@ -772,12 +878,14 @@ def test_query_dependency_edges(
|
|||||||
):
|
):
|
||||||
"""Tests querying edges to dependencies on the following DAG:
|
"""Tests querying edges to dependencies on the following DAG:
|
||||||
|
|
||||||
[ ] mpileaks@=2.3
|
- [ ] mpileaks@2.3
|
||||||
[bl ] ^callpath@=1.0
|
- [bl ] ^callpath@1.0
|
||||||
[bl ] ^dyninst@=8.2
|
- [bl ] ^dyninst@8.2
|
||||||
[bl ] ^libdwarf@=20130729
|
- [bl ] ^libdwarf@20130729
|
||||||
[bl ] ^libelf@=0.8.13
|
- [bl ] ^libelf@0.8.13
|
||||||
[bl ] ^mpich@=3.0.4
|
[e] [b ] ^gcc@10.1.0
|
||||||
|
- [ l ] ^gcc-runtime@10.1.0
|
||||||
|
- [bl ] ^mpich@3.0.4~debug
|
||||||
"""
|
"""
|
||||||
mpileaks = default_mock_concretization("mpileaks")
|
mpileaks = default_mock_concretization("mpileaks")
|
||||||
edges = mpileaks.edges_to_dependencies(**query)
|
edges = mpileaks.edges_to_dependencies(**query)
|
||||||
@@ -843,8 +951,8 @@ def test_synthetic_construction_of_split_dependencies_from_same_package(mock_pac
|
|||||||
root.add_dependency_edge(build_spec, depflag=dt.BUILD, virtuals=())
|
root.add_dependency_edge(build_spec, depflag=dt.BUILD, virtuals=())
|
||||||
|
|
||||||
# Check dependencies from the perspective of root
|
# Check dependencies from the perspective of root
|
||||||
assert len(root.dependencies()) == 2
|
assert len(root.dependencies()) == 4
|
||||||
assert all(x.name == "pkg-c" for x in root.dependencies())
|
assert len([x for x in root.dependencies() if x.name == "pkg-c"]) == 2
|
||||||
|
|
||||||
assert "@2.0" in root.dependencies(name="pkg-c", deptype=dt.BUILD)[0]
|
assert "@2.0" in root.dependencies(name="pkg-c", deptype=dt.BUILD)[0]
|
||||||
assert "@1.0" in root.dependencies(name="pkg-c", deptype=dt.LINK | dt.RUN)[0]
|
assert "@1.0" in root.dependencies(name="pkg-c", deptype=dt.LINK | dt.RUN)[0]
|
||||||
@@ -868,8 +976,7 @@ def test_synthetic_construction_bootstrapping(mock_packages, config):
|
|||||||
|
|
||||||
root.add_dependency_edge(bootstrap, depflag=dt.BUILD, virtuals=())
|
root.add_dependency_edge(bootstrap, depflag=dt.BUILD, virtuals=())
|
||||||
|
|
||||||
assert len(root.dependencies()) == 1
|
assert len([x for x in root.dependencies() if x.name == "pkg-b"]) == 1
|
||||||
assert root.dependencies()[0].name == "pkg-b"
|
|
||||||
assert root.name == "pkg-b"
|
assert root.name == "pkg-b"
|
||||||
|
|
||||||
|
|
||||||
@@ -888,8 +995,8 @@ def test_addition_of_different_deptypes_in_multiple_calls(mock_packages, config)
|
|||||||
root.add_dependency_edge(bootstrap, depflag=current_depflag, virtuals=())
|
root.add_dependency_edge(bootstrap, depflag=current_depflag, virtuals=())
|
||||||
|
|
||||||
# Check edges in dependencies
|
# Check edges in dependencies
|
||||||
assert len(root.edges_to_dependencies()) == 1
|
assert len(root.edges_to_dependencies(name="pkg-b")) == 1
|
||||||
forward_edge = root.edges_to_dependencies(depflag=current_depflag)[0]
|
forward_edge = root.edges_to_dependencies(depflag=current_depflag, name="pkg-b")[0]
|
||||||
assert current_depflag & forward_edge.depflag
|
assert current_depflag & forward_edge.depflag
|
||||||
assert id(forward_edge.parent) == id(root)
|
assert id(forward_edge.parent) == id(root)
|
||||||
assert id(forward_edge.spec) == id(bootstrap)
|
assert id(forward_edge.spec) == id(bootstrap)
|
||||||
@@ -920,8 +1027,9 @@ def test_adding_same_deptype_with_the_same_name_raises(
|
|||||||
|
|
||||||
@pytest.mark.regression("33499")
|
@pytest.mark.regression("33499")
|
||||||
def test_indexing_prefers_direct_or_transitive_link_deps():
|
def test_indexing_prefers_direct_or_transitive_link_deps():
|
||||||
# Test whether spec indexing prefers direct/transitive link type deps over deps of
|
"""Tests whether spec indexing prefers direct/transitive link/run type deps over deps of
|
||||||
# build/run/test deps, and whether it does fall back to a full dag search.
|
build/test deps.
|
||||||
|
"""
|
||||||
root = Spec("root")
|
root = Spec("root")
|
||||||
|
|
||||||
# Use a and z to since we typically traverse by edges sorted alphabetically.
|
# Use a and z to since we typically traverse by edges sorted alphabetically.
|
||||||
@@ -934,7 +1042,7 @@ def test_indexing_prefers_direct_or_transitive_link_deps():
|
|||||||
z3_flavor_1 = Spec("z3 +through_a1")
|
z3_flavor_1 = Spec("z3 +through_a1")
|
||||||
z3_flavor_2 = Spec("z3 +through_z1")
|
z3_flavor_2 = Spec("z3 +through_z1")
|
||||||
|
|
||||||
root.add_dependency_edge(a1, depflag=dt.BUILD | dt.RUN | dt.TEST, virtuals=())
|
root.add_dependency_edge(a1, depflag=dt.BUILD | dt.TEST, virtuals=())
|
||||||
|
|
||||||
# unique package as a dep of a build/run/test type dep.
|
# unique package as a dep of a build/run/test type dep.
|
||||||
a1.add_dependency_edge(a2, depflag=dt.ALL, virtuals=())
|
a1.add_dependency_edge(a2, depflag=dt.ALL, virtuals=())
|
||||||
@@ -949,9 +1057,6 @@ def test_indexing_prefers_direct_or_transitive_link_deps():
|
|||||||
assert "through_z1" in root["z3"].variants
|
assert "through_z1" in root["z3"].variants
|
||||||
assert "through_a1" in a1["z3"].variants
|
assert "through_a1" in a1["z3"].variants
|
||||||
|
|
||||||
# Ensure that the full DAG is still searched
|
|
||||||
assert root["a2"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_getitem_sticks_to_subdag():
|
def test_getitem_sticks_to_subdag():
|
||||||
"""Test that indexing on Spec by virtual does not traverse outside the dag, which happens in
|
"""Test that indexing on Spec by virtual does not traverse outside the dag, which happens in
|
||||||
|
|||||||
@@ -18,15 +18,7 @@
|
|||||||
import spack.variant
|
import spack.variant
|
||||||
import spack.version as vn
|
import spack.version as vn
|
||||||
from spack.error import SpecError, UnsatisfiableSpecError
|
from spack.error import SpecError, UnsatisfiableSpecError
|
||||||
from spack.spec import (
|
from spack.spec import ArchSpec, DependencySpec, Spec, SpecFormatSigilError, SpecFormatStringError
|
||||||
ArchSpec,
|
|
||||||
CompilerSpec,
|
|
||||||
DependencySpec,
|
|
||||||
Spec,
|
|
||||||
SpecFormatSigilError,
|
|
||||||
SpecFormatStringError,
|
|
||||||
UnsupportedCompilerError,
|
|
||||||
)
|
|
||||||
from spack.variant import (
|
from spack.variant import (
|
||||||
InvalidVariantValueError,
|
InvalidVariantValueError,
|
||||||
MultipleValuesInExclusiveVariantError,
|
MultipleValuesInExclusiveVariantError,
|
||||||
@@ -461,8 +453,6 @@ def test_concrete_specs_which_satisfies_abstract(self, lhs, rhs, default_mock_co
|
|||||||
("foo os=redhat6", "platform=test os=debian6 target=x86_64"),
|
("foo os=redhat6", "platform=test os=debian6 target=x86_64"),
|
||||||
("foo target=x86_64", "platform=test os=redhat6 target=x86"),
|
("foo target=x86_64", "platform=test os=redhat6 target=x86"),
|
||||||
("foo arch=test-frontend-frontend", "platform=test os=frontend target=backend"),
|
("foo arch=test-frontend-frontend", "platform=test os=frontend target=backend"),
|
||||||
("foo%intel", "%gcc"),
|
|
||||||
("foo%intel", "%gcc"),
|
|
||||||
("foo%gcc@4.3", "%gcc@4.4:4.6"),
|
("foo%gcc@4.3", "%gcc@4.4:4.6"),
|
||||||
("foo@4.0%gcc", "@1:3%gcc"),
|
("foo@4.0%gcc", "@1:3%gcc"),
|
||||||
("foo@4.0%gcc@4.5", "@1:3%gcc@4.4:4.6"),
|
("foo@4.0%gcc@4.5", "@1:3%gcc@4.4:4.6"),
|
||||||
@@ -868,18 +858,21 @@ def test_spec_formatting(self, default_mock_concretization):
|
|||||||
package_segments = [
|
package_segments = [
|
||||||
("{NAME}", "", "name", lambda spec: spec),
|
("{NAME}", "", "name", lambda spec: spec),
|
||||||
("{VERSION}", "", "version", lambda spec: spec),
|
("{VERSION}", "", "version", lambda spec: spec),
|
||||||
("{compiler}", "", "compiler", lambda spec: spec),
|
# FIXME (compiler as nodes): recover this semantic
|
||||||
|
# ("{compiler}", "", "compiler", lambda spec: spec),
|
||||||
("{compiler_flags}", "", "compiler_flags", lambda spec: spec),
|
("{compiler_flags}", "", "compiler_flags", lambda spec: spec),
|
||||||
("{variants}", "", "variants", lambda spec: spec),
|
("{variants}", "", "variants", lambda spec: spec),
|
||||||
("{architecture}", "", "architecture", lambda spec: spec),
|
("{architecture}", "", "architecture", lambda spec: spec),
|
||||||
("{@VERSIONS}", "@", "versions", lambda spec: spec),
|
("{@VERSIONS}", "@", "versions", lambda spec: spec),
|
||||||
("{%compiler}", "%", "compiler", lambda spec: spec),
|
# FIXME (compiler as nodes): recover this semantic
|
||||||
|
# ("{%compiler}", "%", "compiler", lambda spec: spec),
|
||||||
("{arch=architecture}", "arch=", "architecture", lambda spec: spec),
|
("{arch=architecture}", "arch=", "architecture", lambda spec: spec),
|
||||||
("{namespace=namespace}", "namespace=", "namespace", lambda spec: spec),
|
("{namespace=namespace}", "namespace=", "namespace", lambda spec: spec),
|
||||||
("{compiler.name}", "", "name", lambda spec: spec.compiler),
|
# FIXME (compiler as nodes): recover this semantic
|
||||||
("{compiler.version}", "", "version", lambda spec: spec.compiler),
|
# ("{compiler.name}", "", "name", lambda spec: spec.compiler),
|
||||||
("{%compiler.name}", "%", "name", lambda spec: spec.compiler),
|
# ("{compiler.version}", "", "version", lambda spec: spec.compiler),
|
||||||
("{@compiler.version}", "@", "version", lambda spec: spec.compiler),
|
# ("{%compiler.name}", "%", "name", lambda spec: spec.compiler),
|
||||||
|
# ("{@compiler.version}", "@", "version", lambda spec: spec.compiler),
|
||||||
("{architecture.platform}", "", "platform", lambda spec: spec.architecture),
|
("{architecture.platform}", "", "platform", lambda spec: spec.architecture),
|
||||||
("{architecture.os}", "", "os", lambda spec: spec.architecture),
|
("{architecture.os}", "", "os", lambda spec: spec.architecture),
|
||||||
("{architecture.target}", "", "target", lambda spec: spec.architecture),
|
("{architecture.target}", "", "target", lambda spec: spec.architecture),
|
||||||
@@ -942,7 +935,6 @@ def check_prop(check_spec, fmt_str, prop, getter):
|
|||||||
"{name}",
|
"{name}",
|
||||||
"{version}",
|
"{version}",
|
||||||
"{@version}",
|
"{@version}",
|
||||||
"{%compiler}",
|
|
||||||
"{namespace}",
|
"{namespace}",
|
||||||
"{ namespace=namespace}",
|
"{ namespace=namespace}",
|
||||||
"{ namespace =namespace}",
|
"{ namespace =namespace}",
|
||||||
@@ -1520,16 +1512,17 @@ def test_unsatisfiable_virtual_deps_bindings(self, spec_str):
|
|||||||
("git-test@git.foo/bar", "{name}-{version}", str(pathlib.Path("git-test-git.foo_bar"))),
|
("git-test@git.foo/bar", "{name}-{version}", str(pathlib.Path("git-test-git.foo_bar"))),
|
||||||
("git-test@git.foo/bar", "{name}-{version}-{/hash}", None),
|
("git-test@git.foo/bar", "{name}-{version}-{/hash}", None),
|
||||||
("git-test@git.foo/bar", "{name}/{version}", str(pathlib.Path("git-test", "git.foo_bar"))),
|
("git-test@git.foo/bar", "{name}/{version}", str(pathlib.Path("git-test", "git.foo_bar"))),
|
||||||
(
|
# FIXME (compiler as nodes): revisit these tests
|
||||||
"git-test@{0}=1.0%gcc".format("a" * 40),
|
# (
|
||||||
"{name}/{version}/{compiler}",
|
# "git-test@{0}=1.0%gcc".format("a" * 40),
|
||||||
str(pathlib.Path("git-test", "{0}_1.0".format("a" * 40), "gcc")),
|
# "{name}/{version}/{compiler}",
|
||||||
),
|
# str(pathlib.Path("git-test", "{0}_1.0".format("a" * 40), "gcc")),
|
||||||
(
|
# ),
|
||||||
"git-test@git.foo/bar=1.0%gcc",
|
# (
|
||||||
"{name}/{version}/{compiler}",
|
# "git-test@git.foo/bar=1.0%gcc",
|
||||||
str(pathlib.Path("git-test", "git.foo_bar_1.0", "gcc")),
|
# "{name}/{version}/{compiler}",
|
||||||
),
|
# str(pathlib.Path("git-test", "git.foo_bar_1.0", "gcc")),
|
||||||
|
# ),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_spec_format_path(spec_str, format_str, expected, mock_git_test_package):
|
def test_spec_format_path(spec_str, format_str, expected, mock_git_test_package):
|
||||||
@@ -1712,12 +1705,18 @@ def test_call_dag_hash_on_old_dag_hash_spec(mock_packages, default_mock_concreti
|
|||||||
def test_spec_trim(mock_packages, config):
|
def test_spec_trim(mock_packages, config):
|
||||||
top = Spec("dt-diamond").concretized()
|
top = Spec("dt-diamond").concretized()
|
||||||
top.trim("dt-diamond-left")
|
top.trim("dt-diamond-left")
|
||||||
remaining = set(x.name for x in top.traverse())
|
remaining = {x.name for x in top.traverse()}
|
||||||
assert set(["dt-diamond", "dt-diamond-right", "dt-diamond-bottom"]) == remaining
|
assert {
|
||||||
|
"dt-diamond",
|
||||||
|
"dt-diamond-right",
|
||||||
|
"dt-diamond-bottom",
|
||||||
|
"gcc-runtime",
|
||||||
|
"gcc",
|
||||||
|
} == remaining
|
||||||
|
|
||||||
top.trim("dt-diamond-right")
|
top.trim("dt-diamond-right")
|
||||||
remaining = set(x.name for x in top.traverse())
|
remaining = {x.name for x in top.traverse()}
|
||||||
assert set(["dt-diamond"]) == remaining
|
assert {"dt-diamond", "gcc-runtime", "gcc"} == remaining
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.regression("30861")
|
@pytest.mark.regression("30861")
|
||||||
@@ -1747,11 +1746,6 @@ def test_concretize_partial_old_dag_hash_spec(mock_packages, config):
|
|||||||
assert not getattr(spec["dt-diamond-bottom"], "_package_hash", None)
|
assert not getattr(spec["dt-diamond-bottom"], "_package_hash", None)
|
||||||
|
|
||||||
|
|
||||||
def test_unsupported_compiler():
|
|
||||||
with pytest.raises(UnsupportedCompilerError):
|
|
||||||
Spec("gcc%fake-compiler").validate_or_raise()
|
|
||||||
|
|
||||||
|
|
||||||
def test_package_hash_affects_dunder_and_dag_hash(mock_packages, default_mock_concretization):
|
def test_package_hash_affects_dunder_and_dag_hash(mock_packages, default_mock_concretization):
|
||||||
a1 = default_mock_concretization("pkg-a")
|
a1 = default_mock_concretization("pkg-a")
|
||||||
a2 = default_mock_concretization("pkg-a")
|
a2 = default_mock_concretization("pkg-a")
|
||||||
@@ -1824,10 +1818,10 @@ def test_abstract_contains_semantic(lhs, rhs, expected, mock_packages):
|
|||||||
(ArchSpec, "None-ubuntu20.04-None", "None-ubuntu20.04-None", (True, True, True)),
|
(ArchSpec, "None-ubuntu20.04-None", "None-ubuntu20.04-None", (True, True, True)),
|
||||||
(ArchSpec, "None-ubuntu20.04-None", "None-ubuntu22.04-None", (False, False, False)),
|
(ArchSpec, "None-ubuntu20.04-None", "None-ubuntu22.04-None", (False, False, False)),
|
||||||
# Compiler
|
# Compiler
|
||||||
(CompilerSpec, "gcc", "clang", (False, False, False)),
|
(Spec, "gcc", "clang", (False, False, False)),
|
||||||
(CompilerSpec, "gcc", "gcc@5", (True, False, True)),
|
(Spec, "gcc", "gcc@5", (True, False, True)),
|
||||||
(CompilerSpec, "gcc@5", "gcc@5.3", (True, False, True)),
|
(Spec, "gcc@5", "gcc@5.3", (True, False, True)),
|
||||||
(CompilerSpec, "gcc@5", "gcc@5-tag", (True, False, True)),
|
(Spec, "gcc@5", "gcc@5-tag", (True, False, True)),
|
||||||
# Flags (flags are a map, so for convenience we initialize a full Spec)
|
# Flags (flags are a map, so for convenience we initialize a full Spec)
|
||||||
# Note: the semantic is that of sv variants, not mv variants
|
# Note: the semantic is that of sv variants, not mv variants
|
||||||
(Spec, "cppflags=-foo", "cppflags=-bar", (True, False, False)),
|
(Spec, "cppflags=-foo", "cppflags=-bar", (True, False, False)),
|
||||||
@@ -1883,8 +1877,8 @@ def test_intersects_and_satisfies(factory, lhs_str, rhs_str, results):
|
|||||||
"None-ubuntu20.04-nocona,haswell",
|
"None-ubuntu20.04-nocona,haswell",
|
||||||
),
|
),
|
||||||
# Compiler
|
# Compiler
|
||||||
(CompilerSpec, "gcc@5", "gcc@5-tag", True, "gcc@5-tag"),
|
(Spec, "foo %gcc@5", "foo %gcc@5-tag", True, "foo %gcc@5-tag"),
|
||||||
(CompilerSpec, "gcc@5", "gcc@5", False, "gcc@5"),
|
(Spec, "foo %gcc@5", "foo %gcc@5", False, "foo %gcc@5"),
|
||||||
# Flags
|
# Flags
|
||||||
(Spec, "cppflags=-foo", "cppflags=-foo", False, "cppflags=-foo"),
|
(Spec, "cppflags=-foo", "cppflags=-foo", False, "cppflags=-foo"),
|
||||||
(Spec, "cppflags=-foo", "cflags=-foo", True, "cppflags=-foo cflags=-foo"),
|
(Spec, "cppflags=-foo", "cflags=-foo", True, "cppflags=-foo cflags=-foo"),
|
||||||
|
|||||||
@@ -815,9 +815,7 @@ def test_dep_spec_by_hash(database, config):
|
|||||||
assert "zmpi" in mpileaks_hash_fake
|
assert "zmpi" in mpileaks_hash_fake
|
||||||
assert mpileaks_hash_fake["zmpi"] == spack.spec.Spec("zmpi")
|
assert mpileaks_hash_fake["zmpi"] == spack.spec.Spec("zmpi")
|
||||||
|
|
||||||
mpileaks_hash_zmpi = SpecParser(
|
mpileaks_hash_zmpi = SpecParser(f"mpileaks ^ /{zmpi.dag_hash()}").next_spec()
|
||||||
f"mpileaks %{mpileaks_zmpi.compiler} ^ /{zmpi.dag_hash()}"
|
|
||||||
).next_spec()
|
|
||||||
mpileaks_hash_zmpi.replace_hash()
|
mpileaks_hash_zmpi.replace_hash()
|
||||||
assert "zmpi" in mpileaks_hash_zmpi
|
assert "zmpi" in mpileaks_hash_zmpi
|
||||||
assert mpileaks_hash_zmpi["zmpi"] == zmpi
|
assert mpileaks_hash_zmpi["zmpi"] == zmpi
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ def test_tag_get_available(tags, expected, mock_packages):
|
|||||||
|
|
||||||
|
|
||||||
def test_tag_get_installed_packages(mock_packages, mock_archive, mock_fetch, install_mockery):
|
def test_tag_get_installed_packages(mock_packages, mock_archive, mock_fetch, install_mockery):
|
||||||
install("mpich")
|
install("--fake", "mpich")
|
||||||
|
|
||||||
for skip in [False, True]:
|
for skip in [False, True]:
|
||||||
all_pkgs = spack.tag.packages_with_tags(None, True, skip)
|
all_pkgs = spack.tag.packages_with_tags(None, True, skip)
|
||||||
|
|||||||
Reference in New Issue
Block a user