1*bb4ee6a4SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*bb4ee6a4SAndroid Build Coastguard Worker# Copyright 2022 The ChromiumOS Authors 3*bb4ee6a4SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 4*bb4ee6a4SAndroid Build Coastguard Worker# found in the LICENSE file. 5*bb4ee6a4SAndroid Build Coastguard Worker 6*bb4ee6a4SAndroid Build Coastguard Workerimport os 7*bb4ee6a4SAndroid Build Coastguard Workerfrom pathlib import Path 8*bb4ee6a4SAndroid Build Coastguard Workerimport shutil 9*bb4ee6a4SAndroid Build Coastguard Workerimport sys 10*bb4ee6a4SAndroid Build Coastguard Workerimport tempfile 11*bb4ee6a4SAndroid Build Coastguard Workerimport unittest 12*bb4ee6a4SAndroid Build Coastguard Worker 13*bb4ee6a4SAndroid Build Coastguard Workersys.path.append(os.path.dirname(sys.path[0])) 14*bb4ee6a4SAndroid Build Coastguard Worker 15*bb4ee6a4SAndroid Build Coastguard Workerfrom impl.common import CROSVM_ROOT, cmd, quoted, TOOLS_ROOT 16*bb4ee6a4SAndroid Build Coastguard Worker 17*bb4ee6a4SAndroid Build Coastguard Workergit = cmd("git") 18*bb4ee6a4SAndroid Build Coastguard Workercl = cmd(f"{TOOLS_ROOT}/cl") 19*bb4ee6a4SAndroid Build Coastguard Worker 20*bb4ee6a4SAndroid Build Coastguard Worker 21*bb4ee6a4SAndroid Build Coastguard Workerclass ClTests(unittest.TestCase): 22*bb4ee6a4SAndroid Build Coastguard Worker test_root: Path 23*bb4ee6a4SAndroid Build Coastguard Worker 24*bb4ee6a4SAndroid Build Coastguard Worker def setUp(self): 25*bb4ee6a4SAndroid Build Coastguard Worker self.test_root = Path(tempfile.mkdtemp()) 26*bb4ee6a4SAndroid Build Coastguard Worker os.chdir(self.test_root) 27*bb4ee6a4SAndroid Build Coastguard Worker git("clone", CROSVM_ROOT, ".").fg(quiet=True) 28*bb4ee6a4SAndroid Build Coastguard Worker 29*bb4ee6a4SAndroid Build Coastguard Worker # Set up user name (it's not set up in Luci) 30*bb4ee6a4SAndroid Build Coastguard Worker git("config user.name Nobody").fg(quiet=True) 31*bb4ee6a4SAndroid Build Coastguard Worker git("config user.email [email protected]").fg(quiet=True) 32*bb4ee6a4SAndroid Build Coastguard Worker 33*bb4ee6a4SAndroid Build Coastguard Worker # Check out a detached head and delete all branches. 34*bb4ee6a4SAndroid Build Coastguard Worker git("checkout -d HEAD").fg(quiet=True) 35*bb4ee6a4SAndroid Build Coastguard Worker branch_list = git("branch").lines() 36*bb4ee6a4SAndroid Build Coastguard Worker for branch in branch_list: 37*bb4ee6a4SAndroid Build Coastguard Worker if not branch.startswith("*"): 38*bb4ee6a4SAndroid Build Coastguard Worker git("branch -D", branch).fg(quiet=True) 39*bb4ee6a4SAndroid Build Coastguard Worker 40*bb4ee6a4SAndroid Build Coastguard Worker # Set up the origin for testing uploads and rebases. 41*bb4ee6a4SAndroid Build Coastguard Worker git("remote set-url origin https://chromium.googlesource.com/crosvm/crosvm").fg(quiet=True) 42*bb4ee6a4SAndroid Build Coastguard Worker git("fetch -q origin main").fg(quiet=True) 43*bb4ee6a4SAndroid Build Coastguard Worker git("fetch -q origin chromeos").fg(quiet=True) 44*bb4ee6a4SAndroid Build Coastguard Worker 45*bb4ee6a4SAndroid Build Coastguard Worker def tearDown(self) -> None: 46*bb4ee6a4SAndroid Build Coastguard Worker shutil.rmtree(self.test_root) 47*bb4ee6a4SAndroid Build Coastguard Worker 48*bb4ee6a4SAndroid Build Coastguard Worker def create_test_commit(self, message: str, branch: str, upstream: str = "origin/main"): 49*bb4ee6a4SAndroid Build Coastguard Worker git("checkout -b", branch, "--track", upstream).fg(quiet=True) 50*bb4ee6a4SAndroid Build Coastguard Worker with Path("Cargo.toml").open("a") as file: 51*bb4ee6a4SAndroid Build Coastguard Worker file.write("# Foo") 52*bb4ee6a4SAndroid Build Coastguard Worker git("commit -a -m", quoted(message)).fg(quiet=True) 53*bb4ee6a4SAndroid Build Coastguard Worker return git("rev-parse HEAD").stdout() 54*bb4ee6a4SAndroid Build Coastguard Worker 55*bb4ee6a4SAndroid Build Coastguard Worker def test_cl_upload(self): 56*bb4ee6a4SAndroid Build Coastguard Worker sha = self.create_test_commit("Test Commit", "foo") 57*bb4ee6a4SAndroid Build Coastguard Worker expected = f"""\ 58*bb4ee6a4SAndroid Build Coastguard WorkerUploading to origin/main: 59*bb4ee6a4SAndroid Build Coastguard Worker {sha} Test Commit 60*bb4ee6a4SAndroid Build Coastguard Worker 61*bb4ee6a4SAndroid Build Coastguard WorkerNot running: git push origin HEAD:refs/for/main%""" 62*bb4ee6a4SAndroid Build Coastguard Worker 63*bb4ee6a4SAndroid Build Coastguard Worker self.assertEqual(cl("upload --dry-run").stdout(), expected) 64*bb4ee6a4SAndroid Build Coastguard Worker 65*bb4ee6a4SAndroid Build Coastguard Worker def test_cl_status(self): 66*bb4ee6a4SAndroid Build Coastguard Worker self.create_test_commit("Test Commit", "foo") 67*bb4ee6a4SAndroid Build Coastguard Worker expected = """\ 68*bb4ee6a4SAndroid Build Coastguard WorkerBranch foo tracking origin/main 69*bb4ee6a4SAndroid Build Coastguard Worker NOT_UPLOADED Test Commit""" 70*bb4ee6a4SAndroid Build Coastguard Worker 71*bb4ee6a4SAndroid Build Coastguard Worker self.assertEqual(cl("status").stdout(), expected) 72*bb4ee6a4SAndroid Build Coastguard Worker 73*bb4ee6a4SAndroid Build Coastguard Worker def test_cl_rebase(self): 74*bb4ee6a4SAndroid Build Coastguard Worker self.create_test_commit("Test Commit", "foo", "origin/chromeos") 75*bb4ee6a4SAndroid Build Coastguard Worker cl("rebase").fg() 76*bb4ee6a4SAndroid Build Coastguard Worker 77*bb4ee6a4SAndroid Build Coastguard Worker # Expect foo-upstream to be tracking `main` and have the same commit 78*bb4ee6a4SAndroid Build Coastguard Worker self.assertEqual(git("rev-parse --abbrev-ref foo-upstream@{u}").stdout(), "origin/main") 79*bb4ee6a4SAndroid Build Coastguard Worker self.assertEqual( 80*bb4ee6a4SAndroid Build Coastguard Worker git("log -1 --format=%s foo").stdout(), 81*bb4ee6a4SAndroid Build Coastguard Worker git("log -1 --format=%s foo-upstream").stdout(), 82*bb4ee6a4SAndroid Build Coastguard Worker ) 83*bb4ee6a4SAndroid Build Coastguard Worker 84*bb4ee6a4SAndroid Build Coastguard Worker def test_cl_rebase_with_existing_branch(self): 85*bb4ee6a4SAndroid Build Coastguard Worker previous_sha = self.create_test_commit("Previous commit", "foo-upstream ") 86*bb4ee6a4SAndroid Build Coastguard Worker self.create_test_commit("Test Commit", "foo", "origin/chromeos") 87*bb4ee6a4SAndroid Build Coastguard Worker message = cl("rebase").stdout() 88*bb4ee6a4SAndroid Build Coastguard Worker 89*bb4ee6a4SAndroid Build Coastguard Worker # `cl rebase` will overwrite the branch, but we should print the previous sha in case 90*bb4ee6a4SAndroid Build Coastguard Worker # the user needs to recover it. 91*bb4ee6a4SAndroid Build Coastguard Worker self.assertIn(previous_sha, message) 92*bb4ee6a4SAndroid Build Coastguard Worker 93*bb4ee6a4SAndroid Build Coastguard Worker # Expect foo-upstream to be tracking `main` and have the same commit. The previous commit 94*bb4ee6a4SAndroid Build Coastguard Worker # would be dropped. 95*bb4ee6a4SAndroid Build Coastguard Worker self.assertEqual(git("rev-parse --abbrev-ref foo-upstream@{u}").stdout(), "origin/main") 96*bb4ee6a4SAndroid Build Coastguard Worker self.assertEqual( 97*bb4ee6a4SAndroid Build Coastguard Worker git("log -1 --format=%s foo").stdout(), 98*bb4ee6a4SAndroid Build Coastguard Worker git("log -1 --format=%s foo-upstream").stdout(), 99*bb4ee6a4SAndroid Build Coastguard Worker ) 100*bb4ee6a4SAndroid Build Coastguard Worker 101*bb4ee6a4SAndroid Build Coastguard Worker def test_prune(self): 102*bb4ee6a4SAndroid Build Coastguard Worker self.create_test_commit("Test Commit", "foo") 103*bb4ee6a4SAndroid Build Coastguard Worker git("branch foo-no-commit origin/main").fg() 104*bb4ee6a4SAndroid Build Coastguard Worker cl("prune --force").fg() 105*bb4ee6a4SAndroid Build Coastguard Worker 106*bb4ee6a4SAndroid Build Coastguard Worker # `foo` has unsubmitted commits, it should still be there. 107*bb4ee6a4SAndroid Build Coastguard Worker self.assertTrue(git("rev-parse foo").success()) 108*bb4ee6a4SAndroid Build Coastguard Worker 109*bb4ee6a4SAndroid Build Coastguard Worker # `foo-no-commit` has no commits, it should have been pruned. 110*bb4ee6a4SAndroid Build Coastguard Worker self.assertFalse(git("rev-parse foo-no-commit").success()) 111*bb4ee6a4SAndroid Build Coastguard Worker 112*bb4ee6a4SAndroid Build Coastguard Worker 113*bb4ee6a4SAndroid Build Coastguard Workerif __name__ == "__main__": 114*bb4ee6a4SAndroid Build Coastguard Worker unittest.main(warnings="ignore") 115