~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: 2011-01-10 23:55:16 UTC
  • mfrom: (5574.6.10 321320-isolate-doc-tests)
  • Revision ID: pqm@pqm.ubuntu.com-20110110235516-vkoji04jm8zjstwl
(vila) Isolate doctests from os.environ (Vincent Ladeuil)

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
 
20
import doctest
21
21
import os
22
22
import signal
23
23
import sys
92
92
            "text", "plain", {"charset": "utf8"})))
93
93
        self.assertThat(u"".join(log.iter_text()), Equals(self.get_log()))
94
94
        self.assertThat(self.get_log(),
95
 
            DocTestMatches(u"...a test message\n", ELLIPSIS))
 
95
            DocTestMatches(u"...a test message\n", doctest.ELLIPSIS))
96
96
 
97
97
 
98
98
class TestUnicodeFilename(tests.TestCase):
3210
3210
        tpr.register('bar', 'bBB.aAA.rRR')
3211
3211
        self.assertEquals('bbb.aaa.rrr', tpr.get('bar'))
3212
3212
        self.assertThat(self.get_log(),
3213
 
            DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR", ELLIPSIS))
 
3213
            DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR",
 
3214
                           doctest.ELLIPSIS))
3214
3215
 
3215
3216
    def test_get_unknown_prefix(self):
3216
3217
        tpr = self._get_registry()
3453
3454
            self.fail(output.getvalue())
3454
3455
        # We get our value back
3455
3456
        self.assertEquals('42', os.environ.get('MYVAR'))
 
3457
 
 
3458
 
 
3459
class TestIsolatedEnv(tests.TestCase):
 
3460
    """Test isolating tests from os.environ.
 
3461
 
 
3462
    Since we use tests that are already isolated from os.environ a bit of care
 
3463
    should be taken when designing the tests to avoid bootstrap side-effects.
 
3464
    The tests start an already clean os.environ which allow doing valid
 
3465
    assertions about which variables are present or not and design tests around
 
3466
    these assertions.
 
3467
    """
 
3468
 
 
3469
    class ScratchMonkey(tests.TestCase):
 
3470
 
 
3471
        def test_me(self):
 
3472
            pass
 
3473
 
 
3474
    def test_basics(self):
 
3475
        # Make sure we know the definition of BZR_HOME: not part of os.environ
 
3476
        # for tests.TestCase.
 
3477
        self.assertTrue('BZR_HOME' in tests.isolated_environ)
 
3478
        self.assertEquals(None, tests.isolated_environ['BZR_HOME'])
 
3479
        # Being part of isolated_environ, BZR_HOME should not appear here
 
3480
        self.assertFalse('BZR_HOME' in os.environ)
 
3481
        # Make sure we know the definition of LINES: part of os.environ for
 
3482
        # tests.TestCase
 
3483
        self.assertTrue('LINES' in tests.isolated_environ)
 
3484
        self.assertEquals('25', tests.isolated_environ['LINES'])
 
3485
        self.assertEquals('25', os.environ['LINES'])
 
3486
 
 
3487
    def test_injecting_unknown_variable(self):
 
3488
        # BZR_HOME is known to be absent from os.environ
 
3489
        test = self.ScratchMonkey('test_me')
 
3490
        tests.override_os_environ(test, {'BZR_HOME': 'foo'})
 
3491
        self.assertEquals('foo', os.environ['BZR_HOME'])
 
3492
        tests.restore_os_environ(test)
 
3493
        self.assertFalse('BZR_HOME' in os.environ)
 
3494
 
 
3495
    def test_injecting_known_variable(self):
 
3496
        test = self.ScratchMonkey('test_me')
 
3497
        # LINES is known to be present in os.environ
 
3498
        tests.override_os_environ(test, {'LINES': '42'})
 
3499
        self.assertEquals('42', os.environ['LINES'])
 
3500
        tests.restore_os_environ(test)
 
3501
        self.assertEquals('25', os.environ['LINES'])
 
3502
 
 
3503
    def test_deleting_variable(self):
 
3504
        test = self.ScratchMonkey('test_me')
 
3505
        # LINES is known to be present in os.environ
 
3506
        tests.override_os_environ(test, {'LINES': None})
 
3507
        self.assertTrue('LINES' not in os.environ)
 
3508
        tests.restore_os_environ(test)
 
3509
        self.assertEquals('25', os.environ['LINES'])
 
3510
 
 
3511
 
 
3512
class TestDocTestSuiteIsolation(tests.TestCase):
 
3513
    """Test that `tests.DocTestSuite` isolates doc tests from os.environ.
 
3514
 
 
3515
    Since tests.TestCase alreay provides an isolation from os.environ, we use
 
3516
    the clean environment as a base for testing. To precisely capture the
 
3517
    isolation provided by tests.DocTestSuite, we use doctest.DocTestSuite to
 
3518
    compare against.
 
3519
 
 
3520
    We want to make sure `tests.DocTestSuite` respect `tests.isolated_environ`,
 
3521
    not `os.environ` so each test overrides it to suit its needs.
 
3522
 
 
3523
    """
 
3524
 
 
3525
    def get_doctest_suite_for_string(self, klass, string):
 
3526
        class Finder(doctest.DocTestFinder):
 
3527
 
 
3528
            def find(*args, **kwargs):
 
3529
                test = doctest.DocTestParser().get_doctest(
 
3530
                    string, {}, 'foo', 'foo.py', 0)
 
3531
                return [test]
 
3532
 
 
3533
        suite = klass(test_finder=Finder())
 
3534
        return suite
 
3535
 
 
3536
    def run_doctest_suite_for_string(self, klass, string):
 
3537
        suite = self.get_doctest_suite_for_string(klass, string)
 
3538
        output = StringIO()
 
3539
        result = tests.TextTestResult(output, 0, 1)
 
3540
        suite.run(result)
 
3541
        return result, output
 
3542
 
 
3543
    def assertDocTestStringSucceds(self, klass, string):
 
3544
        result, output = self.run_doctest_suite_for_string(klass, string)
 
3545
        if not result.wasStrictlySuccessful():
 
3546
            self.fail(output.getvalue())
 
3547
 
 
3548
    def assertDocTestStringFails(self, klass, string):
 
3549
        result, output = self.run_doctest_suite_for_string(klass, string)
 
3550
        if result.wasStrictlySuccessful():
 
3551
            self.fail(output.getvalue())
 
3552
 
 
3553
    def test_injected_variable(self):
 
3554
        self.overrideAttr(tests, 'isolated_environ', {'LINES': '42'})
 
3555
        test = """
 
3556
            >>> import os
 
3557
            >>> os.environ['LINES']
 
3558
            '42'
 
3559
            """
 
3560
        # doctest.DocTestSuite fails as it sees '25'
 
3561
        self.assertDocTestStringFails(doctest.DocTestSuite, test)
 
3562
        # tests.DocTestSuite sees '42'
 
3563
        self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
 
3564
 
 
3565
    def test_deleted_variable(self):
 
3566
        self.overrideAttr(tests, 'isolated_environ', {'LINES': None})
 
3567
        test = """
 
3568
            >>> import os
 
3569
            >>> os.environ.get('LINES')
 
3570
            """
 
3571
        # doctest.DocTestSuite fails as it sees '25'
 
3572
        self.assertDocTestStringFails(doctest.DocTestSuite, test)
 
3573
        # tests.DocTestSuite sees None
 
3574
        self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)