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
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.
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.
36 from auto_push import LastReleaseBailout
38 import common_includes
39 from common_includes import *
41 from create_release import CreateRelease
42 import merge_to_branch
43 from merge_to_branch import *
44 import push_to_candidates
45 from push_to_candidates import *
47 from chromium_roll import ChromiumRoll
49 from releases import Releases
50 from auto_tag import AutoTag
55 "BRANCHNAME": "test-prepare-push",
56 "CANDIDATESBRANCH": "test-candidates-push",
57 "PERSISTFILE_BASENAME": "/tmp/test-v8-push-to-candidates-tempfile",
58 "CHANGELOG_ENTRY_FILE":
59 "/tmp/test-v8-push-to-candidates-tempfile-changelog-entry",
60 "PATCH_FILE": "/tmp/test-v8-push-to-candidates-tempfile-patch",
61 "COMMITMSG_FILE": "/tmp/test-v8-push-to-candidates-tempfile-commitmsg",
62 "CHROMIUM": "/tmp/test-v8-push-to-candidates-tempfile-chromium",
63 "SETTINGS_LOCATION": None,
64 "ALREADY_MERGING_SENTINEL_FILE":
65 "/tmp/test-merge-to-branch-tempfile-already-merging",
66 "TEMPORARY_PATCH_FILE": "/tmp/test-merge-to-branch-tempfile-temporary-patch",
71 "-a", "author@chromium.org",
72 "-r", "reviewer@chromium.org",
76 class ToplevelTest(unittest.TestCase):
77 def testSortBranches(self):
78 S = releases.SortBranches
79 self.assertEquals(["3.1", "2.25"], S(["2.25", "3.1"])[0:2])
80 self.assertEquals(["3.0", "2.25"], S(["2.25", "3.0", "2.24"])[0:2])
81 self.assertEquals(["3.11", "3.2"], S(["3.11", "3.2", "2.24"])[0:2])
83 def testFilterDuplicatesAndReverse(self):
84 F = releases.FilterDuplicatesAndReverse
85 self.assertEquals([], F([]))
86 self.assertEquals([["100", "10"]], F([["100", "10"]]))
87 self.assertEquals([["99", "9"], ["100", "10"]],
88 F([["100", "10"], ["99", "9"]]))
89 self.assertEquals([["98", "9"], ["100", "10"]],
90 F([["100", "10"], ["99", "9"], ["98", "9"]]))
91 self.assertEquals([["98", "9"], ["99", "10"]],
92 F([["100", "10"], ["99", "10"], ["98", "9"]]))
94 def testBuildRevisionRanges(self):
95 B = releases.BuildRevisionRanges
96 self.assertEquals({}, B([]))
97 self.assertEquals({"10": "100"}, B([["100", "10"]]))
98 self.assertEquals({"10": "100", "9": "99:99"},
99 B([["100", "10"], ["99", "9"]]))
100 self.assertEquals({"10": "100", "9": "97:99"},
101 B([["100", "10"], ["98", "9"], ["97", "9"]]))
102 self.assertEquals({"10": "100", "9": "99:99", "3": "91:98"},
103 B([["100", "10"], ["99", "9"], ["91", "3"]]))
104 self.assertEquals({"13": "101", "12": "100:100", "9": "94:97",
105 "3": "91:93, 98:99"},
106 B([["101", "13"], ["100", "12"], ["98", "3"],
107 ["94", "9"], ["91", "3"]]))
109 def testMakeComment(self):
110 self.assertEquals("# Line 1\n# Line 2\n#",
111 MakeComment(" Line 1\n Line 2\n"))
112 self.assertEquals("#Line 1\n#Line 2",
113 MakeComment("Line 1\n Line 2"))
115 def testStripComments(self):
116 self.assertEquals(" Line 1\n Line 3\n",
117 StripComments(" Line 1\n# Line 2\n Line 3\n#\n"))
118 self.assertEquals("\nLine 2 ### Test\n #",
119 StripComments("###\n# \n\n# Line 1\nLine 2 ### Test\n #"))
121 def testMakeChangeLogBodySimple(self):
124 "Title text 1\n\nBUG=\n",
125 "author1@chromium.org"],
127 "Title text 2\n\nBUG=1234\n",
128 "author2@chromium.org"],
130 self.assertEquals(" Title text 1.\n"
131 " (author1@chromium.org)\n\n"
132 " Title text 2 (Chromium issue 1234).\n"
133 " (author2@chromium.org)\n\n",
134 MakeChangeLogBody(commits))
136 def testMakeChangeLogBodyEmpty(self):
137 self.assertEquals("", MakeChangeLogBody([]))
139 def testMakeChangeLogBodyAutoFormat(self):
142 "Title text 1\nLOG=y\nBUG=\n",
143 "author1@chromium.org"],
145 "Title text 2\n\nBUG=1234\n",
146 "author2@chromium.org"],
148 "Title text 3\n\nBUG=1234\nLOG = Yes\n",
149 "author3@chromium.org"],
151 "Title text 4\n\nBUG=1234\nLOG=\n",
152 "author4@chromium.org"],
154 self.assertEquals(" Title text 1.\n\n"
155 " Title text 3 (Chromium issue 1234).\n\n",
156 MakeChangeLogBody(commits, True))
158 def testRegressWrongLogEntryOnTrue(self):
160 Check elimination: Learn from if(CompareMap(x)) on true branch.
163 R=verwaest@chromium.org
165 Committed: https://code.google.com/p/v8/source/detail?r=18210
167 self.assertEquals("", MakeChangeLogBody([["title", body, "author"]], True))
169 def testMakeChangeLogBugReferenceEmpty(self):
170 self.assertEquals("", MakeChangeLogBugReference(""))
171 self.assertEquals("", MakeChangeLogBugReference("LOG="))
172 self.assertEquals("", MakeChangeLogBugReference(" BUG ="))
173 self.assertEquals("", MakeChangeLogBugReference("BUG=none\t"))
175 def testMakeChangeLogBugReferenceSimple(self):
176 self.assertEquals("(issue 987654)",
177 MakeChangeLogBugReference("BUG = v8:987654"))
178 self.assertEquals("(Chromium issue 987654)",
179 MakeChangeLogBugReference("BUG=987654 "))
181 def testMakeChangeLogBugReferenceFromBody(self):
182 self.assertEquals("(Chromium issue 1234567)",
183 MakeChangeLogBugReference("Title\n\nTBR=\nBUG=\n"
184 " BUG=\tchromium:1234567\t\n"
187 def testMakeChangeLogBugReferenceMultiple(self):
188 # All issues should be sorted and grouped. Multiple references to the same
189 # issue should be filtered.
190 self.assertEquals("(issues 123, 234, Chromium issue 345)",
191 MakeChangeLogBugReference("Title\n\n"
193 " BUG\t= 345, \tv8:234,\n"
196 self.assertEquals("(Chromium issues 123, 234)",
197 MakeChangeLogBugReference("Title\n\n"
198 "BUG=234,,chromium:123 \n"
200 self.assertEquals("(Chromium issues 123, 234)",
201 MakeChangeLogBugReference("Title\n\n"
202 "BUG=chromium:234, , 123\n"
204 self.assertEquals("(issues 345, 456)",
205 MakeChangeLogBugReference("Title\n\n"
206 "\t\tBUG=v8:345,v8:456\n"
208 self.assertEquals("(issue 123, Chromium issues 345, 456)",
209 MakeChangeLogBugReference("Title\n\n"
213 "BUG=456,v8:123, 345"))
215 # TODO(machenbach): These test don't make much sense when the formatting is
217 def testMakeChangeLogBugReferenceLong(self):
218 # -----------------00--------10--------20--------30--------
219 self.assertEquals("(issues 234, 1234567890, 1234567"
220 "8901234567890, Chromium issues 12345678,"
222 MakeChangeLogBugReference("BUG=v8:234\n"
223 "BUG=v8:1234567890\n"
224 "BUG=v8:12345678901234567890\n"
227 # -----------------00--------10--------20--------30--------
228 self.assertEquals("(issues 234, 1234567890, 1234567"
229 "8901234567890, Chromium issues"
230 " 123456789, 1234567890)",
231 MakeChangeLogBugReference("BUG=v8:234\n"
232 "BUG=v8:12345678901234567890\n"
233 "BUG=v8:1234567890\n"
236 # -----------------00--------10--------20--------30--------
237 self.assertEquals("(Chromium issues 234, 1234567890"
238 ", 12345678901234567, "
239 "1234567890123456789)",
240 MakeChangeLogBugReference("BUG=234\n"
241 "BUG=12345678901234567\n"
242 "BUG=1234567890123456789\n"
246 def Cmd(*args, **kwargs):
247 """Convenience function returning a shell command test expectation."""
252 "cb": kwargs.get("cb"),
253 "cwd": kwargs.get("cwd", TEST_CONFIG["DEFAULT_CWD"]),
257 def RL(text, cb=None):
258 """Convenience function returning a readline test expectation."""
268 def URL(*args, **kwargs):
269 """Convenience function returning a readurl test expectation."""
274 "cb": kwargs.get("cb"),
279 class SimpleMock(object):
284 def Expect(self, recipe):
285 self._recipe = recipe
287 def Call(self, name, *args, **kwargs): # pragma: no cover
290 expected_call = self._recipe[self._index]
292 raise NoRetryException("Calling %s %s" % (name, " ".join(args)))
294 if not isinstance(expected_call, dict):
295 raise NoRetryException("Found wrong expectation type for %s %s" %
296 (name, " ".join(args)))
298 if expected_call["name"] != name:
299 raise NoRetryException("Expected action: %s %s - Actual: %s" %
300 (expected_call["name"], expected_call["args"], name))
302 # Check if the given working directory matches the expected one.
303 if expected_call["cwd"] != kwargs.get("cwd"):
304 raise NoRetryException("Expected cwd: %s in %s %s - Actual: %s" %
305 (expected_call["cwd"],
306 expected_call["name"],
307 expected_call["args"],
310 # The number of arguments in the expectation must match the actual
312 if len(args) > len(expected_call['args']):
313 raise NoRetryException("When calling %s with arguments, the "
314 "expectations must consist of at least as many arguments." %
317 # Compare expected and actual arguments.
318 for (expected_arg, actual_arg) in zip(expected_call['args'], args):
319 if expected_arg != actual_arg:
320 raise NoRetryException("Expected: %s - Actual: %s" %
321 (expected_arg, actual_arg))
323 # The expected call contains an optional callback for checking the context
324 # at the time of the call.
325 if expected_call['cb']:
327 expected_call['cb']()
329 tb = traceback.format_exc()
330 raise NoRetryException("Caught exception from callback: %s" % tb)
332 # If the return value is an exception, raise it instead of returning.
333 if isinstance(expected_call['ret'], Exception):
334 raise expected_call['ret']
335 return expected_call['ret']
337 def AssertFinished(self): # pragma: no cover
338 if self._index < len(self._recipe) -1:
339 raise NoRetryException("Called mock too seldom: %d vs. %d" %
340 (self._index, len(self._recipe)))
343 class ScriptTest(unittest.TestCase):
344 def MakeEmptyTempFile(self):
345 handle, name = tempfile.mkstemp()
347 self._tmp_files.append(name)
350 def MakeEmptyTempDirectory(self):
351 name = tempfile.mkdtemp()
352 self._tmp_files.append(name)
356 def WriteFakeVersionFile(self, major=3, minor=22, build=4, patch=0):
357 version_file = os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE)
358 if not os.path.exists(os.path.dirname(version_file)):
359 os.makedirs(os.path.dirname(version_file))
360 with open(version_file, "w") as f:
361 f.write(" // Some line...\n")
363 f.write("#define V8_MAJOR_VERSION %s\n" % major)
364 f.write("#define V8_MINOR_VERSION %s\n" % minor)
365 f.write("#define V8_BUILD_NUMBER %s\n" % build)
366 f.write("#define V8_PATCH_LEVEL %s\n" % patch)
367 f.write(" // Some line...\n")
368 f.write("#define V8_IS_CANDIDATE_VERSION 0\n")
371 """Convenience wrapper."""
372 options = ScriptsBase(TEST_CONFIG, self, self._state).MakeOptions([])
373 return MakeStep(step_class=Step, state=self._state,
374 config=TEST_CONFIG, side_effect_handler=self,
377 def RunStep(self, script=PushToCandidates, step_class=Step, args=None):
378 """Convenience wrapper."""
379 args = args if args is not None else ["-m"]
380 return script(TEST_CONFIG, self, self._state).RunSteps([step_class], args)
382 def Call(self, fun, *args, **kwargs):
383 print "Calling %s with %s and %s" % (str(fun), str(args), str(kwargs))
385 def Command(self, cmd, args="", prefix="", pipe=True, cwd=None):
386 print "%s %s" % (cmd, args)
388 return self._mock.Call("command", cmd + " " + args, cwd=cwd)
391 return self._mock.Call("readline")
393 def ReadURL(self, url, params):
394 if params is not None:
395 return self._mock.Call("readurl", url, params)
397 return self._mock.Call("readurl", url)
399 def Sleep(self, seconds):
405 def GetUTCStamp(self):
408 def Expect(self, *args):
409 """Convenience wrapper."""
410 self._mock.Expect(*args)
413 self._mock = SimpleMock()
416 TEST_CONFIG["DEFAULT_CWD"] = self.MakeEmptyTempDirectory()
419 if os.path.exists(TEST_CONFIG["PERSISTFILE_BASENAME"]):
420 shutil.rmtree(TEST_CONFIG["PERSISTFILE_BASENAME"])
422 # Clean up temps. Doesn't work automatically.
423 for name in self._tmp_files:
424 if os.path.isfile(name):
426 if os.path.isdir(name):
429 self._mock.AssertFinished()
431 def testGitMock(self):
432 self.Expect([Cmd("git --version", "git version 1.2.3"),
433 Cmd("git dummy", "")])
434 self.assertEquals("git version 1.2.3", self.MakeStep().Git("--version"))
435 self.assertEquals("", self.MakeStep().Git("dummy"))
437 def testCommonPrepareDefault(self):
439 Cmd("git status -s -uno", ""),
440 Cmd("git checkout -f origin/master", ""),
441 Cmd("git fetch", ""),
442 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
444 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
446 self.MakeStep().CommonPrepare()
447 self.MakeStep().PrepareBranch()
449 def testCommonPrepareNoConfirm(self):
451 Cmd("git status -s -uno", ""),
452 Cmd("git checkout -f origin/master", ""),
453 Cmd("git fetch", ""),
454 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
457 self.MakeStep().CommonPrepare()
458 self.assertRaises(Exception, self.MakeStep().PrepareBranch)
460 def testCommonPrepareDeleteBranchFailure(self):
462 Cmd("git status -s -uno", ""),
463 Cmd("git checkout -f origin/master", ""),
464 Cmd("git fetch", ""),
465 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
467 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], None),
469 self.MakeStep().CommonPrepare()
470 self.assertRaises(Exception, self.MakeStep().PrepareBranch)
472 def testInitialEnvironmentChecks(self):
473 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
474 os.environ["EDITOR"] = "vi"
476 Cmd("which vi", "/usr/bin/vi"),
478 self.MakeStep().InitialEnvironmentChecks(TEST_CONFIG["DEFAULT_CWD"])
480 def testTagTimeout(self):
482 Cmd("git fetch", ""),
483 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
484 Cmd("git fetch", ""),
485 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
486 Cmd("git fetch", ""),
487 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
488 Cmd("git fetch", ""),
489 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
491 args = ["--branch", "candidates", "ab12345"]
492 self._state["version"] = "tag_name"
493 self._state["commit_title"] = "Title"
494 self.assertRaises(Exception,
495 lambda: self.RunStep(MergeToBranch, TagRevision, args))
497 def testReadAndPersistVersion(self):
498 self.WriteFakeVersionFile(build=5)
499 step = self.MakeStep()
500 step.ReadAndPersistVersion()
501 self.assertEquals("3", step["major"])
502 self.assertEquals("22", step["minor"])
503 self.assertEquals("5", step["build"])
504 self.assertEquals("0", step["patch"])
507 self.assertEqual("(issue 321)",
508 re.sub(r"BUG=v8:(.*)$", r"(issue \1)", "BUG=v8:321"))
509 self.assertEqual("(Chromium issue 321)",
510 re.sub(r"BUG=(.*)$", r"(Chromium issue \1)", "BUG=321"))
512 cl = " too little\n\ttab\ttab\n too much\n trailing "
513 cl = MSub(r"\t", r" ", cl)
514 cl = MSub(r"^ {1,7}([^ ])", r" \1", cl)
515 cl = MSub(r"^ {9,80}([^ ])", r" \1", cl)
516 cl = MSub(r" +$", r"", cl)
517 self.assertEqual(" too little\n"
522 self.assertEqual("//\n#define V8_BUILD_NUMBER 3\n",
523 MSub(r"(?<=#define V8_BUILD_NUMBER)(?P<space>\s+)\d*$",
525 "//\n#define V8_BUILD_NUMBER 321\n"))
527 def testPreparePushRevision(self):
528 # Tests the default push hash used when the --revision option is not set.
530 Cmd("git log -1 --format=%H HEAD", "push_hash")
533 self.RunStep(PushToCandidates, PreparePushRevision)
534 self.assertEquals("push_hash", self._state["push_hash"])
536 def testPrepareChangeLog(self):
537 self.WriteFakeVersionFile()
538 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
541 Cmd("git log --format=%H 1234..push_hash", "rev1\nrev2\nrev3\nrev4"),
542 Cmd("git log -1 --format=%s rev1", "Title text 1"),
543 Cmd("git log -1 --format=%B rev1", "Title\n\nBUG=\nLOG=y\n"),
544 Cmd("git log -1 --format=%an rev1", "author1@chromium.org"),
545 Cmd("git log -1 --format=%s rev2", "Title text 2."),
546 Cmd("git log -1 --format=%B rev2", "Title\n\nBUG=123\nLOG= \n"),
547 Cmd("git log -1 --format=%an rev2", "author2@chromium.org"),
548 Cmd("git log -1 --format=%s rev3", "Title text 3"),
549 Cmd("git log -1 --format=%B rev3", "Title\n\nBUG=321\nLOG=true\n"),
550 Cmd("git log -1 --format=%an rev3", "author3@chromium.org"),
551 Cmd("git log -1 --format=%s rev4", "Title text 4"),
552 Cmd("git log -1 --format=%B rev4",
553 ("Title\n\nBUG=456\nLOG=Y\n\n"
554 "Review URL: https://codereview.chromium.org/9876543210\n")),
555 URL("https://codereview.chromium.org/9876543210/description",
556 "Title\n\nBUG=456\nLOG=N\n\n"),
557 Cmd("git log -1 --format=%an rev4", "author4@chromium.org"),
560 self._state["last_push_master"] = "1234"
561 self._state["push_hash"] = "push_hash"
562 self._state["version"] = "3.22.5"
563 self.RunStep(PushToCandidates, PrepareChangeLog)
565 actual_cl = FileToText(TEST_CONFIG["CHANGELOG_ENTRY_FILE"])
567 expected_cl = """1999-07-31: Version 3.22.5
571 Title text 3 (Chromium issue 321).
573 Performance and stability improvements on all platforms.
575 # The change log above is auto-generated. Please review if all relevant
576 # commit messages from the list below are included.
577 # All lines starting with # will be stripped.
580 # (author1@chromium.org)
582 # Title text 2 (Chromium issue 123).
583 # (author2@chromium.org)
585 # Title text 3 (Chromium issue 321).
586 # (author3@chromium.org)
588 # Title text 4 (Chromium issue 456).
589 # (author4@chromium.org)
593 self.assertEquals(expected_cl, actual_cl)
595 def testEditChangeLog(self):
596 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
597 TextToFile(" New \n\tLines \n", TEST_CONFIG["CHANGELOG_ENTRY_FILE"])
598 os.environ["EDITOR"] = "vi"
600 RL(""), # Open editor.
601 Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], ""),
604 self.RunStep(PushToCandidates, EditChangeLog)
606 self.assertEquals("New\n Lines",
607 FileToText(TEST_CONFIG["CHANGELOG_ENTRY_FILE"]))
617 # Version as tag: 3.22.4.0. Version on master: 3.22.6.
618 # Make sure that the latest version is 3.22.6.0.
619 def testIncrementVersion(self):
621 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
622 Cmd("git tag", self.TAGS),
623 Cmd("git checkout -f origin/master -- include/v8-version.h",
624 "", cb=lambda: self.WriteFakeVersionFile(3, 22, 6)),
627 self.RunStep(PushToCandidates, IncrementVersion)
629 self.assertEquals("3", self._state["new_major"])
630 self.assertEquals("22", self._state["new_minor"])
631 self.assertEquals("7", self._state["new_build"])
632 self.assertEquals("0", self._state["new_patch"])
634 def _TestSquashCommits(self, change_log, expected_msg):
635 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
636 with open(TEST_CONFIG["CHANGELOG_ENTRY_FILE"], "w") as f:
640 Cmd("git diff origin/candidates hash1", "patch content"),
643 self._state["push_hash"] = "hash1"
644 self._state["date"] = "1999-11-11"
646 self.RunStep(PushToCandidates, SquashCommits)
647 self.assertEquals(FileToText(TEST_CONFIG["COMMITMSG_FILE"]), expected_msg)
649 patch = FileToText(TEST_CONFIG["PATCH_FILE"])
650 self.assertTrue(re.search(r"patch content", patch))
652 def testSquashCommitsUnformatted(self):
653 change_log = """1999-11-11: Version 3.22.5
658 Performance and stability improvements on all platforms.\n"""
659 commit_msg = """Version 3.22.5 (based on hash1)
661 Log text 1. Chromium issue 12345
663 Performance and stability improvements on all platforms."""
664 self._TestSquashCommits(change_log, commit_msg)
666 def testSquashCommitsFormatted(self):
667 change_log = """1999-11-11: Version 3.22.5
669 Long commit message that fills more than 80 characters (Chromium issue
672 Performance and stability improvements on all platforms.\n"""
673 commit_msg = """Version 3.22.5 (based on hash1)
675 Long commit message that fills more than 80 characters (Chromium issue 12345).
677 Performance and stability improvements on all platforms."""
678 self._TestSquashCommits(change_log, commit_msg)
680 def testSquashCommitsQuotationMarks(self):
681 change_log = """Line with "quotation marks".\n"""
682 commit_msg = """Line with "quotation marks"."""
683 self._TestSquashCommits(change_log, commit_msg)
685 def testBootstrapper(self):
686 work_dir = self.MakeEmptyTempDirectory()
687 class FakeScript(ScriptsBase):
691 # Use the test configuration without the fake testing default work dir.
692 fake_config = dict(TEST_CONFIG)
693 del(fake_config["DEFAULT_CWD"])
696 Cmd("fetch v8", "", cwd=work_dir),
698 FakeScript(fake_config, self).Run(["--work-dir", work_dir])
700 def _PushToCandidates(self, force=False, manual=False):
701 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
703 # The version file on master has build level 5, while the version
704 # file from candidates has build level 4.
705 self.WriteFakeVersionFile(build=5)
707 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
708 master_change_log = "2014-03-17: Sentinel\n"
709 TextToFile(master_change_log,
710 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
711 os.environ["EDITOR"] = "vi"
713 commit_msg_squashed = """Version 3.22.5 (squashed - based on push_hash)
715 Log text 1 (issue 321).
717 Performance and stability improvements on all platforms."""
719 commit_msg = """Version 3.22.5 (based on push_hash)
721 Log text 1 (issue 321).
723 Performance and stability improvements on all platforms."""
725 def ResetChangeLog():
726 """On 'git co -b new_branch origin/candidates',
727 and 'git checkout -- ChangeLog',
728 the ChangLog will be reset to its content on candidates."""
729 candidates_change_log = """1999-04-05: Version 3.22.4
731 Performance and stability improvements on all platforms.\n"""
732 TextToFile(candidates_change_log,
733 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
735 def ResetToCandidates():
737 self.WriteFakeVersionFile()
739 def CheckVersionCommit():
740 commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
741 self.assertEquals(commit_msg, commit)
742 version = FileToText(
743 os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
744 self.assertTrue(re.search(r"#define V8_MINOR_VERSION\s+22", version))
745 self.assertTrue(re.search(r"#define V8_BUILD_NUMBER\s+5", version))
746 self.assertFalse(re.search(r"#define V8_BUILD_NUMBER\s+6", version))
747 self.assertTrue(re.search(r"#define V8_PATCH_LEVEL\s+0", version))
749 re.search(r"#define V8_IS_CANDIDATE_VERSION\s+0", version))
751 # Check that the change log on the candidates branch got correctly
753 change_log = FileToText(
754 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
756 """1999-07-31: Version 3.22.5
758 Log text 1 (issue 321).
760 Performance and stability improvements on all platforms.
763 1999-04-05: Version 3.22.4
765 Performance and stability improvements on all platforms.\n""",
768 force_flag = " -f" if not manual else ""
771 expectations.append(Cmd("which vi", "/usr/bin/vi"))
773 Cmd("git status -s -uno", ""),
774 Cmd("git checkout -f origin/master", ""),
775 Cmd("git fetch", ""),
776 Cmd("git branch", " branch1\n* branch2\n"),
777 Cmd("git branch", " branch1\n* branch2\n"),
778 Cmd(("git new-branch %s --upstream origin/master" %
779 TEST_CONFIG["BRANCHNAME"]), ""),
780 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
781 Cmd("git tag", self.TAGS),
782 Cmd("git checkout -f origin/master -- include/v8-version.h",
783 "", cb=self.WriteFakeVersionFile),
784 Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"),
785 Cmd("git log -1 --format=%s release_hash",
786 "Version 3.22.4 (based on abc3)\n"),
787 Cmd("git log --format=%H abc3..push_hash", "rev1\n"),
788 Cmd("git log -1 --format=%s rev1", "Log text 1.\n"),
789 Cmd("git log -1 --format=%B rev1", "Text\nLOG=YES\nBUG=v8:321\nText\n"),
790 Cmd("git log -1 --format=%an rev1", "author1@chromium.org\n"),
793 expectations.append(RL("")) # Open editor.
796 Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], ""))
798 Cmd("git fetch", ""),
799 Cmd("git checkout -f origin/master", ""),
800 Cmd("git diff origin/candidates push_hash", "patch content\n"),
801 Cmd(("git new-branch %s --upstream origin/candidates" %
802 TEST_CONFIG["CANDIDATESBRANCH"]), "", cb=ResetToCandidates),
803 Cmd("git apply --index --reject \"%s\"" % TEST_CONFIG["PATCH_FILE"], ""),
804 Cmd("git checkout -f origin/candidates -- ChangeLog", "",
806 Cmd("git checkout -f origin/candidates -- include/v8-version.h", "",
807 cb=self.WriteFakeVersionFile),
808 Cmd("git commit -am \"%s\"" % commit_msg_squashed, ""),
811 expectations.append(RL("Y")) # Sanity check.
813 Cmd("git cl land -f --bypass-hooks", ""),
814 Cmd("git checkout -f master", ""),
815 Cmd("git fetch", ""),
816 Cmd("git branch -D %s" % TEST_CONFIG["CANDIDATESBRANCH"], ""),
817 Cmd(("git new-branch %s --upstream origin/candidates" %
818 TEST_CONFIG["CANDIDATESBRANCH"]), "", cb=ResetToCandidates),
819 Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "",
820 cb=CheckVersionCommit),
821 Cmd("git cl land -f --bypass-hooks", ""),
822 Cmd("git fetch", ""),
823 Cmd("git log -1 --format=%H --grep="
824 "\"Version 3.22.5 (based on push_hash)\""
825 " origin/candidates", "hsh_to_tag"),
826 Cmd("git tag 3.22.5 hsh_to_tag", ""),
827 Cmd("git push origin 3.22.5", ""),
828 Cmd("git checkout -f origin/master", ""),
829 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
830 Cmd("git branch -D %s" % TEST_CONFIG["CANDIDATESBRANCH"], ""),
832 self.Expect(expectations)
834 args = ["-a", "author@chromium.org", "--revision", "push_hash"]
835 if force: args.append("-f")
836 if manual: args.append("-m")
837 else: args += ["-r", "reviewer@chromium.org"]
838 PushToCandidates(TEST_CONFIG, self).Run(args)
840 cl = FileToText(os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
841 self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl))
842 self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl))
843 self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl))
845 # Note: The version file is on build number 5 again in the end of this test
846 # since the git command that merges to master is mocked out.
848 def testPushToCandidatesManual(self):
849 self._PushToCandidates(manual=True)
851 def testPushToCandidatesSemiAutomatic(self):
852 self._PushToCandidates()
854 def testPushToCandidatesForced(self):
855 self._PushToCandidates(force=True)
857 def testCreateRelease(self):
858 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
860 # The version file on master has build level 5.
861 self.WriteFakeVersionFile(build=5)
863 master_change_log = "2014-03-17: Sentinel\n"
864 TextToFile(master_change_log,
865 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
867 commit_msg = """Version 3.22.5
869 Log text 1 (issue 321).
871 Performance and stability improvements on all platforms."""
873 def ResetChangeLog():
874 last_change_log = """1999-04-05: Version 3.22.4
876 Performance and stability improvements on all platforms.\n"""
877 TextToFile(last_change_log,
878 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
881 def CheckVersionCommit():
882 commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
883 self.assertEquals(commit_msg, commit)
884 version = FileToText(
885 os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
886 self.assertTrue(re.search(r"#define V8_MINOR_VERSION\s+22", version))
887 self.assertTrue(re.search(r"#define V8_BUILD_NUMBER\s+5", version))
888 self.assertFalse(re.search(r"#define V8_BUILD_NUMBER\s+6", version))
889 self.assertTrue(re.search(r"#define V8_PATCH_LEVEL\s+0", version))
891 re.search(r"#define V8_IS_CANDIDATE_VERSION\s+0", version))
893 # Check that the change log on the candidates branch got correctly
895 change_log = FileToText(
896 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
898 """1999-07-31: Version 3.22.5
900 Log text 1 (issue 321).
902 Performance and stability improvements on all platforms.
905 1999-04-05: Version 3.22.4
907 Performance and stability improvements on all platforms.\n""",
911 Cmd("git fetch origin "
912 "+refs/heads/*:refs/heads/* "
913 "+refs/pending/*:refs/pending/* "
914 "+refs/pending-tags/*:refs/pending-tags/*", ""),
915 Cmd("git checkout -f origin/master", ""),
916 Cmd("git branch", ""),
917 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
918 Cmd("git tag", self.TAGS),
919 Cmd("git checkout -f origin/master -- include/v8-version.h",
920 "", cb=self.WriteFakeVersionFile),
921 Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"),
922 Cmd("git log -1 --format=%s release_hash", "Version 3.22.4\n"),
923 Cmd("git log -1 --format=%H release_hash^", "abc3\n"),
924 Cmd("git log --format=%H abc3..push_hash", "rev1\n"),
925 Cmd("git log -1 --format=%s rev1", "Log text 1.\n"),
926 Cmd("git log -1 --format=%B rev1", "Text\nLOG=YES\nBUG=v8:321\nText\n"),
927 Cmd("git log -1 --format=%an rev1", "author1@chromium.org\n"),
928 Cmd("git reset --hard origin/master", ""),
929 Cmd("git checkout -b work-branch push_hash", ""),
930 Cmd("git checkout -f 3.22.4 -- ChangeLog", "", cb=ResetChangeLog),
931 Cmd("git checkout -f 3.22.4 -- include/v8-version.h", "",
932 cb=self.WriteFakeVersionFile),
933 Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "",
934 cb=CheckVersionCommit),
935 Cmd("git push origin "
936 "refs/heads/work-branch:refs/pending/heads/3.22.5 "
937 "push_hash:refs/pending-tags/heads/3.22.5 "
938 "push_hash:refs/heads/3.22.5", ""),
939 Cmd("git fetch", ""),
940 Cmd("git log -1 --format=%H --grep="
941 "\"Version 3.22.5\" origin/3.22.5", "hsh_to_tag"),
942 Cmd("git tag 3.22.5 hsh_to_tag", ""),
943 Cmd("git push origin 3.22.5", ""),
944 Cmd("git checkout -f origin/master", ""),
945 Cmd("git branch", "* master\n work-branch\n"),
946 Cmd("git branch -D work-branch", ""),
949 self.Expect(expectations)
951 args = ["-a", "author@chromium.org",
952 "-r", "reviewer@chromium.org",
953 "--revision", "push_hash"]
954 CreateRelease(TEST_CONFIG, self).Run(args)
956 cl = FileToText(os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
957 self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl))
958 self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl))
959 self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl))
961 # Note: The version file is on build number 5 again in the end of this test
962 # since the git command that merges to master is mocked out.
964 C_V8_22624_LOG = """V8 CL.
966 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22624 123
970 C_V8_123455_LOG = """V8 CL.
972 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@123455 123
976 C_V8_123456_LOG = """V8 CL.
978 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@123456 123
982 ROLL_COMMIT_MSG = """Update V8 to version 3.22.4 (based on abc).
984 Summary of changes available at:
985 https://chromium.googlesource.com/v8/v8/+log/last_rol..roll_hsh
987 Please follow these instructions for assigning/CC'ing issues:
988 https://code.google.com/p/v8-wiki/wiki/TriagingIssues
990 TBR=g_name@chromium.org,reviewer@chromium.org"""
992 def testChromiumRoll(self):
993 # Setup fake directory structures.
994 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
995 TextToFile("", os.path.join(TEST_CONFIG["CHROMIUM"], ".git"))
996 chrome_dir = TEST_CONFIG["CHROMIUM"]
997 os.makedirs(os.path.join(chrome_dir, "v8"))
999 # Write fake deps file.
1000 TextToFile("Some line\n \"v8_revision\": \"123444\",\n some line",
1001 os.path.join(chrome_dir, "DEPS"))
1003 TextToFile("Some line\n \"v8_revision\": \"22624\",\n some line",
1004 os.path.join(chrome_dir, "DEPS"))
1007 Cmd("git fetch origin", ""),
1008 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
1009 Cmd("git log -1 --format=%s roll_hsh",
1010 "Version 3.22.4 (based on abc)\n"),
1011 Cmd("git describe --tags roll_hsh", "3.22.4"),
1012 Cmd("git describe --tags last_roll_hsh", "3.22.2.1"),
1013 URL("https://chromium-build.appspot.com/p/chromium/sheriff_v8.js",
1014 "document.write('g_name')"),
1015 Cmd("git status -s -uno", "", cwd=chrome_dir),
1016 Cmd("git checkout -f master", "", cwd=chrome_dir),
1017 Cmd("gclient sync --nohooks", "syncing...", cwd=chrome_dir),
1018 Cmd("git pull", "", cwd=chrome_dir),
1019 Cmd("git fetch origin", ""),
1020 Cmd("git new-branch v8-roll-roll_hsh", "", cwd=chrome_dir),
1021 Cmd("roll-dep v8 roll_hsh", "rolled", cb=WriteDeps, cwd=chrome_dir),
1022 Cmd(("git commit -am \"%s\" "
1023 "--author \"author@chromium.org <author@chromium.org>\"" %
1024 self.ROLL_COMMIT_MSG),
1025 "", cwd=chrome_dir),
1026 Cmd("git cl upload --send-mail --email \"author@chromium.org\" -f", "",
1029 self.Expect(expectations)
1031 args = ["-a", "author@chromium.org", "-c", chrome_dir,
1033 "-r", "reviewer@chromium.org",
1034 "--last-roll", "last_roll_hsh",
1036 ChromiumRoll(TEST_CONFIG, self).Run(args)
1038 deps = FileToText(os.path.join(chrome_dir, "DEPS"))
1039 self.assertTrue(re.search("\"v8_revision\": \"22624\"", deps))
1041 def testCheckLastPushRecently(self):
1043 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
1044 Cmd("git tag", self.TAGS),
1045 Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"),
1046 Cmd("git log -1 --format=%s release_hash",
1047 "Version 3.22.4 (based on abc3)\n"),
1048 Cmd("git log --format=%H abc3..abc123", "\n"),
1051 self._state["candidate"] = "abc123"
1052 self.assertEquals(0, self.RunStep(
1053 auto_push.AutoPush, LastReleaseBailout, AUTO_PUSH_ARGS))
1055 def testAutoPush(self):
1057 Cmd("git fetch", ""),
1058 Cmd("git fetch origin +refs/heads/roll:refs/heads/roll", ""),
1059 Cmd("git show-ref -s refs/heads/roll", "abc123\n"),
1060 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
1061 Cmd("git tag", self.TAGS),
1062 Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"),
1063 Cmd("git log -1 --format=%s release_hash",
1064 "Version 3.22.4 (based on abc3)\n"),
1065 Cmd("git log --format=%H abc3..abc123", "some_stuff\n"),
1068 auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS + ["--push"])
1070 state = json.loads(FileToText("%s-state.json"
1071 % TEST_CONFIG["PERSISTFILE_BASENAME"]))
1073 self.assertEquals("abc123", state["candidate"])
1075 def testAutoRollExistingRoll(self):
1077 URL("https://codereview.chromium.org/search",
1078 "owner=author%40chromium.org&limit=30&closed=3&format=json",
1079 ("{\"results\": [{\"subject\": \"different\"},"
1080 "{\"subject\": \"Update V8 to Version...\"}]}")),
1083 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
1084 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"]])
1085 self.assertEquals(0, result)
1087 # Snippet from the original DEPS file.
1090 "v8_revision": "abcd123455",
1094 (Var("googlecode_url") % "v8") + "/" + Var("v8_branch") + "@" +
1099 def testAutoRollUpToDate(self):
1100 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
1101 TextToFile(self.FAKE_DEPS, os.path.join(TEST_CONFIG["CHROMIUM"], "DEPS"))
1103 URL("https://codereview.chromium.org/search",
1104 "owner=author%40chromium.org&limit=30&closed=3&format=json",
1105 ("{\"results\": [{\"subject\": \"different\"}]}")),
1106 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
1107 Cmd("git rev-list --max-age=740800 --tags",
1108 "bad_tag\nhash_234\nhash_123"),
1109 Cmd("git describe --tags bad_tag", ""),
1110 Cmd("git describe --tags hash_234", "3.22.4"),
1111 Cmd("git describe --tags hash_123", "3.22.3"),
1112 Cmd("git describe --tags abcd123455", "3.22.4"),
1113 Cmd("git describe --tags hash_234", "3.22.4"),
1114 Cmd("git describe --tags hash_123", "3.22.3"),
1117 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
1118 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"]])
1119 self.assertEquals(0, result)
1121 def testAutoRoll(self):
1122 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
1123 TextToFile(self.FAKE_DEPS, os.path.join(TEST_CONFIG["CHROMIUM"], "DEPS"))
1126 URL("https://codereview.chromium.org/search",
1127 "owner=author%40chromium.org&limit=30&closed=3&format=json",
1128 ("{\"results\": [{\"subject\": \"different\"}]}")),
1129 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
1130 Cmd("git rev-list --max-age=740800 --tags",
1131 "bad_tag\nhash_234\nhash_123"),
1132 Cmd("git describe --tags bad_tag", ""),
1133 Cmd("git describe --tags hash_234", "3.22.4"),
1134 Cmd("git describe --tags hash_123", "3.22.3"),
1135 Cmd("git describe --tags abcd123455", "3.22.3.1"),
1136 Cmd("git describe --tags hash_234", "3.22.4"),
1139 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
1140 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"], "--roll"])
1141 self.assertEquals(0, result)
1143 def testMergeToBranch(self):
1144 TEST_CONFIG["ALREADY_MERGING_SENTINEL_FILE"] = self.MakeEmptyTempFile()
1145 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
1146 self.WriteFakeVersionFile(build=5)
1147 os.environ["EDITOR"] = "vi"
1148 extra_patch = self.MakeEmptyTempFile()
1150 def VerifyPatch(patch):
1151 return lambda: self.assertEquals(patch,
1152 FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"]))
1154 msg = """Version 3.22.5.1 (cherry-pick)
1172 BUG=123,234,345,456,567,v8:123
1177 commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
1178 self.assertEquals(msg, commit)
1179 version = FileToText(
1180 os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
1181 self.assertTrue(re.search(r"#define V8_MINOR_VERSION\s+22", version))
1182 self.assertTrue(re.search(r"#define V8_BUILD_NUMBER\s+5", version))
1183 self.assertTrue(re.search(r"#define V8_PATCH_LEVEL\s+1", version))
1185 re.search(r"#define V8_IS_CANDIDATE_VERSION\s+0", version))
1188 Cmd("git status -s -uno", ""),
1189 Cmd("git checkout -f origin/master", ""),
1190 Cmd("git fetch", ""),
1191 Cmd("git branch", " branch1\n* branch2\n"),
1192 Cmd("git new-branch %s --upstream refs/remotes/origin/candidates" %
1193 TEST_CONFIG["BRANCHNAME"], ""),
1194 Cmd(("git log --format=%H --grep=\"Port ab12345\" "
1195 "--reverse origin/master"),
1196 "ab45678\nab23456"),
1197 Cmd("git log -1 --format=%s ab45678", "Title1"),
1198 Cmd("git log -1 --format=%s ab23456", "Title2"),
1199 Cmd(("git log --format=%H --grep=\"Port ab23456\" "
1200 "--reverse origin/master"),
1202 Cmd(("git log --format=%H --grep=\"Port ab34567\" "
1203 "--reverse origin/master"),
1205 Cmd("git log -1 --format=%s ab56789", "Title3"),
1206 RL("Y"), # Automatically add corresponding ports (ab34567, ab56789)?
1207 # Simulate git being down which stops the script.
1208 Cmd("git log -1 --format=%s ab12345", None),
1209 # Restart script in the failing step.
1210 Cmd("git log -1 --format=%s ab12345", "Title4"),
1211 Cmd("git log -1 --format=%s ab23456", "Title2"),
1212 Cmd("git log -1 --format=%s ab34567", "Title3"),
1213 Cmd("git log -1 --format=%s ab45678", "Title1"),
1214 Cmd("git log -1 --format=%s ab56789", "Revert \"Something\""),
1215 Cmd("git log -1 ab12345", "Title4\nBUG=123\nBUG=234"),
1216 Cmd("git log -1 ab23456", "Title2\n BUG = v8:123,345"),
1217 Cmd("git log -1 ab34567", "Title3\nLOG=n\nBUG=567, 456"),
1218 Cmd("git log -1 ab45678", "Title1\nBUG="),
1219 Cmd("git log -1 ab56789", "Revert \"Something\"\nBUG=none"),
1220 Cmd("git log -1 -p ab12345", "patch4"),
1221 Cmd(("git apply --index --reject \"%s\"" %
1222 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1223 "", cb=VerifyPatch("patch4")),
1224 Cmd("git log -1 -p ab23456", "patch2"),
1225 Cmd(("git apply --index --reject \"%s\"" %
1226 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1227 "", cb=VerifyPatch("patch2")),
1228 Cmd("git log -1 -p ab34567", "patch3"),
1229 Cmd(("git apply --index --reject \"%s\"" %
1230 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1231 "", cb=VerifyPatch("patch3")),
1232 Cmd("git log -1 -p ab45678", "patch1"),
1233 Cmd(("git apply --index --reject \"%s\"" %
1234 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1235 "", cb=VerifyPatch("patch1")),
1236 Cmd("git log -1 -p ab56789", "patch5\n"),
1237 Cmd(("git apply --index --reject \"%s\"" %
1238 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1239 "", cb=VerifyPatch("patch5\n")),
1240 Cmd("git apply --index --reject \"%s\"" % extra_patch, ""),
1241 RL("Y"), # Automatically increment patch level?
1242 Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], ""),
1243 RL("reviewer@chromium.org"), # V8 reviewer.
1244 Cmd("git cl upload --send-mail -r \"reviewer@chromium.org\" "
1245 "--bypass-hooks --cc \"ulan@chromium.org\"", ""),
1246 Cmd("git checkout -f %s" % TEST_CONFIG["BRANCHNAME"], ""),
1247 RL("LGTM"), # Enter LGTM for V8 CL.
1248 Cmd("git cl presubmit", "Presubmit successfull\n"),
1249 Cmd("git cl land -f --bypass-hooks", "Closing issue\n",
1251 Cmd("git fetch", ""),
1252 Cmd("git log -1 --format=%H --grep=\""
1253 "Version 3.22.5.1 (cherry-pick)"
1254 "\" refs/remotes/origin/candidates",
1256 Cmd("git fetch", ""),
1257 Cmd("git log -1 --format=%H --grep=\""
1258 "Version 3.22.5.1 (cherry-pick)"
1259 "\" refs/remotes/origin/candidates",
1261 Cmd("git tag 3.22.5.1 hsh_to_tag", ""),
1262 Cmd("git push origin 3.22.5.1", ""),
1263 Cmd("git checkout -f origin/master", ""),
1264 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
1267 # ab12345 and ab34567 are patches. ab23456 (included) and ab45678 are the
1268 # MIPS ports of ab12345. ab56789 is the MIPS port of ab34567.
1269 args = ["-f", "-p", extra_patch, "--branch", "candidates",
1270 "ab12345", "ab23456", "ab34567"]
1272 # The first run of the script stops because of git being down.
1273 self.assertRaises(GitFailedException,
1274 lambda: MergeToBranch(TEST_CONFIG, self).Run(args))
1276 # Test that state recovery after restarting the script works.
1278 MergeToBranch(TEST_CONFIG, self).Run(args)
1280 def testReleases(self):
1281 c_hash1_commit_log = """Update V8 to Version 4.2.71.
1283 Cr-Commit-Position: refs/heads/master@{#5678}
1285 c_hash2_commit_log = """Revert something.
1291 > Cr-Commit-Position: refs/heads/master@{#12345}
1292 > git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12345 003-1c4
1294 Review URL: https://codereview.chromium.org/12345
1296 Cr-Commit-Position: refs/heads/master@{#4567}
1297 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4567 0039-1c4b
1300 c_hash3_commit_log = """Simple.
1302 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3456 0039-1c4b
1305 c_hash_234_commit_log = """Version 3.3.1.1 (cherry-pick).
1309 Review URL: fake.com
1311 Cr-Commit-Position: refs/heads/candidates@{#234}
1313 c_hash_123_commit_log = """Version 3.3.1.0
1315 git-svn-id: googlecode@123 0039-1c4b
1317 c_hash_345_commit_log = """Version 3.4.0.
1319 Cr-Commit-Position: refs/heads/candidates@{#345}
1321 c_hash_456_commit_log = """Version 4.2.71.
1323 Cr-Commit-Position: refs/heads/4.2.71@{#1}
1326 json_output = self.MakeEmptyTempFile()
1327 csv_output = self.MakeEmptyTempFile()
1328 self.WriteFakeVersionFile()
1330 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
1331 chrome_dir = TEST_CONFIG["CHROMIUM"]
1332 chrome_v8_dir = os.path.join(chrome_dir, "v8")
1333 os.makedirs(chrome_v8_dir)
1334 def WriteDEPS(revision):
1335 TextToFile("Line\n \"v8_revision\": \"%s\",\n line\n" % revision,
1336 os.path.join(chrome_dir, "DEPS"))
1339 def ResetVersion(major, minor, build, patch=0):
1340 return lambda: self.WriteFakeVersionFile(major=major,
1345 def ResetDEPS(revision):
1346 return lambda: WriteDEPS(revision)
1349 Cmd("git status -s -uno", ""),
1350 Cmd("git checkout -f origin/master", ""),
1351 Cmd("git fetch", ""),
1352 Cmd("git branch", " branch1\n* branch2\n"),
1353 Cmd("git new-branch %s" % TEST_CONFIG["BRANCHNAME"], ""),
1354 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
1355 Cmd("git rev-list --max-age=395200 --tags",
1356 "bad_tag\nhash_234\nhash_123\nhash_345\nhash_456\n"),
1357 Cmd("git describe --tags bad_tag", "3.23.42-1-deadbeef"),
1358 Cmd("git describe --tags hash_234", "3.3.1.1"),
1359 Cmd("git describe --tags hash_123", "3.21.2"),
1360 Cmd("git describe --tags hash_345", "3.22.3"),
1361 Cmd("git describe --tags hash_456", "4.2.71"),
1362 Cmd("git diff --name-only hash_234 hash_234^", VERSION_FILE),
1363 Cmd("git checkout -f hash_234 -- %s" % VERSION_FILE, "",
1364 cb=ResetVersion(3, 3, 1, 1)),
1365 Cmd("git branch -r --contains hash_234", " branch-heads/3.3\n"),
1366 Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log),
1367 Cmd("git log -1 --format=%s hash_234", ""),
1368 Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log),
1369 Cmd("git log -1 --format=%ci hash_234", "18:15"),
1370 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1371 cb=ResetVersion(3, 22, 5)),
1372 Cmd("git diff --name-only hash_123 hash_123^", VERSION_FILE),
1373 Cmd("git checkout -f hash_123 -- %s" % VERSION_FILE, "",
1374 cb=ResetVersion(3, 21, 2)),
1375 Cmd("git branch -r --contains hash_123", " branch-heads/3.21\n"),
1376 Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log),
1377 Cmd("git log -1 --format=%s hash_123", ""),
1378 Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log),
1379 Cmd("git log -1 --format=%ci hash_123", "03:15"),
1380 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1381 cb=ResetVersion(3, 22, 5)),
1382 Cmd("git diff --name-only hash_345 hash_345^", VERSION_FILE),
1383 Cmd("git checkout -f hash_345 -- %s" % VERSION_FILE, "",
1384 cb=ResetVersion(3, 22, 3)),
1385 Cmd("git branch -r --contains hash_345", " origin/candidates\n"),
1386 Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log),
1387 Cmd("git log -1 --format=%s hash_345", ""),
1388 Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log),
1389 Cmd("git log -1 --format=%ci hash_345", ""),
1390 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1391 cb=ResetVersion(3, 22, 5)),
1392 Cmd("git diff --name-only hash_456 hash_456^", VERSION_FILE),
1393 Cmd("git checkout -f hash_456 -- %s" % VERSION_FILE, "",
1394 cb=ResetVersion(4, 2, 71)),
1395 Cmd("git branch -r --contains hash_456", " origin/4.2.71\n"),
1396 Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log),
1397 Cmd("git log -1 --format=%H 4.2.71", "hash_456"),
1398 Cmd("git log -1 --format=%s hash_456", "Version 4.2.71"),
1399 Cmd("git log -1 --format=%H hash_456^", "master_456"),
1400 Cmd("git log -1 --format=%B master_456",
1401 "Cr-Commit-Position: refs/heads/master@{#456}"),
1402 Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log),
1403 Cmd("git log -1 --format=%ci hash_456", "02:15"),
1404 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1405 cb=ResetVersion(3, 22, 5)),
1406 Cmd("git status -s -uno", "", cwd=chrome_dir),
1407 Cmd("git checkout -f master", "", cwd=chrome_dir),
1408 Cmd("git pull", "", cwd=chrome_dir),
1409 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"],
1411 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], "",
1413 Cmd("git new-branch %s" % TEST_CONFIG["BRANCHNAME"], "",
1415 Cmd("git fetch origin", "", cwd=chrome_v8_dir),
1416 Cmd("git log --format=%H --grep=\"V8\"",
1417 "c_hash0\nc_hash1\nc_hash2\nc_hash3\n",
1419 Cmd("git diff --name-only c_hash0 c_hash0^", "", cwd=chrome_dir),
1420 Cmd("git diff --name-only c_hash1 c_hash1^", "DEPS", cwd=chrome_dir),
1421 Cmd("git checkout -f c_hash1 -- DEPS", "",
1422 cb=ResetDEPS("hash_456"),
1424 Cmd("git log -1 --format=%B c_hash1", c_hash1_commit_log,
1426 Cmd("git diff --name-only c_hash2 c_hash2^", "DEPS", cwd=chrome_dir),
1427 Cmd("git checkout -f c_hash2 -- DEPS", "",
1428 cb=ResetDEPS("hash_345"),
1430 Cmd("git log -1 --format=%B c_hash2", c_hash2_commit_log,
1432 Cmd("git diff --name-only c_hash3 c_hash3^", "DEPS", cwd=chrome_dir),
1433 Cmd("git checkout -f c_hash3 -- DEPS", "", cb=ResetDEPS("deadbeef"),
1435 Cmd("git log -1 --format=%B c_hash3", c_hash3_commit_log,
1437 Cmd("git checkout -f HEAD -- DEPS", "", cb=ResetDEPS("hash_567"),
1439 Cmd("git branch -r", " weird/123\n branch-heads/7\n", cwd=chrome_dir),
1440 Cmd("git checkout -f branch-heads/7 -- DEPS", "",
1441 cb=ResetDEPS("hash_345"),
1443 Cmd("git checkout -f HEAD -- DEPS", "", cb=ResetDEPS("hash_567"),
1445 Cmd("git checkout -f master", "", cwd=chrome_dir),
1446 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], "", cwd=chrome_dir),
1447 Cmd("git checkout -f origin/master", ""),
1448 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
1451 args = ["-c", TEST_CONFIG["CHROMIUM"],
1452 "--json", json_output,
1453 "--csv", csv_output,
1454 "--max-releases", "1"]
1455 Releases(TEST_CONFIG, self).Run(args)
1457 # Check expected output.
1458 csv = ("4.2.71,4.2.71,1,5678,\r\n"
1459 "3.22.3,candidates,345,4567:5677,\r\n"
1460 "3.21.2,3.21,123,,\r\n"
1461 "3.3.1.1,3.3,234,,abc12\r\n")
1462 self.assertEquals(csv, FileToText(csv_output))
1467 "revision_git": "hash_456",
1468 "master_position": "456",
1469 "master_hash": "master_456",
1470 "patches_merged": "",
1471 "version": "4.2.71",
1472 "chromium_revision": "5678",
1476 "chromium_branch": "",
1477 # FIXME(machenbach): Fix revisions link for git.
1478 "revision_link": "https://code.google.com/p/v8/source/detail?r=1",
1482 "revision_git": "hash_345",
1483 "master_position": "",
1485 "patches_merged": "",
1486 "version": "3.22.3",
1487 "chromium_revision": "4567:5677",
1488 "branch": "candidates",
1491 "chromium_branch": "7",
1492 "revision_link": "https://code.google.com/p/v8/source/detail?r=345",
1496 "revision_git": "hash_123",
1497 "patches_merged": "",
1498 "master_position": "",
1500 "version": "3.21.2",
1501 "chromium_revision": "",
1505 "chromium_branch": "",
1506 "revision_link": "https://code.google.com/p/v8/source/detail?r=123",
1510 "revision_git": "hash_234",
1511 "patches_merged": "abc12",
1512 "master_position": "",
1514 "version": "3.3.1.1",
1515 "chromium_revision": "",
1517 "review_link": "fake.com",
1519 "chromium_branch": "",
1520 "revision_link": "https://code.google.com/p/v8/source/detail?r=234",
1523 self.assertEquals(expected_json, json.loads(FileToText(json_output)))
1526 class SystemTest(unittest.TestCase):
1527 def testReload(self):
1528 options = ScriptsBase(
1529 TEST_CONFIG, DEFAULT_SIDE_EFFECT_HANDLER, {}).MakeOptions([])
1530 step = MakeStep(step_class=PrepareChangeLog, number=0, state={}, config={},
1532 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER)
1534 """------------------------------------------------------------------------
1535 r17997 | machenbach@chromium.org | 2013-11-22 11:04:04 +0100 (...) | 6 lines
1537 Prepare push to trunk. Now working on version 3.23.11.
1539 R=danno@chromium.org
1541 Review URL: https://codereview.chromium.org/83173002
1543 ------------------------------------------------------------------------""")
1545 """Prepare push to trunk. Now working on version 3.23.11.
1547 R=danno@chromium.org
1549 Committed: https://code.google.com/p/v8/source/detail?r=17997""", body)