• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#
2# Copyright (C) 2024 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16"""End-to-end tests for external_updater."""
17import subprocess
18from pathlib import Path
19
20import git_utils
21from .treebuilder import TreeBuilder
22
23UNFORMATTED_BP_FILE = """\
24cc_library_shared {
25    name: "test",
26    srcs: [
27        "source2.c",
28        "source1.c",
29    ],
30    cflags: ["-Wno-error=ignored-attributes", "-Wall", "-Werror"],
31}
32"""
33
34FORMATTED_BP_FILE = """\
35cc_library_shared {
36    name: "test",
37    srcs: [
38        "source2.c",
39        "source1.c",
40    ],
41    cflags: [
42        "-Wno-error=ignored-attributes",
43        "-Wall",
44        "-Werror",
45    ],
46}
47"""
48
49
50class TestUpdate:
51
52    def update(
53        self,
54        updater_cmd: list[str],
55        paths: list[Path],
56        args: list[str] | None = None,
57    ) -> str:
58        """Runs `external_updater update` with the given arguments.
59
60        Returns:
61        The output of the command.
62        """
63        return subprocess.run(
64            updater_cmd + ["update"] +
65            (args if args is not None else []) +
66            [str(p) for p in paths],
67            check=True,
68            capture_output=True,
69            text=True,
70        ).stdout
71
72    def test_bug_number(
73        self, tree_builder: TreeBuilder, updater_cmd: list[str]
74    ) -> None:
75        """Tests that bug number is added to the commit message."""
76        tree = tree_builder.repo_tree("tree")
77        a = tree.project("platform/external/foo", "external/foo")
78        tree.create_manifest_repo()
79        a.initial_import()
80        tree.init_and_sync()
81        bug_number = "12345"
82        self.update(updater_cmd, [a.local.path], args=['--refresh', '--bug', bug_number])
83        latest_sha = a.local.head()
84        latest_commit_message = a.local.commit_message_at_revision(latest_sha)
85        assert f"Bug: {bug_number}" in latest_commit_message
86
87    def test_custom_update_to_tag_successful(
88        self, tree_builder: TreeBuilder, updater_cmd: list[str]
89    ) -> None:
90        """Tests that upgrade to a specific tag is successful."""
91        tree = tree_builder.repo_tree("tree")
92        a = tree.project("platform/external/foo", "external/foo")
93        a.upstream.commit("Initial commit.", allow_empty=True)
94        a.upstream.tag("v1.0.0")
95        tree.create_manifest_repo()
96        a.initial_import(True)
97        tree.init_and_sync()
98        a.upstream.commit("Second commit.", allow_empty=True)
99        a.upstream.tag("v2.0.0")
100        a.upstream.commit("Third commit.", allow_empty=True)
101        a.upstream.tag("v3.0.0")
102        self.update(updater_cmd, [a.local.path], args=['--custom-version', "v2.0.0"])
103        latest_sha = a.local.head()
104        latest_commit_message = a.local.commit_message_at_revision(latest_sha)
105        assert "Upgrade test to v2.0.0" in latest_commit_message
106
107    def test_custom_downgrade_to_tag_unsuccessful(
108        self, tree_builder: TreeBuilder, updater_cmd: list[str]
109    ) -> None:
110        """Tests that downgrade to a specific tag is unsuccessful."""
111        tree = tree_builder.repo_tree("tree")
112        a = tree.project("platform/external/foo", "external/foo")
113        a.upstream.commit("Initial commit.", allow_empty=True)
114        a.upstream.tag("v1.0.0")
115        a.upstream.commit("Second commit.", allow_empty=True)
116        a.upstream.tag("v2.0.0")
117        tree.create_manifest_repo()
118        a.initial_import(True)
119        tree.init_and_sync()
120        self.update(updater_cmd, [a.local.path], args=['--custom-version', "v1.0.0"])
121        latest_sha = a.local.head()
122        latest_commit_message = a.local.commit_message_at_revision(latest_sha)
123        assert "Add metadata files." in latest_commit_message
124
125    def test_custom_update_to_sha_successful(
126        self, tree_builder: TreeBuilder, updater_cmd: list[str]
127    ) -> None:
128        """Tests that upgrade to a specific sha is successful."""
129        tree = tree_builder.repo_tree("tree")
130        a = tree.project("platform/external/foo", "external/foo")
131        a.upstream.commit("Initial commit.", allow_empty=True)
132        tree.create_manifest_repo()
133        a.initial_import()
134        tree.init_and_sync()
135        a.upstream.commit("Second commit.", allow_empty=True)
136        custom_sha = a.upstream.head()
137        a.upstream.commit("Third commit.", allow_empty=True)
138        self.update(updater_cmd, [a.local.path], args=['--custom-version', custom_sha])
139        latest_sha = a.local.head()
140        latest_commit_message = a.local.commit_message_at_revision(latest_sha)
141        assert f"Upgrade test to {custom_sha}" in latest_commit_message
142
143    def test_custom_downgrade_to_sha_unsuccessful(
144        self, tree_builder: TreeBuilder, updater_cmd: list[str]
145    ) -> None:
146        """Tests that downgrade to a specific sha is unsuccessful."""
147        tree = tree_builder.repo_tree("tree")
148        a = tree.project("platform/external/foo", "external/foo")
149        a.upstream.commit("Initial commit.", allow_empty=True)
150        custom_sha = a.upstream.head()
151        a.upstream.commit("Second commit.", allow_empty=True)
152        tree.create_manifest_repo()
153        a.initial_import()
154        tree.init_and_sync()
155        self.update(updater_cmd, [a.local.path], args=['--custom-version', custom_sha])
156        latest_sha = a.local.head()
157        latest_commit_message = a.local.commit_message_at_revision(latest_sha)
158        assert "Add metadata files." in latest_commit_message
159
160    def test_bpfmt_one_local_bp_file_no_upstream_bp_file(
161        self, tree_builder: TreeBuilder, updater_cmd: list[str]
162    ) -> None:
163        """Tests that bpfmt formats the only local bp file."""
164        tree = tree_builder.repo_tree("tree")
165        a = tree.project("platform/external/foo", "external/foo")
166        a.upstream.commit("Initial commit.", allow_empty=True)
167        tree.create_manifest_repo()
168        a.initial_import()
169        a.android_mirror.commit("Add Android.bp file", update_files={"Android.bp": UNFORMATTED_BP_FILE})
170        tree.init_and_sync()
171        a.upstream.commit("Second commit.", allow_empty=True)
172        self.update(updater_cmd, [a.local.path])
173        latest_sha = a.local.head()
174        bp_content = a.local.file_contents_at_revision(latest_sha, 'Android.bp')
175        assert bp_content == FORMATTED_BP_FILE
176
177    def test_bpfmt_one_local_bp_file_one_upstream_bp_file(
178        self, tree_builder: TreeBuilder, updater_cmd: list[str]
179    ) -> None:
180        """Tests that bpfmt doesn't format the bp file because it's an upstream file."""
181        tree = tree_builder.repo_tree("tree")
182        a = tree.project("platform/external/foo", "external/foo")
183        a.upstream.commit("Initial commit and adding bp file", update_files={"Android.bp": UNFORMATTED_BP_FILE})
184        tree.create_manifest_repo()
185        a.initial_import()
186        tree.init_and_sync()
187        a.upstream.commit("Second commit.", allow_empty=True)
188        self.update(updater_cmd, [a.local.path])
189        latest_sha = a.local.head()
190        bp_content = a.local.file_contents_at_revision(latest_sha, 'Android.bp')
191        assert bp_content == UNFORMATTED_BP_FILE
192
193    def test_repo_sync(
194        self, tree_builder: TreeBuilder, updater_cmd: list[str]
195    ) -> None:
196        """Tests if updater is fooled by checking out an older commit.
197
198        We want to see if we checkout an older update commit, external_updater
199        knows we are up to date and it is not fooled by the fake out of date
200        state.
201        """
202        tree = tree_builder.repo_tree("tree")
203        a = tree.project("platform/external/foo", "external/foo")
204        a.upstream.commit("Initial commit.", allow_empty=True)
205        tree.create_manifest_repo()
206        a.initial_import()
207        tree.init_and_sync()
208        head_after_import = a.android_mirror.head()
209        a.upstream.commit("Second commit.", allow_empty=True)
210        commit_two = a.upstream.head()
211        self.update(updater_cmd, [a.local.path])
212        a.android_mirror.checkout(head_after_import)
213        output = self.update(updater_cmd, [a.local.path])
214        assert output == (
215            f"repo sync has finished successfully.\n"
216            f"Checking {a.local.path}...\n"
217            f"Current version: {commit_two}\n"
218            f"Latest version: {commit_two}\n"
219            "Up to date.\n"
220        )
221