~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

  • Committer: Matthew Gordon
  • Date: 2010-09-29 01:57:02 UTC
  • mto: (5487.1.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 5488.
  • Revision ID: mgordon@ivs3d.com-20100929015702-16w9ejt21oysws45
Tested push --no-tree ang gor it working right.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd
 
1
# Copyright (C) 2005-2010 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
 
import doctest
 
20
from doctest import ELLIPSIS
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 (
30
 
    ExtendedToOriginalDecorator,
31
 
    MultiTestResult,
32
 
    )
 
29
from testtools import MultiTestResult
33
30
from testtools.content import Content
34
31
from testtools.content_type import ContentType
35
32
from testtools.matchers import (
42
39
from bzrlib import (
43
40
    branchbuilder,
44
41
    bzrdir,
 
42
    debug,
45
43
    errors,
46
44
    lockdir,
47
45
    memorytree,
52
50
    tests,
53
51
    transport,
54
52
    workingtree,
55
 
    workingtree_3,
56
 
    workingtree_4,
57
53
    )
58
54
from bzrlib.repofmt import (
59
55
    groupcompress_repo,
 
56
    pack_repo,
 
57
    weaverepo,
60
58
    )
61
59
from bzrlib.symbol_versioning import (
62
60
    deprecated_function,
67
65
    features,
68
66
    test_lsprof,
69
67
    test_server,
 
68
    test_sftp_transport,
70
69
    TestUtil,
71
70
    )
72
71
from bzrlib.trace import note, mutter
73
72
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
 
81
93
class MetaTestLog(tests.TestCase):
82
94
 
83
95
    def test_logging(self):
89
101
            "text", "plain", {"charset": "utf8"})))
90
102
        self.assertThat(u"".join(log.iter_text()), Equals(self.get_log()))
91
103
        self.assertThat(self.get_log(),
92
 
            DocTestMatches(u"...a test message\n", doctest.ELLIPSIS))
 
104
            DocTestMatches(u"...a test message\n", ELLIPSIS))
93
105
 
94
106
 
95
107
class TestUnicodeFilename(tests.TestCase):
108
120
 
109
121
        filename = u'hell\u00d8'
110
122
        self.build_tree_contents([(filename, 'contents of hello')])
111
 
        self.assertPathExists(filename)
 
123
        self.failUnlessExists(filename)
112
124
 
113
125
 
114
126
class TestClassesAvailable(tests.TestCase):
340
352
        from bzrlib.tests.per_workingtree import make_scenarios
341
353
        server1 = "a"
342
354
        server2 = "b"
343
 
        formats = [workingtree_4.WorkingTreeFormat4(),
344
 
                   workingtree_3.WorkingTreeFormat3(),]
 
355
        formats = [workingtree.WorkingTreeFormat2(),
 
356
                   workingtree.WorkingTreeFormat3(),]
345
357
        scenarios = make_scenarios(server1, server2, formats)
