Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: tests/pending_manager_test.py

Issue 23483019: Changes to support One-Click Revert in Commit Queue (Closed) Base URL: https://src.chromium.org/chrome/trunk/tools/commit-queue/
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tests/mocks.py ('k') | tests/project_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Unit tests for pending_manager.py.""" 6 """Unit tests for pending_manager.py."""
7 7
8 import logging 8 import logging
9 import os 9 import os
10 import re 10 import re
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 try: 75 try:
76 pc.load(filename) 76 pc.load(filename)
77 self.assertEqual(pc.queue.pending_commits, {}) 77 self.assertEqual(pc.queue.pending_commits, {})
78 pc.save(filename) 78 pc.save(filename)
79 self.assertEqual(trim(empty), trim(read(filename))) 79 self.assertEqual(trim(empty), trim(read(filename)))
80 finally: 80 finally:
81 os.remove(filename) 81 os.remove(filename)
82 if os.path.exists(filename + '.old'): 82 if os.path.exists(filename + '.old'):
83 os.remove(filename + '.old') 83 os.remove(filename + '.old')
84 84
85 def _get_pc(self, verifiers_no_patch, verifiers): 85 def _get_pc(self, verifiers_no_patch, verifiers,
86 revert_verifiers_no_patch=None, revert_verifiers=None):
86 return pending_manager.PendingManager( 87 return pending_manager.PendingManager(
87 self.context, verifiers_no_patch, verifiers) 88 self.context, verifiers_no_patch, verifiers, revert_verifiers_no_patch,
89 revert_verifiers)
88 90
89 def _check_standard_verification(self, pc, success, defered): 91 def _check_standard_verification(self, pc, success, defered):
90 """Verifies the checkout and rietveld calls.""" 92 """Verifies the checkout and rietveld calls."""
91 pc.scan_results() 93 pc.scan_results()
92 self.assertEqual(len(pc.queue.iterate()), 0) 94 self.assertEqual(len(pc.queue.iterate()), 0)
93 issue = 31337 95 issue = 31337
94 if pc.verifiers: 96 if pc.verifiers:
95 if success: 97 if success:
96 self.context.checkout.check_calls( 98 self.context.checkout.check_calls(
97 [ 'prepare(None)', 99 [ 'prepare(None)',
98 'apply_patch(%r)' % (self.context.rietveld.patchsets[0],), 100 'apply_patch(%r, revert=False)' % (
101 self.context.rietveld.patchsets[0]),
99 'prepare(None)', # Will sync to HEAD/124. 102 'prepare(None)', # Will sync to HEAD/124.
100 'apply_patch(%r)' % (self.context.rietveld.patchsets[1],), 103 'apply_patch(%r, revert=False)' % (
104 self.context.rietveld.patchsets[1]),
101 ( 105 (
102 "commit(u'foo\\n\\n" 106 "commit(u'foo\\n\\n"
103 "Review URL: http://nowhere/%d', " 107 "Review URL: http://nowhere/%d', "
104 "u'author@example.com')") % issue]) 108 "u'author@example.com')") % issue])
105 self.context.rietveld.check_calls( 109 self.context.rietveld.check_calls(
106 [ _try_comment(), 110 [ _try_comment(),
107 'close_issue(%d)' % issue, 111 'close_issue(%d)' % issue,
108 "update_description(%d, u'foo')" % issue, 112 "update_description(%d, u'foo')" % issue,
109 "add_comment(%d, 'Change committed as 125')" % issue]) 113 "add_comment(%d, 'Change committed as 125')" % issue])
110 else: 114 else:
111 self.context.checkout.check_calls( 115 self.context.checkout.check_calls(
112 [ 'prepare(None)', 116 [ 'prepare(None)',
113 'apply_patch(%r)' % (self.context.rietveld.patchsets[0],)]) 117 'apply_patch(%r, revert=False)' % (
118 self.context.rietveld.patchsets[0])])
114 self.context.rietveld.check_calls( 119 self.context.rietveld.check_calls(
115 [ _try_comment(), 120 [ _try_comment(),
116 "set_flag(%d, 1, 'commit', 'False')" % issue, 121 "set_flag(%d, 1, 'commit', 'False')" % issue,
117 "add_comment(%d, %r)" % (issue, pc.FAILED_NO_MESSAGE)]) 122 "add_comment(%d, %r)" % (issue, pc.FAILED_NO_MESSAGE)])
118 else: 123 else:
119 if success: 124 if success:
120 self.context.checkout.check_calls( 125 self.context.checkout.check_calls(
121 self._prepare_apply_commit(0, issue)) 126 self._prepare_apply_commit(0, issue))
122 self.context.rietveld.check_calls( 127 self.context.rietveld.check_calls(
123 [ _try_comment(), 128 [ _try_comment(),
124 'close_issue(%d)' % issue, 129 'close_issue(%d)' % issue,
125 "update_description(%d, u'foo')" % issue, 130 "update_description(%d, u'foo')" % issue,
126 "add_comment(%d, 'Change committed as 125')" % issue]) 131 "add_comment(%d, 'Change committed as 125')" % issue])
127 else: 132 else:
128 # checkout is never touched in that case. 133 # checkout is never touched in that case.
129 self.context.checkout.check_calls([]) 134 self.context.checkout.check_calls([])
130 if defered: 135 if defered:
131 self.context.rietveld.check_calls( 136 self.context.rietveld.check_calls(
132 [ _try_comment(), 137 [ _try_comment(),
133 "set_flag(%d, 1, 'commit', 'False')" % issue, 138 "set_flag(%d, 1, 'commit', 'False')" % issue,
134 "add_comment(%d, %r)" % (issue, pc.FAILED_NO_MESSAGE)]) 139 "add_comment(%d, %r)" % (issue, pc.FAILED_NO_MESSAGE)])
135 else: 140 else:
136 self.context.rietveld.check_calls( 141 self.context.rietveld.check_calls(
137 [ "set_flag(%d, 1, 'commit', 'False')" % issue, 142 [ "set_flag(%d, 1, 'commit', 'False')" % issue,
138 "add_comment(%d, %r)" % (issue, pc.FAILED_NO_MESSAGE)]) 143 "add_comment(%d, %r)" % (issue, pc.FAILED_NO_MESSAGE)])
139 144
140 def _prepare_apply_commit(self, index, issue, server_hooks_missing=False): 145 def _prepare_apply_commit(self, index, issue, server_hooks_missing=False,
146 revert=False):
141 """Returns a frequent sequence of action happening on the Checkout object. 147 """Returns a frequent sequence of action happening on the Checkout object.
142 148
143 The list returned by this function should be used as an argument to 149 The list returned by this function should be used as an argument to
144 self.context.checkout.check_calls(). 150 self.context.checkout.check_calls().
145 """ 151 """
146 seq = [ 152 seq = [
147 # Reverts any previous modification or checkout the tree if it was not 153 # Reverts any previous modification or checkout the tree if it was not
148 # present. 154 # present.
149 'prepare(None)', 155 'prepare(None)',
150 # Applies the requested PatchSet. 156 # Applies the requested PatchSet.
151 'apply_patch(%r)' % self.context.rietveld.patchsets[index], 157 'apply_patch(%r, revert=%s)' % (self.context.rietveld.patchsets[index],
158 revert),
152 ] 159 ]
153 # Commits the patch. 160 # Commits the patch.
154 author_and_reviewer = '' 161 author_and_reviewer = ''
155 if server_hooks_missing: 162 if server_hooks_missing:
156 author_and_reviewer = ( 163 author_and_reviewer = (
157 '\\n\\nR=rev@example.com\\n\\nAuthor: author@example.com') 164 '\\n\\nR=rev@example.com\\n\\nAuthor: author@example.com')
165 desc = 'foo'
166 if revert:
167 desc = 'Revert of: ' + desc
158 commit_message = ( 168 commit_message = (
159 "commit(u'foo%s\\n\\n" 169 "commit(u'%s%s\\n\\n"
160 "Review URL: http://nowhere/%d', " 170 "Review URL: http://nowhere/%d', "
161 "u'author@example.com')") % (author_and_reviewer, issue) 171 "u'author@example.com')") % (desc, author_and_reviewer, issue)
162 seq.append(commit_message) 172 seq.append(commit_message)
163 173
164 return seq 174 return seq
165 175
166 def testNoVerification(self): 176 def testNoVerification(self):
167 try: 177 try:
168 # Need at least one verification. 178 # Need at least one verification.
169 self._get_pc([], []) 179 self._get_pc([], [])
170 self.fail() 180 self.fail()
171 except AssertionError: 181 except AssertionError:
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 pc.look_for_new_pending_commit() 261 pc.look_for_new_pending_commit()
252 self.assertEqual(len(pc.queue.iterate()), 1) 262 self.assertEqual(len(pc.queue.iterate()), 1)
253 commit = pc.queue.get(issue) 263 commit = pc.queue.get(issue)
254 self.assertEqual(len(commit.verifications), 0) 264 self.assertEqual(len(commit.verifications), 0)
255 pc.process_new_pending_commit() 265 pc.process_new_pending_commit()
256 self.assertEqual([], pc.queue.iterate()) 266 self.assertEqual([], pc.queue.iterate())
257 pc.update_status() 267 pc.update_status()
258 self.assertEqual([], pc.queue.iterate()) 268 self.assertEqual([], pc.queue.iterate())
259 self.context.checkout.check_calls( 269 self.context.checkout.check_calls(
260 [ 'prepare(None)', 270 [ 'prepare(None)',
261 'apply_patch(%r)' % (self.context.rietveld.patchsets[0],), 271 'apply_patch(%r, revert=False)' % (
272 self.context.rietveld.patchsets[0]),
262 ]) 273 ])
263 self.context.rietveld.check_calls( 274 self.context.rietveld.check_calls(
264 [ _try_comment(), 275 [ _try_comment(),
265 "add_comment(%d, %r)" % (issue, pc.FAILED_NO_MESSAGE), 276 "add_comment(%d, %r)" % (issue, pc.FAILED_NO_MESSAGE),
266 ]) 277 ])
267 self.context.status.check_names(['initial', 'abort']) 278 self.context.status.check_names(['initial', 'abort'])
268 279
269 def _check_defer_1(self, pc, result): 280 def _check_defer_1(self, pc, result):
270 issue = 31337 281 issue = 31337
271 self.assertEqual(len(pc.queue.iterate()), 0) 282 self.assertEqual(len(pc.queue.iterate()), 0)
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 [r'^%s(.*)$' % re.escape(r'http://example.com/')]), 439 [r'^%s(.*)$' % re.escape(r'http://example.com/')]),
429 ] 440 ]
430 pc = self._get_pc([], verifiers) 441 pc = self._get_pc([], verifiers)
431 pc.context.rietveld.issues[issue]['base_url'] = 'http://example.com/sub/dir' 442 pc.context.rietveld.issues[issue]['base_url'] = 'http://example.com/sub/dir'
432 pc.look_for_new_pending_commit() 443 pc.look_for_new_pending_commit()
433 self.assertEqual(1, len(pc.queue.iterate())) 444 self.assertEqual(1, len(pc.queue.iterate()))
434 pc.process_new_pending_commit() 445 pc.process_new_pending_commit()
435 self.assertEqual('sub/dir', pc.queue.get(issue).relpath) 446 self.assertEqual('sub/dir', pc.queue.get(issue).relpath)
436 self.context.checkout.check_calls( 447 self.context.checkout.check_calls(
437 [ 'prepare(None)', 448 [ 'prepare(None)',
438 'apply_patch(%r)' % (self.context.rietveld.patchsets[0],)]) 449 'apply_patch(%r, revert=False)' % (
450 self.context.rietveld.patchsets[0])])
439 pc.update_status() 451 pc.update_status()
440 self.context.checkout.check_calls([]) 452 self.context.checkout.check_calls([])
441 pc.scan_results() 453 pc.scan_results()
442 self.context.checkout.check_calls( 454 self.context.checkout.check_calls(
443 # Will sync to HEAD, 124. 455 # Will sync to HEAD, 124.
444 self._prepare_apply_commit(1, issue)) 456 self._prepare_apply_commit(1, issue))
445 self.context.rietveld.check_calls( 457 self.context.rietveld.check_calls(
446 [ _try_comment(), 458 [ _try_comment(),
447 'close_issue(%d)' % issue, 459 'close_issue(%d)' % issue,
448 "update_description(%d, u'foo')" % issue, 460 "update_description(%d, u'foo')" % issue,
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 self._prepare_apply_commit(next_item + 2, issue)) 535 self._prepare_apply_commit(next_item + 2, issue))
524 self.context.rietveld.check_calls( 536 self.context.rietveld.check_calls(
525 [ 'close_issue(%d)' % (next_item + 1), 537 [ 'close_issue(%d)' % (next_item + 1),
526 "update_description(%d, u'foo')" % (next_item + 1), 538 "update_description(%d, u'foo')" % (next_item + 1),
527 "add_comment(%d, 'Change committed as 125')" % (next_item + 1), 539 "add_comment(%d, 'Change committed as 125')" % (next_item + 1),
528 'close_issue(%d)' % issue, 540 'close_issue(%d)' % issue,
529 "update_description(%d, u'foo')" % issue, 541 "update_description(%d, u'foo')" % issue,
530 "add_comment(%d, 'Change committed as 125')" % issue]) 542 "add_comment(%d, 'Change committed as 125')" % issue])
531 self.context.status.check_names(['why not', 'commit'] * 2) 543 self.context.status.check_names(['why not', 'commit'] * 2)
532 544
545 def testRevertBurst(self):
546 issue = 31337
547 pc = self._get_pc(
548 verifiers_no_patch=[fake.FakeVerifier(base.SUCCEEDED)],
549 verifiers=[],
550 revert_verifiers_no_patch=[fake.FakeVerifier(base.SUCCEEDED)],
551 revert_verifiers=[])
552 self.assertEqual(4, pc.MAX_COMMIT_BURST)
553 timestamp = [1]
554 self.mock(time, 'time', lambda: timestamp[-1])
555 # Set test issues to 'revert' issues, 31337 will still be a regular commit.
556 for i in range(pc.MAX_COMMIT_BURST + 2):
557 rietveld_issue = self.context.rietveld.issues[issue].copy()
558 rietveld_issue['closed'] = True
559 rietveld_issue['commit'] = False
560 rietveld_issue['revert'] = True
561 rietveld_issue['reverted_by'] = 'xyz@example.com'
562 self.context.rietveld.issues[i] = rietveld_issue
563 self.context.rietveld.issues[i]['issue'] = i
564 pc.look_for_new_pending_commit()
565 self.assertEqual(len(pc.queue.iterate()), pc.MAX_COMMIT_BURST + 3)
566 pc.process_new_pending_commit()
567 pc.update_status()
568 pc.scan_results()
569 self.context.checkout.check_calls(
570 self._prepare_apply_commit(0, 0, False, True) +
571 self._prepare_apply_commit(1, 1, False, True) +
572 self._prepare_apply_commit(2, 2, False, True) +
573 self._prepare_apply_commit(3, 3, False, True))
574 self.context.rietveld.check_calls(
575 [ _try_comment(0),
576 _try_comment(1),
577 _try_comment(2),
578 _try_comment(3),
579 _try_comment(4),
580 _try_comment(5),
581 _try_comment(),
582 'open_issue(0)',
583 "update_description(0, u'foo')",
584 "add_comment(0, 'Change reverted as 125')",
585 'open_issue(1)',
586 "update_description(1, u'foo')",
587 "add_comment(1, 'Change reverted as 125')",
588 'open_issue(2)',
589 "update_description(2, u'foo')",
590 "add_comment(2, 'Change reverted as 125')",
591 'open_issue(3)',
592 "update_description(3, u'foo')",
593 "add_comment(3, 'Change reverted as 125')",
594 ])
595 self.assertEqual(3, len(pc.queue.iterate()))
596 total = pc.MAX_COMMIT_BURST + 3
597 self.context.status.check_names(['initial'] * total +
598 (['why not', 'commit'] *
599 pc.MAX_COMMIT_BURST) +
600 ['why not'] * 3)
601
602 # Dry run.
603 pc.scan_results()
604 self.context.checkout.check_calls([])
605 self.context.rietveld.check_calls([])
606 self.context.status.check_names(['why not'] * 3)
607
608 # Remove one item from the burst.
609 pc.recent_commit_timestamps.pop()
610 pc.scan_results()
611 next_item = pc.MAX_COMMIT_BURST
612 self.context.checkout.check_calls(
613 self._prepare_apply_commit(next_item, next_item, False, True))
614 self.context.rietveld.check_calls(
615 [ 'open_issue(%d)' % next_item,
616 "update_description(%d, u'foo')" % next_item,
617 "add_comment(%d, 'Change reverted as 125')" % next_item,
618 ])
619 self.context.status.check_names(['why not', 'commit'] + ['why not'] * 2)
620 # After a delay, must flush the queue.
621 timestamp.append(timestamp[-1] + pc.COMMIT_BURST_DELAY + 1)
622 pc.scan_results()
623 self.context.checkout.check_calls(
624 self._prepare_apply_commit(next_item + 1, next_item + 1, False, True) +
625 self._prepare_apply_commit(next_item + 2, issue, False, False))
626 self.context.rietveld.check_calls(
627 [ 'open_issue(%d)' % (next_item + 1),
628 "update_description(%d, u'foo')" % (next_item + 1),
629 "add_comment(%d, 'Change reverted as 125')" % (next_item + 1),
630 'close_issue(%d)' % issue,
631 "update_description(%d, u'foo')" % issue,
632 "add_comment(%d, 'Change committed as 125')" % issue])
633 self.context.status.check_names(['why not', 'commit'] * 2)
634
533 def testIgnored(self): 635 def testIgnored(self):
534 issue = 31337 636 issue = 31337
535 verifiers = [ 637 verifiers = [
536 project_base.ProjectBaseUrlVerifier( 638 project_base.ProjectBaseUrlVerifier(
537 [r'^%s(.*)$' % re.escape(r'http://example.com/')]), 639 [r'^%s(.*)$' % re.escape(r'http://example.com/')]),
538 ] 640 ]
539 pc = self._get_pc(verifiers, []) 641 pc = self._get_pc(verifiers, [])
540 pc.context.rietveld.issues[issue]['base_url'] = 'http://unrelated.com/sub' 642 pc.context.rietveld.issues[issue]['base_url'] = 'http://unrelated.com/sub'
541 pc.look_for_new_pending_commit() 643 pc.look_for_new_pending_commit()
542 pc.process_new_pending_commit() 644 pc.process_new_pending_commit()
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 self.context.checkout.check_calls( 822 self.context.checkout.check_calls(
721 self._prepare_apply_commit(0, issue)) 823 self._prepare_apply_commit(0, issue))
722 824
723 825
724 if __name__ == '__main__': 826 if __name__ == '__main__':
725 logging.basicConfig( 827 logging.basicConfig(
726 level=[logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG][ 828 level=[logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG][
727 min(sys.argv.count('-v'), 3)], 829 min(sys.argv.count('-v'), 3)],
728 format='%(levelname)5s %(module)15s(%(lineno)3d): %(message)s') 830 format='%(levelname)5s %(module)15s(%(lineno)3d): %(message)s')
729 unittest.main() 831 unittest.main()
OLDNEW
« no previous file with comments | « tests/mocks.py ('k') | tests/project_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698