40
import bzrlib.bzrdir as bzrdir
30
41
import bzrlib.commands
42
import bzrlib.errors as errors
43
import bzrlib.inventory
44
import bzrlib.iterablefile
47
import bzrlib.osutils as osutils
31
50
import bzrlib.trace
33
import bzrlib.osutils as osutils
34
from bzrlib.selftest import TestUtil
35
from bzrlib.selftest.TestUtil import TestLoader, TestSuite
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
38
62
MODULES_TO_TEST = []
39
MODULES_TO_DOCTEST = []
41
from logging import debug, warning, error
45
class EarlyStoppingTestResultAdapter(object):
46
"""An adapter for TestResult to stop at the first first failure or error"""
48
def __init__(self, result):
51
def addError(self, test, err):
52
self._result.addError(test, err)
55
def addFailure(self, test, err):
56
self._result.addFailure(test, err)
59
def __getattr__(self, name):
60
return getattr(self._result, name)
62
def __setattr__(self, name, value):
64
object.__setattr__(self, name, value)
65
return setattr(self._result, name, value)
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,
68
96
class _MyResult(unittest._TextTestResult):
72
No special behaviour for now.
99
Shows output in a different format, including displaying runtime for tests.
75
103
def _elapsedTime(self):
76
return "(Took %.3fs)" % (time.time() - self._start_time)
104
return "%5dms" % (1000 * (time.time() - self._start_time))
78
106
def startTest(self, test):
79
107
unittest.TestResult.startTest(self, test)
80
# TODO: Maybe show test.shortDescription somewhere?
81
what = test.shortDescription() or test.id()
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
83
self.stream.write('%-70.70s' % what)
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)
84
129
self.stream.flush()
85
130
self._start_time = time.time()
87
132
def addError(self, test, err):
133
if isinstance(err[1], TestSkipped):
134
return self.addSkipped(test, err)
88
135
unittest.TestResult.addError(self, test, err)
90
137
self.stream.writeln("ERROR %s" % self._elapsedTime())
92
139
self.stream.write('E')
93
140
self.stream.flush()
95
144
def addFailure(self, test, err):
96
145
unittest.TestResult.addFailure(self, test, err)
98
self.stream.writeln("FAIL %s" % self._elapsedTime())
147
self.stream.writeln(" FAIL %s" % self._elapsedTime())
100
149
self.stream.write('F')
101
150
self.stream.flush()
103
154
def addSuccess(self, test):
105
self.stream.writeln('OK %s' % self._elapsedTime())
156
self.stream.writeln(' OK %s' % self._elapsedTime())
107
158
self.stream.write('~')
108
159
self.stream.flush()
109
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)
111
173
def printErrorList(self, flavour, errors):
112
174
for test, err in errors:
113
175
self.stream.writeln(self.separator1)
114
self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
115
if hasattr(test, '_get_log'):
116
self.stream.writeln()
117
self.stream.writeln('log from this test:')
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,'-')
118
181
print >>self.stream, test._get_log()
182
print >>self.stream, \
183
('^^^^[log from %s]' % test.id()).ljust(78,'-')
119
184
self.stream.writeln(self.separator2)
120
185
self.stream.writeln("%s" % err)
123
188
class TextTestRunner(unittest.TextTestRunner):
189
stop_on_failure = False
125
191
def _makeResult(self):
126
192
result = _MyResult(self.stream, self.descriptions, self.verbosity)
127
return EarlyStoppingTestResultAdapter(result)
193
result.stop_early = self.stop_on_failure
130
197
def iter_suite_tests(suite):
186
274
# TODO: perhaps override assertEquals to call this for strings?
189
raise AssertionError("texts not equal:\n" +
278
message = "texts not equal:\n"
279
raise AssertionError(message +
190
280
self._ndiff_strings(a, b))
192
def _enable_file_logging(self):
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.
193
331
fileno, name = tempfile.mkstemp(suffix='.log', prefix='testbzr')
195
self._log_file = os.fdopen(fileno, 'w+')
197
hdlr = logging.StreamHandler(self._log_file)
198
hdlr.setLevel(logging.DEBUG)
199
hdlr.setFormatter(logging.Formatter('%(levelname)8s %(message)s'))
200
logging.getLogger('').addHandler(hdlr)
201
logging.getLogger('').setLevel(logging.DEBUG)
202
self._log_hdlr = hdlr
203
debug('opened log file %s', name)
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)
205
335
self._log_file_name = name
208
logging.getLogger('').removeHandler(self._log_hdlr)
209
bzrlib.trace.enable_default_logging()
210
logging.debug('%s teardown', self.id())
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()
211
346
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)
212
397
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):
214
409
def log(self, *args):
217
412
def _get_log(self):
218
413
"""Return as a string the log for this test"""
219
414
if self._log_file_name:
220
415
return open(self._log_file_name).read()
417
return self._log_contents
418
# TODO: Delete the log after it's been read in
224
def capture(self, cmd):
420
def capture(self, cmd, retcode=0):
225
421
"""Shortcut that splits cmd into words, runs, and returns stdout"""
226
return self.run_bzr_captured(cmd.split())[0]
422
return self.run_bzr_captured(cmd.split(), retcode=retcode)[0]
228
424
def run_bzr_captured(self, argv, retcode=0):
229
"""Invoke bzr and return (result, stdout, stderr).
425
"""Invoke bzr and return (stdout, stderr).
231
427
Useful for code that wants to check the contents of the
232
428
output, the way error messages are presented, etc.
380
577
# successfully created
381
TestCaseInTempDir.TEST_ROOT = os.path.abspath(root)
578
TestCaseInTempDir.TEST_ROOT = osutils.abspath(root)
383
580
# make a fake bzr directory there to prevent any tests propagating
384
581
# up onto the source directory's real branch
385
os.mkdir(os.path.join(TestCaseInTempDir.TEST_ROOT, '.bzr'))
582
os.mkdir(osutils.pathjoin(TestCaseInTempDir.TEST_ROOT, '.bzr'))
388
585
super(TestCaseInTempDir, self).setUp()
389
586
self._make_test_root()
390
self._currentdir = os.getcwdu()
391
short_id = self.id().replace('bzrlib.selftest.', '') \
587
_currentdir = os.getcwdu()
588
short_id = self.id().replace('bzrlib.tests.', '') \
392
589
.replace('__main__.', '')
393
self.test_dir = os.path.join(self.TEST_ROOT, short_id)
590
self.test_dir = osutils.pathjoin(self.TEST_ROOT, short_id)
394
591
os.mkdir(self.test_dir)
395
592
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)
398
os.chdir(self._currentdir)
399
super(TestCaseInTempDir, self).tearDown()
401
def build_tree(self, shape):
599
def build_tree(self, shape, line_endings='native', transport=None):
402
600
"""Build a test tree according to a pattern.
404
602
shape is a sequence of file specifications. If the final
405
603
character is '/', a directory is created.
407
605
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.
409
615
# 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(".")
410
618
for name in shape:
411
assert isinstance(name, basestring)
619
self.assert_(isinstance(name, basestring))
412
620
if name[-1] == '/':
621
transport.mkdir(urlescape(name[:-1]))
416
print >>f, "contents of", name
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)
419
635
def failUnlessExists(self, path):
420
636
"""Fail unless path, which may be abs or relative, exists."""
421
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))
424
class MetaTestLog(TestCase):
425
def test_logging(self):
426
"""Test logs are captured when a test fails."""
427
logging.info('an info message')
428
warning('something looks dodgy...')
429
logging.debug('hello, test is running')
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, shared=False):
751
"""Create a repository on our default transport at relpath."""
752
made_control = self.make_bzrdir(relpath)
753
return made_control.create_repository(shared=shared)
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
433
793
def filter_suite_by_re(suite, pattern):
434
result = TestUtil.TestSuite()
435
795
filter_re = re.compile(pattern)
436
796
for test in iter_suite_tests(suite):
437
797
if filter_re.search(test.id()):
462
825
return result.wasSuccessful()
465
def selftest(verbose=False, pattern=".*"):
828
def selftest(verbose=False, pattern=".*", stop_on_failure=True,
466
831
"""Run the whole test suite under the enhanced runner"""
467
return run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern)
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
470
847
def test_suite():
471
848
"""Build and return TestSuite for the whole program."""
472
import bzrlib.store, bzrlib.inventory, bzrlib.branch
473
import bzrlib.osutils, bzrlib.merge3, bzrlib.plugin
474
849
from doctest import DocTestSuite
476
global MODULES_TO_TEST, MODULES_TO_DOCTEST
851
global MODULES_TO_DOCTEST
479
['bzrlib.selftest.MetaTestLog',
480
'bzrlib.selftest.testidentitymap',
481
'bzrlib.selftest.testinv',
482
'bzrlib.selftest.test_ancestry',
483
'bzrlib.selftest.test_commit',
484
'bzrlib.selftest.test_commit_merge',
485
'bzrlib.selftest.testconfig',
486
'bzrlib.selftest.versioning',
487
'bzrlib.selftest.testmerge3',
488
'bzrlib.selftest.testmerge',
489
'bzrlib.selftest.testhashcache',
490
'bzrlib.selftest.teststatus',
491
'bzrlib.selftest.testlog',
492
'bzrlib.selftest.testrevisionnamespaces',
493
'bzrlib.selftest.testbranch',
494
'bzrlib.selftest.testrevision',
495
'bzrlib.selftest.test_revision_info',
496
'bzrlib.selftest.test_merge_core',
497
'bzrlib.selftest.test_smart_add',
498
'bzrlib.selftest.test_bad_files',
499
'bzrlib.selftest.testdiff',
500
'bzrlib.selftest.test_parent',
501
'bzrlib.selftest.test_xml',
502
'bzrlib.selftest.test_weave',
503
'bzrlib.selftest.testfetch',
504
'bzrlib.selftest.whitebox',
505
'bzrlib.selftest.teststore',
506
'bzrlib.selftest.blackbox',
507
'bzrlib.selftest.testsampler',
508
'bzrlib.selftest.testtransactions',
509
'bzrlib.selftest.testtransport',
510
'bzrlib.selftest.testgraph',
511
'bzrlib.selftest.testworkingtree',
512
'bzrlib.selftest.test_upgrade',
513
'bzrlib.selftest.test_conflicts',
514
'bzrlib.selftest.testtestament',
515
'bzrlib.selftest.testannotate',
516
'bzrlib.selftest.testrevprops',
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',
519
for m in (bzrlib.store, bzrlib.inventory, bzrlib.branch,
520
bzrlib.osutils, bzrlib.commands, bzrlib.merge3):
521
if m not in MODULES_TO_DOCTEST:
522
MODULES_TO_DOCTEST.append(m)
524
TestCase.BZRPATH = os.path.join(os.path.realpath(os.path.dirname(bzrlib.__path__[0])), 'bzr')
525
print '%-30s %s' % ('bzr binary', TestCase.BZRPATH)
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])
527
924
suite = TestSuite()
528
suite.addTest(TestLoader().loadTestsFromNames(testmod_names))
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())
529
938
for m in MODULES_TO_TEST:
530
suite.addTest(TestLoader().loadTestsFromModule(m))
939
suite.addTest(loader.loadTestsFromModule(m))
531
940
for m in (MODULES_TO_DOCTEST):
532
941
suite.addTest(DocTestSuite(m))
533
for p in bzrlib.plugin.all_plugins:
534
if hasattr(p, 'test_suite'):
535
suite.addTest(p.test_suite())
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())
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))