860
_get_test("test_xfail").run(result)
861
self.assertContainsRe(result_stream.getvalue(),
862
"\n\\S+\\.test_xfail\\s+XFAIL\\s+\\d+ms\n"
863
"\\s*(?:Text attachment: )?reason"
866
test = self.get_passing_test()
867
result.startTest(test)
868
prefix = len(result_stream.getvalue())
869
# the err parameter has the shape:
870
# (class, exception object, traceback)
871
# KnownFailures dont get their tracebacks shown though, so we
873
err = (tests.KnownFailure, tests.KnownFailure('foo'), None)
874
result.report_known_failure(test, err)
875
output = result_stream.getvalue()[prefix:]
876
lines = output.splitlines()
877
self.assertContainsRe(lines[0], r'XFAIL *\d+ms$')
878
if sys.version_info > (2, 7):
879
self.expectFailure("_ExpectedFailure on 2.7 loses the message",
880
self.assertNotEqual, lines[1], ' ')
881
self.assertEqual(lines[1], ' foo')
882
self.assertEqual(2, len(lines))
868
884
def get_passing_test(self):
869
885
"""Return a test object that can't be run usefully."""
1063
1089
self.expectFailure("No absolute truth", self.assertTrue, True)
1064
1090
runner = tests.TextTestRunner(stream=StringIO())
1065
1091
result = self.run_test_runner(runner, Test("test_truth"))
1066
if testtools_version[:3] <= (0, 9, 11):
1067
self.assertContainsRe(runner.stream.getvalue(),
1069
"FAIL: \\S+\.test_truth\n"
1072
"No absolute truth\n"
1075
"Ran 1 test in .*\n"
1077
"FAILED \\(failures=1\\)\n\\Z")
1079
self.assertContainsRe(runner.stream.getvalue(),
1081
"FAIL: \\S+\.test_truth\n"
1083
"Empty attachments:\n"
1086
"reason: {{{No absolute truth}}}\n"
1088
"Ran 1 test in .*\n"
1090
"FAILED \\(failures=1\\)\n\\Z")
1092
self.assertContainsRe(runner.stream.getvalue(),
1094
"FAIL: \\S+\.test_truth\n"
1097
"No absolute truth\n"
1100
"Ran 1 test in .*\n"
1102
"FAILED \\(failures=1\\)\n\\Z")
1092
1104
def test_result_decorator(self):
1093
1105
# decorate results
1674
1683
test.run(unittest.TestResult())
1675
1684
self.assertEqual('original', obj.test_attr)
1677
def test_recordCalls(self):
1678
from bzrlib.tests import test_selftest
1679
calls = self.recordCalls(
1680
test_selftest, '_add_numbers')
1681
self.assertEqual(test_selftest._add_numbers(2, 10),
1683
self.assertEquals(calls, [((2, 10), {})])
1686
def _add_numbers(a, b):
1690
class _MissingFeature(features.Feature):
1687
class _MissingFeature(tests.Feature):
1691
1688
def _probe(self):
1693
1690
missing_feature = _MissingFeature()
1744
1741
result = self._run_test('test_fail')
1745
1742
self.assertEqual(1, len(result.failures))
1746
1743
result_content = result.failures[0][1]
1747
if testtools_version < (0, 9, 12):
1748
self.assertContainsRe(result_content, 'Text attachment: log')
1744
self.assertContainsRe(result_content, 'Text attachment: log')
1749
1745
self.assertContainsRe(result_content, 'this was a failing test')
1751
1747
def test_error_has_log(self):
1752
1748
result = self._run_test('test_error')
1753
1749
self.assertEqual(1, len(result.errors))
1754
1750
result_content = result.errors[0][1]
1755
if testtools_version < (0, 9, 12):
1756
self.assertContainsRe(result_content, 'Text attachment: log')
1751
self.assertContainsRe(result_content, 'Text attachment: log')
1757
1752
self.assertContainsRe(result_content, 'this test errored')
1759
1754
def test_skip_has_no_log(self):
2512
2507
class TestStartBzrSubProcess(tests.TestCase):
2513
"""Stub test start_bzr_subprocess."""
2515
def _subprocess_log_cleanup(self):
2516
"""Inhibits the base version as we don't produce a log file."""
2509
def check_popen_state(self):
2510
"""Replace to make assertions when popen is called."""
2518
2512
def _popen(self, *args, **kwargs):
2519
"""Override the base version to record the command that is run.
2521
From there we can ensure it is correct without spawning a real process.
2513
"""Record the command that is run, so that we can ensure it is correct"""
2523
2514
self.check_popen_state()
2524
2515
self._popen_args = args
2525
2516
self._popen_kwargs = kwargs
2526
2517
raise _DontSpawnProcess()
2528
def check_popen_state(self):
2529
"""Replace to make assertions when popen is called."""
2531
2519
def test_run_bzr_subprocess_no_plugins(self):
2532
2520
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [])
2533
2521
command = self._popen_args[0]
2611
2605
self.assertEqual('bzr: interrupted\n', result[1])
2608
class TestFeature(tests.TestCase):
2610
def test_caching(self):
2611
"""Feature._probe is called by the feature at most once."""
2612
class InstrumentedFeature(tests.Feature):
2614
super(InstrumentedFeature, self).__init__()
2617
self.calls.append('_probe')
2619
feature = InstrumentedFeature()
2621
self.assertEqual(['_probe'], feature.calls)
2623
self.assertEqual(['_probe'], feature.calls)
2625
def test_named_str(self):
2626
"""Feature.__str__ should thunk to feature_name()."""
2627
class NamedFeature(tests.Feature):
2628
def feature_name(self):
2630
feature = NamedFeature()
2631
self.assertEqual('symlinks', str(feature))
2633
def test_default_str(self):
2634
"""Feature.__str__ should default to __class__.__name__."""
2635
class NamedFeature(tests.Feature):
2637
feature = NamedFeature()
2638
self.assertEqual('NamedFeature', str(feature))
2641
class TestUnavailableFeature(tests.TestCase):
2643
def test_access_feature(self):
2644
feature = tests.Feature()
2645
exception = tests.UnavailableFeature(feature)
2646
self.assertIs(feature, exception.args[0])
2649
simple_thunk_feature = tests._CompatabilityThunkFeature(
2650
deprecated_in((2, 1, 0)),
2651
'bzrlib.tests.test_selftest',
2652
'simple_thunk_feature','UnicodeFilename',
2653
replacement_module='bzrlib.tests'
2656
class Test_CompatibilityFeature(tests.TestCase):
2658
def test_does_thunk(self):
2659
res = self.callDeprecated(
2660
['bzrlib.tests.test_selftest.simple_thunk_feature was deprecated'
2661
' in version 2.1.0. Use bzrlib.tests.UnicodeFilename instead.'],
2662
simple_thunk_feature.available)
2663
self.assertEqual(tests.UnicodeFilename.available(), res)
2666
class TestModuleAvailableFeature(tests.TestCase):
2668
def test_available_module(self):
2669
feature = tests.ModuleAvailableFeature('bzrlib.tests')
2670
self.assertEqual('bzrlib.tests', feature.module_name)
2671
self.assertEqual('bzrlib.tests', str(feature))
2672
self.assertTrue(feature.available())
2673
self.assertIs(tests, feature.module)
2675
def test_unavailable_module(self):
2676
feature = tests.ModuleAvailableFeature('bzrlib.no_such_module_exists')
2677
self.assertEqual('bzrlib.no_such_module_exists', str(feature))
2678
self.assertFalse(feature.available())
2679
self.assertIs(None, feature.module)
2614
2682
class TestSelftestFiltering(tests.TestCase):
2616
2684
def setUp(self):
3315
3383
self.assertLength(1, calls)
3318
class TestUncollectedWarnings(tests.TestCase):
3319
"""Check a test case still alive after being run emits a warning"""
3321
class Test(tests.TestCase):
3322
def test_pass(self):
3324
def test_self_ref(self):
3325
self.also_self = self.test_self_ref
3326
def test_skip(self):
3327
self.skip("Don't need")
3329
def _get_suite(self):
3330
return TestUtil.TestSuite([
3331
self.Test("test_pass"),
3332
self.Test("test_self_ref"),
3333
self.Test("test_skip"),
3336
def _inject_stream_into_subunit(self, stream):
3337
"""To be overridden by subclasses that run tests out of process"""
3339
def _run_selftest_with_suite(self, **kwargs):
3341
self._inject_stream_into_subunit(sio)
3342
old_flags = tests.selftest_debug_flags
3343
tests.selftest_debug_flags = old_flags.union(["uncollected_cases"])
3344
gc_on = gc.isenabled()
3348
tests.selftest(test_suite_factory=self._get_suite, stream=sio,
3349
stop_on_failure=False, **kwargs)
3353
tests.selftest_debug_flags = old_flags
3354
output = sio.getvalue()
3355
self.assertNotContainsRe(output, "Uncollected test case.*test_pass")
3356
self.assertContainsRe(output, "Uncollected test case.*test_self_ref")
3359
def test_testsuite(self):
3360
self._run_selftest_with_suite()
3362
def test_pattern(self):
3363
out = self._run_selftest_with_suite(pattern="test_(?:pass|self_ref)$")
3364
self.assertNotContainsRe(out, "test_skip")
3366
def test_exclude_pattern(self):
3367
out = self._run_selftest_with_suite(exclude_pattern="test_skip$")
3368
self.assertNotContainsRe(out, "test_skip")
3370
def test_random_seed(self):
3371
self._run_selftest_with_suite(random_seed="now")
3373
def test_matching_tests_first(self):
3374
self._run_selftest_with_suite(matching_tests_first=True,
3375
pattern="test_self_ref$")
3377
def test_starting_with_and_exclude(self):
3378
out = self._run_selftest_with_suite(starting_with=["bt."],
3379
exclude_pattern="test_skip$")
3380
self.assertNotContainsRe(out, "test_skip")
3382
def test_additonal_decorator(self):
3383
out = self._run_selftest_with_suite(
3384
suite_decorators=[tests.TestDecorator])
3387
class TestUncollectedWarningsSubunit(TestUncollectedWarnings):
3388
"""Check warnings from tests staying alive are emitted with subunit"""
3390
_test_needs_features = [features.subunit]
3392
def _run_selftest_with_suite(self, **kwargs):
3393
return TestUncollectedWarnings._run_selftest_with_suite(self,
3394
runner_class=tests.SubUnitBzrRunner, **kwargs)
3397
class TestUncollectedWarningsForking(TestUncollectedWarnings):
3398
"""Check warnings from tests staying alive are emitted when forking"""
3400
_test_needs_features = [features.subunit]
3402
def _inject_stream_into_subunit(self, stream):
3403
"""Monkey-patch subunit so the extra output goes to stream not stdout
3405
Some APIs need rewriting so this kind of bogus hackery can be replaced
3406
by passing the stream param from run_tests down into ProtocolTestCase.
3408
from subunit import ProtocolTestCase
3409
_original_init = ProtocolTestCase.__init__
3410
def _init_with_passthrough(self, *args, **kwargs):
3411
_original_init(self, *args, **kwargs)
3412
self._passthrough = stream
3413
self.overrideAttr(ProtocolTestCase, "__init__", _init_with_passthrough)
3415
def _run_selftest_with_suite(self, **kwargs):
3416
# GZ 2011-05-26: Add a PosixSystem feature so this check can go away
3417
if getattr(os, "fork", None) is None:
3418
raise tests.TestNotApplicable("Platform doesn't support forking")
3419
# Make sure the fork code is actually invoked by claiming two cores
3420
self.overrideAttr(osutils, "local_concurrency", lambda: 2)
3421
kwargs.setdefault("suite_decorators", []).append(tests.fork_decorator)
3422
return TestUncollectedWarnings._run_selftest_with_suite(self, **kwargs)
3425
3386
class TestEnvironHandling(tests.TestCase):
3427
3388
def test_overrideEnv_None_called_twice_doesnt_leak(self):
3599
3560
def test_mutiple_excludes(self):
3600
3561
self.assertTestList(['c'], '-x', 'a', '-x', 'b')
3603
class TestCounterHooks(tests.TestCase, SelfTestHelper):
3605
_test_needs_features = [features.subunit]
3608
super(TestCounterHooks, self).setUp()
3609
class Test(tests.TestCase):
3612
super(Test, self).setUp()
3613
self.hooks = hooks.Hooks()
3614
self.hooks.add_hook('myhook', 'Foo bar blah', (2,4))
3615
self.install_counter_hook(self.hooks, 'myhook')
3620
def run_hook_once(self):
3621
for hook in self.hooks['myhook']:
3624
self.test_class = Test
3626
def assertHookCalls(self, expected_calls, test_name):
3627
test = self.test_class(test_name)
3628
result = unittest.TestResult()
3630
self.assertTrue(hasattr(test, '_counters'))
3631
self.assertTrue(test._counters.has_key('myhook'))
3632
self.assertEquals(expected_calls, test._counters['myhook'])
3634
def test_no_hook(self):
3635
self.assertHookCalls(0, 'no_hook')
3637
def test_run_hook_once(self):
3638
tt = features.testtools
3639
if tt.module.__version__ < (0, 9, 8):
3640
raise tests.TestSkipped('testtools-0.9.8 required for addDetail')
3641
self.assertHookCalls(1, 'run_hook_once')