blob: 3eb8e355c37a4a183ceba26d49bee1d0f50009a4 [file] [log] [blame]
import os
import unittest
import uuid
from sh import git
from linaropy.cd import cd
from linaropy.proj import Proj
from linaropy.git.clone import Clone
from linaropy.git.worktree import Worktree
from modules.llvm import get_user_from_remote, get_remote_branch, push_branch
# FIXME: Maybe move these helpers somewhere more public, or use LLVMTestCase for
# these tests as well...
def create_dummy_commit(message="Branches without commits confuse git"):
filename = "file" + str(uuid.uuid4())
open(filename, "a").close()
git("add", filename)
git("commit", "-m", message)
def get_last_commit_message(branch=""):
return str(git("rev-list", "-1", "--oneline", branch)).strip()
def create_dummy_repo(path):
if not os.path.exists(path):
os.makedirs(path)
with cd(path):
git("init")
create_dummy_commit()
class TestGetUser(unittest.TestCase):
testdirprefix = "GetUserUT"
def test_full_remote(self):
user = get_user_from_remote("https://user1@remote.url:1234")
self.assertEqual(user, "user1")
user = get_user_from_remote("ssh://user2@remote.url:1234")
self.assertEqual(user, "user2")
def test_no_protocol_remote(self):
user = get_user_from_remote("user.name@remote.url:1234")
self.assertEqual(user, "user.name")
def test_no_user(self):
user = get_user_from_remote("https://remote.url:1234:")
self.assertEqual(user, None)
class TestGetRemoteBranch(unittest.TestCase):
testdirprefix = "GetRemoteBranchUT"
def setUp(self):
# Create a git repo so we can play with its remotes.
self.proj = Proj(prefix=self.testdirprefix)
path = os.path.join(self.proj.projdir, "repo")
create_dummy_repo(path)
self.repo = Clone(self.proj, path)
def tearDown(self):
self.proj.cleanup()
def test_valid_branch(self):
"""
Test that we return the correct remote branch name if everything is
valid.
"""
user = "a.user"
remote = "file://{}@{}".format(user, self.repo.repodir)
with cd(self.repo.repodir):
git("remote", "add", "origin", remote)
local_branch = "a-branch"
remote_branch = get_remote_branch(self.repo, local_branch)
self.assertEqual(
remote_branch, "linaro-local/{}/{}".format(user, local_branch))
def test_no_user(self):
"""Test that we error out when we can't parse a user in the remote name."""
remote = "file://" + self.repo.repodir
with cd(self.repo.repodir):
git("remote", "add", "origin", remote)
with self.assertRaises(EnvironmentError) as context:
get_remote_branch(self.repo, "a-branch")
self.assertEqual(str(context.exception),
"Couldn't parse user from {}.".format(remote))
def test_invalid_user(self):
"""
Test that we error out when the value of the user parsed from the remote
wouldn't look good in a branch name (e.g. if it contains spaces).
"""
badUser = "LLVM Developer"
with cd(self.repo.repodir):
git("remote", "add", "origin",
"file://{}@{}".format(badUser, self.repo.repodir))
branch = "a-branch"
with self.assertRaises(EnvironmentError) as context:
get_remote_branch(self.repo, branch)
self.assertEqual(str(context.exception),
"linaro-local/{}/{} is not a valid branch name.".format(badUser,
branch))
class TestPushBranch(unittest.TestCase):
testdirprefix = "PushBranchUT"
def setUp(self):
# We're going to create a hierarchy with an origin repo, a clone repo
# and a worktree of the clone. When pushing through the worktree, we
# expect to see things in origin.
self.proj = Proj(prefix=self.testdirprefix)
self.user = "llvm-developer"
path = os.path.join(self.proj.projdir, "origin")
create_dummy_repo(path)
self.origin = Clone(self.proj, path)
path = os.path.join(self.proj.projdir, "clone")
git("clone", "file://" + self.user + "@" + self.origin.repodir, path)
self.clone = Clone(self.proj, path)
self.worktreeBranch = "a-branch"
self.remoteBranch = "remotely/a-branch"
self.worktree = Worktree.create(
self.proj, self.clone, os.path.join(
self.proj.projdir, "worktree"), self.worktreeBranch)
def tearDown(self):
self.proj.cleanup()
def test_push_new_branch(self):
"""Test that we can push a new branch to origin."""
with cd(self.worktree.repodir):
create_dummy_commit("This should make it to origin")
push_branch(self.proj, self.worktreeBranch, self.remoteBranch,
self.worktree.repodir)
with cd(self.origin.repodir):
self.assertRegex(
get_last_commit_message(self.remoteBranch),
".*This should make it to origin")
def test_push_existing_branch(self):
"""Test that we can push to a branch that already exists in origin."""
with cd(self.worktree.repodir):
create_dummy_commit("This already exists in origin")
git("push", "origin", "{}:{}".format(
self.worktreeBranch, self.remoteBranch))
create_dummy_commit("This should make it to origin too")
push_branch(self.proj, self.worktreeBranch, self.remoteBranch,
self.worktree.repodir)
with cd(self.origin.repodir):
self.assertRegex(get_last_commit_message(self.remoteBranch),
".*This should make it to origin too")
def test_push_squashed_update(self):
"""
Test that we can push again after squashing some fixes into a commit
that has already been pushed to origin. This isn't a nice thing to do,
but we need to support it because Gerrit requires squashes.
"""
with cd(self.worktree.repodir):
create_dummy_commit("First version of the patch")
push_branch(self.proj, self.worktreeBranch, self.remoteBranch,
self.worktree.repodir)
with cd(self.origin.repodir):
self.assertRegex(
get_last_commit_message(self.remoteBranch),
".*First version of the patch")
with cd(self.worktree.repodir):
git("commit", "--amend", "-m", "Second version of the patch")
push_branch(self.proj, self.worktreeBranch, self.remoteBranch,
self.worktree.repodir)
with cd(self.origin.repodir):
self.assertRegex(
get_last_commit_message(self.remoteBranch),
"/*Second version of the patch")
def test_push_rebased_branch(self):
""" Test that we can push again with new updates after a rebase."""
with cd(self.worktree.repodir):
create_dummy_commit("First change")
push_branch(self.proj, self.worktreeBranch, self.remoteBranch,
self.worktree.repodir)
with cd(self.origin.repodir):
self.assertRegex(
get_last_commit_message(self.remoteBranch),
".*First change")
with cd(self.origin.repodir):
create_dummy_commit("Master moving forward")
with cd(self.worktree.repodir):
create_dummy_commit("Second change")
git("fetch", "origin", "master")
git("rebase", "origin/master")
push_branch(self.proj, self.worktreeBranch, self.remoteBranch,
self.worktree.repodir)
with cd(self.origin.repodir):
self.assertRegex(get_last_commit_message(self.remoteBranch),
".*Second change")
if __name__ == "__main__":
unittest.main()