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
25
from testsweet import run_suite
41
26
import bzrlib.commands
42
import bzrlib.errors as errors
43
import bzrlib.inventory
44
import bzrlib.iterablefile
48
import bzrlib.osutils as osutils
51
28
import bzrlib.trace
52
from bzrlib.transport import urlescape, get_transport
53
import bzrlib.transport
54
from bzrlib.transport.local import LocalRelpathServer
55
from bzrlib.transport.readonly import ReadonlyServer
56
from bzrlib.trace import mutter
57
from bzrlib.tests.TestUtil import TestLoader, TestSuite
58
from bzrlib.tests.treeshape import build_tree_contents
59
from bzrlib.workingtree import WorkingTree, WorkingTreeFormat2
61
default_transport = LocalRelpathServer
63
32
MODULES_TO_TEST = []
64
MODULES_TO_DOCTEST = [
76
def packages_to_test():
77
"""Return a list of packages to test.
79
The packages are not globally imported so that import failures are
80
triggered when running selftest, not when importing the command.
83
import bzrlib.tests.blackbox
84
import bzrlib.tests.branch_implementations
85
import bzrlib.tests.bzrdir_implementations
86
import bzrlib.tests.interrepository_implementations
87
import bzrlib.tests.interversionedfile_implementations
88
import bzrlib.tests.repository_implementations
89
import bzrlib.tests.revisionstore_implementations
90
import bzrlib.tests.workingtree_implementations
93
bzrlib.tests.blackbox,
94
bzrlib.tests.branch_implementations,
95
bzrlib.tests.bzrdir_implementations,
96
bzrlib.tests.interrepository_implementations,
97
bzrlib.tests.interversionedfile_implementations,
98
bzrlib.tests.repository_implementations,
99
bzrlib.tests.revisionstore_implementations,
100
bzrlib.tests.workingtree_implementations,
104
class _MyResult(unittest._TextTestResult):
105
"""Custom TestResult.
107
Shows output in a different format, including displaying runtime for tests.
111
def _elapsedTime(self):
112
return "%5dms" % (1000 * (time.time() - self._start_time))
114
def startTest(self, test):
115
unittest.TestResult.startTest(self, test)
116
# In a short description, the important words are in
117
# the beginning, but in an id, the important words are
119
SHOW_DESCRIPTIONS = False
121
width = osutils.terminal_width()
122
name_width = width - 15
124
if SHOW_DESCRIPTIONS:
125
what = test.shortDescription()
127
if len(what) > name_width:
128
what = what[:name_width-3] + '...'
131
if what.startswith('bzrlib.tests.'):
133
if len(what) > name_width:
134
what = '...' + what[3-name_width:]
135
what = what.ljust(name_width)
136
self.stream.write(what)
138
self._start_time = time.time()
140
def addError(self, test, err):
141
if isinstance(err[1], TestSkipped):
142
return self.addSkipped(test, err)
143
unittest.TestResult.addError(self, test, err)
145
self.stream.writeln("ERROR %s" % self._elapsedTime())
147
self.stream.write('E')
152
def addFailure(self, test, err):
153
unittest.TestResult.addFailure(self, test, err)
155
self.stream.writeln(" FAIL %s" % self._elapsedTime())
157
self.stream.write('F')
162
def addSuccess(self, test):
164
self.stream.writeln(' OK %s' % self._elapsedTime())
166
self.stream.write('~')
168
unittest.TestResult.addSuccess(self, test)
170
def addSkipped(self, test, skip_excinfo):
172
print >>self.stream, ' SKIP %s' % self._elapsedTime()
173
print >>self.stream, ' %s' % skip_excinfo[1]
175
self.stream.write('S')
177
# seems best to treat this as success from point-of-view of unittest
178
# -- it actually does nothing so it barely matters :)
179
unittest.TestResult.addSuccess(self, test)
181
def printErrorList(self, flavour, errors):
182
for test, err in errors:
183
self.stream.writeln(self.separator1)
184
self.stream.writeln("%s: %s" % (flavour, self.getDescription(test)))
185
if getattr(test, '_get_log', None) is not None:
187
print >>self.stream, \
188
('vvvv[log from %s]' % test.id()).ljust(78,'-')
189
print >>self.stream, test._get_log()
190
print >>self.stream, \
191
('^^^^[log from %s]' % test.id()).ljust(78,'-')
192
self.stream.writeln(self.separator2)
193
self.stream.writeln("%s" % err)
196
class TextTestRunner(unittest.TextTestRunner):
197
stop_on_failure = False
199
def _makeResult(self):
200
result = _MyResult(self.stream, self.descriptions, self.verbosity)
201
result.stop_early = self.stop_on_failure
205
def iter_suite_tests(suite):
206
"""Return all tests in a suite, recursing through nested suites"""
207
for item in suite._tests:
208
if isinstance(item, unittest.TestCase):
210
elif isinstance(item, unittest.TestSuite):
211
for r in iter_suite_tests(item):
214
raise Exception('unknown object %r inside test suite %r'
218
class TestSkipped(Exception):
219
"""Indicates that a test was intentionally skipped, rather than failing."""
33
MODULES_TO_DOCTEST = []
35
from logging import debug, warning, error
223
37
class CommandFailed(Exception):
232
46
Error and debug log messages are redirected from their usual
233
47
location into a temporary file, the contents of which can be
234
retrieved by _get_log(). We use a real OS file, not an in-memory object,
235
so that it can also capture file IO. When the test completes this file
236
is read into memory and removed from disk.
48
retrieved by _get_log().
238
50
There are also convenience functions to invoke bzr's command-line
239
routine, and to build and check bzr trees.
241
In addition to the usual method of overriding tearDown(), this class also
242
allows subclasses to register functions into the _cleanups list, which is
243
run in order as the object is torn down. It's less likely this will be
244
accidentally overlooked.
51
routine, and to build and check bzr trees."""
248
_log_file_name = None
251
def __init__(self, methodName='testMethod'):
252
super(TestCase, self).__init__(methodName)
56
# this replaces the default testsweet.TestCase; we don't want logging changed
256
57
unittest.TestCase.setUp(self)
257
self._cleanEnvironment()
258
58
bzrlib.trace.disable_default_logging()
261
def _ndiff_strings(self, a, b):
262
"""Return ndiff between two strings containing lines.
264
A trailing newline is added if missing to make the strings
266
if b and b[-1] != '\n':
268
if a and a[-1] != '\n':
270
difflines = difflib.ndiff(a.splitlines(True),
272
linejunk=lambda x: False,
273
charjunk=lambda x: False)
274
return ''.join(difflines)
276
def assertEqualDiff(self, a, b, message=None):
277
"""Assert two texts are equal, if not raise an exception.
279
This is intended for use with multi-line strings where it can
280
be hard to find the differences by eye.
282
# TODO: perhaps override assertEquals to call this for strings?
286
message = "texts not equal:\n"
287
raise AssertionError(message +
288
self._ndiff_strings(a, b))
290
def assertEqualMode(self, mode, mode_test):
291
self.assertEqual(mode, mode_test,
292
'mode mismatch %o != %o' % (mode, mode_test))
294
def assertStartsWith(self, s, prefix):
295
if not s.startswith(prefix):
296
raise AssertionError('string %r does not start with %r' % (s, prefix))
298
def assertEndsWith(self, s, suffix):
299
if not s.endswith(prefix):
300
raise AssertionError('string %r does not end with %r' % (s, suffix))
302
def assertContainsRe(self, haystack, needle_re):
303
"""Assert that a contains something matching a regular expression."""
304
if not re.search(needle_re, haystack):
305
raise AssertionError('pattern "%s" not found in "%s"'
306
% (needle_re, haystack))
308
def assertSubset(self, sublist, superlist):
309
"""Assert that every entry in sublist is present in superlist."""
311
for entry in sublist:
312
if entry not in superlist:
313
missing.append(entry)
315
raise AssertionError("value(s) %r not present in container %r" %
316
(missing, superlist))
318
def assertIs(self, left, right):
319
if not (left is right):
320
raise AssertionError("%r is not %r." % (left, right))
322
def assertTransportMode(self, transport, path, mode):
323
"""Fail if a path does not have mode mode.
325
If modes are not supported on this platform, the test is skipped.
327
if sys.platform == 'win32':
329
path_stat = transport.stat(path)
330
actual_mode = stat.S_IMODE(path_stat.st_mode)
331
self.assertEqual(mode, actual_mode,
332
'mode of %r incorrect (%o != %o)' % (path, mode, actual_mode))
334
def _startLogFile(self):
335
"""Send bzr and test log messages to a temporary file.
337
The file is removed as the test is torn down.
59
self._enable_file_logging()
62
def _enable_file_logging(self):
339
63
fileno, name = tempfile.mkstemp(suffix='.log', prefix='testbzr')
340
encoder, decoder, stream_reader, stream_writer = codecs.lookup('UTF-8')
341
self._log_file = stream_writer(os.fdopen(fileno, 'w+'))
342
self._log_nonce = bzrlib.trace.enable_test_log(self._log_file)
65
self._log_file = os.fdopen(fileno, 'w+')
67
hdlr = logging.StreamHandler(self._log_file)
68
hdlr.setLevel(logging.DEBUG)
69
hdlr.setFormatter(logging.Formatter('%(levelname)8s %(message)s'))
70
logging.getLogger('').addHandler(hdlr)
71
logging.getLogger('').setLevel(logging.DEBUG)
73
debug('opened log file %s', name)
343
75
self._log_file_name = name
344
self.addCleanup(self._finishLogFile)
346
def _finishLogFile(self):
347
"""Finished with the log file.
349
Read contents into memory, close, and delete.
351
bzrlib.trace.disable_test_log(self._log_nonce)
352
self._log_file.seek(0)
353
self._log_contents = self._log_file.read()
79
logging.getLogger('').removeHandler(self._log_hdlr)
80
bzrlib.trace.enable_default_logging()
81
logging.debug('%s teardown', self.id())
354
82
self._log_file.close()
355
os.remove(self._log_file_name)
356
self._log_file = self._log_file_name = None
358
def addCleanup(self, callable):
359
"""Arrange to run a callable when this case is torn down.
361
Callables are run in the reverse of the order they are registered,
362
ie last-in first-out.
364
if callable in self._cleanups:
365
raise ValueError("cleanup function %r already registered on %s"
367
self._cleanups.append(callable)
369
def _cleanEnvironment(self):
372
'APPDATA': os.getcwd(),
377
self.addCleanup(self._restoreEnvironment)
378
for name, value in new_env.iteritems():
379
self._captureVar(name, value)
382
def _captureVar(self, name, newvalue):
383
"""Set an environment variable, preparing it to be reset when finished."""
384
self.__old_env[name] = os.environ.get(name, None)
386
if name in os.environ:
389
os.environ[name] = newvalue
392
def _restoreVar(name, value):
394
if name in os.environ:
397
os.environ[name] = value
399
def _restoreEnvironment(self):
400
for name, value in self.__old_env.iteritems():
401
self._restoreVar(name, value)
405
83
unittest.TestCase.tearDown(self)
407
def _runCleanups(self):
408
"""Run registered cleanup functions.
410
This should only be called from TestCase.tearDown.
412
# TODO: Perhaps this should keep running cleanups even if
414
for cleanup_fn in reversed(self._cleanups):
417
86
def log(self, *args):
420
89
def _get_log(self):
421
90
"""Return as a string the log for this test"""
422
if self._log_file_name:
423
return open(self._log_file_name).read()
425
return self._log_contents
426
# TODO: Delete the log after it's been read in
428
def capture(self, cmd, retcode=0):
429
"""Shortcut that splits cmd into words, runs, and returns stdout"""
430
return self.run_bzr_captured(cmd.split(), retcode=retcode)[0]
432
def run_bzr_captured(self, argv, retcode=0):
433
"""Invoke bzr and return (stdout, stderr).
435
Useful for code that wants to check the contents of the
436
output, the way error messages are presented, etc.
91
return open(self._log_file_name).read()
93
def run_bzr(self, *args, **kwargs):
94
"""Invoke bzr, as if it were run from the command line.
438
96
This should be the main method for tests that want to exercise the
439
97
overall behavior of the bzr application (rather than a unit test
566
181
if contents != expect:
567
182
self.log("expected: %r" % expect)
568
183
self.log("actually: %r" % contents)
569
self.fail("contents of %s not as expected" % filename)
184
self.fail("contents of %s not as expected")
571
186
def _make_test_root(self):
572
191
if TestCaseInTempDir.TEST_ROOT is not None:
576
root = u'test%04d.tmp' % i
580
if e.errno == errno.EEXIST:
585
# successfully created
586
TestCaseInTempDir.TEST_ROOT = osutils.abspath(root)
193
TestCaseInTempDir.TEST_ROOT = os.path.abspath(
194
tempfile.mkdtemp(suffix='.tmp',
195
prefix=self._TEST_NAME + '-',
588
198
# make a fake bzr directory there to prevent any tests propagating
589
199
# up onto the source directory's real branch
590
bzrdir.BzrDir.create_standalone_workingtree(TestCaseInTempDir.TEST_ROOT)
200
os.mkdir(os.path.join(TestCaseInTempDir.TEST_ROOT, '.bzr'))
593
203
super(TestCaseInTempDir, self).setUp()
594
205
self._make_test_root()
595
_currentdir = os.getcwdu()
596
short_id = self.id().replace('bzrlib.tests.', '') \
597
.replace('__main__.', '')
598
self.test_dir = osutils.pathjoin(self.TEST_ROOT, short_id)
206
self._currentdir = os.getcwdu()
207
short_id = self.id().replace('bzrlib.selftest.', '')
208
self.test_dir = os.path.join(self.TEST_ROOT, short_id)
599
209
os.mkdir(self.test_dir)
600
210
os.chdir(self.test_dir)
601
os.environ['HOME'] = self.test_dir
602
os.environ['APPDATA'] = self.test_dir
603
def _leaveDirectory():
604
os.chdir(_currentdir)
605
self.addCleanup(_leaveDirectory)
607
def build_tree(self, shape, line_endings='native', transport=None):
214
os.chdir(self._currentdir)
215
super(TestCaseInTempDir, self).tearDown()
217
def _formcmd(self, cmd):
218
if isinstance(cmd, basestring):
221
cmd[0] = self.BZRPATH
222
if self.OVERRIDE_PYTHON:
223
cmd.insert(0, self.OVERRIDE_PYTHON)
224
self.log('$ %r' % cmd)
227
def runcmd(self, cmd, retcode=0):
228
"""Run one command and check the return code.
230
Returns a tuple of (stdout,stderr) strings.
232
If a single string is based, it is split into words.
233
For commands that are not simple space-separated words, please
234
pass a list instead."""
235
cmd = self._formcmd(cmd)
236
self.log('$ ' + ' '.join(cmd))
237
actual_retcode = subprocess.call(cmd, stdout=self._log_file,
238
stderr=self._log_file)
239
if retcode != actual_retcode:
240
raise CommandFailed("test failed: %r returned %d, expected %d"
241
% (cmd, actual_retcode, retcode))
243
def backtick(self, cmd, retcode=0):
244
"""Run a command and return its output"""
245
cmd = self._formcmd(cmd)
246
child = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=self._log_file)
247
outd, errd = child.communicate()
249
actual_retcode = child.wait()
251
outd = outd.replace('\r', '')
253
if retcode != actual_retcode:
254
raise CommandFailed("test failed: %r returned %d, expected %d"
255
% (cmd, actual_retcode, retcode))
261
def build_tree(self, shape):
608
262
"""Build a test tree according to a pattern.
610
264
shape is a sequence of file specifications. If the final
611
265
character is '/', a directory is created.
613
267
This doesn't add anything to a branch.
614
:param line_endings: Either 'binary' or 'native'
615
in binary mode, exact contents are written
616
in native mode, the line endings match the
617
default platform endings.
619
:param transport: A transport to write to, for building trees on
620
VFS's. If the transport is readonly or None,
621
"." is opened automatically.
623
269
# XXX: It's OK to just create them using forward slashes on windows?
624
if transport is None or transport.is_readonly():
625
transport = get_transport(".")
626
271
for name in shape:
627
self.assert_(isinstance(name, basestring))
272
assert isinstance(name, basestring)
628
273
if name[-1] == '/':
629
transport.mkdir(urlescape(name[:-1]))
631
if line_endings == 'binary':
633
elif line_endings == 'native':
636
raise errors.BzrError('Invalid line ending request %r' % (line_endings,))
637
content = "contents of %s%s" % (name, end)
638
transport.put(urlescape(name), StringIO(content))
640
def build_tree_contents(self, shape):
641
build_tree_contents(shape)
643
def failUnlessExists(self, path):
644
"""Fail unless path, which may be abs or relative, exists."""
645
self.failUnless(osutils.lexists(path))
647
def failIfExists(self, path):
648
"""Fail if path, which may be abs or relative, exists."""
649
self.failIf(osutils.lexists(path))
651
def assertFileEqual(self, content, path):
652
"""Fail if path does not contain 'content'."""
653
self.failUnless(osutils.lexists(path))
654
self.assertEqualDiff(content, open(path, 'r').read())
657
class TestCaseWithTransport(TestCaseInTempDir):
658
"""A test case that provides get_url and get_readonly_url facilities.
660
These back onto two transport servers, one for readonly access and one for
663
If no explicit class is provided for readonly access, a
664
ReadonlyTransportDecorator is used instead which allows the use of non disk
665
based read write transports.
667
If an explicit class is provided for readonly access, that server and the
668
readwrite one must both define get_url() as resolving to os.getcwd().
671
def __init__(self, methodName='testMethod'):
672
super(TestCaseWithTransport, self).__init__(methodName)
673
self.__readonly_server = None
675
self.transport_server = default_transport
676
self.transport_readonly_server = None
678
def get_readonly_url(self, relpath=None):
679
"""Get a URL for the readonly transport.
681
This will either be backed by '.' or a decorator to the transport
682
used by self.get_url()
683
relpath provides for clients to get a path relative to the base url.
684
These should only be downwards relative, not upwards.
686
base = self.get_readonly_server().get_url()
687
if relpath is not None:
688
if not base.endswith('/'):
690
base = base + relpath
693
def get_readonly_server(self):
694
"""Get the server instance for the readonly transport
696
This is useful for some tests with specific servers to do diagnostics.
698
if self.__readonly_server is None:
699
if self.transport_readonly_server is None:
700
# readonly decorator requested
701
# bring up the server
703
self.__readonly_server = ReadonlyServer()
704
self.__readonly_server.setUp(self.__server)
706
self.__readonly_server = self.transport_readonly_server()
707
self.__readonly_server.setUp()
708
self.addCleanup(self.__readonly_server.tearDown)
709
return self.__readonly_server
711
def get_server(self):
712
"""Get the read/write server instance.
714
This is useful for some tests with specific servers that need
717
if self.__server is None:
718
self.__server = self.transport_server()
719
self.__server.setUp()
720
self.addCleanup(self.__server.tearDown)
723
def get_url(self, relpath=None):
724
"""Get a URL for the readwrite transport.
726
This will either be backed by '.' or to an equivalent non-file based
728
relpath provides for clients to get a path relative to the base url.
729
These should only be downwards relative, not upwards.
731
base = self.get_server().get_url()
732
if relpath is not None and relpath != '.':
733
if not base.endswith('/'):
735
base = base + relpath
738
def get_transport(self):
739
"""Return a writeable transport for the test scratch space"""
740
t = get_transport(self.get_url())
741
self.assertFalse(t.is_readonly())
744
def get_readonly_transport(self):
745
"""Return a readonly transport for the test scratch space
747
This can be used to test that operations which should only need
748
readonly access in fact do not try to write.
750
t = get_transport(self.get_readonly_url())
751
self.assertTrue(t.is_readonly())
754
def make_branch(self, relpath):
755
"""Create a branch on the transport at relpath."""
756
repo = self.make_repository(relpath)
757
return repo.bzrdir.create_branch()
759
def make_bzrdir(self, relpath):
761
url = self.get_url(relpath)
762
segments = relpath.split('/')
763
if segments and segments[-1] not in ('', '.'):
764
parent = self.get_url('/'.join(segments[:-1]))
765
t = get_transport(parent)
767
t.mkdir(segments[-1])
768
except errors.FileExists:
770
return bzrlib.bzrdir.BzrDir.create(url)
771
except errors.UninitializableFormat:
772
raise TestSkipped("Format %s is not initializable.")
774
def make_repository(self, relpath, shared=False):
775
"""Create a repository on our default transport at relpath."""
776
made_control = self.make_bzrdir(relpath)
777
return made_control.create_repository(shared=shared)
779
def make_branch_and_tree(self, relpath):
780
"""Create a branch on the transport and a tree locally.
784
# TODO: always use the local disk path for the working tree,
785
# this obviously requires a format that supports branch references
786
# so check for that by checking bzrdir.BzrDirFormat.get_default_format()
788
b = self.make_branch(relpath)
790
return b.bzrdir.create_workingtree()
791
except errors.NotLocalUrl:
792
# new formats - catch No tree error and create
793
# a branch reference and a checkout.
794
# old formats at that point - raise TestSkipped.
796
return WorkingTreeFormat2().initialize(bzrdir.BzrDir.open(relpath))
799
class ChrootedTestCase(TestCaseWithTransport):
800
"""A support class that provides readonly urls outside the local namespace.
802
This is done by checking if self.transport_server is a MemoryServer. if it
803
is then we are chrooted already, if it is not then an HttpServer is used
806
TODO RBC 20060127: make this an option to TestCaseWithTransport so it can
807
be used without needed to redo it when a different
812
super(ChrootedTestCase, self).setUp()
813
if not self.transport_server == bzrlib.transport.memory.MemoryServer:
814
self.transport_readonly_server = bzrlib.transport.http.HttpServer
817
def filter_suite_by_re(suite, pattern):
819
filter_re = re.compile(pattern)
820
for test in iter_suite_tests(suite):
821
if filter_re.search(test.id()):
826
def run_suite(suite, name='test', verbose=False, pattern=".*",
827
stop_on_failure=False, keep_output=False,
829
TestCaseInTempDir._TEST_NAME = name
834
runner = TextTestRunner(stream=sys.stdout,
837
runner.stop_on_failure=stop_on_failure
839
suite = filter_suite_by_re(suite, pattern)
840
result = runner.run(suite)
841
# This is still a little bogus,
842
# but only a little. Folk not using our testrunner will
843
# have to delete their temp directories themselves.
844
if result.wasSuccessful() or not keep_output:
845
if TestCaseInTempDir.TEST_ROOT is not None:
846
shutil.rmtree(TestCaseInTempDir.TEST_ROOT)
848
print "Failed tests working directories are in '%s'\n" % TestCaseInTempDir.TEST_ROOT
849
return result.wasSuccessful()
852
def selftest(verbose=False, pattern=".*", stop_on_failure=True,
277
print >>f, "contents of", name
282
class MetaTestLog(TestCase):
283
def test_logging(self):
284
"""Test logs are captured when a test fails."""
285
logging.info('an info message')
286
warning('something looks dodgy...')
287
logging.debug('hello, test is running')
291
def selftest(verbose=False, pattern=".*"):
855
292
"""Run the whole test suite under the enhanced runner"""
856
global default_transport
857
if transport is None:
858
transport = default_transport
859
old_transport = default_transport
860
default_transport = transport
863
return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
864
stop_on_failure=stop_on_failure, keep_output=keep_output,
867
default_transport = old_transport
293
return run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern)
871
296
def test_suite():
872
297
"""Build and return TestSuite for the whole program."""
298
from bzrlib.selftest.TestUtil import TestLoader, TestSuite
299
import bzrlib, bzrlib.store, bzrlib.inventory, bzrlib.branch
300
import bzrlib.osutils, bzrlib.commands, bzrlib.merge3, bzrlib.plugin
873
301
from doctest import DocTestSuite
875
global MODULES_TO_DOCTEST
878
'bzrlib.tests.test_ancestry',
879
'bzrlib.tests.test_annotate',
880
'bzrlib.tests.test_api',
881
'bzrlib.tests.test_bad_files',
882
'bzrlib.tests.test_basis_inventory',
883
'bzrlib.tests.test_branch',
884
'bzrlib.tests.test_bzrdir',
885
'bzrlib.tests.test_command',
886
'bzrlib.tests.test_commit',
887
'bzrlib.tests.test_commit_merge',
888
'bzrlib.tests.test_config',
889
'bzrlib.tests.test_conflicts',
890
'bzrlib.tests.test_decorators',
891
'bzrlib.tests.test_diff',
892
'bzrlib.tests.test_doc_generate',
893
'bzrlib.tests.test_errors',
894
'bzrlib.tests.test_fetch',
895
'bzrlib.tests.test_gpg',
896
'bzrlib.tests.test_graph',
897
'bzrlib.tests.test_hashcache',
898
'bzrlib.tests.test_http',
899
'bzrlib.tests.test_identitymap',
900
'bzrlib.tests.test_inv',
901
'bzrlib.tests.test_knit',
902
'bzrlib.tests.test_lockdir',
903
'bzrlib.tests.test_lockable_files',
904
'bzrlib.tests.test_log',
905
'bzrlib.tests.test_merge',
906
'bzrlib.tests.test_merge3',
907
'bzrlib.tests.test_merge_core',
908
'bzrlib.tests.test_missing',
909
'bzrlib.tests.test_msgeditor',
910
'bzrlib.tests.test_nonascii',
911
'bzrlib.tests.test_options',
912
'bzrlib.tests.test_osutils',
913
'bzrlib.tests.test_permissions',
914
'bzrlib.tests.test_plugins',
915
'bzrlib.tests.test_reconcile',
916
'bzrlib.tests.test_repository',
917
'bzrlib.tests.test_revision',
918
'bzrlib.tests.test_revisionnamespaces',
919
'bzrlib.tests.test_revprops',
920
'bzrlib.tests.test_rio',
921
'bzrlib.tests.test_sampler',
922
'bzrlib.tests.test_selftest',
923
'bzrlib.tests.test_setup',
924
'bzrlib.tests.test_sftp_transport',
925
'bzrlib.tests.test_smart_add',
926
'bzrlib.tests.test_source',
927
'bzrlib.tests.test_store',
928
'bzrlib.tests.test_symbol_versioning',
929
'bzrlib.tests.test_testament',
930
'bzrlib.tests.test_trace',
931
'bzrlib.tests.test_transactions',
932
'bzrlib.tests.test_transform',
933
'bzrlib.tests.test_transport',
934
'bzrlib.tests.test_tsort',
935
'bzrlib.tests.test_ui',
936
'bzrlib.tests.test_uncommit',
937
'bzrlib.tests.test_upgrade',
938
'bzrlib.tests.test_versionedfile',
939
'bzrlib.tests.test_weave',
940
'bzrlib.tests.test_whitebox',
941
'bzrlib.tests.test_workingtree',
942
'bzrlib.tests.test_xml',
307
global MODULES_TO_TEST, MODULES_TO_DOCTEST
310
['bzrlib.selftest.MetaTestLog',
311
'bzrlib.selftest.testinv',
312
'bzrlib.selftest.versioning',
313
'bzrlib.selftest.testmerge3',
314
'bzrlib.selftest.testhashcache',
315
'bzrlib.selftest.teststatus',
316
'bzrlib.selftest.testlog',
317
'bzrlib.selftest.testrevisionnamespaces',
318
'bzrlib.selftest.testbranch',
319
'bzrlib.selftest.testrevision',
320
'bzrlib.selftest.test_merge_core',
321
'bzrlib.selftest.test_smart_add',
322
'bzrlib.selftest.testdiff',
323
'bzrlib.selftest.test_parent',
324
'bzrlib.selftest.test_xml',
325
'bzrlib.selftest.testfetch',
326
'bzrlib.selftest.whitebox',
327
'bzrlib.selftest.teststore',
328
'bzrlib.selftest.blackbox',
944
test_transport_implementations = [
945
'bzrlib.tests.test_transport_implementations']
947
TestCase.BZRPATH = osutils.pathjoin(
948
osutils.realpath(osutils.dirname(bzrlib.__path__[0])), 'bzr')
949
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
950
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
331
for m in (bzrlib.store, bzrlib.inventory, bzrlib.branch,
332
bzrlib.osutils, bzrlib.commands, bzrlib.merge3):
333
if m not in MODULES_TO_DOCTEST:
334
MODULES_TO_DOCTEST.append(m)
336
TestCase.BZRPATH = os.path.join(os.path.realpath(os.path.dirname(bzrlib.__path__[0])), 'bzr')
337
print '%-30s %s' % ('bzr binary', TestCase.BZRPATH)
952
339
suite = TestSuite()
953
# python2.4's TestLoader.loadTestsFromNames gives very poor
954
# errors if it fails to load a named module - no indication of what's
955
# actually wrong, just "no such module". We should probably override that
956
# class, but for the moment just load them ourselves. (mbp 20051202)
957
loader = TestLoader()
958
from bzrlib.transport import TransportTestProviderAdapter
959
adapter = TransportTestProviderAdapter()
960
adapt_modules(test_transport_implementations, adapter, loader, suite)
961
for mod_name in testmod_names:
962
mod = _load_module_by_name(mod_name)
963
suite.addTest(loader.loadTestsFromModule(mod))
964
for package in packages_to_test():
965
suite.addTest(package.test_suite())
340
suite.addTest(TestLoader().loadTestsFromNames(testmod_names))
966
341
for m in MODULES_TO_TEST:
967
suite.addTest(loader.loadTestsFromModule(m))
342
suite.addTest(TestLoader().loadTestsFromModule(m))
968
343
for m in (MODULES_TO_DOCTEST):
969
344
suite.addTest(DocTestSuite(m))
970
for name, plugin in bzrlib.plugin.all_plugins().items():
971
if getattr(plugin, 'test_suite', None) is not None:
972
suite.addTest(plugin.test_suite())
345
for p in bzrlib.plugin.all_plugins:
346
if hasattr(p, 'test_suite'):
347
suite.addTest(p.test_suite())
976
def adapt_modules(mods_list, adapter, loader, suite):
977
"""Adapt the modules in mods_list using adapter and add to suite."""
978
for mod_name in mods_list:
979
mod = _load_module_by_name(mod_name)
980
for test in iter_suite_tests(loader.loadTestsFromModule(mod)):
981
suite.addTests(adapter.adapt(test))
984
def _load_module_by_name(mod_name):
985
parts = mod_name.split('.')
986
module = __import__(mod_name)
988
# for historical reasons python returns the top-level module even though
989
# it loads the submodule; we need to walk down to get the one we want.
991
module = getattr(module, parts.pop(0))