/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
608 by Martin Pool
- Split selftests out into a new module and start changing them
1
# Copyright (C) 2005 by Canonical Ltd
2
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
609 by Martin Pool
- cleanup test code
17
1535 by Martin Pool
todo idea from John
18
# TODO: Perhaps there should be an API to find out if bzr running under the
19
# test suite -- some plugins might want to avoid making intrusive changes if
20
# this is the case.  However, we want behaviour under to test to diverge as
21
# little as possible, so this should be used rarely if it's added at all.
22
# (Suggestion from j-a-meinel, 2005-11-24)
23
1185.1.29 by Robert Collins
merge merge tweaks from aaron, which includes latest .dev
24
from cStringIO import StringIO
1185.16.16 by Martin Pool
- add TestCase.assertEqualDiffs helper
25
import difflib
26
import errno
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
27
import logging
28
import os
1185.16.16 by Martin Pool
- add TestCase.assertEqualDiffs helper
29
import re
30
import shutil
1530.1.17 by Robert Collins
Move check_mode to TestCase.assertMode to make it generally accessible.
31
import stat
1185.1.58 by Robert Collins
make selftest -v show the elapsed time for each test run.
32
import sys
1185.16.16 by Martin Pool
- add TestCase.assertEqualDiffs helper
33
import tempfile
34
import unittest
1185.1.58 by Robert Collins
make selftest -v show the elapsed time for each test run.
35
import time
1185.52.1 by James Henstridge
Don't encode unicode messages to UTF-8 in mutter() (the stream writer does it).
36
import codecs
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
37
1513 by Robert Collins
Blackbox tests are maintained within the bzrlib.tests.blackbox directory.
38
import bzrlib.branch
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
39
import bzrlib.commands
1514 by Robert Collins
Unbreak self.build_tree_shape in tests.
40
from bzrlib.errors import BzrError
1513 by Robert Collins
Blackbox tests are maintained within the bzrlib.tests.blackbox directory.
41
import bzrlib.inventory
42
import bzrlib.merge3
43
import bzrlib.osutils
44
import bzrlib.osutils as osutils
45
import bzrlib.plugin
46
import bzrlib.store
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
47
import bzrlib.trace
1530.1.3 by Robert Collins
transport implementations now tested consistently.
48
from bzrlib.transport import urlescape
1185.43.1 by Martin Pool
Remove direct logging calls from selftest
49
from bzrlib.trace import mutter
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
50
from bzrlib.tests.TestUtil import TestLoader, TestSuite
1514 by Robert Collins
Unbreak self.build_tree_shape in tests.
51
from bzrlib.tests.treeshape import build_tree_contents
1147 by Martin Pool
- split builtin commands into separate module bzrlib.builtins;
52
855 by Martin Pool
- Patch from John to allow plugins to add their own tests.
53
MODULES_TO_TEST = []
1513 by Robert Collins
Blackbox tests are maintained within the bzrlib.tests.blackbox directory.
54
MODULES_TO_DOCTEST = [
55
                      bzrlib.branch,
56
                      bzrlib.commands,
57
                      bzrlib.errors,
58
                      bzrlib.inventory,
59
                      bzrlib.merge3,
60
                      bzrlib.osutils,
61
                      bzrlib.store,
62
                      ]
63
def packages_to_test():
64
    import bzrlib.tests.blackbox
65
    return [
66
            bzrlib.tests.blackbox
67
            ]
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
68
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
69
70
class EarlyStoppingTestResultAdapter(object):
71
    """An adapter for TestResult to stop at the first first failure or error"""
72
73
    def __init__(self, result):
74
        self._result = result
75
76
    def addError(self, test, err):
77
        self._result.addError(test, err)
78
        self._result.stop()
79
80
    def addFailure(self, test, err):
81
        self._result.addFailure(test, err)
82
        self._result.stop()
83
84
    def __getattr__(self, name):
85
        return getattr(self._result, name)
86
87
    def __setattr__(self, name, value):
88
        if name == '_result':
89
            object.__setattr__(self, name, value)
90
        return setattr(self._result, name, value)
91
92
93
class _MyResult(unittest._TextTestResult):
1185.43.2 by Martin Pool
Nicer display of verbose test results and progress
94
    """Custom TestResult.
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
95
1185.33.54 by Martin Pool
[merge] test renames and other fixes (John)
96
    Shows output in a different format, including displaying runtime for tests.
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
97
    """
98
1185.1.58 by Robert Collins
make selftest -v show the elapsed time for each test run.
99
    def _elapsedTime(self):
1185.43.2 by Martin Pool
Nicer display of verbose test results and progress
100
        return "%5dms" % (1000 * (time.time() - self._start_time))
1185.1.58 by Robert Collins
make selftest -v show the elapsed time for each test run.
101
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
102
    def startTest(self, test):
103
        unittest.TestResult.startTest(self, test)
1185.31.17 by John Arbash Meinel
Shorten test names in verbose mode in a logical way. Removed bzrlib.selftest prefix
104
        # In a short description, the important words are in
105
        # the beginning, but in an id, the important words are
106
        # at the end
1185.33.54 by Martin Pool
[merge] test renames and other fixes (John)
107
        SHOW_DESCRIPTIONS = False
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
108
        if self.showAll:
1185.33.60 by Martin Pool
Use full terminal width for verbose test output.
109
            width = osutils.terminal_width()
110
            name_width = width - 15
111
            what = None
112
            if SHOW_DESCRIPTIONS:
113
                what = test.shortDescription()
114
                if what:
115
                    if len(what) > name_width:
116
                        what = what[:name_width-3] + '...'
117
            if what is None:
118
                what = test.id()
119
                if what.startswith('bzrlib.tests.'):
