blob: 0bcca666a3e7d8f71cb3386caa91bbf25a917b8b [file] [log] [blame]
"""Command line interface tests for llvm.py push.
Note that although this uses the unittest framework, it does *not* contain unit
tests.
"""
import shutil
import os
import subprocess
import unittest
from tempfile import mkdtemp
from uuid import uuid4
from linaropy.cd import cd
from linaropy.git.clone import Clone
from llvmtestcase import LLVMTestCase, require_command_arg, debug
class Testllvmpush(LLVMTestCase):
@classmethod
def llvm_push(cls, *args, **kwargs):
return cls.command_with_defaults("push", *args, **kwargs)
@classmethod
def get_origin_path(cls, subproj):
return os.path.join(cls.origins, subproj)
@classmethod
def get_clone_path(cls, subproj):
return os.path.join(cls.repos, subproj)
@classmethod
def setUpClass(cls):
"""Create the file structure and environment for testing llvm push."""
cls.all_repos = ("llvm", "clang", "compiler-rt", "lld", "lldb",
"libcxx", "libcxxabi", "libunwind", "test-suite")
cls.origins = mkdtemp()
cls.repos = mkdtemp()
cls.llvm_root = mkdtemp()
cls.user = "llvm-developer"
# Create dummy repos - one origin that we will push to, and one clone
# that we will create worktrees from
for reponame in cls.all_repos:
origin = cls.get_origin_path(reponame)
cls.create_dummy_repo(origin)
clone = cls.get_clone_path(reponame)
cls.create_dummy_repo(
clone, "file://{}@{}".format(cls.user, origin))
@classmethod
def tearDownClass(cls):
shutil.rmtree(cls.origins)
shutil.rmtree(cls.repos)
@classmethod
def setUp(cls):
cls.env = os.path.join(cls.llvm_root, "env" + str(uuid4()))
cls.llvm_src = os.path.join(cls.env, "llvm")
# Create LLVM worktree
cls.branch = "br" + str(uuid4())
cls.add_worktree(cls.get_clone_path("llvm"), cls.llvm_src,
cls.branch)
@classmethod
def tearDown(cls):
# Clean up the directories where we might have added subprojects.
# This isn't 100% clean, because we don't clean up the repos between
# tests (so any branches will remain), but it's good enough for the
# current tests.
for subprojdir in (os.path.join(cls.llvm_src, "projects"),
os.path.join(cls.llvm_src, "tools")):
if os.path.isdir(subprojdir):
shutil.rmtree(subprojdir)
os.makedirs(subprojdir)
# Run prune on the original repos, to remove any dangling worktrees.
for reponame in cls.all_repos:
repopath = cls.get_clone_path(reponame)
with cd(repopath):
cls.run_quietly(["git", "worktree", "prune"])
@require_command_arg("--source-dir")
def test_source_dir_ir_compulsory(self):
"""Test that we get an error if we don't pass the source dir."""
self.run_with_output(self.llvm_push())
def test_push(self):
with cd(self.llvm_src):
self.create_dummy_commit("Test llvm push")
enabled = ["clang", "lld"]
for subproj in enabled:
worktreePath = os.path.join(self.llvm_src, "tools", subproj)
self.add_worktree(self.get_clone_path(subproj),
worktreePath,
self.branch)
with cd(worktreePath):
self.create_dummy_commit("Test {} push".format(subproj))
pushed = self.run_with_output(
self.llvm_push("--source-dir", self.llvm_src))
remote_branch = "linaro-local/{}/{}".format(self.user, self.branch)
self.assertRegex(
pushed, "(.*\n)*Pushed to {}(.*\n)*".format(remote_branch))
for subproj in self.all_repos:
origin = self.get_origin_path(subproj)
with cd(origin):
if subproj == "llvm" or subproj in enabled:
output = self.run_with_output(["git", "log", "--oneline",
"-1", remote_branch])
self.assertRegex(
output, ".*Test {} push.*".format(subproj))
else:
with self.assertRaises(subprocess.CalledProcessError) as context:
output = self.run_with_output(
["git", "log", "--oneline", "-1", remote_branch])
self.assertRegex(
str(context.exception.output),
"(.*\n)*.*unknown revision or path not in the working tree(.*\n)*")
def test_push_mismatched_branches(self):
with cd(self.llvm_src):
self.create_dummy_commit("Test llvm push")
enabled = ["clang", "lld"]
for subproj in enabled:
branch = self.branch
# Move only lld to a different branch
if subproj == "lld":
branch = branch + "-different"
worktreePath = os.path.join(self.llvm_src, "tools", subproj)
self.add_worktree(self.get_clone_path(subproj),
worktreePath,
branch)
with cd(worktreePath):
self.create_dummy_commit("Test {} push".format(subproj))
with self.assertRaises(subprocess.CalledProcessError) as context:
output = self.run_with_output(
self.llvm_push("--source-dir", self.llvm_src))
# Check that we error out because lld is on a different branch
self.assertRegex(str(context.exception.output),
"(.*\n)*.*lld is on branch {}, but should be on {}".format(
self.branch + "-different", self.branch))
# Check that we haven't pushed llvm or clang either, even if they're on
# the same branch
remote_branch = "linaro-local/{}/{}".format(self.user, self.branch)
for subproj in ["llvm", "clang"]:
with cd(self.get_origin_path(subproj)):
with self.assertRaises(subprocess.CalledProcessError) as context:
self.run_with_output(["git", "log", "--oneline", "-1",
remote_branch])
self.assertRegex(
str(context.exception.output),
"(.*\n)*.*unknown revision or path not in the working tree(.*\n)*")