~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

Merge fetch-spec-everything-not-in-other.

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
42
42
from bzrlib import (
43
43
    branchbuilder,
44
44
    bzrdir,
45
 
    debug,
46
45
    errors,
47
46
    lockdir,
48
47
    memorytree,
56
55
    )
57
56
from bzrlib.repofmt import (
58
57
    groupcompress_repo,
59
 
    pack_repo,
60
58
    weaverepo,
61
59
    )
62
60
from bzrlib.symbol_versioning import (
68
66
    features,
69
67
    test_lsprof,
70
68
    test_server,
71
 
    test_sftp_transport,
72
69
    TestUtil,
73
70
    )
74
71
from bzrlib.trace import note, mutter
75
72
from bzrlib.transport import memory
76
 
from bzrlib.version import _get_bzr_source_tree
77
73
 
78
74
 
79
75
def _test_ids(test_suite):
92
88
            "text", "plain", {"charset": "utf8"})))
93
89
        self.assertThat(u"".join(log.iter_text()), Equals(self.get_log()))
94
90
        self.assertThat(self.get_log(),
95
 
            DocTestMatches(u"...a test message\n", ELLIPSIS))
 
91
            DocTestMatches(u"...a test message\n", doctest.ELLIPSIS))
96
92
 
97
93
 
98
94
class TestUnicodeFilename(tests.TestCase):
3210
3206
        tpr.register('bar', 'bBB.aAA.rRR')
3211
3207
        self.assertEquals('bbb.aaa.rrr', tpr.get('bar'))
3212
3208
        self.assertThat(self.get_log(),
3213
 
            DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR", ELLIPSIS))
 
3209
            DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR",
 
3210
                           doctest.ELLIPSIS))
3214
3211
 
3215
3212
    def test_get_unknown_prefix(self):
3216
3213
        tpr = self._get_registry()
3251
3248
        class Test(unittest.TestCase):
3252
3249
            def runTest(self):
3253
3250
                pass
3254
 
            addCleanup = None # for when on Python 2.7 with native addCleanup
3255
3251
        result = self.LeakRecordingResult()
3256
3252
        test = Test()
3257
 
        self.assertIs(getattr(test, "addCleanup", None), None)
3258
3253
        result.startTestRun()
3259
3254
        test.run(result)
3260
3255
        result.stopTestRun()
3387
3382
        result = tests.ExtendedTestResult(StringIO(), 0, 1)
3388
3383
        post_mortem_calls = []
3389
3384
        self.overrideAttr(pdb, "post_mortem", post_mortem_calls.append)
3390
 
        self.addCleanup(osutils.set_or_unset_env, "BZR_TEST_PDB",
3391
 
            osutils.set_or_unset_env("BZR_TEST_PDB", None))
 
3385
        self.overrideEnv('BZR_TEST_PDB', None)
3392
3386
        result._post_mortem(1)
3393
 
        os.environ["BZR_TEST_PDB"] = "on"
 
3387
        self.overrideEnv('BZR_TEST_PDB', 'on')
3394
3388
        result._post_mortem(2)
3395
3389
        self.assertEqual([2], post_mortem_calls)
3396
3390
 
3411
3405
                                                self.verbosity)
3412
3406
        tests.run_suite(suite, runner_class=MyRunner, stream=StringIO())
3413
3407
        self.assertLength(1, calls)
 
3408
 
 
3409
 
 
3410
class TestEnvironHandling(tests.TestCase):
 
3411
 
 
3412
    def test_overrideEnv_None_called_twice_doesnt_leak(self):
 
3413
        self.failIf('MYVAR' in os.environ)
 
3414
        self.overrideEnv('MYVAR', '42')
 
3415
        # We use an embedded test to make sure we fix the _captureVar bug
 
3416
        class Test(tests.TestCase):
 
3417
            def test_me(self):
 
3418
                # The first call save the 42 value
 
3419
                self.overrideEnv('MYVAR', None)
 
3420
                self.assertEquals(None, os.environ.get('MYVAR'))
 
3421
                # Make sure we can call it twice
 
3422
                self.overrideEnv('MYVAR', None)
 
3423
                self.assertEquals(None, os.environ.get('MYVAR'))
 
3424
        output = StringIO()
 
3425
        result = tests.TextTestResult(output, 0, 1)
 
3426
        Test('test_me').run(result)
 
3427
        if not result.wasStrictlySuccessful():
 
3428
            self.fail(output.getvalue())
 
3429
        # We get our value back
 
3430
        self.assertEquals('42', os.environ.get('MYVAR'))
 
3431
 
 
3432
 
 
3433
class TestIsolatedEnv(tests.TestCase):
 
3434
    """Test isolating tests from os.environ.
 
3435
 
 
3436
    Since we use tests that are already isolated from os.environ a bit of care
 
3437
    should be taken when designing the tests to avoid bootstrap side-effects.
 
3438
    The tests start an already clean os.environ which allow doing valid
 
3439
    assertions about which variables are present or not and design tests around
 
3440
    these assertions.
 
3441
    """
 
3442
 
 
3443
    class ScratchMonkey(tests.TestCase):
 
3444
 
 
3445
        def test_me(self):
 
3446
            pass
 
3447
 
 
3448
    def test_basics(self):
 
