326
312
from bzrlib.tests.per_interrepository import make_scenarios
329
formats = [("C0", "C1", "C2"), ("D0", "D1", "D2")]
315
formats = [("C0", "C1", "C2", "C3"), ("D0", "D1", "D2", "D3")]
330
316
scenarios = make_scenarios(server1, server2, formats)
331
317
self.assertEqual([
333
319
{'repository_format': 'C1',
334
320
'repository_format_to': 'C2',
335
321
'transport_readonly_server': 'b',
336
'transport_server': 'a'}),
322
'transport_server': 'a',
323
'extra_setup': 'C3'}),
338
325
{'repository_format': 'D1',
339
326
'repository_format_to': 'D2',
340
327
'transport_readonly_server': 'b',
341
'transport_server': 'a'})],
328
'transport_server': 'a',
329
'extra_setup': 'D3'})],
847
834
self.assertContainsRe(output,
848
835
r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
837
def test_uses_time_from_testtools(self):
838
"""Test case timings in verbose results should use testtools times"""
840
class TimeAddedVerboseTestResult(tests.VerboseTestResult):
841
def startTest(self, test):
842
self.time(datetime.datetime.utcfromtimestamp(1.145))
843
super(TimeAddedVerboseTestResult, self).startTest(test)
844
def addSuccess(self, test):
845
self.time(datetime.datetime.utcfromtimestamp(51.147))
846
super(TimeAddedVerboseTestResult, self).addSuccess(test)
847
def report_tests_starting(self): pass
849
self.get_passing_test().run(TimeAddedVerboseTestResult(sio, 0, 2))
850
self.assertEndsWith(sio.getvalue(), "OK 50002ms\n")
850
852
def test_known_failure(self):
851
853
"""A KnownFailure being raised should trigger several result actions."""
852
854
class InstrumentedTestResult(tests.ExtendedTestResult):
1234
1236
self.assertContainsRe(output_string, "--date [0-9.]+")
1235
1237
self.assertLength(1, self._get_source_tree_calls)
1239
def test_verbose_test_count(self):
1240
"""A verbose test run reports the right test count at the start"""
1241
suite = TestUtil.TestSuite([
1242
unittest.FunctionTestCase(lambda:None),
1243
unittest.FunctionTestCase(lambda:None)])
1244
self.assertEqual(suite.countTestCases(), 2)
1246
runner = tests.TextTestRunner(stream=stream, verbosity=2)
1247
# Need to use the CountingDecorator as that's what sets num_tests
1248
result = self.run_test_runner(runner, tests.CountingDecorator(suite))
1249
self.assertStartsWith(stream.getvalue(), "running 2 tests")
1237
1251
def test_startTestRun(self):
1238
1252
"""run should call result.startTestRun()"""
1240
class LoggingDecorator(tests.ForwardingResult):
1254
class LoggingDecorator(ExtendedToOriginalDecorator):
1241
1255
def startTestRun(self):
1242
tests.ForwardingResult.startTestRun(self)
1256
ExtendedToOriginalDecorator.startTestRun(self)
1243
1257
calls.append('startTestRun')
1244
1258
test = unittest.FunctionTestCase(lambda:None)
1245
1259
stream = StringIO()
1676
1707
self.assertEqual('original', obj.test_attr)
1710
class _MissingFeature(tests.Feature):
1713
missing_feature = _MissingFeature()
1716
def _get_test(name):
1717
"""Get an instance of a specific example test.
1719
We protect this in a function so that they don't auto-run in the test
1723
class ExampleTests(tests.TestCase):
1725
def test_fail(self):
1726
mutter('this was a failing test')
1727
self.fail('this test will fail')
1729
def test_error(self):
1730
mutter('this test errored')
1731
raise RuntimeError('gotcha')
1733
def test_missing_feature(self):
1734
mutter('missing the feature')
1735
self.requireFeature(missing_feature)
1737
def test_skip(self):
1738
mutter('this test will be skipped')
1739
raise tests.TestSkipped('reason')
1741
def test_success(self):
1742
mutter('this test succeeds')
1744
def test_xfail(self):
1745
mutter('test with expected failure')
1746
self.knownFailure('this_fails')
1748
def test_unexpected_success(self):
1749
mutter('test with unexpected success')
1750
self.expectFailure('should_fail', lambda: None)
1752
return ExampleTests(name)
1755
class TestTestCaseLogDetails(tests.TestCase):
1757
def _run_test(self, test_name):
1758
test = _get_test(test_name)
1759
result = testtools.TestResult()
1763
def test_fail_has_log(self):
1764
result = self._run_test('test_fail')
1765
self.assertEqual(1, len(result.failures))
1766
result_content = result.failures[0][1]
1767
self.assertContainsRe(result_content, 'Text attachment: log')
1768
self.assertContainsRe(result_content, 'this was a failing test')
1770
def test_error_has_log(self):
1771
result = self._run_test('test_error')
1772
self.assertEqual(1, len(result.errors))
1773
result_content = result.errors[0][1]
1774
self.assertContainsRe(result_content, 'Text attachment: log')
1775
self.assertContainsRe(result_content, 'this test errored')
1777
def test_skip_has_no_log(self):
1778
result = self._run_test('test_skip')
1779
self.assertEqual(['reason'], result.skip_reasons.keys())
1780
skips = result.skip_reasons['reason']
1781
self.assertEqual(1, len(skips))
1783
self.assertFalse('log' in test.getDetails())
1785
def test_missing_feature_has_no_log(self):
1786
# testtools doesn't know about addNotSupported, so it just gets
1787
# considered as a skip
1788
result = self._run_test('test_missing_feature')
1789
self.assertEqual([missing_feature], result.skip_reasons.keys())
1790
skips = result.skip_reasons[missing_feature]
1791
self.assertEqual(1, len(skips))
1793
self.assertFalse('log' in test.getDetails())
1795
def test_xfail_has_no_log(self):
1796
result = self._run_test('test_xfail')
1797
self.assertEqual(1, len(result.expectedFailures))
1798
result_content = result.expectedFailures[0][1]
1799
self.assertNotContainsRe(result_content, 'Text attachment: log')
1800
self.assertNotContainsRe(result_content, 'test with expected failure')
1802
def test_unexpected_success_has_log(self):
1803
result = self._run_test('test_unexpected_success')
1804
self.assertEqual(1, len(result.unexpectedSuccesses))
1805
# Inconsistency, unexpectedSuccesses is a list of tests,
1806
# expectedFailures is a list of reasons?
1807
test = result.unexpectedSuccesses[0]
1808
details = test.getDetails()
1809
self.assertTrue('log' in details)
1812
class TestTestCloning(tests.TestCase):
1813
"""Tests that test cloning of TestCases (as used by multiply_tests)."""
1815
def test_cloned_testcase_does_not_share_details(self):
1816
"""A TestCase cloned with clone_test does not share mutable attributes
1817
such as details or cleanups.
1819
class Test(tests.TestCase):
1821
self.addDetail('foo', Content('text/plain', lambda: 'foo'))
1822
orig_test = Test('test_foo')
1823
cloned_test = tests.clone_test(orig_test, orig_test.id() + '(cloned)')
1824
orig_test.run(unittest.TestResult())
1825
self.assertEqual('foo', orig_test.getDetails()['foo'].iter_bytes())
1826
self.assertEqual(None, cloned_test.getDetails().get('foo'))
1828
def test_double_apply_scenario_preserves_first_scenario(self):
1829
"""Applying two levels of scenarios to a test preserves the attributes
1830
added by both scenarios.
1832
class Test(tests.TestCase):
1835
test = Test('test_foo')
1836
scenarios_x = [('x=1', {'x': 1}), ('x=2', {'x': 2})]
1837
scenarios_y = [('y=1', {'y': 1}), ('y=2', {'y': 2})]
1838
suite = tests.multiply_tests(test, scenarios_x, unittest.TestSuite())
1839
suite = tests.multiply_tests(suite, scenarios_y, unittest.TestSuite())
1840
all_tests = list(tests.iter_suite_tests(suite))
1841
self.assertLength(4, all_tests)
1842
all_xys = sorted((t.x, t.y) for t in all_tests)
1843
self.assertEqual([(1, 1), (1, 2), (2, 1), (2, 2)], all_xys)
1679
1846
# NB: Don't delete this; it's not actually from 0.11!
1680
1847
@deprecated_function(deprecated_in((0, 11, 0)))
1681
1848
def sample_deprecated_function():
1992
2156
load_list='missing file name', list_only=True)
2159
class TestSubunitLogDetails(tests.TestCase, SelfTestHelper):
2161
_test_needs_features = [features.subunit]
2163
def run_subunit_stream(self, test_name):
2164
from subunit import ProtocolTestCase
2166
return TestUtil.TestSuite([_get_test(test_name)])
2167
stream = self.run_selftest(runner_class=tests.SubUnitBzrRunner,
2168
test_suite_factory=factory)
2169
test = ProtocolTestCase(stream)
2170
result = testtools.TestResult()
2172
content = stream.getvalue()
2173
return content, result
2175
def test_fail_has_log(self):
2176
content, result = self.run_subunit_stream('test_fail')
2177
self.assertEqual(1, len(result.failures))
2178
self.assertContainsRe(content, '(?m)^log$')
2179
self.assertContainsRe(content, 'this test will fail')
2181
def test_error_has_log(self):
2182
content, result = self.run_subunit_stream('test_error')
2183
self.assertContainsRe(content, '(?m)^log$')
2184
self.assertContainsRe(content, 'this test errored')
2186
def test_skip_has_no_log(self):
2187
content, result = self.run_subunit_stream('test_skip')
2188
self.assertNotContainsRe(content, '(?m)^log$')
2189
self.assertNotContainsRe(content, 'this test will be skipped')
2190
self.assertEqual(['reason'], result.skip_reasons.keys())
2191
skips = result.skip_reasons['reason']
2192
self.assertEqual(1, len(skips))
2194
# RemotedTestCase doesn't preserve the "details"
2195
## self.assertFalse('log' in test.getDetails())
2197
def test_missing_feature_has_no_log(self):
2198
content, result = self.run_subunit_stream('test_missing_feature')
2199
self.assertNotContainsRe(content, '(?m)^log$')
2200
self.assertNotContainsRe(content, 'missing the feature')
2201
self.assertEqual(['_MissingFeature\n'], result.skip_reasons.keys())
2202
skips = result.skip_reasons['_MissingFeature\n']
2203
self.assertEqual(1, len(skips))
2205
# RemotedTestCase doesn't preserve the "details"
2206
## self.assertFalse('log' in test.getDetails())
2208
def test_xfail_has_no_log(self):
2209
content, result = self.run_subunit_stream('test_xfail')
2210
self.assertNotContainsRe(content, '(?m)^log$')
2211
self.assertNotContainsRe(content, 'test with expected failure')
2212
self.assertEqual(1, len(result.expectedFailures))
2213
result_content = result.expectedFailures[0][1]
2214
self.assertNotContainsRe(result_content, 'Text attachment: log')
2215
self.assertNotContainsRe(result_content, 'test with expected failure')
2217
def test_unexpected_success_has_log(self):
2218
content, result = self.run_subunit_stream('test_unexpected_success')
2219
self.assertContainsRe(content, '(?m)^log$')
2220
self.assertContainsRe(content, 'test with unexpected success')
2221
self.expectFailure('subunit treats "unexpectedSuccess"'
2222
' as a plain success',
2223
self.assertEqual, 1, len(result.unexpectedSuccesses))
2224
self.assertEqual(1, len(result.unexpectedSuccesses))
2225
test = result.unexpectedSuccesses[0]
2226
# RemotedTestCase doesn't preserve the "details"
2227
## self.assertTrue('log' in test.getDetails())
2229
def test_success_has_no_log(self):
2230
content, result = self.run_subunit_stream('test_success')
2231
self.assertEqual(1, result.testsRun)
2232
self.assertNotContainsRe(content, '(?m)^log$')
2233
self.assertNotContainsRe(content, 'this test succeeds')
1995
2236
class TestRunBzr(tests.TestCase):
3074
3314
self.assertContainsString(result.stream.getvalue(), "leaking threads")
3317
class TestPostMortemDebugging(tests.TestCase):
3318
"""Check post mortem debugging works when tests fail or error"""
3320
class TracebackRecordingResult(tests.ExtendedTestResult):
3322
tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
3323
self.postcode = None
3324
def _post_mortem(self, tb=None):
3325
"""Record the code object at the end of the current traceback"""
3326
tb = tb or sys.exc_info()[2]
3329
while next is not None:
3332
self.postcode = tb.tb_frame.f_code
3333
def report_error(self, test, err):
3335
def report_failure(self, test, err):
3338
def test_location_unittest_error(self):
3339
"""Needs right post mortem traceback with erroring unittest case"""
3340
class Test(unittest.TestCase):
3343
result = self.TracebackRecordingResult()
3345
self.assertEqual(result.postcode, Test.runTest.func_code)
3347
def test_location_unittest_failure(self):
3348
"""Needs right post mortem traceback with failing unittest case"""
3349
class Test(unittest.TestCase):
3351
raise self.failureException
3352
result = self.TracebackRecordingResult()
3354
self.assertEqual(result.postcode, Test.runTest.func_code)
3356
def test_location_bt_error(self):
3357
"""Needs right post mortem traceback with erroring bzrlib.tests case"""
3358
class Test(tests.TestCase):
3359
def test_error(self):
3361
result = self.TracebackRecordingResult()
3362
Test("test_error").run(result)
3363
self.assertEqual(result.postcode, Test.test_error.func_code)
3365
def test_location_bt_failure(self):
3366
"""Needs right post mortem traceback with failing bzrlib.tests case"""
3367
class Test(tests.TestCase):
3368
def test_failure(self):
3369
raise self.failureException
3370
result = self.TracebackRecordingResult()
3371
Test("test_failure").run(result)
3372
self.assertEqual(result.postcode, Test.test_failure.func_code)
3374
def test_env_var_triggers_post_mortem(self):
3375
"""Check pdb.post_mortem is called iff BZR_TEST_PDB is set"""
3377
result = tests.ExtendedTestResult(StringIO(), 0, 1)
3378
post_mortem_calls = []
3379
self.overrideAttr(pdb, "post_mortem", post_mortem_calls.append)
3380
self.overrideEnv('BZR_TEST_PDB', None)
3381
result._post_mortem(1)
3382
self.overrideEnv('BZR_TEST_PDB', 'on')
3383
result._post_mortem(2)
3384
self.assertEqual([2], post_mortem_calls)
3077
3387
class TestRunSuite(tests.TestCase):
3079
3389
def test_runner_class(self):
3090
3400
self.verbosity)
3091
3401
tests.run_suite(suite, runner_class=MyRunner, stream=StringIO())
3092
3402
self.assertLength(1, calls)
3405
class TestEnvironHandling(tests.TestCase):
3407
def test_overrideEnv_None_called_twice_doesnt_leak(self):
3408
self.failIf('MYVAR' in os.environ)
3409
self.overrideEnv('MYVAR', '42')
3410
# We use an embedded test to make sure we fix the _captureVar bug
3411
class Test(tests.TestCase):
3413
# The first call save the 42 value
3414
self.overrideEnv('MYVAR', None)
3415
self.assertEquals(None, os.environ.get('MYVAR'))
3416
# Make sure we can call it twice
3417
self.overrideEnv('MYVAR', None)
3418
self.assertEquals(None, os.environ.get('MYVAR'))
3420
result = tests.TextTestResult(output, 0, 1)
3421
Test('test_me').run(result)
3422
if not result.wasStrictlySuccessful():
3423
self.fail(output.getvalue())
3424
# We get our value back
3425
self.assertEquals('42', os.environ.get('MYVAR'))
3428
class TestIsolatedEnv(tests.TestCase):
3429
"""Test isolating tests from os.environ.
3431
Since we use tests that are already isolated from os.environ a bit of care
3432
should be taken when designing the tests to avoid bootstrap side-effects.
3433
The tests start an already clean os.environ which allow doing valid
3434
assertions about which variables are present or not and design tests around
3438
class ScratchMonkey(tests.TestCase):
3443
def test_basics(self):
3444
# Make sure we know the definition of BZR_HOME: not part of os.environ
3445
# for tests.TestCase.
3446
self.assertTrue('BZR_HOME' in tests.isolated_environ)
3447
self.assertEquals(None, tests.isolated_environ['BZR_HOME'])
3448
# Being part of isolated_environ, BZR_HOME should not appear here
3449
self.assertFalse('BZR_HOME' in os.environ)
3450
# Make sure we know the definition of LINES: part of os.environ for
3452
self.assertTrue('LINES' in tests.isolated_environ)
3453
self.assertEquals('25', tests.isolated_environ['LINES'])
3454
self.assertEquals('25', os.environ['LINES'])
3456
def test_injecting_unknown_variable(self):
3457
# BZR_HOME is known to be absent from os.environ
3458
test = self.ScratchMonkey('test_me')
3459
tests.override_os_environ(test, {'BZR_HOME': 'foo'})
3460
self.assertEquals('foo', os.environ['BZR_HOME'])
3461
tests.restore_os_environ(test)
3462
self.assertFalse('BZR_HOME' in os.environ)
3464
def test_injecting_known_variable(self):
3465
test = self.ScratchMonkey('test_me')
3466
# LINES is known to be present in os.environ
3467
tests.override_os_environ(test, {'LINES': '42'})
3468
self.assertEquals('42', os.environ['LINES'])
3469
tests.restore_os_environ(test)
3470
self.assertEquals('25', os.environ['LINES'])
3472
def test_deleting_variable(self):
3473
test = self.ScratchMonkey('test_me')
3474
# LINES is known to be present in os.environ
3475
tests.override_os_environ(test, {'LINES': None})
3476
self.assertTrue('LINES' not in os.environ)
3477
tests.restore_os_environ(test)
3478
self.assertEquals('25', os.environ['LINES'])
3481
class TestDocTestSuiteIsolation(tests.TestCase):
3482
"""Test that `tests.DocTestSuite` isolates doc tests from os.environ.
3484
Since tests.TestCase alreay provides an isolation from os.environ, we use
3485
the clean environment as a base for testing. To precisely capture the
3486
isolation provided by tests.DocTestSuite, we use doctest.DocTestSuite to
3489
We want to make sure `tests.DocTestSuite` respect `tests.isolated_environ`,
3490
not `os.environ` so each test overrides it to suit its needs.
3494
def get_doctest_suite_for_string(self, klass, string):
3495
class Finder(doctest.DocTestFinder):
3497
def find(*args, **kwargs):
3498
test = doctest.DocTestParser().get_doctest(
3499
string, {}, 'foo', 'foo.py', 0)
3502
suite = klass(test_finder=Finder())
3505
def run_doctest_suite_for_string(self, klass, string):
3506
suite = self.get_doctest_suite_for_string(klass, string)
3508
result = tests.TextTestResult(output, 0, 1)
3510
return result, output
3512
def assertDocTestStringSucceds(self, klass, string):
3513
result, output = self.run_doctest_suite_for_string(klass, string)
3514
if not result.wasStrictlySuccessful():
3515
self.fail(output.getvalue())
3517
def assertDocTestStringFails(self, klass, string):
3518
result, output = self.run_doctest_suite_for_string(klass, string)
3519
if result.wasStrictlySuccessful():
3520
self.fail(output.getvalue())
3522
def test_injected_variable(self):
3523
self.overrideAttr(tests, 'isolated_environ', {'LINES': '42'})
3526
>>> os.environ['LINES']
3529
# doctest.DocTestSuite fails as it sees '25'
3530
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3531
# tests.DocTestSuite sees '42'
3532
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
3534
def test_deleted_variable(self):
3535
self.overrideAttr(tests, 'isolated_environ', {'LINES': None})
3538
>>> os.environ.get('LINES')
3540
# doctest.DocTestSuite fails as it sees '25'
3541
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3542
# tests.DocTestSuite sees None
3543
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)