blob: 0bcca666a3e7d8f71cb3386caa91bbf25a917b8b [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
Diana Picus9276b782018-01-24 14:40:46 +010018from llvmtestcase import LLVMTestCase, require_command_arg, debug
Diana Picusefc7bda2017-06-09 19:14:08 +020019
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
Diana Picus9276b782018-01-24 14:40:46 +010090 @require_command_arg("--source-dir")
Diana Picus9f756862017-12-20 10:35:08 +010091 def test_source_dir_ir_compulsory(self):
92 """Test that we get an error if we don't pass the source dir."""
Diana Picus9276b782018-01-24 14:40:46 +010093 self.run_with_output(self.llvm_push())
Diana Picus9f756862017-12-20 10:35:08 +010094
Diana Picusefc7bda2017-06-09 19:14:08 +020095 def test_push(self):
96 with cd(self.llvm_src):
97 self.create_dummy_commit("Test llvm push")
98
99 enabled = ["clang", "lld"]
100
101 for subproj in enabled:
102 worktreePath = os.path.join(self.llvm_src, "tools", subproj)
103 self.add_worktree(self.get_clone_path(subproj),
104 worktreePath,
105 self.branch)
106 with cd(worktreePath):
107 self.create_dummy_commit("Test {} push".format(subproj))
108
Diana Picus9f756862017-12-20 10:35:08 +0100109 pushed = self.run_with_output(
110 self.llvm_push("--source-dir", self.llvm_src))
Diana Picusefc7bda2017-06-09 19:14:08 +0200111 remote_branch = "linaro-local/{}/{}".format(self.user, self.branch)
112
Diana Picus95226d42017-11-01 13:16:54 +0100113 self.assertRegex(
114 pushed, "(.*\n)*Pushed to {}(.*\n)*".format(remote_branch))
115
Diana Picusefc7bda2017-06-09 19:14:08 +0200116 for subproj in self.all_repos:
117 origin = self.get_origin_path(subproj)
118
119 with cd(origin):
120 if subproj == "llvm" or subproj in enabled:
121 output = self.run_with_output(["git", "log", "--oneline",
122 "-1", remote_branch])
123
124 self.assertRegex(
125 output, ".*Test {} push.*".format(subproj))
126 else:
127 with self.assertRaises(subprocess.CalledProcessError) as context:
128 output = self.run_with_output(
129 ["git", "log", "--oneline", "-1", remote_branch])
130
131 self.assertRegex(
132 str(context.exception.output),
133 "(.*\n)*.*unknown revision or path not in the working tree(.*\n)*")
134
135 def test_push_mismatched_branches(self):
136 with cd(self.llvm_src):
137 self.create_dummy_commit("Test llvm push")
138
139 enabled = ["clang", "lld"]
140
141 for subproj in enabled:
142 branch = self.branch
143
144 # Move only lld to a different branch
145 if subproj == "lld":
146 branch = branch + "-different"
147
148 worktreePath = os.path.join(self.llvm_src, "tools", subproj)
149 self.add_worktree(self.get_clone_path(subproj),
150 worktreePath,
151 branch)
152 with cd(worktreePath):
153 self.create_dummy_commit("Test {} push".format(subproj))
154
155 with self.assertRaises(subprocess.CalledProcessError) as context:
Diana Picus9f756862017-12-20 10:35:08 +0100156 output = self.run_with_output(
157 self.llvm_push("--source-dir", self.llvm_src))
Diana Picusefc7bda2017-06-09 19:14:08 +0200158
159 # Check that we error out because lld is on a different branch
160 self.assertRegex(str(context.exception.output),
161 "(.*\n)*.*lld is on branch {}, but should be on {}".format(
162 self.branch + "-different", self.branch))
163
164 # Check that we haven't pushed llvm or clang either, even if they're on
165 # the same branch
166 remote_branch = "linaro-local/{}/{}".format(self.user, self.branch)
167
168 for subproj in ["llvm", "clang"]:
169 with cd(self.get_origin_path(subproj)):
170 with self.assertRaises(subprocess.CalledProcessError) as context:
171 self.run_with_output(["git", "log", "--oneline", "-1",
172 remote_branch])
173
174 self.assertRegex(
175 str(context.exception.output),
176 "(.*\n)*.*unknown revision or path not in the working tree(.*\n)*")