summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2024-05-03 04:16:02 +0200
committerGitHub <noreply@github.com>2024-05-02 22:16:02 -0400
commit89bf1edb6e60bd018bd4c0ffc090c01235429427 (patch)
treed5e5afba85b2eada3c83cbe559e6d0674aa72ff1
parentcc85dc05b7117abce941b71843c192b38cb8182a (diff)
downloadspack-89bf1edb6e60bd018bd4c0ffc090c01235429427.tar.gz
spack-89bf1edb6e60bd018bd4c0ffc090c01235429427.tar.bz2
spack-89bf1edb6e60bd018bd4c0ffc090c01235429427.tar.xz
spack-89bf1edb6e60bd018bd4c0ffc090c01235429427.zip
Spec.satisfies: fix a bug with concrete spec from JSON (#43968)
Fix a bug triggered by missing a virtual on some transitive edge, in a subdag of a pure build dependency.
-rw-r--r--lib/spack/spack/spec.py14
-rw-r--r--lib/spack/spack/test/concretize.py14
-rw-r--r--var/spack/repos/builtin.mock/packages/dtbuild1/package.py2
-rw-r--r--var/spack/repos/builtin.mock/packages/dtbuild2/package.py2
4 files changed, 28 insertions, 4 deletions
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 7d8266400e..1f30f7e923 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -3898,9 +3898,13 @@ class Spec:
if not self._dependencies:
return False
- # If we arrived here, then rhs is abstract. At the moment we don't care about the edge
- # structure of an abstract DAG, so we check if any edge could satisfy the properties
- # we ask for.
+ # If we arrived here, the lhs root node satisfies the rhs root node. Now we need to check
+ # all the edges that have an abstract parent, and verify that they match some edge in the
+ # lhs.
+ #
+ # It might happen that the rhs brings in concrete sub-DAGs. For those we don't need to
+ # verify the edge properties, cause everything is encoded in the hash of the nodes that
+ # will be verified later.
lhs_edges: Dict[str, Set[DependencySpec]] = collections.defaultdict(set)
for rhs_edge in other.traverse_edges(root=False, cover="edges"):
# If we are checking for ^mpi we need to verify if there is any edge
@@ -3910,6 +3914,10 @@ class Spec:
if not rhs_edge.virtuals:
continue
+ # Skip edges from a concrete sub-DAG
+ if rhs_edge.parent.concrete:
+ continue
+
if not lhs_edges:
# Construct a map of the link/run subDAG + direct "build" edges,
# keyed by dependency name
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index cf20934a00..cc4bec8e3c 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -2448,6 +2448,20 @@ class TestConcretize:
s = Spec("a %gcc@=13.2.0").concretized()
assert s.satisfies("%gcc@13.2.0")
+ @pytest.mark.regression("43267")
+ def test_spec_with_build_dep_from_json(self, tmp_path):
+ """Tests that we can correctly concretize a spec, when we express its dependency as a
+ concrete spec to be read from JSON.
+
+ The bug was triggered by missing virtuals on edges that were trimmed from pure build
+ dependencies.
+ """
+ build_dep = Spec("dttop").concretized()
+ json_file = tmp_path / "build.json"
+ json_file.write_text(build_dep.to_json())
+ s = Spec(f"dtuse ^{str(json_file)}").concretized()
+ assert s["dttop"].dag_hash() == build_dep.dag_hash()
+
@pytest.fixture()
def duplicates_test_repository():
diff --git a/var/spack/repos/builtin.mock/packages/dtbuild1/package.py b/var/spack/repos/builtin.mock/packages/dtbuild1/package.py
index 0f9c6e2e99..cb83bbc9f1 100644
--- a/var/spack/repos/builtin.mock/packages/dtbuild1/package.py
+++ b/var/spack/repos/builtin.mock/packages/dtbuild1/package.py
@@ -16,6 +16,6 @@ class Dtbuild1(Package):
version("1.0", md5="0123456789abcdef0123456789abcdef")
version("0.5", md5="fedcba9876543210fedcba9876543210")
- depends_on("dtbuild2", type="build")
+ depends_on("vdtbuild2", type="build")
depends_on("dtlink2")
depends_on("dtrun2", type="run")
diff --git a/var/spack/repos/builtin.mock/packages/dtbuild2/package.py b/var/spack/repos/builtin.mock/packages/dtbuild2/package.py
index 7aae2109ce..59316434f8 100644
--- a/var/spack/repos/builtin.mock/packages/dtbuild2/package.py
+++ b/var/spack/repos/builtin.mock/packages/dtbuild2/package.py
@@ -13,3 +13,5 @@ class Dtbuild2(Package):
url = "http://www.example.com/dtbuild2-1.0.tar.gz"
version("1.0", md5="0123456789abcdef0123456789abcdef")
+
+ provides("vdtbuild2")