Source code for spack.test.cmd.find

# 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)

import argparse
import json
import os
import sys
from textwrap import dedent

import pytest

import spack.cmd as cmd
import spack.cmd.find
import spack.environment as ev
import spack.user_environment as uenv
from spack.main import SpackCommand
from spack.spec import Spec
from spack.util.pattern import Bunch

find = SpackCommand("find")
env = SpackCommand("env")
install = SpackCommand("install")

base32_alphabet = "abcdefghijklmnopqrstuvwxyz234567"

pytestmark = pytest.mark.skipif(sys.platform == "win32", reason="does not run on windows")


[docs]@pytest.fixture(scope="module") def parser(): """Returns the parser for the module command""" prs = argparse.ArgumentParser() spack.cmd.find.setup_parser(prs) return prs
[docs]@pytest.fixture() def specs(): s = [] return s
[docs]@pytest.fixture() def mock_display(monkeypatch, specs): """Monkeypatches the display function to return its first argument""" def display(x, *args, **kwargs): specs.extend(x) monkeypatch.setattr(spack.cmd, "display_specs", display)
[docs]def test_query_arguments(): query_arguments = spack.cmd.find.query_arguments # Default arguments args = Bunch( only_missing=False, missing=False, only_deprecated=False, deprecated=False, unknown=False, explicit=False, implicit=False, start_date="2018-02-23", end_date=None, ) q_args = query_arguments(args) assert "installed" in q_args assert "known" in q_args assert "explicit" in q_args assert q_args["installed"] == ["installed"] assert q_args["known"] is any assert q_args["explicit"] is any assert "start_date" in q_args assert "end_date" not in q_args # Check that explicit works correctly args.explicit = True q_args = query_arguments(args) assert q_args["explicit"] is True args.explicit = False args.implicit = True q_args = query_arguments(args) assert q_args["explicit"] is False
[docs]@pytest.mark.db @pytest.mark.usefixtures("database", "mock_display") def test_tag1(parser, specs): args = parser.parse_args(["--tag", "tag1"]) spack.cmd.find.find(parser, args) assert len(specs) == 2 assert "mpich" in [x.name for x in specs] assert "mpich2" in [x.name for x in specs]
[docs]@pytest.mark.db @pytest.mark.usefixtures("database", "mock_display") def test_tag2(parser, specs): args = parser.parse_args(["--tag", "tag2"]) spack.cmd.find.find(parser, args) assert len(specs) == 1 assert "mpich" in [x.name for x in specs]
[docs]@pytest.mark.db @pytest.mark.usefixtures("database", "mock_display") def test_tag2_tag3(parser, specs): args = parser.parse_args(["--tag", "tag2", "--tag", "tag3"]) spack.cmd.find.find(parser, args) assert len(specs) == 0
[docs]@pytest.mark.db def test_namespaces_shown_correctly(database): out = find() assert "builtin.mock.zmpi" not in out out = find("--namespace") assert "builtin.mock.zmpi" in out
[docs]@pytest.mark.db def test_find_cli_output_format(database, mock_tty_stdout): out = find("zmpi") assert out.endswith( dedent( """\ zmpi@1.0 ==> 1 installed package """ ) )
def _check_json_output(spec_list): assert len(spec_list) == 3 assert all(spec["name"] == "mpileaks" for spec in spec_list) assert all(spec["hash"] for spec in spec_list) deps = [spec["dependencies"] for spec in spec_list] assert sum(["zmpi" in [node["name"] for d in deps for node in d]]) == 1 assert sum(["mpich" in [node["name"] for d in deps for node in d]]) == 1 assert sum(["mpich2" in [node["name"] for d in deps for node in d]]) == 1 def _check_json_output_deps(spec_list): assert len(spec_list) == 13 names = [spec["name"] for spec in spec_list] assert names.count("mpileaks") == 3 assert names.count("callpath") == 3 assert names.count("zmpi") == 1 assert names.count("mpich") == 1 assert names.count("mpich2") == 1 assert names.count("fake") == 1 assert names.count("dyninst") == 1 assert names.count("libdwarf") == 1 assert names.count("libelf") == 1
[docs]@pytest.mark.db def test_find_json(database): output = find("--json", "mpileaks") spec_list = json.loads(output) _check_json_output(spec_list)
[docs]@pytest.mark.db def test_find_json_deps(database): output = find("-d", "--json", "mpileaks") spec_list = json.loads(output) _check_json_output_deps(spec_list)
[docs]@pytest.mark.db def test_display_json(database, capsys): specs = [ Spec(s).concretized() for s in [ "mpileaks ^zmpi", "mpileaks ^mpich", "mpileaks ^mpich2", ] ] cmd.display_specs_as_json(specs) spec_list = json.loads(capsys.readouterr()[0]) _check_json_output(spec_list) cmd.display_specs_as_json(specs + specs + specs) spec_list = json.loads(capsys.readouterr()[0]) _check_json_output(spec_list)
[docs]@pytest.mark.db def test_display_json_deps(database, capsys): specs = [ Spec(s).concretized() for s in [ "mpileaks ^zmpi", "mpileaks ^mpich", "mpileaks ^mpich2", ] ] cmd.display_specs_as_json(specs, deps=True) spec_list = json.loads(capsys.readouterr()[0]) _check_json_output_deps(spec_list) cmd.display_specs_as_json(specs + specs + specs, deps=True) spec_list = json.loads(capsys.readouterr()[0]) _check_json_output_deps(spec_list)
[docs]@pytest.mark.db def test_find_format(database, config): output = find("--format", "{name}-{^mpi.name}", "mpileaks") assert set(output.strip().split("\n")) == set( [ "mpileaks-zmpi", "mpileaks-mpich", "mpileaks-mpich2", ] ) output = find("--format", "{name}-{version}-{compiler.name}-{^mpi.name}", "mpileaks") assert "installed package" not in output assert set(output.strip().split("\n")) == set( [ "mpileaks-2.3-gcc-zmpi", "mpileaks-2.3-gcc-mpich", "mpileaks-2.3-gcc-mpich2", ] ) output = find("--format", "{name}-{^mpi.name}-{hash:7}", "mpileaks") elements = output.strip().split("\n") assert set(e[:-7] for e in elements) == set( [ "mpileaks-zmpi-", "mpileaks-mpich-", "mpileaks-mpich2-", ] ) # hashes are in base32 for e in elements: for c in e[-7:]: assert c in base32_alphabet
[docs]@pytest.mark.db def test_find_format_deps(database, config): output = find("-d", "--format", "{name}-{version}", "mpileaks", "^zmpi") assert ( output == """\ mpileaks-2.3 callpath-1.0 dyninst-8.2 libdwarf-20130729 libelf-0.8.13 zmpi-1.0 fake-1.0 """ )
[docs]@pytest.mark.db def test_find_format_deps_paths(database, config): output = find("-dp", "--format", "{name}-{version}", "mpileaks", "^zmpi") spec = Spec("mpileaks ^zmpi").concretized() prefixes = [s.prefix for s in spec.traverse()] assert ( output == """\ mpileaks-2.3 {0} callpath-1.0 {1} dyninst-8.2 {2} libdwarf-20130729 {3} libelf-0.8.13 {4} zmpi-1.0 {5} fake-1.0 {6} """.format( *prefixes ) )
[docs]@pytest.mark.db def test_find_very_long(database, config): output = find("-L", "--no-groups", "mpileaks") specs = [ Spec(s).concretized() for s in [ "mpileaks ^zmpi", "mpileaks ^mpich", "mpileaks ^mpich2", ] ] assert set(output.strip().split("\n")) == set( [("%s mpileaks@2.3" % s.dag_hash()) for s in specs] )
[docs]@pytest.mark.db def test_find_show_compiler(database, config): output = find("--no-groups", "--show-full-compiler", "mpileaks") assert "mpileaks@2.3%gcc@10.2.1" in output
[docs]@pytest.mark.db def test_find_not_found(database, config, capsys): with capsys.disabled(): output = find("foobarbaz", fail_on_error=False) assert "No package matches the query: foobarbaz" in output assert find.returncode == 1
[docs]@pytest.mark.db def test_find_no_sections(database, config): output = find() assert "-----------" in output output = find("--no-groups") assert "-----------" not in output assert "==>" not in output
[docs]@pytest.mark.db def test_find_command_basic_usage(database): output = find() assert "mpileaks" in output
[docs]@pytest.mark.regression("9875") def test_find_prefix_in_env( mutable_mock_env_path, install_mockery, mock_fetch, mock_packages, mock_archive, config ): """Test `find` formats requiring concrete specs work in environments.""" env("create", "test") with ev.read("test"): install("--add", "mpileaks") find("-p") find("-l") find("-L")
# Would throw error on regression
[docs]def test_find_loaded(database, working_env): output = find("--loaded", "--group") assert output == "" os.environ[uenv.spack_loaded_hashes_var] = ":".join( [x.dag_hash() for x in spack.store.db.query()] ) output = find("--loaded") expected = find() assert output == expected