| OLD | NEW |
| 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 checkout.py.""" | 6 """Unit tests for checkout.py.""" |
| 7 | 7 |
| 8 import logging | 8 import logging |
| 9 import os | 9 import os |
| 10 import shutil | 10 import shutil |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 DEBUGGING = False | 27 DEBUGGING = False |
| 28 | 28 |
| 29 # A patch that will fail to apply. | 29 # A patch that will fail to apply. |
| 30 BAD_PATCH = ''.join( | 30 BAD_PATCH = ''.join( |
| 31 [l for l in GIT.PATCH.splitlines(True) if l.strip() != 'e']) | 31 [l for l in GIT.PATCH.splitlines(True) if l.strip() != 'e']) |
| 32 | 32 |
| 33 | 33 |
| 34 class FakeRepos(fake_repos.FakeReposBase): | 34 class FakeRepos(fake_repos.FakeReposBase): |
| 35 TEST_GIT_REPO = 'repo_1' | 35 TEST_GIT_REPO = 'repo_1' |
| 36 | 36 |
| 37 def populateSvn(self): | |
| 38 """Creates a few revisions of changes files.""" | |
| 39 subprocess2.check_call( | |
| 40 ['svn', 'checkout', self.svn_base, self.svn_checkout, '-q', | |
| 41 '--non-interactive', '--no-auth-cache', | |
| 42 '--username', self.USERS[0][0], '--password', self.USERS[0][1]]) | |
| 43 assert os.path.isdir(os.path.join(self.svn_checkout, '.svn')) | |
| 44 self._commit_svn(self._svn_tree_1()) | |
| 45 self._commit_svn(self._svn_tree_2()) | |
| 46 | |
| 47 def populateGit(self): | 37 def populateGit(self): |
| 48 """Creates a few revisions of changes files.""" | 38 """Creates a few revisions of changes files.""" |
| 49 self._commit_git(self.TEST_GIT_REPO, self._git_tree()) | 39 self._commit_git(self.TEST_GIT_REPO, self._git_tree()) |
| 50 # Fix for the remote rejected error. For more details see: | 40 # Fix for the remote rejected error. For more details see: |
| 51 # http://stackoverflow.com/questions/2816369/git-push-error-remote | 41 # http://stackoverflow.com/questions/2816369/git-push-error-remote |
| 52 subprocess2.check_output( | 42 subprocess2.check_output( |
| 53 ['git', '--git-dir', | 43 ['git', '--git-dir', |
| 54 os.path.join(self.git_root, self.TEST_GIT_REPO, '.git'), | 44 os.path.join(self.git_root, self.TEST_GIT_REPO, '.git'), |
| 55 'config', '--bool', 'core.bare', 'true']) | 45 'config', '--bool', 'core.bare', 'true']) |
| 56 | 46 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 '// found in the LICENSE file.\n' | 79 '// found in the LICENSE file.\n' |
| 90 '\n' | 80 '\n' |
| 91 '#ifndef DOM\n' | 81 '#ifndef DOM\n' |
| 92 '#define DOM\n' | 82 '#define DOM\n' |
| 93 '#pragma once\n' | 83 '#pragma once\n' |
| 94 '\n' | 84 '\n' |
| 95 '#include <string>\n' | 85 '#include <string>\n' |
| 96 '#endif\n') | 86 '#endif\n') |
| 97 return fs | 87 return fs |
| 98 | 88 |
| 99 @staticmethod | |
| 100 def _svn_tree_1(): | |
| 101 fs = {} | |
| 102 fs['trunk/origin'] = 'svn@1' | |
| 103 fs['trunk/codereview.settings'] = ( | |
| 104 '# Test data\n' | |
| 105 'bar: pouet\n') | |
| 106 fs['trunk/chrome/file.cc'] = ( | |
| 107 'a\n' | |
| 108 'bb\n' | |
| 109 'ccc\n' | |
| 110 'dd\n' | |
| 111 'e\n' | |
| 112 'ff\n' | |
| 113 'ggg\n' | |
| 114 'hh\n' | |
| 115 'i\n' | |
| 116 'jj\n' | |
| 117 'kkk\n' | |
| 118 'll\n' | |
| 119 'm\n' | |
| 120 'nn\n' | |
| 121 'ooo\n' | |
| 122 'pp\n' | |
| 123 'q\n') | |
| 124 return fs | |
| 125 | |
| 126 @classmethod | |
| 127 def _svn_tree_2(cls): | |
| 128 fs = cls._svn_tree_1() | |
| 129 fs['trunk/origin'] = 'svn@2\n' | |
| 130 fs['trunk/extra'] = 'dummy\n' | |
| 131 fs['trunk/bin_file'] = '\x00' | |
| 132 fs['trunk/chromeos/views/DOMui_menu_widget.h'] = ( | |
| 133 '// Copyright (c) 2010\n' | |
| 134 '// Use of this source code\n' | |
| 135 '// found in the LICENSE file.\n' | |
| 136 '\n' | |
| 137 '#ifndef DOM\n' | |
| 138 '#define DOM\n' | |
| 139 '#pragma once\n' | |
| 140 '\n' | |
| 141 '#include <string>\n' | |
| 142 '#endif\n') | |
| 143 return fs | |
| 144 | |
| 145 | 89 |
| 146 # pylint: disable=R0201 | 90 # pylint: disable=R0201 |
| 147 class BaseTest(fake_repos.FakeReposTestBase): | 91 class BaseTest(fake_repos.FakeReposTestBase): |
| 148 name = 'foo' | 92 name = 'foo' |
| 149 FAKE_REPOS_CLASS = FakeRepos | 93 FAKE_REPOS_CLASS = FakeRepos |
| 150 is_read_only = False | 94 is_read_only = False |
| 151 | 95 |
| 152 def setUp(self): | 96 def setUp(self): |
| 153 # Need to enforce subversion_config first. | |
| 154 checkout.SvnMixIn.svn_config_dir = os.path.join( | |
| 155 ROOT_DIR, 'subversion_config') | |
| 156 super(BaseTest, self).setUp() | 97 super(BaseTest, self).setUp() |
| 157 self._old_call = subprocess2.call | 98 self._old_call = subprocess2.call |
| 158 def redirect_call(args, **kwargs): | 99 def redirect_call(args, **kwargs): |
| 159 if not DEBUGGING: | 100 if not DEBUGGING: |
| 160 kwargs.setdefault('stdout', subprocess2.PIPE) | 101 kwargs.setdefault('stdout', subprocess2.PIPE) |
| 161 kwargs.setdefault('stderr', subprocess2.STDOUT) | 102 kwargs.setdefault('stderr', subprocess2.STDOUT) |
| 162 return self._old_call(args, **kwargs) | 103 return self._old_call(args, **kwargs) |
| 163 subprocess2.call = redirect_call | 104 subprocess2.call = redirect_call |
| 164 self.usr, self.pwd = self.FAKE_REPOS.USERS[0] | 105 self.usr, self.pwd = self.FAKE_REPOS.USERS[0] |
| 165 self.previous_log = None | 106 self.previous_log = None |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 '#define WEB\n' | 174 '#define WEB\n' |
| 234 '#pragma once\n' | 175 '#pragma once\n' |
| 235 '\n' | 176 '\n' |
| 236 '#include <string>\n' | 177 '#include <string>\n' |
| 237 '#endif\n') | 178 '#endif\n') |
| 238 #print patchset[0].get() | 179 #print patchset[0].get() |
| 239 #print fake_repos.read_tree(root) | 180 #print fake_repos.read_tree(root) |
| 240 self.assertTree(tree, root) | 181 self.assertTree(tree, root) |
| 241 | 182 |
| 242 | 183 |
| 243 class SvnBaseTest(BaseTest): | |
| 244 def setUp(self): | |
| 245 super(SvnBaseTest, self).setUp() | |
| 246 self.enabled = self.FAKE_REPOS.set_up_svn() | |
| 247 self.assertTrue(self.enabled) | |
| 248 self.svn_trunk = 'trunk' | |
| 249 self.svn_url = self.svn_base + self.svn_trunk | |
| 250 self.previous_log = self._log() | |
| 251 | |
| 252 def _log(self): | |
| 253 # Don't use the local checkout in case of caching incorrency. | |
| 254 out = subprocess2.check_output( | |
| 255 ['svn', 'log', self.svn_url, | |
| 256 '--non-interactive', '--no-auth-cache', | |
| 257 '--username', self.usr, '--password', self.pwd, | |
| 258 '--with-all-revprops', '--xml', | |
| 259 '--limit', '1']) | |
| 260 logentry = ElementTree.XML(out).find('logentry') | |
| 261 if logentry == None: | |
| 262 return {'revision': 0} | |
| 263 data = { | |
| 264 'revision': int(logentry.attrib['revision']), | |
| 265 } | |
| 266 def set_item(name): | |
| 267 item = logentry.find(name) | |
| 268 if item != None: | |
| 269 data[name] = item.text | |
| 270 set_item('author') | |
| 271 set_item('msg') | |
| 272 revprops = logentry.find('revprops') | |
| 273 if revprops != None: | |
| 274 data['revprops'] = [] | |
| 275 for prop in revprops.getiterator('property'): | |
| 276 data['revprops'].append((prop.attrib['name'], prop.text)) | |
| 277 return data | |
| 278 | |
| 279 def _check_base(self, co, root, expected): | |
| 280 read_only = isinstance(co, checkout.ReadOnlyCheckout) | |
| 281 self.assertEquals(not read_only, bool(expected)) | |
| 282 self.assertEquals(read_only, self.is_read_only) | |
| 283 if not read_only: | |
| 284 self.FAKE_REPOS.svn_dirty = True | |
| 285 | |
| 286 self.assertEquals(root, co.project_path) | |
| 287 svn_rev = co.prepare(None) | |
| 288 self.assertEquals(int, type(svn_rev)) | |
| 289 self.assertEquals(self.previous_log['revision'], svn_rev) | |
| 290 self.assertEquals('pouet', co.get_settings('bar')) | |
| 291 self.assertTree(self.get_trunk(False), root) | |
| 292 patches = self.get_patches() | |
| 293 co.apply_patch(patches) | |
| 294 self.assertEquals( | |
| 295 ['bin_file', 'chrome/file.cc', 'new_dir/subdir/new_file', 'extra'], | |
| 296 patches.filenames) | |
| 297 | |
| 298 # Verify that the patch is applied even for read only checkout. | |
| 299 self.assertTree(self.get_trunk(True), root) | |
| 300 fake_author = self.FAKE_REPOS.USERS[1][0] | |
| 301 revision = co.commit(u'msg', fake_author) | |
| 302 # Nothing changed. | |
| 303 self.assertTree(self.get_trunk(True), root) | |
| 304 | |
| 305 if read_only: | |
| 306 self.assertEquals('FAKE', revision) | |
| 307 self.assertEquals(self.previous_log['revision'], co.prepare(None)) | |
| 308 # Changes should be reverted now. | |
| 309 self.assertTree(self.get_trunk(False), root) | |
| 310 expected = self.previous_log | |
| 311 else: | |
| 312 self.assertEquals(self.previous_log['revision'] + 1, revision) | |
| 313 self.assertEquals(self.previous_log['revision'] + 1, co.prepare(None)) | |
| 314 self.assertTree(self.get_trunk(True), root) | |
| 315 expected = expected.copy() | |
| 316 expected['msg'] = 'msg' | |
| 317 expected['revision'] = self.previous_log['revision'] + 1 | |
| 318 expected.setdefault('author', fake_author) | |
| 319 | |
| 320 actual = self._log() | |
| 321 self.assertEquals(expected, actual) | |
| 322 | |
| 323 def _test_prepare(self, co): | |
| 324 self.assertEquals(1, co.prepare(1)) | |
| 325 | |
| 326 def get_trunk(self, modified): | |
| 327 tree = {} | |
| 328 subroot = 'trunk/' | |
| 329 for k, v in self.FAKE_REPOS.svn_revs[-1].iteritems(): | |
| 330 if k.startswith(subroot): | |
| 331 f = k[len(subroot):] | |
| 332 assert f not in tree | |
| 333 tree[f] = v | |
| 334 | |
| 335 if modified: | |
| 336 content_lines = tree['chrome/file.cc'].splitlines(True) | |
| 337 tree['chrome/file.cc'] = ''.join( | |
| 338 content_lines[0:5] + ['FOO!\n'] + content_lines[5:]) | |
| 339 del tree['extra'] | |
| 340 tree['new_dir/subdir/new_file'] = 'A new file\nshould exist.\n' | |
| 341 return tree | |
| 342 | |
| 343 | |
| 344 class GitBaseTest(BaseTest): | 184 class GitBaseTest(BaseTest): |
| 345 def setUp(self): | 185 def setUp(self): |
| 346 super(GitBaseTest, self).setUp() | 186 super(GitBaseTest, self).setUp() |
| 347 self.enabled = self.FAKE_REPOS.set_up_git() | 187 self.enabled = self.FAKE_REPOS.set_up_git() |
| 348 self.assertTrue(self.enabled) | 188 self.assertTrue(self.enabled) |
| 349 self.previous_log = self._log() | 189 self.previous_log = self._log() |
| 350 | 190 |
| 351 # pylint: disable=W0221 | 191 # pylint: disable=W0221 |
| 352 def _log(self, log_from_local_repo=False): | 192 def _log(self, log_from_local_repo=False): |
| 353 if log_from_local_repo: | 193 if log_from_local_repo: |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 ['git', 'diff', '--staged', '--name-status'], cwd=co.project_path) | 314 ['git', 'diff', '--staged', '--name-status'], cwd=co.project_path) |
| 475 out = sorted(out.splitlines()) | 315 out = sorted(out.splitlines()) |
| 476 expected = sorted( | 316 expected = sorted( |
| 477 [ | 317 [ |
| 478 'A\tchromeos/views/webui_menu_widget.h', | 318 'A\tchromeos/views/webui_menu_widget.h', |
| 479 'D\tchromeos/views/DOMui_menu_widget.h', | 319 'D\tchromeos/views/DOMui_menu_widget.h', |
| 480 ]) | 320 ]) |
| 481 self.assertEquals(expected, out) | 321 self.assertEquals(expected, out) |
| 482 | 322 |
| 483 | 323 |
| 484 class SvnCheckout(SvnBaseTest): | |
| 485 def _get_co(self, post_processors): | |
| 486 self.assertNotEqual(False, post_processors) | |
| 487 return checkout.SvnCheckout( | |
| 488 self.root_dir, self.name, self.usr, self.pwd, self.svn_url, | |
| 489 post_processors) | |
| 490 | |
| 491 def testAll(self): | |
| 492 expected = { | |
| 493 'author': self.FAKE_REPOS.USERS[0][0], | |
| 494 'revprops': [('realauthor', self.FAKE_REPOS.USERS[1][0])] | |
| 495 } | |
| 496 root = os.path.join(self.root_dir, self.name) | |
| 497 self._check_base(self._get_co(None), root, expected) | |
| 498 | |
| 499 def testException(self): | |
| 500 self._check_exception( | |
| 501 self._get_co(None), | |
| 502 'While running patch -p1 --forward --force --no-backup-if-mismatch;\n' | |
| 503 ' patching file chrome/file.cc\n' | |
| 504 ' Hunk #1 FAILED at 3.\n' | |
| 505 ' 1 out of 1 hunk FAILED -- saving rejects to file ' | |
| 506 'chrome/file.cc.rej\n') | |
| 507 | |
| 508 def testSvnProps(self): | |
| 509 co = self._get_co(None) | |
| 510 co.prepare(None) | |
| 511 try: | |
| 512 # svn:ignore can only be applied to directories. | |
| 513 svn_props = [('svn:ignore', 'foo')] | |
| 514 co.apply_patch( | |
| 515 [patch.FilePatchDiff('chrome/file.cc', RAW.PATCH, svn_props)]) | |
| 516 self.fail() | |
| 517 except checkout.PatchApplicationFailed, e: | |
| 518 self.assertEquals(e.filename, 'chrome/file.cc') | |
| 519 # The last line of the output depends on the svn version so we can't | |
| 520 # check it precisely | |
| 521 self.assertRegexpMatches( | |
| 522 e.status, | |
| 523 'While running svn propset svn:ignore foo chrome/file.cc ' | |
| 524 '--non-interactive;\n' | |
| 525 ' patching file chrome/file.cc\n' | |
| 526 ' svn:.*') | |
| 527 co.prepare(None) | |
| 528 svn_props = [('svn:eol-style', 'LF'), ('foo', 'bar')] | |
| 529 co.apply_patch( | |
| 530 [patch.FilePatchDiff('chrome/file.cc', RAW.PATCH, svn_props)]) | |
| 531 filepath = os.path.join(self.root_dir, self.name, 'chrome/file.cc') | |
| 532 # Manually verify the properties. | |
| 533 props = subprocess2.check_output( | |
| 534 ['svn', 'proplist', filepath], | |
| 535 cwd=self.root_dir).splitlines()[1:] | |
| 536 props = sorted(p.strip() for p in props) | |
| 537 expected_props = dict(svn_props) | |
| 538 self.assertEquals(sorted(expected_props.iterkeys()), props) | |
| 539 for k, v in expected_props.iteritems(): | |
| 540 value = subprocess2.check_output( | |
| 541 ['svn', 'propget', '--strict', k, filepath], | |
| 542 cwd=self.root_dir).strip() | |
| 543 self.assertEquals(v, value) | |
| 544 | |
| 545 def testWithRevPropsSupport(self): | |
| 546 # Add the hook that will commit in a way that removes the race condition. | |
| 547 hook = os.path.join(self.FAKE_REPOS.svn_repo, 'hooks', 'pre-commit') | |
| 548 shutil.copyfile(os.path.join(ROOT_DIR, 'sample_pre_commit_hook'), hook) | |
| 549 os.chmod(hook, 0755) | |
| 550 expected = { | |
| 551 'revprops': [('commit-bot', 'user1@example.com')], | |
| 552 } | |
| 553 root = os.path.join(self.root_dir, self.name) | |
| 554 self._check_base(self._get_co(None), root, expected) | |
| 555 | |
| 556 def testWithRevPropsSupportNotCommitBot(self): | |
| 557 # Add the hook that will commit in a way that removes the race condition. | |
| 558 hook = os.path.join(self.FAKE_REPOS.svn_repo, 'hooks', 'pre-commit') | |
| 559 shutil.copyfile(os.path.join(ROOT_DIR, 'sample_pre_commit_hook'), hook) | |
| 560 os.chmod(hook, 0755) | |
| 561 co = checkout.SvnCheckout( | |
| 562 self.root_dir, self.name, | |
| 563 self.FAKE_REPOS.USERS[1][0], self.FAKE_REPOS.USERS[1][1], | |
| 564 self.svn_url) | |
| 565 root = os.path.join(self.root_dir, self.name) | |
| 566 expected = { | |
| 567 'author': self.FAKE_REPOS.USERS[1][0], | |
| 568 } | |
| 569 self._check_base(co, root, expected) | |
| 570 | |
| 571 def testAutoProps(self): | |
| 572 co = self._get_co(None) | |
| 573 co.svn_config = checkout.SvnConfig( | |
| 574 os.path.join(ROOT_DIR, 'subversion_config')) | |
| 575 co.prepare(None) | |
| 576 patches = self.get_patches() | |
| 577 co.apply_patch(patches) | |
| 578 self.assertEquals( | |
| 579 ['bin_file', 'chrome/file.cc', 'new_dir/subdir/new_file', 'extra'], | |
| 580 patches.filenames) | |
| 581 # *.txt = svn:eol-style=LF in subversion_config/config. | |
| 582 out = subprocess2.check_output( | |
| 583 ['svn', 'pget', 'svn:eol-style', 'chrome/file.cc'], | |
| 584 cwd=co.project_path) | |
| 585 self.assertEquals('LF\n', out) | |
| 586 | |
| 587 def testProcess(self): | |
| 588 self._test_process(self._get_co) | |
| 589 | |
| 590 def testPrepare(self): | |
| 591 self._test_prepare(self._get_co(None)) | |
| 592 | |
| 593 def testMove(self): | |
| 594 co = self._get_co(None) | |
| 595 self._check_move(co) | |
| 596 out = subprocess2.check_output( | |
| 597 ['svn', 'status'], cwd=co.project_path) | |
| 598 out = sorted(out.splitlines()) | |
| 599 expected = sorted( | |
| 600 [ | |
| 601 'A + chromeos/views/webui_menu_widget.h', | |
| 602 'D chromeos/views/DOMui_menu_widget.h', | |
| 603 ]) | |
| 604 self.assertEquals(expected, out) | |
| 605 # Make sure ancestry is what is expected; | |
| 606 env = os.environ.copy() | |
| 607 env['LANGUAGE'] = 'en_US.UTF-8' | |
| 608 out = subprocess2.check_output( | |
| 609 ['svn', 'info', 'chromeos/views/webui_menu_widget.h'], | |
| 610 cwd=co.project_path, | |
| 611 env=env) | |
| 612 values = dict(l.split(': ', 1) for l in out.splitlines() if l) | |
| 613 expected = { | |
| 614 # checksum seems to vary with svn version so we can't check it | |
| 615 #'Checksum': '65837bb3da662c8fa88a4a50940ea7c6', | |
| 616 'Copied From Rev': '2', | |
| 617 'Copied From URL': | |
| 618 '%strunk/chromeos/views/DOMui_menu_widget.h' % self.svn_base, | |
| 619 'Name': 'webui_menu_widget.h', | |
| 620 'Node Kind': 'file', | |
| 621 'Path': 'chromeos/views/webui_menu_widget.h', | |
| 622 'Repository Root': '%s' % self.svn_base.rstrip('/'), | |
| 623 'Revision': '2', | |
| 624 'Schedule': 'add', | |
| 625 'URL': '%strunk/chromeos/views/webui_menu_widget.h' % self.svn_base, | |
| 626 } | |
| 627 for key in expected: | |
| 628 self.assertIn(key, values) | |
| 629 self.assertEquals(expected[key], values[key]) | |
| 630 | |
| 631 | |
| 632 class RawCheckout(SvnBaseTest): | |
| 633 def setUp(self): | |
| 634 super(RawCheckout, self).setUp() | |
| 635 # Use a svn checkout as the base. | |
| 636 self.base_co = checkout.SvnCheckout( | |
| 637 self.root_dir, self.name, None, None, self.svn_url) | |
| 638 self.base_co.prepare(None) | |
| 639 | |
| 640 def _get_co(self, post_processors): | |
| 641 self.assertNotEqual(False, post_processors) | |
| 642 return checkout.RawCheckout(self.root_dir, self.name, post_processors) | |
| 643 | |
| 644 def testAll(self): | |
| 645 # Can't use self._check_base() since it's too different. | |
| 646 root = os.path.join(self.root_dir, self.name) | |
| 647 co = self._get_co(None) | |
| 648 | |
| 649 # A copy of BaseTest._check_base() | |
| 650 self.assertEquals(root, co.project_path) | |
| 651 self.assertEquals(None, co.prepare(None)) | |
| 652 self.assertEquals('pouet', co.get_settings('bar')) | |
| 653 self.assertTree(self.get_trunk(False), root) | |
| 654 patches = self.get_patches() | |
| 655 co.apply_patch(patches) | |
| 656 self.assertEquals( | |
| 657 ['bin_file', 'chrome/file.cc', 'new_dir/subdir/new_file', 'extra'], | |
| 658 patches.filenames) | |
| 659 | |
| 660 # Verify that the patch is applied even for read only checkout. | |
| 661 self.assertTree(self.get_trunk(True), root) | |
| 662 try: | |
| 663 co.commit(u'msg', self.FAKE_REPOS.USERS[1][0]) | |
| 664 self.fail() | |
| 665 except NotImplementedError: | |
| 666 pass | |
| 667 self.assertTree(self.get_trunk(True), root) | |
| 668 # Verify that prepare() is a no-op. | |
| 669 self.assertEquals(None, co.prepare(None)) | |
| 670 self.assertTree(self.get_trunk(True), root) | |
| 671 | |
| 672 def testException(self): | |
| 673 self._check_exception( | |
| 674 self._get_co(None), | |
| 675 'While running patch -u --binary -p1;\n' | |
| 676 ' patching file chrome/file.cc\n' | |
| 677 ' Hunk #1 FAILED at 3.\n' | |
| 678 ' 1 out of 1 hunk FAILED -- saving rejects to file ' | |
| 679 'chrome/file.cc.rej\n') | |
| 680 | |
| 681 def testProcess(self): | |
| 682 self._test_process(self._get_co) | |
| 683 | |
| 684 def testPrepare(self): | |
| 685 # RawCheckout doesn't support prepare() but emulate it. | |
| 686 co = self._get_co(None) | |
| 687 revs = [1] | |
| 688 def prepare(asked): | |
| 689 self.assertEquals(1, asked) | |
| 690 return revs.pop(0) | |
| 691 co.prepare = prepare | |
| 692 self._test_prepare(co) | |
| 693 self.assertEquals([], revs) | |
| 694 | |
| 695 def testMove(self): | |
| 696 self._check_move(self._get_co(None)) | |
| 697 | |
| 698 | |
| 699 class ReadOnlyCheckout(SvnBaseTest): | |
| 700 # Use SvnCheckout as the backed since it support read-only checkouts too. | |
| 701 is_read_only = True | |
| 702 | |
| 703 def _get_co(self, post_processors): | |
| 704 self.assertNotEqual(False, post_processors) | |
| 705 return checkout.ReadOnlyCheckout( | |
| 706 checkout.SvnCheckout( | |
| 707 self.root_dir, self.name, None, None, self.svn_url, None), | |
| 708 post_processors) | |
| 709 | |
| 710 def testAll(self): | |
| 711 root = os.path.join(self.root_dir, self.name) | |
| 712 self._check_base(self._get_co(None), root, None) | |
| 713 | |
| 714 def testException(self): | |
| 715 self._check_exception( | |
| 716 self._get_co(None), | |
| 717 'While running patch -p1 --forward --force --no-backup-if-mismatch;\n' | |
| 718 ' patching file chrome/file.cc\n' | |
| 719 ' Hunk #1 FAILED at 3.\n' | |
| 720 ' 1 out of 1 hunk FAILED -- saving rejects to file ' | |
| 721 'chrome/file.cc.rej\n') | |
| 722 | |
| 723 def testProcess(self): | |
| 724 self._test_process(self._get_co) | |
| 725 | |
| 726 def testPrepare(self): | |
| 727 self._test_prepare(self._get_co(None)) | |
| 728 | |
| 729 def testMove(self): | |
| 730 self._check_move(self._get_co(None)) | |
| 731 | |
| 732 | |
| 733 if __name__ == '__main__': | 324 if __name__ == '__main__': |
| 734 if '-v' in sys.argv: | 325 if '-v' in sys.argv: |
| 735 DEBUGGING = True | 326 DEBUGGING = True |
| 736 logging.basicConfig( | 327 logging.basicConfig( |
| 737 level=logging.DEBUG, | 328 level=logging.DEBUG, |
| 738 format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s') | 329 format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s') |
| 739 else: | 330 else: |
| 740 logging.basicConfig( | 331 logging.basicConfig( |
| 741 level=logging.ERROR, | 332 level=logging.ERROR, |
| 742 format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s') | 333 format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s') |
| 743 unittest.main() | 334 unittest.main() |
| OLD | NEW |