summaryrefslogtreecommitdiff
path: root/lib/spack/spack/test/graph.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/spack/spack/test/graph.py')
-rw-r--r--lib/spack/spack/test/graph.py151
1 files changed, 67 insertions, 84 deletions
diff --git a/lib/spack/spack/test/graph.py b/lib/spack/spack/test/graph.py
index 6cd8b69d84..c836c9905a 100644
--- a/lib/spack/spack/test/graph.py
+++ b/lib/spack/spack/test/graph.py
@@ -2,43 +2,31 @@
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import sys
-from six import StringIO
+import pytest
+import six
+import spack.graph
import spack.repo
-from spack.graph import AsciiGraph, graph_dot, topological_sort
-from spack.spec import Spec
+import spack.spec
-def test_topo_sort(mock_packages):
- """Test topo sort gives correct order."""
- s = Spec('mpileaks').normalized()
+@pytest.mark.parametrize('spec_str', ['mpileaks', 'callpath'])
+def test_topo_sort(spec_str, config, mock_packages):
+ """Ensure nodes are ordered topologically"""
+ s = spack.spec.Spec(spec_str).concretized()
+ nodes = spack.graph.topological_sort(s)
+ for idx, current in enumerate(nodes):
+ assert all(following not in current for following in nodes[idx + 1:])
- topo = topological_sort(s)
- assert topo.index('mpileaks') < topo.index('callpath')
- assert topo.index('mpileaks') < topo.index('mpi')
- assert topo.index('mpileaks') < topo.index('dyninst')
- assert topo.index('mpileaks') < topo.index('libdwarf')
- assert topo.index('mpileaks') < topo.index('libelf')
-
- assert topo.index('callpath') < topo.index('mpi')
- assert topo.index('callpath') < topo.index('dyninst')
- assert topo.index('callpath') < topo.index('libdwarf')
- assert topo.index('callpath') < topo.index('libelf')
-
- assert topo.index('dyninst') < topo.index('libdwarf')
- assert topo.index('dyninst') < topo.index('libelf')
-
- assert topo.index('libdwarf') < topo.index('libelf')
-
-
-def test_static_graph_mpileaks(mock_packages):
+def test_static_graph_mpileaks(config, mock_packages):
"""Test a static spack graph for a simple package."""
- s = Spec('mpileaks').normalized()
+ s = spack.spec.Spec('mpileaks').normalized()
- stream = StringIO()
- graph_dot([s], static=True, out=stream)
+ stream = six.StringIO()
+ spack.graph.graph_dot([s], static=True, out=stream)
dot = stream.getvalue()
@@ -62,72 +50,67 @@ def test_static_graph_mpileaks(mock_packages):
def test_dynamic_dot_graph_mpileaks(mock_packages, config):
"""Test dynamically graphing the mpileaks package."""
- s = Spec('mpileaks').concretized()
-
- stream = StringIO()
- graph_dot([s], static=False, out=stream)
-
+ s = spack.spec.Spec('mpileaks').concretized()
+ stream = six.StringIO()
+ spack.graph.graph_dot([s], static=False, out=stream)
dot = stream.getvalue()
- print(dot)
-
- mpileaks_hash, mpileaks_lbl = s.dag_hash(), s.format('{name}')
- mpi_hash, mpi_lbl = s['mpi'].dag_hash(), s['mpi'].format('{name}')
- callpath_hash, callpath_lbl = (
- s['callpath'].dag_hash(), s['callpath'].format('{name}'))
- dyninst_hash, dyninst_lbl = (
- s['dyninst'].dag_hash(), s['dyninst'].format('{name}'))
- libdwarf_hash, libdwarf_lbl = (
- s['libdwarf'].dag_hash(), s['libdwarf'].format('{name}'))
- libelf_hash, libelf_lbl = (
- s['libelf'].dag_hash(), s['libelf'].format('{name}'))
-
- assert ' "%s" [label="%s"]\n' % (mpileaks_hash, mpileaks_lbl) in dot
- assert ' "%s" [label="%s"]\n' % (callpath_hash, callpath_lbl) in dot
- assert ' "%s" [label="%s"]\n' % (mpi_hash, mpi_lbl) in dot
- assert ' "%s" [label="%s"]\n' % (dyninst_hash, dyninst_lbl) in dot
- assert ' "%s" [label="%s"]\n' % (libdwarf_hash, libdwarf_lbl) in dot
- assert ' "%s" [label="%s"]\n' % (libelf_hash, libelf_lbl) in dot
-
- assert ' "%s" -> "%s"\n' % (dyninst_hash, libdwarf_hash) in dot
- assert ' "%s" -> "%s"\n' % (callpath_hash, dyninst_hash) in dot
- assert ' "%s" -> "%s"\n' % (mpileaks_hash, mpi_hash) in dot
- assert ' "%s" -> "%s"\n' % (libdwarf_hash, libelf_hash) in dot
- assert ' "%s" -> "%s"\n' % (callpath_hash, mpi_hash) in dot
- assert ' "%s" -> "%s"\n' % (mpileaks_hash, callpath_hash) in dot
- assert ' "%s" -> "%s"\n' % (dyninst_hash, libelf_hash) in dot
-
-
-def test_ascii_graph_mpileaks(mock_packages):
- """Test dynamically graphing the mpileaks package."""
- s = Spec('mpileaks').normalized()
- stream = StringIO()
- graph = AsciiGraph()
+ nodes_to_check = ['mpileaks', 'mpi', 'callpath', 'dyninst', 'libdwarf', 'libelf']
+ hashes = {}
+ for name in nodes_to_check:
+ current = s[name]
+ current_hash = current.dag_hash()
+ hashes[name] = current_hash
+ assert ' "{0}" [label="{1}"]\n'.format(
+ current_hash, spack.graph.node_label(current)
+ ) in dot
+
+ dependencies_to_check = [
+ ('dyninst', 'libdwarf'),
+ ('callpath', 'dyninst'),
+ ('mpileaks', 'mpi'),
+ ('libdwarf', 'libelf'),
+ ('callpath', 'mpi'),
+ ('mpileaks', 'callpath'),
+ ('dyninst', 'libelf')
+ ]
+ for parent, child in dependencies_to_check:
+ assert ' "{0}" -> "{1}"\n'.format(hashes[parent], hashes[child]) in dot
+
+
+@pytest.mark.skipif(
+ sys.version_info < (3, 6), reason="Ordering might not be consistent"
+)
+def test_ascii_graph_mpileaks(config, mock_packages, monkeypatch):
+ monkeypatch.setattr(
+ spack.graph.AsciiGraph, '_node_label',
+ lambda self, node: node.name
+ )
+ s = spack.spec.Spec('mpileaks').concretized()
+
+ stream = six.StringIO()
+ graph = spack.graph.AsciiGraph()
graph.write(s, out=stream, color=False)
- string = stream.getvalue()
+ graph_str = stream.getvalue()
+ graph_str = '\n'.join([line.rstrip() for line in graph_str.split('\n')])
- # Some lines in spack graph still have trailing space
- # TODO: fix this.
- string = '\n'.join([line.rstrip() for line in string.split('\n')])
-
- assert string == r'''o mpileaks
+ assert graph_str == r'''o mpileaks
|\
-| o callpath
+| o callpath
|/|
-o | mpi
+o | mpich
/
-o dyninst
+o dyninst
|\
-| o libdwarf
+o | libdwarf
|/
-o libelf
+o libelf
'''
-def test_topo_sort_filtered(mock_packages):
- """Test topo sort gives correct order when filtering link deps."""
- s = Spec('both-link-and-build-dep-a').normalized()
-
- topo = topological_sort(s, deptype=('link',))
+def test_topological_sort_filtering_dependency_types(config, mock_packages):
+ s = spack.spec.Spec('both-link-and-build-dep-a').concretized()
- assert topo == ['both-link-and-build-dep-a', 'both-link-and-build-dep-c']
+ nodes = spack.graph.topological_sort(s, deptype=('link',))
+ names = [s.name for s in nodes]
+ assert names == ['both-link-and-build-dep-c', 'both-link-and-build-dep-a']