~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

  • Committer: Vincent Ladeuil
  • Date: 2011-05-17 20:58:43 UTC
  • mfrom: (5609.39.5 2.3)
  • mto: This revision was merged to the branch mainline in revision 5885.
  • Revision ID: v.ladeuil+lp@free.fr-20110517205843-uo1tntrz6kqfn1hb
Merge 2.3 into trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#
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
17
17
"""Tests for the test framework."""
18
18
 
19
19
from cStringIO import StringIO
20
 
from doctest import ELLIPSIS
 
20
import doctest
21
21
import os
22
22
import signal
23
23
import sys
26
26
import unittest
27
27
import warnings
28
28
 
29
 
from testtools import MultiTestResult
 
29
from testtools import (
 
30
    ExtendedToOriginalDecorator,
 
31
    MultiTestResult,
 
32
    )
30
33
from testtools.content import Content
31
34
from testtools.content_type import ContentType
32
35
from testtools.matchers import (
39
42
from bzrlib import (
40
43
    branchbuilder,
41
44
    bzrdir,
42
 
    debug,
43
45
    errors,
44
46
    lockdir,
45
47
    memorytree,
50
52
    tests,
51
53
    transport,
52
54
    workingtree,
 
55
    workingtree_3,
 
56
    workingtree_4,
53
57
    )
54
58
from bzrlib.repofmt import (
55
59
    groupcompress_repo,
56
 
    pack_repo,
57
 
    weaverepo,
58
60
    )
59
61
from bzrlib.symbol_versioning import (
60
62
    deprecated_function,
65
67
    features,
66
68
    test_lsprof,
67
69
    test_server,
68
 
    test_sftp_transport,
69
70
    TestUtil,
70
71
    )
71
72
from bzrlib.trace import note, mutter
72
73
from bzrlib.transport import memory
73
 
from bzrlib.version import _get_bzr_source_tree
74
74
 
75
75
 
76
76
def _test_ids(test_suite):
78
78
    return [t.id() for t in tests.iter_suite_tests(test_suite)]
79
79
 
80
80
 
81
 
class SelftestTests(tests.TestCase):
82
 
 
83
 
    def test_import_tests(self):
84
 
        mod = TestUtil._load_module_by_name('bzrlib.tests.test_selftest')
85
 
        self.assertEqual(mod.SelftestTests, SelftestTests)
86
 
 
87
 
    def test_import_test_failure(self):
88
 
        self.assertRaises(ImportError,
89
 
                          TestUtil._load_module_by_name,
90
 
                          'bzrlib.no-name-yet')
91
 
 
92
 
 
93
81
class MetaTestLog(tests.TestCase):
94
82
 
95
83
    def test_logging(self):
101
89
            "text", "plain", {"charset": "utf8"})))
102
90
        self.assertThat(u"".join(log.iter_text()), Equals(self.get_log()))
103
91
        self.assertThat(self.get_log(),
104
 
            DocTestMatches(u"...a test message\n", ELLIPSIS))
 
92
            DocTestMatches(u"...a test message\n", doctest.ELLIPSIS))
105
93
 
106
94
 
107
95
class TestUnicodeFilename(tests.TestCase):
120
108
 
121
109
        filename = u'hell\u00d8'
122
110
        self.build_tree_contents([(filename, 'contents of hello')])
123
 
        self.failUnlessExists(filename)
 
111
        self.assertPathExists(filename)
124
112
 
125
113
 
126
114
class TestClassesAvailable(tests.TestCase):
352
340
        from bzrlib.tests.per_workingtree import make_scenarios
353
341
        server1 = "a"
354
342
        server2 = "b"
355
 
        formats = [workingtree.WorkingTreeFormat2(),
356
 
                   workingtree.WorkingTreeFormat3(),]
 
343
        formats = [workingtree_4.WorkingTreeFormat4(),
 
344
                   workingtree_3.WorkingTreeFormat3(),]
357
345
        scenarios = make_scenarios(server1, server2, formats)
