/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
        """
1541 by Martin Pool
doc
384
        # TODO: Perhaps this should keep running cleanups even if 
385
        # one of them fails?
1185.33.74 by Martin Pool
pychecker cleanups
386
        for cleanup_fn in reversed(self._cleanups):
387
            cleanup_fn()
1185.16.108 by mbp at sourcefrog
Add TestCase.addCleanup method.
388
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
389
    def log(self, *args):
1185.43.1 by Martin Pool
Remove direct logging calls from selftest
390
        mutter(*args)
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
391
392
    def _get_log(self):
393
        """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
394
        if self._log_file_name:
395
            return open(self._log_file_name).read()
396
        else:
1185.16.109 by mbp at sourcefrog
Clean up test log files when tests complete.
397
            return self._log_contents
1185.43.1 by Martin Pool
Remove direct logging calls from selftest
398
        # TODO: Delete the log after it's been read in
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
399
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
400
    def capture(self, cmd, retcode=0):
1185.3.26 by Martin Pool
- remove remaining external executions of bzr
401
        """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.
402
        return self.run_bzr_captured(cmd.split(), retcode=retcode)[0]
1185.3.26 by Martin Pool
- remove remaining external executions of bzr
403
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
404
    def run_bzr_captured(self, argv, retcode=0):
1185.22.7 by Michael Ellerman
Fix error in run_bzr_captured() doco
405
        """Invoke bzr and return (stdout, stderr).
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
406
407
        Useful for code that wants to check the contents of the
408
        output, the way error messages are presented, etc.
409
410
        This should be the main method for tests that want to exercise the
411
        overall behavior of the bzr application (rather than a unit test
412
        or a functional test of the library.)
413
414
        Much of the old code runs bzr by forking a new copy of Python, but
415
        that is slower, harder to debug, and generally not necessary.
416
1185.3.20 by Martin Pool
- run_bzr_captured also includes logged errors in
417
        This runs bzr through the interface that catches and reports
418
        errors, and with logging set to something approximating the
419
        default, so that error reporting can be checked.
420
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
421
        argv -- arguments to invoke bzr
422
        retcode -- expected return code, or None for don't-care.
423
        """
424
        stdout = StringIO()
425
        stderr = StringIO()
426
        self.log('run bzr: %s', ' '.join(argv))
1185.43.5 by Martin Pool
Update log message quoting
427
        # FIXME: don't call into logging here
1185.3.20 by Martin Pool
- run_bzr_captured also includes logged errors in
428
        handler = logging.StreamHandler(stderr)
429
        handler.setFormatter(bzrlib.trace.QuietFormatter())
430
        handler.setLevel(logging.INFO)
431
        logger = logging.getLogger('')
432
        logger.addHandler(handler)
433
        try:
434
            result = self.apply_redirected(None, stdout, stderr,
435
                                           bzrlib.commands.run_bzr_catch_errors,
436
                                           argv)
437
        finally:
438
            logger.removeHandler(handler)
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
439
        out = stdout.getvalue()
440
        err = stderr.getvalue()
441
        if out:
442
            self.log('output:\n%s', out)
443
        if err:
444
            self.log('errors:\n%s', err)
445
        if retcode is not None:
446
            self.assertEquals(result, retcode)
447
        return out, err
448
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
449
    def run_bzr(self, *args, **kwargs):
1119 by Martin Pool
doc
450
        """Invoke bzr, as if it were run from the command line.
451
452
        This should be the main method for tests that want to exercise the
453
        overall behavior of the bzr application (rather than a unit test
454
        or a functional test of the library.)
455
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
456
        This sends the stdout/stderr results into the test's log,
