blob: 1d9b8ab0ca942bc487c814f06bfb3804fd0ed5bb [file] [log] [blame]
Diana Picusefc7bda2017-06-09 19:14:08 +02001"""Command line interface tests for llvm.py push.
2
3Note that although this uses the unittest framework, it does *not* contain unit
4tests.
5
6"""
7
8import shutil
9import os
10import subprocess
11import unittest
12
13from tempfile import mkdtemp
14from uuid import uuid4
15
16from linaropy.cd import cd
17from linaropy.git.clone import Clone
18from llvmtestcase import LLVMTestCase, debug
19
20
21class Testllvmpush(LLVMTestCase):
22
23 @classmethod
24 def llvm_push(cls, *args, **kwargs):
25 return cls.command_with_defaults("push", *args, **kwargs)
26
27 @classmethod
28 def get_origin_path(cls, subproj):
29 return os.path.join(cls.origins, subproj)
30
31 @classmethod
32 def get_clone_path(cls, subproj):
33 return os.path.join(cls.repos, subproj)
34
35 @classmethod
36 def setUpClass(cls):
37 """Create the file structure and environment for testing llvm push."""
38 cls.all_repos = ("llvm", "clang", "compiler-rt", "lld", "lldb",
39 "libcxx", "libcxxabi", "libunwind", "test-suite")
40
41 cls.origins = mkdtemp()
42 cls.repos = mkdtemp()
43 cls.llvm_root = mkdtemp()
44
45 cls.user = "llvm-developer"
46
47 # Create dummy repos - one origin that we will push to, and one clone
48 # that we will create worktrees from
49 for reponame in cls.all_repos:
50 origin = cls.get_origin_path(reponame)
51 cls.create_dummy_repo(origin)
52
53 clone = cls.get_clone_path(reponame)
54 cls.create_dummy_repo(
55 clone, "file://{}@{}".format(cls.user, origin))
56
57 @classmethod
58 def tearDownClass(cls):
59 shutil.rmtree(cls.origins)
60 shutil.rmtree(cls.repos)
61
62 @classmethod
63 def setUp(cls):
64 cls.env = os.path.join(cls.llvm_root, "env" + str(uuid4()))
65 cls.llvm_src = os.path.join(cls.env, "llvm")
66
67 # Create LLVM worktree
68 cls.branch = "br" + str(uuid4())
69 cls.add_worktree(cls.get_clone_path("llvm"), cls.llvm_src,
70 cls.branch)
71
72 @classmethod
73 def tearDown(cls):
74 # Clean up the directories where we might have added subprojects.
75 # This isn't 100% clean, because we don't clean up the repos between
76 # tests (so any branches will remain), but it's good enough for the
77 # current tests.
78 for subprojdir in (os.path.join(cls.llvm_src, "projects"),
79 os.path.join(cls.llvm_src, "tools")):
80 if os.path.isdir(subprojdir):
81 shutil.rmtree(subprojdir)
82 os.makedirs(subprojdir)
83
84 # Run prune on the original repos, to remove any dangling worktrees.
85 for reponame in cls.all_repos:
86 repopath = cls.get_clone_path(reponame)
87 with cd(repopath):
88 cls.run_quietly(["git", "worktree", "prune"])
89
90 def test_push(self):
91 with cd(self.llvm_src):
92 self.create_dummy_commit("Test llvm push")
93
94 enabled = ["clang", "lld"]
95
96 for subproj in enabled:
97 worktreePath = os.path.join(self.llvm_src, "tools", subproj)
98 self.add_worktree(self.get_clone_path(subproj),
99 worktreePath,
100 self.branch)
101 with cd(worktreePath):
102 self.create_dummy_commit("Test {} push".format(subproj))
103
Diana Picus95226d42017-11-01 13:16:54 +0100104 pushed = self.run_with_output(self.llvm_push())
Diana Picusefc7bda2017-06-09 19:14:08 +0200105 remote_branch = "linaro-local/{}/{}".format(self.user, self.branch)
106
Diana Picus95226d42017-11-01 13:16:54 +0100107 self.assertRegex(
108 pushed, "(.*\n)*Pushed to {}(.*\n)*".format(remote_branch))
109
Diana Picusefc7bda2017-06-09 19:14:08 +0200110 for subproj in self.all_repos:
111 origin = self.get_origin_path(subproj)
112
113 with cd(origin):
114 if subproj == "llvm" or subproj in enabled:
115 output = self.run_with_output(["git", "log", "--oneline",
116 "-1", remote_branch])
117
118 self.assertRegex(
119 output, ".*Test {} push.*".format(subproj))
120 else:
121 with self.assertRaises(subprocess.CalledProcessError) as context:
122 output = self.run_with_output(
123 ["git", "log", "--oneline", "-1", remote_branch])
124
125 self.assertRegex(
126 str(context.exception.output),
127 "(.*\n)*.*unknown revision or path not in the working tree(.*\n)*")
128
129 def test_push_mismatched_branches(self):
130 with cd(self.llvm_src):
131 self.create_dummy_commit("Test llvm push")
132
133 enabled = ["clang", "lld"]
134
135 for subproj in enabled:
136 branch = self.branch
137
138 # Move only lld to a different branch
139 if subproj == "lld":
140 branch = branch + "-different"
141
142 worktreePath = os.path.join(self.llvm_src, "tools", subproj)
143 self.add_worktree(self.get_clone_path(subproj),
144 worktreePath,
145 branch)
146 with cd(worktreePath):
147 self.create_dummy_commit("Test {} push".format(subproj))
148
149 with self.assertRaises(subprocess.CalledProcessError) as context:
150 output = self.run_with_output(self.llvm_push())
151
152 # Check that we error out because lld is on a different branch
153 self.assertRegex(str(context.exception.output),
154 "(.*\n)*.*lld is on branch {}, but should be on {}".format(
155 self.branch + "-different", self.branch))
156
157 # Check that we haven't pushed llvm or clang either, even if they're on
158 # the same branch
159 remote_branch = "linaro-local/{}/{}".format(self.user, self.branch)
160
161 for subproj in ["llvm", "clang"]:
162 with cd(self.get_origin_path(subproj)):
163 with self.assertRaises(subprocess.CalledProcessError) as context:
164 self.run_with_output(["git", "log", "--oneline", "-1",
165 remote_branch])
166
167 self.assertRegex(
168 str(context.exception.output),
169 "(.*\n)*.*unknown revision or path not in the working tree(.*\n)*")