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