120
                    what = what[13:]
121
                if len(what) > name_width:
122
                    what = '...' + what[3-name_width:]
123
            what = what.ljust(name_width)
124
            self.stream.write(what)
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
125
        self.stream.flush()
1185.1.58 by Robert Collins
make selftest -v show the elapsed time for each test run.
126
        self._start_time = time.time()
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
127
128
    def addError(self, test, err):
1185.33.95 by Martin Pool
New TestSkipped facility, and tests for it.
129
        if isinstance(err[1], TestSkipped):
130
            return self.addSkipped(test, err)    
1185.1.58 by Robert Collins
make selftest -v show the elapsed time for each test run.
131
        unittest.TestResult.addError(self, test, err)
132
        if self.showAll:
133
            self.stream.writeln("ERROR %s" % self._elapsedTime())
134
        elif self.dots:
135
            self.stream.write('E')
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
136
        self.stream.flush()
137
138
    def addFailure(self, test, err):
1185.1.58 by Robert Collins
make selftest -v show the elapsed time for each test run.
139
        unittest.TestResult.addFailure(self, test, err)
140
        if self.showAll:
1185.43.2 by Martin Pool
Nicer display of verbose test results and progress
141
            self.stream.writeln(" FAIL %s" % self._elapsedTime())
1185.1.58 by Robert Collins
make selftest -v show the elapsed time for each test run.
142
        elif self.dots:
143
            self.stream.write('F')
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
144
        self.stream.flush()
145
146
    def addSuccess(self, test):
147
        if self.showAll:
1185.43.2 by Martin Pool
Nicer display of verbose test results and progress
148
            self.stream.writeln('   OK %s' % self._elapsedTime())
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
149
        elif self.dots:
150
            self.stream.write('~')
151
        self.stream.flush()
152
        unittest.TestResult.addSuccess(self, test)
153
1185.33.96 by Martin Pool
Fix up display of reasons why tests were skipped.
154
    def addSkipped(self, test, skip_excinfo):
1185.33.95 by Martin Pool
New TestSkipped facility, and tests for it.
155
        if self.showAll:
1185.33.96 by Martin Pool
Fix up display of reasons why tests were skipped.
156
            print >>self.stream, ' SKIP %s' % self._elapsedTime()
157
            print >>self.stream, '     %s' % skip_excinfo[1]
1185.33.95 by Martin Pool
New TestSkipped facility, and tests for it.
158
        elif self.dots:
159
            self.stream.write('S')
160
        self.stream.flush()
161
        # seems best to treat this as success from point-of-view of unittest
162
        # -- it actually does nothing so it barely matters :)
163
        unittest.TestResult.addSuccess(self, test)
164
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
165
    def printErrorList(self, flavour, errors):
166
        for test, err in errors:
167
            self.stream.writeln(self.separator1)
1530.1.3 by Robert Collins
transport implementations now tested consistently.
168
            self.stream.writeln("%s: %s" % (flavour, self.getDescription(test)))
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
169
            if hasattr(test, '_get_log'):
1185.33.95 by Martin Pool
New TestSkipped facility, and tests for it.
170
                print >>self.stream
171
                print >>self.stream, \
1530.1.3 by Robert Collins
transport implementations now tested consistently.
172
                        ('vvvv[log from %s]' % test.id()).ljust(78,'-')
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
173
                print >>self.stream, test._get_log()
1185.33.95 by Martin Pool
New TestSkipped facility, and tests for it.
174
                print >>self.stream, \
1530.1.3 by Robert Collins
transport implementations now tested consistently.
175
                        ('^^^^[log from %s]' % test.id()).ljust(78,'-')
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
176
            self.stream.writeln(self.separator2)
177
            self.stream.writeln("%s" % err)
178
179
180
class TextTestRunner(unittest.TextTestRunner):
1185.16.58 by mbp at sourcefrog
- run all selftests by default
181
    stop_on_failure = False
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
182
183
    def _makeResult(self):
184
        result = _MyResult(self.stream, self.descriptions, self.verbosity)
1185.16.58 by mbp at sourcefrog
- run all selftests by default
185
        if self.stop_on_failure:
186
            result = EarlyStoppingTestResultAdapter(result)
187
        return result
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
188
189
1393.1.46 by Martin Pool
- bzr selftest arguments can be partial ids of tests to run
190
def iter_suite_tests(suite):
191
    """Return all tests in a suite, recursing through nested suites"""
192
    for item in suite._tests:
193
        if isinstance(item, unittest.TestCase):
194
            yield item
195
        elif isinstance(item, unittest.TestSuite):
196
            for r in iter_suite_tests(item):
197
                yield r
198
        else:
199
            raise Exception('unknown object %r inside test suite %r'
200
                            % (item, suite))
201
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
202
203
class TestSkipped(Exception):
204
    """Indicates that a test was intentionally skipped, rather than failing."""
205
    # XXX: Not used yet
206
207
1147 by Martin Pool
- split builtin commands into separate module bzrlib.builtins;
208
class CommandFailed(Exception):
209
    pass
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
210
211
class TestCase(unittest.TestCase):
212
    """Base class for bzr unit tests.
213
    
214
    Tests that need access to disk resources should subclass 
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
215
    TestCaseInTempDir not TestCase.
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
216
217
    Error and debug log messages are redirected from their usual
218
    location into a temporary file, the contents of which can be
1185.16.109 by mbp at sourcefrog
Clean up test log files when tests complete.
219
    retrieved by _get_log().  We use a real OS file, not an in-memory object,
220
    so that it can also capture file IO.  When the test completes this file
221
    is read into memory and removed from disk.
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
222
       
223
    There are also convenience functions to invoke bzr's command-line
1185.16.108 by mbp at sourcefrog
Add TestCase.addCleanup method.
224
    routine, and to build and check bzr trees.
225
   
226
    In addition to the usual method of overriding tearDown(), this class also
227
    allows subclasses to register functions into the _cleanups list, which is
228
    run in order as the object is torn down.  It's less likely this will be
229
    accidentally overlooked.
230
    """
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
231
232
    BZRPATH = 'bzr'
