Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: tools/push-to-trunk/test_scripts.py

Issue 49653002: Add push-to-trunk python port. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2013 the V8 project authors. All rights reserved.
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
5 # met:
6 #
7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following
11 # disclaimer in the documentation and/or other materials provided
12 # with the distribution.
13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived
15 # from this software without specific prior written permission.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 import os
30 import tempfile
31 import unittest
32
33 import common_includes
34 from common_includes import *
35 import push_to_trunk
36 from push_to_trunk import *
37
38
39 TEST_CONFIG = {
40 BRANCHNAME: "test-prepare-push",
41 TRUNKBRANCH: "test-trunk-push",
42 PERSISTFILE_BASENAME: "/tmp/test-v8-push-to-trunk-tempfile",
43 TEMP_BRANCH: "test-prepare-push-temporary-branch-created-by-script",
44 DOT_GIT_LOCATION: None,
45 VERSION_FILE: None,
46 CHANGELOG_FILE: None,
47 CHANGELOG_ENTRY_FILE: "/tmp/test-v8-push-to-trunk-tempfile-changelog-entry",
48 PATCH_FILE: "/tmp/test-v8-push-to-trunk-tempfile-patch",
49 COMMITMSG_FILE: "/tmp/test-v8-push-to-trunk-tempfile-commitmsg",
50 CHROMIUM: "/tmp/test-v8-push-to-trunk-tempfile-chromium",
51 DEPS_FILE: "/tmp/test-v8-push-to-trunk-tempfile-chromium/DEPS",
52 }
53
54
55 class ScriptTest(unittest.TestCase):
56 def MakeEmptyTempFile(self):
57 handle, name = tempfile.mkstemp()
58 os.close(handle)
59 self._tmp_files.append(name)
60 return name
61
62 def MakeTempVersionFile(self):
63 name = self.MakeEmptyTempFile()
64 with open(name, "w") as f:
65 f.write(" // Some line...\n")
66 f.write("\n")
67 f.write("#define MAJOR_VERSION 3\n")
68 f.write("#define MINOR_VERSION 22\n")
69 f.write("#define BUILD_NUMBER 5\n")
70 f.write("#define PATCH_LEVEL 0\n")
71 return name
72
73 def MakeStep(self, step_class=Step, state=None):
74 state = state if state is not None else {}
Jakob Kummerow 2013/11/06 16:37:23 shorter: state = state or {}
Michael Achenbach 2013/11/07 15:56:46 It was like that because of a test that checked th
75 step = step_class()
76 step.SetConfig(TEST_CONFIG)
77 step.SetState(state)
78 step.SetNumber(0)
79 step.SetSideEffectHandler(self)
80 return step
81
82 def GitMock(self, cmd, args="", pipe=True):
83 self._git_index += 1
84 try:
85 git_invokation = self._git_recipe[self._git_index]
Jakob Kummerow 2013/11/06 16:37:23 nit: git_invocation
Michael Achenbach 2013/11/07 15:56:46 Done.
86 except IndexError:
87 raise Exception("Calling git %s" % args)
88 if git_invokation[0] != args:
89 raise Exception("Expected: %s - Actual: %s" % (git_invokation[0], args))
90 if len(git_invokation) == 3:
91 # Run optional function checking the context during this git command.
92 git_invokation[2]()
93 return git_invokation[1]
94
95 def LogMock(self, cmd, args=""):
96 print "Log: %s %s" % (cmd, args)
97
98 MOCKS = {
99 "git": GitMock,
100 "vi": LogMock,
101 }
102
103 def Command(self, cmd, args="", prefix="", pipe=True):
104 return ScriptTest.MOCKS[cmd](self, cmd, args)
105
106 def ReadLine(self):
107 self._rl_index += 1
108 try:
109 return self._rl_recipe[self._rl_index]
110 except IndexError:
111 raise Exception("Calling readline too often")
112
113 def setUp(self):
114 self._git_recipe = []
115 self._git_index = -1
116 self._rl_recipe = []
117 self._rl_index = -1
118 self._tmp_files = []
119
120 def tearDown(self):
121 Command("rm", "-rf %s*" % TEST_CONFIG[PERSISTFILE_BASENAME])
122
123 # Clean up temps. Doesn't work automatically.
124 for name in self._tmp_files:
125 if os.path.exists(name):
126 os.remove(name)
127
128 if self._git_index < len(self._git_recipe) -1:
129 raise Exception("Called git too seldom: %d vs. %d" % (self._git_index,
130 len(self._git_recipe)))
Jakob Kummerow 2013/11/06 16:37:23 nit: break after '%'
Michael Achenbach 2013/11/07 15:56:46 Done.
131 if self._rl_index < len(self._rl_recipe) -1:
132 raise Exception("Too little imput: %d vs. %d" % (self._rl_index,
Jakob Kummerow 2013/11/06 16:37:23 nit: s/imput/input/, break after '%'
Michael Achenbach 2013/11/07 15:56:46 Done.
133 len(self._rl_recipe)))
134
135 def testPersistRestore(self):
136 self.MakeStep().Persist("test1", "")
137 self.assertEquals("", self.MakeStep().Restore("test1"))
138 self.MakeStep().Persist("test2", "AB123")
139 self.assertEquals("AB123", self.MakeStep().Restore("test2"))
140
141 def testGitOrig(self):
142 self.assertTrue(Command("git", "--version").startswith("git version"))
143
144 def testGitMock(self):
145 self._git_recipe = [["--version", "git version 1.2.3"], ["dummy", ""]]
146 self.assertTrue(self.MakeStep().Git("--version").startswith("git version"))
Jakob Kummerow 2013/11/06 16:37:23 why not assertEquals(..., "git version 1.2.3")?
Michael Achenbach 2013/11/07 15:56:46 Done.
147 self.assertEquals("", self.MakeStep().Git("dummy"))
148
149 def testCommonPrepareDefault(self):
150 self._git_recipe = [
151 ["status -s -uno", ""],
152 ["status -s -b -uno", "## some_branch"],
153 ["svn fetch", ""],
154 ["branch", " branch1\n* %s" % TEST_CONFIG[TEMP_BRANCH]],
155 ["branch -D %s" % TEST_CONFIG[TEMP_BRANCH], ""],
156 ["checkout -b %s" % TEST_CONFIG[TEMP_BRANCH], ""],
157 ["branch", ""],
158 ]
159 self._rl_recipe = ["Y"]
160 self.MakeStep().CommonPrepare()
161 self.assertEquals("some_branch", self.MakeStep().Restore("current_branch"))
162
163 def testCommonPrepareNoConfirm(self):
164 self._git_recipe = [
165 ["status -s -uno", ""],
166 ["status -s -b -uno", "## some_branch"],
167 ["svn fetch", ""],
168 ["branch", " branch1\n* %s" % TEST_CONFIG[TEMP_BRANCH]],
169 ]
170 self._rl_recipe = ["n"]
171 self.assertRaises(Exception, self.MakeStep().CommonPrepare)
172 self.assertEquals("some_branch", self.MakeStep().Restore("current_branch"))
173
174 def testCommonPrepareDeleteBranchFailure(self):
175 self._git_recipe = [
176 ["status -s -uno", ""],
177 ["status -s -b -uno", "## some_branch"],
178 ["svn fetch", ""],
179 ["branch", " branch1\n* %s" % TEST_CONFIG[TEMP_BRANCH]],
180 ["branch -D %s" % TEST_CONFIG[TEMP_BRANCH], None],
181 ]
182 self._rl_recipe = ["Y"]
183 self.assertRaises(Exception, self.MakeStep().CommonPrepare)
184 self.assertEquals("some_branch", self.MakeStep().Restore("current_branch"))
185
186 def testInitialEnvironmentChecks(self):
187 TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile()
188 os.environ["EDITOR"] = "vi"
189 self.MakeStep().InitialEnvironmentChecks()
190
191 def testReadAndPersistVersion(self):
192 TEST_CONFIG[VERSION_FILE] = self.MakeTempVersionFile()
193 state = {}
194 self.MakeStep(state=state).ReadAndPersistVersion()
195 self.assertEquals("3", self.MakeStep().Restore("major"))
196 self.assertEquals("22", self.MakeStep().Restore("minor"))
197 self.assertEquals("5", self.MakeStep().Restore("build"))
198 self.assertEquals("0", self.MakeStep().Restore("patch"))
199 self.assertEquals("3", state["major"])
200 self.assertEquals("22", state["minor"])
201 self.assertEquals("5", state["build"])
202 self.assertEquals("0", state["patch"])
203
204 def testRegex(self):
Jakob Kummerow 2013/11/06 16:37:23 This is better than having no test for the regexes
Michael Achenbach 2013/11/07 15:56:46 This is rather a playground, where you can go back
205 self.assertEqual("issue 321",
206 re.sub(r"BUG=v8:(.*)$", r"issue \1", "BUG=v8:321"))
207 self.assertEqual("Chromium issue 321",
208 re.sub(r"BUG=(.*)$", r"Chromium issue \1", "BUG=321"))
209
210 cl = " too little\n\ttab\ttab\n too much\n trailing "
211 cl = MSub(r"\t", r" ", cl)
212 cl = MSub(r"^ {1,7}([^ ])", r" \1", cl)
213 cl = MSub(r"^ {9,80}([^ ])", r" \1", cl)
214 cl = MSub(r" +$", r"", cl)
215 self.assertEqual(" too little\n tab tab\n too "
Jakob Kummerow 2013/11/06 16:37:23 I'd break the line after every "\n" to make it obv
Michael Achenbach 2013/11/07 15:56:46 Done.
216 "much\n trailing", cl)
217
218 self.assertEqual("//\n#define BUILD_NUMBER 3\n",
219 MSub(r"(?<=#define BUILD_NUMBER)(?P<space>\s+)\d*$",
220 r"\g<space>3",
221 "//\n#define BUILD_NUMBER 321\n"))
222
223 def testPrepareChangeLog(self):
224 TEST_CONFIG[VERSION_FILE] = self.MakeTempVersionFile()
225 TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile()
226
227 self._git_recipe = [
228 ["log 1234..HEAD --format=%H", "rev1\nrev2"],
229 ["log -1 rev1 --format=\"%w(80,8,8)%s\"", " Title text 1"],
230 ["log -1 rev1 --format=\"%B\"", "Title\n\nBUG=\n"],
231 ["log -1 rev1 --format=\"%w(80,8,8)(%an)\"",
232 " author1@chromium.org"],
233 ["log -1 rev2 --format=\"%w(80,8,8)%s\"", " Title text 2"],
234 ["log -1 rev2 --format=\"%B\"", "Title\n\nBUG=321\n"],
235 ["log -1 rev2 --format=\"%w(80,8,8)(%an)\"",
236 " author2@chromium.org"],
237 ]
238
239 self.MakeStep().Persist("last_push", "1234")
240 self.MakeStep(PrepareChangeLog).Run()
241
242 cl = FileToText(TEST_CONFIG[CHANGELOG_ENTRY_FILE])
243 self.assertTrue(re.search(r"\d+\-\d+\-\d+: Version 3\.22\.5", cl))
244 self.assertTrue(re.search(r" Title text 1", cl))
245 self.assertTrue(re.search(r" Title text 2", cl))
246 self.assertTrue(re.search(r" author1@chromium.org", cl))
247 self.assertTrue(re.search(r" author2@chromium.org", cl))
248 self.assertTrue(re.search(r" Chromium issue 321", cl))
249 self.assertFalse(re.search(r"BUG=", cl))
250 self.assertEquals("3", self.MakeStep().Restore("major"))
251 self.assertEquals("22", self.MakeStep().Restore("minor"))
252 self.assertEquals("5", self.MakeStep().Restore("build"))
253 self.assertEquals("0", self.MakeStep().Restore("patch"))
254
255 def testEditChangeLog(self):
256 TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile()
257 TEST_CONFIG[CHANGELOG_FILE] = self.MakeEmptyTempFile()
258 TextToFile(" Original CL", TEST_CONFIG[CHANGELOG_FILE])
259 TextToFile(" New \n\tLines \n", TEST_CONFIG[CHANGELOG_ENTRY_FILE])
260 os.environ["EDITOR"] = "vi"
261
262 self._rl_recipe = [
263 "", # Open editor.
264 ]
265
266 self.MakeStep(EditChangeLog).Run()
267
268 self.assertEquals(" New\n Lines\n\n\n Original CL",
269 FileToText(TEST_CONFIG[CHANGELOG_FILE]))
270
271 def testIncrementVersion(self):
272 TEST_CONFIG[VERSION_FILE] = self.MakeTempVersionFile()
273 self.MakeStep().Persist("build", "5")
274
275 self._rl_recipe = [
276 "Y", # Increment build number.
277 ]
278
279 self.MakeStep(IncrementVersion).Run()
280
281 self.assertEquals("3", self.MakeStep().Restore("new_major"))
282 self.assertEquals("22", self.MakeStep().Restore("new_minor"))
283 self.assertEquals("6", self.MakeStep().Restore("new_build"))
284 self.assertEquals("0", self.MakeStep().Restore("new_patch"))
285
286 def testSquashCommits(self):
287 TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile()
288 with open(TEST_CONFIG[CHANGELOG_ENTRY_FILE], "w") as f:
289 f.write("1999-11-11: Version 3.22.5\n")
290 f.write("\n")
291 f.write(" Log text 1.\n")
292 f.write(" Chromium issue 12345\n")
293 f.write("\n")
294 f.write(" Performance and stability improvements on all "
295 "platforms.\n")
296
297 self._git_recipe = [
298 ["diff svn/trunk hash1", "patch content"],
299 ]
300
301 self.MakeStep().Persist("prepare_commit_hash", "hash1")
302 self.MakeStep().Persist("date", "1999-11-11")
303
304 self.MakeStep(SquashCommits).Run()
305
306 msg = FileToText(TEST_CONFIG[COMMITMSG_FILE])
307 self.assertTrue(re.search(r"Version 3\.22\.5", msg))
308 self.assertTrue(re.search(r"Performance and stability", msg))
309 self.assertTrue(re.search(r"Log text 1\. Chromium issue 12345", msg))
310 self.assertFalse(re.search(r"\d+\-\d+\-\d+", msg))
311
312 patch = FileToText(TEST_CONFIG[ PATCH_FILE])
313 self.assertTrue(re.search(r"patch content", patch))
314
315 def testPushToTrunk(self):
316 TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile()
317 TEST_CONFIG[VERSION_FILE] = self.MakeTempVersionFile()
318 TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile()
319 TEST_CONFIG[CHANGELOG_FILE] = self.MakeEmptyTempFile()
320 if not os.path.exists(TEST_CONFIG[CHROMIUM]):
321 os.makedirs(TEST_CONFIG[CHROMIUM])
322 TextToFile("1999-04-05: Version 3.22.4", TEST_CONFIG[CHANGELOG_FILE])
323 TextToFile("Some line\n \"v8_revision\": 123444,\n some line",
324 TEST_CONFIG[DEPS_FILE])
325 os.environ["EDITOR"] = "vi"
326
327 def CheckVersionIncrement():
328 version = FileToText(TEST_CONFIG[VERSION_FILE])
329 self.assertTrue(re.search(r"#define BUILD_NUMBER\s+6", version))
330
331 def CheckCommitMsg():
332 version = FileToText(TEST_CONFIG[COMMITMSG_FILE])
333 self.assertTrue(re.search(r"Version 3.22.5", version))
334 self.assertTrue(re.search(r"Log text 1. issue 321", version))
335
336 self._git_recipe = [
337 ["status -s -uno", ""],
338 ["status -s -b -uno", "## some_branch\n"],
339 ["svn fetch", ""],
340 ["branch", " branch1\n* branch2\n"],
341 ["checkout -b %s" % TEST_CONFIG[TEMP_BRANCH], ""],
342 ["branch", " branch1\n* branch2\n"],
343 ["branch", " branch1\n* branch2\n"],
344 ["checkout -b %s svn/bleeding_edge" % TEST_CONFIG[BRANCHNAME], ""],
345 ["log -1 --format=%H ChangeLog", "1234\n"],
346 ["log -1 1234", "Last push ouput\n"],
347 ["log 1234..HEAD --format=%H", "rev1\n"],
348 ["log -1 rev1 --format=\"%w(80,8,8)%s\"", " Log text 1.\n"],
349 ["log -1 rev1 --format=\"%B\"", "Text\nBUG=v8:321\nText\n"],
350 ["log -1 rev1 --format=\"%w(80,8,8)(%an)\"",
351 " author1@chromium.org\n"],
352 [("commit -a -m \"Prepare push to trunk. "
353 "Now working on version 3.22.6.\""),
354 " 2 files changed\n",
355 CheckVersionIncrement],
356 ["cl upload -r \"reviewer@chromium.org\" --send-mail", "done\n"],
357 ["cl dcommit", "Closing issue\n"],
358 ["svn fetch", "fetch result\n"],
359 ["checkout svn/bleeding_edge", ""],
360 [("log -1 --format=%H --grep=\"Prepare push to trunk. "
361 "Now working on version 3.22.6.\""),
362 "hash1\n"],
363 ["diff svn/trunk hash1", "patch content\n"],
364 ["checkout -b %s svn/trunk" % TEST_CONFIG[TRUNKBRANCH], ""],
365 ["apply --index --reject \"%s\"" % TEST_CONFIG[PATCH_FILE], ""],
366 ["add \"%s\"" % TEST_CONFIG[VERSION_FILE], ""],
367 ["commit -F \"%s\"" % TEST_CONFIG[COMMITMSG_FILE], "", CheckCommitMsg],
368 ["svn dcommit 2>&1", "Some output\nCommitted r123456\nSome output\n"],
369 ["svn tag 3.22.5 -m \"Tagging version 3.22.5\"", ""],
370 ["status -s -uno", ""],
371 ["checkout master", ""],
372 ["pull", ""],
373 ["checkout -b \"v8-roll-123456\"", ""],
374 [("commit -am \"Update V8 to version 3.22.5.\n\n"
375 "TBR=reviewer@chromium.org\""),
376 ""],
377 ["cl upload --send-mail", ""],
378 ["checkout -f some_branch", ""],
379 ["branch -D %s" % TEST_CONFIG[TEMP_BRANCH], ""],
380 ["branch -D %s" % TEST_CONFIG[BRANCHNAME], ""],
381 ["branch -D %s" % TEST_CONFIG[TRUNKBRANCH], ""],
382 ]
383 self._rl_recipe = [
384 "Y", # Confirm last push.
385 "", # Open editor.
386 "Y", # Increment build number.
387 "reviewer@chromium.org", # V8 reviewer.
388 "LGTX", # Enter LGTM for V8 CL (wrong).
389 "LGTM", # Enter LGTM for V8 CL.
390 "Y", # Sanity check.
391 "reviewer@chromium.org", # Chromium reviewer.
392 ]
393
394 class Options( object ):
395 pass
396
397 options = Options()
398 options.s = 0
399 options.l = None
400 options.c = TEST_CONFIG[CHROMIUM]
401 RunScript(TEST_CONFIG, options, self)
402
403 deps = FileToText(TEST_CONFIG[DEPS_FILE])
404 self.assertTrue(re.search("\"v8_revision\": 123456", deps))
405
406 cl = FileToText(TEST_CONFIG[CHANGELOG_FILE])
407 self.assertTrue(re.search(r"\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl))
408 self.assertTrue(re.search(r" Log text 1", cl))
409 self.assertTrue(re.search(r" issue 321", cl))
410 self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl))
411
412 # Note: The version file is on build number 5 again in the end of this test
413 # since the git command that merges to the bleeding edge branch is mocked
414 # out.
OLDNEW
« tools/push-to-trunk/push_to_trunk.py ('K') | « tools/push-to-trunk/push_to_trunk.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698