457
        where it may be useful for debugging.  See also run_captured.
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
458
        """
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
459
        retcode = kwargs.pop('retcode', 0)
1185.3.21 by Martin Pool
TestBase.run_bzr doesn't need to be deprecated
460
        return self.run_bzr_captured(args, retcode)
1185.3.18 by Martin Pool
- add new helper TestBase.run_bzr_captured
461
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
462
    def check_inventory_shape(self, inv, shape):
1291 by Martin Pool
- add test for moving files between directories
463
        """Compare an inventory to a list of expected names.
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
464
465
        Fail if they are not precisely equal.
466
        """
467
        extras = []
468
        shape = list(shape)             # copy
469
        for path, ie in inv.entries():
470
            name = path.replace('\\', '/')
471
            if ie.kind == 'dir':
472
                name = name + '/'
473
            if name in shape:
474
                shape.remove(name)
475
            else:
476
                extras.append(name)
477
        if shape:
478
            self.fail("expected paths not found in inventory: %r" % shape)
479
        if extras:
480
            self.fail("unexpected paths found in inventory: %r" % extras)
481
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
482
    def apply_redirected(self, stdin=None, stdout=None, stderr=None,
483
                         a_callable=None, *args, **kwargs):
484
        """Call callable with redirected std io pipes.
485
486
        Returns the return code."""
487
        if not callable(a_callable):
488
            raise ValueError("a_callable must be callable.")
489
        if stdin is None:
490
            stdin = StringIO("")
491
        if stdout is None:
974.1.70 by Aaron Bentley
Fixed selftest spewage (Brian M. Carlson)
492
            if hasattr(self, "_log_file"):
493
                stdout = self._log_file
494
            else:
495
                stdout = StringIO()
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
496
        if stderr is None:
974.1.70 by Aaron Bentley
Fixed selftest spewage (Brian M. Carlson)
497
            if hasattr(self, "_log_file"):
498
                stderr = self._log_file
499
            else:
500
                stderr = StringIO()
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
501
        real_stdin = sys.stdin
502
        real_stdout = sys.stdout
503
        real_stderr = sys.stderr
504
        try:
505
            sys.stdout = stdout
506
            sys.stderr = stderr
507
            sys.stdin = stdin
1160 by Martin Pool
- tiny refactoring
508
            return a_callable(*args, **kwargs)
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
509
        finally:
510
            sys.stdout = real_stdout
511
            sys.stderr = real_stderr
512
            sys.stdin = real_stdin
513
514
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
515
BzrTestBase = TestCase
516
517
     
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
518
class TestCaseInTempDir(TestCase):
519
    """Derived class that runs a test within a temporary directory.
520
521
    This is useful for tests that need to create a branch, etc.
522
523
    The directory is created in a slightly complex way: for each
524
    Python invocation, a new temporary top-level directory is created.
525
    All test cases create their own directory within that.  If the
526
    tests complete successfully, the directory is removed.
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
527
528
    InTempDir is an old alias for FunctionalTestCase.
