~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-11-17 03:20:35 UTC
  • mfrom: (4792.4.3 456036)
  • Revision ID: pqm@pqm.ubuntu.com-20091117032035-s3sgtlixj1lrminn
(Gordon Tyler) Fix IndexError during 'bzr ignore /' (#456036)

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
"""Tests for the test framework."""
18
18
 
19
19
from cStringIO import StringIO
20
 
from doctest import ELLIPSIS
21
20
import os
22
21
import signal
23
22
import sys
25
24
import unittest
26
25
import warnings
27
26
 
28
 
from testtools import MultiTestResult
29
 
from testtools.content_type import ContentType
30
 
from testtools.matchers import (
31
 
    DocTestMatches,
32
 
    Equals,
33
 
    )
34
 
import testtools.tests.helpers
35
 
 
36
27
import bzrlib
37
28
from bzrlib import (
38
29
    branchbuilder,
61
52
    deprecated_method,
62
53
    )
63
54
from bzrlib.tests import (
64
 
    features,
 
55
    SubUnitFeature,
65
56
    test_lsprof,
66
57
    test_sftp_transport,
67
58
    TestUtil,
87
78
                          TestUtil._load_module_by_name,
88
79
                          'bzrlib.no-name-yet')
89
80
 
90
 
 
91
81
class MetaTestLog(tests.TestCase):
92
82
 
93
83
    def test_logging(self):
94
84
        """Test logs are captured when a test fails."""
95
85
        self.log('a test message')
96
 
        details = self.getDetails()
97
 
        log = details['log']
98
 
        self.assertThat(log.content_type, Equals(ContentType(
99
 
            "text", "plain", {"charset": "utf8"})))
100
 
        self.assertThat(u"".join(log.iter_text()), Equals(self.get_log()))
101
 
        self.assertThat(self.get_log(),
102
 
            DocTestMatches(u"...a test message\n", ELLIPSIS))
 
86
        self._log_file.flush()
 
87
        self.assertContainsRe(self._get_log(keep_log_file=True),
 
88
                              'a test message\n')
103
89
 
104
90
 
105
91
class TestUnicodeFilename(tests.TestCase):
504
490
        self.assertEqualStat(real, fake)
505
491
 
506
492
    def test_assertEqualStat_notequal(self):
507
 
        self.build_tree(["foo", "longname"])
 
493
        self.build_tree(["foo", "bar"])
508
494
        self.assertRaises(AssertionError, self.assertEqualStat,
509
 
            os.lstat("foo"), os.lstat("longname"))
 
495
            os.lstat("foo"), os.lstat("bar"))
510
496
 
511
497
 
512
498
class TestTestCaseWithMemoryTransport(tests.TestCaseWithMemoryTransport):
530
516
        cwd = osutils.getcwd()
531
517
        self.assertIsSameRealPath(self.test_dir, cwd)
532
518
 
533
 
    def test_BZR_HOME_and_HOME_are_bytestrings(self):
534
 
        """The $BZR_HOME and $HOME environment variables should not be unicode.
535
 
 
536
 
        See https://bugs.launchpad.net/bzr/+bug/464174
537
 
        """
538
 
        self.assertIsInstance(os.environ['BZR_HOME'], str)
539
 
        self.assertIsInstance(os.environ['HOME'], str)
540
 
 
541
519
    def test_make_branch_and_memory_tree(self):
