1
# Copyright (C) 2005, 2006 Canonical Ltd
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
79
79
from bzrlib.transport.readonly import ReadonlyServer
80
80
from bzrlib.trace import mutter, note
81
81
from bzrlib.tests import TestUtil
82
from bzrlib.tests.HttpServer import HttpServer
82
83
from bzrlib.tests.TestUtil import (
191
192
self._formatTime(self._benchmarkTime),
192
193
self._elapsedTestTimeString())
194
return " %s" % self._elapsedTestTimeString()
195
return " %s" % self._elapsedTestTimeString()
196
197
def _formatTime(self, seconds):
197
198
"""Format seconds as milliseconds with leading spaces."""
198
return "%5dms" % (1000 * seconds)
199
# some benchmarks can take thousands of seconds to run, so we need 8
201
return "%8dms" % (1000 * seconds)
200
203
def _shortened_test_description(self, test):
202
what = re.sub(r'^bzrlib\.(tests|benchmark)\.', '', what)
205
what = re.sub(r'^bzrlib\.(tests|benchmarks)\.', '', what)
205
208
def startTest(self, test):
324
327
def report_error(self, test, err):
325
328
self.error_count += 1
326
self.pb.note('ERROR: %s\n %s\n' % (
329
self.pb.note('ERROR: %s\n %s\n',
327
330
self._shortened_test_description(test),
331
334
def report_failure(self, test, err):
332
335
self.failure_count += 1
333
self.pb.note('FAIL: %s\n %s\n' % (
336
self.pb.note('FAIL: %s\n %s\n',
334
337
self._shortened_test_description(test),
338
341
def report_skip(self, test, skip_excinfo):
339
342
self.skip_count += 1
345
348
# show test and reason for skip
346
self.pb.note('SKIP: %s\n %s\n' % (
349
self.pb.note('SKIP: %s\n %s\n',
347
350
self._shortened_test_description(test),
350
353
# since the class name was left behind in the still-visible
351
354
# progress bar...
352
self.pb.note('SKIP: %s' % (skip_excinfo[1]))
355
self.pb.note('SKIP: %s', skip_excinfo[1])
354
357
def report_cleaning_up(self):
355
358
self.pb.update('cleaning up...')
375
378
def report_test_start(self, test):
377
380
name = self._shortened_test_description(test)
378
self.stream.write(self._ellipsize_to_right(name, 60))
381
# width needs space for 6 char status, plus 1 for slash, plus 2 10-char
382
# numbers, plus a trailing blank
383
self.stream.write(self._ellipsize_to_right(name,
384
osutils.terminal_width()-30))
379
385
self.stream.flush()
381
387
def report_error(self, test, err):
386
392
def report_failure(self, test, err):
387
393
self.failure_count += 1
388
self.stream.writeln('FAIL %s\n %s'
394
self.stream.writeln(' FAIL %s\n %s'
389
395
% (self._testTimeString(), err[1]))
391
397
def report_success(self, test):
563
569
self._startLogFile()
564
570
self._benchcalls = []
565
571
self._benchtime = None
572
# prevent hooks affecting tests
573
self._preserved_hooks = bzrlib.branch.Branch.hooks
574
self.addCleanup(self._restoreHooks)
575
# this list of hooks must be kept in sync with the defaults
577
bzrlib.branch.Branch.hooks = bzrlib.branch.BranchHooks()
567
579
def _silenceUI(self):
568
580
"""Turn off UI for duration of test"""
637
649
raise AssertionError("value(s) %r not present in container %r" %
638
650
(missing, superlist))
640
def assertIs(self, left, right):
652
def assertListRaises(self, excClass, func, *args, **kwargs):
653
"""Fail unless excClass is raised when the iterator from func is used.
655
Many functions can return generators this makes sure
656
to wrap them in a list() call to make sure the whole generator
657
is run, and that the proper exception is raised.
660
list(func(*args, **kwargs))
664
if getattr(excClass,'__name__', None) is not None:
665
excName = excClass.__name__
667
excName = str(excClass)
668
raise self.failureException, "%s not raised" % excName
670
def assertIs(self, left, right, message=None):
641
671
if not (left is right):
642
raise AssertionError("%r is not %r." % (left, right))
672
if message is not None:
673
raise AssertionError(message)
675
raise AssertionError("%r is not %r." % (left, right))
677
def assertIsNot(self, left, right, message=None):
679
if message is not None:
680
raise AssertionError(message)
682
raise AssertionError("%r is %r." % (left, right))
644
684
def assertTransportMode(self, transport, path, mode):
645
685
"""Fail if a path does not have mode mode.
773
813
'BZREMAIL': None, # may still be present in the environment
775
815
'BZR_PROGRESS_BAR': None,
825
# Nobody cares about these ones AFAIK. So far at
826
# least. If you do (care), please update this comment
777
831
self.__old_env = {}
778
832
self.addCleanup(self._restoreEnvironment)
787
841
for name, value in self.__old_env.iteritems():
788
842
osutils.set_or_unset_env(name, value)
844
def _restoreHooks(self):
845
bzrlib.branch.Branch.hooks = self._preserved_hooks
790
847
def tearDown(self):
791
848
self._runCleanups()
792
849
unittest.TestCase.tearDown(self)
1224
1281
self.transport_server = default_transport
1225
1282
self.transport_readonly_server = None
1227
def failUnlessExists(self, path):
1228
"""Fail unless path, which may be abs or relative, exists."""
1229
self.failUnless(osutils.lexists(path))
1231
def failIfExists(self, path):
1232
"""Fail if path, which may be abs or relative, exists."""
1233
self.failIf(osutils.lexists(path))
1235
1284
def get_transport(self):
1236
1285
"""Return a writeable transport for the test scratch space"""
1237
1286
t = get_transport(self.get_url())
1248
1297
self.assertTrue(t.is_readonly())
1300
def create_transport_readonly_server(self):
1301
"""Create a transport server from class defined at init.
1303
This is mostly a hook for daughter classes.
1305
return self.transport_readonly_server()
1251
1307
def get_readonly_server(self):
1252
1308
"""Get the server instance for the readonly transport
1261
1317
self.__readonly_server = ReadonlyServer()
1262
1318
self.__readonly_server.setUp(self.__server)
1264
self.__readonly_server = self.transport_readonly_server()
1320
self.__readonly_server = self.create_transport_readonly_server()
1265
1321
self.__readonly_server.setUp()
1266
1322
self.addCleanup(self.__readonly_server.tearDown)
1267
1323
return self.__readonly_server
1369
1425
except errors.FileExists:
1371
1427
if format is None:
1372
format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
1429
if isinstance(format, basestring):
1430
format = bzrdir.format_registry.make_bzrdir(format)
1373
1431
return format.initialize_on_transport(t)
1374
1432
except errors.UninitializableFormat:
1375
1433
raise TestSkipped("Format %s is not initializable." % format)
1453
1511
os.chdir(self.test_dir)
1456
def build_tree(self, shape, line_endings='native', transport=None):
1514
def build_tree(self, shape, line_endings='binary', transport=None):
1457
1515
"""Build a test tree according to a pattern.
1459
1517
shape is a sequence of file specifications. If the final
1484
1542
elif line_endings == 'native':
1485
1543
end = os.linesep
1487
raise errors.BzrError('Invalid line ending request %r' % (line_endings,))
1545
raise errors.BzrError(
1546
'Invalid line ending request %r' % line_endings)
1488
1547
content = "contents of %s%s" % (name.encode('utf-8'), end)
1489
# Technically 'put()' is the right command. However, put
1490
# uses an AtomicFile, which requires an extra rename into place
1491
# As long as the files didn't exist in the past, append() will
1492
# do the same thing as put()
1493
# On jam's machine, make_kernel_like_tree is:
1494
# put: 4.5-7.5s (averaging 6s)
1496
# put_non_atomic: 2.9-4.5s
1497
1548
transport.put_bytes_non_atomic(urlutils.escape(name), content)
1499
1550
def build_tree_contents(self, shape):
1502
1553
def assertFileEqual(self, content, path):
1503
1554
"""Fail if path does not contain 'content'."""
1504
self.failUnless(osutils.lexists(path))
1555
self.failUnlessExists(path)
1505
1556
# TODO: jam 20060427 Shouldn't this be 'rb'?
1506
1557
self.assertEqualDiff(content, open(path, 'r').read())
1559
def failUnlessExists(self, path):
1560
"""Fail unless path, which may be abs or relative, exists."""
1561
self.failUnless(osutils.lexists(path),path+" does not exist")
1563
def failIfExists(self, path):
1564
"""Fail if path, which may be abs or relative, exists."""
1565
self.failIf(osutils.lexists(path),path+" exists")
1509
1568
class TestCaseWithTransport(TestCaseInTempDir):
1510
1569
"""A test case that provides get_url and get_readonly_url facilities.
1520
1579
readwrite one must both define get_url() as resolving to os.getcwd().
1582
def create_transport_server(self):
1583
"""Create a transport server from class defined at init.
1585
This is mostly a hook for daughter classes.
1587
return self.transport_server()
1523
1589
def get_server(self):
1524
1590
"""See TestCaseWithMemoryTransport.
1599
1665
def setUp(self):
1600
1666
super(ChrootedTestCase, self).setUp()
1601
if not self.transport_server == bzrlib.transport.memory.MemoryServer:
1602
self.transport_readonly_server = bzrlib.transport.http.HttpServer
1667
if not self.transport_server == MemoryServer:
1668
self.transport_readonly_server = HttpServer
1605
1671
def filter_suite_by_re(suite, pattern):
1680
def sort_suite_by_re(suite, pattern):
1683
filter_re = re.compile(pattern)
1684
for test in iter_suite_tests(suite):
1685
if filter_re.search(test.id()):
1689
return TestUtil.TestSuite(first + second)
1614
1692
def run_suite(suite, name='test', verbose=False, pattern=".*",
1615
1693
stop_on_failure=False, keep_output=False,
1616
transport=None, lsprof_timed=None, bench_history=None):
1694
transport=None, lsprof_timed=None, bench_history=None,
1695
matching_tests_first=None):
1617
1696
TestCase._gather_lsprof_in_benchmarks = lsprof_timed
1626
1705
bench_history=bench_history)
1627
1706
runner.stop_on_failure=stop_on_failure
1628
1707
if pattern != '.*':
1629
suite = filter_suite_by_re(suite, pattern)
1708
if matching_tests_first:
1709
suite = sort_suite_by_re(suite, pattern)
1711
suite = filter_suite_by_re(suite, pattern)
1630
1712
result = runner.run(suite)
1631
1713
return result.wasSuccessful()
1658
1741
stop_on_failure=stop_on_failure, keep_output=keep_output,
1659
1742
transport=transport,
1660
1743
lsprof_timed=lsprof_timed,
1661
bench_history=bench_history)
1744
bench_history=bench_history,
1745
matching_tests_first=matching_tests_first)
1663
1747
default_transport = old_transport
1672
1756
testmod_names = [
1673
1757
'bzrlib.tests.test_ancestry',
1758
'bzrlib.tests.test_annotate',
1674
1759
'bzrlib.tests.test_api',
1675
1760
'bzrlib.tests.test_atomicfile',
1676
1761
'bzrlib.tests.test_bad_files',
1678
1763
'bzrlib.tests.test_bundle',
1679
1764
'bzrlib.tests.test_bzrdir',
1680
1765
'bzrlib.tests.test_cache_utf8',
1681
'bzrlib.tests.test_command',
1766
'bzrlib.tests.test_commands',
1682
1767
'bzrlib.tests.test_commit',
1683
1768
'bzrlib.tests.test_commit_merge',
1684
1769
'bzrlib.tests.test_config',
1685
1770
'bzrlib.tests.test_conflicts',
1686
1771
'bzrlib.tests.test_decorators',
1772
'bzrlib.tests.test_delta',
1687
1773
'bzrlib.tests.test_diff',
1688
1774
'bzrlib.tests.test_doc_generate',
1689
1775
'bzrlib.tests.test_errors',
1690
1776
'bzrlib.tests.test_escaped_store',
1691
1777
'bzrlib.tests.test_fetch',
1692
1778
'bzrlib.tests.test_ftp_transport',
1779
'bzrlib.tests.test_generate_docs',
1780
'bzrlib.tests.test_generate_ids',
1781
'bzrlib.tests.test_globbing',
1693
1782
'bzrlib.tests.test_gpg',
1694
1783
'bzrlib.tests.test_graph',
1695
1784
'bzrlib.tests.test_hashcache',
1696
1785
'bzrlib.tests.test_http',
1697
1786
'bzrlib.tests.test_http_response',
1787
'bzrlib.tests.test_https_ca_bundle',
1698
1788
'bzrlib.tests.test_identitymap',
1699
1789
'bzrlib.tests.test_ignores',
1700
1790
'bzrlib.tests.test_inv',
1713
1803
'bzrlib.tests.test_nonascii',
1714
1804
'bzrlib.tests.test_options',
1715
1805
'bzrlib.tests.test_osutils',
1806
'bzrlib.tests.test_osutils_encodings',
1716
1807
'bzrlib.tests.test_patch',
1717
1808
'bzrlib.tests.test_patches',
1718
1809
'bzrlib.tests.test_permissions',
1736
1827
'bzrlib.tests.test_status',
1737
1828
'bzrlib.tests.test_store',
1738
1829
'bzrlib.tests.test_symbol_versioning',
1830
'bzrlib.tests.test_tag',
1739
1831
'bzrlib.tests.test_testament',
1740
1832
'bzrlib.tests.test_textfile',
1741
1833
'bzrlib.tests.test_textmerge',
1756
1848
'bzrlib.tests.test_weave',
1757
1849
'bzrlib.tests.test_whitebox',
1758
1850
'bzrlib.tests.test_workingtree',
1851
'bzrlib.tests.test_wsgi',
1759
1852
'bzrlib.tests.test_xml',
1761
1854
test_transport_implementations = [
1781
1874
for name, plugin in bzrlib.plugin.all_plugins().items():
1782
1875
if getattr(plugin, 'test_suite', None) is not None:
1783
suite.addTest(plugin.test_suite())
1876
default_encoding = sys.getdefaultencoding()
1878
plugin_suite = plugin.test_suite()
1879
except ImportError, e:
1880
bzrlib.trace.warning(
1881
'Unable to test plugin "%s": %s', name, e)
1883
suite.addTest(plugin_suite)
1884
if default_encoding != sys.getdefaultencoding():
1885
bzrlib.trace.warning(
1886
'Plugin "%s" tried to reset default encoding to: %s', name,
1887
sys.getdefaultencoding())
1889
sys.setdefaultencoding(default_encoding)
1788
1894
"""Adapt the modules in mods_list using adapter and add to suite."""
1789
1895
for test in iter_suite_tests(loader.loadTestsFromModuleNames(mods_list)):
1790
1896
suite.addTests(adapter.adapt(test))
1899
def clean_selftest_output(root=None, quiet=False):
1900
"""Remove all selftest output directories from root directory.
1902
:param root: root directory for clean
1903
(if ommitted or None then clean current directory).
1904
:param quiet: suppress report about deleting directories
1909
re_dir = re.compile(r'''test\d\d\d\d\.tmp''')
1912
for i in os.listdir(root):
1913
if os.path.isdir(i) and re_dir.match(i):
1915
print 'delete directory:', i