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