37
38
import bzrlib.branch
38
39
import bzrlib.commands
39
from bzrlib.errors import BzrError
40
from bzrlib.errors import (BzrError,
42
UninitializableFormat,
40
44
import bzrlib.inventory
45
import bzrlib.iterablefile
41
46
import bzrlib.merge3
42
47
import bzrlib.osutils
43
48
import bzrlib.osutils as osutils
44
49
import bzrlib.plugin
45
50
import bzrlib.store
46
51
import bzrlib.trace
52
from bzrlib.transport import urlescape
53
import bzrlib.transport
54
from bzrlib.transport.local import LocalRelpathServer
55
from bzrlib.transport.readonly import ReadonlyServer
47
56
from bzrlib.trace import mutter
48
57
from bzrlib.tests.TestUtil import TestLoader, TestSuite
49
58
from bzrlib.tests.treeshape import build_tree_contents
59
from bzrlib.workingtree import WorkingTree
61
default_transport = LocalRelpathServer
51
63
MODULES_TO_TEST = []
52
64
MODULES_TO_DOCTEST = [
61
75
def packages_to_test():
76
"""Return a list of packages to test.
78
The packages are not globally imported so that import failures are
79
triggered when running selftest, not when importing the command.
62
82
import bzrlib.tests.blackbox
83
import bzrlib.tests.branch_implementations
86
bzrlib.tests.branch_implementations,
68
class EarlyStoppingTestResultAdapter(object):
69
"""An adapter for TestResult to stop at the first first failure or error"""
71
def __init__(self, result):
74
def addError(self, test, err):
75
self._result.addError(test, err)
78
def addFailure(self, test, err):
79
self._result.addFailure(test, err)
82
def __getattr__(self, name):
83
return getattr(self._result, name)
85
def __setattr__(self, name, value):
87
object.__setattr__(self, name, value)
88
return setattr(self._result, name, value)
91
90
class _MyResult(unittest._TextTestResult):
92
91
"""Custom TestResult.
94
93
Shows output in a different format, including displaying runtime for tests.
97
97
def _elapsedTime(self):
98
98
return "%5dms" % (1000 * (time.time() - self._start_time))
163
167
def printErrorList(self, flavour, errors):
164
168
for test, err in errors:
165
169
self.stream.writeln(self.separator1)
166
self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
167
if hasattr(test, '_get_log'):
170
self.stream.writeln("%s: %s" % (flavour, self.getDescription(test)))
171
if getattr(test, '_get_log', None) is not None:
168
172
print >>self.stream
169
173
print >>self.stream, \
170
('vvvv[log from %s]' % test).ljust(78,'-')
174
('vvvv[log from %s]' % test.id()).ljust(78,'-')
171
175
print >>self.stream, test._get_log()
172
176
print >>self.stream, \
173
('^^^^[log from %s]' % test).ljust(78,'-')
177
('^^^^[log from %s]' % test.id()).ljust(78,'-')
174
178
self.stream.writeln(self.separator2)
175
179
self.stream.writeln("%s" % err)
289
295
raise AssertionError("value(s) %r not present in container %r" %
290
296
(missing, superlist))
298
def assertIs(self, left, right):
299
if not (left is right):
300
raise AssertionError("%r is not %r." % (left, right))
302
def assertTransportMode(self, transport, path, mode):
303
"""Fail if a path does not have mode mode.
305
If modes are not supported on this platform, the test is skipped.
307
if sys.platform == 'win32':
309
path_stat = transport.stat(path)
310
actual_mode = stat.S_IMODE(path_stat.st_mode)
311
self.assertEqual(mode, actual_mode,
312
'mode of %r incorrect (%o != %o)' % (path, mode, actual_mode))
292
314
def _startLogFile(self):
293
315
"""Send bzr and test log messages to a temporary file.
571
595
in binary mode, exact contents are written
572
596
in native mode, the line endings match the
573
597
default platform endings.
599
:param transport: A transport to write to, for building trees on
600
VFS's. If the transport is readonly or None,
601
"." is opened automatically.
575
603
# XXX: It's OK to just create them using forward slashes on windows?
604
if transport is None or transport.is_readonly():
605
transport = bzrlib.transport.get_transport(".")
576
606
for name in shape:
577
607
self.assert_(isinstance(name, basestring))
578
608
if name[-1] == '/':
609
transport.mkdir(urlescape(name[:-1]))
581
611
if line_endings == 'binary':
583
613
elif line_endings == 'native':
586
616
raise BzrError('Invalid line ending request %r' % (line_endings,))
587
print >>f, "contents of", name
617
content = "contents of %s%s" % (name, end)
618
transport.put(urlescape(name), StringIO(content))
590
620
def build_tree_contents(self, shape):
591
621
build_tree_contents(shape)
604
634
self.assertEqualDiff(content, open(path, 'r').read())
637
class TestCaseWithTransport(TestCaseInTempDir):
638
"""A test case that provides get_url and get_readonly_url facilities.
640
These back onto two transport servers, one for readonly access and one for
643
If no explicit class is provided for readonly access, a
644
ReadonlyTransportDecorator is used instead which allows the use of non disk
645
based read write transports.
647
If an explicit class is provided for readonly access, that server and the
648
readwrite one must both define get_url() as resolving to os.getcwd().
651
def __init__(self, methodName='testMethod'):
652
super(TestCaseWithTransport, self).__init__(methodName)
653
self.__readonly_server = None
655
self.transport_server = default_transport
656
self.transport_readonly_server = None
658
def get_readonly_url(self, relpath=None):
659
"""Get a URL for the readonly transport.
661
This will either be backed by '.' or a decorator to the transport
662
used by self.get_url()
663
relpath provides for clients to get a path relative to the base url.
664
These should only be downwards relative, not upwards.
666
if self.__readonly_server is None:
667
if self.transport_readonly_server is None:
668
# readonly decorator requested
669
# bring up the server
671
self.__readonly_server = ReadonlyServer()
672
self.__readonly_server.setUp(self.__server)
674
self.__readonly_server = self.transport_readonly_server()
675
self.__readonly_server.setUp()
676
self.addCleanup(self.__readonly_server.tearDown)
677
base = self.__readonly_server.get_url()
678
if relpath is not None:
679
if not base.endswith('/'):
681
base = base + relpath
684
def get_url(self, relpath=None):
685
"""Get a URL for the readwrite transport.
687
This will either be backed by '.' or to an equivalent non-file based
689
relpath provides for clients to get a path relative to the base url.
690
These should only be downwards relative, not upwards.
692
if self.__server is None:
693
self.__server = self.transport_server()
694
self.__server.setUp()
695
self.addCleanup(self.__server.tearDown)
696
base = self.__server.get_url()
697
if relpath is not None and relpath != '.':
698
if not base.endswith('/'):
700
base = base + relpath
703
def make_branch(self, relpath):
704
"""Create a branch on the transport at relpath."""
706
url = self.get_url(relpath)
707
segments = relpath.split('/')
708
if segments and segments[-1] not in ('', '.'):
709
parent = self.get_url('/'.join(segments[:-1]))
710
t = bzrlib.transport.get_transport(parent)
712
t.mkdir(segments[-1])
715
return bzrlib.branch.Branch.create(url)
716
except UninitializableFormat:
717
raise TestSkipped("Format %s is not initializable.")
719
def make_branch_and_tree(self, relpath):
720
"""Create a branch on the transport and a tree locally.
724
b = self.make_branch(relpath)
725
return WorkingTree.create(b, relpath)
728
class ChrootedTestCase(TestCaseWithTransport):
729
"""A support class that provides readonly urls outside the local namespace.
731
This is done by checking if self.transport_server is a MemoryServer. if it
732
is then we are chrooted already, if it is not then an HttpServer is used
735
TODO RBC 20060127: make this an option to TestCaseWithTransport so it can
736
be used without needed to redo it when a different
741
super(ChrootedTestCase, self).setUp()
742
if not self.transport_server == bzrlib.transport.memory.MemoryServer:
743
self.transport_readonly_server = bzrlib.transport.http.HttpServer
607
746
def filter_suite_by_re(suite, pattern):
608
747
result = TestSuite()
609
748
filter_re = re.compile(pattern)
641
781
def selftest(verbose=False, pattern=".*", stop_on_failure=True,
643
784
"""Run the whole test suite under the enhanced runner"""
644
return run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern,
645
stop_on_failure=stop_on_failure, keep_output=keep_output)
785
global default_transport
786
if transport is None:
787
transport = default_transport
788
old_transport = default_transport
789
default_transport = transport
792
return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
793
stop_on_failure=stop_on_failure, keep_output=keep_output,
796
default_transport = old_transport
648
800
def test_suite():
663
815
'bzrlib.tests.test_commit_merge',
664
816
'bzrlib.tests.test_config',
665
817
'bzrlib.tests.test_conflicts',
818
'bzrlib.tests.test_decorators',
666
819
'bzrlib.tests.test_diff',
820
'bzrlib.tests.test_doc_generate',
667
821
'bzrlib.tests.test_fetch',
822
'bzrlib.tests.test_fileid_involved',
668
823
'bzrlib.tests.test_gpg',
669
824
'bzrlib.tests.test_graph',
670
825
'bzrlib.tests.test_hashcache',
671
826
'bzrlib.tests.test_http',
672
827
'bzrlib.tests.test_identitymap',
673
828
'bzrlib.tests.test_inv',
829
'bzrlib.tests.test_lockable_files',
674
830
'bzrlib.tests.test_log',
675
831
'bzrlib.tests.test_merge',
676
832
'bzrlib.tests.test_merge3',
733
892
for m in (MODULES_TO_DOCTEST):
734
893
suite.addTest(DocTestSuite(m))
735
894
for name, plugin in bzrlib.plugin.all_plugins().items():
736
if hasattr(plugin, 'test_suite'):
895
if getattr(plugin, 'test_suite', None) is not None:
737
896
suite.addTest(plugin.test_suite())
900
def adapt_modules(mods_list, adapter, loader, suite):
901
"""Adapt the modules in mods_list using adapter and add to suite."""
902
for mod_name in mods_list:
903
mod = _load_module_by_name(mod_name)
904
for test in iter_suite_tests(loader.loadTestsFromModule(mod)):
905
suite.addTests(adapter.adapt(test))
741
908
def _load_module_by_name(mod_name):
742
909
parts = mod_name.split('.')
743
910
module = __import__(mod_name)