summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/test/traverse.py139
-rw-r--r--var/spack/repos/builtin.mock/packages/chain-a/package.py34
-rw-r--r--var/spack/repos/builtin.mock/packages/chain-b/package.py32
-rw-r--r--var/spack/repos/builtin.mock/packages/chain-c/package.py32
-rw-r--r--var/spack/repos/builtin.mock/packages/chain-d/package.py31
5 files changed, 107 insertions, 161 deletions
diff --git a/lib/spack/spack/test/traverse.py b/lib/spack/spack/test/traverse.py
index 663f323e67..b88bfdb95e 100644
--- a/lib/spack/spack/test/traverse.py
+++ b/lib/spack/spack/test/traverse.py
@@ -3,28 +3,102 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import pytest
+
import spack.traverse as traverse
from spack.spec import Spec
-def key_by_hash(spec):
- return spec.dag_hash()
+def create_dag(nodes, edges):
+ """
+ Arguments:
+ nodes: list of package names
+ edges: list of tuples (from, to, deptype)
+ Returns:
+ dict: mapping from package name to abstract Spec with proper deps.
+ """
+ specs = {name: Spec(name) for name in nodes}
+ for parent, child, deptype in edges:
+ specs[parent].add_dependency_edge(specs[child], deptype)
+ return specs
-def test_breadth_first_traversal(config, mock_packages):
+@pytest.fixture()
+def abstract_specs_dtuse():
+ nodes = [
+ "dtbuild1",
+ "dtbuild2",
+ "dtbuild3",
+ "dtlink1",
+ "dtlink2",
+ "dtlink3",
+ "dtlink4",
+ "dtlink5",
+ "dtrun1",
+ "dtrun2",
+ "dtrun3",
+ "dttop",
+ "dtuse",
+ ]
+ edges = [
+ ("dtbuild1", "dtbuild2", ("build")),
+ ("dtbuild1", "dtlink2", ("build", "link")),
+ ("dtbuild1", "dtrun2", ("run")),
+ ("dtlink1", "dtlink3", ("build", "link")),
+ ("dtlink3", "dtbuild2", ("build")),
+ ("dtlink3", "dtlink4", ("build", "link")),
+ ("dtrun1", "dtlink5", ("build", "link")),
+ ("dtrun1", "dtrun3", ("run")),
+ ("dtrun3", "dtbuild3", ("build")),
+ ("dttop", "dtbuild1", ("build",)),
+ ("dttop", "dtlink1", ("build", "link")),
+ ("dttop", "dtrun1", ("run")),
+ ("dtuse", "dttop", ("build", "link")),
+ ]
+ return create_dag(nodes, edges)
+
+
+@pytest.fixture()
+def abstract_specs_dt_diamond():
+ nodes = ["dt-diamond", "dt-diamond-left", "dt-diamond-right", "dt-diamond-bottom"]
+ edges = [
+ ("dt-diamond", "dt-diamond-left", ("build", "link")),
+ ("dt-diamond", "dt-diamond-right", ("build", "link")),
+ ("dt-diamond-right", "dt-diamond-bottom", ("build", "link", "run")),
+ ("dt-diamond-left", "dt-diamond-bottom", ("build")),
+ ]
+ return create_dag(nodes, edges)
+
+
+@pytest.fixture()
+def abstract_specs_chain():
+ # Chain a -> b -> c -> d with skip connections
+ # from a -> c and a -> d.
+ nodes = ["chain-a", "chain-b", "chain-c", "chain-d"]
+ edges = [
+ ("chain-a", "chain-b", ("build", "link")),
+ ("chain-b", "chain-c", ("build", "link")),
+ ("chain-c", "chain-d", ("build", "link")),
+ ("chain-a", "chain-c", ("build", "link")),
+ ("chain-a", "chain-d", ("build", "link")),
+ ]
+ return create_dag(nodes, edges)
+
+
+def test_breadth_first_traversal(abstract_specs_dtuse):
# That that depth of discovery is non-decreasing
- s = Spec("dttop").concretized()
+ s = abstract_specs_dtuse["dttop"]
depths = [
depth
for (depth, _) in traverse.traverse_nodes(
- [s], order="breadth", key=key_by_hash, depth=True
+ [s], order="breadth", key=lambda s: s.name, depth=True
)
]
assert depths == sorted(depths)
-def test_breadth_first_deptype_traversal(config, mock_packages):
- s = Spec("dtuse").concretized()
+def test_breadth_first_deptype_traversal(abstract_specs_dtuse):
+ s = abstract_specs_dtuse["dtuse"]
names = [
"dtuse",
@@ -37,25 +111,21 @@ def test_breadth_first_deptype_traversal(config, mock_packages):
"dtlink4",
]
- traversal = traverse.traverse_nodes(
- [s], order="breadth", key=key_by_hash, deptype=("build", "link")
- )
+ traversal = traverse.traverse_nodes([s], order="breadth", key=id, deptype=("build", "link"))
assert [x.name for x in traversal] == names
-def test_breadth_firsrt_traversal_deptype_with_builddeps(config, mock_packages):
- s = Spec("dttop").concretized()
+def test_breadth_firsrt_traversal_deptype_with_builddeps(abstract_specs_dtuse):
+ s = abstract_specs_dtuse["dttop"]
names = ["dttop", "dtbuild1", "dtlink1", "dtbuild2", "dtlink2", "dtlink3", "dtlink4"]
- traversal = traverse.traverse_nodes(
- [s], order="breadth", key=key_by_hash, deptype=("build", "link")
- )
+ traversal = traverse.traverse_nodes([s], order="breadth", key=id, deptype=("build", "link"))
assert [x.name for x in traversal] == names
-def test_breadth_first_traversal_deptype_full(config, mock_packages):
- s = Spec("dttop").concretized()
+def test_breadth_first_traversal_deptype_full(abstract_specs_dtuse):
+ s = abstract_specs_dtuse["dttop"]
names = [
"dttop",
@@ -72,21 +142,24 @@ def test_breadth_first_traversal_deptype_full(config, mock_packages):
"dtbuild3",
]
- traversal = traverse.traverse_nodes([s], order="breadth", key=key_by_hash, deptype="all")
+ traversal = traverse.traverse_nodes([s], order="breadth", key=id, deptype="all")
assert [x.name for x in traversal] == names
-def test_breadth_first_traversal_deptype_run(config, mock_packages):
- s = Spec("dttop").concretized()
+def test_breadth_first_traversal_deptype_run(abstract_specs_dtuse):
+ s = abstract_specs_dtuse["dttop"]
names = ["dttop", "dtrun1", "dtrun3"]
- traversal = traverse.traverse_nodes([s], order="breadth", key=key_by_hash, deptype="run")
+ traversal = traverse.traverse_nodes([s], order="breadth", key=id, deptype="run")
assert [x.name for x in traversal] == names
-def test_breadth_first_traversal_reverse(config, mock_packages):
- s = Spec("dt-diamond").concretized()
+def test_breadth_first_traversal_reverse(abstract_specs_dt_diamond):
gen = traverse.traverse_nodes(
- [s["dt-diamond-bottom"]], order="breadth", key=key_by_hash, direction="parents", depth=True
+ [abstract_specs_dt_diamond["dt-diamond-bottom"]],
+ order="breadth",
+ key=id,
+ direction="parents",
+ depth=True,
)
assert [(depth, spec.name) for (depth, spec) in gen] == [
(0, "dt-diamond-bottom"),
@@ -96,20 +169,22 @@ def test_breadth_first_traversal_reverse(config, mock_packages):
]
-def test_breadth_first_traversal_multiple_roots(config, mock_packages):
+def test_breadth_first_traversal_multiple_roots(abstract_specs_dt_diamond):
# With DFS, the branch dt-diamond -> dt-diamond-left -> dt-diamond-bottom
# is followed, with BFS, dt-diamond-bottom should be traced through the second
# root dt-diamond-right at depth 1 instead.
- s = Spec("dt-diamond").concretized()
- roots = [s["dt-diamond"], s["dt-diamond-right"]]
- gen = traverse.traverse_edges(roots, order="breadth", key=key_by_hash, depth=True, root=False)
+ roots = [
+ abstract_specs_dt_diamond["dt-diamond"],
+ abstract_specs_dt_diamond["dt-diamond-right"],
+ ]
+ gen = traverse.traverse_edges(roots, order="breadth", key=id, depth=True, root=False)
assert [(depth, edge.parent.name, edge.spec.name) for (depth, edge) in gen] == [
(1, "dt-diamond", "dt-diamond-left"), # edge from first root "to" depth 1
(1, "dt-diamond-right", "dt-diamond-bottom"), # edge from second root "to" depth 1
]
-def test_breadth_first_versus_depth_first_tree(config, mock_packages):
+def test_breadth_first_versus_depth_first_tree(abstract_specs_chain):
"""
The packages chain-a, chain-b, chain-c, chain-d have the following DAG:
a --> b --> c --> d # a chain
@@ -117,7 +192,7 @@ def test_breadth_first_versus_depth_first_tree(config, mock_packages):
a --> d
Here we test at what depth the nodes are discovered when using BFS vs DFS.
"""
- s = Spec("chain-a").concretized()
+ s = abstract_specs_chain["chain-a"]
# BFS should find all nodes as direct deps
assert [
@@ -168,9 +243,9 @@ def test_breadth_first_versus_depth_first_tree(config, mock_packages):
]
-def test_breadth_first_versus_depth_first_printing(config, mock_packages):
+def test_breadth_first_versus_depth_first_printing(abstract_specs_chain):
"""Test breadth-first versus depth-first tree printing."""
- s = Spec("chain-a").concretized()
+ s = abstract_specs_chain["chain-a"]
args = {"format": "{name}", "color": False}
diff --git a/var/spack/repos/builtin.mock/packages/chain-a/package.py b/var/spack/repos/builtin.mock/packages/chain-a/package.py
deleted file mode 100644
index 6dc7dc2c90..0000000000
--- a/var/spack/repos/builtin.mock/packages/chain-a/package.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
-# Spack Project Developers. See the top-level COPYRIGHT file for details.
-#
-# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
-from spack.package import *
-
-
-class ChainA(Package):
- """
- Part of a collection of mock packages used for testing depth-first vs
- breadth-first traversal. The DAG they form:
- a --> b --> c --> d # a chain
- a --> c # "skip" connection
- a --> d # "skip" connection
- Spack's edge order is based on the child package name.
- In depth-first traversal we get a tree that looks like a chain:
- a
- b
- c
- d
- In breadth-first we get the tree:
- a
- b
- c
- d
- """
-
- homepage = "https://example.com"
- has_code = False
- version("1.0")
- depends_on("chain-b")
- depends_on("chain-c")
- depends_on("chain-d")
diff --git a/var/spack/repos/builtin.mock/packages/chain-b/package.py b/var/spack/repos/builtin.mock/packages/chain-b/package.py
deleted file mode 100644
index ede29c0e0f..0000000000
--- a/var/spack/repos/builtin.mock/packages/chain-b/package.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
-# Spack Project Developers. See the top-level COPYRIGHT file for details.
-#
-# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
-from spack.package import *
-
-
-class ChainB(Package):
- """
- Part of a collection of mock packages used for testing depth-first vs
- breadth-first traversal. The DAG they form:
- a --> b --> c --> d # a chain
- a --> c # "skip" connection
- a --> d # "skip" connection
- Spack's edge order is based on the child package name.
- In depth-first traversal we get a tree that looks like a chain:
- a
- b
- c
- d
- In breadth-first we get the tree:
- a
- b
- c
- d
- """
-
- homepage = "https://example.com"
- has_code = False
- version("1.0")
- depends_on("chain-c")
diff --git a/var/spack/repos/builtin.mock/packages/chain-c/package.py b/var/spack/repos/builtin.mock/packages/chain-c/package.py
deleted file mode 100644
index e9d919f0ba..0000000000
--- a/var/spack/repos/builtin.mock/packages/chain-c/package.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
-# Spack Project Developers. See the top-level COPYRIGHT file for details.
-#
-# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
-from spack.package import *
-
-
-class ChainC(Package):
- """
- Part of a collection of mock packages used for testing depth-first vs
- breadth-first traversal. The DAG they form:
- a --> b --> c --> d # a chain
- a --> c # "skip" connection
- a --> d # "skip" connection
- Spack's edge order is based on the child package name.
- In depth-first traversal we get a tree that looks like a chain:
- a
- b
- c
- d
- In breadth-first we get the tree:
- a
- b
- c
- d
- """
-
- homepage = "https://example.com"
- has_code = False
- version("1.0")
- depends_on("chain-d")
diff --git a/var/spack/repos/builtin.mock/packages/chain-d/package.py b/var/spack/repos/builtin.mock/packages/chain-d/package.py
deleted file mode 100644
index f2e04089ee..0000000000
--- a/var/spack/repos/builtin.mock/packages/chain-d/package.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
-# Spack Project Developers. See the top-level COPYRIGHT file for details.
-#
-# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-
-from spack.package import *
-
-
-class ChainD(Package):
- """
- Part of a collection of mock packages used for testing depth-first vs
- breadth-first traversal. The DAG they form:
- a --> b --> c --> d # a chain
- a --> c # "skip" connection
- a --> d # "skip" connection
- Spack's edge order is based on the child package name.
- In depth-first traversal we get a tree that looks like a chain:
- a
- b
- c
- d
- In breadth-first we get the tree:
- a
- b
- c
- d
- """
-
- homepage = "https://example.com"
- has_code = False
- version("1.0")