summaryrefslogtreecommitdiff
path: root/lib/spack/spack/test/tag.py
blob: ae950002588a2e8d19142fbcfe7a77fa4a4b488a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# Copyright 2013-2023 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)
"""Tests for tag index cache files."""
import io

import pytest

import spack.cmd.install
import spack.tag
from spack.main import SpackCommand

install = SpackCommand("install")

# Alternate representation
tags_json = """
    {
      "tags": {
        "no-version": [
          "noversion",
          "noversion-bundle"
        ],
        "no-source": [
          "nosource"
        ]
      }
    }
    """

more_tags_json = """
    {
      "tags": {
        "merge": [
          "check"
        ]
      }
    }
    """


def test_tag_copy(mock_packages):
    index = spack.tag.TagIndex.from_json(io.StringIO(tags_json), repository=mock_packages)
    new_index = index.copy()

    assert index.tags == new_index.tags


def test_tag_get_all_available(mock_packages):
    for skip in [False, True]:
        all_pkgs = spack.tag.packages_with_tags(None, False, skip)
        assert sorted(all_pkgs["tag1"]) == ["mpich", "mpich2"]
        assert all_pkgs["tag2"] == ["mpich"]
        assert all_pkgs["tag3"] == ["mpich2"]


def ensure_tags_results_equal(results, expected):
    if expected:
        assert sorted(results.keys()) == sorted(expected.keys())
        for tag in results:
            assert sorted(results[tag]) == sorted(expected[tag])
    else:
        assert results == expected


@pytest.mark.parametrize(
    "tags,expected",
    [
        (["tag1"], {"tag1": ["mpich", "mpich2"]}),
        (["tag2"], {"tag2": ["mpich"]}),
        (["tag3"], {"tag3": ["mpich2"]}),
        (["nosuchpackage"], {"nosuchpackage": {}}),
    ],
)
def test_tag_get_available(tags, expected, mock_packages):
    # Ensure results for all tags
    all_tag_pkgs = spack.tag.packages_with_tags(tags, False, False)
    ensure_tags_results_equal(all_tag_pkgs, expected)

    # Ensure results for tags expecting results since skipping otherwise
    only_pkgs = spack.tag.packages_with_tags(tags, False, True)
    if expected[tags[0]]:
        ensure_tags_results_equal(only_pkgs, expected)
    else:
        assert not only_pkgs


def test_tag_get_installed_packages(mock_packages, mock_archive, mock_fetch, install_mockery):
    install("mpich")

    for skip in [False, True]:
        all_pkgs = spack.tag.packages_with_tags(None, True, skip)
        assert sorted(all_pkgs["tag1"]) == ["mpich"]
        assert all_pkgs["tag2"] == ["mpich"]
        assert skip or all_pkgs["tag3"] == []


def test_tag_index_round_trip(mock_packages):
    # Assumes at least two packages -- mpich and mpich2 -- have tags
    mock_index = spack.repo.PATH.tag_index
    assert mock_index.tags

    ostream = io.StringIO()
    mock_index.to_json(ostream)

    istream = io.StringIO(ostream.getvalue())
    new_index = spack.tag.TagIndex.from_json(istream, repository=mock_packages)

    assert mock_index == new_index


def test_tag_equal(mock_packages):
    first_index = spack.tag.TagIndex.from_json(io.StringIO(tags_json), repository=mock_packages)
    second_index = spack.tag.TagIndex.from_json(io.StringIO(tags_json), repository=mock_packages)

    assert first_index == second_index


def test_tag_merge(mock_packages):
    first_index = spack.tag.TagIndex.from_json(io.StringIO(tags_json), repository=mock_packages)
    second_index = spack.tag.TagIndex.from_json(
        io.StringIO(more_tags_json), repository=mock_packages
    )

    assert first_index != second_index

    tags1 = list(first_index.tags.keys())
    tags2 = list(second_index.tags.keys())
    all_tags = sorted(list(set(tags1 + tags2)))

    first_index.merge(second_index)
    tag_keys = sorted(first_index.tags.keys())
    assert tag_keys == all_tags

    # Merge again to make sure the index does not retain duplicates
    first_index.merge(second_index)
    tag_keys = sorted(first_index.tags.keys())
    assert tag_keys == all_tags


def test_tag_not_dict(mock_packages):
    list_json = "[]"
    with pytest.raises(spack.tag.TagIndexError) as e:
        spack.tag.TagIndex.from_json(io.StringIO(list_json), repository=mock_packages)
        assert "not a dict" in str(e)


def test_tag_no_tags(mock_packages):
    pkg_json = '{"packages": []}'
    with pytest.raises(spack.tag.TagIndexError) as e:
        spack.tag.TagIndex.from_json(io.StringIO(pkg_json), repository=mock_packages)
        assert "does not start with" in str(e)


def test_tag_update_package(mock_packages):
    mock_index = spack.repo.PATH.tag_index
    index = spack.tag.TagIndex(repository=mock_packages)
    for name in spack.repo.all_package_names():
        index.update_package(name)

    ensure_tags_results_equal(mock_index.tags, index.tags)