15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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)
25
from cStringIO import StringIO
40
import bzrlib.bzrdir as bzrdir
41
28
import bzrlib.commands
42
import bzrlib.errors as errors
43
import bzrlib.inventory
44
import bzrlib.iterablefile
47
import bzrlib.osutils as osutils
50
30
import bzrlib.trace
51
from bzrlib.transport import urlescape
52
import bzrlib.transport
53
from bzrlib.transport.local import LocalRelpathServer
54
from bzrlib.transport.readonly import ReadonlyServer
55
from bzrlib.trace import mutter
56
from bzrlib.tests.TestUtil import TestLoader, TestSuite
57
from bzrlib.tests.treeshape import build_tree_contents
58
from bzrlib.workingtree import WorkingTree, WorkingTreeFormat2
60
default_transport = LocalRelpathServer
62
34
MODULES_TO_TEST = []
63
MODULES_TO_DOCTEST = [
74
def packages_to_test():
75
"""Return a list of packages to test.
77
The packages are not globally imported so that import failures are
78
triggered when running selftest, not when importing the command.
81
import bzrlib.tests.blackbox
82
import bzrlib.tests.branch_implementations
83
import bzrlib.tests.bzrdir_implementations
84
import bzrlib.tests.repository_implementations
85
import bzrlib.tests.workingtree_implementations
88
bzrlib.tests.blackbox,
89
bzrlib.tests.branch_implementations,
90
bzrlib.tests.bzrdir_implementations,
91
bzrlib.tests.repository_implementations,
92
bzrlib.tests.workingtree_implementations,
96
class _MyResult(unittest._TextTestResult):
99
Shows output in a different format, including displaying runtime for tests.
103
def _elapsedTime(self):
104
return "%5dms" % (1000 * (time.time() - self._start_time))
106
def startTest(self, test):
107
unittest.TestResult.startTest(self, test)
108
# In a short description, the important words are in
109
# the beginning, but in an id, the important words are
111
SHOW_DESCRIPTIONS = False
113
width = osutils.terminal_width()
114
name_width = width - 15
116
if SHOW_DESCRIPTIONS:
117
what = test.shortDescription()
119
if len(what) > name_width:
120
what = what[:name_width-3] + '...'
123
if what.startswith('bzrlib.tests.'):
125
if len(what) > name_width:
126
what = '...' + what[3-name_width:]
127
what = what.ljust(name_width)
128
self.stream.write(what)
130
self._start_time = time.time()
132
def addError(self, test, err):
133
if isinstance(err[1], TestSkipped):
134
return self.addSkipped(test, err)
135
unittest.TestResult.addError(self, test, err)
137
self.stream.writeln("ERROR %s" % self._elapsedTime())
139
self.stream.write('E')
144
def addFailure(self, test, err):
145
unittest.TestResult.addFailure(self, test, err)
147
self.stream.writeln(" FAIL %s" % self._elapsedTime())
149
self.stream.write('F')
154
def addSuccess(self, test):
156
self.stream.writeln(' OK %s' % self._elapsedTime())
158
self.stream.write('~')
160
unittest.TestResult.addSuccess(self, test)
162
def addSkipped(self, test, skip_excinfo):
164
print >>self.stream, ' SKIP %s' % self._elapsedTime()
165
print >>self.stream, ' %s' % skip_excinfo[1]
167
self.stream.write('S')
169
# seems best to treat this as success from point-of-view of unittest
170
# -- it actually does nothing so it barely matters :)
171
unittest.TestResult.addSuccess(self, test)
173
def printErrorList(self, flavour, errors):
174
for test, err in errors:
175
self.stream.writeln(self.separator1)
176
self.stream.writeln("%s: %s" % (flavour, self.getDescription(test)))
177
if getattr(test, '_get_log', None) is not None:
179
print >>self.stream, \
180
('vvvv[log from %s]' % test.id()).ljust(78,'-')
181
print >>self.stream, test._get_log()
182
print >>self.stream, \
183
('^^^^[log from %s]' % test.id()).ljust(78,'-')
184
self.stream.writeln(self.separator2)
185
self.stream.writeln("%s" % err)
188
class TextTestRunner(unittest.TextTestRunner):
189
stop_on_failure = False
191
def _makeResult(self):
192
result = _MyResult(self.stream, self.descriptions, self.verbosity)
193
result.stop_early = self.stop_on_failure
197
def iter_suite_tests(suite):
198
"""Return all tests in a suite, recursing through nested suites"""
199
for item in suite._tests:
200
if isinstance(item, unittest.TestCase):
202
elif isinstance(item, unittest.TestSuite):
203
for r in iter_suite_tests(item):
206
raise Exception('unknown object %r inside test suite %r'
210
class TestSkipped(Exception):
211
"""Indicates that a test was intentionally skipped, rather than failing."""
35
MODULES_TO_DOCTEST = []
37
from logging import debug, warning, error
215
39
class CommandFailed(Exception):
224
48
Error and debug log messages are redirected from their usual
225
49
location into a temporary file, the contents of which can be
226
retrieved by _get_log(). We use a real OS file, not an in-memory object,
227
so that it can also capture file IO. When the test completes this file
228
is read into memory and removed from disk.
50
retrieved by _get_log().
230
52
There are also convenience functions to invoke bzr's command-line
231
routine, and to build and check bzr trees.
233
In addition to the usual method of overriding tearDown(), this class also
234
allows subclasses to register functions into the _cleanups list, which is
235
run in order as the object is torn down. It's less likely this will be
236
accidentally overlooked.
53
routine, and to build and check bzr trees."""
240
_log_file_name = None
243
def __init__(self, methodName='testMethod'):
244
super(TestCase, self).__init__(methodName)
58
# this replaces the default testsweet.TestCase; we don't want logging changed
248
59
unittest.TestCase.setUp(self)
249
self._cleanEnvironment()
250
60
bzrlib.trace.disable_default_logging()
253
def _ndiff_strings(self, a, b):
254
"""Return ndiff between two strings containing lines.
256
A trailing newline is added if missing to make the strings
258
if b and b[-1] != '\n':
260
if a and a[-1] != '\n':
262
difflines = difflib.ndiff(a.splitlines(True),
264
linejunk=lambda x: False,
265
charjunk=lambda x: False)
266
return ''.join(difflines)
268
def assertEqualDiff(self, a, b, message=None):
269
"""Assert two texts are equal, if not raise an exception.
271
This is intended for use with multi-line strings where it can
272
be hard to find the differences by eye.
274
# TODO: perhaps override assertEquals to call this for strings?
278
message = "texts not equal:\n"
279
raise AssertionError(message +
280
self._ndiff_strings(a, b))
282
def assertEqualMode(self, mode, mode_test):
283
self.assertEqual(mode, mode_test,
284
'mode mismatch %o != %o' % (mode, mode_test))
286
def assertStartsWith(self, s, prefix):
287
if not s.startswith(prefix):
288
raise AssertionError('string %r does not start with %r' % (s, prefix))
290
def assertEndsWith(self, s, suffix):
291
if not s.endswith(prefix):
292
raise AssertionError('string %r does not end with %r' % (s, suffix))
294
def assertContainsRe(self, haystack, needle_re):
295
"""Assert that a contains something matching a regular expression."""
296
if not re.search(needle_re, haystack):
297
raise AssertionError('pattern "%s" not found in "%s"'
298
% (needle_re, haystack))
300
def AssertSubset(self, sublist, superlist):
301
"""Assert that every entry in sublist is present in superlist."""
303
for entry in sublist:
304
if entry not in superlist:
305
missing.append(entry)
307
raise AssertionError("value(s) %r not present in container %r" %
308
(missing, superlist))
310
def assertIs(self, left, right):
311
if not (left is right):
312
raise AssertionError("%r is not %r." % (left, right))
314
def assertTransportMode(self, transport, path, mode):
315
"""Fail if a path does not have mode mode.
317
If modes are not supported on this platform, the test is skipped.
319
if sys.platform == 'win32':
321
path_stat = transport.stat(path)
322
actual_mode = stat.S_IMODE(path_stat.st_mode)
323
self.assertEqual(mode, actual_mode,
324
'mode of %r incorrect (%o != %o)' % (path, mode, actual_mode))
326
def _startLogFile(self):
327
"""Send bzr and test log messages to a temporary file.
329
The file is removed as the test is torn down.
61
self._enable_file_logging()
64
def _enable_file_logging(self):
331
65
fileno, name = tempfile.mkstemp(suffix='.log', prefix='testbzr')
332
encoder, decoder, stream_reader, stream_writer = codecs.lookup('UTF-8')
333
self._log_file = stream_writer(os.fdopen(fileno, 'w+'))
334
self._log_nonce = bzrlib.trace.enable_test_log(self._log_file)
67
self._log_file = os.fdopen(fileno, 'w+')
69
hdlr = logging.StreamHandler(self._log_file)
70
hdlr.setLevel(logging.DEBUG)
71
hdlr.setFormatter(logging.Formatter('%(levelname)8s %(message)s'))
72
logging.getLogger('').addHandler(hdlr)
73
logging.getLogger('').setLevel(logging.DEBUG)
75
debug('opened log file %s', name)
335
77
self._log_file_name = name
336
self.addCleanup(self._finishLogFile)
338
def _finishLogFile(self):
339
"""Finished with the log file.
341
Read contents into memory, close, and delete.
343
bzrlib.trace.disable_test_log(self._log_nonce)
344
self._log_file.seek(0)
345
self._log_contents = self._log_file.read()
81
logging.getLogger('').removeHandler(self._log_hdlr)
82
bzrlib.trace.enable_default_logging()
83
logging.debug('%s teardown', self.id())
346
84
self._log_file.close()
347
os.remove(self._log_file_name)
348
self._log_file = self._log_file_name = None
350
def addCleanup(self, callable):
351
"""Arrange to run a callable when this case is torn down.
353
Callables are run in the reverse of the order they are registered,
354
ie last-in first-out.
356
if callable in self._cleanups:
357
raise ValueError("cleanup function %r already registered on %s"
359
self._cleanups.append(callable)
361
def _cleanEnvironment(self):
364
'APPDATA': os.getcwd(),
369
self.addCleanup(self._restoreEnvironment)
370
for name, value in new_env.iteritems():
371
self._captureVar(name, value)
374
def _captureVar(self, name, newvalue):
375
"""Set an environment variable, preparing it to be reset when finished."""
376
self.__old_env[name] = os.environ.get(name, None)
378
if name in os.environ:
381
os.environ[name] = newvalue
384
def _restoreVar(name, value):
386
if name in os.environ:
389
os.environ[name] = value
391
def _restoreEnvironment(self):
392
for name, value in self.__old_env.iteritems():
393
self._restoreVar(name, value)
397
85
unittest.TestCase.tearDown(self)
399
def _runCleanups(self):
400
"""Run registered cleanup functions.
402
This should only be called from TestCase.tearDown.
404
# TODO: Perhaps this should keep running cleanups even if
406
for cleanup_fn in reversed(self._cleanups):
409
88
def log(self, *args):
412
91
def _get_log(self):
413
92
"""Return as a string the log for this test"""
414
if self._log_file_name:
415
return open(self._log_file_name).read()
417
return self._log_contents
418
# TODO: Delete the log after it's been read in
420
def capture(self, cmd, retcode=0):
421
"""Shortcut that splits cmd into words, runs, and returns stdout"""
422
return self.run_bzr_captured(cmd.split(), retcode=retcode)[0]
424
def run_bzr_captured(self, argv, retcode=0):
425
"""Invoke bzr and return (stdout, stderr).
427
Useful for code that wants to check the contents of the
428
output, the way error messages are presented, etc.
93
return open(self._log_file_name).read()
95
def run_bzr(self, *args, **kwargs):
96
"""Invoke bzr, as if it were run from the command line.
430
98
This should be the main method for tests that want to exercise the
431
99
overall behavior of the bzr application (rather than a unit test
577
201
# successfully created
578
TestCaseInTempDir.TEST_ROOT = osutils.abspath(root)
202
TestCaseInTempDir.TEST_ROOT = os.path.abspath(root)
580
204
# make a fake bzr directory there to prevent any tests propagating
581
205
# up onto the source directory's real branch
582
os.mkdir(osutils.pathjoin(TestCaseInTempDir.TEST_ROOT, '.bzr'))
206
os.mkdir(os.path.join(TestCaseInTempDir.TEST_ROOT, '.bzr'))
585
209
super(TestCaseInTempDir, self).setUp()
586
211
self._make_test_root()
587
_currentdir = os.getcwdu()
588
short_id = self.id().replace('bzrlib.tests.', '') \
212
self._currentdir = os.getcwdu()
213
short_id = self.id().replace('bzrlib.selftest.', '') \
589
214
.replace('__main__.', '')
590
self.test_dir = osutils.pathjoin(self.TEST_ROOT, short_id)
215
self.test_dir = os.path.join(self.TEST_ROOT, short_id)
591
216
os.mkdir(self.test_dir)
592
217
os.chdir(self.test_dir)
593
os.environ['HOME'] = self.test_dir
594
os.environ['APPDATA'] = self.test_dir
595
def _leaveDirectory():
596
os.chdir(_currentdir)
597
self.addCleanup(_leaveDirectory)
599
def build_tree(self, shape, line_endings='native', transport=None):
221
os.chdir(self._currentdir)
222
super(TestCaseInTempDir, self).tearDown()
224
def _formcmd(self, cmd):
225
if isinstance(cmd, basestring):
228
cmd[0] = self.BZRPATH
229
if self.OVERRIDE_PYTHON:
230
cmd.insert(0, self.OVERRIDE_PYTHON)
231
self.log('$ %r' % cmd)
234
def runcmd(self, cmd, retcode=0):
235
"""Run one command and check the return code.
237
Returns a tuple of (stdout,stderr) strings.
239
If a single string is based, it is split into words.
240
For commands that are not simple space-separated words, please
241
pass a list instead."""
242
cmd = self._formcmd(cmd)
243
self.log('$ ' + ' '.join(cmd))
244
actual_retcode = subprocess.call(cmd, stdout=self._log_file,
245
stderr=self._log_file)
246
if retcode != actual_retcode:
247
raise CommandFailed("test failed: %r returned %d, expected %d"
248
% (cmd, actual_retcode, retcode))
250
def backtick(self, cmd, retcode=0):
251
"""Run a command and return its output"""
252
cmd = self._formcmd(cmd)
253
child = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=self._log_file)
254
outd, errd = child.communicate()
256
actual_retcode = child.wait()
258
outd = outd.replace('\r', '')
260
if retcode != actual_retcode:
261
raise CommandFailed("test failed: %r returned %d, expected %d"
262
% (cmd, actual_retcode, retcode))
268
def build_tree(self, shape):
600
269
"""Build a test tree according to a pattern.
602
271
shape is a sequence of file specifications. If the final
603
272
character is '/', a directory is created.
605
274
This doesn't add anything to a branch.
606
:param line_endings: Either 'binary' or 'native'
607
in binary mode, exact contents are written
608
in native mode, the line endings match the
609
default platform endings.
611
:param transport: A transport to write to, for building trees on
612
VFS's. If the transport is readonly or None,
613
"." is opened automatically.
615
276
# XXX: It's OK to just create them using forward slashes on windows?
616
if transport is None or transport.is_readonly():
617
transport = bzrlib.transport.get_transport(".")
618
278
for name in shape:
619
self.assert_(isinstance(name, basestring))
279
assert isinstance(name, basestring)
620
280
if name[-1] == '/':
621
transport.mkdir(urlescape(name[:-1]))
623
if line_endings == 'binary':
625
elif line_endings == 'native':
628
raise errors.BzrError('Invalid line ending request %r' % (line_endings,))
629
content = "contents of %s%s" % (name, end)
630
transport.put(urlescape(name), StringIO(content))
632
def build_tree_contents(self, shape):
633
build_tree_contents(shape)
635
def failUnlessExists(self, path):
636
"""Fail unless path, which may be abs or relative, exists."""
637
self.failUnless(osutils.lexists(path))
639
def failIfExists(self, path):
640
"""Fail if path, which may be abs or relative, exists."""
641
self.failIf(osutils.lexists(path))
643
def assertFileEqual(self, content, path):
644
"""Fail if path does not contain 'content'."""
645
self.failUnless(osutils.lexists(path))
646
self.assertEqualDiff(content, open(path, 'r').read())
649
class TestCaseWithTransport(TestCaseInTempDir):
650
"""A test case that provides get_url and get_readonly_url facilities.
652
These back onto two transport servers, one for readonly access and one for
655
If no explicit class is provided for readonly access, a
656
ReadonlyTransportDecorator is used instead which allows the use of non disk
657
based read write transports.
659
If an explicit class is provided for readonly access, that server and the
660
readwrite one must both define get_url() as resolving to os.getcwd().
663
def __init__(self, methodName='testMethod'):
664
super(TestCaseWithTransport, self).__init__(methodName)
665
self.__readonly_server = None
667
self.transport_server = default_transport
668
self.transport_readonly_server = None
670
def get_readonly_url(self, relpath=None):
671
"""Get a URL for the readonly transport.
673
This will either be backed by '.' or a decorator to the transport
674
used by self.get_url()
675
relpath provides for clients to get a path relative to the base url.
676
These should only be downwards relative, not upwards.
678
base = self.get_readonly_server().get_url()
679
if relpath is not None:
680
if not base.endswith('/'):
682
base = base + relpath
685
def get_readonly_server(self):
686
"""Get the server instance for the readonly transport
688
This is useful for some tests with specific servers to do diagnostics.
690
if self.__readonly_server is None:
691
if self.transport_readonly_server is None:
692
# readonly decorator requested
693
# bring up the server
695
self.__readonly_server = ReadonlyServer()
696
self.__readonly_server.setUp(self.__server)
698
self.__readonly_server = self.transport_readonly_server()
699
self.__readonly_server.setUp()
700
self.addCleanup(self.__readonly_server.tearDown)
701
return self.__readonly_server
703
def get_server(self):
704
"""Get the read/write server instance.
706
This is useful for some tests with specific servers that need
709
if self.__server is None:
710
self.__server = self.transport_server()
711
self.__server.setUp()
712
self.addCleanup(self.__server.tearDown)
715
def get_url(self, relpath=None):
716
"""Get a URL for the readwrite transport.
718
This will either be backed by '.' or to an equivalent non-file based
720
relpath provides for clients to get a path relative to the base url.
721
These should only be downwards relative, not upwards.
723
base = self.get_server().get_url()
724
if relpath is not None and relpath != '.':
725
if not base.endswith('/'):
727
base = base + relpath
730
def make_branch(self, relpath):
731
"""Create a branch on the transport at relpath."""
732
repo = self.make_repository(relpath)
733
return repo.bzrdir.create_branch()
735
def make_bzrdir(self, relpath):
737
url = self.get_url(relpath)
738
segments = url.split('/')
739
if segments and segments[-1] not in ('', '.'):
740
parent = '/'.join(segments[:-1])
741
t = bzrlib.transport.get_transport(parent)
743
t.mkdir(segments[-1])
744
except errors.FileExists:
746
return bzrlib.bzrdir.BzrDir.create(url)
747
except errors.UninitializableFormat:
748
raise TestSkipped("Format %s is not initializable.")
750
def make_repository(self, relpath):
751
"""Create a repository on our default transport at relpath."""
752
made_control = self.make_bzrdir(relpath)
753
return made_control.create_repository()
755
def make_branch_and_tree(self, relpath):
756
"""Create a branch on the transport and a tree locally.
760
# TODO: always use the local disk path for the working tree,
761
# this obviously requires a format that supports branch references
762
# so check for that by checking bzrdir.BzrDirFormat.get_default_format()
764
b = self.make_branch(relpath)
766
return b.bzrdir.create_workingtree()
767
except errors.NotLocalUrl:
768
# new formats - catch No tree error and create
769
# a branch reference and a checkout.
770
# old formats at that point - raise TestSkipped.
772
return WorkingTreeFormat2().initialize(bzrdir.BzrDir.open(relpath))
775
class ChrootedTestCase(TestCaseWithTransport):
776
"""A support class that provides readonly urls outside the local namespace.
778
This is done by checking if self.transport_server is a MemoryServer. if it
779
is then we are chrooted already, if it is not then an HttpServer is used
782
TODO RBC 20060127: make this an option to TestCaseWithTransport so it can
783
be used without needed to redo it when a different
788
super(ChrootedTestCase, self).setUp()
789
if not self.transport_server == bzrlib.transport.memory.MemoryServer:
790
self.transport_readonly_server = bzrlib.transport.http.HttpServer
793
def filter_suite_by_re(suite, pattern):
795
filter_re = re.compile(pattern)
796
for test in iter_suite_tests(suite):
797
if filter_re.search(test.id()):
802
def run_suite(suite, name='test', verbose=False, pattern=".*",
803
stop_on_failure=False, keep_output=False,
805
TestCaseInTempDir._TEST_NAME = name
810
runner = TextTestRunner(stream=sys.stdout,
813
runner.stop_on_failure=stop_on_failure
815
suite = filter_suite_by_re(suite, pattern)
816
result = runner.run(suite)
817
# This is still a little bogus,
818
# but only a little. Folk not using our testrunner will
819
# have to delete their temp directories themselves.
820
if result.wasSuccessful() or not keep_output:
821
if TestCaseInTempDir.TEST_ROOT is not None:
822
shutil.rmtree(TestCaseInTempDir.TEST_ROOT)
824
print "Failed tests working directories are in '%s'\n" % TestCaseInTempDir.TEST_ROOT
825
return result.wasSuccessful()
828
def selftest(verbose=False, pattern=".*", stop_on_failure=True,
284
print >>f, "contents of", name
289
class MetaTestLog(TestCase):
290
def test_logging(self):
291
"""Test logs are captured when a test fails."""
292
logging.info('an info message')
293
warning('something looks dodgy...')
294
logging.debug('hello, test is running')
298
def selftest(verbose=False, pattern=".*"):
831
299
"""Run the whole test suite under the enhanced runner"""
832
global default_transport
833
if transport is None:
834
transport = default_transport
835
old_transport = default_transport
836
default_transport = transport
839
return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
840
stop_on_failure=stop_on_failure, keep_output=keep_output,
843
default_transport = old_transport
300
return testsweet.run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern)
847
303
def test_suite():
848
304
"""Build and return TestSuite for the whole program."""
305
from bzrlib.selftest.TestUtil import TestLoader, TestSuite
306
import bzrlib, bzrlib.store, bzrlib.inventory, bzrlib.branch
307
import bzrlib.osutils, bzrlib.commands, bzrlib.merge3, bzrlib.plugin
849
308
from doctest import DocTestSuite
851
global MODULES_TO_DOCTEST
854
'bzrlib.tests.test_ancestry',
855
'bzrlib.tests.test_annotate',
856
'bzrlib.tests.test_api',
857
'bzrlib.tests.test_bad_files',
858
'bzrlib.tests.test_basis_inventory',
859
'bzrlib.tests.test_branch',
860
'bzrlib.tests.test_bzrdir',
861
'bzrlib.tests.test_command',
862
'bzrlib.tests.test_commit',
863
'bzrlib.tests.test_commit_merge',
864
'bzrlib.tests.test_config',
865
'bzrlib.tests.test_conflicts',
866
'bzrlib.tests.test_decorators',
867
'bzrlib.tests.test_diff',
868
'bzrlib.tests.test_doc_generate',
869
'bzrlib.tests.test_errors',
870
'bzrlib.tests.test_fetch',
871
'bzrlib.tests.test_gpg',
872
'bzrlib.tests.test_graph',
873
'bzrlib.tests.test_hashcache',
874
'bzrlib.tests.test_http',
875
'bzrlib.tests.test_identitymap',
876
'bzrlib.tests.test_inv',
877
'bzrlib.tests.test_lockable_files',
878
'bzrlib.tests.test_log',
879
'bzrlib.tests.test_merge',
880
'bzrlib.tests.test_merge3',
881
'bzrlib.tests.test_merge_core',
882
'bzrlib.tests.test_missing',
883
'bzrlib.tests.test_msgeditor',
884
'bzrlib.tests.test_nonascii',
885
'bzrlib.tests.test_options',
886
'bzrlib.tests.test_osutils',
887
'bzrlib.tests.test_permissions',
888
'bzrlib.tests.test_plugins',
889
'bzrlib.tests.test_repository',
890
'bzrlib.tests.test_revision',
891
'bzrlib.tests.test_revisionnamespaces',
892
'bzrlib.tests.test_revprops',
893
'bzrlib.tests.test_reweave',
894
'bzrlib.tests.test_rio',
895
'bzrlib.tests.test_sampler',
896
'bzrlib.tests.test_selftest',
897
'bzrlib.tests.test_setup',
898
'bzrlib.tests.test_sftp_transport',
899
'bzrlib.tests.test_smart_add',
900
'bzrlib.tests.test_source',
901
'bzrlib.tests.test_store',
902
'bzrlib.tests.test_symbol_versioning',
903
'bzrlib.tests.test_testament',
904
'bzrlib.tests.test_trace',
905
'bzrlib.tests.test_transactions',
906
'bzrlib.tests.test_transport',
907
'bzrlib.tests.test_tsort',
908
'bzrlib.tests.test_ui',
909
'bzrlib.tests.test_uncommit',
910
'bzrlib.tests.test_upgrade',
911
'bzrlib.tests.test_weave',
912
'bzrlib.tests.test_whitebox',
913
'bzrlib.tests.test_workingtree',
914
'bzrlib.tests.test_xml',
314
global MODULES_TO_TEST, MODULES_TO_DOCTEST
317
['bzrlib.selftest.MetaTestLog',
318
'bzrlib.selftest.testinv',
319
'bzrlib.selftest.test_commit',
320
'bzrlib.selftest.versioning',
321
'bzrlib.selftest.testmerge3',
322
'bzrlib.selftest.testhashcache',
323
'bzrlib.selftest.teststatus',
324
'bzrlib.selftest.testlog',
325
'bzrlib.selftest.testrevisionnamespaces',
326
'bzrlib.selftest.testbranch',
327
'bzrlib.selftest.testrevision',
328
'bzrlib.selftest.test_merge_core',
329
'bzrlib.selftest.test_smart_add',
330
'bzrlib.selftest.testdiff',
331
'bzrlib.selftest.test_parent',
332
'bzrlib.selftest.test_xml',
333
'bzrlib.selftest.test_weave',
334
'bzrlib.selftest.testfetch',
335
'bzrlib.selftest.whitebox',
336
'bzrlib.selftest.teststore',
337
'bzrlib.selftest.blackbox',
916
test_transport_implementations = [
917
'bzrlib.tests.test_transport_implementations']
919
TestCase.BZRPATH = osutils.pathjoin(
920
osutils.realpath(osutils.dirname(bzrlib.__path__[0])), 'bzr')
921
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
922
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
340
for m in (bzrlib.store, bzrlib.inventory, bzrlib.branch,
341
bzrlib.osutils, bzrlib.commands, bzrlib.merge3):
342
if m not in MODULES_TO_DOCTEST:
343
MODULES_TO_DOCTEST.append(m)
345
TestCase.BZRPATH = os.path.join(os.path.realpath(os.path.dirname(bzrlib.__path__[0])), 'bzr')
346
print '%-30s %s' % ('bzr binary', TestCase.BZRPATH)
924
348
suite = TestSuite()
925
# python2.4's TestLoader.loadTestsFromNames gives very poor
926
# errors if it fails to load a named module - no indication of what's
927
# actually wrong, just "no such module". We should probably override that
928
# class, but for the moment just load them ourselves. (mbp 20051202)
929
loader = TestLoader()
930
from bzrlib.transport import TransportTestProviderAdapter
931
adapter = TransportTestProviderAdapter()
932
adapt_modules(test_transport_implementations, adapter, loader, suite)
933
for mod_name in testmod_names:
934
mod = _load_module_by_name(mod_name)
935
suite.addTest(loader.loadTestsFromModule(mod))
936
for package in packages_to_test():
937
suite.addTest(package.test_suite())
349
suite.addTest(TestLoader().loadTestsFromNames(testmod_names))
938
350
for m in MODULES_TO_TEST:
939
suite.addTest(loader.loadTestsFromModule(m))
351
suite.addTest(TestLoader().loadTestsFromModule(m))
940
352
for m in (MODULES_TO_DOCTEST):
941
353
suite.addTest(DocTestSuite(m))
942
for name, plugin in bzrlib.plugin.all_plugins().items():
943
if getattr(plugin, 'test_suite', None) is not None:
944
suite.addTest(plugin.test_suite())
354
for p in bzrlib.plugin.all_plugins:
355
if hasattr(p, 'test_suite'):
356
suite.addTest(p.test_suite())
948
def adapt_modules(mods_list, adapter, loader, suite):
949
"""Adapt the modules in mods_list using adapter and add to suite."""
950
for mod_name in mods_list:
951
mod = _load_module_by_name(mod_name)
952
for test in iter_suite_tests(loader.loadTestsFromModule(mod)):
953
suite.addTests(adapter.adapt(test))
956
def _load_module_by_name(mod_name):
957
parts = mod_name.split('.')
958
module = __import__(mod_name)
960
# for historical reasons python returns the top-level module even though
961
# it loads the submodule; we need to walk down to get the one we want.
963
module = getattr(module, parts.pop(0))