529
    """
530
531
    TEST_ROOT = None
532
    _TEST_NAME = 'test'
533
    OVERRIDE_PYTHON = 'python'
534
535
    def check_file_contents(self, filename, expect):
536
        self.log("check contents of file %s" % filename)
537
        contents = file(filename, 'r').read()
538
        if contents != expect:
539
            self.log("expected: %r" % expect)
540
            self.log("actually: %r" % contents)
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
541
            self.fail("contents of %s not as expected" % filename)
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
542
543
    def _make_test_root(self):
1141 by Martin Pool
- rename FunctionalTest to TestCaseInTempDir
544
        if TestCaseInTempDir.TEST_ROOT is not None:
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
545
            return
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
546
        i = 0
547
        while True:
1185.16.147 by Martin Pool
[patch] Test base directory must be unicode (from Alexander)
548
            root = u'test%04d.tmp' % i
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
549
            try:
550
                os.mkdir(root)
551
            except OSError, e:
552
                if e.errno == errno.EEXIST:
553
                    i += 1
554
                    continue
555
                else:
556
                    raise
557
            # successfully created
1185.31.37 by John Arbash Meinel
Switched os.path.abspath and os.path.realpath to osutils.* (still passes on cygwin)
558
            TestCaseInTempDir.TEST_ROOT = osutils.abspath(root)
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
559
            break
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
560
        # make a fake bzr directory there to prevent any tests propagating
561
        # up onto the source directory's real branch
1185.31.33 by John Arbash Meinel
A couple more path.join statements needed changing.
562
        os.mkdir(osutils.pathjoin(TestCaseInTempDir.TEST_ROOT, '.bzr'))
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
563
564
    def setUp(self):
1185.16.110 by mbp at sourcefrog
Refactor test setup/teardown into cleanup callbacks
565
        super(TestCaseInTempDir, self).setUp()
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
566
        self._make_test_root()
1185.16.110 by mbp at sourcefrog
Refactor test setup/teardown into cleanup callbacks
567
        _currentdir = os.getcwdu()
1185.31.25 by John Arbash Meinel
Renamed all of the tests from selftest/foo.py to tests/test_foo.py
568
        short_id = self.id().replace('bzrlib.tests.', '') \
1218 by Martin Pool
- fix up import
569
                   .replace('__main__.', '')
1185.31.33 by John Arbash Meinel
A couple more path.join statements needed changing.
570
        self.test_dir = osutils.pathjoin(self.TEST_ROOT, short_id)
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
571
        os.mkdir(self.test_dir)
572
        os.chdir(self.test_dir)
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
573
        os.environ['HOME'] = self.test_dir
1185.31.39 by John Arbash Meinel
Replacing os.getcwdu() with osutils.getcwd(),
574
        os.environ['APPDATA'] = self.test_dir
1185.16.110 by mbp at sourcefrog
Refactor test setup/teardown into cleanup callbacks
575
        def _leaveDirectory():
576
            os.chdir(_currentdir)
577
        self.addCleanup(_leaveDirectory)
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
578
        
1530.1.3 by Robert Collins
transport implementations now tested consistently.
579
    def build_tree(self, shape, line_endings='native', transport=None):
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
580
        """Build a test tree according to a pattern.
581
582
        shape is a sequence of file specifications.  If the final
583
        character is '/', a directory is created.
584
585
        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
586
        :param line_endings: Either 'binary' or 'native'
587
                             in binary mode, exact contents are written
588
                             in native mode, the line endings match the
589
                             default platform endings.
1530.1.3 by Robert Collins
transport implementations now tested consistently.
590
591
        :param transport: A transport to write to, for building trees on 
592
                          VFS's. If the transport is readonly or None,
