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 |