1185.16.14 by Martin Pool
- make TestCase._get_log work even if setup was aborted
233
    _log_file_name = None
1185.16.109 by mbp at sourcefrog
Clean up test log files when tests complete.
234
    _log_contents = ''
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
235
236
    def setUp(self):
237
        unittest.TestCase.setUp(self)
1185.16.108 by mbp at sourcefrog
Add TestCase.addCleanup method.
238
        self._cleanups = []
1185.16.110 by mbp at sourcefrog
Refactor test setup/teardown into cleanup callbacks
239
        self._cleanEnvironment()
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
240
        bzrlib.trace.disable_default_logging()
1185.16.109 by mbp at sourcefrog
Clean up test log files when tests complete.
241
        self._startLogFile()
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
242
1185.16.16 by Martin Pool
- add TestCase.assertEqualDiffs helper
243
    def _ndiff_strings(self, a, b):
1185.16.67 by Martin Pool
- assertEqualDiff handles strings without trailing newline
244
        """Return ndiff between two strings containing lines.
245
        
246
        A trailing newline is added if missing to make the strings
247
        print properly."""
248
        if b and b[-1] != '\n':
249
            b += '\n'
250
        if a and a[-1] != '\n':
251
            a += '\n'
1185.16.21 by Martin Pool
- tweak diff shown by assertEqualDiff
252
        difflines = difflib.ndiff(a.splitlines(True),
253
                                  b.splitlines(True),
254
                                  linejunk=lambda x: False,
255
                                  charjunk=lambda x: False)
256
        return ''.join(difflines)
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
257
1185.16.16 by Martin Pool
- add TestCase.assertEqualDiffs helper
258
    def assertEqualDiff(self, a, b):
259
        """Assert two texts are equal, if not raise an exception.
260
        
261
        This is intended for use with multi-line strings where it can 
262
        be hard to find the differences by eye.
263
        """
264
        # TODO: perhaps override assertEquals to call this for strings?
265
        if a == b:
266
            return
267
        raise AssertionError("texts not equal:\n" + 
268
                             self._ndiff_strings(a, b))      
1185.31.40 by John Arbash Meinel
Added osutils.mkdtemp()
269
        
270
    def assertStartsWith(self, s, prefix):
271
        if not s.startswith(prefix):
272
            raise AssertionError('string %r does not start with %r' % (s, prefix))
273
274
    def assertEndsWith(self, s, suffix):
275
        if not s.endswith(prefix):
276
            raise AssertionError('string %r does not end with %r' % (s, suffix))
1185.16.42 by Martin Pool
- Add assertContainsRe
277
278
    def assertContainsRe(self, haystack, needle_re):
279
        """Assert that a contains something matching a regular expression."""
280
        if not re.search(needle_re, haystack):
281
            raise AssertionError('pattern "%s" not found in "%s"'
282
                    % (needle_re, haystack))
1442.1.70 by Robert Collins
Add assertFileEqual to TestCaseInTempDir.
283
1185.46.8 by Aaron Bentley
bzr add reports ignored patterns.
284
    def AssertSubset(self, sublist, superlist):
285
        """Assert that every entry in sublist is present in superlist."""
286
        missing = []
287
        for entry in sublist:
288
            if entry not in superlist:
289
                missing.append(entry)
290
        if len(missing) > 0:
291
            raise AssertionError("value(s) %r not present in container %r" % 
292
                                 (missing, superlist))
293
1530.1.21 by Robert Collins
Review feedback fixes.
294
    def assertTransportMode(self, transport, path, mode):
1530.1.17 by Robert Collins
Move check_mode to TestCase.assertMode to make it generally accessible.
295
        """Fail if a path does not have mode mode.
296
        
297
        If modes are not supported on this platform, the test is skipped.
298
        """
299
        if sys.platform == 'win32':
300
            return
301
        path_stat = transport.stat(path)
302
        actual_mode = stat.S_IMODE(path_stat.st_mode)
303
        self.assertEqual(mode, actual_mode,
304
            'mode of %r incorrect (%o != %o)' % (path, mode, actual_mode))
305
1185.16.109 by mbp at sourcefrog
Clean up test log files when tests complete.
306
    def _startLogFile(self):
307
        """Send bzr and test log messages to a temporary file.
308
309
        The file is removed as the test is torn down.
310
        """
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
311
        fileno, name = tempfile.mkstemp(suffix='.log', prefix='testbzr')
1185.52.1 by James Henstridge
Don't encode unicode messages to UTF-8 in mutter() (the stream writer does it).
312
        encoder, decoder, stream_reader, stream_writer = codecs.lookup('UTF-8')
313
        self._log_file = stream_writer(os.fdopen(fileno, 'w+'))
1185.33.13 by Martin Pool
Hide more stuff in bzrlib.trace
314
        bzrlib.trace.enable_test_log(self._log_file)
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
315
        self._log_file_name = name
1185.16.109 by mbp at sourcefrog
Clean up test log files when tests complete.
316
        self.addCleanup(self._finishLogFile)
317
318
    def _finishLogFile(self):
319
        """Finished with the log file.
320
321
        Read contents into memory, close, and delete.
322
        """
1185.33.13 by Martin Pool
Hide more stuff in bzrlib.trace
323
        bzrlib.trace.disable_test_log()