358
346
        self.assertEqual([
359
 
            ('WorkingTreeFormat2',
 
347
            ('WorkingTreeFormat4',
360
348
             {'bzrdir_format': formats[0]._matchingbzrdir,
361
349
              'transport_readonly_server': 'b',
362
350
              'transport_server': 'a',
389
377
            )
390
378
        server1 = "a"
391
379
        server2 = "b"
392
 
        formats = [workingtree.WorkingTreeFormat2(),
393
 
                   workingtree.WorkingTreeFormat3(),]
 
380
        formats = [workingtree_4.WorkingTreeFormat4(),
 
381
                   workingtree_3.WorkingTreeFormat3(),]
394
382
        scenarios = make_scenarios(server1, server2, formats)
395
383
        self.assertEqual(7, len(scenarios))
396
 
        default_wt_format = workingtree.WorkingTreeFormat4._default_format
397
 
        wt4_format = workingtree.WorkingTreeFormat4()
398
 
        wt5_format = workingtree.WorkingTreeFormat5()
 
384
        default_wt_format = workingtree.format_registry.get_default()
 
385
        wt4_format = workingtree_4.WorkingTreeFormat4()
 
386
        wt5_format = workingtree_4.WorkingTreeFormat5()
399
387
        expected_scenarios = [
400
 
            ('WorkingTreeFormat2',
 
388
            ('WorkingTreeFormat4',
401
389
             {'bzrdir_format': formats[0]._matchingbzrdir,
402
390
              'transport_readonly_server': 'b',
403
391
              'transport_server': 'a',
463
451
        # ones to add.
464
452
        from bzrlib.tests.per_tree import (
465
453
            return_parameter,
466
 
            revision_tree_from_workingtree
467
454
            )
468
455
        from bzrlib.tests.per_intertree import (
469
456
            make_scenarios,
470
457
            )
471
 
        from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
 
458
        from bzrlib.workingtree_3 import WorkingTreeFormat3
 
459
        from bzrlib.workingtree_4 import WorkingTreeFormat4
472
460
        input_test = TestInterTreeScenarios(
473
461
            "test_scenarios")
474
462
        server1 = "a"
475
463
        server2 = "b"
476
 
        format1 = WorkingTreeFormat2()
 
464
        format1 = WorkingTreeFormat4()
477
465
        format2 = WorkingTreeFormat3()
478
466
        formats = [("1", str, format1, format2, "converter1"),
479
467
            ("2", int, format2, format1, "converter2")]
525
513
        self.assertRaises(AssertionError, self.assertEqualStat,
526
514
            os.lstat("foo"), os.lstat("longname"))
527
515
 
 
516
    def test_failUnlessExists(self):
 
517
        """Deprecated failUnlessExists and failIfExists"""
 
518
        self.applyDeprecated(
 
519
            deprecated_in((2, 4)),
 
520
            self.failUnlessExists, '.')
 
521
        self.build_tree(['foo/', 'foo/bar'])
 
522
        self.applyDeprecated(
 
523
            deprecated_in((2, 4)),
 
524
            self.failUnlessExists, 'foo/bar')
 
525
        self.applyDeprecated(
 
526
            deprecated_in((2, 4)),
 
527
            self.failIfExists, 'foo/foo')
 
528
 
 
529
    def test_assertPathExists(self):
 
530
        self.assertPathExists('.')
 
531
        self.build_tree(['foo/', 'foo/bar'])
 
532
        self.assertPathExists('foo/bar')
 
533
        self.assertPathDoesNotExist('foo/foo')
 
534
 
528
535
 
529
536
class TestTestCaseWithMemoryTransport(tests.TestCaseWithMemoryTransport):
530
537
 
564
571
        tree = self.make_branch_and_memory_tree('dir')
565
572
        # Guard against regression into MemoryTransport leaking
566
573
        # files to disk instead of keeping them in memory.
567
 
        self.failIf(osutils.lexists('dir'))
 
574
        self.assertFalse(osutils.lexists('dir'))
568
575
        self.assertIsInstance(tree, memorytree.MemoryTree)
569
576
 
570
577
    def test_make_branch_and_memory_tree_with_format(self):
571
578
        """make_branch_and_memory_tree should accept a format option."""
572
579
        format = bzrdir.BzrDirMetaFormat1()
573
 
        format.repository_format = weaverepo.RepositoryFormat7()
 
580
        format.repository_format = repository.format_registry.get_default()
574
581
        tree = self.make_branch_and_memory_tree('dir', format=format)
575
582
        # Guard against regression into MemoryTransport leaking
576
583
        # files to disk instead of keeping them in memory.
577
 
        self.failIf(osutils.lexists('dir'))
 
584
        self.assertFalse(osutils.lexists('dir'))
578
585
        self.assertIsInstance(tree, memorytree.MemoryTree)
579
586
        self.assertEqual(format.repository_format.__class__,
580
587
            tree.branch.repository._format.__class__)
584
591
        self.assertIsInstance(builder, branchbuilder.BranchBuilder)
585
592
        # Guard against regression into MemoryTransport leaking
586
593
        # files to disk instead of keeping them in memory.
587
 
        self.failIf(osutils.lexists('dir'))
 
594
        self.assertFalse(osutils.lexists('dir'))
588
595
 
589
596
    def test_make_branch_builder_with_format(self):
590
597
        # Use a repo layout that doesn't conform to a 'named' layout, to ensure
591
598
        # that the format objects are used.
592
599
        format = bzrdir.BzrDirMetaFormat1()
593
 
        repo_format = weaverepo.RepositoryFormat7()
 
600
        repo_format = repository.format_registry.get_default()
594
601
        format.repository_format = repo_format
595
602
        builder = self.make_branch_builder('dir', format=format)
596
603
        the_branch = builder.get_branch()
597
604
        # Guard against regression into MemoryTransport leaking
598
605
        # files to disk instead of keeping them in memory.
599
 
        self.failIf(osutils.lexists('dir'))
 
606
        self.assertFalse(osutils.lexists('dir'))
600
607
        self.assertEqual(format.repository_format.__class__,
601
608
                         the_branch.repository._format.__class__)
602
609
        self.assertEqual(repo_format.get_format_string(),
608
615
        the_branch = builder.get_branch()
609
616
        # Guard against regression into MemoryTransport leaking
610
617
        # files to disk instead of keeping them in memory.
611
 
        self.failIf(osutils.lexists('dir'))
 
618
        self.assertFalse(osutils.lexists('dir'))
612
619
        dir_format = bzrdir.format_registry.make_bzrdir('knit')
613
620
        self.assertEqual(dir_format.repository_format.__class__,
614
621
                         the_branch.repository._format.__class__)
647
654
        url2 = self.get_readonly_url('foo/bar')
648
655
        t = transport.get_transport(url)
649
656
        t2 = transport.get_transport(url2)
650
 
        self.failUnless(isinstance(t, ReadonlyTransportDecorator))
651
 
        self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
 
657
        self.assertIsInstance(t, ReadonlyTransportDecorator)
 
658
        self.assertIsInstance(t2, ReadonlyTransportDecorator)
652
659
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
653
660
 
654
661
    def test_get_readonly_url_http(self):
662
669
        # the transport returned may be any HttpTransportBase subclass
663
670
        t = transport.get_transport(url)
664
671
        t2 = transport.get_transport(url2)
665
 
        self.failUnless(isinstance(t, HttpTransportBase))
666
 
        self.failUnless(isinstance(t2, HttpTransportBase))
 
672
        self.assertIsInstance(t, HttpTransportBase)
 
673
        self.assertIsInstance(t2, HttpTransportBase)
667
674
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
668
675
 
669
676
    def test_is_directory(self):
677
684
    def test_make_branch_builder(self):
678
685
        builder = self.make_branch_builder('dir')
679
686
        rev_id = builder.build_commit()
680
 
        self.failUnlessExists('dir')
 
687
        self.assertPathExists('dir')
681
688
        a_dir = bzrdir.BzrDir.open('dir')
682
689
        self.assertRaises(errors.NoWorkingTree, a_dir.open_workingtree)
683
690
        a_branch = a_dir.open_branch()
699
706
        self.assertIsInstance(result_bzrdir.transport,
700
707
                              memory.MemoryTransport)
701
708
        # should not be on disk, should only be in memory
702
 
        self.failIfExists('subdir')
 
709
        self.assertPathDoesNotExist('subdir')
703
710
 
704
711
 
705
712
class TestChrootedTest(tests.ChrootedTestCase):
764
771
        self.check_timing(ShortDelayTestCase('test_short_delay'),
765
772
                          r"^ +[0-9]+ms$")
766
773
 
767
 
    def _patch_get_bzr_source_tree(self):
768
 
        # Reading from the actual source tree breaks isolation, but we don't
769
 
        # want to assume that thats *all* that would happen.
770
 
        self.overrideAttr(bzrlib.version, '_get_bzr_source_tree', lambda: None)
771
 
 
772
 
    def test_assigned_benchmark_file_stores_date(self):
773
 
        self._patch_get_bzr_source_tree()
774
 
        output = StringIO()
775
 
        result = bzrlib.tests.TextTestResult(self._log_file,
776
 
                                        descriptions=0,
777
 
                                        verbosity=1,
778
 
                                        bench_history=output
779
 
                                        )
780
 
        output_string = output.getvalue()
781
 
        # if you are wondering about the regexp please read the comment in
782
 
        # test_bench_history (bzrlib.tests.test_selftest.TestRunner)
783
 
        # XXX: what comment?  -- Andrew Bennetts
784
 
        self.assertContainsRe(output_string, "--date [0-9.]+")
785
 
 
786
 
    def test_benchhistory_records_test_times(self):
787
 
        self._patch_get_bzr_source_tree()
788
 
        result_stream = StringIO()
789
 
        result = bzrlib.tests.TextTestResult(
790
 
            self._log_file,
791
 
            descriptions=0,
792
 
            verbosity=1,
793
 
            bench_history=result_stream
794
 
            )
795
 
 
796
 
        # we want profile a call and check that its test duration is recorded
797
 
        # make a new test instance that when run will generate a benchmark
798
 
        example_test_case = TestTestResult("_time_hello_world_encoding")
799
 
        # execute the test, which should succeed and record times
800
 
        example_test_case.run(result)
801
 
        lines = result_stream.getvalue().splitlines()
802
 
        self.assertEqual(2, len(lines))
803
 
        self.assertContainsRe(lines[1],
804
 
            " *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
805
 
            "._time_hello_world_encoding")
806
 
 
807
774
    def _time_hello_world_encoding(self):
808
775
        """Profile two sleep calls
809
776
 
849
816
        self.assertContainsRe(output,
850
817
            r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
851
818
 
 
819
    def test_uses_time_from_testtools(self):
 
820
        """Test case timings in verbose results should use testtools times"""
 
821
        import datetime
 
822
        class TimeAddedVerboseTestResult(tests.VerboseTestResult):
 
823
            def startTest(self, test):
 
824
                self.time(datetime.datetime.utcfromtimestamp(1.145))
 
825
                super(TimeAddedVerboseTestResult, self).startTest(test)
 
826
            def addSuccess(self, test):
 
827
                self.time(datetime.datetime.utcfromtimestamp(51.147))
 
828
                super(TimeAddedVerboseTestResult, self).addSuccess(test)
 
829
            def report_tests_starting(self): pass
 
830
        sio = StringIO()
 
831
        self.get_passing_test().run(TimeAddedVerboseTestResult(sio, 0, 2))
 
832
        self.assertEndsWith(sio.getvalue(), "OK    50002ms\n")
 
833
 
852
834
    def test_known_failure(self):
853
835
        """A KnownFailure being raised should trigger several result actions."""
854
836
        class InstrumentedTestResult(tests.ExtendedTestResult):
1104
1086
    def test_result_decorator(self):
1105
1087
        # decorate results
1106
1088
        calls = []
1107
 
        class LoggingDecorator(tests.ForwardingResult):
 
1089
        class LoggingDecorator(ExtendedToOriginalDecorator):
1108
1090
            def startTest(self, test):
1109
 
                tests.ForwardingResult.startTest(self, test)
 
1091
                ExtendedToOriginalDecorator.startTest(self, test)
1110
1092
                calls.append('start')
1111
1093
        test = unittest.FunctionTestCase(lambda:None)
1112
1094
        stream = StringIO()
1213
1195
            ],
1214
1196
            lines[-3:])
1215
1197
 
1216
 
    def _patch_get_bzr_source_tree(self):
1217
 
        # Reading from the actual source tree breaks isolation, but we don't
1218
 
        # want to assume that thats *all* that would happen.
1219
 
        self._get_source_tree_calls = []
1220
 
        def new_get():
1221
 
            self._get_source_tree_calls.append("called")
1222
 
            return None
1223
 
        self.overrideAttr(bzrlib.version, '_get_bzr_source_tree',  new_get)
1224
 
 
1225
 
    def test_bench_history(self):
1226
 
        # tests that the running the benchmark passes bench_history into
1227
 
        # the test result object. We can tell that happens if
1228
 
        # _get_bzr_source_tree is called.
1229
 
        self._patch_get_bzr_source_tree()
1230
 
        test = TestRunner('dummy_test')
1231
 
        output = StringIO()
1232
 
        runner = tests.TextTestRunner(stream=self._log_file,
1233
 
                                      bench_history=output)
1234
 
        result = self.run_test_runner(runner, test)
1235
 
        output_string = output.getvalue()
1236
 
        self.assertContainsRe(output_string, "--date [0-9.]+")
1237
 
        self.assertLength(1, self._get_source_tree_calls)
1238
 
 
1239
1198
    def test_verbose_test_count(self):
1240
1199
        """A verbose test run reports the right test count at the start"""
1241
1200
        suite = TestUtil.TestSuite([
1251
1210
    def test_startTestRun(self):
1252
1211
        """run should call result.startTestRun()"""
1253
1212
        calls = []
1254
 
        class LoggingDecorator(tests.ForwardingResult):
 
1213
        class LoggingDecorator(ExtendedToOriginalDecorator):
1255
1214
            def startTestRun(self):
1256
 
                tests.ForwardingResult.startTestRun(self)
 
1215
                ExtendedToOriginalDecorator.startTestRun(self)
1257
1216
                calls.append('startTestRun')
1258
1217
        test = unittest.FunctionTestCase(lambda:None)
1259
1218
        stream = StringIO()
1265
1224
    def test_stopTestRun(self):
1266
1225
        """run should call result.stopTestRun()"""
1267
1226
        calls = []
1268
 
        class LoggingDecorator(tests.ForwardingResult):
 
1227
        class LoggingDecorator(ExtendedToOriginalDecorator):
1269
1228
            def stopTestRun(self):
1270
 
                tests.ForwardingResult.stopTestRun(self)
 
1229
                ExtendedToOriginalDecorator.stopTestRun(self)
1271
1230
                calls.append('stopTestRun')
1272
1231
        test = unittest.FunctionTestCase(lambda:None)
1273
1232
        stream = StringIO()
1276
1235
        result = self.run_test_runner(runner, test)
1277
1236
        self.assertLength(1, calls)
1278
1237
 
 
1238
    def test_unicode_test_output_on_ascii_stream(self):
 
1239
        """Showing results should always succeed even on an ascii console"""
 
1240
        class FailureWithUnicode(tests.TestCase):
 
1241
            def test_log_unicode(self):
 
1242
                self.log(u"\u2606")
 
1243
                self.fail("Now print that log!")
 
1244
        out = StringIO()
 
1245
        self.overrideAttr(osutils, "get_terminal_encoding",
 
1246
            lambda trace=False: "ascii")
 
1247
        result = self.run_test_runner(tests.TextTestRunner(stream=out),
 
1248
            FailureWithUnicode("test_log_unicode"))
 
1249
        self.assertContainsRe(out.getvalue(),
 
1250
            "Text attachment: log\n"
 
1251
            "-+\n"
 
1252
            "\d+\.\d+  \\\\u2606\n"
 
1253
            "-+\n")
 
1254
 
1279
1255
 
1280
1256
class SampleTestCase(tests.TestCase):
1281
1257
 
1469
1445
        # Note this test won't fail with hooks that the core library doesn't
1470
1446
        # use - but it trigger with a plugin that adds hooks, so its still a
1471
1447
        # useful warning in that case.
1472
 
        self.assertEqual(bzrlib.branch.BranchHooks(),
1473
 
            bzrlib.branch.Branch.hooks)
1474
 
        self.assertEqual(bzrlib.smart.server.SmartServerHooks(),
 
1448
        self.assertEqual(bzrlib.branch.BranchHooks(), bzrlib.branch.Branch.hooks)
 
1449
        self.assertEqual(
 
1450
            bzrlib.smart.server.SmartServerHooks(),
1475
1451
            bzrlib.smart.server.SmartTCPServer.hooks)
1476
 
        self.assertEqual(bzrlib.commands.CommandHooks(),
1477
 
            bzrlib.commands.Command.hooks)
 
1452
        self.assertEqual(
 
1453
            bzrlib.commands.CommandHooks(), bzrlib.commands.Command.hooks)
1478
1454
 
1479
1455
    def test__gather_lsprof_in_benchmarks(self):
1480
1456
        """When _gather_lsprof_in_benchmarks is on, accumulate profile data.
1958
1934
    def test_make_branch_and_tree_with_format(self):
1959
1935
        # we should be able to supply a format to make_branch_and_tree
1960
1936
        self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
1961
 
        self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
1962
1937
        self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
1963
1938
                              bzrlib.bzrdir.BzrDirMetaFormat1)
1964
 
        self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
1965
 
                              bzrlib.bzrdir.BzrDirFormat6)
1966
1939
 
1967
1940
    def test_make_branch_and_memory_tree(self):
1968
1941
        # we should be able to get a new branch and a mutable tree from
2051
2024
            def __call__(test, result):
2052
2025
                test.run(result)
2053
2026
            def run(test, result):
2054
 
                self.assertIsInstance(result, tests.ForwardingResult)
 
2027
                self.assertIsInstance(result, ExtendedToOriginalDecorator)
2055
2028
                calls.append("called")
2056
2029
            def countTestCases(self):
2057
2030
                return 1
2347
2320
        # stdout and stderr of the invoked run_bzr
2348
2321
        current_factory = bzrlib.ui.ui_factory
2349
2322
        self.run_bzr(['foo'])
2350
 
        self.failIf(current_factory is self.factory)
 
2323
        self.assertFalse(current_factory is self.factory)
2351
2324
        self.assertNotEqual(sys.stdout, self.factory.stdout)
2352
2325
        self.assertNotEqual(sys.stderr, self.factory.stderr)
2353
2326
        self.assertEqual('foo\n', self.factory.stdout.getvalue())
2535
2508
        self.assertEqual([], command[2:])
2536
2509
 
2537
2510
    def test_set_env(self):
2538
 
        self.failIf('EXISTANT_ENV_VAR' in os.environ)
 
2511
        self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2539
2512
        # set in the child
2540
2513
        def check_environment():
2541
2514
            self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2547
2520
 
2548
2521
    def test_run_bzr_subprocess_env_del(self):
2549
2522
        """run_bzr_subprocess can remove environment variables too."""
2550
 
        self.failIf('EXISTANT_ENV_VAR' in os.environ)
 
2523
        self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2551
2524
        def check_environment():
2552
2525
            self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2553
2526
        os.environ['EXISTANT_ENV_VAR'] = 'set variable'
2559
2532
        del os.environ['EXISTANT_ENV_VAR']
2560
2533
 
2561
2534
    def test_env_del_missing(self):
2562
 
        self.failIf('NON_EXISTANT_ENV_VAR' in os.environ)
 
2535
        self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
2563
2536
        def check_environment():
2564
2537
            self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
2565
2538
        self.check_popen_state = check_environment
2840
2813
        self.assertEqual(remaining_names, _test_ids(split_suite[1]))
2841
2814
 
2842
2815
 
2843
 
class TestCheckInventoryShape(tests.TestCaseWithTransport):
 
2816
class TestCheckTreeShape(tests.TestCaseWithTransport):
2844
2817
 
2845
 
    def test_check_inventory_shape(self):
 
2818
    def test_check_tree_shape(self):
2846
2819
        files = ['a', 'b/', 'b/c']
2847
2820
        tree = self.make_branch_and_tree('.')
2848
2821
        self.build_tree(files)
2849
2822
        tree.add(files)
2850
2823
        tree.lock_read()
2851
2824
        try:
2852
 
            self.check_inventory_shape(tree.inventory, files)
 
2825
            self.check_tree_shape(tree, files)
2853
2826
        finally:
2854
2827
            tree.unlock()
2855
2828
 
3187
3160
        tpr.register('bar', 'bBB.aAA.rRR')
3188
3161
        self.assertEquals('bbb.aaa.rrr', tpr.get('bar'))
3189
3162
        self.assertThat(self.get_log(),
3190
 
            DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR", ELLIPSIS))
 
3163
            DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR",
 
3164
                           doctest.ELLIPSIS))
3191
3165
 
3192
3166
    def test_get_unknown_prefix(self):
3193
3167
        tpr = self._get_registry()
3228
3202
        class Test(unittest.TestCase):
3229
3203
            def runTest(self):
3230
3204
                pass
3231
 
            addCleanup = None # for when on Python 2.7 with native addCleanup
3232
3205
        result = self.LeakRecordingResult()
3233
3206
        test = Test()
3234
 
        self.assertIs(getattr(test, "addCleanup", None), None)
3235
3207
        result.startTestRun()
3236
3208
        test.run(result)
3237
3209
        result.stopTestRun()
3301
3273
        self.assertContainsString(result.stream.getvalue(), "leaking threads")
3302
3274
 
3303
3275
 
 
3276
class TestPostMortemDebugging(tests.TestCase):
 
3277
    """Check post mortem debugging works when tests fail or error"""
 
3278
 
 
3279
    class TracebackRecordingResult(tests.ExtendedTestResult):
 
3280
        def __init__(self):
 
3281
            tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
 
3282
            self.postcode = None
 
3283
        def _post_mortem(self, tb=None):
 
3284
            """Record the code object at the end of the current traceback"""
 
3285
            tb = tb or sys.exc_info()[2]
 
3286
            if tb is not None:
 
3287
                next = tb.tb_next
 
3288
                while next is not None:
 
3289
                    tb = next
 
3290
                    next = next.tb_next
 
3291
                self.postcode = tb.tb_frame.f_code
 
3292
        def report_error(self, test, err):
 
3293
            pass
 
3294
        def report_failure(self, test, err):
 
3295
            pass
 
3296
 
 
3297
    def test_location_unittest_error(self):
 
3298
        """Needs right post mortem traceback with erroring unittest case"""
 
3299
        class Test(unittest.TestCase):
 
3300
            def runTest(self):
 
3301
                raise RuntimeError
 
3302
        result = self.TracebackRecordingResult()
 
3303
        Test().run(result)
 
3304
        self.assertEqual(result.postcode, Test.runTest.func_code)
 
3305
 
 
3306
    def test_location_unittest_failure(self):
 
3307
        """Needs right post mortem traceback with failing unittest case"""
 
3308
        class Test(unittest.TestCase):
 
3309
            def runTest(self):
 
3310
                raise self.failureException
 
3311
        result = self.TracebackRecordingResult()
 
3312
        Test().run(result)
 
3313
        self.assertEqual(result.postcode, Test.runTest.func_code)
 
3314
 
 
3315
    def test_location_bt_error(self):
 
3316
        """Needs right post mortem traceback with erroring bzrlib.tests case"""
 
3317
        class Test(tests.TestCase):
 
3318
            def test_error(self):
 
3319
                raise RuntimeError
 
3320
        result = self.TracebackRecordingResult()
 
3321
        Test("test_error").run(result)
 
3322
        self.assertEqual(result.postcode, Test.test_error.func_code)
 
3323
 
 
3324
    def test_location_bt_failure(self):
 
3325
        """Needs right post mortem traceback with failing bzrlib.tests case"""
 
3326
        class Test(tests.TestCase):
 
3327
            def test_failure(self):
 
3328
                raise self.failureException
 
3329
        result = self.TracebackRecordingResult()
 
3330
        Test("test_failure").run(result)
 
3331
        self.assertEqual(result.postcode, Test.test_failure.func_code)
 
3332
 
 
3333
    def test_env_var_triggers_post_mortem(self):
 
3334
        """Check pdb.post_mortem is called iff BZR_TEST_PDB is set"""
 
3335
        import pdb
 
3336
        result = tests.ExtendedTestResult(StringIO(), 0, 1)
 
3337
        post_mortem_calls = []
 
3338
        self.overrideAttr(pdb, "post_mortem", post_mortem_calls.append)
 
3339
        self.overrideEnv('BZR_TEST_PDB', None)
 
3340
        result._post_mortem(1)
 
3341
        self.overrideEnv('BZR_TEST_PDB', 'on')
 
3342
        result._post_mortem(2)
 
3343
        self.assertEqual([2], post_mortem_calls)
 
3344
 
 
3345
 
3304
3346
class TestRunSuite(tests.TestCase):
3305
3347
 
3306
3348
    def test_runner_class(self):
3317
3359
                                                self.verbosity)
3318
3360
        tests.run_suite(suite, runner_class=MyRunner, stream=StringIO())
3319
3361
        self.assertLength(1, calls)
 
3362
 
 
3363
 
 
3364
class TestEnvironHandling(tests.TestCase):
 
3365
 
 
3366
    def test_overrideEnv_None_called_twice_doesnt_leak(self):
 
3367
        self.assertFalse('MYVAR' in os.environ)
 
3368
        self.overrideEnv('MYVAR', '42')
 
3369
        # We use an embedded test to make sure we fix the _captureVar bug
 
3370
        class Test(tests.TestCase):
 
3371
            def test_me(self):
 
3372
                # The first call save the 42 value
 
3373
                self.overrideEnv('MYVAR', None)
 
3374
                self.assertEquals(None, os.environ.get('MYVAR'))
 
3375
                # Make sure we can call it twice
 
3376
                self.overrideEnv('MYVAR', None)
 
3377
                self.assertEquals(None, os.environ.get('MYVAR'))
 
3378
        output = StringIO()
 
3379
        result = tests.TextTestResult(output, 0, 1)
 
3380
        Test('test_me').run(result)
 
3381
        if not result.wasStrictlySuccessful():
 
3382
            self.fail(output.getvalue())
 
3383
        # We get our value back
 
3384
        self.assertEquals('42', os.environ.get('MYVAR'))
 
3385
 
 
3386
 
 
3387
class TestIsolatedEnv(tests.TestCase):
 
3388
    """Test isolating tests from os.environ.
 
3389
 
 
3390
    Since we use tests that are already isolated from os.environ a bit of care
 
3391
    should be taken when designing the tests to avoid bootstrap side-effects.
 
3392
    The tests start an already clean os.environ which allow doing valid
 
3393
    assertions about which variables are present or not and design tests around
 
3394
    these assertions.
 
3395
    """
 
3396
 
 
3397
    class ScratchMonkey(tests.TestCase):
 
3398
 
 
3399
        def test_me(self):
 
3400
            pass
 
3401
 
 
3402
    def test_basics(self):
 
3403
        # Make sure we know the definition of BZR_HOME: not part of os.environ
 
3404
        # for tests.TestCase.
 
3405
        self.assertTrue('BZR_HOME' in tests.isolated_environ)
 
3406
        self.assertEquals(None, tests.isolated_environ['BZR_HOME'])
 
3407
        # Being part of isolated_environ, BZR_HOME should not appear here
 
3408
        self.assertFalse('BZR_HOME' in os.environ)
 
3409
        # Make sure we know the definition of LINES: part of os.environ for
 
3410
        # tests.TestCase
 
3411
        self.assertTrue('LINES' in tests.isolated_environ)
 
3412
        self.assertEquals('25', tests.isolated_environ['LINES'])
 
3413
        self.assertEquals('25', os.environ['LINES'])
 
3414
 
 
3415
    def test_injecting_unknown_variable(self):
 
3416
        # BZR_HOME is known to be absent from os.environ
 
3417
        test = self.ScratchMonkey('test_me')
 
3418
        tests.override_os_environ(test, {'BZR_HOME': 'foo'})
 
3419
        self.assertEquals('foo', os.environ['BZR_HOME'])
 
3420
        tests.restore_os_environ(test)
 
3421
        self.assertFalse('BZR_HOME' in os.environ)
 
3422
 
 
3423
    def test_injecting_known_variable(self):
 
3424
        test = self.ScratchMonkey('test_me')
 
3425
        # LINES is known to be present in os.environ
 
3426
        tests.override_os_environ(test, {'LINES': '42'})
 
3427
        self.assertEquals('42', os.environ['LINES'])
 
3428
        tests.restore_os_environ(test)
 
3429
        self.assertEquals('25', os.environ['LINES'])
 
3430
 
 
3431
    def test_deleting_variable(self):
 
3432
        test = self.ScratchMonkey('test_me')
 
3433
        # LINES is known to be present in os.environ
 
3434
        tests.override_os_environ(test, {'LINES': None})
 
3435
        self.assertTrue('LINES' not in os.environ)
 
3436
        tests.restore_os_environ(test)
 
3437
        self.assertEquals('25', os.environ['LINES'])
 
3438
 
 
3439
 
 
3440
class TestDocTestSuiteIsolation(tests.TestCase):
 
3441
    """Test that `tests.DocTestSuite` isolates doc tests from os.environ.
 
3442
 
 
3443
    Since tests.TestCase alreay provides an isolation from os.environ, we use
 
3444
    the clean environment as a base for testing. To precisely capture the
 
3445
    isolation provided by tests.DocTestSuite, we use doctest.DocTestSuite to
 
3446
    compare against.
 
3447
 
 
3448
    We want to make sure `tests.DocTestSuite` respect `tests.isolated_environ`,
 
3449
    not `os.environ` so each test overrides it to suit its needs.
 
3450
 
 
3451
    """
 
3452
 
 
3453
    def get_doctest_suite_for_string(self, klass, string):
 
3454
        class Finder(doctest.DocTestFinder):
 
3455
 
 
3456
            def find(*args, **kwargs):
 
3457
                test = doctest.DocTestParser().get_doctest(
 
3458
                    string, {}, 'foo', 'foo.py', 0)
 
3459
                return [test]
 
3460
 
 
3461
        suite = klass(test_finder=Finder())
 
3462
        return suite
 
3463
 
 
3464
    def run_doctest_suite_for_string(self, klass, string):
 
3465
        suite = self.get_doctest_suite_for_string(klass, string)
 
3466
        output = StringIO()
 
3467
        result = tests.TextTestResult(output, 0, 1)
 
3468
        suite.run(result)
 
3469
        return result, output
 
3470
 
 
3471
    def assertDocTestStringSucceds(self, klass, string):
 
3472
        result, output = self.run_doctest_suite_for_string(klass, string)
 
3473
        if not result.wasStrictlySuccessful():
 
3474
            self.fail(output.getvalue())
 
3475
 
 
3476
    def assertDocTestStringFails(self, klass, string):
 
3477
        result, output = self.run_doctest_suite_for_string(klass, string)
 
3478
        if result.wasStrictlySuccessful():
 
3479
            self.fail(output.getvalue())
 
3480
 
 
3481
    def test_injected_variable(self):
 
3482
        self.overrideAttr(tests, 'isolated_environ', {'LINES': '42'})
 
3483
        test = """
 
3484
            >>> import os
 
3485
            >>> os.environ['LINES']
 
3486
            '42'
 
3487
            """
 
3488
        # doctest.DocTestSuite fails as it sees '25'
 
3489
        self.assertDocTestStringFails(doctest.DocTestSuite, test)
 
3490
        # tests.DocTestSuite sees '42'
 
3491
        self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
 
3492
 
 
3493
    def test_deleted_variable(self):
 
3494
        self.overrideAttr(tests, 'isolated_environ', {'LINES': None})
 
3495
        test = """
 
3496
            >>> import os
 
3497
            >>> os.environ.get('LINES')
 
3498
            """
 
3499
        # doctest.DocTestSuite fails as it sees '25'
 
3500
        self.assertDocTestStringFails(doctest.DocTestSuite, test)
 
3501
        # tests.DocTestSuite sees None
 
3502
        self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)