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