2629
2610
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)
2632
2687
class TestSelftestFiltering(tests.TestCase):
2634
2689
def setUp(self):
2635
super(TestSelftestFiltering, self).setUp()
2690
tests.TestCase.setUp(self)
2636
2691
self.suite = TestUtil.TestSuite()
2637
2692
self.loader = TestUtil.TestLoader()
2638
2693
self.suite.addTest(self.loader.loadTestsFromModule(
3245
3301
self.assertContainsString(result.stream.getvalue(), "leaking threads")
3248
class TestPostMortemDebugging(tests.TestCase):
3249
"""Check post mortem debugging works when tests fail or error"""
3251
class TracebackRecordingResult(tests.ExtendedTestResult):
3253
tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
3254
self.postcode = None
3255
def _post_mortem(self, tb=None):
3256
"""Record the code object at the end of the current traceback"""
3257
tb = tb or sys.exc_info()[2]
3260
while next is not None:
3263
self.postcode = tb.tb_frame.f_code
3264
def report_error(self, test, err):
3266
def report_failure(self, test, err):
3269
def test_location_unittest_error(self):
3270
"""Needs right post mortem traceback with erroring unittest case"""
3271
class Test(unittest.TestCase):
3274
result = self.TracebackRecordingResult()
3276
self.assertEqual(result.postcode, Test.runTest.func_code)
3278
def test_location_unittest_failure(self):
3279
"""Needs right post mortem traceback with failing unittest case"""
3280
class Test(unittest.TestCase):
3282
raise self.failureException
3283
result = self.TracebackRecordingResult()
3285
self.assertEqual(result.postcode, Test.runTest.func_code)
3287
def test_location_bt_error(self):
3288
"""Needs right post mortem traceback with erroring bzrlib.tests case"""
3289
class Test(tests.TestCase):
3290
def test_error(self):
3292
result = self.TracebackRecordingResult()
3293
Test("test_error").run(result)
3294
self.assertEqual(result.postcode, Test.test_error.func_code)
3296
def test_location_bt_failure(self):
3297
"""Needs right post mortem traceback with failing bzrlib.tests case"""
3298
class Test(tests.TestCase):
3299
def test_failure(self):
3300
raise self.failureException
3301
result = self.TracebackRecordingResult()
3302
Test("test_failure").run(result)
3303
self.assertEqual(result.postcode, Test.test_failure.func_code)
3305
def test_env_var_triggers_post_mortem(self):
3306
"""Check pdb.post_mortem is called iff BZR_TEST_PDB is set"""
3308
result = tests.ExtendedTestResult(StringIO(), 0, 1)
3309
post_mortem_calls = []
3310
self.overrideAttr(pdb, "post_mortem", post_mortem_calls.append)
3311
self.overrideEnv('BZR_TEST_PDB', None)
3312
result._post_mortem(1)
3313
self.overrideEnv('BZR_TEST_PDB', 'on')
3314
result._post_mortem(2)
3315
self.assertEqual([2], post_mortem_calls)
3318
3304
class TestRunSuite(tests.TestCase):
3320
3306
def test_runner_class(self):
3331
3317
self.verbosity)
3332
3318
tests.run_suite(suite, runner_class=MyRunner, stream=StringIO())
3333
3319
self.assertLength(1, calls)
3336
class _Selftest(object):
3337
"""Mixin for tests needing full selftest output"""
3339
def _inject_stream_into_subunit(self, stream):
3340
"""To be overridden by subclasses that run tests out of process"""
3342
def _run_selftest(self, **kwargs):
3344
self._inject_stream_into_subunit(sio)
3345
tests.selftest(stream=sio, stop_on_failure=False, **kwargs)
3346
return sio.getvalue()
3349
class _ForkedSelftest(_Selftest):
3350
"""Mixin for tests needing full selftest output with forked children"""
3352
_test_needs_features = [features.subunit]
3354
def _inject_stream_into_subunit(self, stream):
3355
"""Monkey-patch subunit so the extra output goes to stream not stdout
3357
Some APIs need rewriting so this kind of bogus hackery can be replaced
3358
by passing the stream param from run_tests down into ProtocolTestCase.
3360
from subunit import ProtocolTestCase
3361
_original_init = ProtocolTestCase.__init__
3362
def _init_with_passthrough(self, *args, **kwargs):
3363
_original_init(self, *args, **kwargs)
3364
self._passthrough = stream
3365
self.overrideAttr(ProtocolTestCase, "__init__", _init_with_passthrough)
3367
def _run_selftest(self, **kwargs):
3368
# GZ 2011-05-26: Add a PosixSystem feature so this check can go away
3369
if getattr(os, "fork", None) is None:
3370
raise tests.TestNotApplicable("Platform doesn't support forking")
3371
# Make sure the fork code is actually invoked by claiming two cores
3372
self.overrideAttr(osutils, "local_concurrency", lambda: 2)
3373
kwargs.setdefault("suite_decorators", []).append(tests.fork_decorator)
3374
return super(_ForkedSelftest, self)._run_selftest(**kwargs)
3377
class TestParallelFork(_ForkedSelftest, tests.TestCase):
3378
"""Check operation of --parallel=fork selftest option"""
3380
def test_error_in_child_during_fork(self):
3381
"""Error in a forked child during test setup should get reported"""
3382
class Test(tests.TestCase):
3383
def testMethod(self):
3385
# We don't care what, just break something that a child will run
3386
self.overrideAttr(tests, "workaround_zealous_crypto_random", None)
3387
out = self._run_selftest(test_suite_factory=Test)
3388
# Lines from the tracebacks of the two child processes may be mixed
3389
# together due to the way subunit parses and forwards the streams,
3390
# so permit extra lines between each part of the error output.
3391
self.assertContainsRe(out,
3394
".+ in fork_for_tests\n"
3396
"\s*workaround_zealous_crypto_random\(\)\n"
3401
class TestUncollectedWarnings(_Selftest, tests.TestCase):
3402
"""Check a test case still alive after being run emits a warning"""
3404
class Test(tests.TestCase):
3405
def test_pass(self):
3407
def test_self_ref(self):
3408
self.also_self = self.test_self_ref
3409
def test_skip(self):
3410
self.skip("Don't need")
3412
def _get_suite(self):
3413
return TestUtil.TestSuite([
3414
self.Test("test_pass"),
3415
self.Test("test_self_ref"),
3416
self.Test("test_skip"),
3419
def _run_selftest_with_suite(self, **kwargs):
3420
old_flags = tests.selftest_debug_flags
3421
tests.selftest_debug_flags = old_flags.union(["uncollected_cases"])
3422
gc_on = gc.isenabled()
3426
output = self._run_selftest(test_suite_factory=self._get_suite,
3431
tests.selftest_debug_flags = old_flags
3432
self.assertNotContainsRe(output, "Uncollected test case.*test_pass")
3433
self.assertContainsRe(output, "Uncollected test case.*test_self_ref")
3436
def test_testsuite(self):
3437
self._run_selftest_with_suite()
3439
def test_pattern(self):
3440
out = self._run_selftest_with_suite(pattern="test_(?:pass|self_ref)$")
3441
self.assertNotContainsRe(out, "test_skip")
3443
def test_exclude_pattern(self):
3444
out = self._run_selftest_with_suite(exclude_pattern="test_skip$")
3445
self.assertNotContainsRe(out, "test_skip")
3447
def test_random_seed(self):
3448
self._run_selftest_with_suite(random_seed="now")
3450
def test_matching_tests_first(self):
3451
self._run_selftest_with_suite(matching_tests_first=True,
3452
pattern="test_self_ref$")
3454
def test_starting_with_and_exclude(self):
3455
out = self._run_selftest_with_suite(starting_with=["bt."],
3456
exclude_pattern="test_skip$")
3457
self.assertNotContainsRe(out, "test_skip")
3459
def test_additonal_decorator(self):
3460
out = self._run_selftest_with_suite(
3461
suite_decorators=[tests.TestDecorator])
3464
class TestUncollectedWarningsSubunit(TestUncollectedWarnings):
3465
"""Check warnings from tests staying alive are emitted with subunit"""
3467
_test_needs_features = [features.subunit]
3469
def _run_selftest_with_suite(self, **kwargs):
3470
return TestUncollectedWarnings._run_selftest_with_suite(self,
3471
runner_class=tests.SubUnitBzrRunner, **kwargs)
3474
class TestUncollectedWarningsForked(_ForkedSelftest, TestUncollectedWarnings):
3475
"""Check warnings from tests staying alive are emitted when forking"""
3478
class TestEnvironHandling(tests.TestCase):
3480
def test_overrideEnv_None_called_twice_doesnt_leak(self):
3481
self.assertFalse('MYVAR' in os.environ)
3482
self.overrideEnv('MYVAR', '42')
3483
# We use an embedded test to make sure we fix the _captureVar bug
3484
class Test(tests.TestCase):
3486
# The first call save the 42 value
3487
self.overrideEnv('MYVAR', None)
3488
self.assertEquals(None, os.environ.get('MYVAR'))
3489
# Make sure we can call it twice
3490
self.overrideEnv('MYVAR', None)
3491
self.assertEquals(None, os.environ.get('MYVAR'))
3493
result = tests.TextTestResult(output, 0, 1)
3494
Test('test_me').run(result)
3495
if not result.wasStrictlySuccessful():
3496
self.fail(output.getvalue())
3497
# We get our value back
3498
self.assertEquals('42', os.environ.get('MYVAR'))
3501
class TestIsolatedEnv(tests.TestCase):
3502
"""Test isolating tests from os.environ.
3504
Since we use tests that are already isolated from os.environ a bit of care
3505
should be taken when designing the tests to avoid bootstrap side-effects.
3506
The tests start an already clean os.environ which allow doing valid
3507
assertions about which variables are present or not and design tests around
3511
class ScratchMonkey(tests.TestCase):
3516
def test_basics(self):
3517
# Make sure we know the definition of BZR_HOME: not part of os.environ
3518
# for tests.TestCase.
3519
self.assertTrue('BZR_HOME' in tests.isolated_environ)
3520
self.assertEquals(None, tests.isolated_environ['BZR_HOME'])
3521
# Being part of isolated_environ, BZR_HOME should not appear here
3522
self.assertFalse('BZR_HOME' in os.environ)
3523
# Make sure we know the definition of LINES: part of os.environ for
3525
self.assertTrue('LINES' in tests.isolated_environ)
3526
self.assertEquals('25', tests.isolated_environ['LINES'])
3527
self.assertEquals('25', os.environ['LINES'])
3529
def test_injecting_unknown_variable(self):
3530
# BZR_HOME is known to be absent from os.environ
3531
test = self.ScratchMonkey('test_me')
3532
tests.override_os_environ(test, {'BZR_HOME': 'foo'})
3533
self.assertEquals('foo', os.environ['BZR_HOME'])
3534
tests.restore_os_environ(test)
3535
self.assertFalse('BZR_HOME' in os.environ)
3537
def test_injecting_known_variable(self):
3538
test = self.ScratchMonkey('test_me')
3539
# LINES is known to be present in os.environ
3540
tests.override_os_environ(test, {'LINES': '42'})
3541
self.assertEquals('42', os.environ['LINES'])
3542
tests.restore_os_environ(test)
3543
self.assertEquals('25', os.environ['LINES'])
3545
def test_deleting_variable(self):
3546
test = self.ScratchMonkey('test_me')
3547
# LINES is known to be present in os.environ
3548
tests.override_os_environ(test, {'LINES': None})
3549
self.assertTrue('LINES' not in os.environ)
3550
tests.restore_os_environ(test)
3551
self.assertEquals('25', os.environ['LINES'])
3554
class TestDocTestSuiteIsolation(tests.TestCase):
3555
"""Test that `tests.DocTestSuite` isolates doc tests from os.environ.
3557
Since tests.TestCase alreay provides an isolation from os.environ, we use
3558
the clean environment as a base for testing. To precisely capture the
3559
isolation provided by tests.DocTestSuite, we use doctest.DocTestSuite to
3562
We want to make sure `tests.DocTestSuite` respect `tests.isolated_environ`,
3563
not `os.environ` so each test overrides it to suit its needs.
3567
def get_doctest_suite_for_string(self, klass, string):
3568
class Finder(doctest.DocTestFinder):
3570
def find(*args, **kwargs):
3571
test = doctest.DocTestParser().get_doctest(
3572
string, {}, 'foo', 'foo.py', 0)
3575
suite = klass(test_finder=Finder())
3578
def run_doctest_suite_for_string(self, klass, string):
3579
suite = self.get_doctest_suite_for_string(klass, string)
3581
result = tests.TextTestResult(output, 0, 1)
3583
return result, output
3585
def assertDocTestStringSucceds(self, klass, string):
3586
result, output = self.run_doctest_suite_for_string(klass, string)
3587
if not result.wasStrictlySuccessful():
3588
self.fail(output.getvalue())
3590
def assertDocTestStringFails(self, klass, string):
3591
result, output = self.run_doctest_suite_for_string(klass, string)
3592
if result.wasStrictlySuccessful():
3593
self.fail(output.getvalue())
3595
def test_injected_variable(self):
3596
self.overrideAttr(tests, 'isolated_environ', {'LINES': '42'})
3599
>>> os.environ['LINES']
3602
# doctest.DocTestSuite fails as it sees '25'
3603
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3604
# tests.DocTestSuite sees '42'
3605
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
3607
def test_deleted_variable(self):
3608
self.overrideAttr(tests, 'isolated_environ', {'LINES': None})
3611
>>> os.environ.get('LINES')
3613
# doctest.DocTestSuite fails as it sees '25'
3614
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3615
# tests.DocTestSuite sees None
3616
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
3619
class TestSelftestExcludePatterns(tests.TestCase):
3622
super(TestSelftestExcludePatterns, self).setUp()
3623
self.overrideAttr(tests, 'test_suite', self.suite_factory)
3625
def suite_factory(self, keep_only=None, starting_with=None):
3626
"""A test suite factory with only a few tests."""
3627
class Test(tests.TestCase):
3629
# We don't need the full class path
3630
return self._testMethodName
3637
return TestUtil.TestSuite([Test("a"), Test("b"), Test("c")])
3639
def assertTestList(self, expected, *selftest_args):
3640
# We rely on setUp installing the right test suite factory so we can
3641
# test at the command level without loading the whole test suite
3642
out, err = self.run_bzr(('selftest', '--list') + selftest_args)
3643
actual = out.splitlines()
3644
self.assertEquals(expected, actual)
3646
def test_full_list(self):
3647
self.assertTestList(['a', 'b', 'c'])
3649
def test_single_exclude(self):
3650
self.assertTestList(['b', 'c'], '-x', 'a')
3652
def test_mutiple_excludes(self):
3653
self.assertTestList(['c'], '-x', 'a', '-x', 'b')
3656
class TestCounterHooks(tests.TestCase, SelfTestHelper):
3658
_test_needs_features = [features.subunit]
3661
super(TestCounterHooks, self).setUp()
3662
class Test(tests.TestCase):
3665
super(Test, self).setUp()
3666
self.hooks = hooks.Hooks()
3667
self.hooks.add_hook('myhook', 'Foo bar blah', (2,4))
3668
self.install_counter_hook(self.hooks, 'myhook')
3673
def run_hook_once(self):
3674
for hook in self.hooks['myhook']:
3677
self.test_class = Test
3679
def assertHookCalls(self, expected_calls, test_name):
3680
test = self.test_class(test_name)
3681
result = unittest.TestResult()
3683
self.assertTrue(hasattr(test, '_counters'))
3684
self.assertTrue(test._counters.has_key('myhook'))
3685
self.assertEquals(expected_calls, test._counters['myhook'])
3687
def test_no_hook(self):
3688
self.assertHookCalls(0, 'no_hook')
3690
def test_run_hook_once(self):
3691
tt = features.testtools
3692
if tt.module.__version__ < (0, 9, 8):
3693
raise tests.TestSkipped('testtools-0.9.8 required for addDetail')
3694
self.assertHookCalls(1, 'run_hook_once')