diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 9fd85eaa7cc..b764775572d 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -3653,6 +3653,7 @@ def _resolve_automatic_splices(self): ): continue new_spec = spec.copy(deps=False) + new_spec.clear_caches(ignore=("package_hash",)) new_spec.build_spec = spec for edge in spec.edges_to_dependencies(): depflag = edge.depflag & ~dt.BUILD diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index 829039f13a9..37076ce9933 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -3591,25 +3591,16 @@ def patches(self): return self._patches - def _dup(self, other, deps: Union[bool, dt.DepTypes, dt.DepFlag] = True, cleardeps=True): - """Copy the spec other into self. This is an overwriting - copy. It does not copy any dependents (parents), but by default - copies dependencies. - - To duplicate an entire DAG, call _dup() on the root of the DAG. + def _dup(self, other: "Spec", deps: Union[bool, dt.DepTypes, dt.DepFlag] = True) -> bool: + """Copies "other" into self, by overwriting all attributes. Args: - other (Spec): spec to be copied onto ``self`` - deps: if True copies all the dependencies. If - False copies None. If deptype/depflag, copy matching types. - cleardeps (bool): if True clears the dependencies of ``self``, - before possibly copying the dependencies of ``other`` onto - ``self`` + other: spec to be copied onto ``self`` + deps: if True copies all the dependencies. If False copies None. + If deptype, or depflag, copy matching types. Returns: - True if ``self`` changed because of the copy operation, - False otherwise. - + True if ``self`` changed because of the copy operation, False otherwise. """ # We don't count dependencies as changes here changed = True @@ -3634,14 +3625,15 @@ def _dup(self, other, deps: Union[bool, dt.DepTypes, dt.DepFlag] = True, clearde self.versions = other.versions.copy() self.architecture = other.architecture.copy() if other.architecture else None self.compiler = other.compiler.copy() if other.compiler else None - if cleardeps: - self._dependents = _EdgeMap(store_by_child=False) - self._dependencies = _EdgeMap(store_by_child=True) self.compiler_flags = other.compiler_flags.copy() self.compiler_flags.spec = self self.variants = other.variants.copy() self._build_spec = other._build_spec + # Clear dependencies + self._dependents = _EdgeMap(store_by_child=False) + self._dependencies = _EdgeMap(store_by_child=True) + # FIXME: we manage _patches_in_order_of_appearance specially here # to keep it from leaking out of spec.py, but we should figure # out how to handle it more elegantly in the Variant classes. @@ -4524,7 +4516,7 @@ def mask_build_deps(in_spec): return spec - def clear_caches(self, ignore=()): + def clear_caches(self, ignore: Tuple[str, ...] = ()) -> None: """ Clears all cached hashes in a Spec, while preserving other properties. """ diff --git a/lib/spack/spack/test/abi_splicing.py b/lib/spack/spack/test/abi_splicing.py index d70dc09b377..a1d2210a889 100644 --- a/lib/spack/spack/test/abi_splicing.py +++ b/lib/spack/spack/test/abi_splicing.py @@ -10,33 +10,11 @@ import spack.concretize import spack.config import spack.deptypes as dt -import spack.solver.asp from spack.installer import PackageInstaller +from spack.solver.asp import SolverError from spack.spec import Spec -class CacheManager: - def __init__(self, specs: List[str]) -> None: - self.req_specs = specs - self.concr_specs: List[Spec] - self.concr_specs = [] - - def __enter__(self): - self.concr_specs = [spack.concretize.concretize_one(s) for s in self.req_specs] - for s in self.concr_specs: - PackageInstaller([s.package], fake=True, explicit=True).install() - - def __exit__(self, exc_type, exc_val, exc_tb): - for s in self.concr_specs: - s.package.do_uninstall() - - -# MacOS and Windows only work if you pass this function pointer rather than a -# closure -def _mock_has_runtime_dependencies(_x): - return True - - def _make_specs_non_buildable(specs: List[str]): output_config = {} for spec in specs: @@ -45,203 +23,263 @@ def _make_specs_non_buildable(specs: List[str]): @pytest.fixture -def splicing_setup(mutable_database, mock_packages, monkeypatch): - spack.config.set("concretizer:reuse", True) - monkeypatch.setattr( - spack.solver.asp, "_has_runtime_dependencies", _mock_has_runtime_dependencies - ) +def install_specs( + mutable_database, + mock_packages, + mutable_config, + do_not_check_runtimes_on_reuse, + install_mockery, +): + """Returns a function that concretizes and installs a list of abstract specs""" + mutable_config.set("concretizer:reuse", True) + + def _impl(*specs_str): + concrete_specs = [Spec(s).concretized() for s in specs_str] + PackageInstaller([s.package for s in concrete_specs], fake=True, explicit=True).install() + return concrete_specs + + return _impl def _enable_splicing(): spack.config.set("concretizer:splice", {"automatic": True}) -def _has_build_dependency(spec: Spec, name: str): - return any(s.name == name for s in spec.dependencies(None, dt.BUILD)) +@pytest.mark.parametrize("spec_str", ["splice-z", "splice-h@1"]) +def test_spec_reuse(spec_str, install_specs, mutable_config): + """Tests reuse of splice-z, without splicing, as a root and as a dependency of splice-h""" + splice_z = install_specs("splice-z@1.0.0+compat")[0] + mutable_config.set("packages", _make_specs_non_buildable(["splice-z"])) + concrete = spack.concretize.concretize_one(spec_str) + assert concrete["splice-z"].satisfies(splice_z) -def test_simple_reuse(splicing_setup): - with CacheManager(["splice-z@1.0.0+compat"]): - spack.config.set("packages", _make_specs_non_buildable(["splice-z"])) - assert spack.concretize.concretize_one("splice-z").satisfies(Spec("splice-z")) - - -def test_simple_dep_reuse(splicing_setup): - with CacheManager(["splice-z@1.0.0+compat"]): - spack.config.set("packages", _make_specs_non_buildable(["splice-z"])) - assert spack.concretize.concretize_one("splice-h@1").satisfies(Spec("splice-h@1")) - - -def test_splice_installed_hash(splicing_setup): - cache = [ +@pytest.mark.regression("48578") +def test_splice_installed_hash(install_specs, mutable_config): + """Tests splicing the dependency of an installed spec, for another installed spec""" + splice_t, splice_h = install_specs( "splice-t@1 ^splice-h@1.0.0+compat ^splice-z@1.0.0", "splice-h@1.0.2+compat ^splice-z@1.0.0", - ] - with CacheManager(cache): - packages_config = _make_specs_non_buildable(["splice-t", "splice-h"]) - spack.config.set("packages", packages_config) - goal_spec = Spec("splice-t@1 ^splice-h@1.0.2+compat ^splice-z@1.0.0") - with pytest.raises(Exception): - spack.concretize.concretize_one(goal_spec) - _enable_splicing() - assert spack.concretize.concretize_one(goal_spec).satisfies(goal_spec) + ) + packages_config = _make_specs_non_buildable(["splice-t", "splice-h"]) + mutable_config.set("packages", packages_config) + + goal_spec = "splice-t@1 ^splice-h@1.0.2+compat ^splice-z@1.0.0" + with pytest.raises(SolverError): + spack.concretize.concretize_one(goal_spec) + _enable_splicing() + concrete = spack.concretize.concretize_one(goal_spec) + + # splice-t has a dependency that is changing, thus its hash should be different + assert concrete.dag_hash() != splice_t.dag_hash() + assert concrete.build_spec.satisfies(splice_t) + assert not concrete.satisfies(splice_t) + + # splice-h is reused, so the hash should stay the same + assert concrete["splice-h"].satisfies(splice_h) + assert concrete["splice-h"].build_spec.satisfies(splice_h) + assert concrete["splice-h"].dag_hash() == splice_h.dag_hash() -def test_splice_build_splice_node(splicing_setup): - with CacheManager(["splice-t@1 ^splice-h@1.0.0+compat ^splice-z@1.0.0+compat"]): - spack.config.set("packages", _make_specs_non_buildable(["splice-t"])) - goal_spec = Spec("splice-t@1 ^splice-h@1.0.2+compat ^splice-z@1.0.0+compat") - with pytest.raises(Exception): - spack.concretize.concretize_one(goal_spec) - _enable_splicing() - assert spack.concretize.concretize_one(goal_spec).satisfies(goal_spec) +def test_splice_build_splice_node(install_specs, mutable_config): + """Tests splicing the dependency of an installed spec, for a spec that is yet to be built""" + splice_t = install_specs("splice-t@1 ^splice-h@1.0.0+compat ^splice-z@1.0.0+compat")[0] + mutable_config.set("packages", _make_specs_non_buildable(["splice-t"])) + + goal_spec = "splice-t@1 ^splice-h@1.0.2+compat ^splice-z@1.0.0+compat" + with pytest.raises(SolverError): + spack.concretize.concretize_one(goal_spec) + + _enable_splicing() + concrete = spack.concretize.concretize_one(goal_spec) + + # splice-t has a dependency that is changing, thus its hash should be different + assert concrete.dag_hash() != splice_t.dag_hash() + assert concrete.build_spec.satisfies(splice_t) + assert not concrete.satisfies(splice_t) + + # splice-h should be different + assert concrete["splice-h"].dag_hash() != splice_t["splice-h"].dag_hash() + assert concrete["splice-h"].build_spec.dag_hash() == concrete["splice-h"].dag_hash() -def test_double_splice(splicing_setup): - cache = [ +@pytest.mark.xfail(reason="the spliced splice-h has sometimes the original splice-h hash") +def test_double_splice(install_specs, mutable_config): + """Tests splicing two dependencies of an installed spec, for other installed specs""" + splice_t, splice_h, splice_z = install_specs( "splice-t@1 ^splice-h@1.0.0+compat ^splice-z@1.0.0+compat", "splice-h@1.0.2+compat ^splice-z@1.0.1+compat", "splice-z@1.0.2+compat", - ] - with CacheManager(cache): - freeze_builds_config = _make_specs_non_buildable(["splice-t", "splice-h", "splice-z"]) - spack.config.set("packages", freeze_builds_config) - goal_spec = Spec("splice-t@1 ^splice-h@1.0.2+compat ^splice-z@1.0.2+compat") - with pytest.raises(Exception): - spack.concretize.concretize_one(goal_spec) - _enable_splicing() - assert spack.concretize.concretize_one(goal_spec).satisfies(goal_spec) + ) + mutable_config.set("packages", _make_specs_non_buildable(["splice-t", "splice-h", "splice-z"])) + + goal_spec = "splice-t@1 ^splice-h@1.0.2+compat ^splice-z@1.0.2+compat" + with pytest.raises(SolverError): + spack.concretize.concretize_one(goal_spec) + + _enable_splicing() + concrete = spack.concretize.concretize_one(goal_spec) + + # splice-t and splice-h have a dependency that is changing, thus its hash should be different + assert concrete.dag_hash() != splice_t.dag_hash() + assert concrete.build_spec.satisfies(splice_t) + assert not concrete.satisfies(splice_t) + + assert concrete["splice-h"].dag_hash() != splice_h.dag_hash() + assert concrete["splice-h"].build_spec.satisfies(splice_h) + assert not concrete["splice-h"].satisfies(splice_h) + + # splice-z is reused, so the hash should stay the same + assert concrete["splice-z"].dag_hash() == splice_z.dag_hash() -# The next two tests are mirrors of one another -def test_virtual_multi_splices_in(splicing_setup): - cache = [ - "depends-on-virtual-with-abi ^virtual-abi-1", - "depends-on-virtual-with-abi ^virtual-abi-2", - ] - goal_specs = [ - "depends-on-virtual-with-abi ^virtual-abi-multi abi=one", - "depends-on-virtual-with-abi ^virtual-abi-multi abi=two", - ] - with CacheManager(cache): - spack.config.set("packages", _make_specs_non_buildable(["depends-on-virtual-with-abi"])) - for gs in goal_specs: - with pytest.raises(Exception): - spack.concretize.concretize_one(gs) - _enable_splicing() - for gs in goal_specs: - assert spack.concretize.concretize_one(gs).satisfies(gs) +@pytest.mark.parametrize( + "original_spec,goal_spec", + [ + # `virtual-abi-1` can be spliced for `virtual-abi-multi abi=one` and vice-versa + ( + "depends-on-virtual-with-abi ^virtual-abi-1", + "depends-on-virtual-with-abi ^virtual-abi-multi abi=one", + ), + ( + "depends-on-virtual-with-abi ^virtual-abi-multi abi=one", + "depends-on-virtual-with-abi ^virtual-abi-1", + ), + # `virtual-abi-2` can be spliced for `virtual-abi-multi abi=two` and vice-versa + ( + "depends-on-virtual-with-abi ^virtual-abi-2", + "depends-on-virtual-with-abi ^virtual-abi-multi abi=two", + ), + ( + "depends-on-virtual-with-abi ^virtual-abi-multi abi=two", + "depends-on-virtual-with-abi ^virtual-abi-2", + ), + ], +) +def test_virtual_multi_splices_in(original_spec, goal_spec, install_specs, mutable_config): + """Tests that we can splice a virtual dependency with a different, but compatible, provider.""" + original = install_specs(original_spec)[0] + mutable_config.set("packages", _make_specs_non_buildable(["depends-on-virtual-with-abi"])) + + with pytest.raises(SolverError): + spack.concretize.concretize_one(goal_spec) + + _enable_splicing() + spliced = spack.concretize.concretize_one(goal_spec) + + assert spliced.dag_hash() != original.dag_hash() + assert spliced.build_spec.dag_hash() == original.dag_hash() + assert spliced["virtual-with-abi"].name != spliced.build_spec["virtual-with-abi"].name -def test_virtual_multi_can_be_spliced(splicing_setup): - cache = [ - "depends-on-virtual-with-abi ^virtual-abi-multi abi=one", - "depends-on-virtual-with-abi ^virtual-abi-multi abi=two", - ] - goal_specs = [ - "depends-on-virtual-with-abi ^virtual-abi-1", - "depends-on-virtual-with-abi ^virtual-abi-2", - ] - with CacheManager(cache): - spack.config.set("packages", _make_specs_non_buildable(["depends-on-virtual-with-abi"])) - for gs in goal_specs: - with pytest.raises(Exception): - spack.concretize.concretize_one(gs) - _enable_splicing() - for gs in goal_specs: - assert spack.concretize.concretize_one(gs).satisfies(gs) - - -def test_manyvariant_star_matching_variant_splice(splicing_setup): - cache = [ +@pytest.mark.parametrize( + "original_spec,goal_spec", + [ # can_splice("manyvariants@1.0.0", when="@1.0.1", match_variants="*") - "depends-on-manyvariants ^manyvariants@1.0.0+a+b c=v1 d=v2", - "depends-on-manyvariants ^manyvariants@1.0.0~a~b c=v3 d=v3", - ] - goal_specs = [ - Spec("depends-on-manyvariants ^manyvariants@1.0.1+a+b c=v1 d=v2"), - Spec("depends-on-manyvariants ^manyvariants@1.0.1~a~b c=v3 d=v3"), - ] - with CacheManager(cache): - freeze_build_config = {"depends-on-manyvariants": {"buildable": False}} - spack.config.set("packages", freeze_build_config) - for goal in goal_specs: - with pytest.raises(Exception): - spack.concretize.concretize_one(goal) - _enable_splicing() - for goal in goal_specs: - assert spack.concretize.concretize_one(goal).satisfies(goal) - - -def test_manyvariant_limited_matching(splicing_setup): - cache = [ + ( + "depends-on-manyvariants ^manyvariants@1.0.0+a+b c=v1 d=v2", + "depends-on-manyvariants ^manyvariants@1.0.1+a+b c=v1 d=v2", + ), + ( + "depends-on-manyvariants ^manyvariants@1.0.0~a~b c=v3 d=v3", + "depends-on-manyvariants ^manyvariants@1.0.1~a~b c=v3 d=v3", + ), # can_splice("manyvariants@2.0.0+a~b", when="@2.0.1~a+b", match_variants=["c", "d"]) - "depends-on-manyvariants@2.0 ^manyvariants@2.0.0+a~b c=v3 d=v2", + ( + "depends-on-manyvariants@2.0 ^manyvariants@2.0.0+a~b c=v3 d=v2", + "depends-on-manyvariants@2.0 ^manyvariants@2.0.1~a+b c=v3 d=v2", + ), # can_splice("manyvariants@2.0.0 c=v1 d=v1", when="@2.0.1+a+b") - "depends-on-manyvariants@2.0 ^manyvariants@2.0.0~a~b c=v1 d=v1", - ] - goal_specs = [ - Spec("depends-on-manyvariants@2.0 ^manyvariants@2.0.1~a+b c=v3 d=v2"), - Spec("depends-on-manyvariants@2.0 ^manyvariants@2.0.1+a+b c=v3 d=v3"), - ] - with CacheManager(cache): - freeze_build_config = {"depends-on-manyvariants": {"buildable": False}} - spack.config.set("packages", freeze_build_config) - for s in goal_specs: - with pytest.raises(Exception): - spack.concretize.concretize_one(s) - _enable_splicing() - for s in goal_specs: - assert spack.concretize.concretize_one(s).satisfies(s) + ( + "depends-on-manyvariants@2.0 ^manyvariants@2.0.0~a~b c=v1 d=v1", + "depends-on-manyvariants@2.0 ^manyvariants@2.0.1+a+b c=v3 d=v3", + ), + ], +) +def test_manyvariant_matching_variant_splice( + original_spec, goal_spec, install_specs, mutable_config +): + """Tests splicing with different kind of matching on variants""" + original = install_specs(original_spec)[0] + mutable_config.set("packages", {"depends-on-manyvariants": {"buildable": False}}) + + with pytest.raises(SolverError): + spack.concretize.concretize_one(goal_spec) + + _enable_splicing() + spliced = spack.concretize.concretize_one(goal_spec) + + assert spliced.dag_hash() != original.dag_hash() + assert spliced.build_spec.dag_hash() == original.dag_hash() + + # The spliced 'manyvariants' is yet to be built + assert spliced["manyvariants"].dag_hash() != original["manyvariants"].dag_hash() + assert spliced["manyvariants"].build_spec.dag_hash() == spliced["manyvariants"].dag_hash() -def test_external_splice_same_name(splicing_setup): - cache = [ +def test_external_splice_same_name(install_specs, mutable_config): + """Tests that externals can be spliced for non-external specs""" + original_splice_h, original_splice_t = install_specs( "splice-h@1.0.0 ^splice-z@1.0.0+compat", "splice-t@1.0 ^splice-h@1.0.1 ^splice-z@1.0.1+compat", - ] - packages_yaml = { - "splice-z": {"externals": [{"spec": "splice-z@1.0.2+compat", "prefix": "/usr"}]} - } - goal_specs = [ - Spec("splice-h@1.0.0 ^splice-z@1.0.2"), - Spec("splice-t@1.0 ^splice-h@1.0.1 ^splice-z@1.0.2"), - ] - with CacheManager(cache): - spack.config.set("packages", packages_yaml) - _enable_splicing() - for s in goal_specs: - assert spack.concretize.concretize_one(s).satisfies(s) + ) + mutable_config.set("packages", _make_specs_non_buildable(["splice-t", "splice-h"])) + mutable_config.set( + "packages", + { + "splice-z": { + "externals": [{"spec": "splice-z@1.0.2+compat", "prefix": "/usr"}], + "buildable": False, + } + }, + ) + + _enable_splicing() + concrete_splice_h = spack.concretize.concretize_one("splice-h@1.0.0 ^splice-z@1.0.2") + concrete_splice_t = spack.concretize.concretize_one( + "splice-t@1.0 ^splice-h@1.0.1 ^splice-z@1.0.2" + ) + + assert concrete_splice_h.dag_hash() != original_splice_h.dag_hash() + assert concrete_splice_h.build_spec.dag_hash() == original_splice_h.dag_hash() + assert concrete_splice_h["splice-z"].external + + assert concrete_splice_t.dag_hash() != original_splice_t.dag_hash() + assert concrete_splice_t.build_spec.dag_hash() == original_splice_t.dag_hash() + assert concrete_splice_t["splice-z"].external + + assert concrete_splice_t["splice-z"].dag_hash() == concrete_splice_h["splice-z"].dag_hash() -def test_spliced_build_deps_only_in_build_spec(splicing_setup): - cache = ["splice-t@1.0 ^splice-h@1.0.1 ^splice-z@1.0.0"] - goal_spec = Spec("splice-t@1.0 ^splice-h@1.0.2 ^splice-z@1.0.0") +def test_spliced_build_deps_only_in_build_spec(install_specs): + """Tests that build specs are not reported in the spliced spec""" + install_specs("splice-t@1.0 ^splice-h@1.0.1 ^splice-z@1.0.0") - with CacheManager(cache): - _enable_splicing() - concr_goal = spack.concretize.concretize_one(goal_spec) - build_spec = concr_goal._build_spec - # Spec has been spliced - assert build_spec is not None - # Build spec has spliced build dependencies - assert _has_build_dependency(build_spec, "splice-h") - assert _has_build_dependency(build_spec, "splice-z") - # Spliced build dependencies are removed - assert len(concr_goal.dependencies(None, dt.BUILD)) == 0 + _enable_splicing() + spliced = spack.concretize.concretize_one("splice-t@1.0 ^splice-h@1.0.2 ^splice-z@1.0.0") + build_spec = spliced.build_spec + + # Spec has been spliced + assert build_spec.dag_hash() != spliced.dag_hash() + # Build spec has spliced build dependencies + assert build_spec.dependencies("splice-h", dt.BUILD) + assert build_spec.dependencies("splice-z", dt.BUILD) + # Spliced build dependencies are removed + assert len(spliced.dependencies(None, dt.BUILD)) == 0 -def test_spliced_transitive_dependency(splicing_setup): - cache = ["splice-depends-on-t@1.0 ^splice-h@1.0.1"] - goal_spec = Spec("splice-depends-on-t^splice-h@1.0.2") +def test_spliced_transitive_dependency(install_specs, mutable_config): + """Tests that build specs are not reported, even for spliced transitive dependencies""" + install_specs("splice-depends-on-t@1.0 ^splice-h@1.0.1") + mutable_config.set("packages", _make_specs_non_buildable(["splice-depends-on-t"])) - with CacheManager(cache): - spack.config.set("packages", _make_specs_non_buildable(["splice-depends-on-t"])) - _enable_splicing() - concr_goal = spack.concretize.concretize_one(goal_spec) - # Spec has been spliced - assert concr_goal._build_spec is not None - assert concr_goal["splice-t"]._build_spec is not None - assert concr_goal.satisfies(goal_spec) - # Spliced build dependencies are removed - assert len(concr_goal.dependencies(None, dt.BUILD)) == 0 + _enable_splicing() + spliced = spack.concretize.concretize_one("splice-depends-on-t^splice-h@1.0.2") + + # Spec has been spliced + assert spliced.build_spec.dag_hash() != spliced.dag_hash() + assert spliced["splice-t"].build_spec.dag_hash() != spliced["splice-t"].dag_hash() + + # Spliced build dependencies are removed + assert len(spliced.dependencies(None, dt.BUILD)) == 0 + assert len(spliced["splice-t"].dependencies(None, dt.BUILD)) == 0 diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py index 0c0bcad7445..0cbe9ddecd8 100644 --- a/lib/spack/spack/test/cmd/env.py +++ b/lib/spack/spack/test/cmd/env.py @@ -2125,15 +2125,7 @@ def configure_reuse(reuse_mode, combined_env) -> Optional[ev.Environment]: "from_environment_raise", ], ) -def test_env_include_concrete_reuse(monkeypatch, reuse_mode): - - # The mock packages do not use the gcc-runtime - def mock_has_runtime_dependencies(*args, **kwargs): - return True - - monkeypatch.setattr( - spack.solver.asp, "_has_runtime_dependencies", mock_has_runtime_dependencies - ) +def test_env_include_concrete_reuse(do_not_check_runtimes_on_reuse, reuse_mode): # The default mpi version is 3.x provided by mpich in the mock repo. # This test verifies that concretizing with an included concrete # environment with "concretizer:reuse:true" the included diff --git a/lib/spack/spack/test/concretization/core.py b/lib/spack/spack/test/concretization/core.py index 3a978a4ceb2..82fee8e6b9e 100644 --- a/lib/spack/spack/test/concretization/core.py +++ b/lib/spack/spack/test/concretization/core.py @@ -3122,14 +3122,13 @@ def test_concretization_version_order(): ), ], ) -@pytest.mark.usefixtures("mutable_database", "mock_store") +@pytest.mark.usefixtures("mutable_database", "mock_store", "do_not_check_runtimes_on_reuse") @pytest.mark.not_on_windows("Expected length is different on Windows") def test_filtering_reused_specs( - roots, reuse_yaml, expected, not_expected, expected_length, mutable_config, monkeypatch + roots, reuse_yaml, expected, not_expected, expected_length, mutable_config ): """Tests that we can select which specs are to be reused, using constraints as filters""" # Assume all specs have a runtime dependency - monkeypatch.setattr(spack.solver.asp, "_has_runtime_dependencies", lambda x: True) mutable_config.set("concretizer:reuse", reuse_yaml) selector = spack.solver.asp.ReusableSpecsSelector(mutable_config) specs = selector.reusable_specs(roots) @@ -3149,10 +3148,11 @@ def test_filtering_reused_specs( [({"from": [{"type": "local"}]}, 17), ({"from": [{"type": "buildcache"}]}, 0)], ) @pytest.mark.not_on_windows("Expected length is different on Windows") -def test_selecting_reused_sources(reuse_yaml, expected_length, mutable_config, monkeypatch): +def test_selecting_reused_sources( + reuse_yaml, expected_length, mutable_config, do_not_check_runtimes_on_reuse +): """Tests that we can turn on/off sources of reusable specs""" # Assume all specs have a runtime dependency - monkeypatch.setattr(spack.solver.asp, "_has_runtime_dependencies", lambda x: True) mutable_config.set("concretizer:reuse", reuse_yaml) selector = spack.solver.asp.ReusableSpecsSelector(mutable_config) specs = selector.reusable_specs(["mpileaks"])