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
171
175
bench_history.write("--date %s %s\n" % (time.time(), revision_id))
172
176
self._bench_history = bench_history
173
self.ui = bzrlib.ui.ui_factory
177
self.ui = ui.ui_factory
174
178
self.num_tests = num_tests
175
179
self.error_count = 0
176
180
self.failure_count = 0
208
212
def startTest(self, test):
209
213
unittest.TestResult.startTest(self, test)
210
214
self.report_test_start(test)
215
test.number = self.count
211
216
self._recordTestStartTime()
213
218
def _recordTestStartTime(self):
325
330
+ self._shortened_test_description(test))
332
def _test_description(self, test):
334
return '#%d %s' % (self.count,
335
self._shortened_test_description(test))
337
return self._shortened_test_description(test)
327
339
def report_error(self, test, err):
328
340
self.error_count += 1
329
341
self.pb.note('ERROR: %s\n %s\n',
330
self._shortened_test_description(test),
342
self._test_description(test),
334
346
def report_failure(self, test, err):
335
347
self.failure_count += 1
336
348
self.pb.note('FAIL: %s\n %s\n',
337
self._shortened_test_description(test),
349
self._test_description(test),
380
392
name = self._shortened_test_description(test)
381
393
# width needs space for 6 char status, plus 1 for slash, plus 2 10-char
382
394
# numbers, plus a trailing blank
383
self.stream.write(self._ellipsize_to_right(name,
384
osutils.terminal_width()-30))
395
# when NUMBERED_DIRS: plus 5 chars on test number, plus 1 char on space
397
self.stream.write('%5d ' % self.count)
398
self.stream.write(self._ellipsize_to_right(name,
399
osutils.terminal_width()-36))
401
self.stream.write(self._ellipsize_to_right(name,
402
osutils.terminal_width()-30))
385
403
self.stream.flush()
405
def _error_summary(self, err):
409
return '%s%s' % (indent, err[1])
387
411
def report_error(self, test, err):
388
412
self.error_count += 1
389
self.stream.writeln('ERROR %s\n %s'
390
% (self._testTimeString(), err[1]))
413
self.stream.writeln('ERROR %s\n%s'
414
% (self._testTimeString(),
415
self._error_summary(err)))
392
417
def report_failure(self, test, err):
393
418
self.failure_count += 1
394
self.stream.writeln(' FAIL %s\n %s'
395
% (self._testTimeString(), err[1]))
419
self.stream.writeln(' FAIL %s\n%s'
420
% (self._testTimeString(),
421
self._error_summary(err)))
397
423
def report_success(self, test):
398
424
self.stream.writeln(' OK %s' % self._testTimeString())
402
428
self.stream.flush()
404
430
def report_skip(self, test, skip_excinfo):
405
print >>self.stream, ' SKIP %s' % self._testTimeString()
406
print >>self.stream, ' %s' % skip_excinfo[1]
432
self.stream.writeln(' SKIP %s\n%s'
433
% (self._testTimeString(),
434
self._error_summary(skip_excinfo)))
409
437
class TextTestRunner(object):
456
484
self.stream.writeln(")")
458
486
self.stream.writeln("OK")
487
if result.skip_count > 0:
488
skipped = result.skip_count
489
self.stream.writeln('%d test%s skipped' %
490
(skipped, skipped != 1 and "s" or ""))
459
491
result.report_cleaning_up()
460
492
# This is still a little bogus,
461
493
# but only a little. Folk not using our testrunner will
476
508
test_root = test_root.encode(
477
509
sys.getfilesystemencoding())
478
osutils.rmtree(test_root)
511
osutils.rmtree(test_root)
513
if sys.platform == 'win32' and e.errno == errno.EACCES:
514
print >>sys.stderr, ('Permission denied: '
515
'unable to remove testing dir '
516
'%s' % os.path.basename(test_root))
480
520
note("Failed tests working directories are in '%s'\n", test_root)
481
521
TestCaseWithMemoryTransport.TEST_ROOT = None
530
570
return setattr(self._cstring, name, val)
573
class TestUIFactory(ui.CLIUIFactory):
574
"""A UI Factory for testing.
576
Hide the progress bar but emit note()s.
578
Allows get_password to be tested without real tty attached.
585
super(TestUIFactory, self).__init__()
586
if stdin is not None:
587
# We use a StringIOWrapper to be able to test various
588
# encodings, but the user is still responsible to
589
# encode the string and to set the encoding attribute
590
# of StringIOWrapper.
591
self.stdin = StringIOWrapper(stdin)
593
self.stdout = sys.stdout
597
self.stderr = sys.stderr
602
"""See progress.ProgressBar.clear()."""
604
def clear_term(self):
605
"""See progress.ProgressBar.clear_term()."""
607
def clear_term(self):
608
"""See progress.ProgressBar.clear_term()."""
611
"""See progress.ProgressBar.finished()."""
613
def note(self, fmt_string, *args, **kwargs):
614
"""See progress.ProgressBar.note()."""
615
self.stdout.write((fmt_string + "\n") % args)
617
def progress_bar(self):
620
def nested_progress_bar(self):
623
def update(self, message, count=None, total=None):
624
"""See progress.ProgressBar.update()."""
626
def get_non_echoed_password(self, prompt):
627
"""Get password from stdin without trying to handle the echo mode"""
629
self.stdout.write(prompt)
630
password = self.stdin.readline()
633
if password[-1] == '\n':
634
password = password[:-1]
533
638
class TestCase(unittest.TestCase):
534
639
"""Base class for bzr unit tests.
579
684
def _silenceUI(self):
580
685
"""Turn off UI for duration of test"""
581
686
# by default the UI is off; tests can turn it on if they want it.
582
saved = bzrlib.ui.ui_factory
687
saved = ui.ui_factory
584
bzrlib.ui.ui_factory = saved
585
bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
689
ui.ui_factory = saved
690
ui.ui_factory = ui.SilentUIFactory()
586
691
self.addCleanup(_restore)
588
693
def _ndiff_strings(self, a, b):
600
705
charjunk=lambda x: False)
601
706
return ''.join(difflines)
708
def assertEqual(self, a, b, message=''):
713
raise AssertionError("%snot equal:\na = %s\nb = %s\n"
715
pformat(a, indent=4), pformat(b, indent=4)))
717
assertEquals = assertEqual
603
719
def assertEqualDiff(self, a, b, message=None):
604
720
"""Assert two texts are equal, if not raise an exception.
630
746
def assertContainsRe(self, haystack, needle_re):
631
747
"""Assert that a contains something matching a regular expression."""
632
748
if not re.search(needle_re, haystack):
633
raise AssertionError('pattern "%s" not found in "%s"'
749
raise AssertionError('pattern "%r" not found in "%r"'
634
750
% (needle_re, haystack))
636
752
def assertNotContainsRe(self, haystack, needle_re):
741
857
expected_first_warning = symbol_versioning.deprecation_string(
742
858
a_callable, deprecation_format)
743
859
if len(call_warnings) == 0:
744
self.fail("No assertion generated by call to %s" %
860
self.fail("No deprecation warning generated by call to %s" %
746
862
self.assertEqual(expected_first_warning, call_warnings[0])
809
925
'BZR_HOME': None, # Don't inherit BZR_HOME to all the tests.
810
926
'HOME': os.getcwd(),
811
'APPDATA': os.getcwd(),
927
'APPDATA': None, # bzr now use Win32 API and don't rely on APPDATA
812
928
'BZR_EMAIL': None,
813
929
'BZREMAIL': None, # may still be present in the environment
901
1017
if not keep_log_file:
902
1018
self._log_contents = log_contents
903
os.remove(self._log_file_name)
1020
os.remove(self._log_file_name)
1022
if sys.platform == 'win32' and e.errno == errno.EACCES:
1023
print >>sys.stderr, ('Unable to delete log file '
1024
' %r' % self._log_file_name)
904
1027
return log_contents
906
1029
return "DELETED log file to reduce memory footprint"
948
1069
handler.setLevel(logging.INFO)
949
1070
logger = logging.getLogger('')
950
1071
logger.addHandler(handler)
951
old_ui_factory = bzrlib.ui.ui_factory
952
bzrlib.ui.ui_factory = bzrlib.tests.blackbox.TestUIFactory(
955
bzrlib.ui.ui_factory.stdin = stdin
1072
old_ui_factory = ui.ui_factory
1073
ui.ui_factory = TestUIFactory(stdin=stdin, stdout=stdout, stderr=stderr)
958
1076
if working_dir is not None:
963
1081
saved_debug_flags = frozenset(debug.debug_flags)
964
1082
debug.debug_flags.clear()
966
result = self.apply_redirected(stdin, stdout, stderr,
1084
result = self.apply_redirected(ui.ui_factory.stdin,
967
1086
bzrlib.commands.run_bzr_catch_errors,
970
1089
debug.debug_flags.update(saved_debug_flags)
972
1091
logger.removeHandler(handler)
973
bzrlib.ui.ui_factory = old_ui_factory
1092
ui.ui_factory = old_ui_factory
974
1093
if cwd is not None:
995
1114
where it may be useful for debugging. See also run_captured.
997
1116
:param stdin: A string to be used as stdin for the command.
1117
:param retcode: The status code the command should return
1118
:param working_dir: The directory to run the command in
999
1120
retcode = kwargs.pop('retcode', 0)
1000
1121
encoding = kwargs.pop('encoding', None)
1496
1617
def overrideEnvironmentForTesting(self):
1497
1618
os.environ['HOME'] = self.test_home_dir
1498
os.environ['APPDATA'] = self.test_home_dir
1619
os.environ['BZR_HOME'] = self.test_home_dir
1500
1621
def setUp(self):
1501
1622
super(TestCaseWithMemoryTransport, self).setUp()
1539
1660
For TestCaseInTempDir we create a temporary directory based on the test
1540
1661
name and then create two subdirs - test and home under it.
1663
if NUMBERED_DIRS: # strongly recommended on Windows
1664
# due the path length limitation (260 chars)
1665
candidate_dir = '%s/%dK/%05d' % (self.TEST_ROOT,
1666
int(self.number/1000),
1668
os.makedirs(candidate_dir)
1669
self.test_home_dir = candidate_dir + '/home'
1670
os.mkdir(self.test_home_dir)
1671
self.test_dir = candidate_dir + '/work'
1672
os.mkdir(self.test_dir)
1673
os.chdir(self.test_dir)
1674
# put name of test inside
1675
f = file(candidate_dir + '/name', 'w')
1542
1680
# shorten the name, to avoid test failures due to path length
1543
1681
short_id = self.id().replace('bzrlib.tests.', '') \
1544
1682
.replace('__main__.', '')[-100:]
1686
1824
self.fail("path %s is not a directory; has mode %#o"
1687
1825
% (relpath, mode))
1827
def assertTreesEqual(self, left, right):
1828
"""Check that left and right have the same content and properties."""
1829
# we use a tree delta to check for equality of the content, and we
1830
# manually check for equality of other things such as the parents list.
1831
self.assertEqual(left.get_parent_ids(), right.get_parent_ids())
1832
differences = left.changes_from(right)
1833
self.assertFalse(differences.has_changed(),
1834
"Trees %r and %r are different: %r" % (left, right, differences))
1689
1836
def setUp(self):
1690
1837
super(TestCaseWithTransport, self).setUp()
1691
1838
self.__vfs_server = None
1735
1882
def run_suite(suite, name='test', verbose=False, pattern=".*",
1736
1883
stop_on_failure=False, keep_output=False,
1737
1884
transport=None, lsprof_timed=None, bench_history=None,
1738
matching_tests_first=None):
1885
matching_tests_first=None,
1886
numbered_dirs=None):
1887
global NUMBERED_DIRS
1888
if numbered_dirs is not None:
1889
NUMBERED_DIRS = bool(numbered_dirs)
1739
1891
TestCase._gather_lsprof_in_benchmarks = lsprof_timed
1762
1914
test_suite_factory=None,
1763
1915
lsprof_timed=None,
1764
1916
bench_history=None,
1765
matching_tests_first=None):
1917
matching_tests_first=None,
1918
numbered_dirs=None):
1766
1919
"""Run the whole test suite under the enhanced runner"""
1767
1920
# XXX: Very ugly way to do this...
1768
1921
# Disable warning about old formats because we don't want it to disturb
1785
1938
transport=transport,
1786
1939
lsprof_timed=lsprof_timed,
1787
1940
bench_history=bench_history,
1788
matching_tests_first=matching_tests_first)
1941
matching_tests_first=matching_tests_first,
1942
numbered_dirs=numbered_dirs)
1790
1944
default_transport = old_transport
1814
1968
'bzrlib.tests.test_decorators',
1815
1969
'bzrlib.tests.test_delta',
1816
1970
'bzrlib.tests.test_diff',
1971
'bzrlib.tests.test_dirstate',
1817
1972
'bzrlib.tests.test_doc_generate',
1818
1973
'bzrlib.tests.test_errors',
1819
1974
'bzrlib.tests.test_escaped_store',
1975
'bzrlib.tests.test_extract',
1820
1976
'bzrlib.tests.test_fetch',
1821
1977
'bzrlib.tests.test_ftp_transport',
1822
1978
'bzrlib.tests.test_generate_docs',
1841
1997
'bzrlib.tests.test_merge',
1842
1998
'bzrlib.tests.test_merge3',
1843
1999
'bzrlib.tests.test_merge_core',
2000
'bzrlib.tests.test_merge_directive',
1844
2001
'bzrlib.tests.test_missing',
1845
2002
'bzrlib.tests.test_msgeditor',
1846
2003
'bzrlib.tests.test_nonascii',
1869
2026
'bzrlib.tests.test_smart_add',
1870
2027
'bzrlib.tests.test_smart_transport',
1871
2028
'bzrlib.tests.test_source',
2029
'bzrlib.tests.test_ssh_transport',
1872
2030
'bzrlib.tests.test_status',
1873
2031
'bzrlib.tests.test_store',
2032
'bzrlib.tests.test_subsume',
1874
2033
'bzrlib.tests.test_symbol_versioning',
2034
'bzrlib.tests.test_tag',
1875
2035
'bzrlib.tests.test_testament',
1876
2036
'bzrlib.tests.test_textfile',
1877
2037
'bzrlib.tests.test_textmerge',
2038
'bzrlib.tests.test_timestamp',
1878
2039
'bzrlib.tests.test_trace',
1879
2040
'bzrlib.tests.test_transactions',
1880
2041
'bzrlib.tests.test_transform',
1892
2053
'bzrlib.tests.test_weave',
1893
2054
'bzrlib.tests.test_whitebox',
1894
2055
'bzrlib.tests.test_workingtree',
2056
'bzrlib.tests.test_workingtree_4',
1895
2057
'bzrlib.tests.test_wsgi',
1896
2058
'bzrlib.tests.test_xml',