1185.16.109 by mbp at sourcefrog
Clean up test log files when tests complete.
324
        self._log_file.seek(0)
325
        self._log_contents = self._log_file.read()
1185.16.122 by Martin Pool
[patch] Close test log file before deleting, needed on Windows
326
        self._log_file.close()
1185.16.109 by mbp at sourcefrog
Clean up test log files when tests complete.
327
        os.remove(self._log_file_name)
328
        self._log_file = self._log_file_name = None
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
329
1185.16.108 by mbp at sourcefrog
Add TestCase.addCleanup method.
330
    def addCleanup(self, callable):
331
        """Arrange to run a callable when this case is torn down.
332
333
        Callables are run in the reverse of the order they are registered, 
334
        ie last-in first-out.
335
        """
1185.16.109 by mbp at sourcefrog
Clean up test log files when tests complete.
336
        if callable in self._cleanups:
337
            raise ValueError("cleanup function %r already registered on %s" 
338
                    % (callable, self))
1185.16.108 by mbp at sourcefrog
Add TestCase.addCleanup method.
339
        self._cleanups.append(callable)
340
1185.16.110 by mbp at sourcefrog
Refactor test setup/teardown into cleanup callbacks
341
    def _cleanEnvironment(self):
1185.38.3 by John Arbash Meinel
Refactored environment cleaning code
342
        new_env = {
343
            'HOME': os.getcwd(),
344
            'APPDATA': os.getcwd(),
345
            'BZREMAIL': None,
346
            'EMAIL': None,
347
        }
1185.38.4 by John Arbash Meinel
Making old_env a private member
348
        self.__old_env = {}
1185.16.110 by mbp at sourcefrog
Refactor test setup/teardown into cleanup callbacks
349
        self.addCleanup(self._restoreEnvironment)
1185.38.3 by John Arbash Meinel
Refactored environment cleaning code
350
        for name, value in new_env.iteritems():
351
            self._captureVar(name, value)
352
353
354
    def _captureVar(self, name, newvalue):
355
        """Set an environment variable, preparing it to be reset when finished."""
1185.38.4 by John Arbash Meinel
Making old_env a private member
356
        self.__old_env[name] = os.environ.get(name, None)
1185.38.3 by John Arbash Meinel
Refactored environment cleaning code
357
        if newvalue is None:
358
            if name in os.environ:
359
                del os.environ[name]
360
        else:
361
            os.environ[name] = newvalue
1185.16.110 by mbp at sourcefrog
Refactor test setup/teardown into cleanup callbacks
362
1185.38.2 by John Arbash Meinel
[patch] Aaron Bentley's HOME fix.
363
    @staticmethod
364
    def _restoreVar(name, value):
365
        if value is None:
1185.38.3 by John Arbash Meinel
Refactored environment cleaning code
366
            if name in os.environ:
367
                del os.environ[name]
1185.38.2 by John Arbash Meinel
[patch] Aaron Bentley's HOME fix.
368
        else:
369
            os.environ[name] = value
370
1185.16.110 by mbp at sourcefrog
Refactor test setup/teardown into cleanup callbacks
371
    def _restoreEnvironment(self):
1185.38.4 by John Arbash Meinel
Making old_env a private member
372
        for name, value in self.__old_env.iteritems():
1185.38.3 by John Arbash Meinel
Refactored environment cleaning code
373
            self._restoreVar(name, value)
1185.16.110 by mbp at sourcefrog
Refactor test setup/teardown into cleanup callbacks
374
375
    def tearDown(self):
1185.16.108 by mbp at sourcefrog
Add TestCase.addCleanup method.
376
        self._runCleanups()
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
377
        unittest.TestCase.tearDown(self)
378
1185.16.108 by mbp at sourcefrog
Add TestCase.addCleanup method.
379
    def _runCleanups(self):
380
        """Run registered cleanup functions. 
381
382
        This should only be called from TestCase.tearDown.
383
        """
1185.33.74 by Martin Pool
pychecker cleanups
384
        for cleanup_fn in reversed(self._cleanups):
385
            cleanup_fn()
1185.16.108 by mbp at sourcefrog
Add TestCase.addCleanup method.
386
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
387
    def log(self, *args):
1185.43.1 by Martin Pool
Remove direct logging calls from selftest
388
        mutter(*args)
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
389
390
    def _get_log(self):
391
        """Return as a string the log for this test"""
1185.16.14 by Martin Pool
- make TestCase._get_log work even if setup was aborted
392
        if self._log_file_name:
393
            return open(self._log_file_name).read()
394
        else:
1185.16.109 by mbp at sourcefrog
Clean up test log files when tests complete.
395
            return self._log_contents
1185.43.1 by Martin Pool
Remove direct logging calls from selftest
396
        # TODO: Delete the log after it's been read in
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
397
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
398
    def capture(self, cmd, retcode=0):
1185.3.26 by Martin Pool
- remove remaining external executions of bzr
399
        """Shortcut that splits cmd into words, runs, and returns stdout"""
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
400
        return self.run_bzr_captured(cmd.split(), retcode=retcode)[0]
1185.3.26 by Martin Pool
- remove remaining external executions of bzr
401
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
402
    def run_bzr_captured(self, argv, retcode=0):
1185.22.7 by Michael Ellerman
Fix error in run_bzr_captured() doco
403
        """Invoke bzr and return (stdout, stderr).
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
404
405
        Useful for code that wants to check the contents of the
406
        output, the way error messages are presented, etc.
407
408
        This should be the main method for tests that want to exercise the
409
        overall behavior of the bzr application (rather than a unit test
410
        or a functional test of the library.)
411
412
        Much of the old code runs bzr by forking a new copy of Python, but
413
        that is slower, harder to debug, and generally not necessary.
414
1185.3.20 by Martin Pool
- run_bzr_captured also includes logged errors in
415
        This runs bzr through the interface that catches and reports
416
        errors, and with logging set to something approximating the
417
        default, so that error reporting can be checked.
418
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
419
        argv -- arguments to invoke bzr
420
        retcode -- expected return code, or None for don't-care.
421
        """
