1#!/usr/bin/env python 2# Copyright 2013 the V8 project authors. All rights reserved. 3# Redistribution and use in source and binary forms, with or without 4# modification, are permitted provided that the following conditions are 5# met: 6# 7# * Redistributions of source code must retain the above copyright 8# notice, this list of conditions and the following disclaimer. 9# * Redistributions in binary form must reproduce the above 10# copyright notice, this list of conditions and the following 11# disclaimer in the documentation and/or other materials provided 12# with the distribution. 13# * Neither the name of Google Inc. nor the names of its 14# contributors may be used to endorse or promote products derived 15# from this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29import os 30import shutil 31import tempfile 32import traceback 33import unittest 34 35import auto_push 36from auto_push import LastReleaseBailout 37import auto_roll 38import common_includes 39from common_includes import * 40import create_release 41from create_release import CreateRelease 42import merge_to_branch 43from merge_to_branch import MergeToBranch 44import push_to_candidates 45from push_to_candidates import * 46import releases 47from releases import Releases 48from auto_tag import AutoTag 49import roll_merge 50from roll_merge import RollMerge 51 52TEST_CONFIG = { 53 "DEFAULT_CWD": None, 54 "BRANCHNAME": "test-prepare-push", 55 "CANDIDATESBRANCH": "test-candidates-push", 56 "PERSISTFILE_BASENAME": "/tmp/test-v8-push-to-candidates-tempfile", 57 "CHANGELOG_ENTRY_FILE": 58 "/tmp/test-v8-push-to-candidates-tempfile-changelog-entry", 59 "PATCH_FILE": "/tmp/test-v8-push-to-candidates-tempfile-patch", 60 "COMMITMSG_FILE": "/tmp/test-v8-push-to-candidates-tempfile-commitmsg", 61 "CHROMIUM": "/tmp/test-v8-push-to-candidates-tempfile-chromium", 62 "SETTINGS_LOCATION": None, 63 "ALREADY_MERGING_SENTINEL_FILE": 64 "/tmp/test-merge-to-branch-tempfile-already-merging", 65 "TEMPORARY_PATCH_FILE": "/tmp/test-merge-to-branch-tempfile-temporary-patch", 66} 67 68 69AUTO_PUSH_ARGS = [ 70 "-a", "author@chromium.org", 71 "-r", "reviewer@chromium.org", 72] 73 74 75class ToplevelTest(unittest.TestCase): 76 def testSaniniziteVersionTags(self): 77 self.assertEquals("4.8.230", SanitizeVersionTag("4.8.230")) 78 self.assertEquals("4.8.230", SanitizeVersionTag("tags/4.8.230")) 79 self.assertEquals(None, SanitizeVersionTag("candidate")) 80 81 def testNormalizeVersionTags(self): 82 input = ["4.8.230", 83 "tags/4.8.230", 84 "tags/4.8.224.1", 85 "4.8.224.1", 86 "4.8.223.1", 87 "tags/4.8.223", 88 "tags/4.8.231", 89 "candidates"] 90 expected = ["4.8.230", 91 "4.8.230", 92 "4.8.224.1", 93 "4.8.224.1", 94 "4.8.223.1", 95 "4.8.223", 96 "4.8.231", 97 ] 98 self.assertEquals(expected, NormalizeVersionTags(input)) 99 100 def testSortBranches(self): 101 S = releases.SortBranches 102 self.assertEquals(["3.1", "2.25"], S(["2.25", "3.1"])[0:2]) 103 self.assertEquals(["3.0", "2.25"], S(["2.25", "3.0", "2.24"])[0:2]) 104 self.assertEquals(["3.11", "3.2"], S(["3.11", "3.2", "2.24"])[0:2]) 105 106 def testFilterDuplicatesAndReverse(self): 107 F = releases.FilterDuplicatesAndReverse 108 self.assertEquals([], F([])) 109 self.assertEquals([["100", "10"]], F([["100", "10"]])) 110 self.assertEquals([["99", "9"], ["100", "10"]], 111 F([["100", "10"], ["99", "9"]])) 112 self.assertEquals([["98", "9"], ["100", "10"]], 113 F([["100", "10"], ["99", "9"], ["98", "9"]])) 114 self.assertEquals([["98", "9"], ["99", "10"]], 115 F([["100", "10"], ["99", "10"], ["98", "9"]])) 116 117 def testBuildRevisionRanges(self): 118 B = releases.BuildRevisionRanges 119 self.assertEquals({}, B([])) 120 self.assertEquals({"10": "100"}, B([["100", "10"]])) 121 self.assertEquals({"10": "100", "9": "99:99"}, 122 B([["100", "10"], ["99", "9"]])) 123 self.assertEquals({"10": "100", "9": "97:99"}, 124 B([["100", "10"], ["98", "9"], ["97", "9"]])) 125 self.assertEquals({"10": "100", "9": "99:99", "3": "91:98"}, 126 B([["100", "10"], ["99", "9"], ["91", "3"]])) 127 self.assertEquals({"13": "101", "12": "100:100", "9": "94:97", 128 "3": "91:93, 98:99"}, 129 B([["101", "13"], ["100", "12"], ["98", "3"], 130 ["94", "9"], ["91", "3"]])) 131 132 def testMakeComment(self): 133 self.assertEquals("# Line 1\n# Line 2\n#", 134 MakeComment(" Line 1\n Line 2\n")) 135 self.assertEquals("#Line 1\n#Line 2", 136 MakeComment("Line 1\n Line 2")) 137 138 def testStripComments(self): 139 self.assertEquals(" Line 1\n Line 3\n", 140 StripComments(" Line 1\n# Line 2\n Line 3\n#\n")) 141 self.assertEquals("\nLine 2 ### Test\n #", 142 StripComments("###\n# \n\n# Line 1\nLine 2 ### Test\n #")) 143 144 def testMakeChangeLogBodySimple(self): 145 commits = [ 146 ["Title text 1", 147 "Title text 1\n\nBUG=\n", 148 "author1@chromium.org"], 149 ["Title text 2.", 150 "Title text 2\n\nBUG=1234\n", 151 "author2@chromium.org"], 152 ] 153 self.assertEquals(" Title text 1.\n" 154 " (author1@chromium.org)\n\n" 155 " Title text 2 (Chromium issue 1234).\n" 156 " (author2@chromium.org)\n\n", 157 MakeChangeLogBody(commits)) 158 159 def testMakeChangeLogBodyEmpty(self): 160 self.assertEquals("", MakeChangeLogBody([])) 161 162 def testMakeChangeLogBodyAutoFormat(self): 163 commits = [ 164 ["Title text 1!", 165 "Title text 1\nLOG=y\nBUG=\n", 166 "author1@chromium.org"], 167 ["Title text 2", 168 "Title text 2\n\nBUG=1234\n", 169 "author2@chromium.org"], 170 ["Title text 3", 171 "Title text 3\n\nBUG=1234\nLOG = Yes\n", 172 "author3@chromium.org"], 173 ["Title text 3", 174 "Title text 4\n\nBUG=1234\nLOG=\n", 175 "author4@chromium.org"], 176 ] 177 self.assertEquals(" Title text 1.\n\n" 178 " Title text 3 (Chromium issue 1234).\n\n", 179 MakeChangeLogBody(commits, True)) 180 181 def testRegressWrongLogEntryOnTrue(self): 182 body = """ 183Check elimination: Learn from if(CompareMap(x)) on true branch. 184 185BUG= 186R=verwaest@chromium.org 187 188Committed: https://code.google.com/p/v8/source/detail?r=18210 189""" 190 self.assertEquals("", MakeChangeLogBody([["title", body, "author"]], True)) 191 192 def testMakeChangeLogBugReferenceEmpty(self): 193 self.assertEquals("", MakeChangeLogBugReference("")) 194 self.assertEquals("", MakeChangeLogBugReference("LOG=")) 195 self.assertEquals("", MakeChangeLogBugReference(" BUG =")) 196 self.assertEquals("", MakeChangeLogBugReference("BUG=none\t")) 197 198 def testMakeChangeLogBugReferenceSimple(self): 199 self.assertEquals("(issue 987654)", 200 MakeChangeLogBugReference("BUG = v8:987654")) 201 self.assertEquals("(Chromium issue 987654)", 202 MakeChangeLogBugReference("BUG=987654 ")) 203 204 def testMakeChangeLogBugReferenceFromBody(self): 205 self.assertEquals("(Chromium issue 1234567)", 206 MakeChangeLogBugReference("Title\n\nTBR=\nBUG=\n" 207 " BUG=\tchromium:1234567\t\n" 208 "R=somebody\n")) 209 210 def testMakeChangeLogBugReferenceMultiple(self): 211 # All issues should be sorted and grouped. Multiple references to the same 212 # issue should be filtered. 213 self.assertEquals("(issues 123, 234, Chromium issue 345)", 214 MakeChangeLogBugReference("Title\n\n" 215 "BUG=v8:234\n" 216 " BUG\t= 345, \tv8:234,\n" 217 "BUG=v8:123\n" 218 "R=somebody\n")) 219 self.assertEquals("(Chromium issues 123, 234)", 220 MakeChangeLogBugReference("Title\n\n" 221 "BUG=234,,chromium:123 \n" 222 "R=somebody\n")) 223 self.assertEquals("(Chromium issues 123, 234)", 224 MakeChangeLogBugReference("Title\n\n" 225 "BUG=chromium:234, , 123\n" 226 "R=somebody\n")) 227 self.assertEquals("(issues 345, 456)", 228 MakeChangeLogBugReference("Title\n\n" 229 "\t\tBUG=v8:345,v8:456\n" 230 "R=somebody\n")) 231 self.assertEquals("(issue 123, Chromium issues 345, 456)", 232 MakeChangeLogBugReference("Title\n\n" 233 "BUG=chromium:456\n" 234 "BUG = none\n" 235 "R=somebody\n" 236 "BUG=456,v8:123, 345")) 237 238 # TODO(machenbach): These test don't make much sense when the formatting is 239 # done later. 240 def testMakeChangeLogBugReferenceLong(self): 241 # -----------------00--------10--------20--------30-------- 242 self.assertEquals("(issues 234, 1234567890, 1234567" 243 "8901234567890, Chromium issues 12345678," 244 " 123456789)", 245 MakeChangeLogBugReference("BUG=v8:234\n" 246 "BUG=v8:1234567890\n" 247 "BUG=v8:12345678901234567890\n" 248 "BUG=123456789\n" 249 "BUG=12345678\n")) 250 # -----------------00--------10--------20--------30-------- 251 self.assertEquals("(issues 234, 1234567890, 1234567" 252 "8901234567890, Chromium issues" 253 " 123456789, 1234567890)", 254 MakeChangeLogBugReference("BUG=v8:234\n" 255 "BUG=v8:12345678901234567890\n" 256 "BUG=v8:1234567890\n" 257 "BUG=123456789\n" 258 "BUG=1234567890\n")) 259 # -----------------00--------10--------20--------30-------- 260 self.assertEquals("(Chromium issues 234, 1234567890" 261 ", 12345678901234567, " 262 "1234567890123456789)", 263 MakeChangeLogBugReference("BUG=234\n" 264 "BUG=12345678901234567\n" 265 "BUG=1234567890123456789\n" 266 "BUG=1234567890\n")) 267 268 269def Cmd(*args, **kwargs): 270 """Convenience function returning a shell command test expectation.""" 271 return { 272 "name": "command", 273 "args": args, 274 "ret": args[-1], 275 "cb": kwargs.get("cb"), 276 "cwd": kwargs.get("cwd", TEST_CONFIG["DEFAULT_CWD"]), 277 } 278 279 280def RL(text, cb=None): 281 """Convenience function returning a readline test expectation.""" 282 return { 283 "name": "readline", 284 "args": [], 285 "ret": text, 286 "cb": cb, 287 "cwd": None, 288 } 289 290 291def URL(*args, **kwargs): 292 """Convenience function returning a readurl test expectation.""" 293 return { 294 "name": "readurl", 295 "args": args[:-1], 296 "ret": args[-1], 297 "cb": kwargs.get("cb"), 298 "cwd": None, 299 } 300 301 302class SimpleMock(object): 303 def __init__(self): 304 self._recipe = [] 305 self._index = -1 306 307 def Expect(self, recipe): 308 self._recipe = recipe 309 310 def Call(self, name, *args, **kwargs): # pragma: no cover 311 self._index += 1 312 try: 313 expected_call = self._recipe[self._index] 314 except IndexError: 315 raise NoRetryException("Calling %s %s" % (name, " ".join(args))) 316 317 if not isinstance(expected_call, dict): 318 raise NoRetryException("Found wrong expectation type for %s %s" % 319 (name, " ".join(args))) 320 321 if expected_call["name"] != name: 322 raise NoRetryException("Expected action: %s %s - Actual: %s" % 323 (expected_call["name"], expected_call["args"], name)) 324 325 # Check if the given working directory matches the expected one. 326 if expected_call["cwd"] != kwargs.get("cwd"): 327 raise NoRetryException("Expected cwd: %s in %s %s - Actual: %s" % 328 (expected_call["cwd"], 329 expected_call["name"], 330 expected_call["args"], 331 kwargs.get("cwd"))) 332 333 # The number of arguments in the expectation must match the actual 334 # arguments. 335 if len(args) > len(expected_call['args']): 336 raise NoRetryException("When calling %s with arguments, the " 337 "expectations must consist of at least as many arguments." % 338 name) 339 340 # Compare expected and actual arguments. 341 for (expected_arg, actual_arg) in zip(expected_call['args'], args): 342 if expected_arg != actual_arg: 343 raise NoRetryException("Expected: %s - Actual: %s" % 344 (expected_arg, actual_arg)) 345 346 # The expected call contains an optional callback for checking the context 347 # at the time of the call. 348 if expected_call['cb']: 349 try: 350 expected_call['cb']() 351 except: 352 tb = traceback.format_exc() 353 raise NoRetryException("Caught exception from callback: %s" % tb) 354 355 # If the return value is an exception, raise it instead of returning. 356 if isinstance(expected_call['ret'], Exception): 357 raise expected_call['ret'] 358 return expected_call['ret'] 359 360 def AssertFinished(self): # pragma: no cover 361 if self._index < len(self._recipe) -1: 362 raise NoRetryException("Called mock too seldom: %d vs. %d" % 363 (self._index, len(self._recipe))) 364 365 366class ScriptTest(unittest.TestCase): 367 def MakeEmptyTempFile(self): 368 handle, name = tempfile.mkstemp() 369 os.close(handle) 370 self._tmp_files.append(name) 371 return name 372 373 def MakeEmptyTempDirectory(self): 374 name = tempfile.mkdtemp() 375 self._tmp_files.append(name) 376 return name 377 378 379 def WriteFakeVersionFile(self, major=3, minor=22, build=4, patch=0): 380 version_file = os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE) 381 if not os.path.exists(os.path.dirname(version_file)): 382 os.makedirs(os.path.dirname(version_file)) 383 with open(version_file, "w") as f: 384 f.write(" // Some line...\n") 385 f.write("\n") 386 f.write("#define V8_MAJOR_VERSION %s\n" % major) 387 f.write("#define V8_MINOR_VERSION %s\n" % minor) 388 f.write("#define V8_BUILD_NUMBER %s\n" % build) 389 f.write("#define V8_PATCH_LEVEL %s\n" % patch) 390 f.write(" // Some line...\n") 391 f.write("#define V8_IS_CANDIDATE_VERSION 0\n") 392 393 def WriteFakeWatchlistsFile(self): 394 watchlists_file = os.path.join(TEST_CONFIG["DEFAULT_CWD"], WATCHLISTS_FILE) 395 if not os.path.exists(os.path.dirname(watchlists_file)): 396 os.makedirs(os.path.dirname(watchlists_file)) 397 with open(watchlists_file, "w") as f: 398 399 content = """ 400 'merges': [ 401 # Only enabled on branches created with tools/release/create_release.py 402 # 'v8-merges@googlegroups.com', 403 ], 404""" 405 f.write(content) 406 407 def MakeStep(self): 408 """Convenience wrapper.""" 409 options = ScriptsBase(TEST_CONFIG, self, self._state).MakeOptions([]) 410 return MakeStep(step_class=Step, state=self._state, 411 config=TEST_CONFIG, side_effect_handler=self, 412 options=options) 413 414 def RunStep(self, script=PushToCandidates, step_class=Step, args=None): 415 """Convenience wrapper.""" 416 args = args if args is not None else ["-m"] 417 return script(TEST_CONFIG, self, self._state).RunSteps([step_class], args) 418 419 def Call(self, fun, *args, **kwargs): 420 print "Calling %s with %s and %s" % (str(fun), str(args), str(kwargs)) 421 422 def Command(self, cmd, args="", prefix="", pipe=True, cwd=None): 423 print "%s %s" % (cmd, args) 424 print "in %s" % cwd 425 return self._mock.Call("command", cmd + " " + args, cwd=cwd) 426 427 def ReadLine(self): 428 return self._mock.Call("readline") 429 430 def ReadURL(self, url, params): 431 if params is not None: 432 return self._mock.Call("readurl", url, params) 433 else: 434 return self._mock.Call("readurl", url) 435 436 def Sleep(self, seconds): 437 pass 438 439 def GetDate(self): 440 return "1999-07-31" 441 442 def GetUTCStamp(self): 443 return "1000000" 444 445 def Expect(self, *args): 446 """Convenience wrapper.""" 447 self._mock.Expect(*args) 448 449 def setUp(self): 450 self._mock = SimpleMock() 451 self._tmp_files = [] 452 self._state = {} 453 TEST_CONFIG["DEFAULT_CWD"] = self.MakeEmptyTempDirectory() 454 455 def tearDown(self): 456 if os.path.exists(TEST_CONFIG["PERSISTFILE_BASENAME"]): 457 shutil.rmtree(TEST_CONFIG["PERSISTFILE_BASENAME"]) 458 459 # Clean up temps. Doesn't work automatically. 460 for name in self._tmp_files: 461 if os.path.isfile(name): 462 os.remove(name) 463 if os.path.isdir(name): 464 shutil.rmtree(name) 465 466 self._mock.AssertFinished() 467 468 def testGitMock(self): 469 self.Expect([Cmd("git --version", "git version 1.2.3"), 470 Cmd("git dummy", "")]) 471 self.assertEquals("git version 1.2.3", self.MakeStep().Git("--version")) 472 self.assertEquals("", self.MakeStep().Git("dummy")) 473 474 def testCommonPrepareDefault(self): 475 self.Expect([ 476 Cmd("git status -s -uno", ""), 477 Cmd("git checkout -f origin/master", ""), 478 Cmd("git fetch", ""), 479 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]), 480 RL("Y"), 481 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""), 482 ]) 483 self.MakeStep().CommonPrepare() 484 self.MakeStep().PrepareBranch() 485 486 def testCommonPrepareNoConfirm(self): 487 self.Expect([ 488 Cmd("git status -s -uno", ""), 489 Cmd("git checkout -f origin/master", ""), 490 Cmd("git fetch", ""), 491 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]), 492 RL("n"), 493 ]) 494 self.MakeStep().CommonPrepare() 495 self.assertRaises(Exception, self.MakeStep().PrepareBranch) 496 497 def testCommonPrepareDeleteBranchFailure(self): 498 self.Expect([ 499 Cmd("git status -s -uno", ""), 500 Cmd("git checkout -f origin/master", ""), 501 Cmd("git fetch", ""), 502 Cmd("git branch", " branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]), 503 RL("Y"), 504 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], None), 505 ]) 506 self.MakeStep().CommonPrepare() 507 self.assertRaises(Exception, self.MakeStep().PrepareBranch) 508 509 def testInitialEnvironmentChecks(self): 510 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git")) 511 os.environ["EDITOR"] = "vi" 512 self.Expect([ 513 Cmd("which vi", "/usr/bin/vi"), 514 ]) 515 self.MakeStep().InitialEnvironmentChecks(TEST_CONFIG["DEFAULT_CWD"]) 516 517 def testTagTimeout(self): 518 self.Expect([ 519 Cmd("git fetch", ""), 520 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""), 521 Cmd("git fetch", ""), 522 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""), 523 Cmd("git fetch", ""), 524 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""), 525 Cmd("git fetch", ""), 526 Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""), 527 ]) 528 args = ["--branch", "candidates", "ab12345"] 529 self._state["version"] = "tag_name" 530 self._state["commit_title"] = "Title" 531 self.assertRaises(Exception, 532 lambda: self.RunStep(RollMerge, TagRevision, args)) 533 534 def testReadAndPersistVersion(self): 535 self.WriteFakeVersionFile(build=5) 536 step = self.MakeStep() 537 step.ReadAndPersistVersion() 538 self.assertEquals("3", step["major"]) 539 self.assertEquals("22", step["minor"]) 540 self.assertEquals("5", step["build"]) 541 self.assertEquals("0", step["patch"]) 542 543 def testRegex(self): 544 self.assertEqual("(issue 321)", 545 re.sub(r"BUG=v8:(.*)$", r"(issue \1)", "BUG=v8:321")) 546 self.assertEqual("(Chromium issue 321)", 547 re.sub(r"BUG=(.*)$", r"(Chromium issue \1)", "BUG=321")) 548 549 cl = " too little\n\ttab\ttab\n too much\n trailing " 550 cl = MSub(r"\t", r" ", cl) 551 cl = MSub(r"^ {1,7}([^ ])", r" \1", cl) 552 cl = MSub(r"^ {9,80}([^ ])", r" \1", cl) 553 cl = MSub(r" +$", r"", cl) 554 self.assertEqual(" too little\n" 555 " tab tab\n" 556 " too much\n" 557 " trailing", cl) 558 559 self.assertEqual("//\n#define V8_BUILD_NUMBER 3\n", 560 MSub(r"(?<=#define V8_BUILD_NUMBER)(?P<space>\s+)\d*$", 561 r"\g<space>3", 562 "//\n#define V8_BUILD_NUMBER 321\n")) 563 564 def testPreparePushRevision(self): 565 # Tests the default push hash used when the --revision option is not set. 566 self.Expect([ 567 Cmd("git log -1 --format=%H HEAD", "push_hash") 568 ]) 569 570 self.RunStep(PushToCandidates, PreparePushRevision) 571 self.assertEquals("push_hash", self._state["push_hash"]) 572 573 def testPrepareChangeLog(self): 574 self.WriteFakeVersionFile() 575 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile() 576 577 self.Expect([ 578 Cmd("git log --format=%H 1234..push_hash", "rev1\nrev2\nrev3\nrev4"), 579 Cmd("git log -1 --format=%s rev1", "Title text 1"), 580 Cmd("git log -1 --format=%B rev1", "Title\n\nBUG=\nLOG=y\n"), 581 Cmd("git log -1 --format=%an rev1", "author1@chromium.org"), 582 Cmd("git log -1 --format=%s rev2", "Title text 2."), 583 Cmd("git log -1 --format=%B rev2", "Title\n\nBUG=123\nLOG= \n"), 584 Cmd("git log -1 --format=%an rev2", "author2@chromium.org"), 585 Cmd("git log -1 --format=%s rev3", "Title text 3"), 586 Cmd("git log -1 --format=%B rev3", "Title\n\nBUG=321\nLOG=true\n"), 587 Cmd("git log -1 --format=%an rev3", "author3@chromium.org"), 588 Cmd("git log -1 --format=%s rev4", "Title text 4"), 589 Cmd("git log -1 --format=%B rev4", 590 ("Title\n\nBUG=456\nLOG=Y\n\n" 591 "Review URL: https://codereview.chromium.org/9876543210\n")), 592 URL("https://codereview.chromium.org/9876543210/description", 593 "Title\n\nBUG=456\nLOG=N\n\n"), 594 Cmd("git log -1 --format=%an rev4", "author4@chromium.org"), 595 ]) 596 597 self._state["last_push_master"] = "1234" 598 self._state["push_hash"] = "push_hash" 599 self._state["version"] = "3.22.5" 600 self.RunStep(PushToCandidates, PrepareChangeLog) 601 602 actual_cl = FileToText(TEST_CONFIG["CHANGELOG_ENTRY_FILE"]) 603 604 expected_cl = """1999-07-31: Version 3.22.5 605 606 Title text 1. 607 608 Title text 3 (Chromium issue 321). 609 610 Performance and stability improvements on all platforms. 611# 612# The change log above is auto-generated. Please review if all relevant 613# commit messages from the list below are included. 614# All lines starting with # will be stripped. 615# 616# Title text 1. 617# (author1@chromium.org) 618# 619# Title text 2 (Chromium issue 123). 620# (author2@chromium.org) 621# 622# Title text 3 (Chromium issue 321). 623# (author3@chromium.org) 624# 625# Title text 4 (Chromium issue 456). 626# (author4@chromium.org) 627# 628#""" 629 630 self.assertEquals(expected_cl, actual_cl) 631 632 def testEditChangeLog(self): 633 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile() 634 TextToFile(" New \n\tLines \n", TEST_CONFIG["CHANGELOG_ENTRY_FILE"]) 635 os.environ["EDITOR"] = "vi" 636 self.Expect([ 637 RL(""), # Open editor. 638 Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], ""), 639 ]) 640 641 self.RunStep(PushToCandidates, EditChangeLog) 642 643 self.assertEquals("New\n Lines", 644 FileToText(TEST_CONFIG["CHANGELOG_ENTRY_FILE"])) 645 646 TAGS = """ 6474425.0 6480.0.0.0 6493.9.6 6503.22.4 651test_tag 652""" 653 654 # Version as tag: 3.22.4.0. Version on master: 3.22.6. 655 # Make sure that the latest version is 3.22.6.0. 656 def testIncrementVersion(self): 657 self.Expect([ 658 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), 659 Cmd("git tag", self.TAGS), 660 Cmd("git checkout -f origin/master -- include/v8-version.h", 661 "", cb=lambda: self.WriteFakeVersionFile(3, 22, 6)), 662 ]) 663 664 self.RunStep(PushToCandidates, IncrementVersion) 665 666 self.assertEquals("3", self._state["new_major"]) 667 self.assertEquals("22", self._state["new_minor"]) 668 self.assertEquals("7", self._state["new_build"]) 669 self.assertEquals("0", self._state["new_patch"]) 670 671 def _TestSquashCommits(self, change_log, expected_msg): 672 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile() 673 with open(TEST_CONFIG["CHANGELOG_ENTRY_FILE"], "w") as f: 674 f.write(change_log) 675 676 self.Expect([ 677 Cmd("git diff origin/candidates hash1", "patch content"), 678 ]) 679 680 self._state["push_hash"] = "hash1" 681 self._state["date"] = "1999-11-11" 682 683 self.RunStep(PushToCandidates, SquashCommits) 684 self.assertEquals(FileToText(TEST_CONFIG["COMMITMSG_FILE"]), expected_msg) 685 686 patch = FileToText(TEST_CONFIG["PATCH_FILE"]) 687 self.assertTrue(re.search(r"patch content", patch)) 688 689 def testSquashCommitsUnformatted(self): 690 change_log = """1999-11-11: Version 3.22.5 691 692 Log text 1. 693 Chromium issue 12345 694 695 Performance and stability improvements on all platforms.\n""" 696 commit_msg = """Version 3.22.5 (based on hash1) 697 698Log text 1. Chromium issue 12345 699 700Performance and stability improvements on all platforms.""" 701 self._TestSquashCommits(change_log, commit_msg) 702 703 def testSquashCommitsFormatted(self): 704 change_log = """1999-11-11: Version 3.22.5 705 706 Long commit message that fills more than 80 characters (Chromium issue 707 12345). 708 709 Performance and stability improvements on all platforms.\n""" 710 commit_msg = """Version 3.22.5 (based on hash1) 711 712Long commit message that fills more than 80 characters (Chromium issue 12345). 713 714Performance and stability improvements on all platforms.""" 715 self._TestSquashCommits(change_log, commit_msg) 716 717 def testSquashCommitsQuotationMarks(self): 718 change_log = """Line with "quotation marks".\n""" 719 commit_msg = """Line with "quotation marks".""" 720 self._TestSquashCommits(change_log, commit_msg) 721 722 def testBootstrapper(self): 723 work_dir = self.MakeEmptyTempDirectory() 724 class FakeScript(ScriptsBase): 725 def _Steps(self): 726 return [] 727 728 # Use the test configuration without the fake testing default work dir. 729 fake_config = dict(TEST_CONFIG) 730 del(fake_config["DEFAULT_CWD"]) 731 732 self.Expect([ 733 Cmd("fetch v8", "", cwd=work_dir), 734 ]) 735 FakeScript(fake_config, self).Run(["--work-dir", work_dir]) 736 737 def _PushToCandidates(self, force=False, manual=False): 738 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git")) 739 740 # The version file on master has build level 5, while the version 741 # file from candidates has build level 4. 742 self.WriteFakeVersionFile(build=5) 743 744 TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile() 745 master_change_log = "2014-03-17: Sentinel\n" 746 TextToFile(master_change_log, 747 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) 748 os.environ["EDITOR"] = "vi" 749 750 commit_msg_squashed = """Version 3.22.5 (squashed - based on push_hash) 751 752Log text 1 (issue 321). 753 754Performance and stability improvements on all platforms.""" 755 756 commit_msg = """Version 3.22.5 (based on push_hash) 757 758Log text 1 (issue 321). 759 760Performance and stability improvements on all platforms.""" 761 762 def ResetChangeLog(): 763 """On 'git co -b new_branch origin/candidates', 764 and 'git checkout -- ChangeLog', 765 the ChangLog will be reset to its content on candidates.""" 766 candidates_change_log = """1999-04-05: Version 3.22.4 767 768 Performance and stability improvements on all platforms.\n""" 769 TextToFile(candidates_change_log, 770 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) 771 772 def ResetToCandidates(): 773 ResetChangeLog() 774 self.WriteFakeVersionFile() 775 776 def CheckVersionCommit(): 777 commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"]) 778 self.assertEquals(commit_msg, commit) 779 version = FileToText( 780 os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE)) 781 self.assertTrue(re.search(r"#define V8_MINOR_VERSION\s+22", version)) 782 self.assertTrue(re.search(r"#define V8_BUILD_NUMBER\s+5", version)) 783 self.assertFalse(re.search(r"#define V8_BUILD_NUMBER\s+6", version)) 784 self.assertTrue(re.search(r"#define V8_PATCH_LEVEL\s+0", version)) 785 self.assertTrue( 786 re.search(r"#define V8_IS_CANDIDATE_VERSION\s+0", version)) 787 788 # Check that the change log on the candidates branch got correctly 789 # modified. 790 change_log = FileToText( 791 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) 792 self.assertEquals( 793"""1999-07-31: Version 3.22.5 794 795 Log text 1 (issue 321). 796 797 Performance and stability improvements on all platforms. 798 799 8001999-04-05: Version 3.22.4 801 802 Performance and stability improvements on all platforms.\n""", 803 change_log) 804 805 force_flag = " -f" if not manual else "" 806 expectations = [] 807 if not force: 808 expectations.append(Cmd("which vi", "/usr/bin/vi")) 809 expectations += [ 810 Cmd("git status -s -uno", ""), 811 Cmd("git checkout -f origin/master", ""), 812 Cmd("git fetch", ""), 813 Cmd("git branch", " branch1\n* branch2\n"), 814 Cmd("git branch", " branch1\n* branch2\n"), 815 Cmd(("git new-branch %s --upstream origin/master" % 816 TEST_CONFIG["BRANCHNAME"]), ""), 817 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), 818 Cmd("git tag", self.TAGS), 819 Cmd("git checkout -f origin/master -- include/v8-version.h", 820 "", cb=self.WriteFakeVersionFile), 821 Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"), 822 Cmd("git log -1 --format=%s release_hash", 823 "Version 3.22.4 (based on abc3)\n"), 824 Cmd("git log --format=%H abc3..push_hash", "rev1\n"), 825 Cmd("git log -1 --format=%s rev1", "Log text 1.\n"), 826 Cmd("git log -1 --format=%B rev1", "Text\nLOG=YES\nBUG=v8:321\nText\n"), 827 Cmd("git log -1 --format=%an rev1", "author1@chromium.org\n"), 828 ] 829 if manual: 830 expectations.append(RL("")) # Open editor. 831 if not force: 832 expectations.append( 833 Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], "")) 834 expectations += [ 835 Cmd("git fetch", ""), 836 Cmd("git checkout -f origin/master", ""), 837 Cmd("git diff origin/candidates push_hash", "patch content\n"), 838 Cmd(("git new-branch %s --upstream origin/candidates" % 839 TEST_CONFIG["CANDIDATESBRANCH"]), "", cb=ResetToCandidates), 840 Cmd("git apply --index --reject \"%s\"" % TEST_CONFIG["PATCH_FILE"], ""), 841 Cmd("git checkout -f origin/candidates -- ChangeLog", "", 842 cb=ResetChangeLog), 843 Cmd("git checkout -f origin/candidates -- include/v8-version.h", "", 844 cb=self.WriteFakeVersionFile), 845 Cmd("git commit -am \"%s\"" % commit_msg_squashed, ""), 846 ] 847 if manual: 848 expectations.append(RL("Y")) # Sanity check. 849 expectations += [ 850 Cmd("git cl land -f --bypass-hooks", ""), 851 Cmd("git checkout -f master", ""), 852 Cmd("git fetch", ""), 853 Cmd("git branch -D %s" % TEST_CONFIG["CANDIDATESBRANCH"], ""), 854 Cmd(("git new-branch %s --upstream origin/candidates" % 855 TEST_CONFIG["CANDIDATESBRANCH"]), "", cb=ResetToCandidates), 856 Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "", 857 cb=CheckVersionCommit), 858 Cmd("git cl land -f --bypass-hooks", ""), 859 Cmd("git fetch", ""), 860 Cmd("git log -1 --format=%H --grep=" 861 "\"Version 3.22.5 (based on push_hash)\"" 862 " origin/candidates", "hsh_to_tag"), 863 Cmd("git tag 3.22.5 hsh_to_tag", ""), 864 Cmd("git push origin 3.22.5", ""), 865 Cmd("git checkout -f origin/master", ""), 866 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""), 867 Cmd("git branch -D %s" % TEST_CONFIG["CANDIDATESBRANCH"], ""), 868 ] 869 self.Expect(expectations) 870 871 args = ["-a", "author@chromium.org", "--revision", "push_hash"] 872 if force: args.append("-f") 873 if manual: args.append("-m") 874 else: args += ["-r", "reviewer@chromium.org"] 875 PushToCandidates(TEST_CONFIG, self).Run(args) 876 877 cl = FileToText(os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) 878 self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl)) 879 self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl)) 880 self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl)) 881 882 # Note: The version file is on build number 5 again in the end of this test 883 # since the git command that merges to master is mocked out. 884 885 def testPushToCandidatesManual(self): 886 self._PushToCandidates(manual=True) 887 888 def testPushToCandidatesSemiAutomatic(self): 889 self._PushToCandidates() 890 891 def testPushToCandidatesForced(self): 892 self._PushToCandidates(force=True) 893 894 def testCreateRelease(self): 895 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git")) 896 897 # The version file on master has build level 5. 898 self.WriteFakeVersionFile(build=5) 899 900 master_change_log = "2014-03-17: Sentinel\n" 901 TextToFile(master_change_log, 902 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) 903 904 commit_msg = """Version 3.22.5 905 906Log text 1 (issue 321). 907 908Performance and stability improvements on all platforms.""" 909 910 def ResetChangeLog(): 911 last_change_log = """1999-04-05: Version 3.22.4 912 913 Performance and stability improvements on all platforms.\n""" 914 TextToFile(last_change_log, 915 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) 916 917 918 def CheckVersionCommit(): 919 commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"]) 920 self.assertEquals(commit_msg, commit) 921 version = FileToText( 922 os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE)) 923 self.assertTrue(re.search(r"#define V8_MINOR_VERSION\s+22", version)) 924 self.assertTrue(re.search(r"#define V8_BUILD_NUMBER\s+5", version)) 925 self.assertFalse(re.search(r"#define V8_BUILD_NUMBER\s+6", version)) 926 self.assertTrue(re.search(r"#define V8_PATCH_LEVEL\s+0", version)) 927 self.assertTrue( 928 re.search(r"#define V8_IS_CANDIDATE_VERSION\s+0", version)) 929 930 # Check that the change log on the candidates branch got correctly 931 # modified. 932 change_log = FileToText( 933 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) 934 self.assertEquals( 935"""1999-07-31: Version 3.22.5 936 937 Log text 1 (issue 321). 938 939 Performance and stability improvements on all platforms. 940 941 9421999-04-05: Version 3.22.4 943 944 Performance and stability improvements on all platforms.\n""", 945 change_log) 946 947 expectations = [ 948 Cmd("git fetch origin +refs/heads/*:refs/heads/*", ""), 949 Cmd("git checkout -f origin/master", ""), 950 Cmd("git branch", ""), 951 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), 952 Cmd("git tag", self.TAGS), 953 Cmd("git checkout -f origin/master -- include/v8-version.h", 954 "", cb=self.WriteFakeVersionFile), 955 Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"), 956 Cmd("git log -1 --format=%s release_hash", "Version 3.22.4\n"), 957 Cmd("git log -1 --format=%H release_hash^", "abc3\n"), 958 Cmd("git log --format=%H abc3..push_hash", "rev1\n"), 959 Cmd("git log -1 --format=%s rev1", "Log text 1.\n"), 960 Cmd("git log -1 --format=%B rev1", "Text\nLOG=YES\nBUG=v8:321\nText\n"), 961 Cmd("git log -1 --format=%an rev1", "author1@chromium.org\n"), 962 Cmd("git push origin push_hash:refs/heads/3.22.5", ""), 963 Cmd("git reset --hard origin/master", ""), 964 Cmd("git new-branch work-branch --upstream origin/3.22.5", ""), 965 Cmd("git checkout -f 3.22.4 -- ChangeLog", "", cb=ResetChangeLog), 966 Cmd("git checkout -f 3.22.4 -- include/v8-version.h", "", 967 cb=self.WriteFakeVersionFile), 968 Cmd("git checkout -f 3.22.4 -- WATCHLISTS", "", 969 cb=self.WriteFakeWatchlistsFile), 970 Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "", 971 cb=CheckVersionCommit), 972 Cmd("git cl land --bypass-hooks -f", ""), 973 Cmd("git fetch", ""), 974 Cmd("git log -1 --format=%H --grep=" 975 "\"Version 3.22.5\" origin/3.22.5", "hsh_to_tag"), 976 Cmd("git tag 3.22.5 hsh_to_tag", ""), 977 Cmd("git push origin 3.22.5", ""), 978 Cmd("git checkout -f origin/master", ""), 979 Cmd("git branch", "* master\n work-branch\n"), 980 Cmd("git branch -D work-branch", ""), 981 Cmd("git gc", ""), 982 ] 983 self.Expect(expectations) 984 985 args = ["-a", "author@chromium.org", 986 "-r", "reviewer@chromium.org", 987 "--revision", "push_hash"] 988 CreateRelease(TEST_CONFIG, self).Run(args) 989 990 cl = FileToText(os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE)) 991 self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl)) 992 self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl)) 993 self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl)) 994 995 # Note: The version file is on build number 5 again in the end of this test 996 # since the git command that merges to master is mocked out. 997 998 # Check for correct content of the WATCHLISTS file 999 1000 watchlists_content = FileToText(os.path.join(TEST_CONFIG["DEFAULT_CWD"], 1001 WATCHLISTS_FILE)) 1002 expected_watchlists_content = """ 1003 'merges': [ 1004 # Only enabled on branches created with tools/release/create_release.py 1005 'v8-merges@googlegroups.com', 1006 ], 1007""" 1008 self.assertEqual(watchlists_content, expected_watchlists_content) 1009 1010 C_V8_22624_LOG = """V8 CL. 1011 1012git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22624 123 1013 1014""" 1015 1016 C_V8_123455_LOG = """V8 CL. 1017 1018git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@123455 123 1019 1020""" 1021 1022 C_V8_123456_LOG = """V8 CL. 1023 1024git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@123456 123 1025 1026""" 1027 1028 ROLL_COMMIT_MSG = """Update V8 to version 3.22.4. 1029 1030Summary of changes available at: 1031https://chromium.googlesource.com/v8/v8/+log/last_rol..roll_hsh 1032 1033Please follow these instructions for assigning/CC'ing issues: 1034https://github.com/v8/v8/wiki/Triaging%20issues 1035 1036Please close rolling in case of a roll revert: 1037https://v8-roll.appspot.com/ 1038This only works with a Google account. 1039 1040CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel 1041 1042TBR=reviewer@chromium.org""" 1043 1044 # Snippet from the original DEPS file. 1045 FAKE_DEPS = """ 1046vars = { 1047 "v8_revision": "last_roll_hsh", 1048} 1049deps = { 1050 "src/v8": 1051 (Var("googlecode_url") % "v8") + "/" + Var("v8_branch") + "@" + 1052 Var("v8_revision"), 1053} 1054""" 1055 1056 def testChromiumRollUpToDate(self): 1057 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory() 1058 json_output_file = os.path.join(TEST_CONFIG["CHROMIUM"], "out.json") 1059 TextToFile(self.FAKE_DEPS, os.path.join(TEST_CONFIG["CHROMIUM"], "DEPS")) 1060 self.Expect([ 1061 Cmd("git fetch origin", ""), 1062 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), 1063 Cmd("git describe --tags last_roll_hsh", "3.22.4"), 1064 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), 1065 Cmd("git rev-list --max-age=395200 --tags", 1066 "bad_tag\nroll_hsh\nhash_123"), 1067 Cmd("git describe --tags bad_tag", ""), 1068 Cmd("git describe --tags roll_hsh", "3.22.4"), 1069 Cmd("git describe --tags hash_123", "3.22.3"), 1070 Cmd("git describe --tags roll_hsh", "3.22.4"), 1071 Cmd("git describe --tags hash_123", "3.22.3"), 1072 ]) 1073 1074 result = auto_roll.AutoRoll(TEST_CONFIG, self).Run( 1075 AUTO_PUSH_ARGS + [ 1076 "-c", TEST_CONFIG["CHROMIUM"], 1077 "--json-output", json_output_file]) 1078 self.assertEquals(0, result) 1079 json_output = json.loads(FileToText(json_output_file)) 1080 self.assertEquals("up_to_date", json_output["monitoring_state"]) 1081 1082 1083 def testChromiumRoll(self): 1084 # Setup fake directory structures. 1085 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory() 1086 json_output_file = os.path.join(TEST_CONFIG["CHROMIUM"], "out.json") 1087 TextToFile(self.FAKE_DEPS, os.path.join(TEST_CONFIG["CHROMIUM"], "DEPS")) 1088 TextToFile("", os.path.join(TEST_CONFIG["CHROMIUM"], ".git")) 1089 chrome_dir = TEST_CONFIG["CHROMIUM"] 1090 os.makedirs(os.path.join(chrome_dir, "v8")) 1091 1092 def WriteDeps(): 1093 TextToFile("Some line\n \"v8_revision\": \"22624\",\n some line", 1094 os.path.join(chrome_dir, "DEPS")) 1095 1096 expectations = [ 1097 Cmd("git fetch origin", ""), 1098 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), 1099 Cmd("git describe --tags last_roll_hsh", "3.22.3.1"), 1100 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), 1101 Cmd("git rev-list --max-age=395200 --tags", 1102 "bad_tag\nroll_hsh\nhash_123"), 1103 Cmd("git describe --tags bad_tag", ""), 1104 Cmd("git describe --tags roll_hsh", "3.22.4"), 1105 Cmd("git describe --tags hash_123", "3.22.3"), 1106 Cmd("git describe --tags roll_hsh", "3.22.4"), 1107 Cmd("git log -1 --format=%s roll_hsh", "Version 3.22.4\n"), 1108 Cmd("git describe --tags roll_hsh", "3.22.4"), 1109 Cmd("git describe --tags last_roll_hsh", "3.22.2.1"), 1110 Cmd("git status -s -uno", "", cwd=chrome_dir), 1111 Cmd("git checkout -f master", "", cwd=chrome_dir), 1112 Cmd("git branch", "", cwd=chrome_dir), 1113 Cmd("git pull", "", cwd=chrome_dir), 1114 Cmd("git fetch origin", ""), 1115 Cmd("git new-branch work-branch", "", cwd=chrome_dir), 1116 Cmd("roll-dep-svn v8 roll_hsh", "rolled", cb=WriteDeps, cwd=chrome_dir), 1117 Cmd(("git commit -am \"%s\" " 1118 "--author \"author@chromium.org <author@chromium.org>\"" % 1119 self.ROLL_COMMIT_MSG), 1120 "", cwd=chrome_dir), 1121 Cmd("git cl upload --send-mail --email \"author@chromium.org\" -f " 1122 "--use-commit-queue --bypass-hooks", "", cwd=chrome_dir), 1123 Cmd("git checkout -f master", "", cwd=chrome_dir), 1124 Cmd("git branch -D work-branch", "", cwd=chrome_dir), 1125 ] 1126 self.Expect(expectations) 1127 1128 args = ["-a", "author@chromium.org", "-c", chrome_dir, 1129 "-r", "reviewer@chromium.org", "--json-output", json_output_file] 1130 auto_roll.AutoRoll(TEST_CONFIG, self).Run(args) 1131 1132 deps = FileToText(os.path.join(chrome_dir, "DEPS")) 1133 self.assertTrue(re.search("\"v8_revision\": \"22624\"", deps)) 1134 1135 json_output = json.loads(FileToText(json_output_file)) 1136 self.assertEquals("success", json_output["monitoring_state"]) 1137 1138 def testCheckLastPushRecently(self): 1139 self.Expect([ 1140 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), 1141 Cmd("git tag", self.TAGS), 1142 Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"), 1143 Cmd("git log -1 --format=%s release_hash", 1144 "Version 3.22.4 (based on abc3)\n"), 1145 Cmd("git log --format=%H abc3..abc123", "\n"), 1146 ]) 1147 1148 self._state["candidate"] = "abc123" 1149 self.assertEquals(0, self.RunStep( 1150 auto_push.AutoPush, LastReleaseBailout, AUTO_PUSH_ARGS)) 1151 1152 def testAutoPush(self): 1153 self.Expect([ 1154 Cmd("git fetch", ""), 1155 Cmd("git fetch origin +refs/heads/lkgr:refs/heads/lkgr", ""), 1156 Cmd("git show-ref -s refs/heads/lkgr", "abc123\n"), 1157 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), 1158 Cmd("git tag", self.TAGS), 1159 Cmd("git log -1 --format=%H 3.22.4", "release_hash\n"), 1160 Cmd("git log -1 --format=%s release_hash", 1161 "Version 3.22.4 (based on abc3)\n"), 1162 Cmd("git log --format=%H abc3..abc123", "some_stuff\n"), 1163 ]) 1164 1165 auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS + ["--push"]) 1166 1167 state = json.loads(FileToText("%s-state.json" 1168 % TEST_CONFIG["PERSISTFILE_BASENAME"])) 1169 1170 self.assertEquals("abc123", state["candidate"]) 1171 1172 def testRollMerge(self): 1173 TEST_CONFIG["ALREADY_MERGING_SENTINEL_FILE"] = self.MakeEmptyTempFile() 1174 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git")) 1175 self.WriteFakeVersionFile(build=5) 1176 os.environ["EDITOR"] = "vi" 1177 extra_patch = self.MakeEmptyTempFile() 1178 1179 def VerifyPatch(patch): 1180 return lambda: self.assertEquals(patch, 1181 FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"])) 1182 1183 msg = """Version 3.22.5.1 (cherry-pick) 1184 1185Merged ab12345 1186Merged ab23456 1187Merged ab34567 1188Merged ab45678 1189Merged ab56789 1190 1191Title4 1192 1193Title2 1194 1195Title3 1196 1197Title1 1198 1199Revert "Something" 1200 1201BUG=123,234,345,456,567,v8:123 1202LOG=N 1203""" 1204 1205 def VerifyLand(): 1206 commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"]) 1207 self.assertEquals(msg, commit) 1208 version = FileToText( 1209 os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE)) 1210 self.assertTrue(re.search(r"#define V8_MINOR_VERSION\s+22", version)) 1211 self.assertTrue(re.search(r"#define V8_BUILD_NUMBER\s+5", version)) 1212 self.assertTrue(re.search(r"#define V8_PATCH_LEVEL\s+1", version)) 1213 self.assertTrue( 1214 re.search(r"#define V8_IS_CANDIDATE_VERSION\s+0", version)) 1215 1216 self.Expect([ 1217 Cmd("git status -s -uno", ""), 1218 Cmd("git checkout -f origin/master", ""), 1219 Cmd("git fetch", ""), 1220 Cmd("git branch", " branch1\n* branch2\n"), 1221 Cmd("git new-branch %s --upstream refs/remotes/origin/candidates" % 1222 TEST_CONFIG["BRANCHNAME"], ""), 1223 Cmd(("git log --format=%H --grep=\"Port ab12345\" " 1224 "--reverse origin/master"), 1225 "ab45678\nab23456"), 1226 Cmd("git log -1 --format=%s ab45678", "Title1"), 1227 Cmd("git log -1 --format=%s ab23456", "Title2"), 1228 Cmd(("git log --format=%H --grep=\"Port ab23456\" " 1229 "--reverse origin/master"), 1230 ""), 1231 Cmd(("git log --format=%H --grep=\"Port ab34567\" " 1232 "--reverse origin/master"), 1233 "ab56789"), 1234 Cmd("git log -1 --format=%s ab56789", "Title3"), 1235 RL("Y"), # Automatically add corresponding ports (ab34567, ab56789)? 1236 # Simulate git being down which stops the script. 1237 Cmd("git log -1 --format=%s ab12345", None), 1238 # Restart script in the failing step. 1239 Cmd("git log -1 --format=%s ab12345", "Title4"), 1240 Cmd("git log -1 --format=%s ab23456", "Title2"), 1241 Cmd("git log -1 --format=%s ab34567", "Title3"), 1242 Cmd("git log -1 --format=%s ab45678", "Title1"), 1243 Cmd("git log -1 --format=%s ab56789", "Revert \"Something\""), 1244 Cmd("git log -1 ab12345", "Title4\nBUG=123\nBUG=234"), 1245 Cmd("git log -1 ab23456", "Title2\n BUG = v8:123,345"), 1246 Cmd("git log -1 ab34567", "Title3\nLOG=n\nBUG=567, 456"), 1247 Cmd("git log -1 ab45678", "Title1\nBUG="), 1248 Cmd("git log -1 ab56789", "Revert \"Something\"\nBUG=none"), 1249 Cmd("git log -1 -p ab12345", "patch4"), 1250 Cmd(("git apply --index --reject \"%s\"" % 1251 TEST_CONFIG["TEMPORARY_PATCH_FILE"]), 1252 "", cb=VerifyPatch("patch4")), 1253 Cmd("git log -1 -p ab23456", "patch2"), 1254 Cmd(("git apply --index --reject \"%s\"" % 1255 TEST_CONFIG["TEMPORARY_PATCH_FILE"]), 1256 "", cb=VerifyPatch("patch2")), 1257 Cmd("git log -1 -p ab34567", "patch3"), 1258 Cmd(("git apply --index --reject \"%s\"" % 1259 TEST_CONFIG["TEMPORARY_PATCH_FILE"]), 1260 "", cb=VerifyPatch("patch3")), 1261 Cmd("git log -1 -p ab45678", "patch1"), 1262 Cmd(("git apply --index --reject \"%s\"" % 1263 TEST_CONFIG["TEMPORARY_PATCH_FILE"]), 1264 "", cb=VerifyPatch("patch1")), 1265 Cmd("git log -1 -p ab56789", "patch5\n"), 1266 Cmd(("git apply --index --reject \"%s\"" % 1267 TEST_CONFIG["TEMPORARY_PATCH_FILE"]), 1268 "", cb=VerifyPatch("patch5\n")), 1269 Cmd("git apply --index --reject \"%s\"" % extra_patch, ""), 1270 RL("Y"), # Automatically increment patch level? 1271 Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], ""), 1272 RL("reviewer@chromium.org"), # V8 reviewer. 1273 Cmd("git cl upload --send-mail -r \"reviewer@chromium.org\" " 1274 "--bypass-hooks --cc \"ulan@chromium.org\"", ""), 1275 Cmd("git checkout -f %s" % TEST_CONFIG["BRANCHNAME"], ""), 1276 RL("LGTM"), # Enter LGTM for V8 CL. 1277 Cmd("git cl presubmit", "Presubmit successfull\n"), 1278 Cmd("git cl land -f --bypass-hooks", "Closing issue\n", 1279 cb=VerifyLand), 1280 Cmd("git fetch", ""), 1281 Cmd("git log -1 --format=%H --grep=\"" 1282 "Version 3.22.5.1 (cherry-pick)" 1283 "\" refs/remotes/origin/candidates", 1284 ""), 1285 Cmd("git fetch", ""), 1286 Cmd("git log -1 --format=%H --grep=\"" 1287 "Version 3.22.5.1 (cherry-pick)" 1288 "\" refs/remotes/origin/candidates", 1289 "hsh_to_tag"), 1290 Cmd("git tag 3.22.5.1 hsh_to_tag", ""), 1291 Cmd("git push origin 3.22.5.1", ""), 1292 Cmd("git checkout -f origin/master", ""), 1293 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""), 1294 ]) 1295 1296 # ab12345 and ab34567 are patches. ab23456 (included) and ab45678 are the 1297 # MIPS ports of ab12345. ab56789 is the MIPS port of ab34567. 1298 args = ["-f", "-p", extra_patch, "--branch", "candidates", 1299 "ab12345", "ab23456", "ab34567"] 1300 1301 # The first run of the script stops because of git being down. 1302 self.assertRaises(GitFailedException, 1303 lambda: RollMerge(TEST_CONFIG, self).Run(args)) 1304 1305 # Test that state recovery after restarting the script works. 1306 args += ["-s", "4"] 1307 RollMerge(TEST_CONFIG, self).Run(args) 1308 1309 def testReleases(self): 1310 c_hash1_commit_log = """Update V8 to Version 4.2.71. 1311 1312Cr-Commit-Position: refs/heads/master@{#5678} 1313""" 1314 c_hash2_commit_log = """Revert something. 1315 1316BUG=12345 1317 1318Reason: 1319> Some reason. 1320> Cr-Commit-Position: refs/heads/master@{#12345} 1321> git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12345 003-1c4 1322 1323Review URL: https://codereview.chromium.org/12345 1324 1325Cr-Commit-Position: refs/heads/master@{#4567} 1326git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4567 0039-1c4b 1327 1328""" 1329 c_hash3_commit_log = """Simple. 1330 1331git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3456 0039-1c4b 1332 1333""" 1334 c_hash_234_commit_log = """Version 3.3.1.1 (cherry-pick). 1335 1336Merged abc12. 1337 1338Review URL: fake.com 1339 1340Cr-Commit-Position: refs/heads/candidates@{#234} 1341""" 1342 c_hash_123_commit_log = """Version 3.3.1.0 1343 1344git-svn-id: googlecode@123 0039-1c4b 1345""" 1346 c_hash_345_commit_log = """Version 3.4.0. 1347 1348Cr-Commit-Position: refs/heads/candidates@{#345} 1349""" 1350 c_hash_456_commit_log = """Version 4.2.71. 1351 1352Cr-Commit-Position: refs/heads/4.2.71@{#1} 1353""" 1354 c_deps = "Line\n \"v8_revision\": \"%s\",\n line\n" 1355 1356 json_output = self.MakeEmptyTempFile() 1357 csv_output = self.MakeEmptyTempFile() 1358 self.WriteFakeVersionFile() 1359 1360 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory() 1361 chrome_dir = TEST_CONFIG["CHROMIUM"] 1362 chrome_v8_dir = os.path.join(chrome_dir, "v8") 1363 os.makedirs(chrome_v8_dir) 1364 1365 def ResetVersion(major, minor, build, patch=0): 1366 return lambda: self.WriteFakeVersionFile(major=major, 1367 minor=minor, 1368 build=build, 1369 patch=patch) 1370 1371 self.Expect([ 1372 Cmd("git status -s -uno", ""), 1373 Cmd("git checkout -f origin/master", ""), 1374 Cmd("git fetch", ""), 1375 Cmd("git branch", " branch1\n* branch2\n"), 1376 Cmd("git new-branch %s" % TEST_CONFIG["BRANCHNAME"], ""), 1377 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), 1378 Cmd("git rev-list --max-age=395200 --tags", 1379 "bad_tag\nhash_234\nhash_123\nhash_345\nhash_456\n"), 1380 Cmd("git describe --tags bad_tag", "3.23.42-1-deadbeef"), 1381 Cmd("git describe --tags hash_234", "3.3.1.1"), 1382 Cmd("git describe --tags hash_123", "3.21.2"), 1383 Cmd("git describe --tags hash_345", "3.22.3"), 1384 Cmd("git describe --tags hash_456", "4.2.71"), 1385 Cmd("git diff --name-only hash_234 hash_234^", VERSION_FILE), 1386 Cmd("git checkout -f hash_234 -- %s" % VERSION_FILE, "", 1387 cb=ResetVersion(3, 3, 1, 1)), 1388 Cmd("git branch -r --contains hash_234", " branch-heads/3.3\n"), 1389 Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log), 1390 Cmd("git log -1 --format=%s hash_234", ""), 1391 Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log), 1392 Cmd("git log -1 --format=%ci hash_234", "18:15"), 1393 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", 1394 cb=ResetVersion(3, 22, 5)), 1395 Cmd("git diff --name-only hash_123 hash_123^", VERSION_FILE), 1396 Cmd("git checkout -f hash_123 -- %s" % VERSION_FILE, "", 1397 cb=ResetVersion(3, 21, 2)), 1398 Cmd("git branch -r --contains hash_123", " branch-heads/3.21\n"), 1399 Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log), 1400 Cmd("git log -1 --format=%s hash_123", ""), 1401 Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log), 1402 Cmd("git log -1 --format=%ci hash_123", "03:15"), 1403 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", 1404 cb=ResetVersion(3, 22, 5)), 1405 Cmd("git diff --name-only hash_345 hash_345^", VERSION_FILE), 1406 Cmd("git checkout -f hash_345 -- %s" % VERSION_FILE, "", 1407 cb=ResetVersion(3, 22, 3)), 1408 Cmd("git branch -r --contains hash_345", " origin/candidates\n"), 1409 Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log), 1410 Cmd("git log -1 --format=%s hash_345", ""), 1411 Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log), 1412 Cmd("git log -1 --format=%ci hash_345", ""), 1413 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", 1414 cb=ResetVersion(3, 22, 5)), 1415 Cmd("git diff --name-only hash_456 hash_456^", VERSION_FILE), 1416 Cmd("git checkout -f hash_456 -- %s" % VERSION_FILE, "", 1417 cb=ResetVersion(4, 2, 71)), 1418 Cmd("git branch -r --contains hash_456", " origin/4.2.71\n"), 1419 Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log), 1420 Cmd("git log -1 --format=%H 4.2.71", "hash_456"), 1421 Cmd("git log -1 --format=%s hash_456", "Version 4.2.71"), 1422 Cmd("git log -1 --format=%H hash_456^", "master_456"), 1423 Cmd("git log -1 --format=%B master_456", 1424 "Cr-Commit-Position: refs/heads/master@{#456}"), 1425 Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log), 1426 Cmd("git log -1 --format=%ci hash_456", "02:15"), 1427 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", 1428 cb=ResetVersion(3, 22, 5)), 1429 Cmd("git fetch origin +refs/heads/*:refs/remotes/origin/* " 1430 "+refs/branch-heads/*:refs/remotes/branch-heads/*", "", 1431 cwd=chrome_dir), 1432 Cmd("git fetch origin", "", cwd=chrome_v8_dir), 1433 Cmd("git log --format=%H --grep=\"V8\" origin/master -- DEPS", 1434 "c_hash1\nc_hash2\nc_hash3\n", 1435 cwd=chrome_dir), 1436 Cmd("git show c_hash1:DEPS", c_deps % "hash_456", cwd=chrome_dir), 1437 Cmd("git log -1 --format=%B c_hash1", c_hash1_commit_log, 1438 cwd=chrome_dir), 1439 Cmd("git show c_hash2:DEPS", c_deps % "hash_345", cwd=chrome_dir), 1440 Cmd("git log -1 --format=%B c_hash2", c_hash2_commit_log, 1441 cwd=chrome_dir), 1442 Cmd("git show c_hash3:DEPS", c_deps % "deadbeef", cwd=chrome_dir), 1443 Cmd("git log -1 --format=%B c_hash3", c_hash3_commit_log, 1444 cwd=chrome_dir), 1445 Cmd("git branch -r", " weird/123\n branch-heads/7\n", cwd=chrome_dir), 1446 Cmd("git show refs/branch-heads/7:DEPS", c_deps % "hash_345", 1447 cwd=chrome_dir), 1448 URL("http://omahaproxy.appspot.com/all.json", """[{ 1449 "os": "win", 1450 "versions": [{ 1451 "version": "2.2.2.2", 1452 "v8_version": "22.2.2.2", 1453 "current_reldate": "04/09/15", 1454 "os": "win", 1455 "channel": "canary", 1456 "previous_version": "1.1.1.0" 1457 }] 1458 }]"""), 1459 URL("http://omahaproxy.appspot.com/v8.json?version=1.1.1.0", """{ 1460 "chromium_version": "1.1.1.0", 1461 "v8_version": "11.1.1.0" 1462 }"""), 1463 Cmd("git rev-list -1 11.1.1", "v8_previous_version_hash"), 1464 Cmd("git rev-list -1 22.2.2.2", "v8_version_hash"), 1465 Cmd("git checkout -f origin/master", ""), 1466 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], "") 1467 ]) 1468 1469 args = ["-c", TEST_CONFIG["CHROMIUM"], 1470 "--json", json_output, 1471 "--csv", csv_output, 1472 "--max-releases", "1"] 1473 Releases(TEST_CONFIG, self).Run(args) 1474 1475 # Check expected output. 1476 csv = ("4.2.71,4.2.71,1,5678,\r\n" 1477 "3.22.3,candidates,345,4567:5677,\r\n" 1478 "3.21.2,3.21,123,,\r\n" 1479 "3.3.1.1,3.3,234,,abc12\r\n") 1480 self.assertEquals(csv, FileToText(csv_output)) 1481 1482 expected_json = {"chrome_releases":{ 1483 "canaries": [ 1484 { 1485 "chrome_version": "2.2.2.2", 1486 "os": "win", 1487 "release_date": "04/09/15", 1488 "v8_version": "22.2.2.2", 1489 "v8_version_hash": "v8_version_hash", 1490 "v8_previous_version": "11.1.1.0", 1491 "v8_previous_version_hash": "v8_previous_version_hash" 1492 }]}, 1493 "releases":[ 1494 { 1495 "revision": "1", 1496 "revision_git": "hash_456", 1497 "master_position": "456", 1498 "master_hash": "master_456", 1499 "patches_merged": "", 1500 "version": "4.2.71", 1501 "chromium_revision": "5678", 1502 "branch": "4.2.71", 1503 "review_link": "", 1504 "date": "02:15", 1505 "chromium_branch": "", 1506 # FIXME(machenbach): Fix revisions link for git. 1507 "revision_link": "https://code.google.com/p/v8/source/detail?r=1", 1508 }, 1509 { 1510 "revision": "345", 1511 "revision_git": "hash_345", 1512 "master_position": "", 1513 "master_hash": "", 1514 "patches_merged": "", 1515 "version": "3.22.3", 1516 "chromium_revision": "4567:5677", 1517 "branch": "candidates", 1518 "review_link": "", 1519 "date": "", 1520 "chromium_branch": "7", 1521 "revision_link": "https://code.google.com/p/v8/source/detail?r=345", 1522 }, 1523 { 1524 "revision": "123", 1525 "revision_git": "hash_123", 1526 "patches_merged": "", 1527 "master_position": "", 1528 "master_hash": "", 1529 "version": "3.21.2", 1530 "chromium_revision": "", 1531 "branch": "3.21", 1532 "review_link": "", 1533 "date": "03:15", 1534 "chromium_branch": "", 1535 "revision_link": "https://code.google.com/p/v8/source/detail?r=123", 1536 }, 1537 { 1538 "revision": "234", 1539 "revision_git": "hash_234", 1540 "patches_merged": "abc12", 1541 "master_position": "", 1542 "master_hash": "", 1543 "version": "3.3.1.1", 1544 "chromium_revision": "", 1545 "branch": "3.3", 1546 "review_link": "fake.com", 1547 "date": "18:15", 1548 "chromium_branch": "", 1549 "revision_link": "https://code.google.com/p/v8/source/detail?r=234", 1550 },], 1551 } 1552 self.assertEquals(expected_json, json.loads(FileToText(json_output))) 1553 1554 def testMergeToBranch(self): 1555 TEST_CONFIG["ALREADY_MERGING_SENTINEL_FILE"] = self.MakeEmptyTempFile() 1556 TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git")) 1557 self.WriteFakeVersionFile(build=5) 1558 os.environ["EDITOR"] = "vi" 1559 extra_patch = self.MakeEmptyTempFile() 1560 1561 1562 def VerifyPatch(patch): 1563 return lambda: self.assertEquals(patch, 1564 FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"])) 1565 1566 info_msg = ("NOTE: This script will no longer automatically " 1567 "update include/v8-version.h " 1568 "and create a tag. This is done automatically by the autotag bot. " 1569 "Please call the merge_to_branch.py with --help for more information.") 1570 1571 msg = """Merged: Squashed multiple commits. 1572 1573Merged: Title4 1574Revision: ab12345 1575 1576Merged: Title2 1577Revision: ab23456 1578 1579Merged: Title3 1580Revision: ab34567 1581 1582Merged: Title1 1583Revision: ab45678 1584 1585Merged: Revert \"Something\" 1586Revision: ab56789 1587 1588BUG=123,234,345,456,567,v8:123 1589LOG=N 1590NOTRY=true 1591NOPRESUBMIT=true 1592NOTREECHECKS=true 1593""" 1594 1595 def VerifyLand(): 1596 commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"]) 1597 self.assertEquals(msg, commit) 1598 1599 self.Expect([ 1600 Cmd("git status -s -uno", ""), 1601 Cmd("git checkout -f origin/master", ""), 1602 Cmd("git fetch", ""), 1603 Cmd("git branch", " branch1\n* branch2\n"), 1604 Cmd("git new-branch %s --upstream refs/remotes/origin/candidates" % 1605 TEST_CONFIG["BRANCHNAME"], ""), 1606 Cmd(("git log --format=%H --grep=\"^[Pp]ort ab12345\" " 1607 "--reverse origin/master"), 1608 "ab45678\nab23456"), 1609 Cmd("git log -1 --format=%s ab45678", "Title1"), 1610 Cmd("git log -1 --format=%s ab23456", "Title2"), 1611 Cmd(("git log --format=%H --grep=\"^[Pp]ort ab23456\" " 1612 "--reverse origin/master"), 1613 ""), 1614 Cmd(("git log --format=%H --grep=\"^[Pp]ort ab34567\" " 1615 "--reverse origin/master"), 1616 "ab56789"), 1617 Cmd("git log -1 --format=%s ab56789", "Title3"), 1618 RL("Y"), # Automatically add corresponding ports (ab34567, ab56789)? 1619 # Simulate git being down which stops the script. 1620 Cmd("git log -1 --format=%s ab12345", None), 1621 # Restart script in the failing step. 1622 Cmd("git log -1 --format=%s ab12345", "Title4"), 1623 Cmd("git log -1 --format=%s ab23456", "Title2"), 1624 Cmd("git log -1 --format=%s ab34567", "Title3"), 1625 Cmd("git log -1 --format=%s ab45678", "Title1"), 1626 Cmd("git log -1 --format=%s ab56789", "Revert \"Something\""), 1627 Cmd("git log -1 ab12345", "Title4\nBUG=123\nBUG=234"), 1628 Cmd("git log -1 ab23456", "Title2\n BUG = v8:123,345"), 1629 Cmd("git log -1 ab34567", "Title3\nLOG=n\nBUG=567, 456"), 1630 Cmd("git log -1 ab45678", "Title1\nBUG="), 1631 Cmd("git log -1 ab56789", "Revert \"Something\"\nBUG=none"), 1632 Cmd("git log -1 -p ab12345", "patch4"), 1633 Cmd(("git apply --index --reject \"%s\"" % 1634 TEST_CONFIG["TEMPORARY_PATCH_FILE"]), 1635 "", cb=VerifyPatch("patch4")), 1636 Cmd("git log -1 -p ab23456", "patch2"), 1637 Cmd(("git apply --index --reject \"%s\"" % 1638 TEST_CONFIG["TEMPORARY_PATCH_FILE"]), 1639 "", cb=VerifyPatch("patch2")), 1640 Cmd("git log -1 -p ab34567", "patch3"), 1641 Cmd(("git apply --index --reject \"%s\"" % 1642 TEST_CONFIG["TEMPORARY_PATCH_FILE"]), 1643 "", cb=VerifyPatch("patch3")), 1644 Cmd("git log -1 -p ab45678", "patch1"), 1645 Cmd(("git apply --index --reject \"%s\"" % 1646 TEST_CONFIG["TEMPORARY_PATCH_FILE"]), 1647 "", cb=VerifyPatch("patch1")), 1648 Cmd("git log -1 -p ab56789", "patch5\n"), 1649 Cmd(("git apply --index --reject \"%s\"" % 1650 TEST_CONFIG["TEMPORARY_PATCH_FILE"]), 1651 "", cb=VerifyPatch("patch5\n")), 1652 Cmd("git apply --index --reject \"%s\"" % extra_patch, ""), 1653 Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], ""), 1654 RL("reviewer@chromium.org"), # V8 reviewer. 1655 Cmd("git cl upload --send-mail -r \"reviewer@chromium.org\" " 1656 "--bypass-hooks --cc \"ulan@chromium.org\"", ""), 1657 Cmd("git cl comments -a \"%s\"" % info_msg, ""), 1658 Cmd("git checkout -f %s" % TEST_CONFIG["BRANCHNAME"], ""), 1659 RL("LGTM"), # Enter LGTM for V8 CL. 1660 Cmd("git cl presubmit", "Presubmit successfull\n"), 1661 Cmd("git cl land -f --bypass-hooks", "Closing issue\n", 1662 cb=VerifyLand), 1663 Cmd("git checkout -f origin/master", ""), 1664 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""), 1665 ]) 1666 1667 # ab12345 and ab34567 are patches. ab23456 (included) and ab45678 are the 1668 # MIPS ports of ab12345. ab56789 is the MIPS port of ab34567. 1669 args = ["-f", "-p", extra_patch, "--branch", "candidates", 1670 "ab12345", "ab23456", "ab34567"] 1671 1672 # The first run of the script stops because of git being down. 1673 self.assertRaises(GitFailedException, 1674 lambda: MergeToBranch(TEST_CONFIG, self).Run(args)) 1675 1676 # Test that state recovery after restarting the script works. 1677 args += ["-s", "4"] 1678 MergeToBranch(TEST_CONFIG, self).Run(args) 1679 1680 def testReleases(self): 1681 c_hash1_commit_log = """Update V8 to Version 4.2.71. 1682 1683Cr-Commit-Position: refs/heads/master@{#5678} 1684""" 1685 c_hash2_commit_log = """Revert something. 1686 1687BUG=12345 1688 1689Reason: 1690> Some reason. 1691> Cr-Commit-Position: refs/heads/master@{#12345} 1692> git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12345 003-1c4 1693 1694Review URL: https://codereview.chromium.org/12345 1695 1696Cr-Commit-Position: refs/heads/master@{#4567} 1697git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4567 0039-1c4b 1698 1699""" 1700 c_hash3_commit_log = """Simple. 1701 1702git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3456 0039-1c4b 1703 1704""" 1705 c_hash_234_commit_log = """Version 3.3.1.1 (cherry-pick). 1706 1707Merged abc12. 1708 1709Review URL: fake.com 1710 1711Cr-Commit-Position: refs/heads/candidates@{#234} 1712""" 1713 c_hash_123_commit_log = """Version 3.3.1.0 1714 1715git-svn-id: googlecode@123 0039-1c4b 1716""" 1717 c_hash_345_commit_log = """Version 3.4.0. 1718 1719Cr-Commit-Position: refs/heads/candidates@{#345} 1720""" 1721 c_hash_456_commit_log = """Version 4.2.71. 1722 1723Cr-Commit-Position: refs/heads/4.2.71@{#1} 1724""" 1725 c_deps = "Line\n \"v8_revision\": \"%s\",\n line\n" 1726 1727 json_output = self.MakeEmptyTempFile() 1728 csv_output = self.MakeEmptyTempFile() 1729 self.WriteFakeVersionFile() 1730 1731 TEST_CONFIG["CHROMIUM"] = self.MakeEmptyTempDirectory() 1732 chrome_dir = TEST_CONFIG["CHROMIUM"] 1733 chrome_v8_dir = os.path.join(chrome_dir, "v8") 1734 os.makedirs(chrome_v8_dir) 1735 1736 def ResetVersion(major, minor, build, patch=0): 1737 return lambda: self.WriteFakeVersionFile(major=major, 1738 minor=minor, 1739 build=build, 1740 patch=patch) 1741 1742 self.Expect([ 1743 Cmd("git status -s -uno", ""), 1744 Cmd("git checkout -f origin/master", ""), 1745 Cmd("git fetch", ""), 1746 Cmd("git branch", " branch1\n* branch2\n"), 1747 Cmd("git new-branch %s" % TEST_CONFIG["BRANCHNAME"], ""), 1748 Cmd("git fetch origin +refs/tags/*:refs/tags/*", ""), 1749 Cmd("git rev-list --max-age=395200 --tags", 1750 "bad_tag\nhash_234\nhash_123\nhash_345\nhash_456\n"), 1751 Cmd("git describe --tags bad_tag", "3.23.42-1-deadbeef"), 1752 Cmd("git describe --tags hash_234", "3.3.1.1"), 1753 Cmd("git describe --tags hash_123", "3.21.2"), 1754 Cmd("git describe --tags hash_345", "3.22.3"), 1755 Cmd("git describe --tags hash_456", "4.2.71"), 1756 Cmd("git diff --name-only hash_234 hash_234^", VERSION_FILE), 1757 Cmd("git checkout -f hash_234 -- %s" % VERSION_FILE, "", 1758 cb=ResetVersion(3, 3, 1, 1)), 1759 Cmd("git branch -r --contains hash_234", " branch-heads/3.3\n"), 1760 Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log), 1761 Cmd("git log -1 --format=%s hash_234", ""), 1762 Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log), 1763 Cmd("git log -1 --format=%ci hash_234", "18:15"), 1764 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", 1765 cb=ResetVersion(3, 22, 5)), 1766 Cmd("git diff --name-only hash_123 hash_123^", VERSION_FILE), 1767 Cmd("git checkout -f hash_123 -- %s" % VERSION_FILE, "", 1768 cb=ResetVersion(3, 21, 2)), 1769 Cmd("git branch -r --contains hash_123", " branch-heads/3.21\n"), 1770 Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log), 1771 Cmd("git log -1 --format=%s hash_123", ""), 1772 Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log), 1773 Cmd("git log -1 --format=%ci hash_123", "03:15"), 1774 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", 1775 cb=ResetVersion(3, 22, 5)), 1776 Cmd("git diff --name-only hash_345 hash_345^", VERSION_FILE), 1777 Cmd("git checkout -f hash_345 -- %s" % VERSION_FILE, "", 1778 cb=ResetVersion(3, 22, 3)), 1779 Cmd("git branch -r --contains hash_345", " origin/candidates\n"), 1780 Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log), 1781 Cmd("git log -1 --format=%s hash_345", ""), 1782 Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log), 1783 Cmd("git log -1 --format=%ci hash_345", ""), 1784 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", 1785 cb=ResetVersion(3, 22, 5)), 1786 Cmd("git diff --name-only hash_456 hash_456^", VERSION_FILE), 1787 Cmd("git checkout -f hash_456 -- %s" % VERSION_FILE, "", 1788 cb=ResetVersion(4, 2, 71)), 1789 Cmd("git branch -r --contains hash_456", " origin/4.2.71\n"), 1790 Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log), 1791 Cmd("git log -1 --format=%H 4.2.71", "hash_456"), 1792 Cmd("git log -1 --format=%s hash_456", "Version 4.2.71"), 1793 Cmd("git log -1 --format=%H hash_456^", "master_456"), 1794 Cmd("git log -1 --format=%B master_456", 1795 "Cr-Commit-Position: refs/heads/master@{#456}"), 1796 Cmd("git log -1 --format=%B hash_456", c_hash_456_commit_log), 1797 Cmd("git log -1 --format=%ci hash_456", "02:15"), 1798 Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "", 1799 cb=ResetVersion(3, 22, 5)), 1800 Cmd("git fetch origin +refs/heads/*:refs/remotes/origin/* " 1801 "+refs/branch-heads/*:refs/remotes/branch-heads/*", "", 1802 cwd=chrome_dir), 1803 Cmd("git fetch origin", "", cwd=chrome_v8_dir), 1804 Cmd("git log --format=%H --grep=\"V8\" origin/master -- DEPS", 1805 "c_hash1\nc_hash2\nc_hash3\n", 1806 cwd=chrome_dir), 1807 Cmd("git show c_hash1:DEPS", c_deps % "hash_456", cwd=chrome_dir), 1808 Cmd("git log -1 --format=%B c_hash1", c_hash1_commit_log, 1809 cwd=chrome_dir), 1810 Cmd("git show c_hash2:DEPS", c_deps % "hash_345", cwd=chrome_dir), 1811 Cmd("git log -1 --format=%B c_hash2", c_hash2_commit_log, 1812 cwd=chrome_dir), 1813 Cmd("git show c_hash3:DEPS", c_deps % "deadbeef", cwd=chrome_dir), 1814 Cmd("git log -1 --format=%B c_hash3", c_hash3_commit_log, 1815 cwd=chrome_dir), 1816 Cmd("git branch -r", " weird/123\n branch-heads/7\n", cwd=chrome_dir), 1817 Cmd("git show refs/branch-heads/7:DEPS", c_deps % "hash_345", 1818 cwd=chrome_dir), 1819 URL("http://omahaproxy.appspot.com/all.json", """[{ 1820 "os": "win", 1821 "versions": [{ 1822 "version": "2.2.2.2", 1823 "v8_version": "22.2.2.2", 1824 "current_reldate": "04/09/15", 1825 "os": "win", 1826 "channel": "canary", 1827 "previous_version": "1.1.1.0" 1828 }] 1829 }]"""), 1830 URL("http://omahaproxy.appspot.com/v8.json?version=1.1.1.0", """{ 1831 "chromium_version": "1.1.1.0", 1832 "v8_version": "11.1.1.0" 1833 }"""), 1834 Cmd("git rev-list -1 11.1.1", "v8_previous_version_hash"), 1835 Cmd("git rev-list -1 22.2.2.2", "v8_version_hash"), 1836 Cmd("git checkout -f origin/master", ""), 1837 Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], "") 1838 ]) 1839 1840 args = ["-c", TEST_CONFIG["CHROMIUM"], 1841 "--json", json_output, 1842 "--csv", csv_output, 1843 "--max-releases", "1"] 1844 Releases(TEST_CONFIG, self).Run(args) 1845 1846 # Check expected output. 1847 csv = ("4.2.71,4.2.71,1,5678,\r\n" 1848 "3.22.3,candidates,345,4567:5677,\r\n" 1849 "3.21.2,3.21,123,,\r\n" 1850 "3.3.1.1,3.3,234,,abc12\r\n") 1851 self.assertEquals(csv, FileToText(csv_output)) 1852 1853 expected_json = {"chrome_releases":{ 1854 "canaries": [ 1855 { 1856 "chrome_version": "2.2.2.2", 1857 "os": "win", 1858 "release_date": "04/09/15", 1859 "v8_version": "22.2.2.2", 1860 "v8_version_hash": "v8_version_hash", 1861 "v8_previous_version": "11.1.1.0", 1862 "v8_previous_version_hash": "v8_previous_version_hash" 1863 }]}, 1864 "releases":[ 1865 { 1866 "revision": "1", 1867 "revision_git": "hash_456", 1868 "master_position": "456", 1869 "master_hash": "master_456", 1870 "patches_merged": "", 1871 "version": "4.2.71", 1872 "chromium_revision": "5678", 1873 "branch": "4.2.71", 1874 "review_link": "", 1875 "date": "02:15", 1876 "chromium_branch": "", 1877 # FIXME(machenbach): Fix revisions link for git. 1878 "revision_link": "https://code.google.com/p/v8/source/detail?r=1", 1879 }, 1880 { 1881 "revision": "345", 1882 "revision_git": "hash_345", 1883 "master_position": "", 1884 "master_hash": "", 1885 "patches_merged": "", 1886 "version": "3.22.3", 1887 "chromium_revision": "4567:5677", 1888 "branch": "candidates", 1889 "review_link": "", 1890 "date": "", 1891 "chromium_branch": "7", 1892 "revision_link": "https://code.google.com/p/v8/source/detail?r=345", 1893 }, 1894 { 1895 "revision": "123", 1896 "revision_git": "hash_123", 1897 "patches_merged": "", 1898 "master_position": "", 1899 "master_hash": "", 1900 "version": "3.21.2", 1901 "chromium_revision": "", 1902 "branch": "3.21", 1903 "review_link": "", 1904 "date": "03:15", 1905 "chromium_branch": "", 1906 "revision_link": "https://code.google.com/p/v8/source/detail?r=123", 1907 }, 1908 { 1909 "revision": "234", 1910 "revision_git": "hash_234", 1911 "patches_merged": "abc12", 1912 "master_position": "", 1913 "master_hash": "", 1914 "version": "3.3.1.1", 1915 "chromium_revision": "", 1916 "branch": "3.3", 1917 "review_link": "fake.com", 1918 "date": "18:15", 1919 "chromium_branch": "", 1920 "revision_link": "https://code.google.com/p/v8/source/detail?r=234", 1921 },], 1922 } 1923 self.assertEquals(expected_json, json.loads(FileToText(json_output))) 1924 1925 1926 1927 1928class SystemTest(unittest.TestCase): 1929 def testReload(self): 1930 options = ScriptsBase( 1931 TEST_CONFIG, DEFAULT_SIDE_EFFECT_HANDLER, {}).MakeOptions([]) 1932 step = MakeStep(step_class=PrepareChangeLog, number=0, state={}, config={}, 1933 options=options, 1934 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER) 1935 body = step.Reload( 1936"""------------------------------------------------------------------------ 1937r17997 | machenbach@chromium.org | 2013-11-22 11:04:04 +0100 (...) | 6 lines 1938 1939Prepare push to trunk. Now working on version 3.23.11. 1940 1941R=danno@chromium.org 1942 1943Review URL: https://codereview.chromium.org/83173002 1944 1945------------------------------------------------------------------------""") 1946 self.assertEquals( 1947"""Prepare push to trunk. Now working on version 3.23.11. 1948 1949R=danno@chromium.org 1950 1951Committed: https://code.google.com/p/v8/source/detail?r=17997""", body) 1952