346
358
        self.assertEqual([
347
 
            ('WorkingTreeFormat4',
 
359
            ('WorkingTreeFormat2',
348
360
             {'bzrdir_format': formats[0]._matchingbzrdir,
349
361
              'transport_readonly_server': 'b',
350
362
              'transport_server': 'a',
377
389
            )
378
390
        server1 = "a"
379
391
        server2 = "b"
380
 
        formats = [workingtree_4.WorkingTreeFormat4(),
381
 
                   workingtree_3.WorkingTreeFormat3(),]
 
392
        formats = [workingtree.WorkingTreeFormat2(),
 
393
                   workingtree.WorkingTreeFormat3(),]
382
394
        scenarios = make_scenarios(server1, server2, formats)
383
395
        self.assertEqual(7, len(scenarios))
384
 
        default_wt_format = workingtree.format_registry.get_default()
385
 
        wt4_format = workingtree_4.WorkingTreeFormat4()
386
 
        wt5_format = workingtree_4.WorkingTreeFormat5()
 
396
        default_wt_format = workingtree.WorkingTreeFormat4._default_format
 
397
        wt4_format = workingtree.WorkingTreeFormat4()
 
398
        wt5_format = workingtree.WorkingTreeFormat5()
387
399
        expected_scenarios = [
388
 
            ('WorkingTreeFormat4',
 
400
            ('WorkingTreeFormat2',
389
401
             {'bzrdir_format': formats[0]._matchingbzrdir,
390
402
              'transport_readonly_server': 'b',
391
403
              'transport_server': 'a',
451
463
        # ones to add.
452
464
        from bzrlib.tests.per_tree import (
453
465
            return_parameter,
 
466
            revision_tree_from_workingtree
454
467
            )
455
468
        from bzrlib.tests.per_intertree import (
456
469
            make_scenarios,
457
470
            )
458
 
        from bzrlib.workingtree_3 import WorkingTreeFormat3
459
 
        from bzrlib.workingtree_4 import WorkingTreeFormat4
 
471
        from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
460
472
        input_test = TestInterTreeScenarios(
461
473
            "test_scenarios")
462
474
        server1 = "a"
463
475
        server2 = "b"
464
 
        format1 = WorkingTreeFormat4()
 
476
        format1 = WorkingTreeFormat2()
465
477
        format2 = WorkingTreeFormat3()
466
478
        formats = [("1", str, format1, format2, "converter1"),
467
479
            ("2", int, format2, format1, "converter2")]
513
525
        self.assertRaises(AssertionError, self.assertEqualStat,
514
526
            os.lstat("foo"), os.lstat("longname"))
515
527
 
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
 
 
535
528
 
536
529
class TestTestCaseWithMemoryTransport(tests.TestCaseWithMemoryTransport):
537
530
 
571
564
        tree = self.make_branch_and_memory_tree('dir')
572
565
        # Guard against regression into MemoryTransport leaking
573
566
        # files to disk instead of keeping them in memory.
574
 
        self.assertFalse(osutils.lexists('dir'))
 
567
        self.failIf(osutils.lexists('dir'))
575
568
        self.assertIsInstance(tree, memorytree.MemoryTree)
576
569
 
577
570
    def test_make_branch_and_memory_tree_with_format(self):
578
571
        """make_branch_and_memory_tree should accept a format option."""
579
572
        format = bzrdir.BzrDirMetaFormat1()
580
 
        format.repository_format = repository.format_registry.get_default()
 
573
        format.repository_format = weaverepo.RepositoryFormat7()
581
574
        tree = self.make_branch_and_memory_tree('dir', format=format)
582
575
        # Guard against regression into MemoryTransport leaking
583
576
        # files to disk instead of keeping them in memory.
584
 
        self.assertFalse(osutils.lexists('dir'))
 
577
        self.failIf(osutils.lexists('dir'))
585
578
        self.assertIsInstance(tree, memorytree.MemoryTree)
586
579
        self.assertEqual(format.repository_format.__class__,
587
580
            tree.branch.repository._format.__class__)
591
584
        self.assertIsInstance(builder, branchbuilder.BranchBuilder)
592
585
        # Guard against regression into MemoryTransport leaking
593
586
        # files to disk instead of keeping them in memory.
594
 
        self.assertFalse(osutils.lexists('dir'))
 
587
        self.failIf(osutils.lexists('dir'))
595
588
 
596
589
    def test_make_branch_builder_with_format(self):
597
590
        # Use a repo layout that doesn't conform to a 'named' layout, to ensure
598
591
        # that the format objects are used.
599
592
        format = bzrdir.BzrDirMetaFormat1()
600
 
        repo_format = repository.format_registry.get_default()
 
593
        repo_format = weaverepo.RepositoryFormat7()
601
594
        format.repository_format = repo_format
602
595
        builder = self.make_branch_builder('dir', format=format)
603
596
        the_branch = builder.get_branch()
604
597
        # Guard against regression into MemoryTransport leaking
605
598
        # files to disk instead of keeping them in memory.
606
 
        self.assertFalse(osutils.lexists('dir'))
 
599
        self.failIf(osutils.lexists('dir'))
607
600
        self.assertEqual(format.repository_format.__class__,
608
601
                         the_branch.repository._format.__class__)
609
602
        self.assertEqual(repo_format.get_format_string(),
615
608
        the_branch = builder.get_branch()
616
609
        # Guard against regression into MemoryTransport leaking
617
610
        # files to disk instead of keeping them in memory.
618
 
        self.assertFalse(osutils.lexists('dir'))
 
611
        self.failIf(osutils.lexists('dir'))
619
612
        dir_format = bzrdir.format_registry.make_bzrdir('knit')
620
613
        self.assertEqual(dir_format.repository_format.__class__,
621
614
                         the_branch.repository._format.__class__)
654
647
        url2 = self.get_readonly_url('foo/bar')
655
648
        t = transport.get_transport(url)
656
649
        t2 = transport.get_transport(url2)
657
 
        self.assertIsInstance(t, ReadonlyTransportDecorator)
658
 
        self.assertIsInstance(t2, ReadonlyTransportDecorator)
 
650
        self.failUnless(isinstance(t, ReadonlyTransportDecorator))
 
651
        self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
659
652
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
660
653
 
661
654
    def test_get_readonly_url_http(self):
669
662
        # the transport returned may be any HttpTransportBase subclass
670
663
        t = transport.get_transport(url)
671
664
        t2 = transport.get_transport(url2)
672
 
        self.assertIsInstance(t, HttpTransportBase)
673
 
        self.assertIsInstance(t2, HttpTransportBase)
 
665
        self.failUnless(isinstance(t, HttpTransportBase))
 
666
        self.failUnless(isinstance(t2, HttpTransportBase))
674
667
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
675
668
 
676
669
    def test_is_directory(self):
684
677
    def test_make_branch_builder(self):
685
678
        builder = self.make_branch_builder('dir')
686
679
        rev_id = builder.build_commit()
687
 
        self.assertPathExists('dir')
 
680
        self.failUnlessExists('dir')
688
681
        a_dir = bzrdir.BzrDir.open('dir')
689
682
        self.assertRaises(errors.NoWorkingTree, a_dir.open_workingtree)
690
683
        a_branch = a_dir.open_branch()
706
699
        self.assertIsInstance(result_bzrdir.transport,
707
700
                              memory.MemoryTransport)
708
701
        # should not be on disk, should only be in memory
709
 
        self.assertPathDoesNotExist('subdir')
 
702
        self.failIfExists('subdir')
710
703
 
711
704
 
712
705
class TestChrootedTest(tests.ChrootedTestCase):
771
764
        self.check_timing(ShortDelayTestCase('test_short_delay'),
772
765
                          r"^ +[0-9]+ms$")
773
766
 
 
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
 
774
807
    def _time_hello_world_encoding(self):
775
808
        """Profile two sleep calls
776
809
 
816
849
        self.assertContainsRe(output,
817
850
            r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
818
851
 
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
 
 
834
852
    def test_known_failure(self):
835
853
        """A KnownFailure being raised should trigger several result actions."""
836
854
        class InstrumentedTestResult(tests.ExtendedTestResult):
1086
1104
    def test_result_decorator(self):
1087
1105
        # decorate results
1088
1106
        calls = []
1089
 
        class LoggingDecorator(ExtendedToOriginalDecorator):
 
1107
        class LoggingDecorator(tests.ForwardingResult):
1090
1108
            def startTest(self, test):
1091
 
                ExtendedToOriginalDecorator.startTest(self, test)
 
1109
                tests.ForwardingResult.startTest(self, test)
1092
1110
                calls.append('start')
1093
1111
        test = unittest.FunctionTestCase(lambda:None)
1094
1112
        stream = StringIO()
1195
1213
            ],
1196
1214
            lines[-3:])
1197
1215
 
 
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
 
1198
1239
    def test_verbose_test_count(self):
1199
1240
        """A verbose test run reports the right test count at the start"""
1200
1241
        suite = TestUtil.TestSuite([
1210
1251
    def test_startTestRun(self):
1211
1252
        """run should call result.startTestRun()"""
1212
1253
        calls = []
1213
 
        class LoggingDecorator(ExtendedToOriginalDecorator):
 
1254
        class LoggingDecorator(tests.ForwardingResult):
1214
1255
            def startTestRun(self):
1215
 
                ExtendedToOriginalDecorator.startTestRun(self)
 
1256
                tests.ForwardingResult.startTestRun(self)
1216
1257
                calls.append('startTestRun')
1217
1258
        test = unittest.FunctionTestCase(lambda:None)
1218
1259
        stream = StringIO()
1224
1265
    def test_stopTestRun(self):
1225
1266
        """run should call result.stopTestRun()"""
1226
1267
        calls = []
1227
 
        class LoggingDecorator(ExtendedToOriginalDecorator):
 
1268
        class LoggingDecorator(tests.ForwardingResult):
1228
1269
            def stopTestRun(self):
1229
 
                ExtendedToOriginalDecorator.stopTestRun(self)
 
1270
                tests.ForwardingResult.stopTestRun(self)
1230
1271
                calls.append('stopTestRun')
1231
1272
        test = unittest.FunctionTestCase(lambda:None)
1232
1273
        stream = StringIO()
1235
1276
        result = self.run_test_runner(runner, test)
1236
1277
        self.assertLength(1, calls)
1237
1278
 
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
 
 
1255
1279
 
1256
1280
class SampleTestCase(tests.TestCase):
1257
1281
 
1445
1469
        # Note this test won't fail with hooks that the core library doesn't
1446
1470
        # use - but it trigger with a plugin that adds hooks, so its still a
1447
1471
        # useful warning in that case.
1448
 
        self.assertEqual(bzrlib.branch.BranchHooks(), bzrlib.branch.Branch.hooks)
1449
 
        self.assertEqual(
1450
 
            bzrlib.smart.server.SmartServerHooks(),
 
1472
        self.assertEqual(bzrlib.branch.BranchHooks(),
 
1473
            bzrlib.branch.Branch.hooks)
 
1474
        self.assertEqual(bzrlib.smart.server.SmartServerHooks(),
1451
1475
            bzrlib.smart.server.SmartTCPServer.hooks)
1452
 
        self.assertEqual(
1453
 
            bzrlib.commands.CommandHooks(), bzrlib.commands.Command.hooks)
 
1476
        self.assertEqual(bzrlib.commands.CommandHooks(),
 
1477
            bzrlib.commands.Command.hooks)
1454
1478
 
1455
1479
    def test__gather_lsprof_in_benchmarks(self):
1456
1480
        """When _gather_lsprof_in_benchmarks is on, accumulate profile data.
1934
1958
    def test_make_branch_and_tree_with_format(self):
1935
1959
        # we should be able to supply a format to make_branch_and_tree
1936
1960
        self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
 
1961
        self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
1937
1962
        self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
1938
1963
                              bzrlib.bzrdir.BzrDirMetaFormat1)
 
1964
        self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
 
1965
                              bzrlib.bzrdir.BzrDirFormat6)
1939
1966
 
1940
1967
    def test_make_branch_and_memory_tree(self):
1941
1968
        # we should be able to get a new branch and a mutable tree from
2024
2051
            def __call__(test, result):
2025
2052
                test.run(result)
2026
2053
            def run(test, result):
2027
 
                self.assertIsInstance(result, ExtendedToOriginalDecorator)
 
2054
                self.assertIsInstance(result, tests.ForwardingResult)
2028
2055
                calls.append("called")
2029
2056
            def countTestCases(self):
2030
2057
                return 1
2320
2347
        # stdout and stderr of the invoked run_bzr
2321
2348
        current_factory = bzrlib.ui.ui_factory
2322
2349
        self.run_bzr(['foo'])
2323
 
        self.assertFalse(current_factory is self.factory)
 
2350
        self.failIf(current_factory is self.factory)
2324
2351
        self.assertNotEqual(sys.stdout, self.factory.stdout)
2325
2352
        self.assertNotEqual(sys.stderr, self.factory.stderr)
2326
2353
        self.assertEqual('foo\n', self.factory.stdout.getvalue())
2508
2535
        self.assertEqual([], command[2:])
2509
2536
 
2510
2537
    def test_set_env(self):
2511
 
        self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
 
2538
        self.failIf('EXISTANT_ENV_VAR' in os.environ)
2512
2539
        # set in the child
2513
2540
        def check_environment():
2514
2541
            self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2520
2547
 
2521
2548
    def test_run_bzr_subprocess_env_del(self):
2522
2549
        """run_bzr_subprocess can remove environment variables too."""
2523
 
        self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
 
2550
        self.failIf('EXISTANT_ENV_VAR' in os.environ)
2524
2551
        def check_environment():
2525
2552
            self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2526
2553
        os.environ['EXISTANT_ENV_VAR'] = 'set variable'
2532
2559
        del os.environ['EXISTANT_ENV_VAR']
2533
2560
 
2534
2561
    def test_env_del_missing(self):
2535
 
        self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
 
2562
        self.failIf('NON_EXISTANT_ENV_VAR' in os.environ)
2536
2563
        def check_environment():
2537
2564
            self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
2538
2565
        self.check_popen_state = check_environment
2813
2840
        self.assertEqual(remaining_names, _test_ids(split_suite[1]))
2814
2841
 
2815
2842
 
2816
 
class TestCheckTreeShape(tests.TestCaseWithTransport):
 
2843
class TestCheckInventoryShape(tests.TestCaseWithTransport):
2817
2844
 
2818
 
    def test_check_tree_shape(self):
 
2845
    def test_check_inventory_shape(self):
2819
2846
        files = ['a', 'b/', 'b/c']
2820
2847
        tree = self.make_branch_and_tree('.')
2821
2848
        self.build_tree(files)
2822
2849
        tree.add(files)
2823
2850
        tree.lock_read()
2824
2851
        try:
2825
 
            self.check_tree_shape(tree, files)
 
2852
            self.check_inventory_shape(tree.inventory, files)
2826
2853
        finally:
2827
2854
            tree.unlock()
2828
2855
 
3160
3187
        tpr.register('bar', 'bBB.aAA.rRR')
3161
3188
        self.assertEquals('bbb.aaa.rrr', tpr.get('bar'))
3162
3189
        self.assertThat(self.get_log(),
3163
 
            DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR",
3164
 
                           doctest.ELLIPSIS))
 
3190
            DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR", ELLIPSIS))
3165
3191
 
3166
3192
    def test_get_unknown_prefix(self):
3167
3193
        tpr = self._get_registry()
3202
3228
        class Test(unittest.TestCase):
3203
3229
            def runTest(self):
3204
3230
                pass
 
3231
            addCleanup = None # for when on Python 2.7 with native addCleanup
3205
3232
        result = self.LeakRecordingResult()
3206
3233
        test = Test()
 
3234
        self.assertIs(getattr(test, "addCleanup", None), None)
3207
3235
        result.startTestRun()
3208
3236
        test.run(result)
3209
3237
        result.stopTestRun()
3273
3301
        self.assertContainsString(result.stream.getvalue(), "leaking threads")
3274
3302
 
3275
3303
 
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
 
 
3346
3304
class TestRunSuite(tests.TestCase):
3347
3305
 
3348
3306
    def test_runner_class(self):
3359
3317
                                                self.verbosity)
3360
3318
        tests.run_suite(suite, runner_class=MyRunner, stream=StringIO())
3361
3319
        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)