542
520
        """In TestCaseWithMemoryTransport we should not make the branch on disk.
543
521
 
701
679
 
702
680
    def test_profiles_tests(self):
703
681
        self.requireFeature(test_lsprof.LSProfFeature)
704
 
        terminal = testtools.tests.helpers.ExtendedTestResult()
 
682
        terminal = unittest.TestResult()
705
683
        result = tests.ProfileResult(terminal)
706
684
        class Sample(tests.TestCase):
707
685
            def a(self):
709
687
            def sample_function(self):
710
688
                pass
711
689
        test = Sample("a")
 
690
        test.attrs_to_keep = test.attrs_to_keep + ('_benchcalls',)
712
691
        test.run(result)
713
 
        case = terminal._events[0][1]
714
 
        self.assertLength(1, case._benchcalls)
 
692
        self.assertLength(1, test._benchcalls)
715
693
        # We must be able to unpack it as the test reporting code wants
716
 
        (_, _, _), stats = case._benchcalls[0]
 
694
        (_, _, _), stats = test._benchcalls[0]
717
695
        self.assertTrue(callable(stats.pprint))
718
696
 
719
697
 
724
702
                descriptions=0,
725
703
                verbosity=1,
726
704
                )
727
 
        capture = testtools.tests.helpers.ExtendedTestResult()
728
 
        test_case.run(MultiTestResult(result, capture))
729
 
        run_case = capture._events[0][1]
730
 
        timed_string = result._testTimeString(run_case)
 
705
        test_case.run(result)
 
706
        timed_string = result._testTimeString(test_case)
731
707
        self.assertContainsRe(timed_string, expected_re)
732
708
 
733
709
    def test_test_reporting(self):
848
824
            def stopTestRun(self): pass
849
825
            def startTests(self): pass
850
826
            def report_test_start(self, test): pass
851
 
            def report_known_failure(self, test, err=None, details=None):
852
 
                self._call = test, 'known failure'
 
827
            def report_known_failure(self, test, err):
 
828
                self._call = test, err
853
829
        result = InstrumentedTestResult(None, None, None, None)
854
830
        class Test(tests.TestCase):
855
831
            def test_function(self):
858
834
        test.run(result)
859
835
        # it should invoke 'report_known_failure'.
860
836
        self.assertEqual(2, len(result._call))
861
 
        self.assertEqual(test.id(), result._call[0].id())
862
 
        self.assertEqual('known failure', result._call[1])
 
837
        self.assertEqual(test, result._call[0])
 
838
        self.assertEqual(tests.KnownFailure, result._call[1][0])
 
839
        self.assertIsInstance(result._call[1][1], tests.KnownFailure)
863
840
        # we dont introspec the traceback, if the rest is ok, it would be
864
841
        # exceptional for it not to be.
865
842
        # it should update the known_failure_count on the object.
937
914
        result.report_unsupported(test, feature)
938
915
        output = result_stream.getvalue()[prefix:]
939
916
        lines = output.splitlines()
940
 
        # We don't check for the final '0ms' since it may fail on slow hosts
941
 
        self.assertStartsWith(lines[0], 'NODEP')
942
 
        self.assertEqual(lines[1],
943
 
                         "    The feature 'Feature' is not available.")
 
917
        self.assertEqual(lines, ['NODEP        0ms',
 
918
                                 "    The feature 'Feature' is not available."])
944
919
 
945
920
    def test_unavailable_exception(self):
946
921
        """An UnavailableFeature being raised should invoke addNotSupported."""
959
934
        test.run(result)
960
935
        # it should invoke 'addNotSupported'.
961
936
        self.assertEqual(2, len(result._call))
962
 
        self.assertEqual(test.id(), result._call[0].id())
 
937
        self.assertEqual(test, result._call[0])
963
938
        self.assertEqual(feature, result._call[1])
964
939
        # and not count as an error
965
940
        self.assertEqual(0, result.error_count)
1043
1018
        # the final output when real failures occur.
1044
1019
        class Test(tests.TestCase):
1045
1020
            def known_failure_test(self):
1046
 
                self.expectFailure('failed', self.assertTrue, False)
 
1021
                raise tests.KnownFailure('failed')
1047
1022
        test = unittest.TestSuite()
1048
1023
        test.addTest(Test("known_failure_test"))
1049
1024
        def failing_test():
1050
 
            self.fail('foo')
 
1025
            raise AssertionError('foo')
1051
1026
        test.addTest(unittest.FunctionTestCase(failing_test))
1052
1027
        stream = StringIO()
1053
1028
        runner = tests.TextTestRunner(stream=stream)
1054
1029
        result = self.run_test_runner(runner, test)
1055
1030
        lines = stream.getvalue().splitlines()
1056
1031
        self.assertContainsRe(stream.getvalue(),
1057
 
            '(?sm)^bzr selftest.*$'
 
1032
            '(?sm)^testing.*$'
1058
1033
            '.*'
1059
1034
            '^======================================================================\n'
1060
1035
            '^FAIL: unittest.FunctionTestCase \\(failing_test\\)\n'
1061
1036
            '^----------------------------------------------------------------------\n'
1062
1037
            'Traceback \\(most recent call last\\):\n'
1063
1038
            '  .*' # File .*, line .*, in failing_test' - but maybe not from .pyc
1064
 
            '    self.fail\\(\'foo\'\\)\n'
 
1039
            '    raise AssertionError\\(\'foo\'\\)\n'
1065
1040
            '.*'
1066
1041
            '^----------------------------------------------------------------------\n'
1067
1042
            '.*'
1073
1048
        # the final output.
1074
1049
        class Test(tests.TestCase):
1075
1050
            def known_failure_test(self):
1076
 
                self.expectFailure('failed', self.assertTrue, False)
 
1051
                raise tests.KnownFailure('failed')
1077
1052
        test = Test("known_failure_test")
1078
1053
        stream = StringIO()
1079
1054
        runner = tests.TextTestRunner(stream=stream)
1224
1199
        self.assertContainsRe(output_string, "--date [0-9.]+")
1225
1200
        self.assertLength(1, self._get_source_tree_calls)
1226
1201
 
 
1202
    def assertLogDeleted(self, test):
 
1203
        log = test._get_log()
 
1204
        self.assertEqual("DELETED log file to reduce memory footprint", log)
 
1205
        self.assertEqual('', test._log_contents)
 
1206
        self.assertIs(None, test._log_file_name)
 
1207
 
 
1208
    def test_success_log_deleted(self):
 
1209
        """Successful tests have their log deleted"""
 
1210
 
 
1211
        class LogTester(tests.TestCase):
 
1212
 
 
1213
            def test_success(self):
 
1214
                self.log('this will be removed\n')
 
1215
 
 
1216
        sio = StringIO()
 
1217
        runner = tests.TextTestRunner(stream=sio)
 
1218
        test = LogTester('test_success')
 
1219
        result = self.run_test_runner(runner, test)
 
1220
 
 
1221
        self.assertLogDeleted(test)
 
1222
 
 
1223
    def test_skipped_log_deleted(self):
 
1224
        """Skipped tests have their log deleted"""
 
1225
 
 
1226
        class LogTester(tests.TestCase):
 
1227
 
 
1228
            def test_skipped(self):
 
1229
                self.log('this will be removed\n')
 
1230
                raise tests.TestSkipped()
 
1231
 
 
1232
        sio = StringIO()
 
1233
        runner = tests.TextTestRunner(stream=sio)
 
1234
        test = LogTester('test_skipped')
 
1235
        result = self.run_test_runner(runner, test)
 
1236
 
 
1237
        self.assertLogDeleted(test)
 
1238
 
 
1239
    def test_not_aplicable_log_deleted(self):
 
1240
        """Not applicable tests have their log deleted"""
 
1241
 
 
1242
        class LogTester(tests.TestCase):
 
1243
 
 
1244
            def test_not_applicable(self):
 
1245
                self.log('this will be removed\n')
 
1246
                raise tests.TestNotApplicable()
 
1247
 
 
1248
        sio = StringIO()
 
1249
        runner = tests.TextTestRunner(stream=sio)
 
1250
        test = LogTester('test_not_applicable')
 
1251
        result = self.run_test_runner(runner, test)
 
1252
 
 
1253
        self.assertLogDeleted(test)
 
1254
 
 
1255
    def test_known_failure_log_deleted(self):
 
1256
        """Know failure tests have their log deleted"""
 
1257
 
 
1258
        class LogTester(tests.TestCase):
 
1259
 
 
1260
            def test_known_failure(self):
 
1261
                self.log('this will be removed\n')
 
1262
                raise tests.KnownFailure()
 
1263
 
 
1264
        sio = StringIO()
 
1265
        runner = tests.TextTestRunner(stream=sio)
 
1266
        test = LogTester('test_known_failure')
 
1267
        result = self.run_test_runner(runner, test)
 
1268
 
 
1269
        self.assertLogDeleted(test)
 
1270
 
 
1271
    def test_fail_log_kept(self):
 
1272
        """Failed tests have their log kept"""
 
1273
 
 
1274
        class LogTester(tests.TestCase):
 
1275
 
 
1276
            def test_fail(self):
 
1277
                self.log('this will be kept\n')
 
1278
                self.fail('this test fails')
 
1279
 
 
1280
        sio = StringIO()
 
1281
        runner = tests.TextTestRunner(stream=sio)
 
1282
        test = LogTester('test_fail')
 
1283
        result = self.run_test_runner(runner, test)
 
1284
 
 
1285
        text = sio.getvalue()
 
1286
        self.assertContainsRe(text, 'this will be kept')
 
1287
        self.assertContainsRe(text, 'this test fails')
 
1288
 
 
1289
        log = test._get_log()
 
1290
        self.assertContainsRe(log, 'this will be kept')
 
1291
        self.assertEqual(log, test._log_contents)
 
1292
 
 
1293
    def test_error_log_kept(self):
 
1294
        """Tests with errors have their log kept"""
 
1295
 
 
1296
        class LogTester(tests.TestCase):
 
1297
 
 
1298
            def test_error(self):
 
1299
                self.log('this will be kept\n')
 
1300
                raise ValueError('random exception raised')
 
1301
 
 
1302
        sio = StringIO()
 
1303
        runner = tests.TextTestRunner(stream=sio)
 
1304
        test = LogTester('test_error')
 
1305
        result = self.run_test_runner(runner, test)
 
1306
 
 
1307
        text = sio.getvalue()
 
1308
        self.assertContainsRe(text, 'this will be kept')
 
1309
        self.assertContainsRe(text, 'random exception raised')
 
1310
 
 
1311
        log = test._get_log()
 
1312
        self.assertContainsRe(log, 'this will be kept')
 
1313
        self.assertEqual(log, test._log_contents)
 
1314
 
1227
1315
    def test_startTestRun(self):
1228
1316
        """run should call result.startTestRun()"""
1229
1317
        calls = []
1393
1481
        self.assertEqual(set(['original-state']), bzrlib.debug.debug_flags)
1394
1482
 
1395
1483
    def make_test_result(self):
1396
 
        """Get a test result that writes to the test log file."""
1397
1484
        return tests.TextTestResult(self._log_file, descriptions=0, verbosity=1)
1398
1485
 
1399
1486
    def inner_test(self):
1407
1494
        result = self.make_test_result()
1408
1495
        self.inner_test.run(result)
1409
1496
        note("outer finish")
1410
 
        self.addCleanup(osutils.delete_any, self._log_file_name)
1411
1497
 
1412
1498
    def test_trace_nesting(self):
1413
1499
        # this tests that each test case nests its trace facility correctly.
1425
1511
        outer_test = TestTestCase("outer_child")
1426
1512
        result = self.make_test_result()
1427
1513
        outer_test.run(result)
 
1514
        self.addCleanup(osutils.delete_any, outer_test._log_file_name)
1428
1515
        self.assertEqual(original_trace, bzrlib.trace._trace_file)
1429
1516
 
1430
1517
    def method_that_times_a_bit_twice(self):
1485
1572
        # Manually set one up (TestCase doesn't and shouldn't provide magic
1486
1573
        # machinery)
1487
1574
        transport_server = MemoryServer()
1488
 
        transport_server.start_server()
1489
 
        self.addCleanup(transport_server.stop_server)
 
1575
        transport_server.setUp()
 
1576
        self.addCleanup(transport_server.tearDown)
1490
1577
        t = transport.get_transport(transport_server.get_url())
1491
1578
        bzrdir.BzrDir.create(t.base)
1492
1579
        self.assertRaises(errors.BzrError,
1545
1632
        """Test disabled tests behaviour with support aware results."""
1546
1633
        test = SampleTestCase('_test_pass')
1547
1634
        class DisabledFeature(object):
1548
 
            def __eq__(self, other):
1549
 
                return isinstance(other, DisabledFeature)
1550
1635
            def available(self):
1551
1636
                return False
1552
1637
        the_feature = DisabledFeature()
1563
1648
                self.calls.append(('addNotSupported', test, feature))
1564
1649
        result = InstrumentedTestResult()
1565
1650
        test.run(result)
1566
 
        case = result.calls[0][1]
1567
1651
        self.assertEqual([
1568
 
            ('startTest', case),
1569
 
            ('addNotSupported', case, the_feature),
1570
 
            ('stopTest', case),
 
1652
            ('startTest', test),
 
1653
            ('addNotSupported', test, the_feature),
 
1654
            ('stopTest', test),
1571
1655
            ],
1572
1656
            result.calls)
1573
1657
 
1888
1972
        self.assertEqual(expected.getvalue(), repeated.getvalue())
1889
1973
 
1890
1974
    def test_runner_class(self):
1891
 
        self.requireFeature(features.subunit)
 
1975
        self.requireFeature(SubUnitFeature)
1892
1976
        from subunit import ProtocolTestCase
1893
1977
        stream = self.run_selftest(runner_class=tests.SubUnitBzrRunner,
1894
1978
            test_suite_factory=self.factory)
1926
2010
        self.assertEqual(transport_server, captured_transport[0])
1927
2011
 
1928
2012
    def test_transport_sftp(self):
1929
 
        self.requireFeature(features.paramiko)
 
2013
        try:
 
2014
            import bzrlib.transport.sftp
 
2015
        except errors.ParamikoNotPresent:
 
2016
            raise tests.TestSkipped("Paramiko not present")
1930
2017
        self.check_transport_set(bzrlib.transport.sftp.SFTPAbsoluteServer)
1931
2018
 
1932
2019
    def test_transport_memory(self):
2337
2424
        self.assertEqual('bzr: interrupted\n', result[1])
2338
2425
 
2339
2426
 
 
2427
class TestKnownFailure(tests.TestCase):
 
2428
 
 
2429
    def test_known_failure(self):
 
2430
        """Check that KnownFailure is defined appropriately."""
 
2431
        # a KnownFailure is an assertion error for compatability with unaware
 
2432
        # runners.
 
2433
        self.assertIsInstance(tests.KnownFailure(""), AssertionError)
 
2434
 
 
2435
    def test_expect_failure(self):
 
2436
        try:
 
2437
            self.expectFailure("Doomed to failure", self.assertTrue, False)
 
2438
        except tests.KnownFailure, e:
 
2439
            self.assertEqual('Doomed to failure', e.args[0])
 
2440
        try:
 
2441
            self.expectFailure("Doomed to failure", self.assertTrue, True)
 
2442
        except AssertionError, e:
 
2443
            self.assertEqual('Unexpected success.  Should have failed:'
 
2444
                             ' Doomed to failure', e.args[0])
 
2445
        else:
 
2446
            self.fail('Assertion not raised')
 
2447
 
 
2448
 
2340
2449
class TestFeature(tests.TestCase):
2341
2450
 
2342
2451
    def test_caching(self):
2378
2487
        self.assertIs(feature, exception.args[0])
2379
2488
 
2380
2489
 
2381
 
simple_thunk_feature = tests._CompatabilityThunkFeature(
2382
 
    'bzrlib.tests', 'UnicodeFilename',
2383
 
    'bzrlib.tests.test_selftest.simple_thunk_feature',
2384
 
    deprecated_in((2,1,0)))
2385
 
 
2386
 
class Test_CompatibilityFeature(tests.TestCase):
2387
 
 
2388
 
    def test_does_thunk(self):
2389
 
        res = self.callDeprecated(
2390
 
            ['bzrlib.tests.test_selftest.simple_thunk_feature was deprecated'
2391
 
             ' in version 2.1.0. Use bzrlib.tests.UnicodeFilename instead.'],
2392
 
            simple_thunk_feature.available)
2393
 
        self.assertEqual(tests.UnicodeFilename.available(), res)
2394
 
 
2395
 
        
2396
 
class TestModuleAvailableFeature(tests.TestCase):
2397
 
 
2398
 
    def test_available_module(self):
2399
 
        feature = tests.ModuleAvailableFeature('bzrlib.tests')
2400
 
        self.assertEqual('bzrlib.tests', feature.module_name)
2401
 
        self.assertEqual('bzrlib.tests', str(feature))
2402
 
        self.assertTrue(feature.available())
2403
 
        self.assertIs(tests, feature.module)
2404
 
 
2405
 
    def test_unavailable_module(self):
2406
 
        feature = tests.ModuleAvailableFeature('bzrlib.no_such_module_exists')
2407
 
        self.assertEqual('bzrlib.no_such_module_exists', str(feature))
2408
 
        self.assertFalse(feature.available())
2409
 
        self.assertIs(None, feature.module)
2410
 
 
2411
 
 
2412
2490
class TestSelftestFiltering(tests.TestCase):
2413
2491
 
2414
2492
    def setUp(self):
2593
2671
        # the test framework
2594
2672
        self.assertEquals('always fails', str(e))
2595
2673
        # check that there's no traceback in the test log
2596
 
        self.assertNotContainsRe(self.get_log(), r'Traceback')
 
2674
        self.assertNotContainsRe(self._get_log(keep_log_file=True),
 
2675
            r'Traceback')
2597
2676
 
2598
2677
    def test_run_bzr_user_error_caught(self):
2599
2678
        # Running bzr in blackbox mode, normal/expected/user errors should be
2600
2679
        # caught in the regular way and turned into an error message plus exit
2601
2680
        # code.
2602
2681
        transport_server = MemoryServer()
2603
 
        transport_server.start_server()
2604
 
        self.addCleanup(transport_server.stop_server)
 
2682
        transport_server.setUp()
 
2683
        self.addCleanup(transport_server.tearDown)
2605
2684
        url = transport_server.get_url()
2606
2685
        self.permit_url(url)
2607
2686
        out, err = self.run_bzr(["log", "%s/nonexistantpath" % url], retcode=3)
2852
2931
    def test_load_tests(self):
2853
2932
        test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
2854
2933
        loader = self._create_loader(test_list)
 
2934
 
2855
2935
        suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
2856
2936
        self.assertEquals(test_list, _test_ids(suite))
2857
2937
 
2858
2938
    def test_exclude_tests(self):
2859
2939
        test_list = ['bogus']
2860
2940
        loader = self._create_loader(test_list)
 
2941
 
2861
2942
        suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
2862
2943
        self.assertEquals([], _test_ids(suite))
2863
2944
 
2908
2989
        tpr.register('bar', 'bbb.aaa.rrr')
2909
2990
        tpr.register('bar', 'bBB.aAA.rRR')
2910
2991
        self.assertEquals('bbb.aaa.rrr', tpr.get('bar'))
2911
 
        self.assertThat(self.get_log(),
2912
 
            DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR", ELLIPSIS))
 
2992
        self.assertContainsRe(self._get_log(keep_log_file=True),
 
2993
                              r'.*bar.*bbb.aaa.rrr.*bBB.aAA.rRR')
2913
2994
 
2914
2995
    def test_get_unknown_prefix(self):
2915
2996
        tpr = self._get_registry()