55
55
# XXX: Not used yet
58
class TestCase(unittest.TestCase):
59
"""Base class for bzr unit tests.
61
Tests that need access to disk resources should subclass
62
FunctionalTestCase not TestCase.
65
# TODO: Special methods to invoke bzr, so that we can run it
66
# through a specified Python intepreter
68
OVERRIDE_PYTHON = None # to run with alternative python 'python'
72
super(TestCase, self).setUp()
73
# setup a temporary log for the test
79
self.TEST_LOG = tempfile.NamedTemporaryFile(mode='wt', bufsize=0)
80
# save stdout & stderr so there's no leakage from code-under-test
81
self.real_stdout = sys.stdout
82
self.real_stderr = sys.stderr
83
sys.stdout = sys.stderr = self.TEST_LOG
85
# set up default python log handler
86
#self._handler = logging.StreamHandler(self.TEST_LOG)
87
#self._handler.setLevel(logging.DEBUG)
88
#logging.getLogger('').addHandler(self._handler)
90
self.log("%s setup" % self.id())
93
# logging.getLogger('').removeHandler(self._handler)
94
sys.stdout = self.real_stdout
95
sys.stderr = self.real_stderr
96
self.log("%s teardown" % self.id())
98
super(TestCase, self).tearDown()
101
"""Log a message to a progress file"""
102
print >>self.TEST_LOG, msg
104
def check_inventory_shape(self, inv, shape):
106
Compare an inventory to a list of expected names.
108
Fail if they are not precisely equal.
111
shape = list(shape) # copy
112
for path, ie in inv.entries():
113
name = path.replace('\\', '/')
121
self.fail("expected paths not found in inventory: %r" % shape)
123
self.fail("unexpected paths found in inventory: %r" % extras)
126
"""Get the log the test case used. This can only be called once,
127
after which an exception will be raised.
129
self.TEST_LOG.flush()
130
log = open(self.TEST_LOG.name, 'rt').read()
131
self.TEST_LOG.close()
135
class FunctionalTestCase(TestCase):
136
"""Base class for tests that perform function testing - running bzr,
137
using files on disk, and similar activities.
139
InTempDir is an old alias for FunctionalTestCase.
145
def check_file_contents(self, filename, expect):
146
self.log("check contents of file %s" % filename)
147
contents = file(filename, 'r').read()
148
if contents != expect:
149
self.log("expected: %r" % expect)
150
self.log("actually: %r" % contents)
151
self.fail("contents of %s not as expected")
153
def _make_test_root(self):
158
if FunctionalTestCase.TEST_ROOT is not None:
160
FunctionalTestCase.TEST_ROOT = os.path.abspath(
161
tempfile.mkdtemp(suffix='.tmp',
162
prefix=self._TEST_NAME + '-',
165
# make a fake bzr directory there to prevent any tests propagating
166
# up onto the source directory's real branch
167
os.mkdir(os.path.join(FunctionalTestCase.TEST_ROOT, '.bzr'))
170
super(FunctionalTestCase, self).setUp()
172
self._make_test_root()
173
self._currentdir = os.getcwdu()
174
self.test_dir = os.path.join(self.TEST_ROOT, self.id())
175
os.mkdir(self.test_dir)
176
os.chdir(self.test_dir)
180
os.chdir(self._currentdir)
181
super(FunctionalTestCase, self).tearDown()
183
def _formcmd(self, cmd):
184
if isinstance(cmd, basestring):
187
cmd[0] = self.BZRPATH
188
if self.OVERRIDE_PYTHON:
189
cmd.insert(0, self.OVERRIDE_PYTHON)
190
self.log('$ %r' % cmd)
193
def runcmd(self, cmd, retcode=0):
194
"""Run one command and check the return code.
196
Returns a tuple of (stdout,stderr) strings.
198
If a single string is based, it is split into words.
199
For commands that are not simple space-separated words, please
200
pass a list instead."""
203
from subprocess import call
204
except ImportError, e:
207
cmd = self._formcmd(cmd)
208
self.log('$ ' + ' '.join(cmd))
209
actual_retcode = call(cmd, stdout=self.TEST_LOG, stderr=self.TEST_LOG)
210
if retcode != actual_retcode:
211
raise CommandFailed("test failed: %r returned %d, expected %d"
212
% (cmd, actual_retcode, retcode))
214
def backtick(self, cmd, retcode=0):
215
"""Run a command and return its output"""
218
from subprocess import Popen, PIPE
219
except ImportError, e:
223
cmd = self._formcmd(cmd)
224
child = Popen(cmd, stdout=PIPE, stderr=self.TEST_LOG)
225
outd, errd = child.communicate()
227
actual_retcode = child.wait()
229
outd = outd.replace('\r', '')
231
if retcode != actual_retcode:
232
raise CommandFailed("test failed: %r returned %d, expected %d"
233
% (cmd, actual_retcode, retcode))
239
def build_tree(self, shape):
240
"""Build a test tree according to a pattern.
242
shape is a sequence of file specifications. If the final
243
character is '/', a directory is created.
245
This doesn't add anything to a branch.
247
# XXX: It's OK to just create them using forward slashes on windows?
250
assert isinstance(name, basestring)
255
print >>f, "contents of", name
258
InTempDir = FunctionalTestCase
261
58
class _MyResult(unittest._TextTestResult):
263
60
Custom TestResult.