Speed-up unit tests by caching default mock concretization (#33755)

This commit is contained in:
Massimiliano Culpo 2022-11-11 21:32:40 +01:00 committed by GitHub
parent 5f8511311c
commit 022a2d2eaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 217 additions and 179 deletions

View File

@ -17,7 +17,7 @@
import spack.target import spack.target
@pytest.fixture @pytest.fixture(scope="module")
def current_host_platform(): def current_host_platform():
"""Return the platform of the current host as detected by the """Return the platform of the current host as detected by the
'platform' stdlib package. 'platform' stdlib package.
@ -34,23 +34,23 @@ def current_host_platform():
# Valid keywords for os=xxx or target=xxx # Valid keywords for os=xxx or target=xxx
valid_keywords = ["fe", "be", "frontend", "backend"] VALID_KEYWORDS = ["fe", "be", "frontend", "backend"]
TEST_PLATFORM = spack.platforms.Test()
@pytest.fixture( @pytest.fixture(params=([str(x) for x in TEST_PLATFORM.targets] + VALID_KEYWORDS), scope="module")
params=([x for x in spack.platforms.Test().targets] + valid_keywords + ["default_target"])
)
def target_str(request): def target_str(request):
"""All the possible strings that can be used for targets""" """All the possible strings that can be used for targets"""
return str(request.param) return request.param
@pytest.fixture( @pytest.fixture(
params=([x for x in spack.platforms.Test().operating_sys] + valid_keywords + ["default_os"]) params=([str(x) for x in TEST_PLATFORM.operating_sys] + VALID_KEYWORDS), scope="module"
) )
def os_str(request): def os_str(request):
"""All the possible strings that can be used for operating systems""" """All the possible strings that can be used for operating systems"""
return str(request.param) return request.param
def test_platform(current_host_platform): def test_platform(current_host_platform):
@ -64,16 +64,19 @@ def test_user_input_combination(config, target_str, os_str):
"""Test for all the valid user input combinations that both the target and """Test for all the valid user input combinations that both the target and
the operating system match. the operating system match.
""" """
platform = spack.platforms.Test() spec_str = "libelf os={} target={}".format(os_str, target_str)
spec_str = "libelf" spec = spack.spec.Spec(spec_str)
if os_str != "default_os": assert spec.architecture.os == str(TEST_PLATFORM.operating_system(os_str))
spec_str += " os={0}".format(os_str) assert spec.architecture.target == TEST_PLATFORM.target(target_str)
if target_str != "default_target":
spec_str += " target={0}".format(target_str)
spec = spack.spec.Spec(spec_str).concretized()
assert spec.architecture.os == str(platform.operating_system(os_str))
assert spec.architecture.target == platform.target(target_str) def test_default_os_and_target(config):
"""Test that is we don't specify `os=` or `target=` we get the default values
after concretization.
"""
spec = spack.spec.Spec("libelf").concretized()
assert spec.architecture.os == str(TEST_PLATFORM.operating_system("default_os"))
assert spec.architecture.target == TEST_PLATFORM.target("default_target")
def test_operating_system_conversion_to_dict(): def test_operating_system_conversion_to_dict():

View File

@ -27,9 +27,9 @@
@pytest.fixture() @pytest.fixture()
def concretize_and_setup(): def concretize_and_setup(default_mock_concretization):
def _func(spec_str): def _func(spec_str):
s = Spec("mpich").concretized() s = default_mock_concretization(spec_str)
setup_package(s.package, False) setup_package(s.package, False)
return s return s
@ -95,8 +95,8 @@ def test_negative_ninja_check(self, input_dir, test_dir, concretize_and_setup):
@pytest.mark.usefixtures("config", "mock_packages") @pytest.mark.usefixtures("config", "mock_packages")
class TestAutotoolsPackage(object): class TestAutotoolsPackage(object):
def test_with_or_without(self): def test_with_or_without(self, default_mock_concretization):
s = Spec("a").concretized() s = default_mock_concretization("a")
options = s.package.with_or_without("foo") options = s.package.with_or_without("foo")
# Ensure that values that are not representing a feature # Ensure that values that are not representing a feature
@ -127,8 +127,8 @@ def activate(value):
options = s.package.with_or_without("lorem-ipsum", variant="lorem_ipsum") options = s.package.with_or_without("lorem-ipsum", variant="lorem_ipsum")
assert "--without-lorem-ipsum" in options assert "--without-lorem-ipsum" in options
def test_none_is_allowed(self): def test_none_is_allowed(self, default_mock_concretization):
s = Spec("a foo=none").concretized() s = default_mock_concretization("a foo=none")
options = s.package.with_or_without("foo") options = s.package.with_or_without("foo")
# Ensure that values that are not representing a feature # Ensure that values that are not representing a feature
@ -138,9 +138,11 @@ def test_none_is_allowed(self):
assert "--without-baz" in options assert "--without-baz" in options
assert "--no-fee" in options assert "--no-fee" in options
def test_libtool_archive_files_are_deleted_by_default(self, mutable_database): def test_libtool_archive_files_are_deleted_by_default(
self, default_mock_concretization, mutable_database
):
# Install a package that creates a mock libtool archive # Install a package that creates a mock libtool archive
s = Spec("libtool-deletion").concretized() s = default_mock_concretization("libtool-deletion")
s.package.do_install(explicit=True) s.package.do_install(explicit=True)
# Assert the libtool archive is not there and we have # Assert the libtool archive is not there and we have
@ -151,24 +153,25 @@ def test_libtool_archive_files_are_deleted_by_default(self, mutable_database):
assert libtool_deletion_log assert libtool_deletion_log
def test_libtool_archive_files_might_be_installed_on_demand( def test_libtool_archive_files_might_be_installed_on_demand(
self, mutable_database, monkeypatch self, mutable_database, monkeypatch, default_mock_concretization
): ):
# Install a package that creates a mock libtool archive, # Install a package that creates a mock libtool archive,
# patch its package to preserve the installation # patch its package to preserve the installation
s = Spec("libtool-deletion").concretized() s = default_mock_concretization("libtool-deletion")
monkeypatch.setattr(type(s.package.builder), "install_libtool_archives", True) monkeypatch.setattr(type(s.package.builder), "install_libtool_archives", True)
s.package.do_install(explicit=True) s.package.do_install(explicit=True)
# Assert libtool archives are installed # Assert libtool archives are installed
assert os.path.exists(s.package.builder.libtool_archive_file) assert os.path.exists(s.package.builder.libtool_archive_file)
def test_autotools_gnuconfig_replacement(self, mutable_database): def test_autotools_gnuconfig_replacement(self, default_mock_concretization, mutable_database):
""" """
Tests whether only broken config.sub and config.guess are replaced with Tests whether only broken config.sub and config.guess are replaced with
files from working alternatives from the gnuconfig package. files from working alternatives from the gnuconfig package.
""" """
s = Spec("autotools-config-replacement +patch_config_files +gnuconfig") s = default_mock_concretization(
s.concretize() "autotools-config-replacement +patch_config_files +gnuconfig"
)
s.package.do_install() s.package.do_install()
with open(os.path.join(s.prefix.broken, "config.sub")) as f: with open(os.path.join(s.prefix.broken, "config.sub")) as f:
@ -183,12 +186,15 @@ def test_autotools_gnuconfig_replacement(self, mutable_database):
with open(os.path.join(s.prefix.working, "config.guess")) as f: with open(os.path.join(s.prefix.working, "config.guess")) as f:
assert "gnuconfig version of config.guess" not in f.read() assert "gnuconfig version of config.guess" not in f.read()
def test_autotools_gnuconfig_replacement_disabled(self, mutable_database): def test_autotools_gnuconfig_replacement_disabled(
self, default_mock_concretization, mutable_database
):
""" """
Tests whether disabling patch_config_files Tests whether disabling patch_config_files
""" """
s = Spec("autotools-config-replacement ~patch_config_files +gnuconfig") s = default_mock_concretization(
s.concretize() "autotools-config-replacement ~patch_config_files +gnuconfig"
)
s.package.do_install() s.package.do_install()
with open(os.path.join(s.prefix.broken, "config.sub")) as f: with open(os.path.join(s.prefix.broken, "config.sub")) as f:
@ -252,29 +258,29 @@ def test_broken_external_gnuconfig(self, mutable_database, tmpdir):
@pytest.mark.usefixtures("config", "mock_packages") @pytest.mark.usefixtures("config", "mock_packages")
class TestCMakePackage(object): class TestCMakePackage(object):
def test_cmake_std_args(self): def test_cmake_std_args(self, default_mock_concretization):
# Call the function on a CMakePackage instance # Call the function on a CMakePackage instance
s = Spec("cmake-client").concretized() s = default_mock_concretization("cmake-client")
expected = spack.build_systems.cmake.CMakeBuilder.std_args(s.package) expected = spack.build_systems.cmake.CMakeBuilder.std_args(s.package)
assert s.package.builder.std_cmake_args == expected assert s.package.builder.std_cmake_args == expected
# Call it on another kind of package # Call it on another kind of package
s = Spec("mpich").concretized() s = default_mock_concretization("mpich")
assert spack.build_systems.cmake.CMakeBuilder.std_args(s.package) assert spack.build_systems.cmake.CMakeBuilder.std_args(s.package)
def test_cmake_bad_generator(self, monkeypatch): def test_cmake_bad_generator(self, monkeypatch, default_mock_concretization):
s = Spec("cmake-client").concretized() s = default_mock_concretization("cmake-client")
monkeypatch.setattr(type(s.package), "generator", "Yellow Sticky Notes", raising=False) monkeypatch.setattr(type(s.package), "generator", "Yellow Sticky Notes", raising=False)
with pytest.raises(spack.package_base.InstallError): with pytest.raises(spack.package_base.InstallError):
s.package.builder.std_cmake_args s.package.builder.std_cmake_args
def test_cmake_secondary_generator(config, mock_packages): def test_cmake_secondary_generator(self, default_mock_concretization):
s = Spec("cmake-client").concretized() s = default_mock_concretization("cmake-client")
s.package.generator = "CodeBlocks - Unix Makefiles" s.package.generator = "CodeBlocks - Unix Makefiles"
assert s.package.builder.std_cmake_args assert s.package.builder.std_cmake_args
def test_define(self): def test_define(self, default_mock_concretization):
s = Spec("cmake-client").concretized() s = default_mock_concretization("cmake-client")
define = s.package.define define = s.package.define
for cls in (list, tuple): for cls in (list, tuple):
@ -324,8 +330,8 @@ class TestDownloadMixins(object):
), ),
], ],
) )
def test_attributes_defined(self, spec_str, expected_url): def test_attributes_defined(self, default_mock_concretization, spec_str, expected_url):
s = Spec(spec_str).concretized() s = default_mock_concretization(spec_str)
assert s.package.urls[0] == expected_url assert s.package.urls[0] == expected_url
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -344,33 +350,33 @@ def test_attributes_defined(self, spec_str, expected_url):
("mirror-xorg-broken", r"{0} must define a `xorg_mirror_path` attribute"), ("mirror-xorg-broken", r"{0} must define a `xorg_mirror_path` attribute"),
], ],
) )
def test_attributes_missing(self, spec_str, error_fmt): def test_attributes_missing(self, default_mock_concretization, spec_str, error_fmt):
s = Spec(spec_str).concretized() s = default_mock_concretization(spec_str)
error_msg = error_fmt.format(type(s.package).__name__) error_msg = error_fmt.format(type(s.package).__name__)
with pytest.raises(AttributeError, match=error_msg): with pytest.raises(AttributeError, match=error_msg):
s.package.urls s.package.urls
def test_cmake_define_from_variant_conditional(config, mock_packages): def test_cmake_define_from_variant_conditional(default_mock_concretization):
"""Test that define_from_variant returns empty string when a condition on a variant """Test that define_from_variant returns empty string when a condition on a variant
is not met. When this is the case, the variant is not set in the spec.""" is not met. When this is the case, the variant is not set in the spec."""
s = Spec("cmake-conditional-variants-test").concretized() s = default_mock_concretization("cmake-conditional-variants-test")
assert "example" not in s.variants assert "example" not in s.variants
assert s.package.define_from_variant("EXAMPLE", "example") == "" assert s.package.define_from_variant("EXAMPLE", "example") == ""
def test_autotools_args_from_conditional_variant(config, mock_packages): def test_autotools_args_from_conditional_variant(default_mock_concretization):
"""Test that _activate_or_not returns an empty string when a condition on a variant """Test that _activate_or_not returns an empty string when a condition on a variant
is not met. When this is the case, the variant is not set in the spec.""" is not met. When this is the case, the variant is not set in the spec."""
s = Spec("autotools-conditional-variants-test").concretized() s = default_mock_concretization("autotools-conditional-variants-test")
assert "example" not in s.variants assert "example" not in s.variants
assert len(s.package.builder._activate_or_not("example", "enable", "disable")) == 0 assert len(s.package.builder._activate_or_not("example", "enable", "disable")) == 0
def test_autoreconf_search_path_args_multiple(config, mock_packages, tmpdir): def test_autoreconf_search_path_args_multiple(default_mock_concretization, tmpdir):
"""autoreconf should receive the right -I flags with search paths for m4 files """autoreconf should receive the right -I flags with search paths for m4 files
for build deps.""" for build deps."""
spec = Spec("dttop").concretized() spec = default_mock_concretization("dttop")
aclocal_fst = str(tmpdir.mkdir("fst").mkdir("share").mkdir("aclocal")) aclocal_fst = str(tmpdir.mkdir("fst").mkdir("share").mkdir("aclocal"))
aclocal_snd = str(tmpdir.mkdir("snd").mkdir("share").mkdir("aclocal")) aclocal_snd = str(tmpdir.mkdir("snd").mkdir("share").mkdir("aclocal"))
build_dep_one, build_dep_two = spec.dependencies(deptype="build") build_dep_one, build_dep_two = spec.dependencies(deptype="build")
@ -384,11 +390,11 @@ def test_autoreconf_search_path_args_multiple(config, mock_packages, tmpdir):
] ]
def test_autoreconf_search_path_args_skip_automake(config, mock_packages, tmpdir): def test_autoreconf_search_path_args_skip_automake(default_mock_concretization, tmpdir):
"""automake's aclocal dir should not be added as -I flag as it is a default """automake's aclocal dir should not be added as -I flag as it is a default
3rd party dir search path, and if it's a system version it usually includes 3rd party dir search path, and if it's a system version it usually includes
m4 files shadowing spack deps.""" m4 files shadowing spack deps."""
spec = Spec("dttop").concretized() spec = default_mock_concretization("dttop")
tmpdir.mkdir("fst").mkdir("share").mkdir("aclocal") tmpdir.mkdir("fst").mkdir("share").mkdir("aclocal")
aclocal_snd = str(tmpdir.mkdir("snd").mkdir("share").mkdir("aclocal")) aclocal_snd = str(tmpdir.mkdir("snd").mkdir("share").mkdir("aclocal"))
build_dep_one, build_dep_two = spec.dependencies(deptype="build") build_dep_one, build_dep_two = spec.dependencies(deptype="build")
@ -398,9 +404,9 @@ def test_autoreconf_search_path_args_skip_automake(config, mock_packages, tmpdir
assert spack.build_systems.autotools._autoreconf_search_path_args(spec) == ["-I", aclocal_snd] assert spack.build_systems.autotools._autoreconf_search_path_args(spec) == ["-I", aclocal_snd]
def test_autoreconf_search_path_args_external_order(config, mock_packages, tmpdir): def test_autoreconf_search_path_args_external_order(default_mock_concretization, tmpdir):
"""When a build dep is external, its -I flag should occur last""" """When a build dep is external, its -I flag should occur last"""
spec = Spec("dttop").concretized() spec = default_mock_concretization("dttop")
aclocal_fst = str(tmpdir.mkdir("fst").mkdir("share").mkdir("aclocal")) aclocal_fst = str(tmpdir.mkdir("fst").mkdir("share").mkdir("aclocal"))
aclocal_snd = str(tmpdir.mkdir("snd").mkdir("share").mkdir("aclocal")) aclocal_snd = str(tmpdir.mkdir("snd").mkdir("share").mkdir("aclocal"))
build_dep_one, build_dep_two = spec.dependencies(deptype="build") build_dep_one, build_dep_two = spec.dependencies(deptype="build")
@ -414,18 +420,18 @@ def test_autoreconf_search_path_args_external_order(config, mock_packages, tmpdi
] ]
def test_autoreconf_search_path_skip_nonexisting(config, mock_packages, tmpdir): def test_autoreconf_search_path_skip_nonexisting(default_mock_concretization, tmpdir):
"""Skip -I flags for non-existing directories""" """Skip -I flags for non-existing directories"""
spec = Spec("dttop").concretized() spec = default_mock_concretization("dttop")
build_dep_one, build_dep_two = spec.dependencies(deptype="build") build_dep_one, build_dep_two = spec.dependencies(deptype="build")
build_dep_one.prefix = str(tmpdir.join("fst")) build_dep_one.prefix = str(tmpdir.join("fst"))
build_dep_two.prefix = str(tmpdir.join("snd")) build_dep_two.prefix = str(tmpdir.join("snd"))
assert spack.build_systems.autotools._autoreconf_search_path_args(spec) == [] assert spack.build_systems.autotools._autoreconf_search_path_args(spec) == []
def test_autoreconf_search_path_dont_repeat(config, mock_packages, tmpdir): def test_autoreconf_search_path_dont_repeat(default_mock_concretization, tmpdir):
"""Do not add the same -I flag twice to keep things readable for humans""" """Do not add the same -I flag twice to keep things readable for humans"""
spec = Spec("dttop").concretized() spec = default_mock_concretization("dttop")
aclocal = str(tmpdir.mkdir("prefix").mkdir("share").mkdir("aclocal")) aclocal = str(tmpdir.mkdir("prefix").mkdir("share").mkdir("aclocal"))
build_dep_one, build_dep_two = spec.dependencies(deptype="build") build_dep_one, build_dep_two = spec.dependencies(deptype="build")
build_dep_one.external_path = str(tmpdir.join("prefix")) build_dep_one.external_path = str(tmpdir.join("prefix"))

