| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2013 the V8 project authors. All rights reserved. | 2 # Copyright 2013 the V8 project authors. All rights reserved. |
| 3 # Redistribution and use in source and binary forms, with or without | 3 # Redistribution and use in source and binary forms, with or without |
| 4 # modification, are permitted provided that the following conditions are | 4 # modification, are permitted provided that the following conditions are |
| 5 # met: | 5 # met: |
| 6 # | 6 # |
| 7 # * Redistributions of source code must retain the above copyright | 7 # * Redistributions of source code must retain the above copyright |
| 8 # notice, this list of conditions and the following disclaimer. | 8 # notice, this list of conditions and the following disclaimer. |
| 9 # * Redistributions in binary form must reproduce the above | 9 # * Redistributions in binary form must reproduce the above |
| 10 # copyright notice, this list of conditions and the following | 10 # copyright notice, this list of conditions and the following |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 | 28 |
| 29 import os | 29 import os |
| 30 import tempfile | 30 import tempfile |
| 31 import unittest | 31 import unittest |
| 32 | 32 |
| 33 import common_includes | 33 import common_includes |
| 34 from common_includes import * | 34 from common_includes import * |
| 35 import push_to_trunk | 35 import push_to_trunk |
| 36 from push_to_trunk import * | 36 from push_to_trunk import * |
| 37 import auto_roll | 37 import auto_roll |
| 38 from auto_roll import AutoRollOptions |
| 39 from auto_roll import CheckLastPush |
| 40 from auto_roll import FetchLatestRevision |
| 38 | 41 |
| 39 | 42 |
| 40 TEST_CONFIG = { | 43 TEST_CONFIG = { |
| 41 BRANCHNAME: "test-prepare-push", | 44 BRANCHNAME: "test-prepare-push", |
| 42 TRUNKBRANCH: "test-trunk-push", | 45 TRUNKBRANCH: "test-trunk-push", |
| 43 PERSISTFILE_BASENAME: "/tmp/test-v8-push-to-trunk-tempfile", | 46 PERSISTFILE_BASENAME: "/tmp/test-v8-push-to-trunk-tempfile", |
| 44 TEMP_BRANCH: "test-prepare-push-temporary-branch-created-by-script", | 47 TEMP_BRANCH: "test-prepare-push-temporary-branch-created-by-script", |
| 45 DOT_GIT_LOCATION: None, | 48 DOT_GIT_LOCATION: None, |
| 46 VERSION_FILE: None, | 49 VERSION_FILE: None, |
| 47 CHANGELOG_FILE: None, | 50 CHANGELOG_FILE: None, |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 except IndexError: | 224 except IndexError: |
| 222 raise Exception("Calling %s %s" % (self._name, " ".join(args))) | 225 raise Exception("Calling %s %s" % (self._name, " ".join(args))) |
| 223 | 226 |
| 224 # Pack expectations without arguments into a list. | 227 # Pack expectations without arguments into a list. |
| 225 if not isinstance(expected_call, list): | 228 if not isinstance(expected_call, list): |
| 226 expected_call = [expected_call] | 229 expected_call = [expected_call] |
| 227 | 230 |
| 228 # The number of arguments in the expectation must match the actual | 231 # The number of arguments in the expectation must match the actual |
| 229 # arguments. | 232 # arguments. |
| 230 if len(args) > len(expected_call): | 233 if len(args) > len(expected_call): |
| 231 raise Exception("When calling %s with arguments, the expectations " | 234 raise NoRetryException("When calling %s with arguments, the " |
| 232 "must consist of at least as many arguments.") | 235 "expectations must consist of at least as many arguments.") |
| 233 | 236 |
| 234 # Compare expected and actual arguments. | 237 # Compare expected and actual arguments. |
| 235 for (expected_arg, actual_arg) in zip(expected_call, args): | 238 for (expected_arg, actual_arg) in zip(expected_call, args): |
| 236 if expected_arg != actual_arg: | 239 if expected_arg != actual_arg: |
| 237 raise Exception("Expected: %s - Actual: %s" | 240 raise NoRetryException("Expected: %s - Actual: %s" |
| 238 % (expected_arg, actual_arg)) | 241 % (expected_arg, actual_arg)) |
| 239 | 242 |
| 240 # The expectation list contains a mandatory return value and an optional | 243 # The expectation list contains a mandatory return value and an optional |
| 241 # callback for checking the context at the time of the call. | 244 # callback for checking the context at the time of the call. |
| 242 if len(expected_call) == len(args) + 2: | 245 if len(expected_call) == len(args) + 2: |
| 243 expected_call[len(args) + 1]() | 246 expected_call[len(args) + 1]() |
| 244 return_value = expected_call[len(args)] | 247 return_value = expected_call[len(args)] |
| 245 | 248 |
| 246 # If the return value is an exception, raise it instead of returning. | 249 # If the return value is an exception, raise it instead of returning. |
| 247 if isinstance(return_value, Exception): | 250 if isinstance(return_value, Exception): |
| 248 raise return_value | 251 raise return_value |
| 249 return return_value | 252 return return_value |
| 250 | 253 |
| 251 def AssertFinished(self): | 254 def AssertFinished(self): |
| 252 if self._index < len(self._recipe) -1: | 255 if self._index < len(self._recipe) -1: |
| 253 raise Exception("Called %s too seldom: %d vs. %d" | 256 raise NoRetryException("Called %s too seldom: %d vs. %d" |
| 254 % (self._name, self._index, len(self._recipe))) | 257 % (self._name, self._index, len(self._recipe))) |
| 255 | 258 |
| 256 | 259 |
| 257 class ScriptTest(unittest.TestCase): | 260 class ScriptTest(unittest.TestCase): |
| 258 def MakeEmptyTempFile(self): | 261 def MakeEmptyTempFile(self): |
| 259 handle, name = tempfile.mkstemp() | 262 handle, name = tempfile.mkstemp() |
| 260 os.close(handle) | 263 os.close(handle) |
| 261 self._tmp_files.append(name) | 264 self._tmp_files.append(name) |
| 262 return name | 265 return name |
| 263 | 266 |
| 264 def MakeTempVersionFile(self): | 267 def MakeTempVersionFile(self): |
| 265 name = self.MakeEmptyTempFile() | 268 name = self.MakeEmptyTempFile() |
| 266 with open(name, "w") as f: | 269 with open(name, "w") as f: |
| 267 f.write(" // Some line...\n") | 270 f.write(" // Some line...\n") |
| 268 f.write("\n") | 271 f.write("\n") |
| 269 f.write("#define MAJOR_VERSION 3\n") | 272 f.write("#define MAJOR_VERSION 3\n") |
| 270 f.write("#define MINOR_VERSION 22\n") | 273 f.write("#define MINOR_VERSION 22\n") |
| 271 f.write("#define BUILD_NUMBER 5\n") | 274 f.write("#define BUILD_NUMBER 5\n") |
| 272 f.write("#define PATCH_LEVEL 0\n") | 275 f.write("#define PATCH_LEVEL 0\n") |
| 273 f.write(" // Some line...\n") | 276 f.write(" // Some line...\n") |
| 274 f.write("#define IS_CANDIDATE_VERSION 0\n") | 277 f.write("#define IS_CANDIDATE_VERSION 0\n") |
| 275 return name | 278 return name |
| 276 | 279 |
| 277 def MakeStep(self, step_class=Step, state=None, options=None): | 280 def MakeStep(self, step_class=Step, state=None, options=None): |
| 278 """Convenience wrapper.""" | 281 """Convenience wrapper.""" |
| 279 options = options or MakeOptions() | 282 options = options or CommonOptions(MakeOptions()) |
| 280 return MakeStep(step_class=step_class, number=0, state=state, | 283 return MakeStep(step_class=step_class, number=0, state=state, |
| 281 config=TEST_CONFIG, options=options, | 284 config=TEST_CONFIG, options=options, |
| 282 side_effect_handler=self) | 285 side_effect_handler=self) |
| 283 | 286 |
| 284 def GitMock(self, cmd, args="", pipe=True): | 287 def GitMock(self, cmd, args="", pipe=True): |
| 285 print "%s %s" % (cmd, args) | 288 print "%s %s" % (cmd, args) |
| 286 return self._git_mock.Call(args) | 289 return self._git_mock.Call(args) |
| 287 | 290 |
| 288 def LogMock(self, cmd, args=""): | 291 def LogMock(self, cmd, args=""): |
| 289 print "Log: %s %s" % (cmd, args) | 292 print "Log: %s %s" % (cmd, args) |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 | 539 |
| 537 cl_chunk = """2013-11-12: Version 3.23.2\n%s | 540 cl_chunk = """2013-11-12: Version 3.23.2\n%s |
| 538 Performance and stability improvements on all platforms.\n\n\n""" % l | 541 Performance and stability improvements on all platforms.\n\n\n""" % l |
| 539 | 542 |
| 540 cl_chunk_full = cl_chunk + cl_chunk + cl_chunk | 543 cl_chunk_full = cl_chunk + cl_chunk + cl_chunk |
| 541 TextToFile(cl_chunk_full, TEST_CONFIG[CHANGELOG_FILE]) | 544 TextToFile(cl_chunk_full, TEST_CONFIG[CHANGELOG_FILE]) |
| 542 | 545 |
| 543 cl = GetLastChangeLogEntries(TEST_CONFIG[CHANGELOG_FILE]) | 546 cl = GetLastChangeLogEntries(TEST_CONFIG[CHANGELOG_FILE]) |
| 544 self.assertEquals(cl_chunk, cl) | 547 self.assertEquals(cl_chunk, cl) |
| 545 | 548 |
| 546 def testSquashCommits(self): | 549 def _TestSquashCommits(self, change_log, expected_msg): |
| 547 TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile() | 550 TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile() |
| 548 with open(TEST_CONFIG[CHANGELOG_ENTRY_FILE], "w") as f: | 551 with open(TEST_CONFIG[CHANGELOG_ENTRY_FILE], "w") as f: |
| 549 f.write("1999-11-11: Version 3.22.5\n") | 552 f.write(change_log) |
| 550 f.write("\n") | |
| 551 f.write(" Log text 1.\n") | |
| 552 f.write(" Chromium issue 12345\n") | |
| 553 f.write("\n") | |
| 554 f.write(" Performance and stability improvements on all " | |
| 555 "platforms.\n") | |
| 556 | 553 |
| 557 self.ExpectGit([ | 554 self.ExpectGit([ |
| 558 ["diff svn/trunk hash1", "patch content"], | 555 ["diff svn/trunk hash1", "patch content"], |
| 559 ]) | 556 ]) |
| 560 | 557 |
| 561 self.MakeStep().Persist("prepare_commit_hash", "hash1") | 558 self.MakeStep().Persist("prepare_commit_hash", "hash1") |
| 562 self.MakeStep().Persist("date", "1999-11-11") | 559 self.MakeStep().Persist("date", "1999-11-11") |
| 563 | 560 |
| 564 self.MakeStep(SquashCommits).Run() | 561 self.MakeStep(SquashCommits).Run() |
| 565 | 562 self.assertEquals(FileToText(TEST_CONFIG[COMMITMSG_FILE]), expected_msg) |
| 566 msg = FileToText(TEST_CONFIG[COMMITMSG_FILE]) | |
| 567 self.assertTrue(re.search(r"Version 3\.22\.5", msg)) | |
| 568 self.assertTrue(re.search(r"Performance and stability", msg)) | |
| 569 self.assertTrue(re.search(r"Log text 1\. Chromium issue 12345", msg)) | |
| 570 self.assertFalse(re.search(r"\d+\-\d+\-\d+", msg)) | |
| 571 | 563 |
| 572 patch = FileToText(TEST_CONFIG[ PATCH_FILE]) | 564 patch = FileToText(TEST_CONFIG[ PATCH_FILE]) |
| 573 self.assertTrue(re.search(r"patch content", patch)) | 565 self.assertTrue(re.search(r"patch content", patch)) |
| 574 | 566 |
| 567 def testSquashCommitsUnformatted(self): |
| 568 change_log = """1999-11-11: Version 3.22.5 |
| 569 |
| 570 Log text 1. |
| 571 Chromium issue 12345 |
| 572 |
| 573 Performance and stability improvements on all platforms.\n""" |
| 574 commit_msg = """Version 3.22.5 |
| 575 |
| 576 Log text 1. Chromium issue 12345 |
| 577 |
| 578 Performance and stability improvements on all platforms.""" |
| 579 self._TestSquashCommits(change_log, commit_msg) |
| 580 |
| 581 def testSquashCommitsFormatted(self): |
| 582 change_log = """1999-11-11: Version 3.22.5 |
| 583 |
| 584 Long commit message that fills more than 80 characters (Chromium issue |
| 585 12345). |
| 586 |
| 587 Performance and stability improvements on all platforms.\n""" |
| 588 commit_msg = """Version 3.22.5 |
| 589 |
| 590 Long commit message that fills more than 80 characters (Chromium issue 12345). |
| 591 |
| 592 Performance and stability improvements on all platforms.""" |
| 593 self._TestSquashCommits(change_log, commit_msg) |
| 594 |
| 595 def testSquashCommitsQuotationMarks(self): |
| 596 change_log = """Line with "quotation marks".\n""" |
| 597 commit_msg = """Line with "quotation marks".""" |
| 598 self._TestSquashCommits(change_log, commit_msg) |
| 599 |
| 575 def _PushToTrunk(self, force=False, manual=False): | 600 def _PushToTrunk(self, force=False, manual=False): |
| 576 TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile() | 601 TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile() |
| 577 TEST_CONFIG[VERSION_FILE] = self.MakeTempVersionFile() | 602 TEST_CONFIG[VERSION_FILE] = self.MakeTempVersionFile() |
| 578 TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile() | 603 TEST_CONFIG[CHANGELOG_ENTRY_FILE] = self.MakeEmptyTempFile() |
| 579 TEST_CONFIG[CHANGELOG_FILE] = self.MakeEmptyTempFile() | 604 TEST_CONFIG[CHANGELOG_FILE] = self.MakeEmptyTempFile() |
| 580 if not os.path.exists(TEST_CONFIG[CHROMIUM]): | 605 if not os.path.exists(TEST_CONFIG[CHROMIUM]): |
| 581 os.makedirs(TEST_CONFIG[CHROMIUM]) | 606 os.makedirs(TEST_CONFIG[CHROMIUM]) |
| 582 TextToFile("1999-04-05: Version 3.22.4", TEST_CONFIG[CHANGELOG_FILE]) | 607 TextToFile("1999-04-05: Version 3.22.4", TEST_CONFIG[CHANGELOG_FILE]) |
| 583 TextToFile("Some line\n \"v8_revision\": \"123444\",\n some line", | 608 TextToFile("Some line\n \"v8_revision\": \"123444\",\n some line", |
| 584 TEST_CONFIG[DEPS_FILE]) | 609 TEST_CONFIG[DEPS_FILE]) |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 "LGTM", # Enter LGTM for V8 CL. | 704 "LGTM", # Enter LGTM for V8 CL. |
| 680 ]) | 705 ]) |
| 681 | 706 |
| 682 # No keyboard input in forced mode: | 707 # No keyboard input in forced mode: |
| 683 if force: | 708 if force: |
| 684 self.ExpectReadline([]) | 709 self.ExpectReadline([]) |
| 685 | 710 |
| 686 options = MakeOptions(f=force, m=manual, | 711 options = MakeOptions(f=force, m=manual, |
| 687 r="reviewer@chromium.org" if not manual else None, | 712 r="reviewer@chromium.org" if not manual else None, |
| 688 c = TEST_CONFIG[CHROMIUM]) | 713 c = TEST_CONFIG[CHROMIUM]) |
| 689 RunPushToTrunk(TEST_CONFIG, options, self) | 714 RunPushToTrunk(TEST_CONFIG, PushToTrunkOptions(options), self) |
| 690 | 715 |
| 691 deps = FileToText(TEST_CONFIG[DEPS_FILE]) | 716 deps = FileToText(TEST_CONFIG[DEPS_FILE]) |
| 692 self.assertTrue(re.search("\"v8_revision\": \"123456\"", deps)) | 717 self.assertTrue(re.search("\"v8_revision\": \"123456\"", deps)) |
| 693 | 718 |
| 694 cl = FileToText(TEST_CONFIG[CHANGELOG_FILE]) | 719 cl = FileToText(TEST_CONFIG[CHANGELOG_FILE]) |
| 695 self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl)) | 720 self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl)) |
| 696 self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl)) | 721 self.assertTrue(re.search(r" Log text 1 \(issue 321\).", cl)) |
| 697 self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl)) | 722 self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl)) |
| 698 | 723 |
| 699 # Note: The version file is on build number 5 again in the end of this test | 724 # Note: The version file is on build number 5 again in the end of this test |
| 700 # since the git command that merges to the bleeding edge branch is mocked | 725 # since the git command that merges to the bleeding edge branch is mocked |
| 701 # out. | 726 # out. |
| 702 | 727 |
| 703 def testPushToTrunkManual(self): | 728 def testPushToTrunkManual(self): |
| 704 self._PushToTrunk(manual=True) | 729 self._PushToTrunk(manual=True) |
| 705 | 730 |
| 706 def testPushToTrunkSemiAutomatic(self): | 731 def testPushToTrunkSemiAutomatic(self): |
| 707 self._PushToTrunk() | 732 self._PushToTrunk() |
| 708 | 733 |
| 709 def testPushToTrunkForced(self): | 734 def testPushToTrunkForced(self): |
| 710 self._PushToTrunk(force=True) | 735 self._PushToTrunk(force=True) |
| 711 | 736 |
| 737 def testCheckLastPushRecently(self): |
| 738 self.ExpectGit([ |
| 739 ["svn log -1 --oneline", "r101 | Text"], |
| 740 ["svn log -1 --oneline ChangeLog", "r99 | Prepare push to trunk..."], |
| 741 ]) |
| 742 |
| 743 state = {} |
| 744 self.MakeStep(FetchLatestRevision, state=state).Run() |
| 745 self.assertRaises(Exception, self.MakeStep(CheckLastPush, state=state).Run) |
| 746 |
| 712 def testAutoRoll(self): | 747 def testAutoRoll(self): |
| 713 TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile() | 748 TEST_CONFIG[DOT_GIT_LOCATION] = self.MakeEmptyTempFile() |
| 714 | 749 |
| 715 self.ExpectReadURL([ | 750 self.ExpectReadURL([ |
| 716 ["https://v8-status.appspot.com/lkgr", Exception("Network problem")], | 751 ["https://v8-status.appspot.com/lkgr", Exception("Network problem")], |
| 717 ["https://v8-status.appspot.com/lkgr", "100"], | 752 ["https://v8-status.appspot.com/lkgr", "100"], |
| 718 ]) | 753 ]) |
| 719 | 754 |
| 720 self.ExpectGit([ | 755 self.ExpectGit([ |
| 721 ["status -s -uno", ""], | 756 ["status -s -uno", ""], |
| 722 ["status -s -b -uno", "## some_branch\n"], | 757 ["status -s -b -uno", "## some_branch\n"], |
| 723 ["svn fetch", ""], | 758 ["svn fetch", ""], |
| 724 ["svn log -1 --oneline", "r101 | Text"], | 759 ["svn log -1 --oneline", "r101 | Text"], |
| 760 ["svn log -1 --oneline ChangeLog", "r65 | Prepare push to trunk..."], |
| 725 ]) | 761 ]) |
| 726 | 762 |
| 727 auto_roll.RunAutoRoll(TEST_CONFIG, MakeOptions(m=False, f=True), self) | 763 auto_roll.RunAutoRoll(TEST_CONFIG, |
| 764 AutoRollOptions(MakeOptions(m=False, f=True)), |
| 765 self) |
| 728 | 766 |
| 729 self.assertEquals("100", self.MakeStep().Restore("lkgr")) | 767 self.assertEquals("100", self.MakeStep().Restore("lkgr")) |
| 730 self.assertEquals("101", self.MakeStep().Restore("latest")) | 768 self.assertEquals("101", self.MakeStep().Restore("latest")) |
| 731 | 769 |
| 732 | 770 |
| 733 class SystemTest(unittest.TestCase): | 771 class SystemTest(unittest.TestCase): |
| 734 def testReload(self): | 772 def testReload(self): |
| 735 step = MakeStep(step_class=PrepareChangeLog, number=0, state={}, config={}, | 773 step = MakeStep(step_class=PrepareChangeLog, number=0, state={}, config={}, |
| 736 options=None, | 774 options=CommonOptions(MakeOptions()), |
| 737 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER) | 775 side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER) |
| 738 body = step.Reload( | 776 body = step.Reload( |
| 739 """------------------------------------------------------------------------ | 777 """------------------------------------------------------------------------ |
| 740 r17997 | machenbach@chromium.org | 2013-11-22 11:04:04 +0100 (...) | 6 lines | 778 r17997 | machenbach@chromium.org | 2013-11-22 11:04:04 +0100 (...) | 6 lines |
| 741 | 779 |
| 742 Prepare push to trunk. Now working on version 3.23.11. | 780 Prepare push to trunk. Now working on version 3.23.11. |
| 743 | 781 |
| 744 R=danno@chromium.org | 782 R=danno@chromium.org |
| 745 | 783 |
| 746 Review URL: https://codereview.chromium.org/83173002 | 784 Review URL: https://codereview.chromium.org/83173002 |
| 747 | 785 |
| 748 ------------------------------------------------------------------------""") | 786 ------------------------------------------------------------------------""") |
| 749 self.assertEquals( | 787 self.assertEquals( |
| 750 """Prepare push to trunk. Now working on version 3.23.11. | 788 """Prepare push to trunk. Now working on version 3.23.11. |
| 751 | 789 |
| 752 R=danno@chromium.org | 790 R=danno@chromium.org |
| 753 | 791 |
| 754 Committed: https://code.google.com/p/v8/source/detail?r=17997""", body) | 792 Committed: https://code.google.com/p/v8/source/detail?r=17997""", body) |
| OLD | NEW |