593
                          "." is opened automatically.
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
594
        """
595
        # XXX: It's OK to just create them using forward slashes on windows?
1530.1.3 by Robert Collins
transport implementations now tested consistently.
596
        if transport is None or transport.is_readonly():
597
            transport = bzrlib.transport.get_transport(".")
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
598
        for name in shape:
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
599
            self.assert_(isinstance(name, basestring))
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
600
            if name[-1] == '/':
1530.1.3 by Robert Collins
transport implementations now tested consistently.
601
                transport.mkdir(urlescape(name[:-1]))
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
602
            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
603
                if line_endings == 'binary':
1530.1.3 by Robert Collins
transport implementations now tested consistently.
604
                    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
605
                elif line_endings == 'native':
1530.1.3 by Robert Collins
transport implementations now tested consistently.
606
                    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
607
                else:
608
                    raise BzrError('Invalid line ending request %r' % (line_endings,))
1530.1.3 by Robert Collins
transport implementations now tested consistently.
609
                content = "contents of %s%s" % (name, end)
610
                transport.put(urlescape(name), StringIO(content))
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
611
1185.16.53 by Martin Pool
- annotate improvements from Goffreddo, with extra bug fixes and tests
612
    def build_tree_contents(self, shape):
1514 by Robert Collins
Unbreak self.build_tree_shape in tests.
613
        build_tree_contents(shape)
1185.16.53 by Martin Pool
- annotate improvements from Goffreddo, with extra bug fixes and tests
614
1405 by Robert Collins
remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave
615
    def failUnlessExists(self, path):
616
        """Fail unless path, which may be abs or relative, exists."""
1448 by Robert Collins
revert symlinks correctly
617
        self.failUnless(osutils.lexists(path))
1185.31.40 by John Arbash Meinel
Added osutils.mkdtemp()
618
619
    def failIfExists(self, path):
620
        """Fail if path, which may be abs or relative, exists."""
621
        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
622
        
1442.1.70 by Robert Collins
Add assertFileEqual to TestCaseInTempDir.
623
    def assertFileEqual(self, content, path):
624
        """Fail if path does not contain 'content'."""
625
        self.failUnless(osutils.lexists(path))
626
        self.assertEqualDiff(content, open(path, 'r').read())
1185.31.40 by John Arbash Meinel
Added osutils.mkdtemp()
627
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
628
1393.1.46 by Martin Pool
- bzr selftest arguments can be partial ids of tests to run
629
def filter_suite_by_re(suite, pattern):
1185.33.74 by Martin Pool
pychecker cleanups
630
    result = TestSuite()
1393.1.46 by Martin Pool
- bzr selftest arguments can be partial ids of tests to run
631
    filter_re = re.compile(pattern)
632
    for test in iter_suite_tests(suite):
1185.1.57 by Robert Collins
nuke --pattern to selftest, replace with regexp.search calls.
633
        if filter_re.search(test.id()):
1393.1.46 by Martin Pool
- bzr selftest arguments can be partial ids of tests to run
634
            result.addTest(test)
635
    return result
636
637
1185.16.58 by mbp at sourcefrog
- run all selftests by default
638
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
639
              stop_on_failure=False, keep_output=False):
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
640
    TestCaseInTempDir._TEST_NAME = name
641
    if verbose:
642
        verbosity = 2
643
    else:
644
        verbosity = 1
645
    runner = TextTestRunner(stream=sys.stdout,
646
                            descriptions=0,
647
                            verbosity=verbosity)
1185.16.58 by mbp at sourcefrog
- run all selftests by default
648
    runner.stop_on_failure=stop_on_failure
1393.1.46 by Martin Pool
- bzr selftest arguments can be partial ids of tests to run
649
    if pattern != '.*':
650
        suite = filter_suite_by_re(suite, pattern)
651
    result = runner.run(suite)
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
652
    # This is still a little bogus, 
653
    # but only a little. Folk not using our testrunner will
654
    # have to delete their temp directories themselves.
1185.35.20 by Aaron Bentley
Only keep test failure directories if --keep-output is specified
655
    if result.wasSuccessful() or not keep_output:
1393.1.6 by Martin Pool
- fold testsweet into bzrlib.selftest
656
        if TestCaseInTempDir.TEST_ROOT is not None:
657
            shutil.rmtree(TestCaseInTempDir.TEST_ROOT) 
658
    else:
659
        print "Failed tests working directories are in '%s'\n" % TestCaseInTempDir.TEST_ROOT
660
    return result.wasSuccessful()
661
662
1185.35.20 by Aaron Bentley
Only keep test failure directories if --keep-output is specified
663
def selftest(verbose=False, pattern=".*", stop_on_failure=True,
664
             keep_output=False):
1204 by Martin Pool
doc
665
    """Run the whole test suite under the enhanced runner"""
1185.16.58 by mbp at sourcefrog
- run all selftests by default
666
    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
667
                     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
668
669
670
def test_suite():
1204 by Martin Pool
doc
671
    """Build and return TestSuite for the whole program."""
721 by Martin Pool
- framework for running external commands from unittest suite
672
    from doctest import DocTestSuite
673
1513 by Robert Collins
Blackbox tests are maintained within the bzrlib.tests.blackbox directory.
674
    global MODULES_TO_DOCTEST
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
675
1185.51.1 by Martin Pool
Better message when failing to import a test suite.
676
    testmod_names = [ \
1518 by Robert Collins
Merge from mbp.
677
                   'bzrlib.tests.test_ancestry',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
678
                   '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
679
                   'bzrlib.tests.test_api',
1518 by Robert Collins
Merge from mbp.
680
                   'bzrlib.tests.test_bad_files',
1185.50.21 by John Arbash Meinel
Added a test for basis-inventory, which should have happened before.
681
                   'bzrlib.tests.test_basis_inventory',
1518 by Robert Collins
Merge from mbp.
682
                   'bzrlib.tests.test_branch',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
683
                   '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
684
                   'bzrlib.tests.test_commit',
685
                   'bzrlib.tests.test_commit_merge',
686
                   'bzrlib.tests.test_config',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
687
                   'bzrlib.tests.test_conflicts',
688
                   'bzrlib.tests.test_diff',
689
                   'bzrlib.tests.test_fetch',
1518 by Robert Collins
Merge from mbp.
690
                   'bzrlib.tests.test_gpg',
691
                   'bzrlib.tests.test_graph',
692
                   'bzrlib.tests.test_hashcache',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
693
                   'bzrlib.tests.test_http',
1518 by Robert Collins
Merge from mbp.
694
                   'bzrlib.tests.test_identitymap',
695
                   'bzrlib.tests.test_inv',
696
                   'bzrlib.tests.test_log',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
697
                   '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
698
                   'bzrlib.tests.test_merge3',
1518 by Robert Collins
Merge from mbp.
699
                   'bzrlib.tests.test_merge_core',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
700
                   'bzrlib.tests.test_missing',
1518 by Robert Collins
Merge from mbp.
701
                   '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
702
                   'bzrlib.tests.test_nonascii',
1518 by Robert Collins
Merge from mbp.
703
                   '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.
704
                   'bzrlib.tests.test_osutils',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
705
                   'bzrlib.tests.test_parent',
1185.58.1 by John Arbash Meinel
Added new permissions test (currently don't pass)
706
                   'bzrlib.tests.test_permissions',
1515 by Robert Collins
* Plugins with the same name in different directories in the bzr plugin
707
                   'bzrlib.tests.test_plugins',
1185.33.92 by Martin Pool
[patch] fix for 'bzr rm -v' (Wouter van Heyst)
708
                   '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
709
                   'bzrlib.tests.test_revision',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
710
                   'bzrlib.tests.test_revisionnamespaces',
1518 by Robert Collins
Merge from mbp.
711
                   '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
712
                   'bzrlib.tests.test_reweave',
1185.47.1 by Martin Pool
[broken] start converting basic_io to more rfc822-like format
713
                   'bzrlib.tests.test_rio',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
714
                   'bzrlib.tests.test_sampler',
1185.51.1 by Martin Pool
Better message when failing to import a test suite.
715
                   'bzrlib.tests.test_selftest',
1185.33.89 by Martin Pool
[patch] add a selftest test that the setup build script works (Alexander Belchenko)
716
                   '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.
717
                   '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
718
                   'bzrlib.tests.test_smart_add',
1522 by Robert Collins
Test for the number of uses of self.working_tree() in branch.py
719
                   'bzrlib.tests.test_source',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
720
                   '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
721
                   'bzrlib.tests.test_store',
1534.2.1 by Robert Collins
Implement deprecated_method
722
                   'bzrlib.tests.test_symbol_versioning',
1518 by Robert Collins
Merge from mbp.
723
                   'bzrlib.tests.test_testament',
724
                   '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
725
                   'bzrlib.tests.test_transactions',
726
                   'bzrlib.tests.test_transport',
727
                   'bzrlib.tests.test_tsort',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
728
                   'bzrlib.tests.test_ui',
729
                   'bzrlib.tests.test_uncommit',
730
                   'bzrlib.tests.test_upgrade',
731
                   'bzrlib.tests.test_weave',
732
                   '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
733
                   'bzrlib.tests.test_workingtree',
1185.33.91 by Martin Pool
[merge] improved 'missing' command from aaron
734
                   'bzrlib.tests.test_xml',
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
735
                   ]
1530.1.3 by Robert Collins
transport implementations now tested consistently.
736
    test_transport_implementations = [
737
        'bzrlib.tests.test_transport_implementations']
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
738
1185.31.33 by John Arbash Meinel
A couple more path.join statements needed changing.
739
    TestCase.BZRPATH = osutils.pathjoin(
740
            osutils.realpath(osutils.dirname(bzrlib.__path__[0])), 'bzr')
1185.31.57 by John Arbash Meinel
[merge] bzr.dev
741
    print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
1185.51.1 by Martin Pool
Better message when failing to import a test suite.
742
    print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
744 by Martin Pool
- show nicer descriptions while running tests
743
    print
721 by Martin Pool
- framework for running external commands from unittest suite
744
    suite = TestSuite()
1185.51.1 by Martin Pool
Better message when failing to import a test suite.
745
    # python2.4's TestLoader.loadTestsFromNames gives very poor 
746
    # errors if it fails to load a named module - no indication of what's
747
    # actually wrong, just "no such module".  We should probably override that
748
    # class, but for the moment just load them ourselves. (mbp 20051202)
749
    loader = TestLoader()
1530.1.3 by Robert Collins
transport implementations now tested consistently.
750
    from bzrlib.transport import TransportTestProviderAdapter
751
    adapter = TransportTestProviderAdapter()
752
    for mod_name in test_transport_implementations:
753
        mod = _load_module_by_name(mod_name)
754
        for test in iter_suite_tests(loader.loadTestsFromModule(mod)):
755
            suite.addTests(adapter.adapt(test))
1185.51.1 by Martin Pool
Better message when failing to import a test suite.
756
    for mod_name in testmod_names:
757
        mod = _load_module_by_name(mod_name)
758
        suite.addTest(loader.loadTestsFromModule(mod))
1513 by Robert Collins
Blackbox tests are maintained within the bzrlib.tests.blackbox directory.
759
    for package in packages_to_test():
760
        suite.addTest(package.test_suite())
855 by Martin Pool
- Patch from John to allow plugins to add their own tests.
761
    for m in MODULES_TO_TEST:
1185.51.1 by Martin Pool
Better message when failing to import a test suite.
762
        suite.addTest(loader.loadTestsFromModule(m))
855 by Martin Pool
- Patch from John to allow plugins to add their own tests.
763
    for m in (MODULES_TO_DOCTEST):
721 by Martin Pool
- framework for running external commands from unittest suite
764
        suite.addTest(DocTestSuite(m))
1516 by Robert Collins
* bzrlib.plugin.all_plugins has been changed from an attribute to a
765
    for name, plugin in bzrlib.plugin.all_plugins().items():
766
        if hasattr(plugin, 'test_suite'):
767
            suite.addTest(plugin.test_suite())
1092.1.17 by Robert Collins
remove TEST_CLASSES dead code and provide a bzrlib.test_suite() convenience method
768
    return suite
764 by Martin Pool
- log messages from a particular test are printed if that test fails
769
1185.51.1 by Martin Pool
Better message when failing to import a test suite.
770
771
def _load_module_by_name(mod_name):
772
    parts = mod_name.split('.')
773
    module = __import__(mod_name)
774
    del parts[0]
775
    # for historical reasons python returns the top-level module even though
776
    # it loads the submodule; we need to walk down to get the one we want.
777
    while parts:
778
        module = getattr(module, parts.pop(0))
779
    return module