# # Copyright (C) 2023 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the 'License'); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an 'AS IS' BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # """Tests for manifest.py.""" import textwrap from pathlib import Path import pytest from manifest import Manifest, ManifestParser, find_manifest_xml_for_tree class TestFindManifestXmlForTree: """Tests for find_manifest_xml_for_tree.""" def test_repo_tree(self, repo_tree: Path) -> None: """Tests that the correct manifest file is found in a repo tree.""" manifest_dir = Path(repo_tree / ".repo/manifests") manifest_dir.mkdir() manifest_path = manifest_dir / "default.xml" manifest_path.touch() assert find_manifest_xml_for_tree(repo_tree) == manifest_path def test_no_manifest(self, tmp_path: Path) -> None: """Tests that an error is raised when no manifest is found.""" with pytest.raises(FileNotFoundError): find_manifest_xml_for_tree(tmp_path) class TestManifestParser: """Tests for ManifestParser.""" def test_default_missing(self, tmp_path: Path) -> None: """Tests that an error is raised when the default node is missing.""" manifest_path = tmp_path / "manifest.xml" manifest_path.write_text( textwrap.dedent( """\ """ ) ) with pytest.raises(RuntimeError): ManifestParser(manifest_path).parse() def test_name_missing(self, tmp_path: Path) -> None: """Tests that an error is raised when neither name nor path is defined for a project.""" manifest_path = tmp_path / "manifest.xml" manifest_path.write_text( textwrap.dedent( """\ """ ) ) with pytest.raises(RuntimeError): ManifestParser(manifest_path).parse() def test_multiple_default(self, tmp_path: Path) -> None: """Tests that an error is raised when there is more than one default node.""" manifest = tmp_path / "manifest.xml" manifest.write_text( textwrap.dedent( """\ """ ) ) with pytest.raises(RuntimeError): ManifestParser(manifest).parse() def test_remote_default(self, tmp_path: Path) -> None: """Tests that the default remote is used when not defined by the project.""" manifest_path = tmp_path / "manifest.xml" manifest_path.write_text( textwrap.dedent( """\ """ ) ) manifest = ManifestParser(manifest_path).parse() assert manifest.project_with_path("external/project").remote == "aosp" def test_revision_default(self, tmp_path: Path) -> None: """Tests that the default revision is used when not defined by the project.""" manifest_path = tmp_path / "manifest.xml" manifest_path.write_text( textwrap.dedent( """\ """ ) ) manifest = ManifestParser(manifest_path).parse() assert manifest.project_with_path("external/project").revision == "main" def test_path_default(self, tmp_path: Path) -> None: """Tests that the default path is used when not defined by the project.""" manifest_path = tmp_path / "manifest.xml" manifest_path.write_text( textwrap.dedent( """\ """ ) ) manifest = ManifestParser(manifest_path).parse() assert manifest.project_with_path("external/project") is not None def test_remote_explicit(self, tmp_path: Path) -> None: """Tests that the project remote is used when defined.""" manifest_path = tmp_path / "manifest.xml" manifest_path.write_text( textwrap.dedent( """\ """ ) ) manifest = ManifestParser(manifest_path).parse() assert manifest.project_with_path("external/project").remote == "origin" def test_revision_explicit(self, tmp_path: Path) -> None: """Tests that the project revision is used when defined.""" manifest_path = tmp_path / "manifest.xml" manifest_path.write_text( textwrap.dedent( """\ """ ) ) manifest = ManifestParser(manifest_path).parse() assert manifest.project_with_path("external/project").revision == "master" def test_path_explicit(self, tmp_path: Path) -> None: """Tests that the project path is used when defined.""" manifest_path = tmp_path / "manifest.xml" manifest_path.write_text( textwrap.dedent( """\ """ ) ) manifest = ManifestParser(manifest_path).parse() assert manifest.project_with_path("other/path") is not None class TestManifest: """Tests for Manifest.""" def test_for_tree(self, repo_tree: Path) -> None: """Tests the Manifest.for_tree constructor.""" manifest_dir = Path(repo_tree / ".repo/manifests") manifest_dir.mkdir() (manifest_dir / "default.xml").write_text( textwrap.dedent( """\ """ ) ) manifest = Manifest.for_tree(repo_tree) assert len(manifest.projects_by_path) == 3 def test_project_with_path(self, repo_tree: Path) -> None: """Tests that Manifest.project_with_path returns the correct project.""" manifest_dir = Path(repo_tree / ".repo/manifests") manifest_dir.mkdir() (manifest_dir / "default.xml").write_text( textwrap.dedent( """\ """ ) ) manifest = Manifest.for_tree(repo_tree) assert manifest.project_with_path("external/b").path == "external/b" def test_project_with_path_missing(self, repo_tree: Path) -> None: """Tests that Manifest.project_with_path raises an error when not found.""" manifest_dir = Path(repo_tree / ".repo/manifests") manifest_dir.mkdir() (manifest_dir / "default.xml").write_text( textwrap.dedent( """\ """ ) ) manifest = Manifest.for_tree(repo_tree) with pytest.raises(KeyError): manifest.project_with_path("external/d")