diff options
Diffstat (limited to 'lib/spack/spack/test/graph.py')
-rw-r--r-- | lib/spack/spack/test/graph.py | 151 |
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'] |