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)
18
24
from cStringIO import StringIO
66
76
self._result = result
68
78
def addError(self, test, err):
79
if (isinstance(err[1], TestSkipped) and
80
getattr(self, "addSkipped", None) is not None):
81
return self.addSkipped(test, err)
69
82
self._result.addError(test, err)
70
83
self._result.stop()
157
170
def printErrorList(self, flavour, errors):
158
171
for test, err in errors:
159
172
self.stream.writeln(self.separator1)
160
self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
161
if hasattr(test, '_get_log'):
173
self.stream.writeln("%s: %s" % (flavour, self.getDescription(test)))
174
if getattr(test, '_get_log', None) is not None:
162
175
print >>self.stream
163
176
print >>self.stream, \
164
('vvvv[log from %s]' % test).ljust(78,'-')
177
('vvvv[log from %s]' % test.id()).ljust(78,'-')
165
178
print >>self.stream, test._get_log()
166
179
print >>self.stream, \
167
('^^^^[log from %s]' % test).ljust(78,'-')
180
('^^^^[log from %s]' % test.id()).ljust(78,'-')
168
181
self.stream.writeln(self.separator2)
169
182
self.stream.writeln("%s" % err)
283
299
raise AssertionError("value(s) %r not present in container %r" %
284
300
(missing, superlist))
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))
286
314
def _startLogFile(self):
287
315
"""Send bzr and test log messages to a temporary file.
467
497
if stdin is None:
468
498
stdin = StringIO("")
469
499
if stdout is None:
470
if hasattr(self, "_log_file"):
500
if getattr(self, "_log_file", None) is not None:
471
501
stdout = self._log_file
473
503
stdout = StringIO()
474
504
if stderr is None:
475
if hasattr(self, "_log_file"):
505
if getattr(self, "_log_file", None is not None):
476
506
stderr = self._log_file
478
508
stderr = StringIO()
554
584
os.chdir(_currentdir)
555
585
self.addCleanup(_leaveDirectory)
557
def build_tree(self, shape, line_endings='native'):
587
def build_tree(self, shape, line_endings='native', transport=None):
558
588
"""Build a test tree according to a pattern.
560
590
shape is a sequence of file specifications. If the final
565
595
in binary mode, exact contents are written
566
596
in native mode, the line endings match the
567
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.
569
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(".")
570
606
for name in shape:
571
607
self.assert_(isinstance(name, basestring))
572
608
if name[-1] == '/':
609
transport.mkdir(urlescape(name[:-1]))
575
611
if line_endings == 'binary':
577
613
elif line_endings == 'native':
580
616
raise BzrError('Invalid line ending request %r' % (line_endings,))
581
print >>f, "contents of", name
617
content = "contents of %s%s" % (name, end)
618
transport.put(urlescape(name), StringIO(content))
584
620
def build_tree_contents(self, shape):
585
621
build_tree_contents(shape)
598
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 = bzrlib.transport.local.LocalRelpathServer
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:
698
if not base.endswith('/'):
700
base = base + relpath
601
706
def filter_suite_by_re(suite, pattern):
602
707
result = TestSuite()
603
708
filter_re = re.compile(pattern)
705
810
'bzrlib.tests.test_workingtree',
706
811
'bzrlib.tests.test_xml',
813
test_branch_implementations = [
814
'bzrlib.tests.test_branch_implementations']
815
test_transport_implementations = [
816
'bzrlib.tests.test_transport_implementations']
709
818
TestCase.BZRPATH = osutils.pathjoin(
710
819
osutils.realpath(osutils.dirname(bzrlib.__path__[0])), 'bzr')
717
826
# actually wrong, just "no such module". We should probably override that
718
827
# class, but for the moment just load them ourselves. (mbp 20051202)
719
828
loader = TestLoader()
829
from bzrlib.transport import TransportTestProviderAdapter
830
adapter = TransportTestProviderAdapter()
831
for mod_name in test_transport_implementations:
832
mod = _load_module_by_name(mod_name)
833
for test in iter_suite_tests(loader.loadTestsFromModule(mod)):
834
suite.addTests(adapter.adapt(test))
835
from bzrlib.branch import BranchTestProviderAdapter
836
adapter = BranchTestProviderAdapter(
837
bzrlib.transport.local.LocalRelpathServer,
838
# None here will cause a readonly decorator to be created
839
# by the TestCaseWithTransport.get_readonly_transport method.
841
bzrlib.branch.BzrBranchFormat._formats.values())
842
for mod_name in test_branch_implementations:
843
mod = _load_module_by_name(mod_name)
844
for test in iter_suite_tests(loader.loadTestsFromModule(mod)):
845
suite.addTests(adapter.adapt(test))
720
846
for mod_name in testmod_names:
721
847
mod = _load_module_by_name(mod_name)
722
848
suite.addTest(loader.loadTestsFromModule(mod))
727
853
for m in (MODULES_TO_DOCTEST):
728
854
suite.addTest(DocTestSuite(m))
729
855
for name, plugin in bzrlib.plugin.all_plugins().items():
730
if hasattr(plugin, 'test_suite'):
856
if getattr(plugin, 'test_suite', None) is not None:
731
857
suite.addTest(plugin.test_suite())