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