View File

@ -18,7 +18,6 @@
import spack.environment as ev import spack.environment as ev
import spack.error import spack.error
import spack.paths as spack_paths import spack.paths as spack_paths
import spack.spec as spec
import spack.util.gpg import spack.util.gpg
import spack.util.spack_yaml as syaml import spack.util.spack_yaml as syaml
@ -145,13 +144,12 @@ def test_download_and_extract_artifacts(tmpdir, monkeypatch, working_env):
ci.download_and_extract_artifacts(url, working_dir) ci.download_and_extract_artifacts(url, working_dir)
def test_ci_copy_stage_logs_to_artifacts_fail(tmpdir, config, mock_packages, monkeypatch, capfd): def test_ci_copy_stage_logs_to_artifacts_fail(tmpdir, default_mock_concretization, capfd):
"""The copy will fail because the spec is not concrete so does not have """The copy will fail because the spec is not concrete so does not have
a package.""" a package."""
log_dir = tmpdir.join("log_dir") log_dir = tmpdir.join("log_dir")
s = spec.Spec("printing-package").concretized() concrete_spec = default_mock_concretization("printing-package")
ci.copy_stage_logs_to_artifacts(concrete_spec, log_dir)
ci.copy_stage_logs_to_artifacts(s, log_dir)
_, err = capfd.readouterr() _, err = capfd.readouterr()
assert "Unable to copy files" in err assert "Unable to copy files" in err
assert "No such file or directory" in err assert "No such file or directory" in err
@ -456,17 +454,16 @@ def test_get_spec_filter_list(mutable_mock_env_path, config, mutable_mock_repo):
assert affected_pkg_names == expected_affected_pkg_names assert affected_pkg_names == expected_affected_pkg_names
@pytest.mark.maybeslow
@pytest.mark.regression("29947") @pytest.mark.regression("29947")
def test_affected_specs_on_first_concretization(mutable_mock_env_path, config): def test_affected_specs_on_first_concretization(mutable_mock_env_path, mock_packages, config):
e = ev.create("first_concretization") e = ev.create("first_concretization")
e.add("hdf5~mpi~szip") e.add("mpileaks~shared")
e.add("hdf5~mpi+szip") e.add("mpileaks+shared")
e.concretize() e.concretize()
affected_specs = spack.ci.get_spec_filter_list(e, ["zlib"]) affected_specs = spack.ci.get_spec_filter_list(e, ["callpath"])
hdf5_specs = [s for s in affected_specs if s.name == "hdf5"] mpileaks_specs = [s for s in affected_specs if s.name == "mpileaks"]
assert len(hdf5_specs) == 2 assert len(mpileaks_specs) == 2, e.all_specs()
@pytest.mark.skipif( @pytest.mark.skipif(
@ -515,14 +512,14 @@ def test_ci_create_buildcache(tmpdir, working_env, config, mock_packages, monkey
def test_ci_run_standalone_tests_missing_requirements( def test_ci_run_standalone_tests_missing_requirements(
tmpdir, working_env, config, mock_packages, capfd tmpdir, working_env, default_mock_concretization, capfd
): ):
"""This test case checks for failing prerequisite checks.""" """This test case checks for failing prerequisite checks."""
ci.run_standalone_tests() ci.run_standalone_tests()
err = capfd.readouterr()[1] err = capfd.readouterr()[1]
assert "Job spec is required" in err assert "Job spec is required" in err
args = {"job_spec": spec.Spec("printing-package").concretized()} args = {"job_spec": default_mock_concretization("printing-package")}
ci.run_standalone_tests(**args) ci.run_standalone_tests(**args)
err = capfd.readouterr()[1] err = capfd.readouterr()[1]
assert "Reproduction directory is required" in err assert "Reproduction directory is required" in err
@ -532,12 +529,12 @@ def test_ci_run_standalone_tests_missing_requirements(
sys.platform == "win32", reason="Reliance on bash script not supported on Windows" sys.platform == "win32", reason="Reliance on bash script not supported on Windows"
) )
def test_ci_run_standalone_tests_not_installed_junit( def test_ci_run_standalone_tests_not_installed_junit(
tmpdir, working_env, config, mock_packages, mock_test_stage, capfd tmpdir, working_env, default_mock_concretization, mock_test_stage, capfd
): ):
log_file = tmpdir.join("junit.xml").strpath log_file = tmpdir.join("junit.xml").strpath
args = { args = {
"log_file": log_file, "log_file": log_file,
"job_spec": spec.Spec("printing-package").concretized(), "job_spec": default_mock_concretization("printing-package"),
"repro_dir": tmpdir.join("repro_dir").strpath, "repro_dir": tmpdir.join("repro_dir").strpath,
"fail_fast": True, "fail_fast": True,
} }
@ -553,13 +550,13 @@ def test_ci_run_standalone_tests_not_installed_junit(
sys.platform == "win32", reason="Reliance on bash script not supported on Windows" sys.platform == "win32", reason="Reliance on bash script not supported on Windows"
) )
def test_ci_run_standalone_tests_not_installed_cdash( def test_ci_run_standalone_tests_not_installed_cdash(
tmpdir, working_env, config, mock_packages, mock_test_stage, capfd tmpdir, working_env, default_mock_concretization, mock_test_stage, capfd
): ):
"""Test run_standalone_tests with cdash and related options.""" """Test run_standalone_tests with cdash and related options."""
log_file = tmpdir.join("junit.xml").strpath log_file = tmpdir.join("junit.xml").strpath
args = { args = {
"log_file": log_file, "log_file": log_file,
"job_spec": spec.Spec("printing-package").concretized(), "job_spec": default_mock_concretization("printing-package"),
"repro_dir": tmpdir.join("repro_dir").strpath, "repro_dir": tmpdir.join("repro_dir").strpath,
} }
os.makedirs(args["repro_dir"]) os.makedirs(args["repro_dir"])

View File

@ -1852,3 +1852,27 @@ def _factory(rpaths, message="Hello world!"):
return executable return executable
return _factory return _factory
@pytest.fixture(scope="session")
def concretized_specs_cache():
"""Cache for mock concrete specs"""
return {}
@pytest.fixture
def default_mock_concretization(config, mock_packages, concretized_specs_cache):
"""Return the default mock concretization of a spec literal, obtained using the mock
repository and the mock configuration.
This fixture is unsafe to call in a test when either the default configuration or mock
repository are not used or have been modified.
"""
def _func(spec_str, tests=False):
key = spec_str, tests
if key not in concretized_specs_cache:
concretized_specs_cache[key] = spack.spec.Spec(spec_str).concretized(tests=tests)
return concretized_specs_cache[key].copy()
return _func

View File

@ -835,7 +835,7 @@ def _is(db, spec):
@pytest.mark.db @pytest.mark.db
def test_clear_failure_forced(mutable_database, monkeypatch, capfd): def test_clear_failure_forced(default_mock_concretization, mutable_database, monkeypatch, capfd):
"""Add test coverage for clear_failure operation when force.""" """Add test coverage for clear_failure operation when force."""
def _is(db, spec): def _is(db, spec):
@ -846,7 +846,7 @@ def _is(db, spec):
# Ensure raise OSError when try to remove the non-existent marking # Ensure raise OSError when try to remove the non-existent marking
monkeypatch.setattr(spack.database.Database, "prefix_failure_marked", _is) monkeypatch.setattr(spack.database.Database, "prefix_failure_marked", _is)
s = spack.spec.Spec("a").concretized() s = default_mock_concretization("a")
spack.store.db.clear_failure(s, force=True) spack.store.db.clear_failure(s, force=True)
out = capfd.readouterr()[1] out = capfd.readouterr()[1]
assert "Removing failure marking despite lock" in out assert "Removing failure marking despite lock" in out
@ -854,7 +854,7 @@ def _is(db, spec):
@pytest.mark.db @pytest.mark.db
def test_mark_failed(mutable_database, monkeypatch, tmpdir, capsys): def test_mark_failed(default_mock_concretization, mutable_database, monkeypatch, tmpdir, capsys):
"""Add coverage to mark_failed.""" """Add coverage to mark_failed."""
def _raise_exc(lock): def _raise_exc(lock):
@ -864,7 +864,7 @@ def _raise_exc(lock):
monkeypatch.setattr(lk.Lock, "acquire_write", _raise_exc) monkeypatch.setattr(lk.Lock, "acquire_write", _raise_exc)
with tmpdir.as_cwd(): with tmpdir.as_cwd():
s = spack.spec.Spec("a").concretized() s = default_mock_concretization("a")
spack.store.db.mark_failed(s) spack.store.db.mark_failed(s)
out = str(capsys.readouterr()[1]) out = str(capsys.readouterr()[1])
@ -876,13 +876,13 @@ def _raise_exc(lock):
@pytest.mark.db @pytest.mark.db
def test_prefix_failed(mutable_database, monkeypatch): def test_prefix_failed(default_mock_concretization, mutable_database, monkeypatch):
"""Add coverage to prefix_failed operation.""" """Add coverage to prefix_failed operation."""
def _is(db, spec): def _is(db, spec):
return True return True
s = spack.spec.Spec("a").concretized() s = default_mock_concretization("a")
# Confirm the spec is not already marked as failed # Confirm the spec is not already marked as failed
assert not spack.store.db.prefix_failed(s) assert not spack.store.db.prefix_failed(s)
@ -900,13 +900,13 @@ def _is(db, spec):
assert spack.store.db.prefix_failed(s) assert spack.store.db.prefix_failed(s)
def test_prefix_read_lock_error(mutable_database, monkeypatch): def test_prefix_read_lock_error(default_mock_concretization, mutable_database, monkeypatch):
"""Cover the prefix read lock exception.""" """Cover the prefix read lock exception."""
def _raise(db, spec): def _raise(db, spec):
raise lk.LockError("Mock lock error") raise lk.LockError("Mock lock error")
s = spack.spec.Spec("a").concretized() s = default_mock_concretization("a")
# Ensure subsequent lock operations fail # Ensure subsequent lock operations fail
monkeypatch.setattr(lk.Lock, "acquire_read", _raise) monkeypatch.setattr(lk.Lock, "acquire_read", _raise)
@ -916,13 +916,13 @@ def _raise(db, spec):
assert False assert False
def test_prefix_write_lock_error(mutable_database, monkeypatch): def test_prefix_write_lock_error(default_mock_concretization, mutable_database, monkeypatch):
"""Cover the prefix write lock exception.""" """Cover the prefix write lock exception."""
def _raise(db, spec): def _raise(db, spec):
raise lk.LockError("Mock lock error") raise lk.LockError("Mock lock error")
s = spack.spec.Spec("a").concretized() s = default_mock_concretization("a")
# Ensure subsequent lock operations fail # Ensure subsequent lock operations fail
monkeypatch.setattr(lk.Lock, "acquire_write", _raise) monkeypatch.setattr(lk.Lock, "acquire_write", _raise)

View File

@ -24,11 +24,10 @@
max_packages = 10 max_packages = 10
def test_yaml_directory_layout_parameters(tmpdir, config): def test_yaml_directory_layout_parameters(tmpdir, default_mock_concretization):
"""This tests the various parameters that can be used to configure """This tests the various parameters that can be used to configure
the install location""" the install location"""
spec = Spec("python") spec = default_mock_concretization("python")
spec.concretize()
# Ensure default layout matches expected spec format # Ensure default layout matches expected spec format
layout_default = DirectoryLayout(str(tmpdir)) layout_default = DirectoryLayout(str(tmpdir))
@ -215,11 +214,9 @@ def test_find(temporary_store, config, mock_packages):
assert found_specs[name].eq_dag(spec) assert found_specs[name].eq_dag(spec)
def test_yaml_directory_layout_build_path(tmpdir, config): def test_yaml_directory_layout_build_path(tmpdir, default_mock_concretization):
"""This tests build path method.""" """This tests build path method."""
spec = Spec("python") spec = default_mock_concretization("python")
spec.concretize()
layout = DirectoryLayout(str(tmpdir)) layout = DirectoryLayout(str(tmpdir))
rel_path = os.path.join(layout.metadata_dir, layout.packages_dir) rel_path = os.path.join(layout.metadata_dir, layout.packages_dir)
assert layout.build_packages_path(spec) == os.path.join(spec.prefix, rel_path) assert layout.build_packages_path(spec) == os.path.join(spec.prefix, rel_path)

View File

@ -83,7 +83,13 @@ def test_bad_git(tmpdir, mock_bad_git):
@pytest.mark.parametrize("type_of_test", ["default", "branch", "tag", "commit"]) @pytest.mark.parametrize("type_of_test", ["default", "branch", "tag", "commit"])
@pytest.mark.parametrize("secure", [True, False]) @pytest.mark.parametrize("secure", [True, False])
def test_fetch( def test_fetch(
type_of_test, secure, mock_git_repository, config, mutable_mock_repo, git_version, monkeypatch type_of_test,
secure,
mock_git_repository,
default_mock_concretization,
mutable_mock_repo,
git_version,
monkeypatch,
): ):
"""Tries to: """Tries to:
@ -104,7 +110,7 @@ def test_fetch(
monkeypatch.delattr(pkg_class, "git") monkeypatch.delattr(pkg_class, "git")
# Construct the package under test # Construct the package under test
s = Spec("git-test").concretized() s = default_mock_concretization("git-test")
monkeypatch.setitem(s.package.versions, ver("git"), t.args) monkeypatch.setitem(s.package.versions, ver("git"), t.args)
# Enter the stage directory and check some properties # Enter the stage directory and check some properties
@ -136,7 +142,7 @@ def test_fetch(
@pytest.mark.disable_clean_stage_check @pytest.mark.disable_clean_stage_check
def test_fetch_pkg_attr_submodule_init( def test_fetch_pkg_attr_submodule_init(
mock_git_repository, config, mutable_mock_repo, monkeypatch, mock_stage mock_git_repository, default_mock_concretization, mutable_mock_repo, monkeypatch, mock_stage
): ):
"""In this case the version() args do not contain a 'git' URL, so """In this case the version() args do not contain a 'git' URL, so
the fetcher must be assembled using the Package-level 'git' attribute. the fetcher must be assembled using the Package-level 'git' attribute.
@ -151,7 +157,7 @@ def test_fetch_pkg_attr_submodule_init(
monkeypatch.setattr(pkg_class, "git", mock_git_repository.url) monkeypatch.setattr(pkg_class, "git", mock_git_repository.url)
# Construct the package under test # Construct the package under test
s = Spec("git-test").concretized() s = default_mock_concretization("git-test")
monkeypatch.setitem(s.package.versions, ver("git"), t.args) monkeypatch.setitem(s.package.versions, ver("git"), t.args)
s.package.do_stage() s.package.do_stage()
@ -193,13 +199,15 @@ def test_adhoc_version_submodules(
@pytest.mark.parametrize("type_of_test", ["branch", "commit"]) @pytest.mark.parametrize("type_of_test", ["branch", "commit"])
def test_debug_fetch(mock_packages, type_of_test, mock_git_repository, config, monkeypatch): def test_debug_fetch(
mock_packages, type_of_test, mock_git_repository, default_mock_concretization, monkeypatch
):
"""Fetch the repo with debug enabled.""" """Fetch the repo with debug enabled."""
# Retrieve the right test parameters # Retrieve the right test parameters
t = mock_git_repository.checks[type_of_test] t = mock_git_repository.checks[type_of_test]
# Construct the package under test # Construct the package under test
s = Spec("git-test").concretized() s = default_mock_concretization("git-test")
monkeypatch.setitem(s.package.versions, ver("git"), t.args) monkeypatch.setitem(s.package.versions, ver("git"), t.args)
# Fetch then ensure source path exists # Fetch then ensure source path exists
@ -231,7 +239,12 @@ def test_needs_stage():
@pytest.mark.parametrize("get_full_repo", [True, False]) @pytest.mark.parametrize("get_full_repo", [True, False])
def test_get_full_repo( def test_get_full_repo(
get_full_repo, git_version, mock_git_repository, config, mutable_mock_repo, monkeypatch get_full_repo,
git_version,
mock_git_repository,
default_mock_concretization,
mutable_mock_repo,
monkeypatch,
): ):
"""Ensure that we can clone a full repository.""" """Ensure that we can clone a full repository."""
@ -243,7 +256,7 @@ def test_get_full_repo(
t = mock_git_repository.checks[type_of_test] t = mock_git_repository.checks[type_of_test]
s = Spec("git-test").concretized() s = default_mock_concretization("git-test")
args = copy.copy(t.args) args = copy.copy(t.args)
args["get_full_repo"] = get_full_repo args["get_full_repo"] = get_full_repo
monkeypatch.setitem(s.package.versions, ver("git"), args) monkeypatch.setitem(s.package.versions, ver("git"), args)
@ -273,7 +286,9 @@ def test_get_full_repo(
@pytest.mark.disable_clean_stage_check @pytest.mark.disable_clean_stage_check
@pytest.mark.parametrize("submodules", [True, False]) @pytest.mark.parametrize("submodules", [True, False])
def test_gitsubmodule(submodules, mock_git_repository, config, mutable_mock_repo, monkeypatch): def test_gitsubmodule(
submodules, mock_git_repository, default_mock_concretization, mutable_mock_repo, monkeypatch
):
""" """
Test GitFetchStrategy behavior with submodules. This package Test GitFetchStrategy behavior with submodules. This package
has a `submodules` property which is always True: when a specific has a `submodules` property which is always True: when a specific
@ -286,7 +301,7 @@ def test_gitsubmodule(submodules, mock_git_repository, config, mutable_mock_repo
t = mock_git_repository.checks[type_of_test] t = mock_git_repository.checks[type_of_test]
# Construct the package under test # Construct the package under test
s = Spec("git-test").concretized() s = default_mock_concretization("git-test")
args = copy.copy(t.args) args = copy.copy(t.args)
args["submodules"] = submodules args["submodules"] = submodules
monkeypatch.setitem(s.package.versions, ver("git"), args) monkeypatch.setitem(s.package.versions, ver("git"), args)
@ -304,7 +319,9 @@ def test_gitsubmodule(submodules, mock_git_repository, config, mutable_mock_repo
@pytest.mark.disable_clean_stage_check @pytest.mark.disable_clean_stage_check
def test_gitsubmodules_callable(mock_git_repository, config, mutable_mock_repo, monkeypatch): def test_gitsubmodules_callable(
mock_git_repository, default_mock_concretization, mutable_mock_repo, monkeypatch
):
""" """
Test GitFetchStrategy behavior with submodules selected after concretization Test GitFetchStrategy behavior with submodules selected after concretization
""" """
@ -317,7 +334,7 @@ def submodules_callback(package):
t = mock_git_repository.checks[type_of_test] t = mock_git_repository.checks[type_of_test]
# Construct the package under test # Construct the package under test
s = Spec("git-test").concretized() s = default_mock_concretization("git-test")
args = copy.copy(t.args) args = copy.copy(t.args)
args["submodules"] = submodules_callback args["submodules"] = submodules_callback
monkeypatch.setitem(s.package.versions, ver("git"), args) monkeypatch.setitem(s.package.versions, ver("git"), args)
@ -330,7 +347,9 @@ def submodules_callback(package):
@pytest.mark.disable_clean_stage_check @pytest.mark.disable_clean_stage_check
def test_gitsubmodules_delete(mock_git_repository, config, mutable_mock_repo, monkeypatch): def test_gitsubmodules_delete(
mock_git_repository, default_mock_concretization, mutable_mock_repo, monkeypatch
):
""" """
Test GitFetchStrategy behavior with submodules_delete Test GitFetchStrategy behavior with submodules_delete
""" """
@ -338,7 +357,7 @@ def test_gitsubmodules_delete(mock_git_repository, config, mutable_mock_repo, mo
t = mock_git_repository.checks[type_of_test] t = mock_git_repository.checks[type_of_test]
# Construct the package under test # Construct the package under test
s = Spec("git-test").concretized() s = default_mock_concretization("git-test")
args = copy.copy(t.args) args = copy.copy(t.args)
args["submodules"] = True args["submodules"] = True
args["submodules_delete"] = ["third_party/submodule0", "third_party/submodule1"] args["submodules_delete"] = ["third_party/submodule0", "third_party/submodule1"]

View File

@ -570,7 +570,9 @@ def fake_fn(self):
"manual,instr", [(False, False), (False, True), (True, False), (True, True)] "manual,instr", [(False, False), (False, True), (True, False), (True, True)]
) )
@pytest.mark.disable_clean_stage_check @pytest.mark.disable_clean_stage_check
def test_manual_download(install_mockery, mock_download, monkeypatch, manual, instr): def test_manual_download(
install_mockery, mock_download, default_mock_concretization, monkeypatch, manual, instr
):
""" """
Ensure expected fetcher fail message based on manual download and instr. Ensure expected fetcher fail message based on manual download and instr.
""" """
@ -579,7 +581,7 @@ def test_manual_download(install_mockery, mock_download, monkeypatch, manual, in
def _instr(pkg): def _instr(pkg):
return "Download instructions for {0}".format(pkg.spec.name) return "Download instructions for {0}".format(pkg.spec.name)
spec = Spec("a").concretized() spec = default_mock_concretization("a")
pkg = spec.package pkg = spec.package
pkg.manual_download = manual pkg.manual_download = manual
@ -605,16 +607,20 @@ def fetch(self):
monkeypatch.setattr(spack.package_base.PackageBase, "fetcher", fetcher) monkeypatch.setattr(spack.package_base.PackageBase, "fetcher", fetcher)
def test_fetch_without_code_is_noop(install_mockery, fetching_not_allowed): def test_fetch_without_code_is_noop(
default_mock_concretization, install_mockery, fetching_not_allowed
):
"""do_fetch for packages without code should be a no-op""" """do_fetch for packages without code should be a no-op"""
pkg = Spec("a").concretized().package pkg = default_mock_concretization("a").package
pkg.has_code = False pkg.has_code = False
pkg.do_fetch() pkg.do_fetch()
def test_fetch_external_package_is_noop(install_mockery, fetching_not_allowed): def test_fetch_external_package_is_noop(
default_mock_concretization, install_mockery, fetching_not_allowed
):
"""do_fetch for packages without code should be a no-op""" """do_fetch for packages without code should be a no-op"""
spec = Spec("a").concretized() spec = default_mock_concretization("a")
spec.external_path = "/some/where" spec.external_path = "/some/where"
assert spec.external assert spec.external
spec.package.do_fetch() spec.package.do_fetch()

View File

@ -719,9 +719,8 @@ def test_exceptional_paths_for_constructor(self):
with pytest.raises(ValueError): with pytest.raises(ValueError):
Spec("libelf foo") Spec("libelf foo")
def test_spec_formatting(self): def test_spec_formatting(self, default_mock_concretization):
spec = Spec("multivalue-variant cflags=-O2") spec = default_mock_concretization("multivalue-variant cflags=-O2")
spec.concretize()
# Since the default is the full spec see if the string rep of # Since the default is the full spec see if the string rep of
# spec is the same as the output of spec.format() # spec is the same as the output of spec.format()
@ -797,9 +796,8 @@ def test_spec_formatting(self):
actual = spec.format(named_str) actual = spec.format(named_str)
assert expected == actual assert expected == actual
def test_spec_formatting_escapes(self): def test_spec_formatting_escapes(self, default_mock_concretization):
spec = Spec("multivalue-variant cflags=-O2") spec = default_mock_concretization("multivalue-variant cflags=-O2")
spec.concretize()
sigil_mismatches = [ sigil_mismatches = [
"{@name}", "{@name}",
@ -881,7 +879,7 @@ def test_spec_flags_maintain_order(self):
# different orderings for repeated concretizations of the same # different orderings for repeated concretizations of the same
# spec and config # spec and config
spec_str = "libelf %gcc@11.1.0 os=redhat6" spec_str = "libelf %gcc@11.1.0 os=redhat6"
for _ in range(25): for _ in range(3):
s = Spec(spec_str).concretized() s = Spec(spec_str).concretized()
assert all( assert all(
s.compiler_flags[x] == ["-O0", "-g"] for x in ("cflags", "cxxflags", "fflags") s.compiler_flags[x] == ["-O0", "-g"] for x in ("cflags", "cxxflags", "fflags")
@ -954,13 +952,11 @@ def test_forwarding_of_architecture_attributes(self):
assert spec.target < "broadwell" assert spec.target < "broadwell"
@pytest.mark.parametrize("transitive", [True, False]) @pytest.mark.parametrize("transitive", [True, False])
def test_splice(self, transitive): def test_splice(self, transitive, default_mock_concretization):
# Tests the new splice function in Spec using a somewhat simple case # Tests the new splice function in Spec using a somewhat simple case
# with a variant with a conditional dependency. # with a variant with a conditional dependency.
spec = Spec("splice-t") spec = default_mock_concretization("splice-t")
dep = Spec("splice-h+foo") dep = default_mock_concretization("splice-h+foo")
spec.concretize()
dep.concretize()
# Sanity checking that these are not the same thing. # Sanity checking that these are not the same thing.
assert dep.dag_hash() != spec["splice-h"].dag_hash() assert dep.dag_hash() != spec["splice-h"].dag_hash()
@ -993,11 +989,9 @@ def test_splice(self, transitive):
assert out.spliced assert out.spliced
@pytest.mark.parametrize("transitive", [True, False]) @pytest.mark.parametrize("transitive", [True, False])
def test_splice_with_cached_hashes(self, transitive): def test_splice_with_cached_hashes(self, default_mock_concretization, transitive):
spec = Spec("splice-t") spec = default_mock_concretization("splice-t")
dep = Spec("splice-h+foo") dep = default_mock_concretization("splice-h+foo")
spec.concretize()
dep.concretize()
# monkeypatch hashes so we can test that they are cached # monkeypatch hashes so we can test that they are cached
spec._hash = "aaaaaa" spec._hash = "aaaaaa"
@ -1014,9 +1008,9 @@ def test_splice_with_cached_hashes(self, transitive):
assert out["splice-z"].dag_hash() == out_z_expected.dag_hash() assert out["splice-z"].dag_hash() == out_z_expected.dag_hash()
@pytest.mark.parametrize("transitive", [True, False]) @pytest.mark.parametrize("transitive", [True, False])
def test_splice_input_unchanged(self, transitive): def test_splice_input_unchanged(self, default_mock_concretization, transitive):
spec = Spec("splice-t").concretized() spec = default_mock_concretization("splice-t")
dep = Spec("splice-h+foo").concretized() dep = default_mock_concretization("splice-h+foo")
orig_spec_hash = spec.dag_hash() orig_spec_hash = spec.dag_hash()
orig_dep_hash = dep.dag_hash() orig_dep_hash = dep.dag_hash()
spec.splice(dep, transitive) spec.splice(dep, transitive)
@ -1026,16 +1020,13 @@ def test_splice_input_unchanged(self, transitive):
assert dep.dag_hash() == orig_dep_hash assert dep.dag_hash() == orig_dep_hash
@pytest.mark.parametrize("transitive", [True, False]) @pytest.mark.parametrize("transitive", [True, False])
def test_splice_subsequent(self, transitive): def test_splice_subsequent(self, default_mock_concretization, transitive):
spec = Spec("splice-t") spec = default_mock_concretization("splice-t")
dep = Spec("splice-h+foo") dep = default_mock_concretization("splice-h+foo")
spec.concretize()
dep.concretize()
out = spec.splice(dep, transitive) out = spec.splice(dep, transitive)
# Now we attempt a second splice. # Now we attempt a second splice.
dep = Spec("splice-z+bar") dep = default_mock_concretization("splice-z+bar")
dep.concretize()
# Transitivity shouldn't matter since Splice Z has no dependencies. # Transitivity shouldn't matter since Splice Z has no dependencies.
out2 = out.splice(dep, transitive) out2 = out.splice(dep, transitive)
@ -1046,11 +1037,9 @@ def test_splice_subsequent(self, transitive):
assert out2.spliced assert out2.spliced
@pytest.mark.parametrize("transitive", [True, False]) @pytest.mark.parametrize("transitive", [True, False])
def test_splice_dict(self, transitive): def test_splice_dict(self, default_mock_concretization, transitive):
spec = Spec("splice-t") spec = default_mock_concretization("splice-t")
dep = Spec("splice-h+foo") dep = default_mock_concretization("splice-h+foo")
spec.concretize()
dep.concretize()
out = spec.splice(dep, transitive) out = spec.splice(dep, transitive)
# Sanity check all hashes are unique... # Sanity check all hashes are unique...
@ -1065,11 +1054,9 @@ def test_splice_dict(self, transitive):
assert len(build_spec_nodes) == 1 assert len(build_spec_nodes) == 1
@pytest.mark.parametrize("transitive", [True, False]) @pytest.mark.parametrize("transitive", [True, False])
def test_splice_dict_roundtrip(self, transitive): def test_splice_dict_roundtrip(self, default_mock_concretization, transitive):
spec = Spec("splice-t") spec = default_mock_concretization("splice-t")
dep = Spec("splice-h+foo") dep = default_mock_concretization("splice-h+foo")
spec.concretize()
dep.concretize()
out = spec.splice(dep, transitive) out = spec.splice(dep, transitive)
# Sanity check all hashes are unique... # Sanity check all hashes are unique...
@ -1132,21 +1119,17 @@ def test_satisfies_dependencies_ordered(self):
assert s.satisfies("mpileaks ^zmpi ^fake", strict=True) assert s.satisfies("mpileaks ^zmpi ^fake", strict=True)
@pytest.mark.parametrize("transitive", [True, False]) @pytest.mark.parametrize("transitive", [True, False])
def test_splice_swap_names(self, transitive): def test_splice_swap_names(self, default_mock_concretization, transitive):
spec = Spec("splice-t") spec = default_mock_concretization("splice-t")
dep = Spec("splice-a+foo") dep = default_mock_concretization("splice-a+foo")
spec.concretize()
dep.concretize()
out = spec.splice(dep, transitive) out = spec.splice(dep, transitive)
assert dep.name in out assert dep.name in out
assert transitive == ("+foo" in out["splice-z"]) assert transitive == ("+foo" in out["splice-z"])
@pytest.mark.parametrize("transitive", [True, False]) @pytest.mark.parametrize("transitive", [True, False])
def test_splice_swap_names_mismatch_virtuals(self, transitive): def test_splice_swap_names_mismatch_virtuals(self, default_mock_concretization, transitive):
spec = Spec("splice-t") spec = default_mock_concretization("splice-t")
dep = Spec("splice-vh+foo") dep = default_mock_concretization("splice-vh+foo")
spec.concretize()
dep.concretize()
with pytest.raises(spack.spec.SpliceError, match="will not provide the same virtuals."): with pytest.raises(spack.spec.SpliceError, match="will not provide the same virtuals."):
spec.splice(dep, transitive) spec.splice(dep, transitive)
@ -1166,12 +1149,11 @@ def test_spec_override(self):
@pytest.mark.regression("3887") @pytest.mark.regression("3887")
@pytest.mark.parametrize("spec_str", ["git", "hdf5", "py-flake8"]) @pytest.mark.parametrize("spec_str", ["py-extension2", "extension1", "perl-extension"])
def test_is_extension_after_round_trip_to_dict(config, spec_str): def test_is_extension_after_round_trip_to_dict(config, mock_packages, spec_str):
# x is constructed directly from string, y from a # x is constructed directly from string, y from a
# round-trip to dict representation # round-trip to dict representation
x = Spec(spec_str) x = Spec(spec_str).concretized()
x.concretize()
y = Spec.from_dict(x.to_dict()) y = Spec.from_dict(x.to_dict())
# Using 'y' since the round-trip make us lose build dependencies # Using 'y' since the round-trip make us lose build dependencies
@ -1231,7 +1213,7 @@ def test_merge_anonymous_spec_with_named_spec(anonymous, named, expected):
assert s == Spec(expected) assert s == Spec(expected)
def test_spec_installed(install_mockery, database): def test_spec_installed(default_mock_concretization, database):
"""Test whether Spec.installed works.""" """Test whether Spec.installed works."""
# a known installed spec should say that it's installed # a known installed spec should say that it's installed
specs = database.query() specs = database.query()
@ -1244,14 +1226,14 @@ def test_spec_installed(install_mockery, database):
assert not spec.installed assert not spec.installed
# 'a' is not in the mock DB and is not installed # 'a' is not in the mock DB and is not installed
spec = Spec("a").concretized() spec = default_mock_concretization("a")
assert not spec.installed assert not spec.installed
@pytest.mark.regression("30678") @pytest.mark.regression("30678")
def test_call_dag_hash_on_old_dag_hash_spec(mock_packages, config): def test_call_dag_hash_on_old_dag_hash_spec(mock_packages, default_mock_concretization):
# create a concrete spec # create a concrete spec
a = Spec("a").concretized() a = default_mock_concretization("a")
dag_hashes = {spec.name: spec.dag_hash() for spec in a.traverse()} dag_hashes = {spec.name: spec.dag_hash() for spec in a.traverse()}
# make it look like an old DAG hash spec with no package hash on the spec. # make it look like an old DAG hash spec with no package hash on the spec.
@ -1298,9 +1280,9 @@ def test_unsupported_compiler():
Spec("gcc%fake-compiler").validate_or_raise() Spec("gcc%fake-compiler").validate_or_raise()
def test_package_hash_affects_dunder_and_dag_hash(mock_packages, config): def test_package_hash_affects_dunder_and_dag_hash(mock_packages, default_mock_concretization):
a1 = Spec("a").concretized() a1 = default_mock_concretization("a")
a2 = Spec("a").concretized() a2 = default_mock_concretization("a")
assert hash(a1) == hash(a2) assert hash(a1) == hash(a2)
assert a1.dag_hash() == a2.dag_hash() assert a1.dag_hash() == a2.dag_hash()

View File

@ -136,18 +136,22 @@ def test_archive_file_errors(tmpdir, mock_archive, _fetch_method):
@pytest.mark.parametrize("secure", [True, False]) @pytest.mark.parametrize("secure", [True, False])
@pytest.mark.parametrize("_fetch_method", ["curl", "urllib"]) @pytest.mark.parametrize("_fetch_method", ["curl", "urllib"])
@pytest.mark.parametrize("mock_archive", files, indirect=True) @pytest.mark.parametrize("mock_archive", files, indirect=True)
def test_fetch(mock_archive, secure, _fetch_method, checksum_type, config, mutable_mock_repo): def test_fetch(
mock_archive,
secure,
_fetch_method,
checksum_type,
default_mock_concretization,
mutable_mock_repo,
):
"""Fetch an archive and make sure we can checksum it.""" """Fetch an archive and make sure we can checksum it."""
mock_archive.url
mock_archive.path
algo = crypto.hash_fun_for_algo(checksum_type)() algo = crypto.hash_fun_for_algo(checksum_type)()
with open(mock_archive.archive_file, "rb") as f: with open(mock_archive.archive_file, "rb") as f:
algo.update(f.read()) algo.update(f.read())
checksum = algo.hexdigest() checksum = algo.hexdigest()
# Get a spec and tweak the test package with new chcecksum params # Get a spec and tweak the test package with new checksum params
s = Spec("url-test").concretized() s = default_mock_concretization("url-test")
s.package.url = mock_archive.url s.package.url = mock_archive.url
s.package.versions[ver("test")] = {checksum_type: checksum, "url": s.package.url} s.package.versions[ver("test")] = {checksum_type: checksum, "url": s.package.url}