422
        stdout = StringIO()
423
        stderr = StringIO()
424
        self.log('run bzr: %s', ' '.join(argv))
1185.43.5 by Martin Pool
Update log message quoting
425
        # FIXME: don't call into logging here
1185.3.20 by Martin Pool
- run_bzr_captured also includes logged errors in
426
        handler = logging.StreamHandler(stderr)
427
        handler.setFormatter(bzrlib.trace.QuietFormatter())
428
        handler.setLevel(logging.INFO)
429
        logger = logging.getLogger('')
430
        logger.addHandler(handler)
431
        try:
432
            result = self.apply_redirected(None, stdout, stderr,
433
                                           bzrlib.commands.run_bzr_catch_errors,
434
                                           argv)
435
        finally:
436
            logger.removeHandler(handler)
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
437
        out = stdout.getvalue()
438
        err = stderr.getvalue()
439
        if out:
440
            self.log('output:\n%s', out)
441
        if err:
442
            self.log('errors:\n%s', err)
443
        if retcode is not None:
444
            self.assertEquals(result, retcode)
445
        return out, err
446
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
447
    def run_bzr(self, *args, **kwargs):
1119 by Martin Pool
doc
448
        """Invoke bzr, as if it were run from the command line.
449
450
        This should be the main method for tests that want to exercise the
451
        overall behavior of the bzr application (rather than a unit test
452
        or a functional test of the library.)
453
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
454
        This sends the stdout/stderr results into the test's log,
455
        where it may be useful for debugging.  See also run_captured.
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
456
        """
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
457
        retcode = kwargs.pop('retcode', 0)
1185.3.21 by Martin Pool
TestBase.run_bzr doesn't need to be deprecated
458
        return self.run_bzr_captured(args, retcode)
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
459
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
460
    def check_inventory_shape(self, inv, shape):
1291 by Martin Pool
- add test for moving files between directories
461
        """Compare an inventory to a list of expected names.
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
462
463
        Fail if they are not precisely equal.
464
        """
465
        extras = []
466
        shape = list(shape)             # copy
467
        for path, ie in inv.entries():
468
            name = path.replace('\\', '/')
469
            if ie.kind == 'dir':
470
                name = name + '/'
471
            if name in shape:
472
                shape.remove(name)
473
            else:
474
                extras.append(name)
475
        if shape:
476
            self.fail("expected paths not found in inventory: %r" % shape)
477
        if extras:
478
            self.fail("unexpected paths found in inventory: %r" % extras)
479
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
480
    def apply_redirected(self, stdin=None, stdout=None, stderr=None,
481
                         a_callable=None, *args, **kwargs):
482
        """Call callable with redirected std io pipes.
483
484
        Returns the return code."""
485
        if not callable(a_callable):
486
            raise ValueError("a_callable must be callable.")
487
        if stdin is None:
488
            stdin = StringIO("")
489
        if stdout is None:
974.1.70 by Aaron Bentley
Fixed selftest spewage (Brian M. Carlson)
490
            if hasattr(self, "_log_file"):
491
                stdout = self._log_file
492
            else:
493
                stdout = StringIO()
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
494
        if stderr is None:
974.1.70 by Aaron Bentley
Fixed selftest spewage (Brian M. Carlson)
495
            if hasattr(self, "_log_file"):
496
                stderr = self._log_file
497
            else:
498
                stderr = StringIO()
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
499
        real_stdin = sys.stdin
500
        real_stdout = sys.stdout
501
        real_stderr = sys.stderr
502
        try:
503
            sys.stdout = stdout
504
            sys.stderr = stderr
505
            sys.stdin = stdin
1160 by Martin Pool
- tiny refactoring
506
            return a_callable(*args, **kwargs)
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
507
        finally:
508
            sys.stdout = real_stdout
509
            sys.stderr = real_stderr
510
            sys.stdin = real_stdin
511
512
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
513
BzrTestBase = TestCase
514
515
     
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
516
class TestCaseInTempDir(TestCase):
517
    """Derived class that runs a test within a temporary directory.
518
519
    This is useful for tests that need to create a branch, etc.
520
521
    The directory is created in a slightly complex way: for each
522
    Python invocation, a new temporary top-level directory is created.
523
    All test cases create their own directory within that.  If the
524
    tests complete successfully, the directory is removed.
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
525
526
    InTempDir is an old alias for FunctionalTestCase.
527
    """
528
529
    TEST_ROOT = None
530
    _TEST_NAME = 'test'
531
    OVERRIDE_PYTHON = 'python'
532
533
    def check_file_contents(self, filename, expect):
534
        self.log("check contents of file %s" % filename)
535
        contents = file(filename, 'r').read()
536
        if contents != expect:
537
            self.log("expected: %r" % expect)
538
            self.log("actually: %r" % contents)
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
539
            self.fail("contents of %s not as expected" % filename)
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
540
541
    def _make_test_root(self):
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
542
        if TestCaseInTempDir.TEST_ROOT is not None:
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
543
            return
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
544
        i = 0
545
        while True:
1185.16.147 by Martin Pool
[patch] Test base directory must be unicode (from Alexander)
546
            root = u'test%04d.tmp' % i
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
547
            try:
548
                os.mkdir(root)
549
            except OSError, e:
550
                if e.errno == errno.EEXIST:
551
                    i += 1
552
                    continue
553
                else:
554
                    raise
555
            # successfully created
1185.31.37 by John Arbash Meinel
Switched os.path.abspath and os.path.realpath to osutils.* (still passes on cygwin)
556
            TestCaseInTempDir.TEST_ROOT = osutils.abspath(root)
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
557
            break
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
558
        # make a fake bzr directory there to prevent any tests propagating
559
        # up onto the source directory's real branch
1185.31.33 by John Arbash Meinel
A couple more path.join statements needed changing.
560
        os.mkdir(osutils.pathjoin(TestCaseInTempDir.TEST_ROOT, '.bzr'))
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
561
562
    def setUp(self):
1185.16.110 by mbp at sourcefrog
Refactor test setup/teardown into cleanup callbacks
563
        super(TestCaseInTempDir, self).setUp()
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
564
        self._make_test_root()
1185.16.110 by mbp at sourcefrog
Refactor test setup/teardown into cleanup callbacks
565
        _currentdir = os.getcwdu()
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
566
        short_id = self.id().replace('bzrlib.tests.', '') \
1218 by Martin Pool
- fix up import
567
                   .replace('__main__.', '')
1185.31.33 by John Arbash Meinel
A couple more path.join statements needed changing.
568
        self.test_dir = osutils.pathjoin(self.TEST_ROOT, short_id)
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
569
        os.mkdir(self.test_dir)
570
        os.chdir(self.test_dir)
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
571
        os.environ['HOME'] = self.test_dir
1185.31.39 by John Arbash Meinel
Replacing os.getcwdu() with osutils.getcwd(),
572
        os.environ['APPDATA'] = self.test_dir
1185.16.110 by mbp at sourcefrog
Refactor test setup/teardown into cleanup callbacks
573
        def _leaveDirectory():
574
            os.chdir(_currentdir)
575
        self.addCleanup(_leaveDirectory)
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
576
        
1530.1.3 by Robert Collins
transport implementations now tested consistently.
577
    def build_tree(self, shape, line_endings='native', transport=None):
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
578
        """Build a test tree according to a pattern.
579
580
        shape is a sequence of file specifications.  If the final
581
        character is '/', a directory is created.
582
583
        This doesn't add anything to a branch.
1185.38.7 by John Arbash Meinel
Updated build_tree to use fixed line-endings for tests which read the file contents and compare
584
        :param line_endings: Either 'binary' or 'native'
585
                             in binary mode, exact contents are written
586
                             in native mode, the line endings match the
587
                             default platform endings.
1530.1.3 by Robert Collins
transport implementations now tested consistently.
588
589
        :param transport: A transport to write to, for building trees on 
590
                          VFS's. If the transport is readonly or None,
591
                          "." is opened automatically.
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
592
        """
593
        # XXX: It's OK to just create them using forward slashes on windows?
1530.1.3 by Robert Collins
transport implementations now tested consistently.
594
        if transport is None or transport.is_readonly():
595
            transport = bzrlib.transport.get_transport(".")
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
596
        for name in shape:
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
597
            self.assert_(isinstance(name, basestring))
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
598
            if name[-1] == '/':
1530.1.3 by Robert Collins
transport implementations now tested consistently.
599
                transport.mkdir(urlescape(name[:-1]))
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
600
            else:
1185.38.7 by John Arbash Meinel
Updated build_tree to use fixed line-endings for tests which read the file contents and compare
601
                if line_endings == 'binary':
1530.1.3 by Robert Collins
transport implementations now tested consistently.
602
                    end = '\n'
1185.38.7 by John Arbash Meinel
Updated build_tree to use fixed line-endings for tests which read the file contents and compare
603
                elif line_endings == 'native':
1530.1.3 by Robert Collins
transport implementations now tested consistently.
604
                    end = os.linesep
1185.38.7 by John Arbash Meinel
Updated build_tree to use fixed line-endings for tests which read the file contents and compare
605
                else:
606
                    raise BzrError('Invalid line ending request %r' % (line_endings,))
1530.1.3 by Robert Collins
transport implementations now tested consistently.
607
                content = "contents of %s%s" % (name, end)
608
                transport.put(urlescape(name), StringIO(content))
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
609
1185.16.53 by Martin Pool
- annotate improvements from Goffreddo, with extra bug fixes and tests
610
    def build_tree_contents(self, shape):
1514 by Robert Collins
Unbreak self.build_tree_shape in tests.
611
        build_tree_contents(shape)
1185.16.53 by Martin Pool
- annotate improvements from Goffreddo, with extra bug fixes and tests
612
1405 by Robert Collins
remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave
613
    def failUnlessExists(self, path):
614
        """Fail unless path, which may be abs or relative, exists."""
1448 by Robert Collins
revert symlinks correctly
615
        self.failUnless(osutils.lexists(path))
1185.31.40 by John Arbash Meinel
Added osutils.mkdtemp()
616
617
    def failIfExists(self, path):
618
        """Fail if path, which may be abs or relative, exists."""
619
        self.failIf(osutils.lexists(path))
1405 by Robert Collins
remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave
620
        
1442.1.70 by Robert Collins
Add assertFileEqual to TestCaseInTempDir.
621
    def assertFileEqual(self, content, path):
622
        """Fail if path does not contain 'content'."""
623
        self.failUnless(osutils.lexists(path))
624
        self.assertEqualDiff(content, open(path, 'r').read())
1185.31.40 by John Arbash Meinel
Added osutils.mkdtemp()
625
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
626
1393.1.46 by Martin Pool
- bzr selftest arguments can be partial ids of tests to run
627
def filter_suite_by_re(suite, pattern):
1185.33.74 by Martin Pool
pychecker cleanups
628
    result = TestSuite()
