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 CheckLastPush
38 import common_includes
39 from common_includes import *
40 import merge_to_branch
41 from merge_to_branch import *
43 from push_to_trunk import *
45 from chromium_roll import ChromiumRoll
47 from releases import Releases
48 import bump_up_version
49 from bump_up_version import BumpUpVersion
50 from bump_up_version import LastChangeBailout
51 from bump_up_version import LKGRVersionUpToDateBailout
52 from auto_tag import AutoTag
57 "BRANCHNAME": "test-prepare-push",
58 "TRUNKBRANCH": "test-trunk-push",
59 "PERSISTFILE_BASENAME": "/tmp/test-v8-push-to-trunk-tempfile",
60 "CHANGELOG_FILE": None,
61 "CHANGELOG_ENTRY_FILE": "/tmp/test-v8-push-to-trunk-tempfile-changelog-entry",
62 "PATCH_FILE": "/tmp/test-v8-push-to-trunk-tempfile-patch",
63 "COMMITMSG_FILE": "/tmp/test-v8-push-to-trunk-tempfile-commitmsg",
64 "CHROMIUM": "/tmp/test-v8-push-to-trunk-tempfile-chromium",
65 "SETTINGS_LOCATION": None,
66 "ALREADY_MERGING_SENTINEL_FILE":
67 "/tmp/test-merge-to-branch-tempfile-already-merging",
68 "TEMPORARY_PATCH_FILE": "/tmp/test-merge-to-branch-tempfile-temporary-patch",
69 "CLUSTERFUZZ_API_KEY_FILE": "/tmp/test-fake-cf-api-key",
74 "-a", "author@chromium.org",
75 "-r", "reviewer@chromium.org",
79 class ToplevelTest(unittest.TestCase):
80 def testSortBranches(self):
81 S = releases.SortBranches
82 self.assertEquals(["3.1", "2.25"], S(["2.25", "3.1"])[0:2])
83 self.assertEquals(["3.0", "2.25"], S(["2.25", "3.0", "2.24"])[0:2])
84 self.assertEquals(["3.11", "3.2"], S(["3.11", "3.2", "2.24"])[0:2])
86 def testFilterDuplicatesAndReverse(self):
87 F = releases.FilterDuplicatesAndReverse
88 self.assertEquals([], F([]))
89 self.assertEquals([["100", "10"]], F([["100", "10"]]))
90 self.assertEquals([["99", "9"], ["100", "10"]],
91 F([["100", "10"], ["99", "9"]]))
92 self.assertEquals([["98", "9"], ["100", "10"]],
93 F([["100", "10"], ["99", "9"], ["98", "9"]]))
94 self.assertEquals([["98", "9"], ["99", "10"]],
95 F([["100", "10"], ["99", "10"], ["98", "9"]]))
97 def testBuildRevisionRanges(self):
98 B = releases.BuildRevisionRanges
99 self.assertEquals({}, B([]))
100 self.assertEquals({"10": "100"}, B([["100", "10"]]))
101 self.assertEquals({"10": "100", "9": "99:99"},
102 B([["100", "10"], ["99", "9"]]))
103 self.assertEquals({"10": "100", "9": "97:99"},
104 B([["100", "10"], ["98", "9"], ["97", "9"]]))
105 self.assertEquals({"10": "100", "9": "99:99", "3": "91:98"},
106 B([["100", "10"], ["99", "9"], ["91", "3"]]))
107 self.assertEquals({"13": "101", "12": "100:100", "9": "94:97",
108 "3": "91:93, 98:99"},
109 B([["101", "13"], ["100", "12"], ["98", "3"],
110 ["94", "9"], ["91", "3"]]))
112 def testMakeComment(self):
113 self.assertEquals("# Line 1\n# Line 2\n#",
114 MakeComment(" Line 1\n Line 2\n"))
115 self.assertEquals("#Line 1\n#Line 2",
116 MakeComment("Line 1\n Line 2"))
118 def testStripComments(self):
119 self.assertEquals(" Line 1\n Line 3\n",
120 StripComments(" Line 1\n# Line 2\n Line 3\n#\n"))
121 self.assertEquals("\nLine 2 ### Test\n #",
122 StripComments("###\n# \n\n# Line 1\nLine 2 ### Test\n #"))
124 def testMakeChangeLogBodySimple(self):
127 "Title text 1\n\nBUG=\n",
128 "author1@chromium.org"],
130 "Title text 2\n\nBUG=1234\n",
131 "author2@chromium.org"],
133 self.assertEquals(" Title text 1.\n"
134 " (author1@chromium.org)\n\n"
135 " Title text 2 (Chromium issue 1234).\n"
136 " (author2@chromium.org)\n\n",
137 MakeChangeLogBody(commits))
139 def testMakeChangeLogBodyEmpty(self):
140 self.assertEquals("", MakeChangeLogBody([]))
142 def testMakeChangeLogBodyAutoFormat(self):
145 "Title text 1\nLOG=y\nBUG=\n",
146 "author1@chromium.org"],
148 "Title text 2\n\nBUG=1234\n",
149 "author2@chromium.org"],
151 "Title text 3\n\nBUG=1234\nLOG = Yes\n",
152 "author3@chromium.org"],
154 "Title text 4\n\nBUG=1234\nLOG=\n",
155 "author4@chromium.org"],
157 self.assertEquals(" Title text 1.\n\n"
158 " Title text 3 (Chromium issue 1234).\n\n",
159 MakeChangeLogBody(commits, True))
161 def testRegressWrongLogEntryOnTrue(self):
163 Check elimination: Learn from if(CompareMap(x)) on true branch.
166 R=verwaest@chromium.org
168 Committed: https://code.google.com/p/v8/source/detail?r=18210
170 self.assertEquals("", MakeChangeLogBody([["title", body, "author"]], True))
172 def testMakeChangeLogBugReferenceEmpty(self):
173 self.assertEquals("", MakeChangeLogBugReference(""))
174 self.assertEquals("", MakeChangeLogBugReference("LOG="))
175 self.assertEquals("", MakeChangeLogBugReference(" BUG ="))
176 self.assertEquals("", MakeChangeLogBugReference("BUG=none\t"))
178 def testMakeChangeLogBugReferenceSimple(self):
179 self.assertEquals("(issue 987654)",
180 MakeChangeLogBugReference("BUG = v8:987654"))
181 self.assertEquals("(Chromium issue 987654)",
182 MakeChangeLogBugReference("BUG=987654 "))
184 def testMakeChangeLogBugReferenceFromBody(self):
185 self.assertEquals("(Chromium issue 1234567)",
186 MakeChangeLogBugReference("Title\n\nTBR=\nBUG=\n"
187 " BUG=\tchromium:1234567\t\n"
190 def testMakeChangeLogBugReferenceMultiple(self):
191 # All issues should be sorted and grouped. Multiple references to the same
192 # issue should be filtered.
193 self.assertEquals("(issues 123, 234, Chromium issue 345)",
194 MakeChangeLogBugReference("Title\n\n"
196 " BUG\t= 345, \tv8:234,\n"
199 self.assertEquals("(Chromium issues 123, 234)",
200 MakeChangeLogBugReference("Title\n\n"
201 "BUG=234,,chromium:123 \n"
203 self.assertEquals("(Chromium issues 123, 234)",
204 MakeChangeLogBugReference("Title\n\n"
205 "BUG=chromium:234, , 123\n"
207 self.assertEquals("(issues 345, 456)",
208 MakeChangeLogBugReference("Title\n\n"
209 "\t\tBUG=v8:345,v8:456\n"
211 self.assertEquals("(issue 123, Chromium issues 345, 456)",
212 MakeChangeLogBugReference("Title\n\n"
216 "BUG=456,v8:123, 345"))
218 # TODO(machenbach): These test don't make much sense when the formatting is
220 def testMakeChangeLogBugReferenceLong(self):
221 # -----------------00--------10--------20--------30--------
222 self.assertEquals("(issues 234, 1234567890, 1234567"
223 "8901234567890, Chromium issues 12345678,"
225 MakeChangeLogBugReference("BUG=v8:234\n"
226 "BUG=v8:1234567890\n"
227 "BUG=v8:12345678901234567890\n"
230 # -----------------00--------10--------20--------30--------
231 self.assertEquals("(issues 234, 1234567890, 1234567"
232 "8901234567890, Chromium issues"
233 " 123456789, 1234567890)",
234 MakeChangeLogBugReference("BUG=v8:234\n"
235 "BUG=v8:12345678901234567890\n"
236 "BUG=v8:1234567890\n"
239 # -----------------00--------10--------20--------30--------
240 self.assertEquals("(Chromium issues 234, 1234567890"
241 ", 12345678901234567, "
242 "1234567890123456789)",
243 MakeChangeLogBugReference("BUG=234\n"
244 "BUG=12345678901234567\n"
245 "BUG=1234567890123456789\n"
249 def Cmd(*args, **kwargs):
250 """Convenience function returning a shell command test expectation."""
255 "cb": kwargs.get("cb"),
256 "cwd": kwargs.get("cwd", TEST_CONFIG["DEFAULT_CWD"]),
260 def RL(text, cb=None):
261 """Convenience function returning a readline test expectation."""
271 def URL(*args, **kwargs):
272 """Convenience function returning a readurl test expectation."""
277 "cb": kwargs.get("cb"),
282 class SimpleMock(object):
287 def Expect(self, recipe):
288 self._recipe = recipe
290 def Call(self, name, *args, **kwargs): # pragma: no cover
293 expected_call = self._recipe[self._index]
295 raise NoRetryException("Calling %s %s" % (name, " ".join(args)))
297 if not isinstance(expected_call, dict):
298 raise NoRetryException("Found wrong expectation type for %s %s" %
299 (name, " ".join(args)))
301 if expected_call["name"] != name:
302 raise NoRetryException("Expected action: %s %s - Actual: %s" %
303 (expected_call["name"], expected_call["args"], name))
305 # Check if the given working directory matches the expected one.
306 if expected_call["cwd"] != kwargs.get("cwd"):
307 raise NoRetryException("Expected cwd: %s in %s %s - Actual: %s" %
308 (expected_call["cwd"],
309 expected_call["name"],
310 expected_call["args"],
313 # The number of arguments in the expectation must match the actual
315 if len(args) > len(expected_call['args']):
316 raise NoRetryException("When calling %s with arguments, the "
317 "expectations must consist of at least as many arguments." %
320 # Compare expected and actual arguments.
321 for (expected_arg, actual_arg) in zip(expected_call['args'], args):
322 if expected_arg != actual_arg:
323 raise NoRetryException("Expected: %s - Actual: %s" %
324 (expected_arg, actual_arg))
326 # The expected call contains an optional callback for checking the context
327 # at the time of the call.
328 if expected_call['cb']:
330 expected_call['cb']()
332 tb = traceback.format_exc()
333 raise NoRetryException("Caught exception from callback: %s" % tb)
335 # If the return value is an exception, raise it instead of returning.
336 if isinstance(expected_call['ret'], Exception):
337 raise expected_call['ret']
338 return expected_call['ret']
340 def AssertFinished(self): # pragma: no cover
341 if self._index < len(self._recipe) -1:
342 raise NoRetryException("Called mock too seldom: %d vs. %d" %
343 (self._index, len(self._recipe)))
346 class ScriptTest(unittest.TestCase):
347 def MakeEmptyTempFile(self):
348 handle, name = tempfile.mkstemp()
350 self._tmp_files.append(name)
353 def MakeEmptyTempDirectory(self):
354 name = tempfile.mkdtemp()
355 self._tmp_files.append(name)
359 def WriteFakeVersionFile(self, minor=22, build=4, patch=0):
360 version_file = os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE)
361 if not os.path.exists(os.path.dirname(version_file)):
362 os.makedirs(os.path.dirname(version_file))
363 with open(version_file, "w") as f:
364 f.write(" // Some line...\n")
366 f.write("#define MAJOR_VERSION 3\n")
367 f.write("#define MINOR_VERSION %s\n" % minor)
368 f.write("#define BUILD_NUMBER %s\n" % build)
369 f.write("#define PATCH_LEVEL %s\n" % patch)
370 f.write(" // Some line...\n")
371 f.write("#define IS_CANDIDATE_VERSION 0\n")
374 """Convenience wrapper."""
375 options = ScriptsBase(TEST_CONFIG, self, self._state).MakeOptions([])
376 return MakeStep(step_class=Step, state=self._state,
377 config=TEST_CONFIG, side_effect_handler=self,
380 def RunStep(self, script=PushToTrunk, step_class=Step, args=None):
381 """Convenience wrapper."""
382 args = args if args is not None else ["-m"]
383 return script(TEST_CONFIG, self, self._state).RunSteps([step_class], args)
385 def Call(self, fun, *args, **kwargs):
386 print "Calling %s with %s and %s" % (str(fun), str(args), str(kwargs))
388 def Command(self, cmd, args="", prefix="", pipe=True, cwd=None):
389 print "%s %s" % (cmd, args)
391 return self._mock.Call("command", cmd + " " + args, cwd=cwd)
394 return self._mock.Call("readline")
396 def ReadURL(self, url, params):
397 if params is not None:
398 return self._mock.Call("readurl", url, params)
400 return self._mock.Call("readurl", url)
402 def ReadClusterFuzzAPI(self, api_key, **params):
403 # TODO(machenbach): Use a mock for this and add a test that stops rolling
404 # due to clustefuzz results.
407 def Sleep(self, seconds):
413 def GetUTCStamp(self):
416 def Expect(self, *args):
417 """Convenience wrapper."""
418 self._mock.Expect(*args)
421 self._mock = SimpleMock()
424 TEST_CONFIG["DEFAULT_CWD"] = self.MakeEmptyTempDirectory()
427 if os.path.exists(TEST_CONFIG["PERSISTFILE_BASENAME"]):
428 shutil.rmtree(TEST_CONFIG["PERSISTFILE_BASENAME"])
430 # Clean up temps. Doesn't work automatically.
431 for name in self._tmp_files:
432 if os.path.isfile(name):
434 if os.path.isdir(name):
437 self._mock.AssertFinished()
439 def testGitMock(self):
440 self.Expect([Cmd("git --version", "git version 1.2.3"),
441 Cmd("git dummy", "")])
442 self.assertEquals("git version 1.2.3", self.MakeStep().Git("--version"))
443 self.assertEquals("", self.MakeStep().Git("dummy"))
445 def testCommonPrepareDefault(self):
447 Cmd("git status -s -uno", ""),
448 Cmd("git status -s -b -uno", "## some_branch"),
449 Cmd("git svn fetch", ""),
450 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
452 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
454 self.MakeStep().CommonPrepare()
455 self.MakeStep().PrepareBranch()
456 self.assertEquals("some_branch", self._state["current_branch"])
458 def testCommonPrepareNoConfirm(self):
460 Cmd("git status -s -uno", ""),
461 Cmd("git status -s -b -uno", "## some_branch"),
462 Cmd("git svn fetch", ""),
463 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
466 self.MakeStep().CommonPrepare()
467 self.assertRaises(Exception, self.MakeStep().PrepareBranch)
468 self.assertEquals("some_branch", self._state["current_branch"])
470 def testCommonPrepareDeleteBranchFailure(self):
472 Cmd("git status -s -uno", ""),
473 Cmd("git status -s -b -uno", "## some_branch"),
474 Cmd("git svn fetch", ""),
475 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
477 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], None),
479 self.MakeStep().CommonPrepare()
480 self.assertRaises(Exception, self.MakeStep().PrepareBranch)
481 self.assertEquals("some_branch", self._state["current_branch"])
483 def testInitialEnvironmentChecks(self):
484 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
485 os.environ["EDITOR"] = "vi"
487 Cmd("which vi", "/usr/bin/vi"),
489 self.MakeStep().InitialEnvironmentChecks(TEST_CONFIG["DEFAULT_CWD"])
491 def testReadAndPersistVersion(self):
492 self.WriteFakeVersionFile(build=5)
493 step = self.MakeStep()
494 step.ReadAndPersistVersion()
495 self.assertEquals("3", step["major"])
496 self.assertEquals("22", step["minor"])
497 self.assertEquals("5", step["build"])
498 self.assertEquals("0", step["patch"])
501 self.assertEqual("(issue 321)",
502 re.sub(r"BUG=v8:(.*)$", r"(issue \1)", "BUG=v8:321"))
503 self.assertEqual("(Chromium issue 321)",
504 re.sub(r"BUG=(.*)$", r"(Chromium issue \1)", "BUG=321"))
506 cl = " too little\n\ttab\ttab\n too much\n trailing "
507 cl = MSub(r"\t", r" ", cl)
508 cl = MSub(r"^ {1,7}([^ ])", r" \1", cl)
509 cl = MSub(r"^ {9,80}([^ ])", r" \1", cl)
510 cl = MSub(r" +$", r"", cl)
511 self.assertEqual(" too little\n"
516 self.assertEqual("//\n#define BUILD_NUMBER 3\n",
517 MSub(r"(?<=#define BUILD_NUMBER)(?P<space>\s+)\d*$",
519 "//\n#define BUILD_NUMBER 321\n"))
521 def testPreparePushRevision(self):
522 # Tests the default push hash used when the --revision option is not set.
524 Cmd("git log -1 --format=%H HEAD", "push_hash")
527 self.RunStep(PushToTrunk, PreparePushRevision)
528 self.assertEquals("push_hash", self._state["push_hash"])
530 def testPrepareChangeLog(self):
531 self.WriteFakeVersionFile()
532 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
535 Cmd("git log --format=%H 1234..push_hash", "rev1\nrev2\nrev3\nrev4"),
536 Cmd("git log -1 --format=%s rev1", "Title text 1"),
537 Cmd("git log -1 --format=%B rev1", "Title\n\nBUG=\nLOG=y\n"),
538 Cmd("git log -1 --format=%an rev1", "author1@chromium.org"),
539 Cmd("git log -1 --format=%s rev2", "Title text 2."),
540 Cmd("git log -1 --format=%B rev2", "Title\n\nBUG=123\nLOG= \n"),
541 Cmd("git log -1 --format=%an rev2", "author2@chromium.org"),
542 Cmd("git log -1 --format=%s rev3", "Title text 3"),
543 Cmd("git log -1 --format=%B rev3", "Title\n\nBUG=321\nLOG=true\n"),
544 Cmd("git log -1 --format=%an rev3", "author3@chromium.org"),
545 Cmd("git log -1 --format=%s rev4", "Title text 4"),
546 Cmd("git log -1 --format=%B rev4",
547 ("Title\n\nBUG=456\nLOG=Y\n\n"
548 "Review URL: https://codereview.chromium.org/9876543210\n")),
549 URL("https://codereview.chromium.org/9876543210/description",
550 "Title\n\nBUG=456\nLOG=N\n\n"),
551 Cmd("git log -1 --format=%an rev4", "author4@chromium.org"),
554 self._state["last_push_bleeding_edge"] = "1234"
555 self._state["push_hash"] = "push_hash"
556 self._state["version"] = "3.22.5"
557 self.RunStep(PushToTrunk, PrepareChangeLog)
559 actual_cl = FileToText(TEST_CONFIG["CHANGELOG_ENTRY_FILE"])
561 expected_cl = """1999-07-31: Version 3.22.5
565 Title text 3 (Chromium issue 321).
567 Performance and stability improvements on all platforms.
569 # The change log above is auto-generated. Please review if all relevant
570 # commit messages from the list below are included.
571 # All lines starting with # will be stripped.
574 # (author1@chromium.org)
576 # Title text 2 (Chromium issue 123).
577 # (author2@chromium.org)
579 # Title text 3 (Chromium issue 321).
580 # (author3@chromium.org)
582 # Title text 4 (Chromium issue 456).
583 # (author4@chromium.org)
587 self.assertEquals(expected_cl, actual_cl)
589 def testEditChangeLog(self):
590 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
591 TextToFile(" New \n\tLines \n", TEST_CONFIG["CHANGELOG_ENTRY_FILE"])
592 os.environ["EDITOR"] = "vi"
594 RL(""), # Open editor.
595 Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], ""),
598 self.RunStep(PushToTrunk, EditChangeLog)
600 self.assertEquals("New\n Lines",
601 FileToText(TEST_CONFIG["CHANGELOG_ENTRY_FILE"]))
603 # Version on trunk: 3.22.4.0. Version on master (bleeding_edge): 3.22.6.
604 # Make sure that the increment is 3.22.7.0.
605 def testIncrementVersion(self):
606 self.WriteFakeVersionFile()
607 self._state["last_push_trunk"] = "hash1"
608 self._state["latest_build"] = "6"
609 self._state["latest_version"] = "3.22.6.0"
612 Cmd("git checkout -f hash1 -- src/version.cc", ""),
613 Cmd("git checkout -f svn/bleeding_edge -- src/version.cc",
614 "", cb=lambda: self.WriteFakeVersionFile(22, 6)),
615 RL("Y"), # Increment build number.
618 self.RunStep(PushToTrunk, IncrementVersion)
620 self.assertEquals("3", self._state["new_major"])
621 self.assertEquals("22", self._state["new_minor"])
622 self.assertEquals("7", self._state["new_build"])
623 self.assertEquals("0", self._state["new_patch"])
625 def _TestSquashCommits(self, change_log, expected_msg):
626 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
627 with open(TEST_CONFIG["CHANGELOG_ENTRY_FILE"], "w") as f:
631 Cmd("git diff svn/trunk hash1", "patch content"),
632 Cmd("git svn find-rev hash1", "123455\n"),
635 self._state["push_hash"] = "hash1"
636 self._state["date"] = "1999-11-11"
638 self.RunStep(PushToTrunk, SquashCommits)
639 self.assertEquals(FileToText(TEST_CONFIG["COMMITMSG_FILE"]), expected_msg)
641 patch = FileToText(TEST_CONFIG["PATCH_FILE"])
642 self.assertTrue(re.search(r"patch content", patch))
644 def testSquashCommitsUnformatted(self):
645 change_log = """1999-11-11: Version 3.22.5
650 Performance and stability improvements on all platforms.\n"""
651 commit_msg = """Version 3.22.5 (based on bleeding_edge revision r123455)
653 Log text 1. Chromium issue 12345
655 Performance and stability improvements on all platforms."""
656 self._TestSquashCommits(change_log, commit_msg)
658 def testSquashCommitsFormatted(self):
659 change_log = """1999-11-11: Version 3.22.5
661 Long commit message that fills more than 80 characters (Chromium issue
664 Performance and stability improvements on all platforms.\n"""
665 commit_msg = """Version 3.22.5 (based on bleeding_edge revision r123455)
667 Long commit message that fills more than 80 characters (Chromium issue 12345).
669 Performance and stability improvements on all platforms."""
670 self._TestSquashCommits(change_log, commit_msg)
672 def testSquashCommitsQuotationMarks(self):
673 change_log = """Line with "quotation marks".\n"""
674 commit_msg = """Line with "quotation marks"."""
675 self._TestSquashCommits(change_log, commit_msg)
677 def _PushToTrunk(self, force=False, manual=False):
678 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
680 # The version file on bleeding edge has build level 5, while the version
681 # file from trunk has build level 4.
682 self.WriteFakeVersionFile(build=5)
684 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
685 TEST_CONFIG["CHANGELOG_FILE"] = self.MakeEmptyTempFile()
686 bleeding_edge_change_log = "2014-03-17: Sentinel\n"
687 TextToFile(bleeding_edge_change_log, TEST_CONFIG["CHANGELOG_FILE"])
688 os.environ["EDITOR"] = "vi"
690 def ResetChangeLog():
691 """On 'git co -b new_branch svn/trunk', and 'git checkout -- ChangeLog',
692 the ChangLog will be reset to its content on trunk."""
693 trunk_change_log = """1999-04-05: Version 3.22.4
695 Performance and stability improvements on all platforms.\n"""
696 TextToFile(trunk_change_log, TEST_CONFIG["CHANGELOG_FILE"])
700 self.WriteFakeVersionFile()
702 def CheckSVNCommit():
703 commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
705 """Version 3.22.5 (based on bleeding_edge revision r123455)
707 Log text 1 (issue 321).
709 Performance and stability improvements on all platforms.""", commit)
710 version = FileToText(
711 os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
712 self.assertTrue(re.search(r"#define MINOR_VERSION\s+22", version))
713 self.assertTrue(re.search(r"#define BUILD_NUMBER\s+5", version))
714 self.assertFalse(re.search(r"#define BUILD_NUMBER\s+6", version))
715 self.assertTrue(re.search(r"#define PATCH_LEVEL\s+0", version))
716 self.assertTrue(re.search(r"#define IS_CANDIDATE_VERSION\s+0", version))
718 # Check that the change log on the trunk branch got correctly modified.
719 change_log = FileToText(TEST_CONFIG["CHANGELOG_FILE"])
721 """1999-07-31: Version 3.22.5
723 Log text 1 (issue 321).
725 Performance and stability improvements on all platforms.
728 1999-04-05: Version 3.22.4
730 Performance and stability improvements on all platforms.\n""",
733 force_flag = " -f" if not manual else ""
736 expectations.append(Cmd("which vi", "/usr/bin/vi"))
738 Cmd("git status -s -uno", ""),
739 Cmd("git status -s -b -uno", "## some_branch\n"),
740 Cmd("git svn fetch", ""),
741 Cmd("git branch", " branch1\n* branch2\n"),
742 Cmd("git branch", " branch1\n* branch2\n"),
743 Cmd("git checkout -b %s svn/bleeding_edge" % TEST_CONFIG["BRANCHNAME"],
745 Cmd("git svn find-rev r123455", "push_hash\n"),
746 Cmd(("git log -1 --format=%H --grep="
747 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\" "
748 "svn/trunk"), "hash2\n"),
749 Cmd("git log -1 hash2", "Log message\n"),
752 expectations.append(RL("Y")) # Confirm last push.
754 Cmd("git log -1 --format=%s hash2",
755 "Version 3.4.5 (based on bleeding_edge revision r1234)\n"),
756 Cmd("git svn find-rev r1234", "hash3\n"),
757 Cmd("git checkout -f svn/bleeding_edge -- src/version.cc",
758 "", cb=self.WriteFakeVersionFile),
759 Cmd("git checkout -f hash2 -- src/version.cc", "",
760 cb=self.WriteFakeVersionFile),
763 expectations.append(RL("")) # Increment build number.
765 Cmd("git log --format=%H hash3..push_hash", "rev1\n"),
766 Cmd("git log -1 --format=%s rev1", "Log text 1.\n"),
767 Cmd("git log -1 --format=%B rev1", "Text\nLOG=YES\nBUG=v8:321\nText\n"),
768 Cmd("git log -1 --format=%an rev1", "author1@chromium.org\n"),
771 expectations.append(RL("")) # Open editor.
774 Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], ""))
776 Cmd("git svn fetch", "fetch result\n"),
777 Cmd("git checkout -f svn/bleeding_edge", ""),
778 Cmd("git diff svn/trunk push_hash", "patch content\n"),
779 Cmd("git svn find-rev push_hash", "123455\n"),
780 Cmd("git checkout -b %s svn/trunk" % TEST_CONFIG["TRUNKBRANCH"], "",
782 Cmd("git apply --index --reject \"%s\"" % TEST_CONFIG["PATCH_FILE"], ""),
783 Cmd("git checkout -f svn/trunk -- %s" % TEST_CONFIG["CHANGELOG_FILE"], "",
785 Cmd("git checkout -f svn/trunk -- src/version.cc", "",
786 cb=self.WriteFakeVersionFile),
787 Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "",
791 expectations.append(RL("Y")) # Sanity check.
793 Cmd("git svn dcommit 2>&1",
794 "Some output\nCommitted r123456\nSome output\n"),
795 Cmd("git svn tag 3.22.5 -m \"Tagging version 3.22.5\"", ""),
796 Cmd("git checkout -f some_branch", ""),
797 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
798 Cmd("git branch -D %s" % TEST_CONFIG["TRUNKBRANCH"], ""),
800 self.Expect(expectations)
802 args = ["-a", "author@chromium.org", "--revision", "123455"]
803 if force: args.append("-f")
804 if manual: args.append("-m")
805 else: args += ["-r", "reviewer@chromium.org"]
806 PushToTrunk(TEST_CONFIG, self).Run(args)
808 cl = FileToText(TEST_CONFIG["CHANGELOG_FILE"])
809 self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl))
810 self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl))
811 self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl))
813 # Note: The version file is on build number 5 again in the end of this test
814 # since the git command that merges to the bleeding edge branch is mocked
817 def testPushToTrunkManual(self):
818 self._PushToTrunk(manual=True)
820 def testPushToTrunkSemiAutomatic(self):
823 def testPushToTrunkForced(self):
824 self._PushToTrunk(force=True)
826 C_V8_22624_LOG = """V8 CL.
828 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22624 123
832 C_V8_123455_LOG = """V8 CL.
834 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@123455 123
838 C_V8_123456_LOG = """V8 CL.
840 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@123456 123
844 def testChromiumRoll(self):
845 googlers_mapping_py = "%s-mapping.py" % TEST_CONFIG["PERSISTFILE_BASENAME"]
846 with open(googlers_mapping_py, "w") as f:
848 def list_to_dict(entries):
849 return {"g_name@google.com": "c_name@chromium.org"}
853 # Setup fake directory structures.
854 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
855 TextToFile("", os.path.join(TEST_CONFIG["CHROMIUM"], ".git"))
856 chrome_dir = TEST_CONFIG["CHROMIUM"]
857 os.makedirs(os.path.join(chrome_dir, "v8"))
859 # Write fake deps file.
860 TextToFile("Some line\n \"v8_revision\": \"123444\",\n some line",
861 os.path.join(chrome_dir, "DEPS"))
863 TextToFile("Some line\n \"v8_revision\": \"22624\",\n some line",
864 os.path.join(chrome_dir, "DEPS"))
867 Cmd("git fetch origin", ""),
868 Cmd(("git log -1 --format=%H --grep="
869 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\" "
870 "origin/master"), "push_hash\n"),
871 Cmd("git log -1 --format=%B push_hash", self.C_V8_22624_LOG),
872 Cmd("git log -1 --format=%s push_hash",
873 "Version 3.22.5 (based on bleeding_edge revision r22622)\n"),
874 URL("https://chromium-build.appspot.com/p/chromium/sheriff_v8.js",
875 "document.write('g_name')"),
876 Cmd("git status -s -uno", "", cwd=chrome_dir),
877 Cmd("git checkout -f master", "", cwd=chrome_dir),
878 Cmd("gclient sync --nohooks", "syncing...", cwd=chrome_dir),
879 Cmd("git pull", "", cwd=chrome_dir),
880 Cmd("git fetch origin", ""),
881 Cmd("git checkout -b v8-roll-22624", "", cwd=chrome_dir),
882 Cmd("roll-dep v8 22624", "rolled", cb=WriteDeps, cwd=chrome_dir),
883 Cmd(("git commit -am \"Update V8 to version 3.22.5 "
884 "(based on bleeding_edge revision r22622).\n\n"
885 "Please reply to the V8 sheriff c_name@chromium.org in "
886 "case of problems.\n\nTBR=c_name@chromium.org\" "
887 "--author \"author@chromium.org <author@chromium.org>\""),
889 Cmd("git cl upload --send-mail --email \"author@chromium.org\" -f", "",
892 self.Expect(expectations)
894 args = ["-a", "author@chromium.org", "-c", chrome_dir,
895 "--sheriff", "--googlers-mapping", googlers_mapping_py,
896 "-r", "reviewer@chromium.org"]
897 ChromiumRoll(TEST_CONFIG, self).Run(args)
899 deps = FileToText(os.path.join(chrome_dir, "DEPS"))
900 self.assertTrue(re.search("\"v8_revision\": \"22624\"", deps))
902 def testCheckLastPushRecently(self):
904 Cmd(("git log -1 --format=%H --grep="
905 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\" "
906 "svn/trunk"), "hash2\n"),
907 Cmd("git log -1 --format=%s hash2",
908 "Version 3.4.5 (based on bleeding_edge revision r99)\n"),
911 self._state["lkgr"] = "101"
913 self.assertRaises(Exception, lambda: self.RunStep(auto_push.AutoPush,
917 def testAutoPush(self):
918 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
919 TEST_CONFIG["SETTINGS_LOCATION"] = "~/.doesnotexist"
922 Cmd("git status -s -uno", ""),
923 Cmd("git status -s -b -uno", "## some_branch\n"),
924 Cmd("git svn fetch", ""),
925 URL("https://v8-status.appspot.com/current?format=json",
926 "{\"message\": \"Tree is throttled\"}"),
927 URL("https://v8-status.appspot.com/lkgr", Exception("Network problem")),
928 URL("https://v8-status.appspot.com/lkgr", "100"),
929 Cmd(("git log -1 --format=%H --grep=\""
930 "^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\""
931 " svn/trunk"), "push_hash\n"),
932 Cmd("git log -1 --format=%s push_hash",
933 "Version 3.4.5 (based on bleeding_edge revision r79)\n"),
936 auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS + ["--push"])
938 state = json.loads(FileToText("%s-state.json"
939 % TEST_CONFIG["PERSISTFILE_BASENAME"]))
941 self.assertEquals("100", state["lkgr"])
943 def testAutoPushStoppedBySettings(self):
944 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
945 TEST_CONFIG["SETTINGS_LOCATION"] = self.MakeEmptyTempFile()
946 TextToFile("{\"enable_auto_push\": false}",
947 TEST_CONFIG["SETTINGS_LOCATION"])
950 Cmd("git status -s -uno", ""),
951 Cmd("git status -s -b -uno", "## some_branch\n"),
952 Cmd("git svn fetch", ""),
956 auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS)
957 self.assertRaises(Exception, RunAutoPush)
959 def testAutoPushStoppedByTreeStatus(self):
960 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
961 TEST_CONFIG["SETTINGS_LOCATION"] = "~/.doesnotexist"
964 Cmd("git status -s -uno", ""),
965 Cmd("git status -s -b -uno", "## some_branch\n"),
966 Cmd("git svn fetch", ""),
967 URL("https://v8-status.appspot.com/current?format=json",
968 "{\"message\": \"Tree is throttled (no push)\"}"),
972 auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS)
973 self.assertRaises(Exception, RunAutoPush)
975 def testAutoRollExistingRoll(self):
977 URL("https://codereview.chromium.org/search",
978 "owner=author%40chromium.org&limit=30&closed=3&format=json",
979 ("{\"results\": [{\"subject\": \"different\"},"
980 "{\"subject\": \"Update V8 to Version...\"}]}")),
983 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
984 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"]])
985 self.assertEquals(0, result)
987 # Snippet from the original DEPS file.
990 "v8_revision": "abcd123455",
994 (Var("googlecode_url") % "v8") + "/" + Var("v8_branch") + "@" +
999 def testAutoRollUpToDate(self):
1000 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
1001 TextToFile(self.FAKE_DEPS, os.path.join(TEST_CONFIG["CHROMIUM"], "DEPS"))
1003 URL("https://codereview.chromium.org/search",
1004 "owner=author%40chromium.org&limit=30&closed=3&format=json",
1005 ("{\"results\": [{\"subject\": \"different\"}]}")),
1006 Cmd(("git log -1 --format=%H --grep="
1007 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\" "
1008 "origin/master"), "push_hash\n"),
1009 Cmd("git log -1 --format=%B push_hash", self.C_V8_22624_LOG),
1010 Cmd("git log -1 --format=%B abcd123455", self.C_V8_123455_LOG),
1013 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
1014 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"]])
1015 self.assertEquals(0, result)
1017 def testAutoRoll(self):
1018 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
1019 TextToFile(self.FAKE_DEPS, os.path.join(TEST_CONFIG["CHROMIUM"], "DEPS"))
1020 TEST_CONFIG["CLUSTERFUZZ_API_KEY_FILE"] = self.MakeEmptyTempFile()
1021 TextToFile("fake key", TEST_CONFIG["CLUSTERFUZZ_API_KEY_FILE"])
1024 URL("https://codereview.chromium.org/search",
1025 "owner=author%40chromium.org&limit=30&closed=3&format=json",
1026 ("{\"results\": [{\"subject\": \"different\"}]}")),
1027 Cmd(("git log -1 --format=%H --grep="
1028 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\" "
1029 "origin/master"), "push_hash\n"),
1030 Cmd("git log -1 --format=%B push_hash", self.C_V8_123456_LOG),
1031 Cmd("git log -1 --format=%B abcd123455", self.C_V8_123455_LOG),
1034 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
1035 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG["CHROMIUM"], "--roll"])
1036 self.assertEquals(0, result)
1038 def testMergeToBranch(self):
1039 TEST_CONFIG["ALREADY_MERGING_SENTINEL_FILE"] = self.MakeEmptyTempFile()
1040 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
1041 self.WriteFakeVersionFile(build=5)
1042 os.environ["EDITOR"] = "vi"
1043 extra_patch = self.MakeEmptyTempFile()
1045 def VerifyPatch(patch):
1046 return lambda: self.assertEquals(patch,
1047 FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"]))
1049 msg = """Version 3.22.5.1 (merged r12345, r23456, r34567, r45678, r56789)
1061 BUG=123,234,345,456,567,v8:123
1065 def VerifySVNCommit():
1066 commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
1067 self.assertEquals(msg, commit)
1068 version = FileToText(
1069 os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
1070 self.assertTrue(re.search(r"#define MINOR_VERSION\s+22", version))
1071 self.assertTrue(re.search(r"#define BUILD_NUMBER\s+5", version))
1072 self.assertTrue(re.search(r"#define PATCH_LEVEL\s+1", version))
1073 self.assertTrue(re.search(r"#define IS_CANDIDATE_VERSION\s+0", version))
1076 Cmd("git status -s -uno", ""),
1077 Cmd("git status -s -b -uno", "## some_branch\n"),
1078 Cmd("git svn fetch", ""),
1079 Cmd("git branch", " branch1\n* branch2\n"),
1080 Cmd("git checkout -b %s svn/trunk" % TEST_CONFIG["BRANCHNAME"], ""),
1081 Cmd(("git log --format=%H --grep=\"Port r12345\" "
1082 "--reverse svn/bleeding_edge"),
1084 Cmd("git svn find-rev hash1 svn/bleeding_edge", "45678"),
1085 Cmd("git log -1 --format=%s hash1", "Title1"),
1086 Cmd("git svn find-rev hash2 svn/bleeding_edge", "23456"),
1087 Cmd("git log -1 --format=%s hash2", "Title2"),
1088 Cmd(("git log --format=%H --grep=\"Port r23456\" "
1089 "--reverse svn/bleeding_edge"),
1091 Cmd(("git log --format=%H --grep=\"Port r34567\" "
1092 "--reverse svn/bleeding_edge"),
1094 Cmd("git svn find-rev hash3 svn/bleeding_edge", "56789"),
1095 Cmd("git log -1 --format=%s hash3", "Title3"),
1096 RL("Y"), # Automatically add corresponding ports (34567, 56789)?
1097 Cmd("git svn find-rev r12345 svn/bleeding_edge", "hash4"),
1098 # Simulate svn being down which stops the script.
1099 Cmd("git svn find-rev r23456 svn/bleeding_edge", None),
1100 # Restart script in the failing step.
1101 Cmd("git svn find-rev r12345 svn/bleeding_edge", "hash4"),
1102 Cmd("git svn find-rev r23456 svn/bleeding_edge", "hash2"),
1103 Cmd("git svn find-rev r34567 svn/bleeding_edge", "hash3"),
1104 Cmd("git svn find-rev r45678 svn/bleeding_edge", "hash1"),
1105 Cmd("git svn find-rev r56789 svn/bleeding_edge", "hash5"),
1106 Cmd("git log -1 --format=%s hash4", "Title4"),
1107 Cmd("git log -1 --format=%s hash2", "Title2"),
1108 Cmd("git log -1 --format=%s hash3", "Title3"),
1109 Cmd("git log -1 --format=%s hash1", "Title1"),
1110 Cmd("git log -1 --format=%s hash5", "Revert \"Something\""),
1111 Cmd("git log -1 hash4", "Title4\nBUG=123\nBUG=234"),
1112 Cmd("git log -1 hash2", "Title2\n BUG = v8:123,345"),
1113 Cmd("git log -1 hash3", "Title3\nLOG=n\nBUG=567, 456"),
1114 Cmd("git log -1 hash1", "Title1\nBUG="),
1115 Cmd("git log -1 hash5", "Revert \"Something\"\nBUG=none"),
1116 Cmd("git log -1 -p hash4", "patch4"),
1117 Cmd(("git apply --index --reject \"%s\"" %
1118 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1119 "", cb=VerifyPatch("patch4")),
1120 Cmd("git log -1 -p hash2", "patch2"),
1121 Cmd(("git apply --index --reject \"%s\"" %
1122 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1123 "", cb=VerifyPatch("patch2")),
1124 Cmd("git log -1 -p hash3", "patch3"),
1125 Cmd(("git apply --index --reject \"%s\"" %
1126 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1127 "", cb=VerifyPatch("patch3")),
1128 Cmd("git log -1 -p hash1", "patch1"),
1129 Cmd(("git apply --index --reject \"%s\"" %
1130 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1131 "", cb=VerifyPatch("patch1")),
1132 Cmd("git log -1 -p hash5", "patch5\n"),
1133 Cmd(("git apply --index --reject \"%s\"" %
1134 TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
1135 "", cb=VerifyPatch("patch5\n")),
1136 Cmd("git apply --index --reject \"%s\"" % extra_patch, ""),
1137 RL("Y"), # Automatically increment patch level?
1138 Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], ""),
1139 RL("reviewer@chromium.org"), # V8 reviewer.
1140 Cmd("git cl upload --send-mail -r \"reviewer@chromium.org\" "
1141 "--bypass-hooks", ""),
1142 Cmd("git checkout -f %s" % TEST_CONFIG["BRANCHNAME"], ""),
1143 RL("LGTM"), # Enter LGTM for V8 CL.
1144 Cmd("git cl presubmit", "Presubmit successfull\n"),
1145 Cmd("git cl dcommit -f --bypass-hooks", "Closing issue\n",
1146 cb=VerifySVNCommit),
1147 Cmd("git svn fetch", ""),
1148 Cmd(("git log -1 --format=%%H --grep=\"%s\" svn/trunk"
1149 % msg.replace("\"", "\\\"")), "hash6"),
1150 Cmd("git svn find-rev hash6", "1324"),
1151 Cmd(("svn copy -r 1324 https://v8.googlecode.com/svn/trunk "
1152 "https://v8.googlecode.com/svn/tags/3.22.5.1 -m "
1153 "\"Tagging version 3.22.5.1\""), ""),
1154 Cmd("git checkout -f some_branch", ""),
1155 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
1158 # r12345 and r34567 are patches. r23456 (included) and r45678 are the MIPS
1159 # ports of r12345. r56789 is the MIPS port of r34567.
1160 args = ["-f", "-p", extra_patch, "--branch", "trunk", "12345", "23456",
1163 # The first run of the script stops because of the svn being down.
1164 self.assertRaises(GitFailedException,
1165 lambda: MergeToBranch(TEST_CONFIG, self).Run(args))
1167 # Test that state recovery after restarting the script works.
1169 MergeToBranch(TEST_CONFIG, self).Run(args)
1171 def testReleases(self):
1172 tag_response_text = """
1173 ------------------------------------------------------------------------
1174 r22631 | author1@chromium.org | 2014-07-28 02:05:29 +0200 (Mon, 28 Jul 2014)
1176 A /tags/3.28.43 (from /trunk:22630)
1178 Tagging version 3.28.43
1179 ------------------------------------------------------------------------
1180 r22629 | author2@chromium.org | 2014-07-26 05:09:29 +0200 (Sat, 26 Jul 2014)
1182 A /tags/3.28.41 (from /branches/bleeding_edge:22626)
1184 Tagging version 3.28.41
1185 ------------------------------------------------------------------------
1186 r22556 | author3@chromium.org | 2014-07-23 13:31:59 +0200 (Wed, 23 Jul 2014)
1188 A /tags/3.27.34.7 (from /branches/3.27:22555)
1190 Tagging version 3.27.34.7
1191 ------------------------------------------------------------------------
1192 r22627 | author4@chromium.org | 2014-07-26 01:39:15 +0200 (Sat, 26 Jul 2014)
1194 A /tags/3.28.40 (from /branches/bleeding_edge:22624)
1196 Tagging version 3.28.40
1197 ------------------------------------------------------------------------
1199 c_hash2_commit_log = """Revert something.
1205 > Cr-Commit-Position: refs/heads/master@{#12345}
1206 > git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12345 003-1c4
1208 Review URL: https://codereview.chromium.org/12345
1210 Cr-Commit-Position: refs/heads/master@{#4567}
1211 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4567 0039-1c4b
1214 c_hash3_commit_log = """Simple.
1216 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3456 0039-1c4b
1219 json_output = self.MakeEmptyTempFile()
1220 csv_output = self.MakeEmptyTempFile()
1221 self.WriteFakeVersionFile()
1223 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory()
1224 chrome_dir = TEST_CONFIG["CHROMIUM"]
1225 chrome_v8_dir = os.path.join(chrome_dir, "v8")
1226 os.makedirs(chrome_v8_dir)
1227 def WriteDEPS(revision):
1228 TextToFile("Line\n \"v8_revision\": \"%s\",\n line\n" % revision,
1229 os.path.join(chrome_dir, "DEPS"))
1232 def ResetVersion(minor, build, patch=0):
1233 return lambda: self.WriteFakeVersionFile(minor=minor,
1237 def ResetDEPS(revision):
1238 return lambda: WriteDEPS(revision)
1241 Cmd("git status -s -uno", ""),
1242 Cmd("git status -s -b -uno", "## some_branch\n"),
1243 Cmd("git svn fetch", ""),
1244 Cmd("git branch", " branch1\n* branch2\n"),
1245 Cmd("git checkout -b %s" % TEST_CONFIG["BRANCHNAME"], ""),
1246 Cmd("git branch -r", " svn/3.21\n svn/3.3\n"),
1247 Cmd("git reset --hard svn/3.3", ""),
1248 Cmd("git log --format=%H", "hash1\nhash2"),
1249 Cmd("git diff --name-only hash1 hash1^", ""),
1250 Cmd("git diff --name-only hash2 hash2^", VERSION_FILE),
1251 Cmd("git checkout -f hash2 -- %s" % VERSION_FILE, "",
1252 cb=ResetVersion(3, 1, 1)),
1253 Cmd("git log -1 --format=%B hash2",
1254 "Version 3.3.1.1 (merged 12)\n\nReview URL: fake.com\n"),
1255 Cmd("git log -1 --format=%s hash2", ""),
1256 Cmd("git svn find-rev hash2", "234"),
1257 Cmd("git log -1 --format=%ci hash2", "18:15"),
1258 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1259 cb=ResetVersion(22, 5)),
1260 Cmd("git reset --hard svn/3.21", ""),
1261 Cmd("git log --format=%H", "hash3\nhash4\nhash5\n"),
1262 Cmd("git diff --name-only hash3 hash3^", VERSION_FILE),
1263 Cmd("git checkout -f hash3 -- %s" % VERSION_FILE, "",
1264 cb=ResetVersion(21, 2)),
1265 Cmd("git log -1 --format=%B hash3", ""),
1266 Cmd("git log -1 --format=%s hash3", ""),
1267 Cmd("git svn find-rev hash3", "123"),
1268 Cmd("git log -1 --format=%ci hash3", "03:15"),
1269 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1270 cb=ResetVersion(22, 5)),
1271 Cmd("git reset --hard svn/trunk", ""),
1272 Cmd("git log --format=%H", "hash6\n"),
1273 Cmd("git diff --name-only hash6 hash6^", VERSION_FILE),
1274 Cmd("git checkout -f hash6 -- %s" % VERSION_FILE, "",
1275 cb=ResetVersion(22, 3)),
1276 Cmd("git log -1 --format=%B hash6", ""),
1277 Cmd("git log -1 --format=%s hash6", ""),
1278 Cmd("git svn find-rev hash6", "345"),
1279 Cmd("git log -1 --format=%ci hash6", ""),
1280 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1281 cb=ResetVersion(22, 5)),
1282 Cmd("git reset --hard svn/bleeding_edge", ""),
1283 Cmd("svn log https://v8.googlecode.com/svn/tags -v --limit 20",
1285 Cmd("git svn find-rev r22626", "hash_22626"),
1286 Cmd("git svn find-rev hash_22626", "22626"),
1287 Cmd("git log -1 --format=%ci hash_22626", "01:23"),
1288 Cmd("git svn find-rev r22624", "hash_22624"),
1289 Cmd("git svn find-rev hash_22624", "22624"),
1290 Cmd("git log -1 --format=%ci hash_22624", "02:34"),
1291 Cmd("git status -s -uno", "", cwd=chrome_dir),
1292 Cmd("git checkout -f master", "", cwd=chrome_dir),
1293 Cmd("git pull", "", cwd=chrome_dir),
1294 Cmd("git checkout -b %s" % TEST_CONFIG["BRANCHNAME"], "", cwd=chrome_dir),
1295 Cmd("git fetch origin", "", cwd=chrome_v8_dir),
1296 Cmd("git log --format=%H --grep=\"V8\"", "c_hash1\nc_hash2\nc_hash3\n",
1298 Cmd("git diff --name-only c_hash1 c_hash1^", "", cwd=chrome_dir),
1299 Cmd("git diff --name-only c_hash2 c_hash2^", "DEPS", cwd=chrome_dir),
1300 Cmd("git checkout -f c_hash2 -- DEPS", "",
1301 cb=ResetDEPS("0123456789012345678901234567890123456789"),
1303 Cmd("git log -1 --format=%B c_hash2", c_hash2_commit_log,
1305 Cmd("git rev-list -n 1 0123456789012345678901234567890123456789",
1306 "0123456789012345678901234567890123456789", cwd=chrome_v8_dir),
1307 Cmd("git log -1 --format=%B 0123456789012345678901234567890123456789",
1308 self.C_V8_22624_LOG, cwd=chrome_v8_dir),
1309 Cmd("git diff --name-only c_hash3 c_hash3^", "DEPS", cwd=chrome_dir),
1310 Cmd("git checkout -f c_hash3 -- DEPS", "", cb=ResetDEPS(345),
1312 Cmd("git log -1 --format=%B c_hash3", c_hash3_commit_log,
1314 Cmd("git checkout -f HEAD -- DEPS", "", cb=ResetDEPS(567),
1316 Cmd("git branch -r", " weird/123\n branch-heads/7\n", cwd=chrome_dir),
1317 Cmd("git checkout -f branch-heads/7 -- DEPS", "", cb=ResetDEPS(345),
1319 Cmd("git checkout -f HEAD -- DEPS", "", cb=ResetDEPS(567),
1321 Cmd("git checkout -f master", "", cwd=chrome_dir),
1322 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], "", cwd=chrome_dir),
1323 Cmd("git checkout -f some_branch", ""),
1324 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
1327 args = ["-c", TEST_CONFIG["CHROMIUM"],
1328 "--json", json_output,
1329 "--csv", csv_output,
1330 "--max-releases", "1"]
1331 Releases(TEST_CONFIG, self).Run(args)
1333 # Check expected output.
1334 csv = ("3.28.41,bleeding_edge,22626,,\r\n"
1335 "3.28.40,bleeding_edge,22624,4567,\r\n"
1336 "3.22.3,trunk,345,3456:4566,\r\n"
1337 "3.21.2,3.21,123,,\r\n"
1338 "3.3.1.1,3.3,234,,12\r\n")
1339 self.assertEquals(csv, FileToText(csv_output))
1342 {"bleeding_edge": "22626", "patches_merged": "", "version": "3.28.41",
1343 "chromium_revision": "", "branch": "bleeding_edge", "revision": "22626",
1344 "review_link": "", "date": "01:23", "chromium_branch": "",
1345 "revision_link": "https://code.google.com/p/v8/source/detail?r=22626"},
1346 {"bleeding_edge": "22624", "patches_merged": "", "version": "3.28.40",
1347 "chromium_revision": "4567", "branch": "bleeding_edge",
1348 "revision": "22624", "review_link": "", "date": "02:34",
1349 "chromium_branch": "",
1350 "revision_link": "https://code.google.com/p/v8/source/detail?r=22624"},
1351 {"bleeding_edge": "", "patches_merged": "", "version": "3.22.3",
1352 "chromium_revision": "3456:4566", "branch": "trunk", "revision": "345",
1353 "review_link": "", "date": "", "chromium_branch": "7",
1354 "revision_link": "https://code.google.com/p/v8/source/detail?r=345"},
1355 {"patches_merged": "", "bleeding_edge": "", "version": "3.21.2",
1356 "chromium_revision": "", "branch": "3.21", "revision": "123",
1357 "review_link": "", "date": "03:15", "chromium_branch": "",
1358 "revision_link": "https://code.google.com/p/v8/source/detail?r=123"},
1359 {"patches_merged": "12", "bleeding_edge": "", "version": "3.3.1.1",
1360 "chromium_revision": "", "branch": "3.3", "revision": "234",
1361 "review_link": "fake.com", "date": "18:15", "chromium_branch": "",
1362 "revision_link": "https://code.google.com/p/v8/source/detail?r=234"},
1364 self.assertEquals(expected_json, json.loads(FileToText(json_output)))
1367 def _bumpUpVersion(self):
1368 self.WriteFakeVersionFile()
1370 def ResetVersion(minor, build, patch=0):
1371 return lambda: self.WriteFakeVersionFile(minor=minor,
1376 Cmd("git status -s -uno", ""),
1377 Cmd("git checkout -f bleeding_edge", "", cb=ResetVersion(11, 4)),
1378 Cmd("git pull", ""),
1379 Cmd("git branch", ""),
1380 Cmd("git checkout -f bleeding_edge", ""),
1381 Cmd("git log -1 --format=%H", "latest_hash"),
1382 Cmd("git diff --name-only latest_hash latest_hash^", ""),
1383 URL("https://v8-status.appspot.com/lkgr", "12345"),
1384 Cmd("git checkout -f bleeding_edge", ""),
1385 Cmd(("git log --format=%H --grep="
1386 "\"^git-svn-id: [^@]*@12345 [A-Za-z0-9-]*$\""),
1388 Cmd("git checkout -b auto-bump-up-version lkgr_hash", ""),
1389 Cmd("git checkout -f bleeding_edge", ""),
1390 Cmd("git branch", ""),
1391 Cmd("git diff --name-only lkgr_hash lkgr_hash^", ""),
1392 Cmd("git checkout -f master", "", cb=ResetVersion(11, 5)),
1393 Cmd("git pull", ""),
1394 URL("https://v8-status.appspot.com/current?format=json",
1395 "{\"message\": \"Tree is open\"}"),
1396 Cmd("git checkout -b auto-bump-up-version bleeding_edge", "",
1397 cb=ResetVersion(11, 4)),
1398 Cmd("git commit -am \"[Auto-roll] Bump up version to 3.11.6.0\n\n"
1399 "TBR=author@chromium.org\" "
1400 "--author \"author@chromium.org <author@chromium.org>\"", ""),
1403 def testBumpUpVersionGit(self):
1404 expectations = self._bumpUpVersion()
1406 Cmd("git cl upload --send-mail --email \"author@chromium.org\" -f "
1407 "--bypass-hooks", ""),
1408 Cmd("git cl dcommit -f --bypass-hooks", ""),
1409 Cmd("git checkout -f bleeding_edge", ""),
1410 Cmd("git branch", "auto-bump-up-version\n* bleeding_edge"),
1411 Cmd("git branch -D auto-bump-up-version", ""),
1413 self.Expect(expectations)
1415 BumpUpVersion(TEST_CONFIG, self).Run(["-a", "author@chromium.org"])
1417 def testBumpUpVersionSvn(self):
1418 svn_root = self.MakeEmptyTempDirectory()
1419 expectations = self._bumpUpVersion()
1421 Cmd("git diff HEAD^ HEAD", "patch content"),
1422 Cmd("svn update", "", cwd=svn_root),
1423 Cmd("svn status", "", cwd=svn_root),
1424 Cmd("patch -d branches/bleeding_edge -p1 -i %s" %
1425 TEST_CONFIG["PATCH_FILE"], "Applied patch...", cwd=svn_root),
1426 Cmd("svn commit --non-interactive --username=author@chromium.org "
1427 "--config-dir=[CONFIG_DIR] "
1428 "-m \"[Auto-roll] Bump up version to 3.11.6.0\"",
1430 Cmd("git checkout -f bleeding_edge", ""),
1431 Cmd("git branch", "auto-bump-up-version\n* bleeding_edge"),
1432 Cmd("git branch -D auto-bump-up-version", ""),
1434 self.Expect(expectations)
1436 BumpUpVersion(TEST_CONFIG, self).Run(
1437 ["-a", "author@chromium.org",
1439 "--svn-config", "[CONFIG_DIR]"])
1441 def testAutoTag(self):
1442 self.WriteFakeVersionFile()
1444 def ResetVersion(minor, build, patch=0):
1445 return lambda: self.WriteFakeVersionFile(minor=minor,
1450 Cmd("git status -s -uno", ""),
1451 Cmd("git status -s -b -uno", "## some_branch\n"),
1452 Cmd("git svn fetch", ""),
1453 Cmd("git branch", " branch1\n* branch2\n"),
1454 Cmd("git checkout -f master", ""),
1455 Cmd("git svn rebase", ""),
1456 Cmd("git checkout -b %s" % TEST_CONFIG["BRANCHNAME"], "",
1457 cb=ResetVersion(4, 5)),
1458 Cmd("git branch -r",
1459 "svn/tags/3.4.2\nsvn/tags/3.2.1.0\nsvn/branches/3.4"),
1460 Cmd(("git log --format=%H --grep="
1461 "\"\\[Auto\\-roll\\] Bump up version to\""),
1462 "hash125\nhash118\nhash111\nhash101"),
1463 Cmd("git checkout -f hash125 -- %s" % VERSION_FILE, "",
1464 cb=ResetVersion(4, 4)),
1465 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1466 cb=ResetVersion(4, 5)),
1467 Cmd("git checkout -f hash118 -- %s" % VERSION_FILE, "",
1468 cb=ResetVersion(4, 3)),
1469 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1470 cb=ResetVersion(4, 5)),
1471 Cmd("git checkout -f hash111 -- %s" % VERSION_FILE, "",
1472 cb=ResetVersion(4, 2)),
1473 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
1474 cb=ResetVersion(4, 5)),
1475 URL("https://v8-status.appspot.com/revisions?format=json",
1476 "[{\"revision\": \"126\", \"status\": true},"
1477 "{\"revision\": \"123\", \"status\": true},"
1478 "{\"revision\": \"112\", \"status\": true}]"),
1479 Cmd("git svn find-rev hash118", "118"),
1480 Cmd("git svn find-rev hash125", "125"),
1481 Cmd("git svn find-rev r123", "hash123"),
1482 Cmd("git log -1 --format=%at hash123", "1"),
1483 Cmd("git reset --hard hash123", ""),
1484 Cmd("git svn tag 3.4.3 -m \"Tagging version 3.4.3\"", ""),
1485 Cmd("git checkout -f some_branch", ""),
1486 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
1489 AutoTag(TEST_CONFIG, self).Run(["-a", "author@chromium.org"])
1491 # Test that we bail out if the last change was a version change.
1492 def testBumpUpVersionBailout1(self):
1493 self._state["latest"] = "latest_hash"
1496 Cmd("git diff --name-only latest_hash latest_hash^", VERSION_FILE),
1499 self.assertEquals(0,
1500 self.RunStep(BumpUpVersion, LastChangeBailout, ["--dry_run"]))
1502 # Test that we bail out if the lkgr was a version change.
1503 def testBumpUpVersionBailout2(self):
1504 self._state["lkgr"] = "lkgr_hash"
1507 Cmd("git diff --name-only lkgr_hash lkgr_hash^", VERSION_FILE),
1510 self.assertEquals(0,
1511 self.RunStep(BumpUpVersion, LKGRVersionUpToDateBailout, ["--dry_run"]))
1513 # Test that we bail out if the last version is already newer than the lkgr's
1515 def testBumpUpVersionBailout3(self):
1516 self._state["lkgr"] = "lkgr_hash"
1517 self._state["lkgr_version"] = "3.22.4.0"
1518 self._state["latest_version"] = "3.22.5.0"
1521 Cmd("git diff --name-only lkgr_hash lkgr_hash^", ""),
1524 self.assertEquals(0,
1525 self.RunStep(BumpUpVersion, LKGRVersionUpToDateBailout, ["--dry_run"]))
1528 class SystemTest(unittest.TestCase):
1529 def testReload(self):
1530 step = MakeStep(step_class=PrepareChangeLog, number=0, state={}, config={},
1531 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER)
1533 """------------------------------------------------------------------------
1534 r17997 | machenbach@chromium.org | 2013-11-22 11:04:04 +0100 (...) | 6 lines
1536 Prepare push to trunk. Now working on version 3.23.11.
1538 R=danno@chromium.org
1540 Review URL: https://codereview.chromium.org/83173002
1542 ------------------------------------------------------------------------""")
1544 """Prepare push to trunk. Now working on version 3.23.11.
1546 R=danno@chromium.org
1548 Committed: https://code.google.com/p/v8/source/detail?r=17997""", body)