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.
35 from auto_push import CheckLastPush
36 from auto_push import SETTINGS_LOCATION
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 CHROMIUM
46 from chromium_roll import DEPS_FILE
47 from chromium_roll import ChromiumRoll
49 from releases import Releases
53 BRANCHNAME: "test-prepare-push",
54 TRUNKBRANCH: "test-trunk-push",
55 PERSISTFILE_BASENAME: "/tmp/test-v8-push-to-trunk-tempfile",
56 DOT_GIT_LOCATION: None,
59 CHANGELOG_ENTRY_FILE: "/tmp/test-v8-push-to-trunk-tempfile-changelog-entry",
60 PATCH_FILE: "/tmp/test-v8-push-to-trunk-tempfile-patch",
61 COMMITMSG_FILE: "/tmp/test-v8-push-to-trunk-tempfile-commitmsg",
62 CHROMIUM: "/tmp/test-v8-push-to-trunk-tempfile-chromium",
63 DEPS_FILE: "/tmp/test-v8-push-to-trunk-tempfile-chromium/DEPS",
64 SETTINGS_LOCATION: None,
65 ALREADY_MERGING_SENTINEL_FILE:
66 "/tmp/test-merge-to-branch-tempfile-already-merging",
67 COMMIT_HASHES_FILE: "/tmp/test-merge-to-branch-tempfile-PATCH_COMMIT_HASHES",
68 TEMPORARY_PATCH_FILE: "/tmp/test-merge-to-branch-tempfile-temporary-patch",
73 "-a", "author@chromium.org",
74 "-r", "reviewer@chromium.org",
78 class ToplevelTest(unittest.TestCase):
79 def testSortBranches(self):
80 S = releases.SortBranches
81 self.assertEquals(["3.1", "2.25"], S(["2.25", "3.1"])[0:2])
82 self.assertEquals(["3.0", "2.25"], S(["2.25", "3.0", "2.24"])[0:2])
83 self.assertEquals(["3.11", "3.2"], S(["3.11", "3.2", "2.24"])[0:2])
85 def testFilterDuplicatesAndReverse(self):
86 F = releases.FilterDuplicatesAndReverse
87 self.assertEquals([], F([]))
88 self.assertEquals([["100", "10"]], F([["100", "10"]]))
89 self.assertEquals([["99", "9"], ["100", "10"]],
90 F([["100", "10"], ["99", "9"]]))
91 self.assertEquals([["98", "9"], ["100", "10"]],
92 F([["100", "10"], ["99", "9"], ["98", "9"]]))
93 self.assertEquals([["98", "9"], ["99", "10"]],
94 F([["100", "10"], ["99", "10"], ["98", "9"]]))
96 def testBuildRevisionRanges(self):
97 B = releases.BuildRevisionRanges
98 self.assertEquals({}, B([]))
99 self.assertEquals({"10": "100"}, B([["100", "10"]]))
100 self.assertEquals({"10": "100", "9": "99:99"},
101 B([["100", "10"], ["99", "9"]]))
102 self.assertEquals({"10": "100", "9": "97:99"},
103 B([["100", "10"], ["98", "9"], ["97", "9"]]))
104 self.assertEquals({"10": "100", "9": "99:99", "3": "91:98"},
105 B([["100", "10"], ["99", "9"], ["91", "3"]]))
106 self.assertEquals({"13": "101", "12": "100:100", "9": "94:97",
107 "3": "91:93, 98:99"},
108 B([["101", "13"], ["100", "12"], ["98", "3"],
109 ["94", "9"], ["91", "3"]]))
111 def testMakeComment(self):
112 self.assertEquals("# Line 1\n# Line 2\n#",
113 MakeComment(" Line 1\n Line 2\n"))
114 self.assertEquals("#Line 1\n#Line 2",
115 MakeComment("Line 1\n Line 2"))
117 def testStripComments(self):
118 self.assertEquals(" Line 1\n Line 3\n",
119 StripComments(" Line 1\n# Line 2\n Line 3\n#\n"))
120 self.assertEquals("\nLine 2 ### Test\n #",
121 StripComments("###\n# \n\n# Line 1\nLine 2 ### Test\n #"))
123 def testMakeChangeLogBodySimple(self):
126 "Title text 1\n\nBUG=\n",
127 "author1@chromium.org"],
129 "Title text 2\n\nBUG=1234\n",
130 "author2@chromium.org"],
132 self.assertEquals(" Title text 1.\n"
133 " (author1@chromium.org)\n\n"
134 " Title text 2 (Chromium issue 1234).\n"
135 " (author2@chromium.org)\n\n",
136 MakeChangeLogBody(commits))
138 def testMakeChangeLogBodyEmpty(self):
139 self.assertEquals("", MakeChangeLogBody([]))
141 def testMakeChangeLogBodyAutoFormat(self):
144 "Title text 1\nLOG=y\nBUG=\n",
145 "author1@chromium.org"],
147 "Title text 2\n\nBUG=1234\n",
148 "author2@chromium.org"],
150 "Title text 3\n\nBUG=1234\nLOG = Yes\n",
151 "author3@chromium.org"],
153 "Title text 4\n\nBUG=1234\nLOG=\n",
154 "author4@chromium.org"],
156 self.assertEquals(" Title text 1.\n\n"
157 " Title text 3 (Chromium issue 1234).\n\n",
158 MakeChangeLogBody(commits, True))
160 def testRegressWrongLogEntryOnTrue(self):
162 Check elimination: Learn from if(CompareMap(x)) on true branch.
165 R=verwaest@chromium.org
167 Committed: https://code.google.com/p/v8/source/detail?r=18210
169 self.assertEquals("", MakeChangeLogBody([["title", body, "author"]], True))
171 def testMakeChangeLogBugReferenceEmpty(self):
172 self.assertEquals("", MakeChangeLogBugReference(""))
173 self.assertEquals("", MakeChangeLogBugReference("LOG="))
174 self.assertEquals("", MakeChangeLogBugReference(" BUG ="))
175 self.assertEquals("", MakeChangeLogBugReference("BUG=none\t"))
177 def testMakeChangeLogBugReferenceSimple(self):
178 self.assertEquals("(issue 987654)",
179 MakeChangeLogBugReference("BUG = v8:987654"))
180 self.assertEquals("(Chromium issue 987654)",
181 MakeChangeLogBugReference("BUG=987654 "))
183 def testMakeChangeLogBugReferenceFromBody(self):
184 self.assertEquals("(Chromium issue 1234567)",
185 MakeChangeLogBugReference("Title\n\nTBR=\nBUG=\n"
186 " BUG=\tchromium:1234567\t\n"
189 def testMakeChangeLogBugReferenceMultiple(self):
190 # All issues should be sorted and grouped. Multiple references to the same
191 # issue should be filtered.
192 self.assertEquals("(issues 123, 234, Chromium issue 345)",
193 MakeChangeLogBugReference("Title\n\n"
195 " BUG\t= 345, \tv8:234,\n"
198 self.assertEquals("(Chromium issues 123, 234)",
199 MakeChangeLogBugReference("Title\n\n"
200 "BUG=234,,chromium:123 \n"
202 self.assertEquals("(Chromium issues 123, 234)",
203 MakeChangeLogBugReference("Title\n\n"
204 "BUG=chromium:234, , 123\n"
206 self.assertEquals("(issues 345, 456)",
207 MakeChangeLogBugReference("Title\n\n"
208 "\t\tBUG=v8:345,v8:456\n"
210 self.assertEquals("(issue 123, Chromium issues 345, 456)",
211 MakeChangeLogBugReference("Title\n\n"
215 "BUG=456,v8:123, 345"))
217 # TODO(machenbach): These test don't make much sense when the formatting is
219 def testMakeChangeLogBugReferenceLong(self):
220 # -----------------00--------10--------20--------30--------
221 self.assertEquals("(issues 234, 1234567890, 1234567"
222 "8901234567890, Chromium issues 12345678,"
224 MakeChangeLogBugReference("BUG=v8:234\n"
225 "BUG=v8:1234567890\n"
226 "BUG=v8:12345678901234567890\n"
229 # -----------------00--------10--------20--------30--------
230 self.assertEquals("(issues 234, 1234567890, 1234567"
231 "8901234567890, Chromium issues"
232 " 123456789, 1234567890)",
233 MakeChangeLogBugReference("BUG=v8:234\n"
234 "BUG=v8:12345678901234567890\n"
235 "BUG=v8:1234567890\n"
238 # -----------------00--------10--------20--------30--------
239 self.assertEquals("(Chromium issues 234, 1234567890"
240 ", 12345678901234567, "
241 "1234567890123456789)",
242 MakeChangeLogBugReference("BUG=234\n"
243 "BUG=12345678901234567\n"
244 "BUG=1234567890123456789\n"
248 def Git(*args, **kwargs):
249 """Convenience function returning a git test expectation."""
254 "cb": kwargs.get("cb"),
258 def RL(text, cb=None):
259 """Convenience function returning a readline test expectation."""
260 return {"name": "readline", "args": [], "ret": text, "cb": cb}
263 def URL(*args, **kwargs):
264 """Convenience function returning a readurl test expectation."""
269 "cb": kwargs.get("cb"),
273 class SimpleMock(object):
274 def __init__(self, name):
279 def Expect(self, recipe):
280 self._recipe = recipe
282 def Call(self, name, *args): # pragma: no cover
285 expected_call = self._recipe[self._index]
287 raise NoRetryException("Calling %s %s" % (name, " ".join(args)))
289 if not isinstance(expected_call, dict):
290 raise NoRetryException("Found wrong expectation type for %s %s"
291 % (name, " ".join(args)))
294 # The number of arguments in the expectation must match the actual
296 if len(args) > len(expected_call['args']):
297 raise NoRetryException("When calling %s with arguments, the "
298 "expectations must consist of at least as many arguments." % name)
300 # Compare expected and actual arguments.
301 for (expected_arg, actual_arg) in zip(expected_call['args'], args):
302 if expected_arg != actual_arg:
303 raise NoRetryException("Expected: %s - Actual: %s"
304 % (expected_arg, actual_arg))
306 # The expected call contains an optional callback for checking the context
307 # at the time of the call.
308 if expected_call['cb']:
310 expected_call['cb']()
312 tb = traceback.format_exc()
313 raise NoRetryException("Caught exception from callback: %s" % tb)
315 # If the return value is an exception, raise it instead of returning.
316 if isinstance(expected_call['ret'], Exception):
317 raise expected_call['ret']
318 return expected_call['ret']
320 def AssertFinished(self): # pragma: no cover
321 if self._index < len(self._recipe) -1:
322 raise NoRetryException("Called %s too seldom: %d vs. %d"
323 % (self._name, self._index, len(self._recipe)))
326 class ScriptTest(unittest.TestCase):
327 def MakeEmptyTempFile(self):
328 handle, name = tempfile.mkstemp()
330 self._tmp_files.append(name)
333 def WriteFakeVersionFile(self, minor=22, build=4, patch=0):
334 with open(TEST_CONFIG[VERSION_FILE], "w") as f:
335 f.write(" // Some line...\n")
337 f.write("#define MAJOR_VERSION 3\n")
338 f.write("#define MINOR_VERSION %s\n" % minor)
339 f.write("#define BUILD_NUMBER %s\n" % build)
340 f.write("#define PATCH_LEVEL %s\n" % patch)
341 f.write(" // Some line...\n")
342 f.write("#define IS_CANDIDATE_VERSION 0\n")
345 """Convenience wrapper."""
346 options = ScriptsBase(TEST_CONFIG, self, self._state).MakeOptions([])
347 return MakeStep(step_class=Step, state=self._state,
348 config=TEST_CONFIG, side_effect_handler=self,
351 def RunStep(self, script=PushToTrunk, step_class=Step, args=None):
352 """Convenience wrapper."""
353 args = args or ["-m"]
354 return script(TEST_CONFIG, self, self._state).RunSteps([step_class], args)
356 def GitMock(self, cmd, args="", pipe=True):
357 print "%s %s" % (cmd, args)
358 return self._git_mock.Call("git", args)
360 def LogMock(self, cmd, args=""):
361 print "Log: %s %s" % (cmd, args)
365 # TODO(machenbach): Little hack to reuse the git mock for the one svn call
366 # in merge-to-branch. The command should be made explicit in the test
372 def Call(self, fun, *args, **kwargs):
373 print "Calling %s with %s and %s" % (str(fun), str(args), str(kwargs))
375 def Command(self, cmd, args="", prefix="", pipe=True):
376 return ScriptTest.MOCKS[cmd](self, cmd, args)
379 return self._rl_mock.Call("readline")
381 def ReadURL(self, url, params):
382 if params is not None:
383 return self._url_mock.Call("readurl", url, params)
385 return self._url_mock.Call("readurl", url)
387 def Sleep(self, seconds):
393 def ExpectGit(self, *args):
394 """Convenience wrapper."""
395 self._git_mock.Expect(*args)
397 def ExpectReadline(self, *args):
398 """Convenience wrapper."""
399 self._rl_mock.Expect(*args)
401 def ExpectReadURL(self, *args):
402 """Convenience wrapper."""
403 self._url_mock.Expect(*args)
406 self._git_mock = SimpleMock("git")
407 self._rl_mock = SimpleMock("readline")
408 self._url_mock = SimpleMock("readurl")
413 Command("rm", "-rf %s*" % TEST_CONFIG[PERSISTFILE_BASENAME])
415 # Clean up temps. Doesn't work automatically.
416 for name in self._tmp_files:
417 if os.path.exists(name):
420 self._git_mock.AssertFinished()
421 self._rl_mock.AssertFinished()
422 self._url_mock.AssertFinished()
424 def testGitOrig(self):
425 self.assertTrue(Command("git", "--version").startswith("git version"))
427 def testGitMock(self):
428 self.ExpectGit([Git("--version", "git version 1.2.3"), Git("dummy", "")])
429 self.assertEquals("git version 1.2.3", self.MakeStep().Git("--version"))
430 self.assertEquals("", self.MakeStep().Git("dummy"))
432 def testCommonPrepareDefault(self):
434 Git("status -s -uno", ""),
435 Git("status -s -b -uno", "## some_branch"),
436 Git("svn fetch", ""),
437 Git("branch", " branch1\n* %s" % TEST_CONFIG[BRANCHNAME]),
438 Git("branch -D %s" % TEST_CONFIG[BRANCHNAME], ""),
440 self.ExpectReadline([RL("Y")])
441 self.MakeStep().CommonPrepare()
442 self.MakeStep().PrepareBranch()
443 self.assertEquals("some_branch", self._state["current_branch"])
445 def testCommonPrepareNoConfirm(self):
447 Git("status -s -uno", ""),
448 Git("status -s -b -uno", "## some_branch"),
449 Git("svn fetch", ""),
450 Git("branch", " branch1\n* %s" % TEST_CONFIG[BRANCHNAME]),
452 self.ExpectReadline([RL("n")])
453 self.MakeStep().CommonPrepare()
454 self.assertRaises(Exception, self.MakeStep().PrepareBranch)
455 self.assertEquals("some_branch", self._state["current_branch"])
457 def testCommonPrepareDeleteBranchFailure(self):
459 Git("status -s -uno", ""),
460 Git("status -s -b -uno", "## some_branch"),
461 Git("svn fetch", ""),
462 Git("branch", " branch1\n* %s" % TEST_CONFIG[BRANCHNAME]),
463 Git("branch -D %s" % TEST_CONFIG[BRANCHNAME], None),
465 self.ExpectReadline([RL("Y")])
466 self.MakeStep().CommonPrepare()
467 self.assertRaises(Exception, self.MakeStep().PrepareBranch)
468 self.assertEquals("some_branch", self._state["current_branch"])
470 def testInitialEnvironmentChecks(self):
471 TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile()
472 os.environ["EDITOR"] = "vi"
473 self.MakeStep().InitialEnvironmentChecks()
475 def testReadAndPersistVersion(self):
476 TEST_CONFIG[VERSION_FILE] = self.MakeEmptyTempFile()
477 self.WriteFakeVersionFile(build=5)
478 step = self.MakeStep()
479 step.ReadAndPersistVersion()
480 self.assertEquals("3", step["major"])
481 self.assertEquals("22", step["minor"])
482 self.assertEquals("5", step["build"])
483 self.assertEquals("0", step["patch"])
486 self.assertEqual("(issue 321)",
487 re.sub(r"BUG=v8:(.*)$", r"(issue \1)", "BUG=v8:321"))
488 self.assertEqual("(Chromium issue 321)",
489 re.sub(r"BUG=(.*)$", r"(Chromium issue \1)", "BUG=321"))
491 cl = " too little\n\ttab\ttab\n too much\n trailing "
492 cl = MSub(r"\t", r" ", cl)
493 cl = MSub(r"^ {1,7}([^ ])", r" \1", cl)
494 cl = MSub(r"^ {9,80}([^ ])", r" \1", cl)
495 cl = MSub(r" +$", r"", cl)
496 self.assertEqual(" too little\n"
501 self.assertEqual("//\n#define BUILD_NUMBER 3\n",
502 MSub(r"(?<=#define BUILD_NUMBER)(?P<space>\s+)\d*$",
504 "//\n#define BUILD_NUMBER 321\n"))
506 def testPreparePushRevision(self):
507 # Tests the default push hash used when the --revision option is not set.
509 Git("log -1 --format=%H HEAD", "push_hash")
512 self.RunStep(PushToTrunk, PreparePushRevision)
513 self.assertEquals("push_hash", self._state["push_hash"])
515 def testPrepareChangeLog(self):
516 TEST_CONFIG[VERSION_FILE] = self.MakeEmptyTempFile()
517 self.WriteFakeVersionFile()
518 TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile()
521 Git("log --format=%H 1234..push_hash", "rev1\nrev2\nrev3\nrev4"),
522 Git("log -1 --format=%s rev1", "Title text 1"),
523 Git("log -1 --format=%B rev1", "Title\n\nBUG=\nLOG=y\n"),
524 Git("log -1 --format=%an rev1", "author1@chromium.org"),
525 Git("log -1 --format=%s rev2", "Title text 2."),
526 Git("log -1 --format=%B rev2", "Title\n\nBUG=123\nLOG= \n"),
527 Git("log -1 --format=%an rev2", "author2@chromium.org"),
528 Git("log -1 --format=%s rev3", "Title text 3"),
529 Git("log -1 --format=%B rev3", "Title\n\nBUG=321\nLOG=true\n"),
530 Git("log -1 --format=%an rev3", "author3@chromium.org"),
531 Git("log -1 --format=%s rev4", "Title text 4"),
532 Git("log -1 --format=%B rev4",
533 ("Title\n\nBUG=456\nLOG=Y\n\n"
534 "Review URL: https://codereview.chromium.org/9876543210\n")),
535 Git("log -1 --format=%an rev4", "author4@chromium.org"),
538 # The cl for rev4 on rietveld has an updated LOG flag.
540 URL("https://codereview.chromium.org/9876543210/description",
541 "Title\n\nBUG=456\nLOG=N\n\n"),
544 self._state["last_push_bleeding_edge"] = "1234"
545 self._state["push_hash"] = "push_hash"
546 self._state["version"] = "3.22.5"
547 self.RunStep(PushToTrunk, PrepareChangeLog)
549 actual_cl = FileToText(TEST_CONFIG[CHANGELOG_ENTRY_FILE])
551 expected_cl = """1999-07-31: Version 3.22.5
555 Title text 3 (Chromium issue 321).
557 Performance and stability improvements on all platforms.
559 # The change log above is auto-generated. Please review if all relevant
560 # commit messages from the list below are included.
561 # All lines starting with # will be stripped.
564 # (author1@chromium.org)
566 # Title text 2 (Chromium issue 123).
567 # (author2@chromium.org)
569 # Title text 3 (Chromium issue 321).
570 # (author3@chromium.org)
572 # Title text 4 (Chromium issue 456).
573 # (author4@chromium.org)
577 self.assertEquals(expected_cl, actual_cl)
579 def testEditChangeLog(self):
580 TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile()
581 TextToFile(" New \n\tLines \n", TEST_CONFIG[CHANGELOG_ENTRY_FILE])
582 os.environ["EDITOR"] = "vi"
584 self.ExpectReadline([
585 RL(""), # Open editor.
588 self.RunStep(PushToTrunk, EditChangeLog)
590 self.assertEquals("New\n Lines",
591 FileToText(TEST_CONFIG[CHANGELOG_ENTRY_FILE]))
593 def testIncrementVersion(self):
594 TEST_CONFIG[VERSION_FILE] = self.MakeEmptyTempFile()
595 self.WriteFakeVersionFile()
596 self._state["last_push_trunk"] = "hash1"
599 Git("checkout -f hash1 -- %s" % TEST_CONFIG[VERSION_FILE], "")
602 self.ExpectReadline([
603 RL("Y"), # Increment build number.
606 self.RunStep(PushToTrunk, IncrementVersion)
608 self.assertEquals("3", self._state["new_major"])
609 self.assertEquals("22", self._state["new_minor"])
610 self.assertEquals("5", self._state["new_build"])
611 self.assertEquals("0", self._state["new_patch"])
613 def _TestSquashCommits(self, change_log, expected_msg):
614 TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile()
615 with open(TEST_CONFIG[CHANGELOG_ENTRY_FILE], "w") as f:
619 Git("diff svn/trunk hash1", "patch content"),
620 Git("svn find-rev hash1", "123455\n"),
623 self._state["push_hash"] = "hash1"
624 self._state["date"] = "1999-11-11"
626 self.RunStep(PushToTrunk, SquashCommits)
627 self.assertEquals(FileToText(TEST_CONFIG[COMMITMSG_FILE]), expected_msg)
629 patch = FileToText(TEST_CONFIG[ PATCH_FILE])
630 self.assertTrue(re.search(r"patch content", patch))
632 def testSquashCommitsUnformatted(self):
633 change_log = """1999-11-11: Version 3.22.5
638 Performance and stability improvements on all platforms.\n"""
639 commit_msg = """Version 3.22.5 (based on bleeding_edge revision r123455)
641 Log text 1. Chromium issue 12345
643 Performance and stability improvements on all platforms."""
644 self._TestSquashCommits(change_log, commit_msg)
646 def testSquashCommitsFormatted(self):
647 change_log = """1999-11-11: Version 3.22.5
649 Long commit message that fills more than 80 characters (Chromium issue
652 Performance and stability improvements on all platforms.\n"""
653 commit_msg = """Version 3.22.5 (based on bleeding_edge revision r123455)
655 Long commit message that fills more than 80 characters (Chromium issue 12345).
657 Performance and stability improvements on all platforms."""
658 self._TestSquashCommits(change_log, commit_msg)
660 def testSquashCommitsQuotationMarks(self):
661 change_log = """Line with "quotation marks".\n"""
662 commit_msg = """Line with "quotation marks"."""
663 self._TestSquashCommits(change_log, commit_msg)
665 def _PushToTrunk(self, force=False, manual=False):
666 TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile()
668 # The version file on bleeding edge has build level 5, while the version
669 # file from trunk has build level 4.
670 TEST_CONFIG[VERSION_FILE] = self.MakeEmptyTempFile()
671 self.WriteFakeVersionFile(build=5)
673 TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile()
674 TEST_CONFIG[CHANGELOG_FILE] = self.MakeEmptyTempFile()
675 bleeding_edge_change_log = "2014-03-17: Sentinel\n"
676 TextToFile(bleeding_edge_change_log, TEST_CONFIG[CHANGELOG_FILE])
677 os.environ["EDITOR"] = "vi"
679 def ResetChangeLog():
680 """On 'git co -b new_branch svn/trunk', and 'git checkout -- ChangeLog',
681 the ChangLog will be reset to its content on trunk."""
682 trunk_change_log = """1999-04-05: Version 3.22.4
684 Performance and stability improvements on all platforms.\n"""
685 TextToFile(trunk_change_log, TEST_CONFIG[CHANGELOG_FILE])
689 self.WriteFakeVersionFile()
691 def CheckSVNCommit():
692 commit = FileToText(TEST_CONFIG[COMMITMSG_FILE])
694 """Version 3.22.5 (based on bleeding_edge revision r123455)
696 Log text 1 (issue 321).
698 Performance and stability improvements on all platforms.""", commit)
699 version = FileToText(TEST_CONFIG[VERSION_FILE])
700 self.assertTrue(re.search(r"#define MINOR_VERSION\s+22", version))
701 self.assertTrue(re.search(r"#define BUILD_NUMBER\s+5", version))
702 self.assertFalse(re.search(r"#define BUILD_NUMBER\s+6", version))
703 self.assertTrue(re.search(r"#define PATCH_LEVEL\s+0", version))
704 self.assertTrue(re.search(r"#define IS_CANDIDATE_VERSION\s+0", version))
706 # Check that the change log on the trunk branch got correctly modified.
707 change_log = FileToText(TEST_CONFIG[CHANGELOG_FILE])
709 """1999-07-31: Version 3.22.5
711 Log text 1 (issue 321).
713 Performance and stability improvements on all platforms.
716 1999-04-05: Version 3.22.4
718 Performance and stability improvements on all platforms.\n""",
721 force_flag = " -f" if not manual else ""
723 Git("status -s -uno", ""),
724 Git("status -s -b -uno", "## some_branch\n"),
725 Git("svn fetch", ""),
726 Git("branch", " branch1\n* branch2\n"),
727 Git("branch", " branch1\n* branch2\n"),
728 Git("checkout -b %s svn/bleeding_edge" % TEST_CONFIG[BRANCHNAME], ""),
729 Git("svn find-rev r123455", "push_hash\n"),
730 Git(("log -1 --format=%H --grep="
731 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\" "
732 "svn/trunk"), "hash2\n"),
733 Git("log -1 hash2", "Log message\n"),
734 Git("log -1 --format=%s hash2",
735 "Version 3.4.5 (based on bleeding_edge revision r1234)\n"),
736 Git("svn find-rev r1234", "hash3\n"),
737 Git("checkout -f hash2 -- %s" % TEST_CONFIG[VERSION_FILE], "",
738 cb=self.WriteFakeVersionFile),
739 Git("log --format=%H hash3..push_hash", "rev1\n"),
740 Git("log -1 --format=%s rev1", "Log text 1.\n"),
741 Git("log -1 --format=%B rev1", "Text\nLOG=YES\nBUG=v8:321\nText\n"),
742 Git("log -1 --format=%an rev1", "author1@chromium.org\n"),
743 Git("svn fetch", "fetch result\n"),
744 Git("checkout -f svn/bleeding_edge", ""),
745 Git("diff svn/trunk push_hash", "patch content\n"),
746 Git("svn find-rev push_hash", "123455\n"),
747 Git("checkout -b %s svn/trunk" % TEST_CONFIG[TRUNKBRANCH], "",
749 Git("apply --index --reject \"%s\"" % TEST_CONFIG[PATCH_FILE], ""),
750 Git("checkout -f svn/trunk -- %s" % TEST_CONFIG[CHANGELOG_FILE], "",
752 Git("checkout -f svn/trunk -- %s" % TEST_CONFIG[VERSION_FILE], "",
753 cb=self.WriteFakeVersionFile),
754 Git("commit -aF \"%s\"" % TEST_CONFIG[COMMITMSG_FILE], "",
756 Git("svn dcommit 2>&1", "Some output\nCommitted r123456\nSome output\n"),
757 Git("svn tag 3.22.5 -m \"Tagging version 3.22.5\"", ""),
758 Git("checkout -f some_branch", ""),
759 Git("branch -D %s" % TEST_CONFIG[BRANCHNAME], ""),
760 Git("branch -D %s" % TEST_CONFIG[TRUNKBRANCH], ""),
763 # Expected keyboard input in manual mode:
765 self.ExpectReadline([
766 RL("Y"), # Confirm last push.
767 RL(""), # Open editor.
768 RL("Y"), # Increment build number.
769 RL("Y"), # Sanity check.
772 # Expected keyboard input in semi-automatic mode and forced mode:
774 self.ExpectReadline([])
776 args = ["-a", "author@chromium.org", "--revision", "123455"]
777 if force: args.append("-f")
778 if manual: args.append("-m")
779 else: args += ["-r", "reviewer@chromium.org"]
780 PushToTrunk(TEST_CONFIG, self).Run(args)
782 cl = FileToText(TEST_CONFIG[CHANGELOG_FILE])
783 self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl))
784 self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl))
785 self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl))
787 # Note: The version file is on build number 5 again in the end of this test
788 # since the git command that merges to the bleeding edge branch is mocked
791 def testPushToTrunkManual(self):
792 self._PushToTrunk(manual=True)
794 def testPushToTrunkSemiAutomatic(self):
797 def testPushToTrunkForced(self):
798 self._PushToTrunk(force=True)
800 def _ChromiumRoll(self, force=False, manual=False):
801 googlers_mapping_py = "%s-mapping.py" % TEST_CONFIG[PERSISTFILE_BASENAME]
802 with open(googlers_mapping_py, "w") as f:
804 def list_to_dict(entries):
805 return {"g_name@google.com": "c_name@chromium.org"}
809 TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile()
810 if not os.path.exists(TEST_CONFIG[CHROMIUM]):
811 os.makedirs(TEST_CONFIG[CHROMIUM])
812 TextToFile("Some line\n \"v8_revision\": \"123444\",\n some line",
813 TEST_CONFIG[DEPS_FILE])
815 os.environ["EDITOR"] = "vi"
816 force_flag = " -f" if not manual else ""
818 Git("status -s -uno", ""),
819 Git("status -s -b -uno", "## some_branch\n"),
820 Git("svn fetch", ""),
821 Git(("log -1 --format=%H --grep="
822 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\" "
823 "svn/trunk"), "push_hash\n"),
824 Git("svn find-rev push_hash", "123455\n"),
825 Git("log -1 --format=%s push_hash",
826 "Version 3.22.5 (based on bleeding_edge revision r123454)\n"),
827 Git("status -s -uno", ""),
828 Git("checkout -f master", ""),
830 Git("checkout -b v8-roll-123455", ""),
831 Git(("commit -am \"Update V8 to version 3.22.5 "
832 "(based on bleeding_edge revision r123454).\n\n"
833 "Please reply to the V8 sheriff c_name@chromium.org in "
834 "case of problems.\n\nTBR=c_name@chromium.org\""),
836 Git(("cl upload --send-mail --email \"author@chromium.org\"%s"
841 URL("https://chromium-build.appspot.com/p/chromium/sheriff_v8.js",
842 "document.write('g_name')"),
845 # Expected keyboard input in manual mode:
847 self.ExpectReadline([
848 RL("c_name@chromium.org"), # Chromium reviewer.
851 # Expected keyboard input in semi-automatic mode and forced mode:
853 self.ExpectReadline([])
855 args = ["-a", "author@chromium.org", "-c", TEST_CONFIG[CHROMIUM],
856 "--sheriff", "--googlers-mapping", googlers_mapping_py]
857 if force: args.append("-f")
858 if manual: args.append("-m")
859 else: args += ["-r", "reviewer@chromium.org"]
860 ChromiumRoll(TEST_CONFIG, self).Run(args)
862 deps = FileToText(TEST_CONFIG[DEPS_FILE])
863 self.assertTrue(re.search("\"v8_revision\": \"123455\"", deps))
865 def testChromiumRollManual(self):
866 self._ChromiumRoll(manual=True)
868 def testChromiumRollSemiAutomatic(self):
871 def testChromiumRollForced(self):
872 self._ChromiumRoll(force=True)
874 def testCheckLastPushRecently(self):
876 Git(("log -1 --format=%H --grep="
877 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\" "
878 "svn/trunk"), "hash2\n"),
879 Git("log -1 --format=%s hash2",
880 "Version 3.4.5 (based on bleeding_edge revision r99)\n"),
883 self._state["lkgr"] = "101"
885 self.assertRaises(Exception, lambda: self.RunStep(auto_push.AutoPush,
889 def testAutoPush(self):
890 TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile()
891 TEST_CONFIG[SETTINGS_LOCATION] = "~/.doesnotexist"
894 URL("https://v8-status.appspot.com/current?format=json",
895 "{\"message\": \"Tree is throttled\"}"),
896 URL("https://v8-status.appspot.com/lkgr", Exception("Network problem")),
897 URL("https://v8-status.appspot.com/lkgr", "100"),
901 Git("status -s -uno", ""),
902 Git("status -s -b -uno", "## some_branch\n"),
903 Git("svn fetch", ""),
904 Git(("log -1 --format=%H --grep=\""
905 "^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\""
906 " svn/trunk"), "push_hash\n"),
907 Git("log -1 --format=%s push_hash",
908 "Version 3.4.5 (based on bleeding_edge revision r79)\n"),
911 auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS + ["--push"])
913 state = json.loads(FileToText("%s-state.json"
914 % TEST_CONFIG[PERSISTFILE_BASENAME]))
916 self.assertEquals("100", state["lkgr"])
918 def testAutoPushStoppedBySettings(self):
919 TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile()
920 TEST_CONFIG[SETTINGS_LOCATION] = self.MakeEmptyTempFile()
921 TextToFile("{\"enable_auto_push\": false}", TEST_CONFIG[SETTINGS_LOCATION])
923 self.ExpectReadURL([])
926 Git("status -s -uno", ""),
927 Git("status -s -b -uno", "## some_branch\n"),
928 Git("svn fetch", ""),
932 auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS)
933 self.assertRaises(Exception, RunAutoPush)
935 def testAutoPushStoppedByTreeStatus(self):
936 TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile()
937 TEST_CONFIG[SETTINGS_LOCATION] = "~/.doesnotexist"
940 URL("https://v8-status.appspot.com/current?format=json",
941 "{\"message\": \"Tree is throttled (no push)\"}"),
945 Git("status -s -uno", ""),
946 Git("status -s -b -uno", "## some_branch\n"),
947 Git("svn fetch", ""),
951 auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS)
952 self.assertRaises(Exception, RunAutoPush)
954 def testAutoRollExistingRoll(self):
956 URL("https://codereview.chromium.org/search",
957 "owner=author%40chromium.org&limit=30&closed=3&format=json",
958 ("{\"results\": [{\"subject\": \"different\"},"
959 "{\"subject\": \"Update V8 to Version...\"}]}")),
962 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
963 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG[CHROMIUM]])
964 self.assertEquals(1, result)
966 # Snippet from the original DEPS file.
969 "v8_revision": "123455",
973 (Var("googlecode_url") % "v8") + "/" + Var("v8_branch") + "@" +
978 def testAutoRollUpToDate(self):
980 URL("https://codereview.chromium.org/search",
981 "owner=author%40chromium.org&limit=30&closed=3&format=json",
982 ("{\"results\": [{\"subject\": \"different\"}]}")),
983 URL("http://src.chromium.org/svn/trunk/src/DEPS",
988 Git(("log -1 --format=%H --grep="
989 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\" "
990 "svn/trunk"), "push_hash\n"),
991 Git("svn find-rev push_hash", "123455\n"),
994 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
995 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG[CHROMIUM]])
996 self.assertEquals(1, result)
998 def testAutoRoll(self):
1000 URL("https://codereview.chromium.org/search",
1001 "owner=author%40chromium.org&limit=30&closed=3&format=json",
1002 ("{\"results\": [{\"subject\": \"different\"}]}")),
1003 URL("http://src.chromium.org/svn/trunk/src/DEPS",
1008 Git(("log -1 --format=%H --grep="
1009 "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\" "
1010 "svn/trunk"), "push_hash\n"),
1011 Git("svn find-rev push_hash", "123456\n"),
1014 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run(
1015 AUTO_PUSH_ARGS + ["-c", TEST_CONFIG[CHROMIUM], "--roll"])
1016 self.assertEquals(0, result)
1018 def testMergeToBranch(self):
1019 TEST_CONFIG[ALREADY_MERGING_SENTINEL_FILE] = self.MakeEmptyTempFile()
1020 TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile()
1021 TEST_CONFIG[VERSION_FILE] = self.MakeEmptyTempFile()
1022 self.WriteFakeVersionFile(build=5)
1023 os.environ["EDITOR"] = "vi"
1024 extra_patch = self.MakeEmptyTempFile()
1026 def VerifyPatch(patch):
1027 return lambda: self.assertEquals(patch,
1028 FileToText(TEST_CONFIG[TEMPORARY_PATCH_FILE]))
1030 msg = """Version 3.22.5.1 (merged r12345, r23456, r34567, r45678, r56789)
1042 BUG=123,234,345,456,567,v8:123
1046 def VerifySVNCommit():
1047 commit = FileToText(TEST_CONFIG[COMMITMSG_FILE])
1048 self.assertEquals(msg, commit)
1049 version = FileToText(TEST_CONFIG[VERSION_FILE])
1050 self.assertTrue(re.search(r"#define MINOR_VERSION\s+22", version))
1051 self.assertTrue(re.search(r"#define BUILD_NUMBER\s+5", version))
1052 self.assertTrue(re.search(r"#define PATCH_LEVEL\s+1", version))
1053 self.assertTrue(re.search(r"#define IS_CANDIDATE_VERSION\s+0", version))
1056 Git("status -s -uno", ""),
1057 Git("status -s -b -uno", "## some_branch\n"),
1058 Git("svn fetch", ""),
1059 Git("branch", " branch1\n* branch2\n"),
1060 Git("checkout -b %s svn/trunk" % TEST_CONFIG[BRANCHNAME], ""),
1061 Git("log --format=%H --grep=\"Port r12345\" --reverse svn/bleeding_edge",
1063 Git("svn find-rev hash1 svn/bleeding_edge", "45678"),
1064 Git("log -1 --format=%s hash1", "Title1"),
1065 Git("svn find-rev hash2 svn/bleeding_edge", "23456"),
1066 Git("log -1 --format=%s hash2", "Title2"),
1067 Git("log --format=%H --grep=\"Port r23456\" --reverse svn/bleeding_edge",
1069 Git("log --format=%H --grep=\"Port r34567\" --reverse svn/bleeding_edge",
1071 Git("svn find-rev hash3 svn/bleeding_edge", "56789"),
1072 Git("log -1 --format=%s hash3", "Title3"),
1073 Git("svn find-rev r12345 svn/bleeding_edge", "hash4"),
1074 # Simulate svn being down which stops the script.
1075 Git("svn find-rev r23456 svn/bleeding_edge", None),
1076 # Restart script in the failing step.
1077 Git("svn find-rev r12345 svn/bleeding_edge", "hash4"),
1078 Git("svn find-rev r23456 svn/bleeding_edge", "hash2"),
1079 Git("svn find-rev r34567 svn/bleeding_edge", "hash3"),
1080 Git("svn find-rev r45678 svn/bleeding_edge", "hash1"),
1081 Git("svn find-rev r56789 svn/bleeding_edge", "hash5"),
1082 Git("log -1 --format=%s hash4", "Title4"),
1083 Git("log -1 --format=%s hash2", "Title2"),
1084 Git("log -1 --format=%s hash3", "Title3"),
1085 Git("log -1 --format=%s hash1", "Title1"),
1086 Git("log -1 --format=%s hash5", "Revert \"Something\""),
1087 Git("log -1 hash4", "Title4\nBUG=123\nBUG=234"),
1088 Git("log -1 hash2", "Title2\n BUG = v8:123,345"),
1089 Git("log -1 hash3", "Title3\nLOG=n\nBUG=567, 456"),
1090 Git("log -1 hash1", "Title1\nBUG="),
1091 Git("log -1 hash5", "Revert \"Something\"\nBUG=none"),
1092 Git("log -1 -p hash4", "patch4"),
1093 Git("apply --index --reject \"%s\"" % TEST_CONFIG[TEMPORARY_PATCH_FILE],
1094 "", cb=VerifyPatch("patch4")),
1095 Git("log -1 -p hash2", "patch2"),
1096 Git("apply --index --reject \"%s\"" % TEST_CONFIG[TEMPORARY_PATCH_FILE],
1097 "", cb=VerifyPatch("patch2")),
1098 Git("log -1 -p hash3", "patch3"),
1099 Git("apply --index --reject \"%s\"" % TEST_CONFIG[TEMPORARY_PATCH_FILE],
1100 "", cb=VerifyPatch("patch3")),
1101 Git("log -1 -p hash1", "patch1"),
1102 Git("apply --index --reject \"%s\"" % TEST_CONFIG[TEMPORARY_PATCH_FILE],
1103 "", cb=VerifyPatch("patch1")),
1104 Git("log -1 -p hash5", "patch5\n"),
1105 Git("apply --index --reject \"%s\"" % TEST_CONFIG[TEMPORARY_PATCH_FILE],
1106 "", cb=VerifyPatch("patch5\n")),
1107 Git("apply --index --reject \"%s\"" % extra_patch, ""),
1108 Git("commit -aF \"%s\"" % TEST_CONFIG[COMMITMSG_FILE], ""),
1109 Git("cl upload --send-mail -r \"reviewer@chromium.org\"", ""),
1110 Git("checkout -f %s" % TEST_CONFIG[BRANCHNAME], ""),
1111 Git("cl presubmit", "Presubmit successfull\n"),
1112 Git("cl dcommit -f --bypass-hooks", "Closing issue\n", cb=VerifySVNCommit),
1113 Git("svn fetch", ""),
1114 Git(("log -1 --format=%%H --grep=\"%s\" svn/trunk"
1115 % msg.replace("\"", "\\\"")), "hash6"),
1116 Git("svn find-rev hash6", "1324"),
1117 Git(("copy -r 1324 https://v8.googlecode.com/svn/trunk "
1118 "https://v8.googlecode.com/svn/tags/3.22.5.1 -m "
1119 "\"Tagging version 3.22.5.1\""), ""),
1120 Git("checkout -f some_branch", ""),
1121 Git("branch -D %s" % TEST_CONFIG[BRANCHNAME], ""),
1124 self.ExpectReadline([
1125 RL("Y"), # Automatically add corresponding ports (34567, 56789)?
1126 RL("Y"), # Automatically increment patch level?
1127 RL("reviewer@chromium.org"), # V8 reviewer.
1128 RL("LGTM"), # Enter LGTM for V8 CL.
1131 # r12345 and r34567 are patches. r23456 (included) and r45678 are the MIPS
1132 # ports of r12345. r56789 is the MIPS port of r34567.
1133 args = ["-f", "-p", extra_patch, "--branch", "trunk", "12345", "23456",
1136 # The first run of the script stops because of the svn being down.
1137 self.assertRaises(GitFailedException,
1138 lambda: MergeToBranch(TEST_CONFIG, self).Run(args))
1140 # Test that state recovery after restarting the script works.
1142 MergeToBranch(TEST_CONFIG, self).Run(args)
1144 def testReleases(self):
1145 json_output = self.MakeEmptyTempFile()
1146 csv_output = self.MakeEmptyTempFile()
1147 TEST_CONFIG[VERSION_FILE] = self.MakeEmptyTempFile()
1148 self.WriteFakeVersionFile()
1150 TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile()
1151 if not os.path.exists(TEST_CONFIG[CHROMIUM]):
1152 os.makedirs(TEST_CONFIG[CHROMIUM])
1153 def WriteDEPS(revision):
1154 TextToFile("Line\n \"v8_revision\": \"%s\",\n line\n" % revision,
1155 TEST_CONFIG[DEPS_FILE])
1158 def ResetVersion(minor, build, patch=0):
1159 return lambda: self.WriteFakeVersionFile(minor=minor,
1163 def ResetDEPS(revision):
1164 return lambda: WriteDEPS(revision)
1167 Git("status -s -uno", ""),
1168 Git("status -s -b -uno", "## some_branch\n"),
1169 Git("svn fetch", ""),
1170 Git("branch", " branch1\n* branch2\n"),
1171 Git("checkout -b %s" % TEST_CONFIG[BRANCHNAME], ""),
1172 Git("branch -r", " svn/3.21\n svn/3.3\n"),
1173 Git("reset --hard svn/3.3", ""),
1174 Git("log --format=%H", "hash1\nhash2"),
1175 Git("diff --name-only hash1 hash1^", ""),
1176 Git("diff --name-only hash2 hash2^", TEST_CONFIG[VERSION_FILE]),
1177 Git("checkout -f hash2 -- %s" % TEST_CONFIG[VERSION_FILE], "",
1178 cb=ResetVersion(3, 1, 1)),
1179 Git("log -1 --format=%B hash2",
1180 "Version 3.3.1.1 (merged 12)\n\nReview URL: fake.com\n"),
1181 Git("log -1 --format=%s hash2", ""),
1182 Git("svn find-rev hash2", "234"),
1183 Git("log -1 --format=%ci hash2", "18:15"),
1184 Git("checkout -f HEAD -- %s" % TEST_CONFIG[VERSION_FILE], "",
1185 cb=ResetVersion(22, 5)),
1186 Git("reset --hard svn/3.21", ""),
1187 Git("log --format=%H", "hash3\nhash4\nhash5\n"),
1188 Git("diff --name-only hash3 hash3^", TEST_CONFIG[VERSION_FILE]),
1189 Git("checkout -f hash3 -- %s" % TEST_CONFIG[VERSION_FILE], "",
1190 cb=ResetVersion(21, 2)),
1191 Git("log -1 --format=%B hash3", ""),
1192 Git("log -1 --format=%s hash3", ""),
1193 Git("svn find-rev hash3", "123"),
1194 Git("log -1 --format=%ci hash3", "03:15"),
1195 Git("checkout -f HEAD -- %s" % TEST_CONFIG[VERSION_FILE], "",
1196 cb=ResetVersion(22, 5)),
1197 Git("reset --hard svn/trunk", ""),
1198 Git("log --format=%H", "hash6\n"),
1199 Git("diff --name-only hash6 hash6^", TEST_CONFIG[VERSION_FILE]),
1200 Git("checkout -f hash6 -- %s" % TEST_CONFIG[VERSION_FILE], "",
1201 cb=ResetVersion(22, 3)),
1202 Git("log -1 --format=%B hash6", ""),
1203 Git("log -1 --format=%s hash6", ""),
1204 Git("svn find-rev hash6", "345"),
1205 Git("log -1 --format=%ci hash6", ""),
1206 Git("checkout -f HEAD -- %s" % TEST_CONFIG[VERSION_FILE], "",
1207 cb=ResetVersion(22, 5)),
1208 Git("status -s -uno", ""),
1209 Git("checkout -f master", ""),
1211 Git("checkout -b %s" % TEST_CONFIG[BRANCHNAME], ""),
1212 Git("log --format=%H --grep=\"V8\"", "c_hash1\nc_hash2\n"),
1213 Git("diff --name-only c_hash1 c_hash1^", ""),
1214 Git("diff --name-only c_hash2 c_hash2^", TEST_CONFIG[DEPS_FILE]),
1215 Git("checkout -f c_hash2 -- %s" % TEST_CONFIG[DEPS_FILE], "",
1217 Git("svn find-rev c_hash2", "4567"),
1218 Git("checkout -f HEAD -- %s" % TEST_CONFIG[DEPS_FILE], "",
1220 Git("branch -r", " weird/123\n branch-heads/7\n"),
1221 Git("checkout -f branch-heads/7 -- %s" % TEST_CONFIG[DEPS_FILE], "",
1223 Git("checkout -f HEAD -- %s" % TEST_CONFIG[DEPS_FILE], "",
1225 Git("checkout -f master", ""),
1226 Git("branch -D %s" % TEST_CONFIG[BRANCHNAME], ""),
1227 Git("checkout -f some_branch", ""),
1228 Git("branch -D %s" % TEST_CONFIG[BRANCHNAME], ""),
1231 args = ["-c", TEST_CONFIG[CHROMIUM],
1232 "--json", json_output,
1233 "--csv", csv_output,
1234 "--max-releases", "1"]
1235 Releases(TEST_CONFIG, self).Run(args)
1237 # Check expected output.
1238 csv = ("3.22.3,trunk,345,4567,\r\n"
1239 "3.21.2,3.21,123,,\r\n"
1240 "3.3.1.1,3.3,234,,12\r\n")
1241 self.assertEquals(csv, FileToText(csv_output))
1244 {"bleeding_edge": "", "patches_merged": "", "version": "3.22.3",
1245 "chromium_revision": "4567", "branch": "trunk", "revision": "345",
1246 "review_link": "", "date": "", "chromium_branch": "7",
1247 "revision_link": "https://code.google.com/p/v8/source/detail?r=345"},
1248 {"patches_merged": "", "bleeding_edge": "", "version": "3.21.2",
1249 "chromium_revision": "", "branch": "3.21", "revision": "123",
1250 "review_link": "", "date": "03:15", "chromium_branch": "",
1251 "revision_link": "https://code.google.com/p/v8/source/detail?r=123"},
1252 {"patches_merged": "12", "bleeding_edge": "", "version": "3.3.1.1",
1253 "chromium_revision": "", "branch": "3.3", "revision": "234",
1254 "review_link": "fake.com", "date": "18:15", "chromium_branch": "",
1255 "revision_link": "https://code.google.com/p/v8/source/detail?r=234"},
1257 self.assertEquals(expected_json, json.loads(FileToText(json_output)))
1260 class SystemTest(unittest.TestCase):
1261 def testReload(self):
1262 step = MakeStep(step_class=PrepareChangeLog, number=0, state={}, config={},
1263 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER)
1265 """------------------------------------------------------------------------
1266 r17997 | machenbach@chromium.org | 2013-11-22 11:04:04 +0100 (...) | 6 lines
1268 Prepare push to trunk. Now working on version 3.23.11.
1270 R=danno@chromium.org
1272 Review URL: https://codereview.chromium.org/83173002
1274 ------------------------------------------------------------------------""")
1276 """Prepare push to trunk. Now working on version 3.23.11.
1278 R=danno@chromium.org
1280 Committed: https://code.google.com/p/v8/source/detail?r=17997""", body)