1393.1.46 by Martin Pool
- bzr selftest arguments can be partial ids of tests to run
629
    filter_re = re.compile(pattern)
630
    for test in iter_suite_tests(suite):
1185.1.57 by Robert Collins
nuke --pattern to selftest, replace with regexp.search calls.
631
        if filter_re.search(test.id()):
1393.1.46 by Martin Pool
- bzr selftest arguments can be partial ids of tests to run
632
            result.addTest(test)
633
    return result
634
635
1185.16.58 by mbp at sourcefrog
- run all selftests by default
636
def run_suite(suite, name='test', verbose=False, pattern=".*",
1185.35.20 by Aaron Bentley
Only keep test failure directories if --keep-output is specified
637
              stop_on_failure=False, keep_output=False):
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
638
    TestCaseInTempDir._TEST_NAME = name
639
    if verbose:
640
        verbosity = 2
641
    else:
642
        verbosity = 1
643
    runner = TextTestRunner(stream=sys.stdout,
644
                            descriptions=0,
645
                            verbosity=verbosity)
1185.16.58 by mbp at sourcefrog
- run all selftests by default
646
    runner.stop_on_failure=stop_on_failure
1393.1.46 by Martin Pool
- bzr selftest arguments can be partial ids of tests to run
647
    if pattern != '.*':
648
        suite = filter_suite_by_re(suite, pattern)
649
    result = runner.run(suite)
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
650
    # This is still a little bogus, 
651
    # but only a little. Folk not using our testrunner will
652
    # have to delete their temp directories themselves.
1185.35.20 by Aaron Bentley
Only keep test failure directories if --keep-output is specified
653
    if result.wasSuccessful() or not keep_output:
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
654
        if TestCaseInTempDir.TEST_ROOT is not None:
655
            shutil.rmtree(TestCaseInTempDir.TEST_ROOT) 
656
    else:
657
        print "Failed tests working directories are in '%s'\n" % TestCaseInTempDir.TEST_ROOT
658
    return result.wasSuccessful()
659
660
1185.35.20 by Aaron Bentley
Only keep test failure directories if --keep-output is specified
661
def selftest(verbose=False, pattern=".*", stop_on_failure=True,
662
             keep_output=False):
1204 by Martin Pool
doc
663
    """Run the whole test suite under the enhanced runner"""
1185.16.58 by mbp at sourcefrog
- run all selftests by default
664
    return run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern,
1185.35.20 by Aaron Bentley
Only keep test failure directories if --keep-output is specified
665
                     stop_on_failure=stop_on_failure, keep_output=keep_output)
1092.1.17 by Robert Collins
remove TEST_CLASSES dead code and provide a bzrlib.test_suite() convenience method
666
667
668
def test_suite():
1204 by Martin Pool
doc
669
    """Build and return TestSuite for the whole program."""
721 by Martin Pool
- framework for running external commands from unittest suite
670
    from doctest import DocTestSuite
