772
764
self.check_timing(ShortDelayTestCase('test_short_delay'),
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)
772
def test_assigned_benchmark_file_stores_date(self):
773
self._patch_get_bzr_source_tree()
775
result = bzrlib.tests.TextTestResult(self._log_file,
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.]+")
786
def test_benchhistory_records_test_times(self):
787
self._patch_get_bzr_source_tree()
788
result_stream = StringIO()
789
result = bzrlib.tests.TextTestResult(
793
bench_history=result_stream
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")
775
807
def _time_hello_world_encoding(self):
776
808
"""Profile two sleep calls
2534
2531
def test_allow_plugins(self):
2535
2532
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2537
2534
command = self._popen_args[0]
2538
2535
self.assertEqual([], command[2:])
2540
2537
def test_set_env(self):
2541
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2538
self.failIf('EXISTANT_ENV_VAR' in os.environ)
2542
2539
# set in the child
2543
2540
def check_environment():
2544
2541
self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2545
2542
self.check_popen_state = check_environment
2546
2543
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2547
env_changes={'EXISTANT_ENV_VAR':'set variable'})
2544
env_changes={'EXISTANT_ENV_VAR':'set variable'})
2548
2545
# not set in theparent
2549
2546
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2551
2548
def test_run_bzr_subprocess_env_del(self):
2552
2549
"""run_bzr_subprocess can remove environment variables too."""
2553
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2550
self.failIf('EXISTANT_ENV_VAR' in os.environ)
2554
2551
def check_environment():
2555
2552
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2556
2553
os.environ['EXISTANT_ENV_VAR'] = 'set variable'
2557
2554
self.check_popen_state = check_environment
2558
2555
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2559
env_changes={'EXISTANT_ENV_VAR':None})
2556
env_changes={'EXISTANT_ENV_VAR':None})
2560
2557
# Still set in parent
2561
2558
self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2562
2559
del os.environ['EXISTANT_ENV_VAR']
2564
2561
def test_env_del_missing(self):
2565
self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
2562
self.failIf('NON_EXISTANT_ENV_VAR' in os.environ)
2566
2563
def check_environment():
2567
2564
self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
2568
2565
self.check_popen_state = check_environment
2569
2566
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2570
env_changes={'NON_EXISTANT_ENV_VAR':None})
2567
env_changes={'NON_EXISTANT_ENV_VAR':None})
2572
2569
def test_working_dir(self):
2573
2570
"""Test that we can specify the working dir for the child"""
3297
3301
self.assertContainsString(result.stream.getvalue(), "leaking threads")
3300
class TestPostMortemDebugging(tests.TestCase):
3301
"""Check post mortem debugging works when tests fail or error"""
3303
class TracebackRecordingResult(tests.ExtendedTestResult):
3305
tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
3306
self.postcode = None
3307
def _post_mortem(self, tb=None):
3308
"""Record the code object at the end of the current traceback"""
3309
tb = tb or sys.exc_info()[2]
3312
while next is not None:
3315
self.postcode = tb.tb_frame.f_code
3316
def report_error(self, test, err):
3318
def report_failure(self, test, err):
3321
def test_location_unittest_error(self):
3322
"""Needs right post mortem traceback with erroring unittest case"""
3323
class Test(unittest.TestCase):
3326
result = self.TracebackRecordingResult()
3328
self.assertEqual(result.postcode, Test.runTest.func_code)
3330
def test_location_unittest_failure(self):
3331
"""Needs right post mortem traceback with failing unittest case"""
3332
class Test(unittest.TestCase):
3334
raise self.failureException
3335
result = self.TracebackRecordingResult()
3337
self.assertEqual(result.postcode, Test.runTest.func_code)
3339
def test_location_bt_error(self):
3340
"""Needs right post mortem traceback with erroring bzrlib.tests case"""
3341
class Test(tests.TestCase):
3342
def test_error(self):
3344
result = self.TracebackRecordingResult()
3345
Test("test_error").run(result)
3346
self.assertEqual(result.postcode, Test.test_error.func_code)
3348
def test_location_bt_failure(self):
3349
"""Needs right post mortem traceback with failing bzrlib.tests case"""
3350
class Test(tests.TestCase):
3351
def test_failure(self):
3352
raise self.failureException
3353
result = self.TracebackRecordingResult()
3354
Test("test_failure").run(result)
3355
self.assertEqual(result.postcode, Test.test_failure.func_code)
3357
def test_env_var_triggers_post_mortem(self):
3358
"""Check pdb.post_mortem is called iff BZR_TEST_PDB is set"""
3360
result = tests.ExtendedTestResult(StringIO(), 0, 1)
3361
post_mortem_calls = []
3362
self.overrideAttr(pdb, "post_mortem", post_mortem_calls.append)
3363
self.overrideEnv('BZR_TEST_PDB', None)
3364
result._post_mortem(1)
3365
self.overrideEnv('BZR_TEST_PDB', 'on')
3366
result._post_mortem(2)
3367
self.assertEqual([2], post_mortem_calls)
3370
3304
class TestRunSuite(tests.TestCase):
3372
3306
def test_runner_class(self):
3383
3317
self.verbosity)
3384
3318
tests.run_suite(suite, runner_class=MyRunner, stream=StringIO())
3385
3319
self.assertLength(1, calls)
3388
class TestEnvironHandling(tests.TestCase):
3390
def test_overrideEnv_None_called_twice_doesnt_leak(self):
3391
self.assertFalse('MYVAR' in os.environ)
3392
self.overrideEnv('MYVAR', '42')
3393
# We use an embedded test to make sure we fix the _captureVar bug
3394
class Test(tests.TestCase):
3396
# The first call save the 42 value
3397
self.overrideEnv('MYVAR', None)
3398
self.assertEquals(None, os.environ.get('MYVAR'))
3399
# Make sure we can call it twice
3400
self.overrideEnv('MYVAR', None)
3401
self.assertEquals(None, os.environ.get('MYVAR'))
3403
result = tests.TextTestResult(output, 0, 1)
3404
Test('test_me').run(result)
3405
if not result.wasStrictlySuccessful():
3406
self.fail(output.getvalue())
3407
# We get our value back
3408
self.assertEquals('42', os.environ.get('MYVAR'))
3411
class TestIsolatedEnv(tests.TestCase):
3412
"""Test isolating tests from os.environ.
3414
Since we use tests that are already isolated from os.environ a bit of care
3415
should be taken when designing the tests to avoid bootstrap side-effects.
3416
The tests start an already clean os.environ which allow doing valid
3417
assertions about which variables are present or not and design tests around
3421
class ScratchMonkey(tests.TestCase):
3426
def test_basics(self):
3427
# Make sure we know the definition of BZR_HOME: not part of os.environ
3428
# for tests.TestCase.
3429
self.assertTrue('BZR_HOME' in tests.isolated_environ)
3430
self.assertEquals(None, tests.isolated_environ['BZR_HOME'])
3431
# Being part of isolated_environ, BZR_HOME should not appear here
3432
self.assertFalse('BZR_HOME' in os.environ)
3433
# Make sure we know the definition of LINES: part of os.environ for
3435
self.assertTrue('LINES' in tests.isolated_environ)
3436
self.assertEquals('25', tests.isolated_environ['LINES'])
3437
self.assertEquals('25', os.environ['LINES'])
3439
def test_injecting_unknown_variable(self):
3440
# BZR_HOME is known to be absent from os.environ
3441
test = self.ScratchMonkey('test_me')
3442
tests.override_os_environ(test, {'BZR_HOME': 'foo'})
3443
self.assertEquals('foo', os.environ['BZR_HOME'])
3444
tests.restore_os_environ(test)
3445
self.assertFalse('BZR_HOME' in os.environ)
3447
def test_injecting_known_variable(self):
3448
test = self.ScratchMonkey('test_me')
3449
# LINES is known to be present in os.environ
3450
tests.override_os_environ(test, {'LINES': '42'})
3451
self.assertEquals('42', os.environ['LINES'])
3452
tests.restore_os_environ(test)
3453
self.assertEquals('25', os.environ['LINES'])
3455
def test_deleting_variable(self):
3456
test = self.ScratchMonkey('test_me')
3457
# LINES is known to be present in os.environ
3458
tests.override_os_environ(test, {'LINES': None})
3459
self.assertTrue('LINES' not in os.environ)
3460
tests.restore_os_environ(test)
3461
self.assertEquals('25', os.environ['LINES'])
3464
class TestDocTestSuiteIsolation(tests.TestCase):
3465
"""Test that `tests.DocTestSuite` isolates doc tests from os.environ.
3467
Since tests.TestCase alreay provides an isolation from os.environ, we use
3468
the clean environment as a base for testing. To precisely capture the
3469
isolation provided by tests.DocTestSuite, we use doctest.DocTestSuite to
3472
We want to make sure `tests.DocTestSuite` respect `tests.isolated_environ`,
3473
not `os.environ` so each test overrides it to suit its needs.
3477
def get_doctest_suite_for_string(self, klass, string):
3478
class Finder(doctest.DocTestFinder):
3480
def find(*args, **kwargs):
3481
test = doctest.DocTestParser().get_doctest(
3482
string, {}, 'foo', 'foo.py', 0)
3485
suite = klass(test_finder=Finder())
3488
def run_doctest_suite_for_string(self, klass, string):
3489
suite = self.get_doctest_suite_for_string(klass, string)
3491
result = tests.TextTestResult(output, 0, 1)
3493
return result, output
3495
def assertDocTestStringSucceds(self, klass, string):
3496
result, output = self.run_doctest_suite_for_string(klass, string)
3497
if not result.wasStrictlySuccessful():
3498
self.fail(output.getvalue())
3500
def assertDocTestStringFails(self, klass, string):
3501
result, output = self.run_doctest_suite_for_string(klass, string)
3502
if result.wasStrictlySuccessful():
3503
self.fail(output.getvalue())
3505
def test_injected_variable(self):
3506
self.overrideAttr(tests, 'isolated_environ', {'LINES': '42'})
3509
>>> os.environ['LINES']
3512
# doctest.DocTestSuite fails as it sees '25'
3513
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3514
# tests.DocTestSuite sees '42'
3515
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
3517
def test_deleted_variable(self):
3518
self.overrideAttr(tests, 'isolated_environ', {'LINES': None})
3521
>>> os.environ.get('LINES')
3523
# doctest.DocTestSuite fails as it sees '25'
3524
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3525
# tests.DocTestSuite sees None
3526
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
3529
class TestSelftestExcludePatterns(tests.TestCase):
3532
super(TestSelftestExcludePatterns, self).setUp()
3533
self.overrideAttr(tests, 'test_suite', self.suite_factory)
3535
def suite_factory(self, keep_only=None, starting_with=None):
3536
"""A test suite factory with only a few tests."""
3537
class Test(tests.TestCase):
3539
# We don't need the full class path
3540
return self._testMethodName
3547
return TestUtil.TestSuite([Test("a"), Test("b"), Test("c")])
3549
def assertTestList(self, expected, *selftest_args):
3550
# We rely on setUp installing the right test suite factory so we can
3551
# test at the command level without loading the whole test suite
3552
out, err = self.run_bzr(('selftest', '--list') + selftest_args)
3553
actual = out.splitlines()
3554
self.assertEquals(expected, actual)
3556
def test_full_list(self):
3557
self.assertTestList(['a', 'b', 'c'])
3559
def test_single_exclude(self):
3560
self.assertTestList(['b', 'c'], '-x', 'a')
3562
def test_mutiple_excludes(self):
3563
self.assertTestList(['c'], '-x', 'a', '-x', 'b')
3566
class TestCounterHooks(tests.TestCase, SelfTestHelper):
3568
_test_needs_features = [features.subunit]
3571
super(TestCounterHooks, self).setUp()
3572
class Test(tests.TestCase):
3575
super(Test, self).setUp()
3576
self.hooks = hooks.Hooks()
3577
self.hooks.add_hook('myhook', 'Foo bar blah', (2,4))
3578
self.install_counter_hook(self.hooks, 'myhook')
3583
def run_hook_once(self):
3584
for hook in self.hooks['myhook']:
3587
self.test_class = Test
3589
def assertHookCalls(self, expected_calls, test_name):
3590
test = self.test_class(test_name)
3591
result = unittest.TestResult()
3593
self.assertTrue(hasattr(test, '_counters'))
3594
self.assertTrue(test._counters.has_key('myhook'))
3595
self.assertEquals(expected_calls, test._counters['myhook'])
3597
def test_no_hook(self):
3598
self.assertHookCalls(0, 'no_hook')
3600
def test_run_hook_once(self):
3601
tt = features.testtools
3602
if tt.module.__version__ < (0, 9, 8):
3603
raise tests.TestSkipped('testtools-0.9.8 required for addDetail')
3604
self.assertHookCalls(1, 'run_hook_once')