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

Side by Side Diff: tests/super_mox.py

Issue 8508015: Create a new depot_tools_testing_lib to move utility modules there (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Renamed to testing_support Created 9 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « tests/scm_unittest.py ('k') | tests/trial_dir.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Simplify unit tests based on pymox."""
6
7 import os
8 import random
9 import shutil
10 import string
11 import StringIO
12 import subprocess
13 import sys
14
15 sys.path.append(os.path.dirname(os.path.dirname(__file__)))
16 from third_party.pymox import mox
17
18
19 class IsOneOf(mox.Comparator):
20 def __init__(self, keys):
21 self._keys = keys
22
23 def equals(self, rhs):
24 return rhs in self._keys
25
26 def __repr__(self):
27 return '<sequence or map containing \'%s\'>' % str(self._keys)
28
29
30 class TestCaseUtils(object):
31 """Base class with some additional functionalities. People will usually want
32 to use SuperMoxTestBase instead."""
33 # Backup the separator in case it gets mocked
34 _OS_SEP = os.sep
35 _RANDOM_CHOICE = random.choice
36 _RANDOM_RANDINT = random.randint
37 _STRING_LETTERS = string.letters
38
39 ## Some utilities for generating arbitrary arguments.
40 def String(self, max_length):
41 return ''.join([self._RANDOM_CHOICE(self._STRING_LETTERS)
42 for _ in xrange(self._RANDOM_RANDINT(1, max_length))])
43
44 def Strings(self, max_arg_count, max_arg_length):
45 return [self.String(max_arg_length) for _ in xrange(max_arg_count)]
46
47 def Args(self, max_arg_count=8, max_arg_length=16):
48 return self.Strings(max_arg_count,
49 self._RANDOM_RANDINT(1, max_arg_length))
50
51 def _DirElts(self, max_elt_count=4, max_elt_length=8):
52 return self._OS_SEP.join(self.Strings(max_elt_count, max_elt_length))
53
54 def Dir(self, max_elt_count=4, max_elt_length=8):
55 return (self._RANDOM_CHOICE((self._OS_SEP, '')) +
56 self._DirElts(max_elt_count, max_elt_length))
57
58 def SvnUrl(self, max_elt_count=4, max_elt_length=8):
59 return ('svn://random_host:port/a' +
60 self._DirElts(max_elt_count, max_elt_length
61 ).replace(self._OS_SEP, '/'))
62
63 def RootDir(self, max_elt_count=4, max_elt_length=8):
64 return self._OS_SEP + self._DirElts(max_elt_count, max_elt_length)
65
66 def compareMembers(self, obj, members):
67 """If you add a member, be sure to add the relevant test!"""
68 # Skip over members starting with '_' since they are usually not meant to
69 # be for public use.
70 actual_members = [x for x in sorted(dir(obj))
71 if not x.startswith('_')]
72 expected_members = sorted(members)
73 if actual_members != expected_members:
74 diff = ([i for i in actual_members if i not in expected_members] +
75 [i for i in expected_members if i not in actual_members])
76 print >> sys.stderr, diff
77 # pylint: disable=E1101
78 self.assertEqual(actual_members, expected_members)
79
80 def setUp(self):
81 self.root_dir = self.Dir()
82 self.args = self.Args()
83 self.relpath = self.String(200)
84
85 def tearDown(self):
86 pass
87
88
89 class StdoutCheck(object):
90 def setUp(self):
91 # Override the mock with a StringIO, it's much less painful to test.
92 self._old_stdout = sys.stdout
93 sys.stdout = StringIO.StringIO()
94 sys.stdout.flush = lambda: None
95
96 def tearDown(self):
97 try:
98 # If sys.stdout was used, self.checkstdout() must be called.
99 # pylint: disable=E1101
100 self.assertEquals('', sys.stdout.getvalue())
101 except AttributeError:
102 pass
103 sys.stdout = self._old_stdout
104
105 def checkstdout(self, expected):
106 value = sys.stdout.getvalue()
107 sys.stdout.close()
108 # pylint: disable=E1101
109 self.assertEquals(expected, value)
110
111
112 class SuperMoxTestBase(TestCaseUtils, StdoutCheck, mox.MoxTestBase):
113 def setUp(self):
114 """Patch a few functions with know side-effects."""
115 TestCaseUtils.setUp(self)
116 mox.MoxTestBase.setUp(self)
117 os_to_mock = ('chdir', 'chown', 'close', 'closerange', 'dup', 'dup2',
118 'fchdir', 'fchmod', 'fchown', 'fdopen', 'getcwd', 'getpid', 'lseek',
119 'makedirs', 'mkdir', 'open', 'popen', 'popen2', 'popen3', 'popen4',
120 'read', 'remove', 'removedirs', 'rename', 'renames', 'rmdir', 'symlink',
121 'system', 'tmpfile', 'walk', 'write')
122 self.MockList(os, os_to_mock)
123 os_path_to_mock = ('abspath', 'exists', 'getsize', 'isdir', 'isfile',
124 'islink', 'ismount', 'lexists', 'realpath', 'samefile', 'walk')
125 self.MockList(os.path, os_path_to_mock)
126 self.MockList(shutil, ('rmtree'))
127 self.MockList(subprocess, ('call', 'Popen'))
128 # Don't mock stderr since it confuses unittests.
129 self.MockList(sys, ('stdin'))
130 StdoutCheck.setUp(self)
131
132 def tearDown(self):
133 StdoutCheck.tearDown(self)
134 TestCaseUtils.tearDown(self)
135 mox.MoxTestBase.tearDown(self)
136
137 def MockList(self, parent, items_to_mock):
138 for item in items_to_mock:
139 # Skip over items not present because of OS-specific implementation,
140 # implemented only in later python version, etc.
141 if hasattr(parent, item):
142 try:
143 self.mox.StubOutWithMock(parent, item)
144 except TypeError, e:
145 raise TypeError(
146 'Couldn\'t mock %s in %s: %s' % (item, parent.__name__, e))
147
148 def UnMock(self, obj, name):
149 """Restore an object inside a test."""
150 for (parent, old_child, child_name) in self.mox.stubs.cache:
151 if parent == obj and child_name == name:
152 setattr(parent, child_name, old_child)
153 break
OLDNEW
« no previous file with comments | « tests/scm_unittest.py ('k') | tests/trial_dir.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698