OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2010 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 """Simplify unit tests based on pymox.""" | 6 """Simplify unit tests based on pymox.""" |
7 | 7 |
8 import __builtin__ | |
9 import os | 8 import os |
10 import random | 9 import random |
11 import shutil | 10 import shutil |
12 import string | 11 import string |
13 import StringIO | 12 import StringIO |
14 import subprocess | 13 import subprocess |
15 import sys | 14 import sys |
16 | 15 |
17 sys.path.append(os.path.dirname(os.path.dirname(__file__))) | 16 sys.path.append(os.path.dirname(os.path.dirname(__file__))) |
18 from third_party.pymox import mox | 17 from third_party.pymox import mox |
(...skipping 15 matching lines...) Expand all Loading... |
34 to use SuperMoxTestBase instead.""" | 33 to use SuperMoxTestBase instead.""" |
35 # Backup the separator in case it gets mocked | 34 # Backup the separator in case it gets mocked |
36 _OS_SEP = os.sep | 35 _OS_SEP = os.sep |
37 _RANDOM_CHOICE = random.choice | 36 _RANDOM_CHOICE = random.choice |
38 _RANDOM_RANDINT = random.randint | 37 _RANDOM_RANDINT = random.randint |
39 _STRING_LETTERS = string.letters | 38 _STRING_LETTERS = string.letters |
40 | 39 |
41 ## Some utilities for generating arbitrary arguments. | 40 ## Some utilities for generating arbitrary arguments. |
42 def String(self, max_length): | 41 def String(self, max_length): |
43 return ''.join([self._RANDOM_CHOICE(self._STRING_LETTERS) | 42 return ''.join([self._RANDOM_CHOICE(self._STRING_LETTERS) |
44 for x in xrange(self._RANDOM_RANDINT(1, max_length))]) | 43 for _ in xrange(self._RANDOM_RANDINT(1, max_length))]) |
45 | 44 |
46 def Strings(self, max_arg_count, max_arg_length): | 45 def Strings(self, max_arg_count, max_arg_length): |
47 return [self.String(max_arg_length) for x in xrange(max_arg_count)] | 46 return [self.String(max_arg_length) for _ in xrange(max_arg_count)] |
48 | 47 |
49 def Args(self, max_arg_count=8, max_arg_length=16): | 48 def Args(self, max_arg_count=8, max_arg_length=16): |
50 return self.Strings(max_arg_count, | 49 return self.Strings(max_arg_count, |
51 self._RANDOM_RANDINT(1, max_arg_length)) | 50 self._RANDOM_RANDINT(1, max_arg_length)) |
52 | 51 |
53 def _DirElts(self, max_elt_count=4, max_elt_length=8): | 52 def _DirElts(self, max_elt_count=4, max_elt_length=8): |
54 return self._OS_SEP.join(self.Strings(max_elt_count, max_elt_length)) | 53 return self._OS_SEP.join(self.Strings(max_elt_count, max_elt_length)) |
55 | 54 |
56 def Dir(self, max_elt_count=4, max_elt_length=8): | 55 def Dir(self, max_elt_count=4, max_elt_length=8): |
57 return (self._RANDOM_CHOICE((self._OS_SEP, '')) + | 56 return (self._RANDOM_CHOICE((self._OS_SEP, '')) + |
(...skipping 10 matching lines...) Expand all Loading... |
68 def compareMembers(self, obj, members): | 67 def compareMembers(self, obj, members): |
69 """If you add a member, be sure to add the relevant test!""" | 68 """If you add a member, be sure to add the relevant test!""" |
70 # Skip over members starting with '_' since they are usually not meant to | 69 # Skip over members starting with '_' since they are usually not meant to |
71 # be for public use. | 70 # be for public use. |
72 actual_members = [x for x in sorted(dir(obj)) | 71 actual_members = [x for x in sorted(dir(obj)) |
73 if not x.startswith('_')] | 72 if not x.startswith('_')] |
74 expected_members = sorted(members) | 73 expected_members = sorted(members) |
75 if actual_members != expected_members: | 74 if actual_members != expected_members: |
76 diff = ([i for i in actual_members if i not in expected_members] + | 75 diff = ([i for i in actual_members if i not in expected_members] + |
77 [i for i in expected_members if i not in actual_members]) | 76 [i for i in expected_members if i not in actual_members]) |
78 print>>sys.stderr, diff | 77 print >> sys.stderr, diff |
| 78 # pylint: disable=E1101 |
79 self.assertEqual(actual_members, expected_members) | 79 self.assertEqual(actual_members, expected_members) |
80 | 80 |
81 def setUp(self): | 81 def setUp(self): |
82 self.root_dir = self.Dir() | 82 self.root_dir = self.Dir() |
83 self.args = self.Args() | 83 self.args = self.Args() |
84 self.relpath = self.String(200) | 84 self.relpath = self.String(200) |
85 | 85 |
86 def tearDown(self): | 86 def tearDown(self): |
87 pass | 87 pass |
88 | 88 |
89 | 89 |
90 class StdoutCheck(object): | 90 class StdoutCheck(object): |
91 def setUp(self): | 91 def setUp(self): |
92 # Override the mock with a StringIO, it's much less painful to test. | 92 # Override the mock with a StringIO, it's much less painful to test. |
93 self._old_stdout = sys.stdout | 93 self._old_stdout = sys.stdout |
94 sys.stdout = StringIO.StringIO() | 94 sys.stdout = StringIO.StringIO() |
95 sys.stdout.flush = lambda: None | 95 sys.stdout.flush = lambda: None |
96 | 96 |
97 def tearDown(self): | 97 def tearDown(self): |
98 try: | 98 try: |
99 # If sys.stdout was used, self.checkstdout() must be called. | 99 # If sys.stdout was used, self.checkstdout() must be called. |
| 100 # pylint: disable=E1101 |
100 self.assertEquals('', sys.stdout.getvalue()) | 101 self.assertEquals('', sys.stdout.getvalue()) |
101 except AttributeError: | 102 except AttributeError: |
102 pass | 103 pass |
103 sys.stdout = self._old_stdout | 104 sys.stdout = self._old_stdout |
104 | 105 |
105 def checkstdout(self, expected): | 106 def checkstdout(self, expected): |
106 value = sys.stdout.getvalue() | 107 value = sys.stdout.getvalue() |
107 sys.stdout.close() | 108 sys.stdout.close() |
| 109 # pylint: disable=E1101 |
108 self.assertEquals(expected, value) | 110 self.assertEquals(expected, value) |
109 | 111 |
110 | 112 |
111 class SuperMoxTestBase(TestCaseUtils, StdoutCheck, mox.MoxTestBase): | 113 class SuperMoxTestBase(TestCaseUtils, StdoutCheck, mox.MoxTestBase): |
112 def setUp(self): | 114 def setUp(self): |
113 """Patch a few functions with know side-effects.""" | 115 """Patch a few functions with know side-effects.""" |
114 TestCaseUtils.setUp(self) | 116 TestCaseUtils.setUp(self) |
115 mox.MoxTestBase.setUp(self) | 117 mox.MoxTestBase.setUp(self) |
116 #self.mox.StubOutWithMock(__builtin__, 'open') | |
117 os_to_mock = ('chdir', 'chown', 'close', 'closerange', 'dup', 'dup2', | 118 os_to_mock = ('chdir', 'chown', 'close', 'closerange', 'dup', 'dup2', |
118 'fchdir', 'fchmod', 'fchown', 'fdopen', 'getcwd', 'getpid', 'lseek', | 119 'fchdir', 'fchmod', 'fchown', 'fdopen', 'getcwd', 'getpid', 'lseek', |
119 'makedirs', 'mkdir', 'open', 'popen', 'popen2', 'popen3', 'popen4', | 120 'makedirs', 'mkdir', 'open', 'popen', 'popen2', 'popen3', 'popen4', |
120 'read', 'remove', 'removedirs', 'rename', 'renames', 'rmdir', 'symlink', | 121 'read', 'remove', 'removedirs', 'rename', 'renames', 'rmdir', 'symlink', |
121 'system', 'tmpfile', 'walk', 'write') | 122 'system', 'tmpfile', 'walk', 'write') |
122 self.MockList(os, os_to_mock) | 123 self.MockList(os, os_to_mock) |
123 os_path_to_mock = ('abspath', 'exists', 'getsize', 'isdir', 'isfile', | 124 os_path_to_mock = ('abspath', 'exists', 'getsize', 'isdir', 'isfile', |
124 'islink', 'ismount', 'lexists', 'realpath', 'samefile', 'walk') | 125 'islink', 'ismount', 'lexists', 'realpath', 'samefile', 'walk') |
125 self.MockList(os.path, os_path_to_mock) | 126 self.MockList(os.path, os_path_to_mock) |
126 self.MockList(shutil, ('rmtree')) | 127 self.MockList(shutil, ('rmtree')) |
(...skipping 10 matching lines...) Expand all Loading... |
137 def MockList(self, parent, items_to_mock): | 138 def MockList(self, parent, items_to_mock): |
138 for item in items_to_mock: | 139 for item in items_to_mock: |
139 # Skip over items not present because of OS-specific implementation, | 140 # Skip over items not present because of OS-specific implementation, |
140 # implemented only in later python version, etc. | 141 # implemented only in later python version, etc. |
141 if hasattr(parent, item): | 142 if hasattr(parent, item): |
142 try: | 143 try: |
143 self.mox.StubOutWithMock(parent, item) | 144 self.mox.StubOutWithMock(parent, item) |
144 except TypeError: | 145 except TypeError: |
145 raise TypeError('Couldn\'t mock %s in %s' % (item, parent.__name__)) | 146 raise TypeError('Couldn\'t mock %s in %s' % (item, parent.__name__)) |
146 | 147 |
147 def UnMock(self, object, name): | 148 def UnMock(self, obj, name): |
148 """Restore an object inside a test.""" | 149 """Restore an object inside a test.""" |
149 for (parent, old_child, child_name) in self.mox.stubs.cache: | 150 for (parent, old_child, child_name) in self.mox.stubs.cache: |
150 if parent == object and child_name == name: | 151 if parent == obj and child_name == name: |
151 setattr(parent, child_name, old_child) | 152 setattr(parent, child_name, old_child) |
152 break | 153 break |
OLD | NEW |