61
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.
62
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
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
96
class _MyResult(unittest._TextTestResult):
92
97
"""Custom TestResult.
94
99
Shows output in a different format, including displaying runtime for tests.
97
103
def _elapsedTime(self):
98
104
return "%5dms" % (1000 * (time.time() - self._start_time))
163
173
def printErrorList(self, flavour, errors):
164
174
for test, err in errors:
165
175
self.stream.writeln(self.separator1)
166
self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
167
if hasattr(test, '_get_log'):
176
self.stream.writeln("%s: %s" % (flavour, self.getDescription(test)))
177
if getattr(test, '_get_log', None) is not None:
168
178
print >>self.stream
169
179
print >>self.stream, \
170
('vvvv[log from %s]' % test).ljust(78,'-')
180
('vvvv[log from %s]' % test.id()).ljust(78,'-')
171
181
print >>self.stream, test._get_log()
172
182
print >>self.stream, \
173
('^^^^[log from %s]' % test).ljust(78,'-')
183
('^^^^[log from %s]' % test.id()).ljust(78,'-')
174
184
self.stream.writeln(self.separator2)
175
185
self.stream.writeln("%s" % err)
289
307
raise AssertionError("value(s) %r not present in container %r" %
290
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))
292
326
def _startLogFile(self):
293
327
"""Send bzr and test log messages to a temporary file.
571
607
in binary mode, exact contents are written
572
608
in native mode, the line endings match the
573
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.
575
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(".")
576
618
for name in shape:
577
619
self.assert_(isinstance(name, basestring))
578
620
if name[-1] == '/':
621
transport.mkdir(urlescape(name[:-1]))
581
623
if line_endings == 'binary':
583
625
elif line_endings == 'native':
586
raise BzrError('Invalid line ending request %r' % (line_endings,))
587
print >>f, "contents of", name
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))
590
632
def build_tree_contents(self, shape):
591
633
build_tree_contents(shape)
604
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
607
793
def filter_suite_by_re(suite, pattern):
608
794
result = TestSuite()
609
795
filter_re = re.compile(pattern)
658
857
'bzrlib.tests.test_bad_files',
659
858
'bzrlib.tests.test_basis_inventory',
660
859
'bzrlib.tests.test_branch',
860
'bzrlib.tests.test_bzrdir',
661
861
'bzrlib.tests.test_command',
662
862
'bzrlib.tests.test_commit',
663
863
'bzrlib.tests.test_commit_merge',
664
864
'bzrlib.tests.test_config',
665
865
'bzrlib.tests.test_conflicts',
866
'bzrlib.tests.test_decorators',
666
867
'bzrlib.tests.test_diff',
868
'bzrlib.tests.test_doc_generate',
869
'bzrlib.tests.test_errors',
667
870
'bzrlib.tests.test_fetch',
668
871
'bzrlib.tests.test_gpg',
669
872
'bzrlib.tests.test_graph',
695
898
'bzrlib.tests.test_sftp_transport',
696
899
'bzrlib.tests.test_smart_add',
697
900
'bzrlib.tests.test_source',
698
'bzrlib.tests.test_status',
699
901
'bzrlib.tests.test_store',
700
902
'bzrlib.tests.test_symbol_versioning',
701
903
'bzrlib.tests.test_testament',
702
904
'bzrlib.tests.test_trace',
703
905
'bzrlib.tests.test_transactions',
906
'bzrlib.tests.test_transform',
704
907
'bzrlib.tests.test_transport',
705
908
'bzrlib.tests.test_tsort',
706
909
'bzrlib.tests.test_ui',
733
941
for m in (MODULES_TO_DOCTEST):
734
942
suite.addTest(DocTestSuite(m))
735
943
for name, plugin in bzrlib.plugin.all_plugins().items():
736
if hasattr(plugin, 'test_suite'):
944
if getattr(plugin, 'test_suite', None) is not None:
737
945
suite.addTest(plugin.test_suite())
949
def adapt_modules(mods_list, adapter, loader, suite):
950
"""Adapt the modules in mods_list using adapter and add to suite."""
951
for mod_name in mods_list:
952
mod = _load_module_by_name(mod_name)
953
for test in iter_suite_tests(loader.loadTestsFromModule(mod)):
954
suite.addTests(adapter.adapt(test))
741
957
def _load_module_by_name(mod_name):
742
958
parts = mod_name.split('.')
743
959
module = __import__(mod_name)