3449
        # Make sure we know the definition of BZR_HOME: not part of os.environ
 
3450
        # for tests.TestCase.
 
3451
        self.assertTrue('BZR_HOME' in tests.isolated_environ)
 
3452
        self.assertEquals(None, tests.isolated_environ['BZR_HOME'])
 
3453
        # Being part of isolated_environ, BZR_HOME should not appear here
 
3454
        self.assertFalse('BZR_HOME' in os.environ)
 
3455
        # Make sure we know the definition of LINES: part of os.environ for
 
3456
        # tests.TestCase
 
3457
        self.assertTrue('LINES' in tests.isolated_environ)
 
3458
        self.assertEquals('25', tests.isolated_environ['LINES'])
 
3459
        self.assertEquals('25', os.environ['LINES'])
 
3460
 
 
3461
    def test_injecting_unknown_variable(self):
 
3462
        # BZR_HOME is known to be absent from os.environ
 
3463
        test = self.ScratchMonkey('test_me')
 
3464
        tests.override_os_environ(test, {'BZR_HOME': 'foo'})
 
3465
        self.assertEquals('foo', os.environ['BZR_HOME'])
 
3466
        tests.restore_os_environ(test)
 
3467
        self.assertFalse('BZR_HOME' in os.environ)
 
3468
 
 
3469
    def test_injecting_known_variable(self):
 
3470
        test = self.ScratchMonkey('test_me')
 
3471
        # LINES is known to be present in os.environ
 
3472
        tests.override_os_environ(test, {'LINES': '42'})
 
3473
        self.assertEquals('42', os.environ['LINES'])
 
3474
        tests.restore_os_environ(test)
 
3475
        self.assertEquals('25', os.environ['LINES'])
 
3476
 
 
3477
    def test_deleting_variable(self):
 
3478
        test = self.ScratchMonkey('test_me')
 
3479
        # LINES is known to be present in os.environ
 
3480
        tests.override_os_environ(test, {'LINES': None})
 
3481
        self.assertTrue('LINES' not in os.environ)
 
3482
        tests.restore_os_environ(test)
 
3483
        self.assertEquals('25', os.environ['LINES'])
 
3484
 
 
3485
 
 
3486
class TestDocTestSuiteIsolation(tests.TestCase):
 
3487
    """Test that `tests.DocTestSuite` isolates doc tests from os.environ.
 
3488
 
 
3489
    Since tests.TestCase alreay provides an isolation from os.environ, we use
 
3490
    the clean environment as a base for testing. To precisely capture the
 
3491
    isolation provided by tests.DocTestSuite, we use doctest.DocTestSuite to
 
3492
    compare against.
 
3493
 
 
3494
    We want to make sure `tests.DocTestSuite` respect `tests.isolated_environ`,
 
3495
    not `os.environ` so each test overrides it to suit its needs.
 
3496
 
 
3497
    """
 
3498
 
 
3499
    def get_doctest_suite_for_string(self, klass, string):
 
3500
        class Finder(doctest.DocTestFinder):
 
3501
 
 
3502
            def find(*args, **kwargs):
 
3503
                test = doctest.DocTestParser().get_doctest(
 
3504
                    string, {}, 'foo', 'foo.py', 0)
 
3505
                return [test]
 
3506
 
 
3507
        suite = klass(test_finder=Finder())
 
3508
        return suite
 
3509
 
 
3510
    def run_doctest_suite_for_string(self, klass, string):
 
3511
        suite = self.get_doctest_suite_for_string(klass, string)
 
3512
        output = StringIO()
 
3513
        result = tests.TextTestResult(output, 0, 1)
 
3514
        suite.run(result)
 
3515
        return result, output
 
3516
 
 
3517
    def assertDocTestStringSucceds(self, klass, string):
 
3518
        result, output = self.run_doctest_suite_for_string(klass, string)
 
3519
        if not result.wasStrictlySuccessful():
 
3520
            self.fail(output.getvalue())
 
3521
 
 
3522
    def assertDocTestStringFails(self, klass, string):
 
3523
        result, output = self.run_doctest_suite_for_string(klass, string)
 
3524
        if result.wasStrictlySuccessful():
 
3525
            self.fail(output.getvalue())
 
3526
 
 
3527
    def test_injected_variable(self):
 
3528
        self.overrideAttr(tests, 'isolated_environ', {'LINES': '42'})
 
3529
        test = """
 
3530
            >>> import os
 
3531
            >>> os.environ['LINES']
 
3532
            '42'
 
3533
            """
 
3534
        # doctest.DocTestSuite fails as it sees '25'
 
3535
        self.assertDocTestStringFails(doctest.DocTestSuite, test)
 
3536
        # tests.DocTestSuite sees '42'
 
3537
        self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
 
3538
 
 
3539
    def test_deleted_variable(self):
 
3540
        self.overrideAttr(tests, 'isolated_environ', {'LINES': None})
 
3541
        test = """
 
3542
            >>> import os
 
3543
            >>> os.environ.get('LINES')
 
3544
            """
 
3545
        # doctest.DocTestSuite fails as it sees '25'
 
3546
        self.assertDocTestStringFails(doctest.DocTestSuite, test)
 
3547
        # tests.DocTestSuite sees None
 
3548
        self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)