671
1513 by Robert Collins
Blackbox tests are maintained within the bzrlib.tests.blackbox directory.
672
    global MODULES_TO_DOCTEST
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
673
1185.51.1 by Martin Pool
Better message when failing to import a test suite.
674
    testmod_names = [ \
1518 by Robert Collins
Merge from mbp.
675
                   'bzrlib.tests.test_ancestry',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
676
                   'bzrlib.tests.test_annotate',
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
677
                   'bzrlib.tests.test_api',
1518 by Robert Collins
Merge from mbp.
678
                   'bzrlib.tests.test_bad_files',
1185.50.21 by John Arbash Meinel
Added a test for basis-inventory, which should have happened before.
679
                   'bzrlib.tests.test_basis_inventory',
1518 by Robert Collins
Merge from mbp.
680
                   'bzrlib.tests.test_branch',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
681
                   'bzrlib.tests.test_command',
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
682
                   'bzrlib.tests.test_commit',
683
                   'bzrlib.tests.test_commit_merge',
684
                   'bzrlib.tests.test_config',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
685
                   'bzrlib.tests.test_conflicts',
686
                   'bzrlib.tests.test_diff',
687
                   'bzrlib.tests.test_fetch',
1518 by Robert Collins
Merge from mbp.
688
                   'bzrlib.tests.test_gpg',
689
                   'bzrlib.tests.test_graph',
690
                   'bzrlib.tests.test_hashcache',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
691
                   'bzrlib.tests.test_http',
1518 by Robert Collins
Merge from mbp.
692
                   'bzrlib.tests.test_identitymap',
693
                   'bzrlib.tests.test_inv',
694
                   'bzrlib.tests.test_log',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
695
                   'bzrlib.tests.test_merge',
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
696
                   'bzrlib.tests.test_merge3',
1518 by Robert Collins
Merge from mbp.
697
                   'bzrlib.tests.test_merge_core',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
698
                   'bzrlib.tests.test_missing',
1518 by Robert Collins
Merge from mbp.
699
                   'bzrlib.tests.test_msgeditor',
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
700
                   'bzrlib.tests.test_nonascii',
1518 by Robert Collins
Merge from mbp.
701
                   'bzrlib.tests.test_options',
1185.50.20 by John Arbash Meinel
merge permissions branch, also fixup tests so they are lined up with bzr.dev to help prevent conflicts.
702
                   'bzrlib.tests.test_osutils',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
703
                   'bzrlib.tests.test_parent',
1185.58.1 by John Arbash Meinel
Added new permissions test (currently don't pass)
704
                   'bzrlib.tests.test_permissions',
1515 by Robert Collins
* Plugins with the same name in different directories in the bzr plugin
705
                   'bzrlib.tests.test_plugins',
1185.33.92 by Martin Pool
[patch] fix for 'bzr rm -v' (Wouter van Heyst)
706
                   'bzrlib.tests.test_remove',
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
707
                   'bzrlib.tests.test_revision',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
708
                   'bzrlib.tests.test_revisionnamespaces',
1518 by Robert Collins
Merge from mbp.
709
                   'bzrlib.tests.test_revprops',
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
710
                   'bzrlib.tests.test_reweave',
1185.47.1 by Martin Pool
[broken] start converting basic_io to more rfc822-like format
711
                   'bzrlib.tests.test_rio',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
712
                   'bzrlib.tests.test_sampler',
1185.51.1 by Martin Pool
Better message when failing to import a test suite.
713
                   'bzrlib.tests.test_selftest',
1185.33.89 by Martin Pool
[patch] add a selftest test that the setup build script works (Alexander Belchenko)
714
                   'bzrlib.tests.test_setup',
1185.50.20 by John Arbash Meinel
merge permissions branch, also fixup tests so they are lined up with bzr.dev to help prevent conflicts.
715
                   'bzrlib.tests.test_sftp_transport',
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
716
                   'bzrlib.tests.test_smart_add',
1522 by Robert Collins
Test for the number of uses of self.working_tree() in branch.py
717
                   'bzrlib.tests.test_source',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
718
                   'bzrlib.tests.test_status',
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
719
                   'bzrlib.tests.test_store',
1534.2.1 by Robert Collins
Implement deprecated_method
720
                   'bzrlib.tests.test_symbol_versioning',
1518 by Robert Collins
Merge from mbp.
721
                   'bzrlib.tests.test_testament',
722
                   'bzrlib.tests.test_trace',
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
723
                   'bzrlib.tests.test_transactions',
724
                   'bzrlib.tests.test_transport',
725
                   'bzrlib.tests.test_tsort',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
726
                   'bzrlib.tests.test_ui',
727
                   'bzrlib.tests.test_uncommit',
728
                   'bzrlib.tests.test_upgrade',
729
                   'bzrlib.tests.test_weave',
730
                   'bzrlib.tests.test_whitebox',
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
731
                   'bzrlib.tests.test_workingtree',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
732
                   'bzrlib.tests.test_xml',
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
733
                   ]
1530.1.3 by Robert Collins
transport implementations now tested consistently.
734
    test_transport_implementations = [
735
        'bzrlib.tests.test_transport_implementations']
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
736
1185.31.33 by John Arbash Meinel
A couple more path.join statements needed changing.
737
    TestCase.BZRPATH = osutils.pathjoin(
738
            osutils.realpath(osutils.dirname(bzrlib.__path__[0])), 'bzr')
1185.31.57 by John Arbash Meinel
[merge] bzr.dev
739
    print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
1185.51.1 by Martin Pool
Better message when failing to import a test suite.
740
    print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
744 by Martin Pool
- show nicer descriptions while running tests
741
    print
721 by Martin Pool
- framework for running external commands from unittest suite
742
    suite = TestSuite()
1185.51.1 by Martin Pool
Better message when failing to import a test suite.
743
    # python2.4's TestLoader.loadTestsFromNames gives very poor 
744
    # errors if it fails to load a named module - no indication of what's
745
    # actually wrong, just "no such module".  We should probably override that
746
    # class, but for the moment just load them ourselves. (mbp 20051202)
747
    loader = TestLoader()
1530.1.3 by Robert Collins
transport implementations now tested consistently.
748
    from bzrlib.transport import TransportTestProviderAdapter
749
    adapter = TransportTestProviderAdapter()
750
    for mod_name in test_transport_implementations:
751
        mod = _load_module_by_name(mod_name)
752
        for test in iter_suite_tests(loader.loadTestsFromModule(mod)):
753
            suite.addTests(adapter.adapt(test))
1185.51.1 by Martin Pool
Better message when failing to import a test suite.
754
    for mod_name in testmod_names:
755
        mod = _load_module_by_name(mod_name)
756
        suite.addTest(loader.loadTestsFromModule(mod))
1513 by Robert Collins
Blackbox tests are maintained within the bzrlib.tests.blackbox directory.
757
    for package in packages_to_test():
758
        suite.addTest(package.test_suite())
855 by Martin Pool
- Patch from John to allow plugins to add their own tests.
759
    for m in MODULES_TO_TEST:
1185.51.1 by Martin Pool
Better message when failing to import a test suite.
760
        suite.addTest(loader.loadTestsFromModule(m))
855 by Martin Pool
- Patch from John to allow plugins to add their own tests.
761
    for m in (MODULES_TO_DOCTEST):
721 by Martin Pool
- framework for running external commands from unittest suite
762
        suite.addTest(DocTestSuite(m))
1516 by Robert Collins
* bzrlib.plugin.all_plugins has been changed from an attribute to a
763
    for name, plugin in bzrlib.plugin.all_plugins().items():
764
        if hasattr(plugin, 'test_suite'):
765
            suite.addTest(plugin.test_suite())
1092.1.17 by Robert Collins
remove TEST_CLASSES dead code and provide a bzrlib.test_suite() convenience method
766
    return suite
764 by Martin Pool
- log messages from a particular test are printed if that test fails
767
1185.51.1 by Martin Pool
Better message when failing to import a test suite.
768
769
def _load_module_by_name(mod_name):
770
    parts = mod_name.split('.')
771
    module = __import__(mod_name)
772
    del parts[0]
773
    # for historical reasons python returns the top-level module even though
774
    # it loads the submodule; we need to walk down to get the one we want.
775
    while parts:
776
        module = getattr(module, parts.pop(0))
777
    return module