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",
67 "CLUSTERFUZZ_API_KEY_FILE": "/tmp/test-fake-cf-api-key",
72 "-a", "author@chromium.org",
73 "-r", "reviewer@chromium.org",
77 class ToplevelTest(unittest.TestCase):
78 def testSortBranches(self):
79 S = releases.SortBranches
80 self.assertEquals(["3.1", "2.25"], S(["2.25", "3.1"])[0:2])
81 self.assertEquals(["3.0", "2.25"], S(["2.25", "3.0", "2.24"])[0:2])
82 self.assertEquals(["3.11", "3.2"], S(["3.11", "3.2", "2.24"])[0:2])
84 def testFilterDuplicatesAndReverse(self):
85 F = releases.FilterDuplicatesAndReverse
86 self.assertEquals([], F([]))
87 self.assertEquals([["100", "10"]], F([["100", "10"]]))
88 self.assertEquals([["99", "9"], ["100", "10"]],
89 F([["100", "10"], ["99", "9"]]))
90 self.assertEquals([["98", "9"], ["100", "10"]],
91 F([["100", "10"], ["99", "9"], ["98", "9"]]))
92 self.assertEquals([["98", "9"], ["99", "10"]],
93 F([["100", "10"], ["99", "10"], ["98", "9"]]))
95 def testBuildRevisionRanges(self):
96 B = releases.BuildRevisionRanges
97 self.assertEquals({}, B([]))
98 self.assertEquals({"10": "100"}, B([["100", "10"]]))
99 self.assertEquals({"10": "100", "9": "99:99"},
100 B([["100", "10"], ["99", "9"]]))
101 self.assertEquals({"10": "100", "9": "97:99"},
102 B([["100", "10"], ["98", "9"], ["97", "9"]]))
103 self.assertEquals({"10": "100", "9": "99:99", "3": "91:98"},
104 B([["100", "10"], ["99", "9"], ["91", "3"]]))
105 self.assertEquals({"13": "101", "12": "100:100", "9": "94:97",
106 "3": "91:93, 98:99"},
107 B([["101", "13"], ["100", "12"], ["98", "3"],
108 ["94", "9"], ["91", "3"]]))
110 def testMakeComment(self):
111 self.assertEquals("# Line 1\n# Line 2\n#",
112 MakeComment(" Line 1\n Line 2\n"))
113 self.assertEquals("#Line 1\n#Line 2",
114 MakeComment("Line 1\n Line 2"))
116 def testStripComments(self):
117 self.assertEquals(" Line 1\n Line 3\n",
118 StripComments(" Line 1\n# Line 2\n Line 3\n#\n"))
119 self.assertEquals("\nLine 2 ### Test\n #",
120 StripComments("###\n# \n\n# Line 1\nLine 2 ### Test\n #"))
122 def testMakeChangeLogBodySimple(self):
125 "Title text 1\n\nBUG=\n",
126 "author1@chromium.org"],
128 "Title text 2\n\nBUG=1234\n",
129 "author2@chromium.org"],
131 self.assertEquals(" Title text 1.\n"
132 " (author1@chromium.org)\n\n"
133 " Title text 2 (Chromium issue 1234).\n"
134 " (author2@chromium.org)\n\n",
135 MakeChangeLogBody(commits))
137 def testMakeChangeLogBodyEmpty(self):
138 self.assertEquals("", MakeChangeLogBody([]))
140 def testMakeChangeLogBodyAutoFormat(self):
143 "Title text 1\nLOG=y\nBUG=\n",
144 "author1@chromium.org"],
146 "Title text 2\n\nBUG=1234\n",
147 "author2@chromium.org"],
149 "Title text 3\n\nBUG=1234\nLOG = Yes\n",
150 "author3@chromium.org"],
152 "Title text 4\n\nBUG=1234\nLOG=\n",
153 "author4@chromium.org"],
155 self.assertEquals(" Title text 1.\n\n"
156 " Title text 3 (Chromium issue 1234).\n\n",
157 MakeChangeLogBody(commits, True))
159 def testRegressWrongLogEntryOnTrue(self):
161 Check elimination: Learn from if(CompareMap(x)) on true branch.
164 R=verwaest@chromium.org
166 Committed: https://code.google.com/p/v8/source/detail?r=18210
168 self.assertEquals("", MakeChangeLogBody([["title", body, "author"]], True))
170 def testMakeChangeLogBugReferenceEmpty(self):
171 self.assertEquals("", MakeChangeLogBugReference(""))
172 self.assertEquals("", MakeChangeLogBugReference("LOG="))
173 self.assertEquals("", MakeChangeLogBugReference(" BUG ="))
174 self.assertEquals("", MakeChangeLogBugReference("BUG=none\t"))
176 def testMakeChangeLogBugReferenceSimple(self):
177 self.assertEquals("(issue 987654)",
178 MakeChangeLogBugReference("BUG = v8:987654"))
179 self.assertEquals("(Chromium issue 987654)",
180 MakeChangeLogBugReference("BUG=987654 "))
182 def testMakeChangeLogBugReferenceFromBody(self):
183 self.assertEquals("(Chromium issue 1234567)",
184 MakeChangeLogBugReference("Title\n\nTBR=\nBUG=\n"
185 " BUG=\tchromium:1234567\t\n"
188 def testMakeChangeLogBugReferenceMultiple(self):
189 # All issues should be sorted and grouped. Multiple references to the same
190 # issue should be filtered.
191 self.assertEquals("(issues 123, 234, Chromium issue 345)",
192 MakeChangeLogBugReference("Title\n\n"
194 " BUG\t= 345, \tv8:234,\n"
197 self.assertEquals("(Chromium issues 123, 234)",
198 MakeChangeLogBugReference("Title\n\n"
199 "BUG=234,,chromium:123 \n"
201 self.assertEquals("(Chromium issues 123, 234)",
202 MakeChangeLogBugReference("Title\n\n"
203 "BUG=chromium:234, , 123\n"
205 self.assertEquals("(issues 345, 456)",
206 MakeChangeLogBugReference("Title\n\n"
207 "\t\tBUG=v8:345,v8:456\n"
209 self.assertEquals("(issue 123, Chromium issues 345, 456)",
210 MakeChangeLogBugReference("Title\n\n"
214 "BUG=456,v8:123, 345"))
216 # TODO(machenbach): These test don't make much sense when the formatting is
218 def testMakeChangeLogBugReferenceLong(self):
219 # -----------------00--------10--------20--------30--------
220 self.assertEquals("(issues 234, 1234567890, 1234567"
221 "8901234567890, Chromium issues 12345678,"
223 MakeChangeLogBugReference("BUG=v8:234\n"
224 "BUG=v8:1234567890\n"
225 "BUG=v8:12345678901234567890\n"
228 # -----------------00--------10--------20--------30--------
229 self.assertEquals("(issues 234, 1234567890, 1234567"
230 "8901234567890, Chromium issues"
231 " 123456789, 1234567890)",
232 MakeChangeLogBugReference("BUG=v8:234\n"
233 "BUG=v8:12345678901234567890\n"
234 "BUG=v8:1234567890\n"
237 # -----------------00--------10--------20--------30--------
238 self.assertEquals("(Chromium issues 234, 1234567890"
239 ", 12345678901234567, "
240 "1234567890123456789)",
241 MakeChangeLogBugReference("BUG=234\n"
242 "BUG=12345678901234567\n"
243 "BUG=1234567890123456789\n"
247 def Cmd(*args, **kwargs):
248 """Convenience function returning a shell command test expectation."""
253 "cb": kwargs.get("cb"),
254 "cwd": kwargs.get("cwd", TEST_CONFIG["DEFAULT_CWD"]),
258 def RL(text, cb=None):
259 """Convenience function returning a readline test expectation."""
269 def URL(*args, **kwargs):
270 """Convenience function returning a readurl test expectation."""
275 "cb": kwargs.get("cb"),
280 class SimpleMock(object):
285 def Expect(self, recipe):
286 self._recipe = recipe
288 def Call(self, name, *args, **kwargs): # pragma: no cover
291 expected_call = self._recipe[self._index]
293 raise NoRetryException("Calling %s %s" % (name, " ".join(args)))
295 if not isinstance(expected_call, dict):
296 raise NoRetryException("Found wrong expectation type for %s %s" %
297 (name, " ".join(args)))
299 if expected_call["name"] != name:
300 raise NoRetryException("Expected action: %s %s - Actual: %s" %
301 (expected_call["name"], expected_call["args"], name))
303 # Check if the given working directory matches the expected one.
304 if expected_call["cwd"] != kwargs.get("cwd"):
305 raise NoRetryException("Expected cwd: %s in %s %s - Actual: %s" %
306 (expected_call["cwd"],
307 expected_call["name"],
308 expected_call["args"],
311 # The number of arguments in the expectation must match the actual
313 if len(args) > len(expected_call['args']):
314 raise NoRetryException("When calling %s with arguments, the "
315 "expectations must consist of at least as many arguments." %
318 # Compare expected and actual arguments.
319 for (expected_arg, actual_arg) in zip(expected_call['args'], args):
320 if expected_arg != actual_arg:
321 raise NoRetryException("Expected: %s - Actual: %s" %
322 (expected_arg, actual_arg))
324 # The expected call contains an optional callback for checking the context
325 # at the time of the call.
326 if expected_call['cb']:
328 expected_call['cb']()
330 tb = traceback.format_exc()
331 raise NoRetryException("Caught exception from callback: %s" % tb)
333 # If the return value is an exception, raise it instead of returning.
334 if isinstance(expected_call['ret'], Exception):
335 raise expected_call['ret']
336 return expected_call['ret']
338 def AssertFinished(self): # pragma: no cover
339 if self._index < len(self._recipe) -1:
340 raise NoRetryException("Called mock too seldom: %d vs. %d" %
341 (self._index, len(self._recipe)))
344 class ScriptTest(unittest.TestCase):
345 def MakeEmptyTempFile(self):
346 handle, name = tempfile.mkstemp()
348 self._tmp_files.append(name)
351 def MakeEmptyTempDirectory(self):
352 name = tempfile.mkdtemp()
353 self._tmp_files.append(name)
357 def WriteFakeVersionFile(self, major=3, minor=22, build=4, patch=0):
358 version_file = os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE)
359 if not os.path.exists(os.path.dirname(version_file)):
360 os.makedirs(os.path.dirname(version_file))
361 with open(version_file, "w") as f:
362 f.write(" // Some line...\n")
364 f.write("#define MAJOR_VERSION %s\n" % major)
365 f.write("#define MINOR_VERSION %s\n" % minor)
366 f.write("#define BUILD_NUMBER %s\n" % build)
367 f.write("#define PATCH_LEVEL %s\n" % patch)
368 f.write(" // Some line...\n")
369 f.write("#define IS_CANDIDATE_VERSION 0\n")
372 """Convenience wrapper."""
373 options = ScriptsBase(TEST_CONFIG, self, self._state).MakeOptions([])
374 return MakeStep(step_class=Step, state=self._state,
375 config=TEST_CONFIG, side_effect_handler=self,
378 def RunStep(self, script=PushToCandidates, step_class=Step, args=None):
379 """Convenience wrapper."""
380 args = args if args is not None else ["-m"]
381 return script(TEST_CONFIG, self, self._state).RunSteps([step_class], args)
383 def Call(self, fun, *args, **kwargs):
384 print "Calling %s with %s and %s" % (str(fun), str(args), str(kwargs))
386 def Command(self, cmd, args="", prefix="", pipe=True, cwd=None):
387 print "%s %s" % (cmd, args)
389 return self._mock.Call("command", cmd + " " + args, cwd=cwd)
392 return self._mock.Call("readline")
394 def ReadURL(self, url, params):
395 if params is not None:
396 return self._mock.Call("readurl", url, params)
398 return self._mock.Call("readurl", url)
400 def ReadClusterFuzzAPI(self, api_key, **params):
401 # TODO(machenbach): Use a mock for this and add a test that stops rolling
402 # due to clustefuzz results.
405 def Sleep(self, seconds):
411 def GetUTCStamp(self):
414 def Expect(self, *args):
415 """Convenience wrapper."""
416 self._mock.Expect(*args)
419 self._mock = SimpleMock()
422 TEST_CONFIG["DEFAULT_CWD"] = self.MakeEmptyTempDirectory()
425 if os.path.exists(TEST_CONFIG["PERSISTFILE_BASENAME"]):
426 shutil.rmtree(TEST_CONFIG["PERSISTFILE_BASENAME"])
428 # Clean up temps. Doesn't work automatically.
429 for name in self._tmp_files:
430 if os.path.isfile(name):
432 if os.path.isdir(name):
435 self._mock.AssertFinished()
437 def testGitMock(self):
438 self.Expect([Cmd("git --version", "git version 1.2.3"),
439 Cmd("git dummy", "")])
440 self.assertEquals("git version 1.2.3", self.MakeStep().Git("--version"))
441 self.assertEquals("", self.MakeStep().Git("dummy"))
443 def testCommonPrepareDefault(self):
445 Cmd("git status -s -uno", ""),
446 Cmd("git status -s -b -uno", "## some_branch"),
447 Cmd("git fetch", ""),
448 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
450 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
452 self.MakeStep().CommonPrepare()
453 self.MakeStep().PrepareBranch()
454 self.assertEquals("some_branch", self._state["current_branch"])
456 def testCommonPrepareNoConfirm(self):
458 Cmd("git status -s -uno", ""),
459 Cmd("git status -s -b -uno", "## some_branch"),
460 Cmd("git fetch", ""),
461 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
464 self.MakeStep().CommonPrepare()
465 self.assertRaises(Exception, self.MakeStep().PrepareBranch)
466 self.assertEquals("some_branch", self._state["current_branch"])
468 def testCommonPrepareDeleteBranchFailure(self):
470 Cmd("git status -s -uno", ""),
471 Cmd("git status -s -b -uno", "## some_branch"),
472 Cmd("git fetch", ""),
473 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
475 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], None),
477 self.MakeStep().CommonPrepare()
478 self.assertRaises(Exception, self.MakeStep().PrepareBranch)
479 self.assertEquals("some_branch", self._state["current_branch"])
481 def testInitialEnvironmentChecks(self):
482 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
483 os.environ["EDITOR"] = "vi"
485 Cmd("which vi", "/usr/bin/vi"),
487 self.MakeStep().InitialEnvironmentChecks(TEST_CONFIG["DEFAULT_CWD"])
489 def testTagTimeout(self):
491 Cmd("git fetch", ""),
492 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
493 Cmd("git fetch", ""),
494 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
495 Cmd("git fetch", ""),
496 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
497 Cmd("git fetch", ""),
498 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
500 args = ["--branch", "candidates", "ab12345"]
501 self._state["version"] = "tag_name"
502 self._state["commit_title"] = "Title"
503 self.assertRaises(Exception,
504 lambda: self.RunStep(MergeToBranch, TagRevision, args))
506 def testReadAndPersistVersion(self):
507 self.WriteFakeVersionFile(build=5)
508 step = self.MakeStep()
509 step.ReadAndPersistVersion()
510 self.assertEquals("3", step["major"])
511 self.assertEquals("22", step["minor"])
512 self.assertEquals("5", step["build"])
513 self.assertEquals("0", step["patch"])
516 self.assertEqual("(issue 321)",
517 re.sub(r"BUG=v8:(.*)$", r"(issue \1)", "BUG=v8:321"))
518 self.assertEqual("(Chromium issue 321)",
519 re.sub(r"BUG=(.*)$", r"(Chromium issue \1)", "BUG=321"))
521 cl = " too little\n\ttab\ttab\n too much\n trailing "
522 cl = MSub(r"\t", r" ", cl)
523 cl = MSub(r"^ {1,7}([^ ])", r" \1", cl)
524 cl = MSub(r"^ {9,80}([^ ])", r" \1", cl)
525 cl = MSub(r" +$", r"", cl)
526 self.assertEqual(" too little\n"
531 self.assertEqual("//\n#define BUILD_NUMBER 3\n",
532 MSub(r"(?<=#define BUILD_NUMBER)(?P<space>\s+)\d*$",
534 "//\n#define BUILD_NUMBER 321\n"))
536 def testPreparePushRevision(self):
537 # Tests the default push hash used when the --revision option is not set.
539 Cmd("git log -1 --format=%H HEAD", "push_hash")
542 self.RunStep(PushToCandidates, PreparePushRevision)
543 self.assertEquals("push_hash", self._state["push_hash"])
545 def testPrepareChangeLog(self):
546 self.WriteFakeVersionFile()
547 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
550 Cmd("git log --format=%H 1234..push_hash", "rev1\nrev2\nrev3\nrev4"),
551 Cmd("git log -1 --format=%s rev1", "Title text 1"),
552 Cmd("git log -1 --format=%B rev1", "Title\n\nBUG=\nLOG=y\n"),
553 Cmd("git log -1 --format=%an rev1", "author1@chromium.org"),
554 Cmd("git log -1 --format=%s rev2", "Title text 2."),
555 Cmd("git log -1 --format=%B rev2", "Title\n\nBUG=123\nLOG= \n"),
556 Cmd("git log -1 --format=%an rev2", "author2@chromium.org"),
557 Cmd("git log -1 --format=%s rev3", "Title text 3"),
558 Cmd("git log -1 --format=%B rev3", "Title\n\nBUG=321\nLOG=true\n"),
559 Cmd("git log -1 --format=%an rev3", "author3@chromium.org"),
560 Cmd("git log -1 --format=%s rev4", "Title text 4"),
561 Cmd("git log -1 --format=%B rev4",
562 ("Title\n\nBUG=456\nLOG=Y\n\n"
563 "Review URL: https://codereview.chromium.org/9876543210\n")),
564 URL("https://codereview.chromium.org/9876543210/description",
565 "Title\n\nBUG=456\nLOG=N\n\n"),
566 Cmd("git log -1 --format=%an rev4", "author4@chromium.org"),
569 self._state["last_push_master"] = "1234"
570 self._state["push_hash"] = "push_hash"
571 self._state["version"] = "3.22.5"
572 self.RunStep(PushToCandidates, PrepareChangeLog)
574 actual_cl = FileToText(TEST_CONFIG["CHANGELOG_ENTRY_FILE"])
576 expected_cl = """1999-07-31: Version 3.22.5
580 Title text 3 (Chromium issue 321).
582 Performance and stability improvements on all platforms.
584 # The change log above is auto-generated. Please review if all relevant
585 # commit messages from the list below are included.
586 # All lines starting with # will be stripped.
589 # (author1@chromium.org)
591 # Title text 2 (Chromium issue 123).
592 # (author2@chromium.org)
594 # Title text 3 (Chromium issue 321).
595 # (author3@chromium.org)
597 # Title text 4 (Chromium issue 456).
598 # (author4@chromium.org)
602 self.assertEquals(expected_cl, actual_cl)
604 def testEditChangeLog(self):
605 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
606 TextToFile(" New \n\tLines \n", TEST_CONFIG["CHANGELOG_ENTRY_FILE"])
607 os.environ["EDITOR"] = "vi"
609 RL(""), # Open editor.
610 Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], ""),
613 self.RunStep(PushToCandidates, EditChangeLog)
615 self.assertEquals("New\n Lines",
616 FileToText(TEST_CONFIG["CHANGELOG_ENTRY_FILE"]))
626 # Version as tag: 3.22.4.0. Version on master: 3.22.6.
627 # Make sure that the latest version is 3.22.6.0.
628 def testIncrementVersion(self):
630 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
631 Cmd("git tag", self.TAGS),
632 Cmd("git checkout -f origin/master -- src/version.cc",
633 "", cb=lambda: self.WriteFakeVersionFile(3, 22, 6)),
636 self.RunStep(PushToCandidates, IncrementVersion)
638 self.assertEquals("3", self._state["new_major"])
639 self.assertEquals("22", self._state["new_minor"])
640 self.assertEquals("7", self._state["new_build"])
641 self.assertEquals("0", self._state["new_patch"])
643 def _TestSquashCommits(self, change_log, expected_msg):
644 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
645 with open(TEST_CONFIG["CHANGELOG_ENTRY_FILE"], "w") as f:
649 Cmd("git diff origin/candidates hash1", "patch content"),
652 self._state["push_hash"] = "hash1"
653 self._state["date"] = "1999-11-11"
655 self.RunStep(PushToCandidates, SquashCommits)
656 self.assertEquals(FileToText(TEST_CONFIG["COMMITMSG_FILE"]), expected_msg)
658 patch = FileToText(TEST_CONFIG["PATCH_FILE"])
659 self.assertTrue(re.search(r"patch content", patch))
661 def testSquashCommitsUnformatted(self):
662 change_log = """1999-11-11: Version 3.22.5
667 Performance and stability improvements on all platforms.\n"""
668 commit_msg = """Version 3.22.5 (based on hash1)
670 Log text 1. Chromium issue 12345
672 Performance and stability improvements on all platforms."""
673 self._TestSquashCommits(change_log, commit_msg)
675 def testSquashCommitsFormatted(self):
676 change_log = """1999-11-11: Version 3.22.5
678 Long commit message that fills more than 80 characters (Chromium issue
681 Performance and stability improvements on all platforms.\n"""
682 commit_msg = """Version 3.22.5 (based on hash1)
684 Long commit message that fills more than 80 characters (Chromium issue 12345).
686 Performance and stability improvements on all platforms."""
687 self._TestSquashCommits(change_log, commit_msg)
689 def testSquashCommitsQuotationMarks(self):
690 change_log = """Line with "quotation marks".\n"""
691 commit_msg = """Line with "quotation marks"."""
692 self._TestSquashCommits(change_log, commit_msg)
694 def testBootstrapper(self):
695 work_dir = self.MakeEmptyTempDirectory()
696 class FakeScript(ScriptsBase):
700 # Use the test configuration without the fake testing default work dir.
701 fake_config = dict(TEST_CONFIG)
702 del(fake_config["DEFAULT_CWD"])
705 Cmd("fetch v8", "", cwd=work_dir),
707 FakeScript(fake_config, self).Run(["--work-dir", work_dir])
709 def _PushToCandidates(self, force=False, manual=False):
710 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
712 # The version file on master has build level 5, while the version
713 # file from candidates has build level 4.
714 self.WriteFakeVersionFile(build=5)
716 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
717 master_change_log = "2014-03-17: Sentinel\n"
718 TextToFile(master_change_log,
719 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
720 os.environ["EDITOR"] = "vi"
722 commit_msg_squashed = """Version 3.22.5 (squashed - based on push_hash)
724 Log text 1 (issue 321).
726 Performance and stability improvements on all platforms."""
728 commit_msg = """Version 3.22.5 (based on push_hash)
730 Log text 1 (issue 321).
732 Performance and stability improvements on all platforms."""
734 def ResetChangeLog():
735 """On 'git co -b new_branch origin/candidates',
736 and 'git checkout -- ChangeLog',
737 the ChangLog will be reset to its content on candidates."""
738 candidates_change_log = """1999-04-05: Version 3.22.4
740 Performance and stability improvements on all platforms.\n"""
741 TextToFile(candidates_change_log,
742 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
744 def ResetToCandidates():
746 self.WriteFakeVersionFile()
748 def CheckVersionCommit():
749 commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
750 self.assertEquals(commit_msg, commit)
751 version = FileToText(
752 os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
753 self.assertTrue(re.search(r"#define MINOR_VERSION\s+22", version))
754 self.assertTrue(re.search(r"#define BUILD_NUMBER\s+5", version))
755 self.assertFalse(re.search(r"#define BUILD_NUMBER\s+6", version))
756 self.assertTrue(re.search(r"#define PATCH_LEVEL\s+0", version))
757 self.assertTrue(re.search(r"#define IS_CANDIDATE_VERSION\s+0", version))
759 # Check that the change log on the candidates branch got correctly
761 change_log = FileToText(
762 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
764 """1999-07-31: Version 3.22.5
766 Log text 1 (issue 321).
768 Performance and stability improvements on all platforms.
771 1999-04-05: Version 3.22.4
773 Performance and stability improvements on all platforms.\n""",
776 force_flag = " -f" if not manual else ""
779 expectations.append(Cmd("which vi", "/usr/bin/vi"))
781 Cmd("git status -s -uno", ""),
782 Cmd("git status -s -b -uno", "## some_branch\n"),
783 Cmd("git fetch", ""),
784 Cmd("git branch", " branch1\n* branch2\n"),
785 Cmd("git branch", " branch1\n* branch2\n"),
786 Cmd(("git new-branch %s --upstream origin/master" %
787 TEST_CONFIG["BRANCHNAME"]), ""),
788 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
789 Cmd("git tag", self.TAGS),
790 Cmd("git checkout -f origin/master -- src/version.cc",
791 "", cb=self.WriteFakeVersionFile),
792 Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"),
793 Cmd("git log -1 --format=%s release_hash",
794 "Version 3.22.4 (based on abc3)\n"),
795 Cmd("git log --format=%H abc3..push_hash", "rev1\n"),
796 Cmd("git log -1 --format=%s rev1", "Log text 1.\n"),
797 Cmd("git log -1 --format=%B rev1", "Text\nLOG=YES\nBUG=v8:321\nText\n"),
798 Cmd("git log -1 --format=%an rev1", "author1@chromium.org\n"),
801 expectations.append(RL("")) # Open editor.
804 Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], ""))
806 Cmd("git fetch", ""),
807 Cmd("git checkout -f origin/master", ""),
808 Cmd("git diff origin/candidates push_hash", "patch content\n"),
809 Cmd(("git new-branch %s --upstream origin/candidates" %
810 TEST_CONFIG["CANDIDATESBRANCH"]), "", cb=ResetToCandidates),
811 Cmd("git apply --index --reject \"%s\"" % TEST_CONFIG["PATCH_FILE"], ""),
812 Cmd("git checkout -f origin/candidates -- ChangeLog", "",
814 Cmd("git checkout -f origin/candidates -- src/version.cc", "",
815 cb=self.WriteFakeVersionFile),
816 Cmd("git commit -am \"%s\"" % commit_msg_squashed, ""),
819 expectations.append(RL("Y")) # Sanity check.
821 Cmd("git cl land -f --bypass-hooks", ""),
822 Cmd("git checkout -f master", ""),
823 Cmd("git fetch", ""),
824 Cmd("git branch -D %s" % TEST_CONFIG["CANDIDATESBRANCH"], ""),
825 Cmd(("git new-branch %s --upstream origin/candidates" %
826 TEST_CONFIG["CANDIDATESBRANCH"]), "", cb=ResetToCandidates),
827 Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "",
828 cb=CheckVersionCommit),
829 Cmd("git cl land -f --bypass-hooks", ""),
830 Cmd("git fetch", ""),
831 Cmd("git log -1 --format=%H --grep="
832 "\"Version 3.22.5 (based on push_hash)\""
833 " origin/candidates", "hsh_to_tag"),
834 Cmd("git tag 3.22.5 hsh_to_tag", ""),
835 Cmd("git push origin 3.22.5", ""),
836 Cmd("git checkout -f some_branch", ""),
837 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
838 Cmd("git branch -D %s" % TEST_CONFIG["CANDIDATESBRANCH"], ""),
840 self.Expect(expectations)
842 args = ["-a", "author@chromium.org", "--revision", "push_hash"]
843 if force: args.append("-f")
844 if manual: args.append("-m")
845 else: args += ["-r", "reviewer@chromium.org"]
846 PushToCandidates(TEST_CONFIG, self).Run(args)
848 cl = FileToText(os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
849 self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl))
850 self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl))
851 self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl))
853 # Note: The version file is on build number 5 again in the end of this test
854 # since the git command that merges to master is mocked out.
856 def testPushToCandidatesManual(self):
857 self._PushToCandidates(manual=True)
859 def testPushToCandidatesSemiAutomatic(self):
860 self._PushToCandidates()
862 def testPushToCandidatesForced(self):
863 self._PushToCandidates(force=True)
865 def testCreateRelease(self):
866 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
868 # The version file on master has build level 5.
869 self.WriteFakeVersionFile(build=5)
871 master_change_log = "2014-03-17: Sentinel\n"
872 TextToFile(master_change_log,
873 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
875 commit_msg = """Version 3.22.5
877 Log text 1 (issue 321).
879 Performance and stability improvements on all platforms."""
881 def ResetChangeLog():
882 last_change_log = """1999-04-05: Version 3.22.4
884 Performance and stability improvements on all platforms.\n"""
885 TextToFile(last_change_log,
886 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
889 def CheckVersionCommit():
890 commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
891 self.assertEquals(commit_msg, commit)
892 version = FileToText(
893 os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
894 self.assertTrue(re.search(r"#define MINOR_VERSION\s+22", version))
895 self.assertTrue(re.search(r"#define BUILD_NUMBER\s+5", version))
896 self.assertFalse(re.search(r"#define BUILD_NUMBER\s+6", version))
897 self.assertTrue(re.search(r"#define PATCH_LEVEL\s+0", version))
898 self.assertTrue(re.search(r"#define IS_CANDIDATE_VERSION\s+0", version))
900 # Check that the change log on the candidates branch got correctly
902 change_log = FileToText(
903 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
905 """1999-07-31: Version 3.22.5
907 Log text 1 (issue 321).
909 Performance and stability improvements on all platforms.
912 1999-04-05: Version 3.22.4
914 Performance and stability improvements on all platforms.\n""",
918 Cmd("git fetch origin "
919 "+refs/heads/*:refs/heads/* "
920 "+refs/pending/*:refs/pending/* "
921 "+refs/pending-tags/*:refs/pending-tags/*", ""),
922 Cmd("git checkout -f origin/master", ""),
923 Cmd("git branch", ""),
924 Cmd("git log -1 --format=\"%H %T\" push_hash", "push_hash tree_hash"),
925 Cmd("git log -200 --format=\"%H %T\" refs/pending/heads/master",
926 "not_right wrong\npending_hash tree_hash\nsome other\n"),
927 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
928 Cmd("git tag", self.TAGS),
929 Cmd("git checkout -f origin/master -- src/version.cc",
930 "", cb=self.WriteFakeVersionFile),
931 Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"),
932 Cmd("git log -1 --format=%s release_hash", "Version 3.22.4\n"),
933 Cmd("git log -1 --format=%H release_hash^", "abc3\n"),
934 Cmd("git log --format=%H abc3..push_hash", "rev1\n"),
935 Cmd("git log -1 --format=%s rev1", "Log text 1.\n"),
936 Cmd("git log -1 --format=%B rev1", "Text\nLOG=YES\nBUG=v8:321\nText\n"),
937 Cmd("git log -1 --format=%an rev1", "author1@chromium.org\n"),
938 Cmd("git reset --hard origin/master", ""),
939 Cmd("git checkout -b work-branch pending_hash", ""),
940 Cmd("git checkout -f 3.22.4 -- ChangeLog", "", cb=ResetChangeLog),
941 Cmd("git checkout -f 3.22.4 -- src/version.cc", "",
942 cb=self.WriteFakeVersionFile),
943 Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "",
944 cb=CheckVersionCommit),
945 Cmd("git push origin "
946 "refs/heads/work-branch:refs/pending/heads/3.22.5 "
947 "pending_hash:refs/pending-tags/heads/3.22.5 "
948 "push_hash:refs/heads/3.22.5", ""),
949 Cmd("git fetch", ""),
950 Cmd("git log -1 --format=%H --grep="
951 "\"Version 3.22.5\" origin/3.22.5", "hsh_to_tag"),
952 Cmd("git tag 3.22.5 hsh_to_tag", ""),
953 Cmd("git push origin 3.22.5", ""),
954 Cmd("git checkout -f origin/master", ""),
955 Cmd("git branch", "* master\n work-branch\n"),
956 Cmd("git branch -D work-branch", ""),
959 self.Expect(expectations)
961 args = ["-a", "author@chromium.org",
962 "-r", "reviewer@chromium.org",
963 "--revision", "push_hash"]
964 CreateRelease(TEST_CONFIG, self).Run(args)
966 cl = FileToText(os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
967 self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl))
968 self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl))
969 self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl))
971 # Note: The version file is on build number 5 again in the end of this test
972 # since the git command that merges to master is mocked out.
974 C_V8_22624_LOG = """V8 CL.
976 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22624 123
980 C_V8_123455_LOG = """V8 CL.
982 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@123455 123
986 C_V8_123456_LOG = """V8 CL.
988 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@123456 123
992 def testChromiumRoll(self):
993 googlers_mapping_py = "%s-mapping.py" % TEST_CONFIG["PERSISTFILE_BASENAME"]
994 with open(googlers_mapping_py, "w") as f:
996 def list_to_dict(entries):
997 return {"g_name@google.com": "c_name@chromium.org"}
1001 # Setup fake directory structures.
1002 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
1003 TextToFile("", os.path.join(TEST_CONFIG["CHROMIUM"], ".git"))
1004 chrome_dir = TEST_CONFIG["CHROMIUM"]
1005 os.makedirs(os.path.join(chrome_dir, "v8"))
1007 # Write fake deps file.
1008 TextToFile("Some line\n \"v8_revision\": \"123444\",\n some line",
1009 os.path.join(chrome_dir, "DEPS"))
1011 TextToFile("Some line\n \"v8_revision\": \"22624\",\n some line",
1012 os.path.join(chrome_dir, "DEPS"))
1015 Cmd("git fetch origin", ""),
1016 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
1017 Cmd("git tag", self.TAGS),
1018 Cmd("git log -1 --format=%H 3.22.4", "push_hash\n"),
1019 Cmd("git log -1 --format=%s push_hash",
1020 "Version 3.22.4 (based on abc)\n"),
1021 Cmd("git log -1 --format=%H 3.22.4", "push_hash\n"),
1022 Cmd("git log -1 --format=%s push_hash",
1023 "Version 3.22.4 (based on abc)"),
1024 Cmd("git describe --tags last_roll_hsh", "3.22.2.1"),
1025 Cmd("git log -1 --format=%H 3.22.2", "last_roll_base_hash"),
1026 Cmd("git log -1 --format=%s last_roll_base_hash", "Version 3.22.2"),
1027 Cmd("git log -1 --format=%H last_roll_base_hash^",
1028 "last_roll_master_hash"),
1029 URL("https://chromium-build.appspot.com/p/chromium/sheriff_v8.js",
1030 "document.write('g_name')"),
1031 Cmd("git status -s -uno", "", cwd=chrome_dir),
1032 Cmd("git checkout -f master", "", cwd=chrome_dir),
1033 Cmd("gclient sync --nohooks", "syncing...", cwd=chrome_dir),
1034 Cmd("git pull", "", cwd=chrome_dir),
1035 Cmd("git fetch origin", ""),
1036 Cmd("git new-branch v8-roll-push_hash", "", cwd=chrome_dir),
1037 Cmd("roll-dep v8 push_hash", "rolled", cb=WriteDeps, cwd=chrome_dir),
1038 Cmd(("git commit -am \"Update V8 to version 3.22.4 "
1039 "(based on abc).\n\n"
1040 "Summary of changes available at:\n"
1041 "https://chromium.googlesource.com/v8/v8/+log/last_rol..abc\n\n"
1042 "Please reply to the V8 sheriff c_name@chromium.org in "
1043 "case of problems.\n\nTBR=c_name@chromium.org\" "
1044 "--author \"author@chromium.org <author@chromium.org>\""),
1045 "", cwd=chrome_dir),
1046 Cmd("git cl upload --send-mail --email \"author@chromium.org\" -f", "",
1049 self.Expect(expectations)
1051 args = ["-a", "author@chromium.org", "-c", chrome_dir,
1052 "--sheriff", "--googlers-mapping", googlers_mapping_py,
1053 "-r", "reviewer@chromium.org",
1054 "--last-roll", "last_roll_hsh"]
1055 ChromiumRoll(TEST_CONFIG, self).Run(args)
1057 deps = FileToText(os.path.join(chrome_dir, "DEPS"))
1058 self.assertTrue(re.search("\"v8_revision\": \"22624\"", deps))
1060 def testCheckLastPushRecently(self):
1062 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
1063 Cmd("git tag", self.TAGS),
1064 Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"),
1065 Cmd("git log -1 --format=%s release_hash",
1066 "Version 3.22.4 (based on abc3)\n"),
1067 Cmd("git log --format=%H abc3..abc123", "\n"),
1070 self._state["candidate"] = "abc123"
1071 self.assertEquals(0, self.RunStep(
1072 auto_push.AutoPush, LastReleaseBailout, AUTO_PUSH_ARGS))
1074 def testAutoPush(self):
1075 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
1078 Cmd("git status -s -uno", ""),
1079 Cmd("git status -s -b -uno", "## some_branch\n"),
1080 Cmd("git fetch", ""),
1081 Cmd("git fetch origin +refs/heads/roll:refs/heads/roll", ""),
1082 Cmd("git show-ref -s refs/heads/roll", "abc123\n"),
1083 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
1084 Cmd("git tag", self.TAGS),
1085 Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"),
1086 Cmd("git log -1 --format=%s release_hash",
1087 "Version 3.22.4 (based on abc3)\n"),
1088 Cmd("git log --format=%H abc3..abc123", "some_stuff\n"),
1091 auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS + ["--push"])
1093 state = json.loads(FileToText("%s-state.json"
1094 % TEST_CONFIG["PERSISTFILE_BASENAME"]))
1096 self.assertEquals("abc123", state["candidate"])
1098 def testAutoRollExistingRoll(self):
1100 URL("https://codereview.chromium.org/search",
1101 "owner=author%40chromium.org&limit=30&closed=3&format=json",
1102 ("{\"results\": [{\"subject\": \"different\"},"
1103 "{\"subject\": \"Update V8 to Version...\"}]}")),
1106 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
1107 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"]])
1108 self.assertEquals(0, result)
1110 # Snippet from the original DEPS file.
1113 "v8_revision": "abcd123455",
1117 (Var("googlecode_url") % "v8") + "/" + Var("v8_branch") + "@" +
1122 def testAutoRollUpToDate(self):
1123 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
1124 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 tag", self.TAGS),
1131 Cmd("git log -1 --format=%H 3.22.4", "push_hash\n"),
1134 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
1135 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"]])
1136 self.assertEquals(0, result)
1138 def testAutoRoll(self):
1139 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
1140 TextToFile(self.FAKE_DEPS, os.path.join(TEST_CONFIG["CHROMIUM"], "DEPS"))
1141 TEST_CONFIG["CLUSTERFUZZ_API_KEY_FILE"] = self.MakeEmptyTempFile()
1142 TextToFile("fake key", TEST_CONFIG["CLUSTERFUZZ_API_KEY_FILE"])
1145 URL("https://codereview.chromium.org/search",
1146 "owner=author%40chromium.org&limit=30&closed=3&format=json",
1147 ("{\"results\": [{\"subject\": \"different\"}]}")),
1148 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
1149 Cmd("git tag", self.TAGS),
1150 Cmd("git log -1 --format=%H 3.22.4", "push_hash\n"),
1153 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
1154 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"], "--roll"])
1155 self.assertEquals(0, result)
1157 def testMergeToBranch(self):
1158 TEST_CONFIG["ALREADY_MERGING_SENTINEL_FILE"] = self.MakeEmptyTempFile()
1159 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
1160 self.WriteFakeVersionFile(build=5)
1161 os.environ["EDITOR"] = "vi"
1162 extra_patch = self.MakeEmptyTempFile()
1164 def VerifyPatch(patch):
1165 return lambda: self.assertEquals(patch,
1166 FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"]))
1168 msg = """Version 3.22.5.1 (cherry-pick)
1186 BUG=123,234,345,456,567,v8:123
1191 commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
1192 self.assertEquals(msg, commit)
1193 version = FileToText(
1194 os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
1195 self.assertTrue(re.search(r"#define MINOR_VERSION\s+22", version))
1196 self.assertTrue(re.search(r"#define BUILD_NUMBER\s+5", version))
1197 self.assertTrue(re.search(r"#define PATCH_LEVEL\s+1", version))
1198 self.assertTrue(re.search(r"#define IS_CANDIDATE_VERSION\s+0", version))
1201 Cmd("git status -s -uno", ""),
1202 Cmd("git status -s -b -uno", "## some_branch\n"),
1203 Cmd("git fetch", ""),
1204 Cmd("git branch", " branch1\n* branch2\n"),
1205 Cmd("git new-branch %s --upstream refs/remotes/origin/candidates" %
1206 TEST_CONFIG["BRANCHNAME"], ""),
1207 Cmd(("git log --format=%H --grep=\"Port ab12345\" "
1208 "--reverse origin/master"),
1209 "ab45678\nab23456"),
1210 Cmd("git log -1 --format=%s ab45678", "Title1"),
1211 Cmd("git log -1 --format=%s ab23456", "Title2"),
1212 Cmd(("git log --format=%H --grep=\"Port ab23456\" "
1213 "--reverse origin/master"),
1215 Cmd(("git log --format=%H --grep=\"Port ab34567\" "
1216 "--reverse origin/master"),
1218 Cmd("git log -1 --format=%s ab56789", "Title3"),
1219 RL("Y"), # Automatically add corresponding ports (ab34567, ab56789)?
1220 # Simulate git being down which stops the script.
1221 Cmd("git log -1 --format=%s ab12345", None),
1222 # Restart script in the failing step.
1223 Cmd("git log -1 --format=%s ab12345", "Title4"),
1224 Cmd("git log -1 --format=%s ab23456", "Title2"),
1225 Cmd("git log -1 --format=%s ab34567", "Title3"),
1226 Cmd("git log -1 --format=%s ab45678", "Title1"),
1227 Cmd("git log -1 --format=%s ab56789", "Revert \"Something\""),
1228 Cmd("git log -1 ab12345", "Title4\nBUG=123\nBUG=234"),
1229 Cmd("git log -1 ab23456", "Title2\n BUG = v8:123,345"),
1230 Cmd("git log -1 ab34567", "Title3\nLOG=n\nBUG=567, 456"),
1231 Cmd("git log -1 ab45678", "Title1\nBUG="),
1232 Cmd("git log -1 ab56789", "Revert \"Something\"\nBUG=none"),
1233 Cmd("git log -1 -p ab12345", "patch4"),
1234 Cmd(("git apply --index --reject \"%s\"" %
1235 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1236 "", cb=VerifyPatch("patch4")),
1237 Cmd("git log -1 -p ab23456", "patch2"),
1238 Cmd(("git apply --index --reject \"%s\"" %
1239 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1240 "", cb=VerifyPatch("patch2")),
1241 Cmd("git log -1 -p ab34567", "patch3"),
1242 Cmd(("git apply --index --reject \"%s\"" %
1243 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1244 "", cb=VerifyPatch("patch3")),
1245 Cmd("git log -1 -p ab45678", "patch1"),
1246 Cmd(("git apply --index --reject \"%s\"" %
1247 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1248 "", cb=VerifyPatch("patch1")),
1249 Cmd("git log -1 -p ab56789", "patch5\n"),
1250 Cmd(("git apply --index --reject \"%s\"" %
1251 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1252 "", cb=VerifyPatch("patch5\n")),
1253 Cmd("git apply --index --reject \"%s\"" % extra_patch, ""),
1254 RL("Y"), # Automatically increment patch level?
1255 Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], ""),
1256 RL("reviewer@chromium.org"), # V8 reviewer.
1257 Cmd("git cl upload --send-mail -r \"reviewer@chromium.org\" "
1258 "--bypass-hooks --cc \"ulan@chromium.org\"", ""),
1259 Cmd("git checkout -f %s" % TEST_CONFIG["BRANCHNAME"], ""),
1260 RL("LGTM"), # Enter LGTM for V8 CL.
1261 Cmd("git cl presubmit", "Presubmit successfull\n"),
1262 Cmd("git cl land -f --bypass-hooks", "Closing issue\n",
1264 Cmd("git fetch", ""),
1265 Cmd("git log -1 --format=%H --grep=\""
1266 "Version 3.22.5.1 (cherry-pick)"
1267 "\" refs/remotes/origin/candidates",
1269 Cmd("git fetch", ""),
1270 Cmd("git log -1 --format=%H --grep=\""
1271 "Version 3.22.5.1 (cherry-pick)"
1272 "\" refs/remotes/origin/candidates",
1274 Cmd("git tag 3.22.5.1 hsh_to_tag", ""),
1275 Cmd("git push origin 3.22.5.1", ""),
1276 Cmd("git checkout -f some_branch", ""),
1277 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
1280 # ab12345 and ab34567 are patches. ab23456 (included) and ab45678 are the
1281 # MIPS ports of ab12345. ab56789 is the MIPS port of ab34567.
1282 args = ["-f", "-p", extra_patch, "--branch", "candidates",
1283 "ab12345", "ab23456", "ab34567"]
1285 # The first run of the script stops because of git being down.
1286 self.assertRaises(GitFailedException,
1287 lambda: MergeToBranch(TEST_CONFIG, self).Run(args))
1289 # Test that state recovery after restarting the script works.
1291 MergeToBranch(TEST_CONFIG, self).Run(args)
1293 def testReleases(self):
1294 c_hash1_commit_log = """Update V8 to Version 4.2.71.
1296 Cr-Commit-Position: refs/heads/master@{#5678}
1298 c_hash2_commit_log = """Revert something.
1304 > Cr-Commit-Position: refs/heads/master@{#12345}
1305 > git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12345 003-1c4
1307 Review URL: https://codereview.chromium.org/12345
1309 Cr-Commit-Position: refs/heads/master@{#4567}
1310 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4567 0039-1c4b
1313 c_hash3_commit_log = """Simple.
1315 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3456 0039-1c4b
1318 c_hash_234_commit_log = """Version 3.3.1.1 (cherry-pick).
1322 Review URL: fake.com
1324 Cr-Commit-Position: refs/heads/candidates@{#234}
1326 c_hash_123_commit_log = """Version 3.3.1.0
1328 git-svn-id: googlecode@123 0039-1c4b
1330 c_hash_345_commit_log = """Version 3.4.0.
1332 Cr-Commit-Position: refs/heads/candidates@{#345}
1334 c_hash_456_commit_log = """Version 4.2.71.
1336 Cr-Commit-Position: refs/heads/4.2.71@{#1}
1339 json_output = self.MakeEmptyTempFile()
1340 csv_output = self.MakeEmptyTempFile()
1341 self.WriteFakeVersionFile()
1343 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
1344 chrome_dir = TEST_CONFIG["CHROMIUM"]
1345 chrome_v8_dir = os.path.join(chrome_dir, "v8")
1346 os.makedirs(chrome_v8_dir)
1347 def WriteDEPS(revision):
1348 TextToFile("Line\n \"v8_revision\": \"%s\",\n line\n" % revision,
1349 os.path.join(chrome_dir, "DEPS"))
1352 def ResetVersion(major, minor, build, patch=0):
1353 return lambda: self.WriteFakeVersionFile(major=major,
1358 def ResetDEPS(revision):
1359 return lambda: WriteDEPS(revision)
1362 Cmd("git status -s -uno", ""),
1363 Cmd("git status -s -b -uno", "## some_branch\n"),
1364 Cmd("git fetch", ""),
1365 Cmd("git branch", " branch1\n* branch2\n"),
1366 Cmd("git new-branch %s" % TEST_CONFIG["BRANCHNAME"], ""),
1367 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""),
1368 Cmd("git rev-list --max-age=395200 --tags",
1369 "bad_tag\nhash_234\nhash_123\nhash_345\nhash_456\n"),
1370 Cmd("git describe --tags bad_tag", "3.23.42-1-deadbeef"),
1371 Cmd("git describe --tags hash_234", "3.3.1.1"),
1372 Cmd("git describe --tags hash_123", "3.21.2"),
1373 Cmd("git describe --tags hash_345", "3.22.3"),
1374 Cmd("git describe --tags hash_456", "4.2.71"),
1375 Cmd("git diff --name-only hash_234 hash_234^", VERSION_FILE),
1376 Cmd("git checkout -f hash_234 -- %s" % VERSION_FILE, "",
1377 cb=ResetVersion(3, 3, 1, 1)),
1378 Cmd("git branch -r --contains hash_234", " branch-heads/3.3\n"),
1379 Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log),
1380 Cmd("git log -1 --format=%s hash_234", ""),
1381 Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log),
1382 Cmd("git log -1 --format=%ci hash_234", "18:15"),
1383 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1384 cb=ResetVersion(3, 22, 5)),
1385 Cmd("git diff --name-only hash_123 hash_123^", VERSION_FILE),
1386 Cmd("git checkout -f hash_123 -- %s" % VERSION_FILE, "",
1387 cb=ResetVersion(3, 21, 2)),
1388 Cmd("git branch -r --contains hash_123", " branch-heads/3.21\n"),
1389 Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log),
1390 Cmd("git log -1 --format=%s hash_123", ""),
1391 Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log),
1392 Cmd("git log -1 --format=%ci hash_123", "03:15"),
1393 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1394 cb=ResetVersion(3, 22, 5)),
1395 Cmd("git diff --name-only hash_345 hash_345^", VERSION_FILE),
1396 Cmd("git checkout -f hash_345 -- %s" % VERSION_FILE, "",
1397 cb=ResetVersion(3, 22, 3)),
1398 Cmd("git branch -r --contains hash_345", " origin/candidates\n"),
1399 Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log),
1400 Cmd("git log -1 --format=%s hash_345", ""),
1401 Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log),
1402 Cmd("git log -1 --format=%ci hash_345", ""),
1403 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1404 cb=ResetVersion(3, 22, 5)),
1405 Cmd("git diff --name-only hash_456 hash_456^", VERSION_FILE),
1406 Cmd("git checkout -f hash_456 -- %s" % VERSION_FILE, "",
1407 cb=ResetVersion(4, 2, 71)),
1408 Cmd("git branch -r --contains hash_456", " origin/4.2.71\n"),
1409 Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log),
1410 Cmd("git log -1 --format=%H 4.2.71", "hash_456"),
1411 Cmd("git log -1 --format=%s hash_456", "Version 4.2.71"),
1412 Cmd("git log -1 --format=%H hash_456^", "master_456"),
1413 Cmd("git log -1 --format=%B master_456",
1414 "Cr-Commit-Position: refs/heads/master@{#456}"),
1415 Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log),
1416 Cmd("git log -1 --format=%ci hash_456", "02:15"),
1417 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1418 cb=ResetVersion(3, 22, 5)),
1419 Cmd("git status -s -uno", "", cwd=chrome_dir),
1420 Cmd("git checkout -f master", "", cwd=chrome_dir),
1421 Cmd("git pull", "", cwd=chrome_dir),
1422 Cmd("git new-branch %s" % TEST_CONFIG["BRANCHNAME"], "",
1424 Cmd("git fetch origin", "", cwd=chrome_v8_dir),
1425 Cmd("git log --format=%H --grep=\"V8\"",
1426 "c_hash0\nc_hash1\nc_hash2\nc_hash3\n",
1428 Cmd("git diff --name-only c_hash0 c_hash0^", "", cwd=chrome_dir),
1429 Cmd("git diff --name-only c_hash1 c_hash1^", "DEPS", cwd=chrome_dir),
1430 Cmd("git checkout -f c_hash1 -- DEPS", "",
1431 cb=ResetDEPS("hash_456"),
1433 Cmd("git log -1 --format=%B c_hash1", c_hash1_commit_log,
1435 Cmd("git diff --name-only c_hash2 c_hash2^", "DEPS", cwd=chrome_dir),
1436 Cmd("git checkout -f c_hash2 -- DEPS", "",
1437 cb=ResetDEPS("hash_345"),
1439 Cmd("git log -1 --format=%B c_hash2", c_hash2_commit_log,
1441 Cmd("git diff --name-only c_hash3 c_hash3^", "DEPS", cwd=chrome_dir),
1442 Cmd("git checkout -f c_hash3 -- DEPS", "", cb=ResetDEPS("deadbeef"),
1444 Cmd("git log -1 --format=%B c_hash3", c_hash3_commit_log,
1446 Cmd("git checkout -f HEAD -- DEPS", "", cb=ResetDEPS("hash_567"),
1448 Cmd("git branch -r", " weird/123\n branch-heads/7\n", cwd=chrome_dir),
1449 Cmd("git checkout -f branch-heads/7 -- DEPS", "",
1450 cb=ResetDEPS("hash_345"),
1452 Cmd("git checkout -f HEAD -- DEPS", "", cb=ResetDEPS("hash_567"),
1454 Cmd("git checkout -f master", "", cwd=chrome_dir),
1455 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], "", cwd=chrome_dir),
1456 Cmd("git checkout -f some_branch", ""),
1457 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
1460 args = ["-c", TEST_CONFIG["CHROMIUM"],
1461 "--json", json_output,
1462 "--csv", csv_output,
1463 "--max-releases", "1"]
1464 Releases(TEST_CONFIG, self).Run(args)
1466 # Check expected output.
1467 csv = ("4.2.71,4.2.71,1,5678,\r\n"
1468 "3.22.3,candidates,345,4567:5677,\r\n"
1469 "3.21.2,3.21,123,,\r\n"
1470 "3.3.1.1,3.3,234,,abc12\r\n")
1471 self.assertEquals(csv, FileToText(csv_output))
1476 "revision_git": "hash_456",
1477 "master_position": "456",
1478 "master_hash": "master_456",
1479 "patches_merged": "",
1480 "version": "4.2.71",
1481 "chromium_revision": "5678",
1485 "chromium_branch": "",
1486 # FIXME(machenbach): Fix revisions link for git.
1487 "revision_link": "https://code.google.com/p/v8/source/detail?r=1",
1491 "revision_git": "hash_345",
1492 "master_position": "",
1494 "patches_merged": "",
1495 "version": "3.22.3",
1496 "chromium_revision": "4567:5677",
1497 "branch": "candidates",
1500 "chromium_branch": "7",
1501 "revision_link": "https://code.google.com/p/v8/source/detail?r=345",
1505 "revision_git": "hash_123",
1506 "patches_merged": "",
1507 "master_position": "",
1509 "version": "3.21.2",
1510 "chromium_revision": "",
1514 "chromium_branch": "",
1515 "revision_link": "https://code.google.com/p/v8/source/detail?r=123",
1519 "revision_git": "hash_234",
1520 "patches_merged": "abc12",
1521 "master_position": "",
1523 "version": "3.3.1.1",
1524 "chromium_revision": "",
1526 "review_link": "fake.com",
1528 "chromium_branch": "",
1529 "revision_link": "https://code.google.com/p/v8/source/detail?r=234",
1532 self.assertEquals(expected_json, json.loads(FileToText(json_output)))
1535 class SystemTest(unittest.TestCase):
1536 def testReload(self):
1537 options = ScriptsBase(
1538 TEST_CONFIG, DEFAULT_SIDE_EFFECT_HANDLER, {}).MakeOptions([])
1539 step = MakeStep(step_class=PrepareChangeLog, number=0, state={}, config={},
1541 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER)
1543 """------------------------------------------------------------------------
1544 r17997 | machenbach@chromium.org | 2013-11-22 11:04:04 +0100 (...) | 6 lines
1546 Prepare push to trunk. Now working on version 3.23.11.
1548 R=danno@chromium.org
1550 Review URL: https://codereview.chromium.org/83173002
1552 ------------------------------------------------------------------------""")
1554 """Prepare push to trunk. Now working on version 3.23.11.
1556 R=danno@chromium.org
1558 Committed: https://code.google.com/p/v8/source/detail?r=17997""", body)