2610
2665
self.assertEqual('bzr: interrupted\n', result[1])
2613
class TestFeature(tests.TestCase):
2615
def test_caching(self):
2616
"""Feature._probe is called by the feature at most once."""
2617
class InstrumentedFeature(tests.Feature):
2619
super(InstrumentedFeature, self).__init__()
2622
self.calls.append('_probe')
2624
feature = InstrumentedFeature()
2626
self.assertEqual(['_probe'], feature.calls)
2628
self.assertEqual(['_probe'], feature.calls)
2630
def test_named_str(self):
2631
"""Feature.__str__ should thunk to feature_name()."""
2632
class NamedFeature(tests.Feature):
2633
def feature_name(self):
2635
feature = NamedFeature()
2636
self.assertEqual('symlinks', str(feature))
2638
def test_default_str(self):
2639
"""Feature.__str__ should default to __class__.__name__."""
2640
class NamedFeature(tests.Feature):
2642
feature = NamedFeature()
2643
self.assertEqual('NamedFeature', str(feature))
2646
class TestUnavailableFeature(tests.TestCase):
2648
def test_access_feature(self):
2649
feature = tests.Feature()
2650
exception = tests.UnavailableFeature(feature)
2651
self.assertIs(feature, exception.args[0])
2654
simple_thunk_feature = tests._CompatabilityThunkFeature(
2655
deprecated_in((2, 1, 0)),
2656
'bzrlib.tests.test_selftest',
2657
'simple_thunk_feature','UnicodeFilename',
2658
replacement_module='bzrlib.tests'
2661
class Test_CompatibilityFeature(tests.TestCase):
2663
def test_does_thunk(self):
2664
res = self.callDeprecated(
2665
['bzrlib.tests.test_selftest.simple_thunk_feature was deprecated'
2666
' in version 2.1.0. Use bzrlib.tests.UnicodeFilename instead.'],
2667
simple_thunk_feature.available)
2668
self.assertEqual(tests.UnicodeFilename.available(), res)
2671
class TestModuleAvailableFeature(tests.TestCase):
2673
def test_available_module(self):
2674
feature = tests.ModuleAvailableFeature('bzrlib.tests')
2675
self.assertEqual('bzrlib.tests', feature.module_name)
2676
self.assertEqual('bzrlib.tests', str(feature))
2677
self.assertTrue(feature.available())
2678
self.assertIs(tests, feature.module)
2680
def test_unavailable_module(self):
2681
feature = tests.ModuleAvailableFeature('bzrlib.no_such_module_exists')
2682
self.assertEqual('bzrlib.no_such_module_exists', str(feature))
2683
self.assertFalse(feature.available())
2684
self.assertIs(None, feature.module)
2687
2668
class TestSelftestFiltering(tests.TestCase):
2689
2670
def setUp(self):
2690
tests.TestCase.setUp(self)
2671
super(TestSelftestFiltering, self).setUp()
2691
2672
self.suite = TestUtil.TestSuite()
2692
2673
self.loader = TestUtil.TestLoader()
2693
2674
self.suite.addTest(self.loader.loadTestsFromModule(
3301
3281
self.assertContainsString(result.stream.getvalue(), "leaking threads")
3284
class TestPostMortemDebugging(tests.TestCase):
3285
"""Check post mortem debugging works when tests fail or error"""
3287
class TracebackRecordingResult(tests.ExtendedTestResult):
3289
tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
3290
self.postcode = None
3291
def _post_mortem(self, tb=None):
3292
"""Record the code object at the end of the current traceback"""
3293
tb = tb or sys.exc_info()[2]
3296
while next is not None:
3299
self.postcode = tb.tb_frame.f_code
3300
def report_error(self, test, err):
3302
def report_failure(self, test, err):
3305
def test_location_unittest_error(self):
3306
"""Needs right post mortem traceback with erroring unittest case"""
3307
class Test(unittest.TestCase):
3310
result = self.TracebackRecordingResult()
3312
self.assertEqual(result.postcode, Test.runTest.func_code)
3314
def test_location_unittest_failure(self):
3315
"""Needs right post mortem traceback with failing unittest case"""
3316
class Test(unittest.TestCase):
3318
raise self.failureException
3319
result = self.TracebackRecordingResult()
3321
self.assertEqual(result.postcode, Test.runTest.func_code)
3323
def test_location_bt_error(self):
3324
"""Needs right post mortem traceback with erroring bzrlib.tests case"""
3325
class Test(tests.TestCase):
3326
def test_error(self):
3328
result = self.TracebackRecordingResult()
3329
Test("test_error").run(result)
3330
self.assertEqual(result.postcode, Test.test_error.func_code)
3332
def test_location_bt_failure(self):
3333
"""Needs right post mortem traceback with failing bzrlib.tests case"""
3334
class Test(tests.TestCase):
3335
def test_failure(self):
3336
raise self.failureException
3337
result = self.TracebackRecordingResult()
3338
Test("test_failure").run(result)
3339
self.assertEqual(result.postcode, Test.test_failure.func_code)
3341
def test_env_var_triggers_post_mortem(self):
3342
"""Check pdb.post_mortem is called iff BZR_TEST_PDB is set"""
3344
result = tests.ExtendedTestResult(StringIO(), 0, 1)
3345
post_mortem_calls = []
3346
self.overrideAttr(pdb, "post_mortem", post_mortem_calls.append)
3347
self.overrideEnv('BZR_TEST_PDB', None)
3348
result._post_mortem(1)
3349
self.overrideEnv('BZR_TEST_PDB', 'on')
3350
result._post_mortem(2)
3351
self.assertEqual([2], post_mortem_calls)
3304
3354
class TestRunSuite(tests.TestCase):
3306
3356
def test_runner_class(self):
3317
3367
self.verbosity)
3318
3368
tests.run_suite(suite, runner_class=MyRunner, stream=StringIO())
3319
3369
self.assertLength(1, calls)
3372
class _Selftest(object):
3373
"""Mixin for tests needing full selftest output"""
3375
def _inject_stream_into_subunit(self, stream):
3376
"""To be overridden by subclasses that run tests out of process"""
3378
def _run_selftest(self, **kwargs):
3380
self._inject_stream_into_subunit(sio)
3381
tests.selftest(stream=sio, stop_on_failure=False, **kwargs)
3382
return sio.getvalue()
3385
class _ForkedSelftest(_Selftest):
3386
"""Mixin for tests needing full selftest output with forked children"""
3388
_test_needs_features = [features.subunit]
3390
def _inject_stream_into_subunit(self, stream):
3391
"""Monkey-patch subunit so the extra output goes to stream not stdout
3393
Some APIs need rewriting so this kind of bogus hackery can be replaced
3394
by passing the stream param from run_tests down into ProtocolTestCase.
3396
from subunit import ProtocolTestCase
3397
_original_init = ProtocolTestCase.__init__
3398
def _init_with_passthrough(self, *args, **kwargs):
3399
_original_init(self, *args, **kwargs)
3400
self._passthrough = stream
3401
self.overrideAttr(ProtocolTestCase, "__init__", _init_with_passthrough)
3403
def _run_selftest(self, **kwargs):
3404
# GZ 2011-05-26: Add a PosixSystem feature so this check can go away
3405
if getattr(os, "fork", None) is None:
3406
raise tests.TestNotApplicable("Platform doesn't support forking")
3407
# Make sure the fork code is actually invoked by claiming two cores
3408
self.overrideAttr(osutils, "local_concurrency", lambda: 2)
3409
kwargs.setdefault("suite_decorators", []).append(tests.fork_decorator)
3410
return super(_ForkedSelftest, self)._run_selftest(**kwargs)
3413
class TestParallelFork(_ForkedSelftest, tests.TestCase):
3414
"""Check operation of --parallel=fork selftest option"""
3416
def test_error_in_child_during_fork(self):
3417
"""Error in a forked child during test setup should get reported"""
3418
class Test(tests.TestCase):
3419
def testMethod(self):
3421
# We don't care what, just break something that a child will run
3422
self.overrideAttr(tests, "workaround_zealous_crypto_random", None)
3423
out = self._run_selftest(test_suite_factory=Test)
3424
# Lines from the tracebacks of the two child processes may be mixed
3425
# together due to the way subunit parses and forwards the streams,
3426
# so permit extra lines between each part of the error output.
3427
self.assertContainsRe(out,
3430
".+ in fork_for_tests\n"
3432
"\s*workaround_zealous_crypto_random\(\)\n"
3437
class TestUncollectedWarnings(_Selftest, tests.TestCase):
3438
"""Check a test case still alive after being run emits a warning"""
3440
class Test(tests.TestCase):
3441
def test_pass(self):
3443
def test_self_ref(self):
3444
self.also_self = self.test_self_ref
3445
def test_skip(self):
3446
self.skip("Don't need")
3448
def _get_suite(self):
3449
return TestUtil.TestSuite([
3450
self.Test("test_pass"),
3451
self.Test("test_self_ref"),
3452
self.Test("test_skip"),
3455
def _run_selftest_with_suite(self, **kwargs):
3456
old_flags = tests.selftest_debug_flags
3457
tests.selftest_debug_flags = old_flags.union(["uncollected_cases"])
3458
gc_on = gc.isenabled()
3462
output = self._run_selftest(test_suite_factory=self._get_suite,
3467
tests.selftest_debug_flags = old_flags
3468
self.assertNotContainsRe(output, "Uncollected test case.*test_pass")
3469
self.assertContainsRe(output, "Uncollected test case.*test_self_ref")
3472
def test_testsuite(self):
3473
self._run_selftest_with_suite()
3475
def test_pattern(self):
3476
out = self._run_selftest_with_suite(pattern="test_(?:pass|self_ref)$")
3477
self.assertNotContainsRe(out, "test_skip")
3479
def test_exclude_pattern(self):
3480
out = self._run_selftest_with_suite(exclude_pattern="test_skip$")
3481
self.assertNotContainsRe(out, "test_skip")
3483
def test_random_seed(self):
3484
self._run_selftest_with_suite(random_seed="now")
3486
def test_matching_tests_first(self):
3487
self._run_selftest_with_suite(matching_tests_first=True,
3488
pattern="test_self_ref$")
3490
def test_starting_with_and_exclude(self):
3491
out = self._run_selftest_with_suite(starting_with=["bt."],
3492
exclude_pattern="test_skip$")
3493
self.assertNotContainsRe(out, "test_skip")
3495
def test_additonal_decorator(self):
3496
out = self._run_selftest_with_suite(
3497
suite_decorators=[tests.TestDecorator])
3500
class TestUncollectedWarningsSubunit(TestUncollectedWarnings):
3501
"""Check warnings from tests staying alive are emitted with subunit"""
3503
_test_needs_features = [features.subunit]
3505
def _run_selftest_with_suite(self, **kwargs):
3506
return TestUncollectedWarnings._run_selftest_with_suite(self,
3507
runner_class=tests.SubUnitBzrRunner, **kwargs)
3510
class TestUncollectedWarningsForked(_ForkedSelftest, TestUncollectedWarnings):
3511
"""Check warnings from tests staying alive are emitted when forking"""
3514
class TestEnvironHandling(tests.TestCase):
3516
def test_overrideEnv_None_called_twice_doesnt_leak(self):
3517
self.assertFalse('MYVAR' in os.environ)
3518
self.overrideEnv('MYVAR', '42')
3519
# We use an embedded test to make sure we fix the _captureVar bug
3520
class Test(tests.TestCase):
3522
# The first call save the 42 value
3523
self.overrideEnv('MYVAR', None)
3524
self.assertEquals(None, os.environ.get('MYVAR'))
3525
# Make sure we can call it twice
3526
self.overrideEnv('MYVAR', None)
3527
self.assertEquals(None, os.environ.get('MYVAR'))
3529
result = tests.TextTestResult(output, 0, 1)
3530
Test('test_me').run(result)
3531
if not result.wasStrictlySuccessful():
3532
self.fail(output.getvalue())
3533
# We get our value back
3534
self.assertEquals('42', os.environ.get('MYVAR'))
3537
class TestIsolatedEnv(tests.TestCase):
3538
"""Test isolating tests from os.environ.
3540
Since we use tests that are already isolated from os.environ a bit of care
3541
should be taken when designing the tests to avoid bootstrap side-effects.
3542
The tests start an already clean os.environ which allow doing valid
3543
assertions about which variables are present or not and design tests around
3547
class ScratchMonkey(tests.TestCase):
3552
def test_basics(self):
3553
# Make sure we know the definition of BZR_HOME: not part of os.environ
3554
# for tests.TestCase.
3555
self.assertTrue('BZR_HOME' in tests.isolated_environ)
3556
self.assertEquals(None, tests.isolated_environ['BZR_HOME'])
3557
# Being part of isolated_environ, BZR_HOME should not appear here
3558
self.assertFalse('BZR_HOME' in os.environ)
3559
# Make sure we know the definition of LINES: part of os.environ for
3561
self.assertTrue('LINES' in tests.isolated_environ)
3562
self.assertEquals('25', tests.isolated_environ['LINES'])
3563
self.assertEquals('25', os.environ['LINES'])
3565
def test_injecting_unknown_variable(self):
3566
# BZR_HOME is known to be absent from os.environ
3567
test = self.ScratchMonkey('test_me')
3568
tests.override_os_environ(test, {'BZR_HOME': 'foo'})
3569
self.assertEquals('foo', os.environ['BZR_HOME'])
3570
tests.restore_os_environ(test)
3571
self.assertFalse('BZR_HOME' in os.environ)
3573
def test_injecting_known_variable(self):
3574
test = self.ScratchMonkey('test_me')
3575
# LINES is known to be present in os.environ
3576
tests.override_os_environ(test, {'LINES': '42'})
3577
self.assertEquals('42', os.environ['LINES'])
3578
tests.restore_os_environ(test)
3579
self.assertEquals('25', os.environ['LINES'])
3581
def test_deleting_variable(self):
3582
test = self.ScratchMonkey('test_me')
3583
# LINES is known to be present in os.environ
3584
tests.override_os_environ(test, {'LINES': None})
3585
self.assertTrue('LINES' not in os.environ)
3586
tests.restore_os_environ(test)
3587
self.assertEquals('25', os.environ['LINES'])
3590
class TestDocTestSuiteIsolation(tests.TestCase):
3591
"""Test that `tests.DocTestSuite` isolates doc tests from os.environ.
3593
Since tests.TestCase alreay provides an isolation from os.environ, we use
3594
the clean environment as a base for testing. To precisely capture the
3595
isolation provided by tests.DocTestSuite, we use doctest.DocTestSuite to
3598
We want to make sure `tests.DocTestSuite` respect `tests.isolated_environ`,
3599
not `os.environ` so each test overrides it to suit its needs.
3603
def get_doctest_suite_for_string(self, klass, string):
3604
class Finder(doctest.DocTestFinder):
3606
def find(*args, **kwargs):
3607
test = doctest.DocTestParser().get_doctest(
3608
string, {}, 'foo', 'foo.py', 0)
3611
suite = klass(test_finder=Finder())
3614
def run_doctest_suite_for_string(self, klass, string):
3615
suite = self.get_doctest_suite_for_string(klass, string)
3617
result = tests.TextTestResult(output, 0, 1)
3619
return result, output
3621
def assertDocTestStringSucceds(self, klass, string):
3622
result, output = self.run_doctest_suite_for_string(klass, string)
3623
if not result.wasStrictlySuccessful():
3624
self.fail(output.getvalue())
3626
def assertDocTestStringFails(self, klass, string):
3627
result, output = self.run_doctest_suite_for_string(klass, string)
3628
if result.wasStrictlySuccessful():
3629
self.fail(output.getvalue())
3631
def test_injected_variable(self):
3632
self.overrideAttr(tests, 'isolated_environ', {'LINES': '42'})
3635
>>> os.environ['LINES']
3638
# doctest.DocTestSuite fails as it sees '25'
3639
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3640
# tests.DocTestSuite sees '42'
3641
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
3643
def test_deleted_variable(self):
3644
self.overrideAttr(tests, 'isolated_environ', {'LINES': None})
3647
>>> os.environ.get('LINES')
3649
# doctest.DocTestSuite fails as it sees '25'
3650
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3651
# tests.DocTestSuite sees None
3652
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
3655
class TestSelftestExcludePatterns(tests.TestCase):
3658
super(TestSelftestExcludePatterns, self).setUp()
3659
self.overrideAttr(tests, 'test_suite', self.suite_factory)
3661
def suite_factory(self, keep_only=None, starting_with=None):
3662
"""A test suite factory with only a few tests."""
3663
class Test(tests.TestCase):
3665
# We don't need the full class path
3666
return self._testMethodName
3673
return TestUtil.TestSuite([Test("a"), Test("b"), Test("c")])
3675
def assertTestList(self, expected, *selftest_args):
3676
# We rely on setUp installing the right test suite factory so we can
3677
# test at the command level without loading the whole test suite
3678
out, err = self.run_bzr(('selftest', '--list') + selftest_args)
3679
actual = out.splitlines()
3680
self.assertEquals(expected, actual)
3682
def test_full_list(self):
3683
self.assertTestList(['a', 'b', 'c'])
3685
def test_single_exclude(self):
3686
self.assertTestList(['b', 'c'], '-x', 'a')
3688
def test_mutiple_excludes(self):
3689
self.assertTestList(['c'], '-x', 'a', '-x', 'b')
3692
class TestCounterHooks(tests.TestCase, SelfTestHelper):
3694
_test_needs_features = [features.subunit]
3697
super(TestCounterHooks, self).setUp()
3698
class Test(tests.TestCase):
3701
super(Test, self).setUp()
3702
self.hooks = hooks.Hooks()
3703
self.hooks.add_hook('myhook', 'Foo bar blah', (2,4))
3704
self.install_counter_hook(self.hooks, 'myhook')
3709
def run_hook_once(self):
3710
for hook in self.hooks['myhook']:
3713
self.test_class = Test
3715
def assertHookCalls(self, expected_calls, test_name):
3716
test = self.test_class(test_name)
3717
result = unittest.TestResult()
3719
self.assertTrue(hasattr(test, '_counters'))
3720
self.assertTrue(test._counters.has_key('myhook'))
3721
self.assertEquals(expected_calls, test._counters['myhook'])
3723
def test_no_hook(self):
3724
self.assertHookCalls(0, 'no_hook')
3726
def test_run_hook_once(self):
3727
tt = features.testtools
3728
if tt.module.__version__ < (0, 9, 8):
3729
raise tests.TestSkipped('testtools-0.9.8 required for addDetail')
3730
self.assertHookCalls(1, 'run_hook_once')