blob: db702a3ae147ab0dd4febc1696bc764af20941d1 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001#!/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
29import os
30import shutil
31import tempfile
32import traceback
33import unittest
34
35import auto_push
36from auto_push import CheckLastPush
37import auto_roll
38import common_includes
39from common_includes import *
40import merge_to_branch
41from merge_to_branch import *
42import push_to_trunk
43from push_to_trunk import *
44import chromium_roll
45from chromium_roll import ChromiumRoll
46import releases
47from releases import Releases
48import bump_up_version
49from bump_up_version import BumpUpVersion
50from bump_up_version import LastChangeBailout
51from bump_up_version import LKGRVersionUpToDateBailout
52from auto_tag import AutoTag
53
54
55TEST_CONFIG = {
56 "DEFAULT_CWD": None,
57 "BRANCHNAME": "test-prepare-push",
58 "TRUNKBRANCH": "test-trunk-push",
59 "PERSISTFILE_BASENAME": "/tmp/test-v8-push-to-trunk-tempfile",
Ben Murdochb8a8cc12014-11-26 15:28:44 +000060 "CHANGELOG_ENTRY_FILE": "/tmp/test-v8-push-to-trunk-tempfile-changelog-entry",
61 "PATCH_FILE": "/tmp/test-v8-push-to-trunk-tempfile-patch",
62 "COMMITMSG_FILE": "/tmp/test-v8-push-to-trunk-tempfile-commitmsg",
63 "CHROMIUM": "/tmp/test-v8-push-to-trunk-tempfile-chromium",
64 "SETTINGS_LOCATION": None,
65 "ALREADY_MERGING_SENTINEL_FILE":
66 "/tmp/test-merge-to-branch-tempfile-already-merging",
67 "TEMPORARY_PATCH_FILE": "/tmp/test-merge-to-branch-tempfile-temporary-patch",
68 "CLUSTERFUZZ_API_KEY_FILE": "/tmp/test-fake-cf-api-key",
69}
70
71
72AUTO_PUSH_ARGS = [
73 "-a", "author@chromium.org",
74 "-r", "reviewer@chromium.org",
75]
76
77
78class ToplevelTest(unittest.TestCase):
79 def testSortBranches(self):
80 S = releases.SortBranches
81 self.assertEquals(["3.1", "2.25"], S(["2.25", "3.1"])[0:2])
82 self.assertEquals(["3.0", "2.25"], S(["2.25", "3.0", "2.24"])[0:2])
83 self.assertEquals(["3.11", "3.2"], S(["3.11", "3.2", "2.24"])[0:2])
84
85 def testFilterDuplicatesAndReverse(self):
86 F = releases.FilterDuplicatesAndReverse
87 self.assertEquals([], F([]))
88 self.assertEquals([["100", "10"]], F([["100", "10"]]))
89 self.assertEquals([["99", "9"], ["100", "10"]],
90 F([["100", "10"], ["99", "9"]]))
91 self.assertEquals([["98", "9"], ["100", "10"]],
92 F([["100", "10"], ["99", "9"], ["98", "9"]]))
93 self.assertEquals([["98", "9"], ["99", "10"]],
94 F([["100", "10"], ["99", "10"], ["98", "9"]]))
95
96 def testBuildRevisionRanges(self):
97 B = releases.BuildRevisionRanges
98 self.assertEquals({}, B([]))
99 self.assertEquals({"10": "100"}, B([["100", "10"]]))
100 self.assertEquals({"10": "100", "9": "99:99"},
101 B([["100", "10"], ["99", "9"]]))
102 self.assertEquals({"10": "100", "9": "97:99"},
103 B([["100", "10"], ["98", "9"], ["97", "9"]]))
104 self.assertEquals({"10": "100", "9": "99:99", "3": "91:98"},
105 B([["100", "10"], ["99", "9"], ["91", "3"]]))
106 self.assertEquals({"13": "101", "12": "100:100", "9": "94:97",
107 "3": "91:93, 98:99"},
108 B([["101", "13"], ["100", "12"], ["98", "3"],
109 ["94", "9"], ["91", "3"]]))
110
111 def testMakeComment(self):
112 self.assertEquals("# Line 1\n# Line 2\n#",
113 MakeComment(" Line 1\n Line 2\n"))
114 self.assertEquals("#Line 1\n#Line 2",
115 MakeComment("Line 1\n Line 2"))
116
117 def testStripComments(self):
118 self.assertEquals(" Line 1\n Line 3\n",
119 StripComments(" Line 1\n# Line 2\n Line 3\n#\n"))
120 self.assertEquals("\nLine 2 ### Test\n #",
121 StripComments("###\n# \n\n# Line 1\nLine 2 ### Test\n #"))
122
123 def testMakeChangeLogBodySimple(self):
124 commits = [
125 ["Title text 1",
126 "Title text 1\n\nBUG=\n",
127 "author1@chromium.org"],
128 ["Title text 2.",
129 "Title text 2\n\nBUG=1234\n",
130 "author2@chromium.org"],
131 ]
132 self.assertEquals(" Title text 1.\n"
133 " (author1@chromium.org)\n\n"
134 " Title text 2 (Chromium issue 1234).\n"
135 " (author2@chromium.org)\n\n",
136 MakeChangeLogBody(commits))
137
138 def testMakeChangeLogBodyEmpty(self):
139 self.assertEquals("", MakeChangeLogBody([]))
140
141 def testMakeChangeLogBodyAutoFormat(self):
142 commits = [
143 ["Title text 1!",
144 "Title text 1\nLOG=y\nBUG=\n",
145 "author1@chromium.org"],
146 ["Title text 2",
147 "Title text 2\n\nBUG=1234\n",
148 "author2@chromium.org"],
149 ["Title text 3",
150 "Title text 3\n\nBUG=1234\nLOG = Yes\n",
151 "author3@chromium.org"],
152 ["Title text 3",
153 "Title text 4\n\nBUG=1234\nLOG=\n",
154 "author4@chromium.org"],
155 ]
156 self.assertEquals(" Title text 1.\n\n"
157 " Title text 3 (Chromium issue 1234).\n\n",
158 MakeChangeLogBody(commits, True))
159
160 def testRegressWrongLogEntryOnTrue(self):
161 body = """
162Check elimination: Learn from if(CompareMap(x)) on true branch.
163
164BUG=
165R=verwaest@chromium.org
166
167Committed: https://code.google.com/p/v8/source/detail?r=18210
168"""
169 self.assertEquals("", MakeChangeLogBody([["title", body, "author"]], True))
170
171 def testMakeChangeLogBugReferenceEmpty(self):
172 self.assertEquals("", MakeChangeLogBugReference(""))
173 self.assertEquals("", MakeChangeLogBugReference("LOG="))
174 self.assertEquals("", MakeChangeLogBugReference(" BUG ="))
175 self.assertEquals("", MakeChangeLogBugReference("BUG=none\t"))
176
177 def testMakeChangeLogBugReferenceSimple(self):
178 self.assertEquals("(issue 987654)",
179 MakeChangeLogBugReference("BUG = v8:987654"))
180 self.assertEquals("(Chromium issue 987654)",
181 MakeChangeLogBugReference("BUG=987654 "))
182
183 def testMakeChangeLogBugReferenceFromBody(self):
184 self.assertEquals("(Chromium issue 1234567)",
185 MakeChangeLogBugReference("Title\n\nTBR=\nBUG=\n"
186 " BUG=\tchromium:1234567\t\n"
187 "R=somebody\n"))
188
189 def testMakeChangeLogBugReferenceMultiple(self):
190 # All issues should be sorted and grouped. Multiple references to the same
191 # issue should be filtered.
192 self.assertEquals("(issues 123, 234, Chromium issue 345)",
193 MakeChangeLogBugReference("Title\n\n"
194 "BUG=v8:234\n"
195 " BUG\t= 345, \tv8:234,\n"
196 "BUG=v8:123\n"
197 "R=somebody\n"))
198 self.assertEquals("(Chromium issues 123, 234)",
199 MakeChangeLogBugReference("Title\n\n"
200 "BUG=234,,chromium:123 \n"
201 "R=somebody\n"))
202 self.assertEquals("(Chromium issues 123, 234)",
203 MakeChangeLogBugReference("Title\n\n"
204 "BUG=chromium:234, , 123\n"
205 "R=somebody\n"))
206 self.assertEquals("(issues 345, 456)",
207 MakeChangeLogBugReference("Title\n\n"
208 "\t\tBUG=v8:345,v8:456\n"
209 "R=somebody\n"))
210 self.assertEquals("(issue 123, Chromium issues 345, 456)",
211 MakeChangeLogBugReference("Title\n\n"
212 "BUG=chromium:456\n"
213 "BUG = none\n"
214 "R=somebody\n"
215 "BUG=456,v8:123, 345"))
216
217 # TODO(machenbach): These test don't make much sense when the formatting is
218 # done later.
219 def testMakeChangeLogBugReferenceLong(self):
220 # -----------------00--------10--------20--------30--------
221 self.assertEquals("(issues 234, 1234567890, 1234567"
222 "8901234567890, Chromium issues 12345678,"
223 " 123456789)",
224 MakeChangeLogBugReference("BUG=v8:234\n"
225 "BUG=v8:1234567890\n"
226 "BUG=v8:12345678901234567890\n"
227 "BUG=123456789\n"
228 "BUG=12345678\n"))
229 # -----------------00--------10--------20--------30--------
230 self.assertEquals("(issues 234, 1234567890, 1234567"
231 "8901234567890, Chromium issues"
232 " 123456789, 1234567890)",
233 MakeChangeLogBugReference("BUG=v8:234\n"
234 "BUG=v8:12345678901234567890\n"
235 "BUG=v8:1234567890\n"
236 "BUG=123456789\n"
237 "BUG=1234567890\n"))
238 # -----------------00--------10--------20--------30--------
239 self.assertEquals("(Chromium issues 234, 1234567890"
240 ", 12345678901234567, "
241 "1234567890123456789)",
242 MakeChangeLogBugReference("BUG=234\n"
243 "BUG=12345678901234567\n"
244 "BUG=1234567890123456789\n"
245 "BUG=1234567890\n"))
246
247
248def Cmd(*args, **kwargs):
249 """Convenience function returning a shell command test expectation."""
250 return {
251 "name": "command",
252 "args": args,
253 "ret": args[-1],
254 "cb": kwargs.get("cb"),
255 "cwd": kwargs.get("cwd", TEST_CONFIG["DEFAULT_CWD"]),
256 }
257
258
259def RL(text, cb=None):
260 """Convenience function returning a readline test expectation."""
261 return {
262 "name": "readline",
263 "args": [],
264 "ret": text,
265 "cb": cb,
266 "cwd": None,
267 }
268
269
270def URL(*args, **kwargs):
271 """Convenience function returning a readurl test expectation."""
272 return {
273 "name": "readurl",
274 "args": args[:-1],
275 "ret": args[-1],
276 "cb": kwargs.get("cb"),
277 "cwd": None,
278 }
279
280
281class SimpleMock(object):
282 def __init__(self):
283 self._recipe = []
284 self._index = -1
285
286 def Expect(self, recipe):
287 self._recipe = recipe
288
289 def Call(self, name, *args, **kwargs): # pragma: no cover
290 self._index += 1
291 try:
292 expected_call = self._recipe[self._index]
293 except IndexError:
294 raise NoRetryException("Calling %s %s" % (name, " ".join(args)))
295
296 if not isinstance(expected_call, dict):
297 raise NoRetryException("Found wrong expectation type for %s %s" %
298 (name, " ".join(args)))
299
300 if expected_call["name"] != name:
301 raise NoRetryException("Expected action: %s %s - Actual: %s" %
302 (expected_call["name"], expected_call["args"], name))
303
304 # Check if the given working directory matches the expected one.
305 if expected_call["cwd"] != kwargs.get("cwd"):
306 raise NoRetryException("Expected cwd: %s in %s %s - Actual: %s" %
307 (expected_call["cwd"],
308 expected_call["name"],
309 expected_call["args"],
310 kwargs.get("cwd")))
311
312 # The number of arguments in the expectation must match the actual
313 # arguments.
314 if len(args) > len(expected_call['args']):
315 raise NoRetryException("When calling %s with arguments, the "
316 "expectations must consist of at least as many arguments." %
317 name)
318
319 # Compare expected and actual arguments.
320 for (expected_arg, actual_arg) in zip(expected_call['args'], args):
321 if expected_arg != actual_arg:
322 raise NoRetryException("Expected: %s - Actual: %s" %
323 (expected_arg, actual_arg))
324
325 # The expected call contains an optional callback for checking the context
326 # at the time of the call.
327 if expected_call['cb']:
328 try:
329 expected_call['cb']()
330 except:
331 tb = traceback.format_exc()
332 raise NoRetryException("Caught exception from callback: %s" % tb)
333
334 # If the return value is an exception, raise it instead of returning.
335 if isinstance(expected_call['ret'], Exception):
336 raise expected_call['ret']
337 return expected_call['ret']
338
339 def AssertFinished(self): # pragma: no cover
340 if self._index < len(self._recipe) -1:
341 raise NoRetryException("Called mock too seldom: %d vs. %d" %
342 (self._index, len(self._recipe)))
343
344
345class ScriptTest(unittest.TestCase):
346 def MakeEmptyTempFile(self):
347 handle, name = tempfile.mkstemp()
348 os.close(handle)
349 self._tmp_files.append(name)
350 return name
351
352 def MakeEmptyTempDirectory(self):
353 name = tempfile.mkdtemp()
354 self._tmp_files.append(name)
355 return name
356
357
358 def WriteFakeVersionFile(self, minor=22, build=4, patch=0):
359 version_file = os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE)
360 if not os.path.exists(os.path.dirname(version_file)):
361 os.makedirs(os.path.dirname(version_file))
362 with open(version_file, "w") as f:
363 f.write(" // Some line...\n")
364 f.write("\n")
365 f.write("#define MAJOR_VERSION 3\n")
366 f.write("#define MINOR_VERSION %s\n" % minor)
367 f.write("#define BUILD_NUMBER %s\n" % build)
368 f.write("#define PATCH_LEVEL %s\n" % patch)
369 f.write(" // Some line...\n")
370 f.write("#define IS_CANDIDATE_VERSION 0\n")
371
372 def MakeStep(self):
373 """Convenience wrapper."""
374 options = ScriptsBase(TEST_CONFIG, self, self._state).MakeOptions([])
375 return MakeStep(step_class=Step, state=self._state,
376 config=TEST_CONFIG, side_effect_handler=self,
377 options=options)
378
379 def RunStep(self, script=PushToTrunk, step_class=Step, args=None):
380 """Convenience wrapper."""
381 args = args if args is not None else ["-m"]
382 return script(TEST_CONFIG, self, self._state).RunSteps([step_class], args)
383
384 def Call(self, fun, *args, **kwargs):
385 print "Calling %s with %s and %s" % (str(fun), str(args), str(kwargs))
386
387 def Command(self, cmd, args="", prefix="", pipe=True, cwd=None):
388 print "%s %s" % (cmd, args)
389 print "in %s" % cwd
390 return self._mock.Call("command", cmd + " " + args, cwd=cwd)
391
392 def ReadLine(self):
393 return self._mock.Call("readline")
394
395 def ReadURL(self, url, params):
396 if params is not None:
397 return self._mock.Call("readurl", url, params)
398 else:
399 return self._mock.Call("readurl", url)
400
401 def ReadClusterFuzzAPI(self, api_key, **params):
402 # TODO(machenbach): Use a mock for this and add a test that stops rolling
403 # due to clustefuzz results.
404 return []
405
406 def Sleep(self, seconds):
407 pass
408
409 def GetDate(self):
410 return "1999-07-31"
411
412 def GetUTCStamp(self):
413 return "100000"
414
415 def Expect(self, *args):
416 """Convenience wrapper."""
417 self._mock.Expect(*args)
418
419 def setUp(self):
420 self._mock = SimpleMock()
421 self._tmp_files = []
422 self._state = {}
423 TEST_CONFIG["DEFAULT_CWD"] = self.MakeEmptyTempDirectory()
424
425 def tearDown(self):
426 if os.path.exists(TEST_CONFIG["PERSISTFILE_BASENAME"]):
427 shutil.rmtree(TEST_CONFIG["PERSISTFILE_BASENAME"])
428
429 # Clean up temps. Doesn't work automatically.
430 for name in self._tmp_files:
431 if os.path.isfile(name):
432 os.remove(name)
433 if os.path.isdir(name):
434 shutil.rmtree(name)
435
436 self._mock.AssertFinished()
437
438 def testGitMock(self):
439 self.Expect([Cmd("git --version", "git version 1.2.3"),
440 Cmd("git dummy", "")])
441 self.assertEquals("git version 1.2.3", self.MakeStep().Git("--version"))
442 self.assertEquals("", self.MakeStep().Git("dummy"))
443
444 def testCommonPrepareDefault(self):
445 self.Expect([
446 Cmd("git status -s -uno", ""),
447 Cmd("git status -s -b -uno", "## some_branch"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400448 Cmd("git fetch", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000449 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
450 RL("Y"),
451 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
452 ])
453 self.MakeStep().CommonPrepare()
454 self.MakeStep().PrepareBranch()
455 self.assertEquals("some_branch", self._state["current_branch"])
456
457 def testCommonPrepareNoConfirm(self):
458 self.Expect([
459 Cmd("git status -s -uno", ""),
460 Cmd("git status -s -b -uno", "## some_branch"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400461 Cmd("git fetch", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000462 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
463 RL("n"),
464 ])
465 self.MakeStep().CommonPrepare()
466 self.assertRaises(Exception, self.MakeStep().PrepareBranch)
467 self.assertEquals("some_branch", self._state["current_branch"])
468
469 def testCommonPrepareDeleteBranchFailure(self):
470 self.Expect([
471 Cmd("git status -s -uno", ""),
472 Cmd("git status -s -b -uno", "## some_branch"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400473 Cmd("git fetch", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000474 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
475 RL("Y"),
476 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], None),
477 ])
478 self.MakeStep().CommonPrepare()
479 self.assertRaises(Exception, self.MakeStep().PrepareBranch)
480 self.assertEquals("some_branch", self._state["current_branch"])
481
482 def testInitialEnvironmentChecks(self):
483 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
484 os.environ["EDITOR"] = "vi"
485 self.Expect([
486 Cmd("which vi", "/usr/bin/vi"),
487 ])
488 self.MakeStep().InitialEnvironmentChecks(TEST_CONFIG["DEFAULT_CWD"])
489
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400490 def testTagTimeout(self):
491 self.Expect([
492 Cmd("git fetch", ""),
493 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
494 Cmd("git fetch", ""),
495 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
496 Cmd("git fetch", ""),
497 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
498 Cmd("git fetch", ""),
499 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
500 ])
501 args = ["--branch", "candidates", "ab12345"]
502 self._state["version"] = "tag_name"
503 self._state["commit_title"] = "Title"
504 self.assertRaises(Exception,
505 lambda: self.RunStep(MergeToBranch, TagRevision, args))
506
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000507 def testReadAndPersistVersion(self):
508 self.WriteFakeVersionFile(build=5)
509 step = self.MakeStep()
510 step.ReadAndPersistVersion()
511 self.assertEquals("3", step["major"])
512 self.assertEquals("22", step["minor"])
513 self.assertEquals("5", step["build"])
514 self.assertEquals("0", step["patch"])
515
516 def testRegex(self):
517 self.assertEqual("(issue 321)",
518 re.sub(r"BUG=v8:(.*)$", r"(issue \1)", "BUG=v8:321"))
519 self.assertEqual("(Chromium issue 321)",
520 re.sub(r"BUG=(.*)$", r"(Chromium issue \1)", "BUG=321"))
521
522 cl = " too little\n\ttab\ttab\n too much\n trailing "
523 cl = MSub(r"\t", r" ", cl)
524 cl = MSub(r"^ {1,7}([^ ])", r" \1", cl)
525 cl = MSub(r"^ {9,80}([^ ])", r" \1", cl)
526 cl = MSub(r" +$", r"", cl)
527 self.assertEqual(" too little\n"
528 " tab tab\n"
529 " too much\n"
530 " trailing", cl)
531
532 self.assertEqual("//\n#define BUILD_NUMBER 3\n",
533 MSub(r"(?<=#define BUILD_NUMBER)(?P<space>\s+)\d*$",
534 r"\g<space>3",
535 "//\n#define BUILD_NUMBER 321\n"))
536
537 def testPreparePushRevision(self):
538 # Tests the default push hash used when the --revision option is not set.
539 self.Expect([
540 Cmd("git log -1 --format=%H HEAD", "push_hash")
541 ])
542
543 self.RunStep(PushToTrunk, PreparePushRevision)
544 self.assertEquals("push_hash", self._state["push_hash"])
545
546 def testPrepareChangeLog(self):
547 self.WriteFakeVersionFile()
548 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
549
550 self.Expect([
551 Cmd("git log --format=%H 1234..push_hash", "rev1\nrev2\nrev3\nrev4"),
552 Cmd("git log -1 --format=%s rev1", "Title text 1"),
553 Cmd("git log -1 --format=%B rev1", "Title\n\nBUG=\nLOG=y\n"),
554 Cmd("git log -1 --format=%an rev1", "author1@chromium.org"),
555 Cmd("git log -1 --format=%s rev2", "Title text 2."),
556 Cmd("git log -1 --format=%B rev2", "Title\n\nBUG=123\nLOG= \n"),
557 Cmd("git log -1 --format=%an rev2", "author2@chromium.org"),
558 Cmd("git log -1 --format=%s rev3", "Title text 3"),
559 Cmd("git log -1 --format=%B rev3", "Title\n\nBUG=321\nLOG=true\n"),
560 Cmd("git log -1 --format=%an rev3", "author3@chromium.org"),
561 Cmd("git log -1 --format=%s rev4", "Title text 4"),
562 Cmd("git log -1 --format=%B rev4",
563 ("Title\n\nBUG=456\nLOG=Y\n\n"
564 "Review URL: https://codereview.chromium.org/9876543210\n")),
565 URL("https://codereview.chromium.org/9876543210/description",
566 "Title\n\nBUG=456\nLOG=N\n\n"),
567 Cmd("git log -1 --format=%an rev4", "author4@chromium.org"),
568 ])
569
570 self._state["last_push_bleeding_edge"] = "1234"
571 self._state["push_hash"] = "push_hash"
572 self._state["version"] = "3.22.5"
573 self.RunStep(PushToTrunk, PrepareChangeLog)
574
575 actual_cl = FileToText(TEST_CONFIG["CHANGELOG_ENTRY_FILE"])
576
577 expected_cl = """1999-07-31: Version 3.22.5
578
579 Title text 1.
580
581 Title text 3 (Chromium issue 321).
582
583 Performance and stability improvements on all platforms.
584#
585# The change log above is auto-generated. Please review if all relevant
586# commit messages from the list below are included.
587# All lines starting with # will be stripped.
588#
589# Title text 1.
590# (author1@chromium.org)
591#
592# Title text 2 (Chromium issue 123).
593# (author2@chromium.org)
594#
595# Title text 3 (Chromium issue 321).
596# (author3@chromium.org)
597#
598# Title text 4 (Chromium issue 456).
599# (author4@chromium.org)
600#
601#"""
602
603 self.assertEquals(expected_cl, actual_cl)
604
605 def testEditChangeLog(self):
606 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
607 TextToFile(" New \n\tLines \n", TEST_CONFIG["CHANGELOG_ENTRY_FILE"])
608 os.environ["EDITOR"] = "vi"
609 self.Expect([
610 RL(""), # Open editor.
611 Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], ""),
612 ])
613
614 self.RunStep(PushToTrunk, EditChangeLog)
615
616 self.assertEquals("New\n Lines",
617 FileToText(TEST_CONFIG["CHANGELOG_ENTRY_FILE"]))
618
619 # Version on trunk: 3.22.4.0. Version on master (bleeding_edge): 3.22.6.
620 # Make sure that the increment is 3.22.7.0.
621 def testIncrementVersion(self):
622 self.WriteFakeVersionFile()
623 self._state["last_push_trunk"] = "hash1"
624 self._state["latest_build"] = "6"
625 self._state["latest_version"] = "3.22.6.0"
626
627 self.Expect([
628 Cmd("git checkout -f hash1 -- src/version.cc", ""),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400629 Cmd("git checkout -f origin/master -- src/version.cc",
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000630 "", cb=lambda: self.WriteFakeVersionFile(22, 6)),
631 RL("Y"), # Increment build number.
632 ])
633
634 self.RunStep(PushToTrunk, IncrementVersion)
635
636 self.assertEquals("3", self._state["new_major"])
637 self.assertEquals("22", self._state["new_minor"])
638 self.assertEquals("7", self._state["new_build"])
639 self.assertEquals("0", self._state["new_patch"])
640
641 def _TestSquashCommits(self, change_log, expected_msg):
642 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
643 with open(TEST_CONFIG["CHANGELOG_ENTRY_FILE"], "w") as f:
644 f.write(change_log)
645
646 self.Expect([
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400647 Cmd("git diff origin/candidates hash1", "patch content"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000648 ])
649
650 self._state["push_hash"] = "hash1"
651 self._state["date"] = "1999-11-11"
652
653 self.RunStep(PushToTrunk, SquashCommits)
654 self.assertEquals(FileToText(TEST_CONFIG["COMMITMSG_FILE"]), expected_msg)
655
656 patch = FileToText(TEST_CONFIG["PATCH_FILE"])
657 self.assertTrue(re.search(r"patch content", patch))
658
659 def testSquashCommitsUnformatted(self):
660 change_log = """1999-11-11: Version 3.22.5
661
662 Log text 1.
663 Chromium issue 12345
664
665 Performance and stability improvements on all platforms.\n"""
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400666 commit_msg = """Version 3.22.5 (based on hash1)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000667
668Log text 1. Chromium issue 12345
669
670Performance and stability improvements on all platforms."""
671 self._TestSquashCommits(change_log, commit_msg)
672
673 def testSquashCommitsFormatted(self):
674 change_log = """1999-11-11: Version 3.22.5
675
676 Long commit message that fills more than 80 characters (Chromium issue
677 12345).
678
679 Performance and stability improvements on all platforms.\n"""
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400680 commit_msg = """Version 3.22.5 (based on hash1)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000681
682Long commit message that fills more than 80 characters (Chromium issue 12345).
683
684Performance and stability improvements on all platforms."""
685 self._TestSquashCommits(change_log, commit_msg)
686
687 def testSquashCommitsQuotationMarks(self):
688 change_log = """Line with "quotation marks".\n"""
689 commit_msg = """Line with "quotation marks"."""
690 self._TestSquashCommits(change_log, commit_msg)
691
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400692 def testBootstrapper(self):
693 work_dir = self.MakeEmptyTempDirectory()
694 class FakeScript(ScriptsBase):
695 def _Steps(self):
696 return []
697
698 # Use the test configuration without the fake testing default work dir.
699 fake_config = dict(TEST_CONFIG)
700 del(fake_config["DEFAULT_CWD"])
701
702 self.Expect([
703 Cmd("fetch v8", "", cwd=work_dir),
704 ])
705 FakeScript(fake_config, self).Run(["--work-dir", work_dir])
706
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000707 def _PushToTrunk(self, force=False, manual=False):
708 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
709
710 # The version file on bleeding edge has build level 5, while the version
711 # file from trunk has build level 4.
712 self.WriteFakeVersionFile(build=5)
713
714 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000715 bleeding_edge_change_log = "2014-03-17: Sentinel\n"
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400716 TextToFile(bleeding_edge_change_log,
717 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000718 os.environ["EDITOR"] = "vi"
719
720 def ResetChangeLog():
721 """On 'git co -b new_branch svn/trunk', and 'git checkout -- ChangeLog',
722 the ChangLog will be reset to its content on trunk."""
723 trunk_change_log = """1999-04-05: Version 3.22.4
724
725 Performance and stability improvements on all platforms.\n"""
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400726 TextToFile(trunk_change_log,
727 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000728
729 def ResetToTrunk():
730 ResetChangeLog()
731 self.WriteFakeVersionFile()
732
733 def CheckSVNCommit():
734 commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
735 self.assertEquals(
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400736"""Version 3.22.5 (based on push_hash)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000737
738Log text 1 (issue 321).
739
740Performance and stability improvements on all platforms.""", commit)
741 version = FileToText(
742 os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
743 self.assertTrue(re.search(r"#define MINOR_VERSION\s+22", version))
744 self.assertTrue(re.search(r"#define BUILD_NUMBER\s+5", version))
745 self.assertFalse(re.search(r"#define BUILD_NUMBER\s+6", version))
746 self.assertTrue(re.search(r"#define PATCH_LEVEL\s+0", version))
747 self.assertTrue(re.search(r"#define IS_CANDIDATE_VERSION\s+0", version))
748
749 # Check that the change log on the trunk branch got correctly modified.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400750 change_log = FileToText(
751 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000752 self.assertEquals(
753"""1999-07-31: Version 3.22.5
754
755 Log text 1 (issue 321).
756
757 Performance and stability improvements on all platforms.
758
759
7601999-04-05: Version 3.22.4
761
762 Performance and stability improvements on all platforms.\n""",
763 change_log)
764
765 force_flag = " -f" if not manual else ""
766 expectations = []
767 if not force:
768 expectations.append(Cmd("which vi", "/usr/bin/vi"))
769 expectations += [
770 Cmd("git status -s -uno", ""),
771 Cmd("git status -s -b -uno", "## some_branch\n"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400772 Cmd("git fetch", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000773 Cmd("git branch", " branch1\n* branch2\n"),
774 Cmd("git branch", " branch1\n* branch2\n"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400775 Cmd(("git new-branch %s --upstream origin/master" %
776 TEST_CONFIG["BRANCHNAME"]),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000777 ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000778 Cmd(("git log -1 --format=%H --grep="
779 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\" "
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400780 "origin/candidates"), "hash2\n"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000781 Cmd("git log -1 hash2", "Log message\n"),
782 ]
783 if manual:
784 expectations.append(RL("Y")) # Confirm last push.
785 expectations += [
786 Cmd("git log -1 --format=%s hash2",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400787 "Version 3.4.5 (based on abc3)\n"),
788 Cmd("git checkout -f origin/master -- src/version.cc",
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000789 "", cb=self.WriteFakeVersionFile),
790 Cmd("git checkout -f hash2 -- src/version.cc", "",
791 cb=self.WriteFakeVersionFile),
792 ]
793 if manual:
794 expectations.append(RL("")) # Increment build number.
795 expectations += [
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400796 Cmd("git log --format=%H abc3..push_hash", "rev1\n"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000797 Cmd("git log -1 --format=%s rev1", "Log text 1.\n"),
798 Cmd("git log -1 --format=%B rev1", "Text\nLOG=YES\nBUG=v8:321\nText\n"),
799 Cmd("git log -1 --format=%an rev1", "author1@chromium.org\n"),
800 ]
801 if manual:
802 expectations.append(RL("")) # Open editor.
803 if not force:
804 expectations.append(
805 Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], ""))
806 expectations += [
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400807 Cmd("git fetch", ""),
808 Cmd("git checkout -f origin/master", ""),
809 Cmd("git diff origin/candidates push_hash", "patch content\n"),
810 Cmd(("git new-branch %s --upstream origin/candidates" %
811 TEST_CONFIG["TRUNKBRANCH"]), "", cb=ResetToTrunk),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000812 Cmd("git apply --index --reject \"%s\"" % TEST_CONFIG["PATCH_FILE"], ""),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400813 Cmd("git checkout -f origin/candidates -- ChangeLog", "",
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000814 cb=ResetChangeLog),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400815 Cmd("git checkout -f origin/candidates -- src/version.cc", "",
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000816 cb=self.WriteFakeVersionFile),
817 Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "",
818 cb=CheckSVNCommit),
819 ]
820 if manual:
821 expectations.append(RL("Y")) # Sanity check.
822 expectations += [
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400823 Cmd("git cl land -f --bypass-hooks", ""),
824 Cmd("git fetch", ""),
825 Cmd("git log -1 --format=%H --grep="
826 "\"Version 3.22.5 (based on push_hash)\""
827 " origin/candidates", "hsh_to_tag"),
828 Cmd("git tag 3.22.5 hsh_to_tag", ""),
829 Cmd("git push origin 3.22.5", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000830 Cmd("git checkout -f some_branch", ""),
831 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
832 Cmd("git branch -D %s" % TEST_CONFIG["TRUNKBRANCH"], ""),
833 ]
834 self.Expect(expectations)
835
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400836 args = ["-a", "author@chromium.org", "--revision", "push_hash"]
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000837 if force: args.append("-f")
838 if manual: args.append("-m")
839 else: args += ["-r", "reviewer@chromium.org"]
840 PushToTrunk(TEST_CONFIG, self).Run(args)
841
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400842 cl = FileToText(os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000843 self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl))
844 self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl))
845 self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl))
846
847 # Note: The version file is on build number 5 again in the end of this test
848 # since the git command that merges to the bleeding edge branch is mocked
849 # out.
850
851 def testPushToTrunkManual(self):
852 self._PushToTrunk(manual=True)
853
854 def testPushToTrunkSemiAutomatic(self):
855 self._PushToTrunk()
856
857 def testPushToTrunkForced(self):
858 self._PushToTrunk(force=True)
859
860 C_V8_22624_LOG = """V8 CL.
861
862git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22624 123
863
864"""
865
866 C_V8_123455_LOG = """V8 CL.
867
868git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@123455 123
869
870"""
871
872 C_V8_123456_LOG = """V8 CL.
873
874git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@123456 123
875
876"""
877
878 def testChromiumRoll(self):
879 googlers_mapping_py = "%s-mapping.py" % TEST_CONFIG["PERSISTFILE_BASENAME"]
880 with open(googlers_mapping_py, "w") as f:
881 f.write("""
882def list_to_dict(entries):
883 return {"g_name@google.com": "c_name@chromium.org"}
884def get_list():
885 pass""")
886
887 # Setup fake directory structures.
888 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
889 TextToFile("", os.path.join(TEST_CONFIG["CHROMIUM"], ".git"))
890 chrome_dir = TEST_CONFIG["CHROMIUM"]
891 os.makedirs(os.path.join(chrome_dir, "v8"))
892
893 # Write fake deps file.
894 TextToFile("Some line\n \"v8_revision\": \"123444\",\n some line",
895 os.path.join(chrome_dir, "DEPS"))
896 def WriteDeps():
897 TextToFile("Some line\n \"v8_revision\": \"22624\",\n some line",
898 os.path.join(chrome_dir, "DEPS"))
899
900 expectations = [
901 Cmd("git fetch origin", ""),
902 Cmd(("git log -1 --format=%H --grep="
903 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\" "
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400904 "origin/candidates"), "push_hash\n"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000905 Cmd("git log -1 --format=%s push_hash",
906 "Version 3.22.5 (based on bleeding_edge revision r22622)\n"),
907 URL("https://chromium-build.appspot.com/p/chromium/sheriff_v8.js",
908 "document.write('g_name')"),
909 Cmd("git status -s -uno", "", cwd=chrome_dir),
910 Cmd("git checkout -f master", "", cwd=chrome_dir),
911 Cmd("gclient sync --nohooks", "syncing...", cwd=chrome_dir),
912 Cmd("git pull", "", cwd=chrome_dir),
913 Cmd("git fetch origin", ""),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400914 Cmd("git new-branch v8-roll-push_hash", "", cwd=chrome_dir),
915 Cmd("roll-dep v8 push_hash", "rolled", cb=WriteDeps, cwd=chrome_dir),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000916 Cmd(("git commit -am \"Update V8 to version 3.22.5 "
917 "(based on bleeding_edge revision r22622).\n\n"
918 "Please reply to the V8 sheriff c_name@chromium.org in "
919 "case of problems.\n\nTBR=c_name@chromium.org\" "
920 "--author \"author@chromium.org <author@chromium.org>\""),
921 "", cwd=chrome_dir),
922 Cmd("git cl upload --send-mail --email \"author@chromium.org\" -f", "",
923 cwd=chrome_dir),
924 ]
925 self.Expect(expectations)
926
927 args = ["-a", "author@chromium.org", "-c", chrome_dir,
928 "--sheriff", "--googlers-mapping", googlers_mapping_py,
929 "-r", "reviewer@chromium.org"]
930 ChromiumRoll(TEST_CONFIG, self).Run(args)
931
932 deps = FileToText(os.path.join(chrome_dir, "DEPS"))
933 self.assertTrue(re.search("\"v8_revision\": \"22624\"", deps))
934
935 def testCheckLastPushRecently(self):
936 self.Expect([
937 Cmd(("git log -1 --format=%H --grep="
938 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\" "
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400939 "origin/candidates"), "hash2\n"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000940 Cmd("git log -1 --format=%s hash2",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400941 "Version 3.4.5 (based on abc123)\n"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000942 ])
943
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400944 self._state["candidate"] = "abc123"
945 self.assertEquals(0, self.RunStep(
946 auto_push.AutoPush, CheckLastPush, AUTO_PUSH_ARGS))
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000947
948 def testAutoPush(self):
949 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
950 TEST_CONFIG["SETTINGS_LOCATION"] = "~/.doesnotexist"
951
952 self.Expect([
953 Cmd("git status -s -uno", ""),
954 Cmd("git status -s -b -uno", "## some_branch\n"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400955 Cmd("git fetch", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000956 URL("https://v8-status.appspot.com/current?format=json",
957 "{\"message\": \"Tree is throttled\"}"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400958 Cmd("git fetch origin +refs/heads/candidate:refs/heads/candidate", ""),
959 Cmd("git show-ref -s refs/heads/candidate", "abc123\n"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000960 Cmd(("git log -1 --format=%H --grep=\""
961 "^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\""
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400962 " origin/candidates"), "push_hash\n"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000963 Cmd("git log -1 --format=%s push_hash",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400964 "Version 3.4.5 (based on abc101)\n"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000965 ])
966
967 auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS + ["--push"])
968
969 state = json.loads(FileToText("%s-state.json"
970 % TEST_CONFIG["PERSISTFILE_BASENAME"]))
971
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400972 self.assertEquals("abc123", state["candidate"])
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000973
974 def testAutoPushStoppedBySettings(self):
975 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
976 TEST_CONFIG["SETTINGS_LOCATION"] = self.MakeEmptyTempFile()
977 TextToFile("{\"enable_auto_push\": false}",
978 TEST_CONFIG["SETTINGS_LOCATION"])
979
980 self.Expect([
981 Cmd("git status -s -uno", ""),
982 Cmd("git status -s -b -uno", "## some_branch\n"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400983 Cmd("git fetch", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000984 ])
985
986 def RunAutoPush():
987 auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS)
988 self.assertRaises(Exception, RunAutoPush)
989
990 def testAutoPushStoppedByTreeStatus(self):
991 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
992 TEST_CONFIG["SETTINGS_LOCATION"] = "~/.doesnotexist"
993
994 self.Expect([
995 Cmd("git status -s -uno", ""),
996 Cmd("git status -s -b -uno", "## some_branch\n"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400997 Cmd("git fetch", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000998 URL("https://v8-status.appspot.com/current?format=json",
999 "{\"message\": \"Tree is throttled (no push)\"}"),
1000 ])
1001
1002 def RunAutoPush():
1003 auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS)
1004 self.assertRaises(Exception, RunAutoPush)
1005
1006 def testAutoRollExistingRoll(self):
1007 self.Expect([
1008 URL("https://codereview.chromium.org/search",
1009 "owner=author%40chromium.org&limit=30&closed=3&format=json",
1010 ("{\"results\": [{\"subject\": \"different\"},"
1011 "{\"subject\": \"Update V8 to Version...\"}]}")),
1012 ])
1013
1014 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
1015 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"]])
1016 self.assertEquals(0, result)
1017
1018 # Snippet from the original DEPS file.
1019 FAKE_DEPS = """
1020vars = {
1021 "v8_revision": "abcd123455",
1022}
1023deps = {
1024 "src/v8":
1025 (Var("googlecode_url") % "v8") + "/" + Var("v8_branch") + "@" +
1026 Var("v8_revision"),
1027}
1028"""
1029
1030 def testAutoRollUpToDate(self):
1031 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
1032 TextToFile(self.FAKE_DEPS, os.path.join(TEST_CONFIG["CHROMIUM"], "DEPS"))
1033 self.Expect([
1034 URL("https://codereview.chromium.org/search",
1035 "owner=author%40chromium.org&limit=30&closed=3&format=json",
1036 ("{\"results\": [{\"subject\": \"different\"}]}")),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001037 Cmd("git fetch", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001038 Cmd(("git log -1 --format=%H --grep="
1039 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\" "
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001040 "origin/candidates"), "push_hash\n"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001041 Cmd("git log -1 --format=%B push_hash", self.C_V8_22624_LOG),
1042 Cmd("git log -1 --format=%B abcd123455", self.C_V8_123455_LOG),
1043 ])
1044
1045 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
1046 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"]])
1047 self.assertEquals(0, result)
1048
1049 def testAutoRoll(self):
1050 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
1051 TextToFile(self.FAKE_DEPS, os.path.join(TEST_CONFIG["CHROMIUM"], "DEPS"))
1052 TEST_CONFIG["CLUSTERFUZZ_API_KEY_FILE"] = self.MakeEmptyTempFile()
1053 TextToFile("fake key", TEST_CONFIG["CLUSTERFUZZ_API_KEY_FILE"])
1054
1055 self.Expect([
1056 URL("https://codereview.chromium.org/search",
1057 "owner=author%40chromium.org&limit=30&closed=3&format=json",
1058 ("{\"results\": [{\"subject\": \"different\"}]}")),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001059 Cmd("git fetch", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001060 Cmd(("git log -1 --format=%H --grep="
1061 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\" "
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001062 "origin/candidates"), "push_hash\n"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001063 Cmd("git log -1 --format=%B push_hash", self.C_V8_123456_LOG),
1064 Cmd("git log -1 --format=%B abcd123455", self.C_V8_123455_LOG),
1065 ])
1066
1067 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
1068 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"], "--roll"])
1069 self.assertEquals(0, result)
1070
1071 def testMergeToBranch(self):
1072 TEST_CONFIG["ALREADY_MERGING_SENTINEL_FILE"] = self.MakeEmptyTempFile()
1073 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
1074 self.WriteFakeVersionFile(build=5)
1075 os.environ["EDITOR"] = "vi"
1076 extra_patch = self.MakeEmptyTempFile()
1077
1078 def VerifyPatch(patch):
1079 return lambda: self.assertEquals(patch,
1080 FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"]))
1081
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001082 msg = """Version 3.22.5.1 (cherry-pick)
1083
1084Merged ab12345
1085Merged ab23456
1086Merged ab34567
1087Merged ab45678
1088Merged ab56789
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001089
1090Title4
1091
1092Title2
1093
1094Title3
1095
1096Title1
1097
1098Revert "Something"
1099
1100BUG=123,234,345,456,567,v8:123
1101LOG=N
1102"""
1103
1104 def VerifySVNCommit():
1105 commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
1106 self.assertEquals(msg, commit)
1107 version = FileToText(
1108 os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
1109 self.assertTrue(re.search(r"#define MINOR_VERSION\s+22", version))
1110 self.assertTrue(re.search(r"#define BUILD_NUMBER\s+5", version))
1111 self.assertTrue(re.search(r"#define PATCH_LEVEL\s+1", version))
1112 self.assertTrue(re.search(r"#define IS_CANDIDATE_VERSION\s+0", version))
1113
1114 self.Expect([
1115 Cmd("git status -s -uno", ""),
1116 Cmd("git status -s -b -uno", "## some_branch\n"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001117 Cmd("git fetch", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001118 Cmd("git branch", " branch1\n* branch2\n"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001119 Cmd("git new-branch %s --upstream origin/candidates" %
1120 TEST_CONFIG["BRANCHNAME"], ""),
1121 Cmd(("git log --format=%H --grep=\"Port ab12345\" "
1122 "--reverse origin/master"),
1123 "ab45678\nab23456"),
1124 Cmd("git log -1 --format=%s ab45678", "Title1"),
1125 Cmd("git log -1 --format=%s ab23456", "Title2"),
1126 Cmd(("git log --format=%H --grep=\"Port ab23456\" "
1127 "--reverse origin/master"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001128 ""),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001129 Cmd(("git log --format=%H --grep=\"Port ab34567\" "
1130 "--reverse origin/master"),
1131 "ab56789"),
1132 Cmd("git log -1 --format=%s ab56789", "Title3"),
1133 RL("Y"), # Automatically add corresponding ports (ab34567, ab56789)?
1134 # Simulate git being down which stops the script.
1135 Cmd("git log -1 --format=%s ab12345", None),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001136 # Restart script in the failing step.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001137 Cmd("git log -1 --format=%s ab12345", "Title4"),
1138 Cmd("git log -1 --format=%s ab23456", "Title2"),
1139 Cmd("git log -1 --format=%s ab34567", "Title3"),
1140 Cmd("git log -1 --format=%s ab45678", "Title1"),
1141 Cmd("git log -1 --format=%s ab56789", "Revert \"Something\""),
1142 Cmd("git log -1 ab12345", "Title4\nBUG=123\nBUG=234"),
1143 Cmd("git log -1 ab23456", "Title2\n BUG = v8:123,345"),
1144 Cmd("git log -1 ab34567", "Title3\nLOG=n\nBUG=567, 456"),
1145 Cmd("git log -1 ab45678", "Title1\nBUG="),
1146 Cmd("git log -1 ab56789", "Revert \"Something\"\nBUG=none"),
1147 Cmd("git log -1 -p ab12345", "patch4"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001148 Cmd(("git apply --index --reject \"%s\"" %
1149 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1150 "", cb=VerifyPatch("patch4")),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001151 Cmd("git log -1 -p ab23456", "patch2"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001152 Cmd(("git apply --index --reject \"%s\"" %
1153 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1154 "", cb=VerifyPatch("patch2")),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001155 Cmd("git log -1 -p ab34567", "patch3"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001156 Cmd(("git apply --index --reject \"%s\"" %
1157 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1158 "", cb=VerifyPatch("patch3")),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001159 Cmd("git log -1 -p ab45678", "patch1"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001160 Cmd(("git apply --index --reject \"%s\"" %
1161 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1162 "", cb=VerifyPatch("patch1")),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001163 Cmd("git log -1 -p ab56789", "patch5\n"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001164 Cmd(("git apply --index --reject \"%s\"" %
1165 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1166 "", cb=VerifyPatch("patch5\n")),
1167 Cmd("git apply --index --reject \"%s\"" % extra_patch, ""),
1168 RL("Y"), # Automatically increment patch level?
1169 Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], ""),
1170 RL("reviewer@chromium.org"), # V8 reviewer.
1171 Cmd("git cl upload --send-mail -r \"reviewer@chromium.org\" "
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001172 "--bypass-hooks --cc \"ulan@chromium.org\"", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001173 Cmd("git checkout -f %s" % TEST_CONFIG["BRANCHNAME"], ""),
1174 RL("LGTM"), # Enter LGTM for V8 CL.
1175 Cmd("git cl presubmit", "Presubmit successfull\n"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001176 Cmd("git cl land -f --bypass-hooks", "Closing issue\n",
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001177 cb=VerifySVNCommit),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001178 Cmd("git fetch", ""),
1179 Cmd("git log -1 --format=%H --grep=\""
1180 "Version 3.22.5.1 (cherry-pick)"
1181 "\" origin/candidates",
1182 ""),
1183 Cmd("git fetch", ""),
1184 Cmd("git log -1 --format=%H --grep=\""
1185 "Version 3.22.5.1 (cherry-pick)"
1186 "\" origin/candidates",
1187 "hsh_to_tag"),
1188 Cmd("git tag 3.22.5.1 hsh_to_tag", ""),
1189 Cmd("git push origin 3.22.5.1", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001190 Cmd("git checkout -f some_branch", ""),
1191 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
1192 ])
1193
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001194 # ab12345 and ab34567 are patches. ab23456 (included) and ab45678 are the
1195 # MIPS ports of ab12345. ab56789 is the MIPS port of ab34567.
1196 args = ["-f", "-p", extra_patch, "--branch", "candidates",
1197 "ab12345", "ab23456", "ab34567"]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001198
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001199 # The first run of the script stops because of git being down.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001200 self.assertRaises(GitFailedException,
1201 lambda: MergeToBranch(TEST_CONFIG, self).Run(args))
1202
1203 # Test that state recovery after restarting the script works.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001204 args += ["-s", "4"]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001205 MergeToBranch(TEST_CONFIG, self).Run(args)
1206
1207 def testReleases(self):
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001208 c_hash2_commit_log = """Revert something.
1209
1210BUG=12345
1211
1212Reason:
1213> Some reason.
1214> Cr-Commit-Position: refs/heads/master@{#12345}
1215> git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12345 003-1c4
1216
1217Review URL: https://codereview.chromium.org/12345
1218
1219Cr-Commit-Position: refs/heads/master@{#4567}
1220git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4567 0039-1c4b
1221
1222"""
1223 c_hash3_commit_log = """Simple.
1224
1225git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3456 0039-1c4b
1226
1227"""
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001228 c_hash_234_commit_log = """Version 3.3.1.1 (cherry-pick).
1229
1230Merged abc12.
1231
1232Review URL: fake.com
1233
1234Cr-Commit-Position: refs/heads/candidates@{#234}
1235"""
1236 c_hash_123_commit_log = """Version 3.3.1.0
1237
1238git-svn-id: googlecode@123 0039-1c4b
1239"""
1240 c_hash_345_commit_log = """Version 3.4.0.
1241
1242Cr-Commit-Position: refs/heads/candidates@{#345}
1243"""
1244
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001245 json_output = self.MakeEmptyTempFile()
1246 csv_output = self.MakeEmptyTempFile()
1247 self.WriteFakeVersionFile()
1248
1249 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
1250 chrome_dir = TEST_CONFIG["CHROMIUM"]
1251 chrome_v8_dir = os.path.join(chrome_dir, "v8")
1252 os.makedirs(chrome_v8_dir)
1253 def WriteDEPS(revision):
1254 TextToFile("Line\n \"v8_revision\": \"%s\",\n line\n" % revision,
1255 os.path.join(chrome_dir, "DEPS"))
1256 WriteDEPS(567)
1257
1258 def ResetVersion(minor, build, patch=0):
1259 return lambda: self.WriteFakeVersionFile(minor=minor,
1260 build=build,
1261 patch=patch)
1262
1263 def ResetDEPS(revision):
1264 return lambda: WriteDEPS(revision)
1265
1266 self.Expect([
1267 Cmd("git status -s -uno", ""),
1268 Cmd("git status -s -b -uno", "## some_branch\n"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001269 Cmd("git fetch", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001270 Cmd("git branch", " branch1\n* branch2\n"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001271 Cmd("git new-branch %s" % TEST_CONFIG["BRANCHNAME"], ""),
1272 Cmd("git branch -r", " branch-heads/3.21\n branch-heads/3.3\n"),
1273 Cmd("git reset --hard branch-heads/3.3", ""),
1274 Cmd("git log --format=%H", "hash1\nhash_234"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001275 Cmd("git diff --name-only hash1 hash1^", ""),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001276 Cmd("git diff --name-only hash_234 hash_234^", VERSION_FILE),
1277 Cmd("git checkout -f hash_234 -- %s" % VERSION_FILE, "",
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001278 cb=ResetVersion(3, 1, 1)),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001279 Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log),
1280 Cmd("git log -1 --format=%s hash_234", ""),
1281 Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log),
1282 Cmd("git log -1 --format=%ci hash_234", "18:15"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001283 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1284 cb=ResetVersion(22, 5)),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001285 Cmd("git reset --hard branch-heads/3.21", ""),
1286 Cmd("git log --format=%H", "hash_123\nhash4\nhash5\n"),
1287 Cmd("git diff --name-only hash_123 hash_123^", VERSION_FILE),
1288 Cmd("git checkout -f hash_123 -- %s" % VERSION_FILE, "",
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001289 cb=ResetVersion(21, 2)),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001290 Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log),
1291 Cmd("git log -1 --format=%s hash_123", ""),
1292 Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log),
1293 Cmd("git log -1 --format=%ci hash_123", "03:15"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001294 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1295 cb=ResetVersion(22, 5)),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001296 Cmd("git reset --hard origin/candidates", ""),
1297 Cmd("git log --format=%H", "hash_345\n"),
1298 Cmd("git diff --name-only hash_345 hash_345^", VERSION_FILE),
1299 Cmd("git checkout -f hash_345 -- %s" % VERSION_FILE, "",
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001300 cb=ResetVersion(22, 3)),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001301 Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log),
1302 Cmd("git log -1 --format=%s hash_345", ""),
1303 Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log),
1304 Cmd("git log -1 --format=%ci hash_345", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001305 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1306 cb=ResetVersion(22, 5)),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001307 Cmd("git reset --hard origin/master", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001308 Cmd("git status -s -uno", "", cwd=chrome_dir),
1309 Cmd("git checkout -f master", "", cwd=chrome_dir),
1310 Cmd("git pull", "", cwd=chrome_dir),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001311 Cmd("git new-branch %s" % TEST_CONFIG["BRANCHNAME"], "",
1312 cwd=chrome_dir),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001313 Cmd("git fetch origin", "", cwd=chrome_v8_dir),
1314 Cmd("git log --format=%H --grep=\"V8\"", "c_hash1\nc_hash2\nc_hash3\n",
1315 cwd=chrome_dir),
1316 Cmd("git diff --name-only c_hash1 c_hash1^", "", cwd=chrome_dir),
1317 Cmd("git diff --name-only c_hash2 c_hash2^", "DEPS", cwd=chrome_dir),
1318 Cmd("git checkout -f c_hash2 -- DEPS", "",
1319 cb=ResetDEPS("0123456789012345678901234567890123456789"),
1320 cwd=chrome_dir),
1321 Cmd("git log -1 --format=%B c_hash2", c_hash2_commit_log,
1322 cwd=chrome_dir),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001323 Cmd("git log -1 --format=%B 0123456789012345678901234567890123456789",
1324 self.C_V8_22624_LOG, cwd=chrome_v8_dir),
1325 Cmd("git diff --name-only c_hash3 c_hash3^", "DEPS", cwd=chrome_dir),
1326 Cmd("git checkout -f c_hash3 -- DEPS", "", cb=ResetDEPS(345),
1327 cwd=chrome_dir),
1328 Cmd("git log -1 --format=%B c_hash3", c_hash3_commit_log,
1329 cwd=chrome_dir),
1330 Cmd("git checkout -f HEAD -- DEPS", "", cb=ResetDEPS(567),
1331 cwd=chrome_dir),
1332 Cmd("git branch -r", " weird/123\n branch-heads/7\n", cwd=chrome_dir),
1333 Cmd("git checkout -f branch-heads/7 -- DEPS", "", cb=ResetDEPS(345),
1334 cwd=chrome_dir),
1335 Cmd("git checkout -f HEAD -- DEPS", "", cb=ResetDEPS(567),
1336 cwd=chrome_dir),
1337 Cmd("git checkout -f master", "", cwd=chrome_dir),
1338 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], "", cwd=chrome_dir),
1339 Cmd("git checkout -f some_branch", ""),
1340 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
1341 ])
1342
1343 args = ["-c", TEST_CONFIG["CHROMIUM"],
1344 "--json", json_output,
1345 "--csv", csv_output,
1346 "--max-releases", "1"]
1347 Releases(TEST_CONFIG, self).Run(args)
1348
1349 # Check expected output.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001350 csv = ("3.22.3,candidates,345,3456:4566,\r\n"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001351 "3.21.2,3.21,123,,\r\n"
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001352 "3.3.1.1,3.3,234,,abc12\r\n")
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001353 self.assertEquals(csv, FileToText(csv_output))
1354
1355 expected_json = [
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001356 {
1357 "revision": "345",
1358 "revision_git": "hash_345",
1359 "bleeding_edge": "",
1360 "bleeding_edge_git": "",
1361 "patches_merged": "",
1362 "version": "3.22.3",
1363 "chromium_revision": "3456:4566",
1364 "branch": "candidates",
1365 "review_link": "",
1366 "date": "",
1367 "chromium_branch": "7",
1368 "revision_link": "https://code.google.com/p/v8/source/detail?r=345",
1369 },
1370 {
1371 "revision": "123",
1372 "revision_git": "hash_123",
1373 "patches_merged": "",
1374 "bleeding_edge": "",
1375 "bleeding_edge_git": "",
1376 "version": "3.21.2",
1377 "chromium_revision": "",
1378 "branch": "3.21",
1379 "review_link": "",
1380 "date": "03:15",
1381 "chromium_branch": "",
1382 "revision_link": "https://code.google.com/p/v8/source/detail?r=123",
1383 },
1384 {
1385 "revision": "234",
1386 "revision_git": "hash_234",
1387 "patches_merged": "abc12",
1388 "bleeding_edge": "",
1389 "bleeding_edge_git": "",
1390 "version": "3.3.1.1",
1391 "chromium_revision": "",
1392 "branch": "3.3",
1393 "review_link": "fake.com",
1394 "date": "18:15",
1395 "chromium_branch": "",
1396 "revision_link": "https://code.google.com/p/v8/source/detail?r=234",
1397 },
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001398 ]
1399 self.assertEquals(expected_json, json.loads(FileToText(json_output)))
1400
1401
1402 def _bumpUpVersion(self):
1403 self.WriteFakeVersionFile()
1404
1405 def ResetVersion(minor, build, patch=0):
1406 return lambda: self.WriteFakeVersionFile(minor=minor,
1407 build=build,
1408 patch=patch)
1409
1410 return [
1411 Cmd("git status -s -uno", ""),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001412 Cmd("git checkout -f master", "", cb=ResetVersion(11, 4)),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001413 Cmd("git pull", ""),
1414 Cmd("git branch", ""),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001415 Cmd("git checkout -f master", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001416 Cmd("git log -1 --format=%H", "latest_hash"),
1417 Cmd("git diff --name-only latest_hash latest_hash^", ""),
1418 URL("https://v8-status.appspot.com/lkgr", "12345"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001419 Cmd("git checkout -f master", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001420 Cmd(("git log --format=%H --grep="
1421 "\"^git-svn-id: [^@]*@12345 [A-Za-z0-9-]*$\""),
1422 "lkgr_hash"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001423 Cmd("git new-branch auto-bump-up-version --upstream lkgr_hash", ""),
1424 Cmd("git checkout -f master", ""),
1425 Cmd("git branch", "auto-bump-up-version\n* master"),
1426 Cmd("git branch -D auto-bump-up-version", ""),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001427 Cmd("git diff --name-only lkgr_hash lkgr_hash^", ""),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001428 Cmd("git checkout -f candidates", "", cb=ResetVersion(11, 5)),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001429 Cmd("git pull", ""),
1430 URL("https://v8-status.appspot.com/current?format=json",
1431 "{\"message\": \"Tree is open\"}"),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001432 Cmd("git new-branch auto-bump-up-version --upstream master", "",
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001433 cb=ResetVersion(11, 4)),
1434 Cmd("git commit -am \"[Auto-roll] Bump up version to 3.11.6.0\n\n"
1435 "TBR=author@chromium.org\" "
1436 "--author \"author@chromium.org <author@chromium.org>\"", ""),
1437 ]
1438
1439 def testBumpUpVersionGit(self):
1440 expectations = self._bumpUpVersion()
1441 expectations += [
1442 Cmd("git cl upload --send-mail --email \"author@chromium.org\" -f "
1443 "--bypass-hooks", ""),
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001444 Cmd("git cl land -f --bypass-hooks", ""),
1445 Cmd("git checkout -f master", ""),
1446 Cmd("git branch", "auto-bump-up-version\n* master"),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001447 Cmd("git branch -D auto-bump-up-version", ""),
1448 ]
1449 self.Expect(expectations)
1450
1451 BumpUpVersion(TEST_CONFIG, self).Run(["-a", "author@chromium.org"])
1452
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001453
1454 # Test that we bail out if the last change was a version change.
1455 def testBumpUpVersionBailout1(self):
1456 self._state["latest"] = "latest_hash"
1457
1458 self.Expect([
1459 Cmd("git diff --name-only latest_hash latest_hash^", VERSION_FILE),
1460 ])
1461
1462 self.assertEquals(0,
1463 self.RunStep(BumpUpVersion, LastChangeBailout, ["--dry_run"]))
1464
1465 # Test that we bail out if the lkgr was a version change.
1466 def testBumpUpVersionBailout2(self):
1467 self._state["lkgr"] = "lkgr_hash"
1468
1469 self.Expect([
1470 Cmd("git diff --name-only lkgr_hash lkgr_hash^", VERSION_FILE),
1471 ])
1472
1473 self.assertEquals(0,
1474 self.RunStep(BumpUpVersion, LKGRVersionUpToDateBailout, ["--dry_run"]))
1475
1476 # Test that we bail out if the last version is already newer than the lkgr's
1477 # version.
1478 def testBumpUpVersionBailout3(self):
1479 self._state["lkgr"] = "lkgr_hash"
1480 self._state["lkgr_version"] = "3.22.4.0"
1481 self._state["latest_version"] = "3.22.5.0"
1482
1483 self.Expect([
1484 Cmd("git diff --name-only lkgr_hash lkgr_hash^", ""),
1485 ])
1486
1487 self.assertEquals(0,
1488 self.RunStep(BumpUpVersion, LKGRVersionUpToDateBailout, ["--dry_run"]))
1489
1490
1491class SystemTest(unittest.TestCase):
1492 def testReload(self):
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001493 options = ScriptsBase(
1494 TEST_CONFIG, DEFAULT_SIDE_EFFECT_HANDLER, {}).MakeOptions([])
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001495 step = MakeStep(step_class=PrepareChangeLog, number=0, state={}, config={},
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001496 options=options,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001497 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER)
1498 body = step.Reload(
1499"""------------------------------------------------------------------------
1500r17997 | machenbach@chromium.org | 2013-11-22 11:04:04 +0100 (...) | 6 lines
1501
1502Prepare push to trunk. Now working on version 3.23.11.
1503
1504R=danno@chromium.org
1505
1506Review URL: https://codereview.chromium.org/83173002
1507
1508------------------------------------------------------------------------""")
1509 self.assertEquals(
1510"""Prepare push to trunk. Now working on version 3.23.11.
1511
1512R=danno@chromium.org
1513
1514Committed: https://code.google.com/p/v8/source/detail?r=17997""", body)