1
# Copyright (C) 2005, 2006 by Canonical Ltd
1
# Copyright (C) 2005, 2006 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License version 2 as published by
5
# the Free Software Foundation.
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
8
# This program is distributed in the hope that it will be useful,
8
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
25
from bzrlib import osutils
27
34
from bzrlib.progress import _BaseProgressBar
28
35
from bzrlib.tests import (
39
TestCaseWithMemoryTransport,
32
40
TestCaseWithTransport,
45
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
37
46
from bzrlib.tests.TestUtil import _load_module_by_name
38
47
import bzrlib.errors as errors
48
from bzrlib import symbol_versioning
49
from bzrlib.symbol_versioning import zero_ten, zero_eleven
39
50
from bzrlib.trace import note
51
from bzrlib.transport.memory import MemoryServer, MemoryTransport
52
from bzrlib.version import _get_bzr_source_tree
42
55
class SelftestTests(TestCase):
417
430
self.assertEqual(tests[1].transport_server, server1)
418
431
self.assertEqual(tests[1].transport_readonly_server, server2)
434
class TestTestCaseInTempDir(TestCaseInTempDir):
436
def test_home_is_not_working(self):
437
self.assertNotEqual(self.test_dir, self.test_home_dir)
438
cwd = osutils.getcwd()
439
self.assertEqual(self.test_dir, cwd)
440
self.assertEqual(self.test_home_dir, os.environ['HOME'])
443
class TestTestCaseWithMemoryTransport(TestCaseWithMemoryTransport):
445
def test_home_is_non_existant_dir_under_root(self):
446
"""The test_home_dir for TestCaseWithMemoryTransport is missing.
448
This is because TestCaseWithMemoryTransport is for tests that do not
449
need any disk resources: they should be hooked into bzrlib in such a
450
way that no global settings are being changed by the test (only a
451
few tests should need to do that), and having a missing dir as home is
452
an effective way to ensure that this is the case.
454
self.assertEqual(self.TEST_ROOT + "/MemoryTransportMissingHomeDir",
456
self.assertEqual(self.test_home_dir, os.environ['HOME'])
458
def test_cwd_is_TEST_ROOT(self):
459
self.assertEqual(self.test_dir, self.TEST_ROOT)
460
cwd = osutils.getcwd()
461
self.assertEqual(self.test_dir, cwd)
463
def test_make_branch_and_memory_tree(self):
464
"""In TestCaseWithMemoryTransport we should not make the branch on disk.
466
This is hard to comprehensively robustly test, so we settle for making
467
a branch and checking no directory was created at its relpath.
469
tree = self.make_branch_and_memory_tree('dir')
470
# Guard against regression into MemoryTransport leaking
471
# files to disk instead of keeping them in memory.
472
self.failIf(osutils.lexists('dir'))
473
self.assertIsInstance(tree, memorytree.MemoryTree)
475
def test_make_branch_and_memory_tree_with_format(self):
476
"""make_branch_and_memory_tree should accept a format option."""
477
format = bzrdir.BzrDirMetaFormat1()
478
format.repository_format = repository.RepositoryFormat7()
479
tree = self.make_branch_and_memory_tree('dir', format=format)
480
# Guard against regression into MemoryTransport leaking
481
# files to disk instead of keeping them in memory.
482
self.failIf(osutils.lexists('dir'))
483
self.assertIsInstance(tree, memorytree.MemoryTree)
484
self.assertEqual(format.repository_format.__class__,
485
tree.branch.repository._format.__class__)
420
488
class TestTestCaseWithTransport(TestCaseWithTransport):
421
489
"""Tests for the convenience functions TestCaseWithTransport introduces."""
437
505
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
439
507
def test_get_readonly_url_http(self):
508
from bzrlib.tests.HttpServer import HttpServer
440
509
from bzrlib.transport import get_transport
441
from bzrlib.transport.local import LocalRelpathServer
442
from bzrlib.transport.http import HttpServer, HttpTransportBase
443
self.transport_server = LocalRelpathServer
510
from bzrlib.transport.local import LocalURLServer
511
from bzrlib.transport.http import HttpTransportBase
512
self.transport_server = LocalURLServer
444
513
self.transport_readonly_server = HttpServer
445
514
# calling get_readonly_transport() gives us a HTTP server instance.
446
515
url = self.get_readonly_url()
461
530
self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
533
class TestTestCaseTransports(TestCaseWithTransport):
536
super(TestTestCaseTransports, self).setUp()
537
self.transport_server = MemoryServer
539
def test_make_bzrdir_preserves_transport(self):
540
t = self.get_transport()
541
result_bzrdir = self.make_bzrdir('subdir')
542
self.assertIsInstance(result_bzrdir.transport,
544
# should not be on disk, should only be in memory
545
self.failIfExists('subdir')
464
548
class TestChrootedTest(ChrootedTestCase):
466
550
def test_root_is_root(self):
496
580
class TestTestResult(TestCase):
498
def test_progress_bar_style_quiet(self):
499
# test using a progress bar.
500
dummy_test = TestTestResult('test_progress_bar_style_quiet')
501
dummy_error = (Exception, None, [])
502
mypb = MockProgress()
503
mypb.update('Running tests', 0, 4)
504
last_calls = mypb.calls[:]
506
result = bzrlib.tests._MyResult(self._log_file,
510
self.assertEqual(last_calls, mypb.calls)
513
"""Shorten a string based on the terminal width"""
514
return result._ellipsise_unimportant_words(s,
515
osutils.terminal_width())
518
result.startTest(dummy_test)
519
# starting a test prints the test name
520
last_calls += [('update', '...tyle_quiet', 0, None)]
521
self.assertEqual(last_calls, mypb.calls)
522
result.addError(dummy_test, dummy_error)
523
last_calls += [('update', 'ERROR ', 1, None),
524
('note', shorten(dummy_test.id() + ': ERROR'), ())
526
self.assertEqual(last_calls, mypb.calls)
529
result.startTest(dummy_test)
530
last_calls += [('update', '...tyle_quiet', 1, None)]
531
self.assertEqual(last_calls, mypb.calls)
532
last_calls += [('update', 'FAIL ', 2, None),
533
('note', shorten(dummy_test.id() + ': FAIL'), ())
535
result.addFailure(dummy_test, dummy_error)
536
self.assertEqual(last_calls, mypb.calls)
539
result.startTest(dummy_test)
540
last_calls += [('update', '...tyle_quiet', 2, None)]
541
self.assertEqual(last_calls, mypb.calls)
542
result.addSuccess(dummy_test)
543
last_calls += [('update', 'OK ', 3, None)]
544
self.assertEqual(last_calls, mypb.calls)
547
result.startTest(dummy_test)
548
last_calls += [('update', '...tyle_quiet', 3, None)]
549
self.assertEqual(last_calls, mypb.calls)
550
result.addSkipped(dummy_test, dummy_error)
551
last_calls += [('update', 'SKIP ', 4, None)]
552
self.assertEqual(last_calls, mypb.calls)
554
582
def test_elapsed_time_with_benchmarking(self):
555
result = bzrlib.tests._MyResult(self._log_file,
583
result = bzrlib.tests.TextTestResult(self._log_file,
561
589
result.extractBenchmarkTime(self)
562
590
timed_string = result._testTimeString()
563
591
# without explicit benchmarking, we should get a simple time.
564
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms$")
592
self.assertContainsRe(timed_string, "^ *[ 1-9][0-9]ms$")
565
593
# if a benchmark time is given, we want a x of y style result.
566
594
self.time(time.sleep, 0.001)
567
595
result.extractBenchmarkTime(self)
568
596
timed_string = result._testTimeString()
569
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms/ [ 1-9][0-9]ms$")
597
self.assertContainsRe(timed_string, "^ *[ 1-9][0-9]ms/ *[ 1-9][0-9]ms$")
570
598
# extracting the time from a non-bzrlib testcase sets to None
571
599
result._recordTestStartTime()
572
600
result.extractBenchmarkTime(
573
601
unittest.FunctionTestCase(self.test_elapsed_time_with_benchmarking))
574
602
timed_string = result._testTimeString()
575
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms$")
603
self.assertContainsRe(timed_string, "^ *[ 1-9][0-9]ms$")
576
604
# cheat. Yes, wash thy mouth out with soap.
577
605
self._benchtime = None
607
def test_assigned_benchmark_file_stores_date(self):
609
result = bzrlib.tests.TextTestResult(self._log_file,
614
output_string = output.getvalue()
616
# if you are wondering about the regexp please read the comment in
617
# test_bench_history (bzrlib.tests.test_selftest.TestRunner)
618
# XXX: what comment? -- Andrew Bennetts
619
self.assertContainsRe(output_string, "--date [0-9.]+")
621
def test_benchhistory_records_test_times(self):
622
result_stream = StringIO()
623
result = bzrlib.tests.TextTestResult(
627
bench_history=result_stream
630
# we want profile a call and check that its test duration is recorded
631
# make a new test instance that when run will generate a benchmark
632
example_test_case = TestTestResult("_time_hello_world_encoding")
633
# execute the test, which should succeed and record times
634
example_test_case.run(result)
635
lines = result_stream.getvalue().splitlines()
636
self.assertEqual(2, len(lines))
637
self.assertContainsRe(lines[1],
638
" *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
639
"._time_hello_world_encoding")
579
641
def _time_hello_world_encoding(self):
580
642
"""Profile two sleep calls
647
709
TestCaseInTempDir.TEST_ROOT = old_root
649
def test_accepts_and_uses_pb_parameter(self):
650
test = TestRunner('dummy_test')
651
mypb = MockProgress()
652
self.assertEqual([], mypb.calls)
653
runner = TextTestRunner(stream=self._log_file, pb=mypb)
654
result = self.run_test_runner(runner, test)
655
self.assertEqual(1, result.testsRun)
656
self.assertEqual(('update', 'Running tests', 0, 1), mypb.calls[0])
657
self.assertEqual(('update', '...dummy_test', 0, None), mypb.calls[1])
658
self.assertEqual(('update', 'OK ', 1, None), mypb.calls[2])
659
self.assertEqual(('update', 'Cleaning up', 0, 1), mypb.calls[3])
660
self.assertEqual(('clear',), mypb.calls[4])
661
self.assertEqual(5, len(mypb.calls))
663
711
def test_skipped_test(self):
664
712
# run a test that is skipped, and check the suite as a whole still
671
719
result = self.run_test_runner(runner, test)
672
720
self.assertTrue(result.wasSuccessful())
722
def test_bench_history(self):
723
# tests that the running the benchmark produces a history file
724
# containing a timestamp and the revision id of the bzrlib source which
726
workingtree = _get_bzr_source_tree()
727
test = TestRunner('dummy_test')
729
runner = TextTestRunner(stream=self._log_file, bench_history=output)
730
result = self.run_test_runner(runner, test)
731
output_string = output.getvalue()
732
self.assertContainsRe(output_string, "--date [0-9.]+")
733
if workingtree is not None:
734
revision_id = workingtree.get_parent_ids()[0]
735
self.assertEndsWith(output_string.rstrip(), revision_id)
737
def test_success_log_deleted(self):
738
"""Successful tests have their log deleted"""
740
class LogTester(TestCase):
742
def test_success(self):
743
self.log('this will be removed\n')
745
sio = cStringIO.StringIO()
746
runner = TextTestRunner(stream=sio)
747
test = LogTester('test_success')
748
result = self.run_test_runner(runner, test)
750
log = test._get_log()
751
self.assertEqual("DELETED log file to reduce memory footprint", log)
752
self.assertEqual('', test._log_contents)
753
self.assertIs(None, test._log_file_name)
755
def test_fail_log_kept(self):
756
"""Failed tests have their log kept"""
758
class LogTester(TestCase):
761
self.log('this will be kept\n')
762
self.fail('this test fails')
764
sio = cStringIO.StringIO()
765
runner = TextTestRunner(stream=sio)
766
test = LogTester('test_fail')
767
result = self.run_test_runner(runner, test)
769
text = sio.getvalue()
770
self.assertContainsRe(text, 'this will be kept')
771
self.assertContainsRe(text, 'this test fails')
773
log = test._get_log()
774
self.assertContainsRe(log, 'this will be kept')
775
self.assertEqual(log, test._log_contents)
777
def test_error_log_kept(self):
778
"""Tests with errors have their log kept"""
780
class LogTester(TestCase):
782
def test_error(self):
783
self.log('this will be kept\n')
784
raise ValueError('random exception raised')
786
sio = cStringIO.StringIO()
787
runner = TextTestRunner(stream=sio)
788
test = LogTester('test_error')
789
result = self.run_test_runner(runner, test)
791
text = sio.getvalue()
792
self.assertContainsRe(text, 'this will be kept')
793
self.assertContainsRe(text, 'random exception raised')
795
log = test._get_log()
796
self.assertContainsRe(log, 'this will be kept')
797
self.assertEqual(log, test._log_contents)
675
800
class TestTestCase(TestCase):
676
801
"""Tests that test the core bzrlib TestCase."""
718
843
"""Test that the TestCase.time() method accumulates a benchmark time."""
719
844
sample_test = TestTestCase("method_that_times_a_bit_twice")
720
845
output_stream = StringIO()
721
result = bzrlib.tests._MyResult(
846
result = bzrlib.tests.VerboseTestResult(
722
847
unittest._WritelnDecorator(output_stream),
850
num_tests=sample_test.countTestCases())
725
851
sample_test.run(result)
726
852
self.assertContainsRe(
727
853
output_stream.getvalue(),
728
"[1-9][0-9]ms/ [1-9][0-9]ms\n$")
856
def test_hooks_sanitised(self):
857
"""The bzrlib hooks should be sanitised by setUp."""
858
self.assertEqual(bzrlib.branch.BranchHooks(),
859
bzrlib.branch.Branch.hooks)
730
861
def test__gather_lsprof_in_benchmarks(self):
731
862
"""When _gather_lsprof_in_benchmarks is on, accumulate profile data.
748
879
self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
882
@symbol_versioning.deprecated_function(zero_eleven)
883
def sample_deprecated_function():
884
"""A deprecated function to test applyDeprecated with."""
888
def sample_undeprecated_function(a_param):
889
"""A undeprecated function to test applyDeprecated with."""
892
class ApplyDeprecatedHelper(object):
893
"""A helper class for ApplyDeprecated tests."""
895
@symbol_versioning.deprecated_method(zero_eleven)
896
def sample_deprecated_method(self, param_one):
897
"""A deprecated method for testing with."""
900
def sample_normal_method(self):
901
"""A undeprecated method."""
903
@symbol_versioning.deprecated_method(zero_ten)
904
def sample_nested_deprecation(self):
905
return sample_deprecated_function()
751
908
class TestExtraAssertions(TestCase):
752
909
"""Tests for new test assertions in bzrlib test suite"""
761
918
self.assertEndsWith('foo', 'oo')
762
919
self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
921
def test_applyDeprecated_not_deprecated(self):
922
sample_object = ApplyDeprecatedHelper()
923
# calling an undeprecated callable raises an assertion
924
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
925
sample_object.sample_normal_method)
926
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
927
sample_undeprecated_function, "a param value")
928
# calling a deprecated callable (function or method) with the wrong
929
# expected deprecation fails.
930
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
931
sample_object.sample_deprecated_method, "a param value")
932
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
933
sample_deprecated_function)
934
# calling a deprecated callable (function or method) with the right
935
# expected deprecation returns the functions result.
936
self.assertEqual("a param value", self.applyDeprecated(zero_eleven,
937
sample_object.sample_deprecated_method, "a param value"))
938
self.assertEqual(2, self.applyDeprecated(zero_eleven,
939
sample_deprecated_function))
940
# calling a nested deprecation with the wrong deprecation version
941
# fails even if a deeper nested function was deprecated with the
943
self.assertRaises(AssertionError, self.applyDeprecated,
944
zero_eleven, sample_object.sample_nested_deprecation)
945
# calling a nested deprecation with the right deprecation value
946
# returns the calls result.
947
self.assertEqual(2, self.applyDeprecated(zero_ten,
948
sample_object.sample_nested_deprecation))
950
def test_callDeprecated(self):
951
def testfunc(be_deprecated, result=None):
952
if be_deprecated is True:
953
symbol_versioning.warn('i am deprecated', DeprecationWarning,
956
result = self.callDeprecated(['i am deprecated'], testfunc, True)
957
self.assertIs(None, result)
958
result = self.callDeprecated([], testfunc, False, 'result')
959
self.assertEqual('result', result)
960
self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
961
self.callDeprecated([], testfunc, be_deprecated=False)
765
964
class TestConvenienceMakers(TestCaseWithTransport):
766
965
"""Test for the make_* convenience functions."""
774
973
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
775
974
bzrlib.bzrdir.BzrDirFormat6)
976
def test_make_branch_and_memory_tree(self):
977
# we should be able to get a new branch and a mutable tree from
978
# TestCaseWithTransport
979
tree = self.make_branch_and_memory_tree('a')
980
self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
983
class TestSFTPMakeBranchAndTree(TestCaseWithSFTPServer):
985
def test_make_tree_for_sftp_branch(self):
986
"""Transports backed by local directories create local trees."""
988
tree = self.make_branch_and_tree('t1')
989
base = tree.bzrdir.root_transport.base
990
self.failIf(base.startswith('sftp'),
991
'base %r is on sftp but should be local' % base)
992
self.assertEquals(tree.bzrdir.root_transport,
993
tree.branch.bzrdir.root_transport)
994
self.assertEquals(tree.bzrdir.root_transport,
995
tree.branch.repository.bzrdir.root_transport)
778
998
class TestSelftest(TestCase):
779
999
"""Tests of bzrlib.tests.selftest."""
788
1008
self.apply_redirected(out, err, None, bzrlib.tests.selftest,
789
1009
test_suite_factory=factory)
790
1010
self.assertEqual([True], factory_called)
1013
class TestSelftestCleanOutput(TestCaseInTempDir):
1015
def test_clean_output(self):
1016
# test functionality of clean_selftest_output()
1017
from bzrlib.tests import clean_selftest_output
1019
dirs = ('test0000.tmp', 'test0001.tmp', 'bzrlib', 'tests')
1020
files = ('bzr', 'setup.py', 'test9999.tmp')
1025
f.write('content of ')
1030
before = os.listdir(root)
1032
self.assertEquals(['bzr','bzrlib','setup.py',
1033
'test0000.tmp','test0001.tmp',
1034
'test9999.tmp','tests'],
1036
clean_selftest_output(root, quiet=True)
1037
after = os.listdir(root)
1039
self.assertEquals(['bzr','bzrlib','setup.py',
1040
'test9999.tmp','tests'],