1217
def test_verbose_test_count(self):
1218
"""A verbose test run reports the right test count at the start"""
1219
suite = TestUtil.TestSuite([
1220
unittest.FunctionTestCase(lambda:None),
1221
unittest.FunctionTestCase(lambda:None)])
1222
self.assertEqual(suite.countTestCases(), 2)
1224
runner = tests.TextTestRunner(stream=stream, verbosity=2)
1225
# Need to use the CountingDecorator as that's what sets num_tests
1226
result = self.run_test_runner(runner, tests.CountingDecorator(suite))
1227
self.assertStartsWith(stream.getvalue(), "running 2 tests")
1229
def test_startTestRun(self):
1230
"""run should call result.startTestRun()"""
1232
class LoggingDecorator(ExtendedToOriginalDecorator):
1233
def startTestRun(self):
1234
ExtendedToOriginalDecorator.startTestRun(self)
1235
calls.append('startTestRun')
1236
test = unittest.FunctionTestCase(lambda:None)
1238
runner = tests.TextTestRunner(stream=stream,
1239
result_decorators=[LoggingDecorator])
1240
result = self.run_test_runner(runner, test)
1241
self.assertLength(1, calls)
1243
def test_stopTestRun(self):
1244
"""run should call result.stopTestRun()"""
1246
class LoggingDecorator(ExtendedToOriginalDecorator):
1247
def stopTestRun(self):
1248
ExtendedToOriginalDecorator.stopTestRun(self)
1249
calls.append('stopTestRun')
1250
test = unittest.FunctionTestCase(lambda:None)
1252
runner = tests.TextTestRunner(stream=stream,
1253
result_decorators=[LoggingDecorator])
1254
result = self.run_test_runner(runner, test)
1255
self.assertLength(1, calls)
1257
def test_unicode_test_output_on_ascii_stream(self):
1258
"""Showing results should always succeed even on an ascii console"""
1259
class FailureWithUnicode(tests.TestCase):
1260
def test_log_unicode(self):
1262
self.fail("Now print that log!")
1264
self.overrideAttr(osutils, "get_terminal_encoding",
1265
lambda trace=False: "ascii")
1266
result = self.run_test_runner(tests.TextTestRunner(stream=out),
1267
FailureWithUnicode("test_log_unicode"))
1268
self.assertContainsRe(out.getvalue(),
1269
"Text attachment: log\n"
1271
"\d+\.\d+ \\\\u2606\n"
1275
class SampleTestCase(tests.TestCase):
1216
def test_bench_history(self):
1217
# tests that the running the benchmark produces a history file
1218
# containing a timestamp and the revision id of the bzrlib source which
1220
workingtree = _get_bzr_source_tree()
1221
test = TestRunner('dummy_test')
1223
runner = TextTestRunner(stream=self._log_file, bench_history=output)
1224
result = self.run_test_runner(runner, test)
1225
output_string = output.getvalue()
1226
self.assertContainsRe(output_string, "--date [0-9.]+")
1227
if workingtree is not None:
1228
revision_id = workingtree.get_parent_ids()[0]
1229
self.assertEndsWith(output_string.rstrip(), revision_id)
1231
def assertLogDeleted(self, test):
1232
log = test._get_log()
1233
self.assertEqual("DELETED log file to reduce memory footprint", log)
1234
self.assertEqual('', test._log_contents)
1235
self.assertIs(None, test._log_file_name)
1237
def test_success_log_deleted(self):
1238
"""Successful tests have their log deleted"""
1240
class LogTester(TestCase):
1242
def test_success(self):
1243
self.log('this will be removed\n')
1245
sio = cStringIO.StringIO()
1246
runner = TextTestRunner(stream=sio)
1247
test = LogTester('test_success')
1248
result = self.run_test_runner(runner, test)
1250
self.assertLogDeleted(test)
1252
def test_skipped_log_deleted(self):
1253
"""Skipped tests have their log deleted"""
1255
class LogTester(TestCase):
1257
def test_skipped(self):
1258
self.log('this will be removed\n')
1259
raise tests.TestSkipped()
1261
sio = cStringIO.StringIO()
1262
runner = TextTestRunner(stream=sio)
1263
test = LogTester('test_skipped')
1264
result = self.run_test_runner(runner, test)
1266
self.assertLogDeleted(test)
1268
def test_not_aplicable_log_deleted(self):
1269
"""Not applicable tests have their log deleted"""
1271
class LogTester(TestCase):
1273
def test_not_applicable(self):
1274
self.log('this will be removed\n')
1275
raise tests.TestNotApplicable()
1277
sio = cStringIO.StringIO()
1278
runner = TextTestRunner(stream=sio)
1279
test = LogTester('test_not_applicable')
1280
result = self.run_test_runner(runner, test)
1282
self.assertLogDeleted(test)
1284
def test_known_failure_log_deleted(self):
1285
"""Know failure tests have their log deleted"""
1287
class LogTester(TestCase):
1289
def test_known_failure(self):
1290
self.log('this will be removed\n')
1291
raise tests.KnownFailure()
1293
sio = cStringIO.StringIO()
1294
runner = TextTestRunner(stream=sio)
1295
test = LogTester('test_known_failure')
1296
result = self.run_test_runner(runner, test)
1298
self.assertLogDeleted(test)
1300
def test_fail_log_kept(self):
1301
"""Failed tests have their log kept"""
1303
class LogTester(TestCase):
1305
def test_fail(self):
1306
self.log('this will be kept\n')
1307
self.fail('this test fails')
1309
sio = cStringIO.StringIO()
1310
runner = TextTestRunner(stream=sio)
1311
test = LogTester('test_fail')
1312
result = self.run_test_runner(runner, test)
1314
text = sio.getvalue()
1315
self.assertContainsRe(text, 'this will be kept')
1316
self.assertContainsRe(text, 'this test fails')
1318
log = test._get_log()
1319
self.assertContainsRe(log, 'this will be kept')
1320
self.assertEqual(log, test._log_contents)
1322
def test_error_log_kept(self):
1323
"""Tests with errors have their log kept"""
1325
class LogTester(TestCase):
1327
def test_error(self):
1328
self.log('this will be kept\n')
1329
raise ValueError('random exception raised')
1331
sio = cStringIO.StringIO()
1332
runner = TextTestRunner(stream=sio)
1333
test = LogTester('test_error')
1334
result = self.run_test_runner(runner, test)
1336
text = sio.getvalue()
1337
self.assertContainsRe(text, 'this will be kept')
1338
self.assertContainsRe(text, 'random exception raised')
1340
log = test._get_log()
1341
self.assertContainsRe(log, 'this will be kept')
1342
self.assertEqual(log, test._log_contents)
1345
class SampleTestCase(TestCase):
1277
1347
def _test_pass(self):
1648
1653
self.assertRaises(AssertionError,
1649
1654
self.assertListRaises, _TestException, success_generator)
1651
def test_overrideAttr_without_value(self):
1652
self.test_attr = 'original' # Define a test attribute
1653
obj = self # Make 'obj' visible to the embedded test
1654
class Test(tests.TestCase):
1657
tests.TestCase.setUp(self)
1658
self.orig = self.overrideAttr(obj, 'test_attr')
1660
def test_value(self):
1661
self.assertEqual('original', self.orig)
1662
self.assertEqual('original', obj.test_attr)
1663
obj.test_attr = 'modified'
1664
self.assertEqual('modified', obj.test_attr)
1666
test = Test('test_value')
1667
test.run(unittest.TestResult())
1668
self.assertEqual('original', obj.test_attr)
1670
def test_overrideAttr_with_value(self):
1671
self.test_attr = 'original' # Define a test attribute
1672
obj = self # Make 'obj' visible to the embedded test
1673
class Test(tests.TestCase):
1676
tests.TestCase.setUp(self)
1677
self.orig = self.overrideAttr(obj, 'test_attr', new='modified')
1679
def test_value(self):
1680
self.assertEqual('original', self.orig)
1681
self.assertEqual('modified', obj.test_attr)
1683
test = Test('test_value')
1684
test.run(unittest.TestResult())
1685
self.assertEqual('original', obj.test_attr)
1688
class _MissingFeature(tests.Feature):
1691
missing_feature = _MissingFeature()
1694
def _get_test(name):
1695
"""Get an instance of a specific example test.
1697
We protect this in a function so that they don't auto-run in the test
1701
class ExampleTests(tests.TestCase):
1703
def test_fail(self):
1704
mutter('this was a failing test')
1705
self.fail('this test will fail')
1707
def test_error(self):
1708
mutter('this test errored')
1709
raise RuntimeError('gotcha')
1711
def test_missing_feature(self):
1712
mutter('missing the feature')
1713
self.requireFeature(missing_feature)
1715
def test_skip(self):
1716
mutter('this test will be skipped')
1717
raise tests.TestSkipped('reason')
1719
def test_success(self):
1720
mutter('this test succeeds')
1722
def test_xfail(self):
1723
mutter('test with expected failure')
1724
self.knownFailure('this_fails')
1726
def test_unexpected_success(self):
1727
mutter('test with unexpected success')
1728
self.expectFailure('should_fail', lambda: None)
1730
return ExampleTests(name)
1733
class TestTestCaseLogDetails(tests.TestCase):
1735
def _run_test(self, test_name):
1736
test = _get_test(test_name)
1737
result = testtools.TestResult()
1741
def test_fail_has_log(self):
1742
result = self._run_test('test_fail')
1743
self.assertEqual(1, len(result.failures))
1744
result_content = result.failures[0][1]
1745
self.assertContainsRe(result_content, 'Text attachment: log')
1746
self.assertContainsRe(result_content, 'this was a failing test')
1748
def test_error_has_log(self):
1749
result = self._run_test('test_error')
1750
self.assertEqual(1, len(result.errors))
1751
result_content = result.errors[0][1]
1752
self.assertContainsRe(result_content, 'Text attachment: log')
1753
self.assertContainsRe(result_content, 'this test errored')
1755
def test_skip_has_no_log(self):
1756
result = self._run_test('test_skip')
1757
self.assertEqual(['reason'], result.skip_reasons.keys())
1758
skips = result.skip_reasons['reason']
1759
self.assertEqual(1, len(skips))
1761
self.assertFalse('log' in test.getDetails())
1763
def test_missing_feature_has_no_log(self):
1764
# testtools doesn't know about addNotSupported, so it just gets
1765
# considered as a skip
1766
result = self._run_test('test_missing_feature')
1767
self.assertEqual([missing_feature], result.skip_reasons.keys())
1768
skips = result.skip_reasons[missing_feature]
1769
self.assertEqual(1, len(skips))
1771
self.assertFalse('log' in test.getDetails())
1773
def test_xfail_has_no_log(self):
1774
result = self._run_test('test_xfail')
1775
self.assertEqual(1, len(result.expectedFailures))
1776
result_content = result.expectedFailures[0][1]
1777
self.assertNotContainsRe(result_content, 'Text attachment: log')
1778
self.assertNotContainsRe(result_content, 'test with expected failure')
1780
def test_unexpected_success_has_log(self):
1781
result = self._run_test('test_unexpected_success')
1782
self.assertEqual(1, len(result.unexpectedSuccesses))
1783
# Inconsistency, unexpectedSuccesses is a list of tests,
1784
# expectedFailures is a list of reasons?
1785
test = result.unexpectedSuccesses[0]
1786
details = test.getDetails()
1787
self.assertTrue('log' in details)
1790
class TestTestCloning(tests.TestCase):
1791
"""Tests that test cloning of TestCases (as used by multiply_tests)."""
1793
def test_cloned_testcase_does_not_share_details(self):
1794
"""A TestCase cloned with clone_test does not share mutable attributes
1795
such as details or cleanups.
1797
class Test(tests.TestCase):
1799
self.addDetail('foo', Content('text/plain', lambda: 'foo'))
1800
orig_test = Test('test_foo')
1801
cloned_test = tests.clone_test(orig_test, orig_test.id() + '(cloned)')
1802
orig_test.run(unittest.TestResult())
1803
self.assertEqual('foo', orig_test.getDetails()['foo'].iter_bytes())
1804
self.assertEqual(None, cloned_test.getDetails().get('foo'))
1806
def test_double_apply_scenario_preserves_first_scenario(self):
1807
"""Applying two levels of scenarios to a test preserves the attributes
1808
added by both scenarios.
1810
class Test(tests.TestCase):
1813
test = Test('test_foo')
1814
scenarios_x = [('x=1', {'x': 1}), ('x=2', {'x': 2})]
1815
scenarios_y = [('y=1', {'y': 1}), ('y=2', {'y': 2})]
1816
suite = tests.multiply_tests(test, scenarios_x, unittest.TestSuite())
1817
suite = tests.multiply_tests(suite, scenarios_y, unittest.TestSuite())
1818
all_tests = list(tests.iter_suite_tests(suite))
1819
self.assertLength(4, all_tests)
1820
all_xys = sorted((t.x, t.y) for t in all_tests)
1821
self.assertEqual([(1, 1), (1, 2), (2, 1), (2, 2)], all_xys)
1824
1657
# NB: Don't delete this; it's not actually from 0.11!
1825
1658
@deprecated_function(deprecated_in((0, 11, 0)))
1962
1776
tree = self.make_branch_and_memory_tree('a')
1963
1777
self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
1965
def test_make_tree_for_local_vfs_backed_transport(self):
1966
# make_branch_and_tree has to use local branch and repositories
1967
# when the vfs transport and local disk are colocated, even if
1968
# a different transport is in use for url generation.
1969
self.transport_server = test_server.FakeVFATServer
1970
self.assertFalse(self.get_url('t1').startswith('file://'))
1780
class TestSFTPMakeBranchAndTree(TestCaseWithSFTPServer):
1782
def test_make_tree_for_sftp_branch(self):
1783
"""Transports backed by local directories create local trees."""
1971
1785
tree = self.make_branch_and_tree('t1')
1972
1786
base = tree.bzrdir.root_transport.base
1973
self.assertStartsWith(base, 'file://')
1787
self.failIf(base.startswith('sftp'),
1788
'base %r is on sftp but should be local' % base)
1974
1789
self.assertEquals(tree.bzrdir.root_transport,
1975
1790
tree.branch.bzrdir.root_transport)
1976
1791
self.assertEquals(tree.bzrdir.root_transport,
1977
1792
tree.branch.repository.bzrdir.root_transport)
1980
class SelfTestHelper(object):
1982
def run_selftest(self, **kwargs):
1983
"""Run selftest returning its output."""
1985
old_transport = bzrlib.tests.default_transport
1986
old_root = tests.TestCaseWithMemoryTransport.TEST_ROOT
1987
tests.TestCaseWithMemoryTransport.TEST_ROOT = None
1989
self.assertEqual(True, tests.selftest(stream=output, **kwargs))
1991
bzrlib.tests.default_transport = old_transport
1992
tests.TestCaseWithMemoryTransport.TEST_ROOT = old_root
1997
class TestSelftest(tests.TestCase, SelfTestHelper):
1795
class TestSelftest(TestCase):
1998
1796
"""Tests of bzrlib.tests.selftest."""
2000
1798
def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
2001
1799
factory_called = []
2003
1801
factory_called.append(True)
2004
return TestUtil.TestSuite()
2005
1803
out = StringIO()
2006
1804
err = StringIO()
2007
1805
self.apply_redirected(out, err, None, bzrlib.tests.selftest,
2008
1806
test_suite_factory=factory)
2009
1807
self.assertEqual([True], factory_called)
2012
"""A test suite factory."""
2013
class Test(tests.TestCase):
2020
return TestUtil.TestSuite([Test("a"), Test("b"), Test("c")])
2022
def test_list_only(self):
2023
output = self.run_selftest(test_suite_factory=self.factory,
2025
self.assertEqual(3, len(output.readlines()))
2027
def test_list_only_filtered(self):
2028
output = self.run_selftest(test_suite_factory=self.factory,
2029
list_only=True, pattern="Test.b")
2030
self.assertEndsWith(output.getvalue(), "Test.b\n")
2031
self.assertLength(1, output.readlines())
2033
def test_list_only_excludes(self):
2034
output = self.run_selftest(test_suite_factory=self.factory,
2035
list_only=True, exclude_pattern="Test.b")
2036
self.assertNotContainsRe("Test.b", output.getvalue())
2037
self.assertLength(2, output.readlines())
2039
def test_lsprof_tests(self):
2040
self.requireFeature(test_lsprof.LSProfFeature)
2043
def __call__(test, result):
2045
def run(test, result):
2046
results.append(result)
2047
def countTestCases(self):
2049
self.run_selftest(test_suite_factory=Test, lsprof_tests=True)
2050
self.assertLength(1, results)
2051
self.assertIsInstance(results.pop(), ExtendedToOriginalDecorator)
2053
def test_random(self):
2054
# test randomising by listing a number of tests.
2055
output_123 = self.run_selftest(test_suite_factory=self.factory,
2056
list_only=True, random_seed="123")
2057
output_234 = self.run_selftest(test_suite_factory=self.factory,
2058
list_only=True, random_seed="234")
2059
self.assertNotEqual(output_123, output_234)
2060
# "Randominzing test order..\n\n
2061
self.assertLength(5, output_123.readlines())
2062
self.assertLength(5, output_234.readlines())
2064
def test_random_reuse_is_same_order(self):
2065
# test randomising by listing a number of tests.
2066
expected = self.run_selftest(test_suite_factory=self.factory,
2067
list_only=True, random_seed="123")
2068
repeated = self.run_selftest(test_suite_factory=self.factory,
2069
list_only=True, random_seed="123")
2070
self.assertEqual(expected.getvalue(), repeated.getvalue())
2072
def test_runner_class(self):
2073
self.requireFeature(features.subunit)
2074
from subunit import ProtocolTestCase
2075
stream = self.run_selftest(runner_class=tests.SubUnitBzrRunner,
2076
test_suite_factory=self.factory)
2077
test = ProtocolTestCase(stream)
2078
result = unittest.TestResult()
2080
self.assertEqual(3, result.testsRun)
2082
def test_starting_with_single_argument(self):
2083
output = self.run_selftest(test_suite_factory=self.factory,
2084
starting_with=['bzrlib.tests.test_selftest.Test.a'],
2086
self.assertEqual('bzrlib.tests.test_selftest.Test.a\n',
2089
def test_starting_with_multiple_argument(self):
2090
output = self.run_selftest(test_suite_factory=self.factory,
2091
starting_with=['bzrlib.tests.test_selftest.Test.a',
2092
'bzrlib.tests.test_selftest.Test.b'],
2094
self.assertEqual('bzrlib.tests.test_selftest.Test.a\n'
2095
'bzrlib.tests.test_selftest.Test.b\n',
2098
def check_transport_set(self, transport_server):
2099
captured_transport = []
2100
def seen_transport(a_transport):
2101
captured_transport.append(a_transport)
2102
class Capture(tests.TestCase):
2104
seen_transport(bzrlib.tests.default_transport)
2106
return TestUtil.TestSuite([Capture("a")])
2107
self.run_selftest(transport=transport_server, test_suite_factory=factory)
2108
self.assertEqual(transport_server, captured_transport[0])
2110
def test_transport_sftp(self):
2111
self.requireFeature(features.paramiko)
2112
from bzrlib.tests import stub_sftp
2113
self.check_transport_set(stub_sftp.SFTPAbsoluteServer)
2115
def test_transport_memory(self):
2116
self.check_transport_set(memory.MemoryServer)
2119
class TestSelftestWithIdList(tests.TestCaseInTempDir, SelfTestHelper):
2120
# Does IO: reads test.list
2122
def test_load_list(self):
2123
# Provide a list with one test - this test.
2124
test_id_line = '%s\n' % self.id()
2125
self.build_tree_contents([('test.list', test_id_line)])
2126
# And generate a list of the tests in the suite.
2127
stream = self.run_selftest(load_list='test.list', list_only=True)
2128
self.assertEqual(test_id_line, stream.getvalue())
2130
def test_load_unknown(self):
2131
# Provide a list with one test - this test.
2132
# And generate a list of the tests in the suite.
2133
err = self.assertRaises(errors.NoSuchFile, self.run_selftest,
2134
load_list='missing file name', list_only=True)
2137
class TestSubunitLogDetails(tests.TestCase, SelfTestHelper):
2139
_test_needs_features = [features.subunit]
2141
def run_subunit_stream(self, test_name):
2142
from subunit import ProtocolTestCase
2144
return TestUtil.TestSuite([_get_test(test_name)])
2145
stream = self.run_selftest(runner_class=tests.SubUnitBzrRunner,
2146
test_suite_factory=factory)
2147
test = ProtocolTestCase(stream)
2148
result = testtools.TestResult()
2150
content = stream.getvalue()
2151
return content, result
2153
def test_fail_has_log(self):
2154
content, result = self.run_subunit_stream('test_fail')
2155
self.assertEqual(1, len(result.failures))
2156
self.assertContainsRe(content, '(?m)^log$')
2157
self.assertContainsRe(content, 'this test will fail')
2159
def test_error_has_log(self):
2160
content, result = self.run_subunit_stream('test_error')
2161
self.assertContainsRe(content, '(?m)^log$')
2162
self.assertContainsRe(content, 'this test errored')
2164
def test_skip_has_no_log(self):
2165
content, result = self.run_subunit_stream('test_skip')
2166
self.assertNotContainsRe(content, '(?m)^log$')
2167
self.assertNotContainsRe(content, 'this test will be skipped')
2168
self.assertEqual(['reason'], result.skip_reasons.keys())
2169
skips = result.skip_reasons['reason']
2170
self.assertEqual(1, len(skips))
2172
# RemotedTestCase doesn't preserve the "details"
2173
## self.assertFalse('log' in test.getDetails())
2175
def test_missing_feature_has_no_log(self):
2176
content, result = self.run_subunit_stream('test_missing_feature')
2177
self.assertNotContainsRe(content, '(?m)^log$')
2178
self.assertNotContainsRe(content, 'missing the feature')
2179
self.assertEqual(['_MissingFeature\n'], result.skip_reasons.keys())
2180
skips = result.skip_reasons['_MissingFeature\n']
2181
self.assertEqual(1, len(skips))
2183
# RemotedTestCase doesn't preserve the "details"
2184
## self.assertFalse('log' in test.getDetails())
2186
def test_xfail_has_no_log(self):
2187
content, result = self.run_subunit_stream('test_xfail')
2188
self.assertNotContainsRe(content, '(?m)^log$')
2189
self.assertNotContainsRe(content, 'test with expected failure')
2190
self.assertEqual(1, len(result.expectedFailures))
2191
result_content = result.expectedFailures[0][1]
2192
self.assertNotContainsRe(result_content, 'Text attachment: log')
2193
self.assertNotContainsRe(result_content, 'test with expected failure')
2195
def test_unexpected_success_has_log(self):
2196
content, result = self.run_subunit_stream('test_unexpected_success')
2197
self.assertContainsRe(content, '(?m)^log$')
2198
self.assertContainsRe(content, 'test with unexpected success')
2199
# GZ 2011-05-18: Old versions of subunit treat unexpected success as a
2200
# success, if a min version check is added remove this
2201
from subunit import TestProtocolClient as _Client
2202
if _Client.addUnexpectedSuccess.im_func is _Client.addSuccess.im_func:
2203
self.expectFailure('subunit treats "unexpectedSuccess"'
2204
' as a plain success',
2205
self.assertEqual, 1, len(result.unexpectedSuccesses))
2206
self.assertEqual(1, len(result.unexpectedSuccesses))
2207
test = result.unexpectedSuccesses[0]
2208
# RemotedTestCase doesn't preserve the "details"
2209
## self.assertTrue('log' in test.getDetails())
2211
def test_success_has_no_log(self):
2212
content, result = self.run_subunit_stream('test_success')
2213
self.assertEqual(1, result.testsRun)
2214
self.assertNotContainsRe(content, '(?m)^log$')
2215
self.assertNotContainsRe(content, 'this test succeeds')
2218
class TestRunBzr(tests.TestCase):
2223
def _run_bzr_core(self, argv, retcode=0, encoding=None, stdin=None,
2225
"""Override _run_bzr_core to test how it is invoked by run_bzr.
2227
Attempts to run bzr from inside this class don't actually run it.
2229
We test how run_bzr actually invokes bzr in another location. Here we
2230
only need to test that it passes the right parameters to run_bzr.
2232
self.argv = list(argv)
2233
self.retcode = retcode
2234
self.encoding = encoding
2236
self.working_dir = working_dir
2237
return self.retcode, self.out, self.err
2239
def test_run_bzr_error(self):
2240
self.out = "It sure does!\n"
2241
out, err = self.run_bzr_error(['^$'], ['rocks'], retcode=34)
2242
self.assertEqual(['rocks'], self.argv)
2243
self.assertEqual(34, self.retcode)
2244
self.assertEqual('It sure does!\n', out)
2245
self.assertEquals(out, self.out)
2246
self.assertEqual('', err)
2247
self.assertEquals(err, self.err)
2249
def test_run_bzr_error_regexes(self):
2251
self.err = "bzr: ERROR: foobarbaz is not versioned"
2252
out, err = self.run_bzr_error(
2253
["bzr: ERROR: foobarbaz is not versioned"],
2254
['file-id', 'foobarbaz'])
2256
def test_encoding(self):
2257
"""Test that run_bzr passes encoding to _run_bzr_core"""
2258
self.run_bzr('foo bar')
2259
self.assertEqual(None, self.encoding)
2260
self.assertEqual(['foo', 'bar'], self.argv)
2262
self.run_bzr('foo bar', encoding='baz')
2263
self.assertEqual('baz', self.encoding)
2264
self.assertEqual(['foo', 'bar'], self.argv)
2266
def test_retcode(self):
2267
"""Test that run_bzr passes retcode to _run_bzr_core"""
2268
# Default is retcode == 0
2269
self.run_bzr('foo bar')
2270
self.assertEqual(0, self.retcode)
2271
self.assertEqual(['foo', 'bar'], self.argv)
2273
self.run_bzr('foo bar', retcode=1)
2274
self.assertEqual(1, self.retcode)
2275
self.assertEqual(['foo', 'bar'], self.argv)
2277
self.run_bzr('foo bar', retcode=None)
2278
self.assertEqual(None, self.retcode)
2279
self.assertEqual(['foo', 'bar'], self.argv)
2281
self.run_bzr(['foo', 'bar'], retcode=3)
2282
self.assertEqual(3, self.retcode)
2283
self.assertEqual(['foo', 'bar'], self.argv)
2285
def test_stdin(self):
2286
# test that the stdin keyword to run_bzr is passed through to
2287
# _run_bzr_core as-is. We do this by overriding
2288
# _run_bzr_core in this class, and then calling run_bzr,
2289
# which is a convenience function for _run_bzr_core, so
2291
self.run_bzr('foo bar', stdin='gam')
2292
self.assertEqual('gam', self.stdin)
2293
self.assertEqual(['foo', 'bar'], self.argv)
2295
self.run_bzr('foo bar', stdin='zippy')
2296
self.assertEqual('zippy', self.stdin)
2297
self.assertEqual(['foo', 'bar'], self.argv)
2299
def test_working_dir(self):
2300
"""Test that run_bzr passes working_dir to _run_bzr_core"""
2301
self.run_bzr('foo bar')
2302
self.assertEqual(None, self.working_dir)
2303
self.assertEqual(['foo', 'bar'], self.argv)
2305
self.run_bzr('foo bar', working_dir='baz')
2306
self.assertEqual('baz', self.working_dir)
2307
self.assertEqual(['foo', 'bar'], self.argv)
2309
def test_reject_extra_keyword_arguments(self):
2310
self.assertRaises(TypeError, self.run_bzr, "foo bar",
2311
error_regex=['error message'])
2314
class TestRunBzrCaptured(tests.TestCaseWithTransport):
2315
# Does IO when testing the working_dir parameter.
2317
def apply_redirected(self, stdin=None, stdout=None, stderr=None,
2318
a_callable=None, *args, **kwargs):
2320
self.factory_stdin = getattr(bzrlib.ui.ui_factory, "stdin", None)
2321
self.factory = bzrlib.ui.ui_factory
2322
self.working_dir = osutils.getcwd()
2323
stdout.write('foo\n')
2324
stderr.write('bar\n')
2327
def test_stdin(self):
2328
# test that the stdin keyword to _run_bzr_core is passed through to
2329
# apply_redirected as a StringIO. We do this by overriding
2330
# apply_redirected in this class, and then calling _run_bzr_core,
2331
# which calls apply_redirected.
2332
self.run_bzr(['foo', 'bar'], stdin='gam')
2333
self.assertEqual('gam', self.stdin.read())
2334
self.assertTrue(self.stdin is self.factory_stdin)
2335
self.run_bzr(['foo', 'bar'], stdin='zippy')
2336
self.assertEqual('zippy', self.stdin.read())
2337
self.assertTrue(self.stdin is self.factory_stdin)
2339
def test_ui_factory(self):
2340
# each invocation of self.run_bzr should get its
2341
# own UI factory, which is an instance of TestUIFactory,
2342
# with stdin, stdout and stderr attached to the stdin,
2343
# stdout and stderr of the invoked run_bzr
2344
current_factory = bzrlib.ui.ui_factory
2345
self.run_bzr(['foo'])
2346
self.assertFalse(current_factory is self.factory)
2347
self.assertNotEqual(sys.stdout, self.factory.stdout)
2348
self.assertNotEqual(sys.stderr, self.factory.stderr)
2349
self.assertEqual('foo\n', self.factory.stdout.getvalue())
2350
self.assertEqual('bar\n', self.factory.stderr.getvalue())
2351
self.assertIsInstance(self.factory, tests.TestUIFactory)
2353
def test_working_dir(self):
2354
self.build_tree(['one/', 'two/'])
2355
cwd = osutils.getcwd()
2357
# Default is to work in the current directory
2358
self.run_bzr(['foo', 'bar'])
2359
self.assertEqual(cwd, self.working_dir)
2361
self.run_bzr(['foo', 'bar'], working_dir=None)
2362
self.assertEqual(cwd, self.working_dir)
2364
# The function should be run in the alternative directory
2365
# but afterwards the current working dir shouldn't be changed
2366
self.run_bzr(['foo', 'bar'], working_dir='one')
2367
self.assertNotEqual(cwd, self.working_dir)
2368
self.assertEndsWith(self.working_dir, 'one')
2369
self.assertEqual(cwd, osutils.getcwd())
2371
self.run_bzr(['foo', 'bar'], working_dir='two')
2372
self.assertNotEqual(cwd, self.working_dir)
2373
self.assertEndsWith(self.working_dir, 'two')
2374
self.assertEqual(cwd, osutils.getcwd())
2377
class StubProcess(object):
2378
"""A stub process for testing run_bzr_subprocess."""
2380
def __init__(self, out="", err="", retcode=0):
2383
self.returncode = retcode
2385
def communicate(self):
2386
return self.out, self.err
2389
class TestWithFakedStartBzrSubprocess(tests.TestCaseWithTransport):
2390
"""Base class for tests testing how we might run bzr."""
2393
tests.TestCaseWithTransport.setUp(self)
2394
self.subprocess_calls = []
2396
def start_bzr_subprocess(self, process_args, env_changes=None,
2397
skip_if_plan_to_signal=False,
2399
allow_plugins=False):
2400
"""capture what run_bzr_subprocess tries to do."""
2401
self.subprocess_calls.append({'process_args':process_args,
2402
'env_changes':env_changes,
2403
'skip_if_plan_to_signal':skip_if_plan_to_signal,
2404
'working_dir':working_dir, 'allow_plugins':allow_plugins})
2405
return self.next_subprocess
2408
class TestRunBzrSubprocess(TestWithFakedStartBzrSubprocess):
2410
def assertRunBzrSubprocess(self, expected_args, process, *args, **kwargs):
2411
"""Run run_bzr_subprocess with args and kwargs using a stubbed process.
2413
Inside TestRunBzrSubprocessCommands we use a stub start_bzr_subprocess
2414
that will return static results. This assertion method populates those
2415
results and also checks the arguments run_bzr_subprocess generates.
2417
self.next_subprocess = process
2419
result = self.run_bzr_subprocess(*args, **kwargs)
2421
self.next_subprocess = None
2422
for key, expected in expected_args.iteritems():
2423
self.assertEqual(expected, self.subprocess_calls[-1][key])
1810
class TestKnownFailure(TestCase):
1812
def test_known_failure(self):
1813
"""Check that KnownFailure is defined appropriately."""
1814
# a KnownFailure is an assertion error for compatability with unaware
1816
self.assertIsInstance(KnownFailure(""), AssertionError)
1818
def test_expect_failure(self):
1820
self.expectFailure("Doomed to failure", self.assertTrue, False)
1821
except KnownFailure, e:
1822
self.assertEqual('Doomed to failure', e.args[0])
1824
self.expectFailure("Doomed to failure", self.assertTrue, True)
1825
except AssertionError, e:
1826
self.assertEqual('Unexpected success. Should have failed:'
1827
' Doomed to failure', e.args[0])
2426
self.next_subprocess = None
2427
for key, expected in expected_args.iteritems():
2428
self.assertEqual(expected, self.subprocess_calls[-1][key])
2431
def test_run_bzr_subprocess(self):
2432
"""The run_bzr_helper_external command behaves nicely."""
2433
self.assertRunBzrSubprocess({'process_args':['--version']},
2434
StubProcess(), '--version')
2435
self.assertRunBzrSubprocess({'process_args':['--version']},
2436
StubProcess(), ['--version'])
2437
# retcode=None disables retcode checking
2438
result = self.assertRunBzrSubprocess({},
2439
StubProcess(retcode=3), '--version', retcode=None)
2440
result = self.assertRunBzrSubprocess({},
2441
StubProcess(out="is free software"), '--version')
2442
self.assertContainsRe(result[0], 'is free software')
2443
# Running a subcommand that is missing errors
2444
self.assertRaises(AssertionError, self.assertRunBzrSubprocess,
2445
{'process_args':['--versionn']}, StubProcess(retcode=3),
2447
# Unless it is told to expect the error from the subprocess
2448
result = self.assertRunBzrSubprocess({},
2449
StubProcess(retcode=3), '--versionn', retcode=3)
2450
# Or to ignore retcode checking
2451
result = self.assertRunBzrSubprocess({},
2452
StubProcess(err="unknown command", retcode=3), '--versionn',
2454
self.assertContainsRe(result[1], 'unknown command')
2456
def test_env_change_passes_through(self):
2457
self.assertRunBzrSubprocess(
2458
{'env_changes':{'new':'value', 'changed':'newvalue', 'deleted':None}},
2460
env_changes={'new':'value', 'changed':'newvalue', 'deleted':None})
2462
def test_no_working_dir_passed_as_None(self):
2463
self.assertRunBzrSubprocess({'working_dir': None}, StubProcess(), '')
2465
def test_no_working_dir_passed_through(self):
2466
self.assertRunBzrSubprocess({'working_dir': 'dir'}, StubProcess(), '',
2469
def test_run_bzr_subprocess_no_plugins(self):
2470
self.assertRunBzrSubprocess({'allow_plugins': False},
2473
def test_allow_plugins(self):
2474
self.assertRunBzrSubprocess({'allow_plugins': True},
2475
StubProcess(), '', allow_plugins=True)
2478
class TestFinishBzrSubprocess(TestWithFakedStartBzrSubprocess):
2480
def test_finish_bzr_subprocess_with_error(self):
2481
"""finish_bzr_subprocess allows specification of the desired exit code.
2483
process = StubProcess(err="unknown command", retcode=3)
2484
result = self.finish_bzr_subprocess(process, retcode=3)
2485
self.assertEqual('', result[0])
2486
self.assertContainsRe(result[1], 'unknown command')
2488
def test_finish_bzr_subprocess_ignoring_retcode(self):
2489
"""finish_bzr_subprocess allows the exit code to be ignored."""
2490
process = StubProcess(err="unknown command", retcode=3)
2491
result = self.finish_bzr_subprocess(process, retcode=None)
2492
self.assertEqual('', result[0])
2493
self.assertContainsRe(result[1], 'unknown command')
2495
def test_finish_subprocess_with_unexpected_retcode(self):
2496
"""finish_bzr_subprocess raises self.failureException if the retcode is
2497
not the expected one.
2499
process = StubProcess(err="unknown command", retcode=3)
2500
self.assertRaises(self.failureException, self.finish_bzr_subprocess,
2504
class _DontSpawnProcess(Exception):
2505
"""A simple exception which just allows us to skip unnecessary steps"""
2508
class TestStartBzrSubProcess(tests.TestCase):
2509
"""Stub test start_bzr_subprocess."""
2511
def _subprocess_log_cleanup(self):
2512
"""Inhibits the base version as we don't produce a log file."""
2514
def _popen(self, *args, **kwargs):
2515
"""Override the base version to record the command that is run.
2517
From there we can ensure it is correct without spawning a real process.
2519
self.check_popen_state()
2520
self._popen_args = args
2521
self._popen_kwargs = kwargs
2522
raise _DontSpawnProcess()
2524
def check_popen_state(self):
2525
"""Replace to make assertions when popen is called."""
2527
def test_run_bzr_subprocess_no_plugins(self):
2528
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [])
2529
command = self._popen_args[0]
2530
self.assertEqual(sys.executable, command[0])
2531
self.assertEqual(self.get_bzr_path(), command[1])
2532
self.assertEqual(['--no-plugins'], command[2:])
2534
def test_allow_plugins(self):
2535
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2537
command = self._popen_args[0]
2538
self.assertEqual([], command[2:])
2540
def test_set_env(self):
2541
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2543
def check_environment():
2544
self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2545
self.check_popen_state = check_environment
2546
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2547
env_changes={'EXISTANT_ENV_VAR':'set variable'})
2548
# not set in theparent
2549
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2551
def test_run_bzr_subprocess_env_del(self):
2552
"""run_bzr_subprocess can remove environment variables too."""
2553
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2554
def check_environment():
2555
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2556
os.environ['EXISTANT_ENV_VAR'] = 'set variable'
2557
self.check_popen_state = check_environment
2558
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2559
env_changes={'EXISTANT_ENV_VAR':None})
2560
# Still set in parent
2561
self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2562
del os.environ['EXISTANT_ENV_VAR']
2564
def test_env_del_missing(self):
2565
self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
2566
def check_environment():
2567
self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
2568
self.check_popen_state = check_environment
2569
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2570
env_changes={'NON_EXISTANT_ENV_VAR':None})
2572
def test_working_dir(self):
2573
"""Test that we can specify the working dir for the child"""
2574
orig_getcwd = osutils.getcwd
2575
orig_chdir = os.chdir
2579
self.overrideAttr(os, 'chdir', chdir)
2582
self.overrideAttr(osutils, 'getcwd', getcwd)
2583
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2585
self.assertEqual(['foo', 'current'], chdirs)
2587
def test_get_bzr_path_with_cwd_bzrlib(self):
2588
self.get_source_path = lambda: ""
2589
self.overrideAttr(os.path, "isfile", lambda path: True)
2590
self.assertEqual(self.get_bzr_path(), "bzr")
2593
class TestActuallyStartBzrSubprocess(tests.TestCaseWithTransport):
2594
"""Tests that really need to do things with an external bzr."""
2596
def test_start_and_stop_bzr_subprocess_send_signal(self):
2597
"""finish_bzr_subprocess raises self.failureException if the retcode is
2598
not the expected one.
2600
self.disable_missing_extensions_warning()
2601
process = self.start_bzr_subprocess(['wait-until-signalled'],
2602
skip_if_plan_to_signal=True)
2603
self.assertEqual('running\n', process.stdout.readline())
2604
result = self.finish_bzr_subprocess(process, send_signal=signal.SIGINT,
2606
self.assertEqual('', result[0])
2607
self.assertEqual('bzr: interrupted\n', result[1])
2610
class TestFeature(tests.TestCase):
1829
self.fail('Assertion not raised')
1832
class TestFeature(TestCase):
2612
1834
def test_caching(self):
2613
1835
"""Feature._probe is called by the feature at most once."""
2614
class InstrumentedFeature(tests.Feature):
1836
class InstrumentedFeature(Feature):
2615
1837
def __init__(self):
2616
super(InstrumentedFeature, self).__init__()
1838
Feature.__init__(self)
2617
1839
self.calls = []
2618
1840
def _probe(self):
2619
1841
self.calls.append('_probe')
3211
2334
self.assertEquals('bzrlib.plugins', tpr.resolve_alias('bp'))
3214
class TestThreadLeakDetection(tests.TestCase):
3215
"""Ensure when tests leak threads we detect and report it"""
3217
class LeakRecordingResult(tests.ExtendedTestResult):
3219
tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
3221
def _report_thread_leak(self, test, leaks, alive):
3222
self.leaks.append((test, leaks))
3224
def test_testcase_without_addCleanups(self):
3225
"""Check old TestCase instances don't break with leak detection"""
3226
class Test(unittest.TestCase):
3229
result = self.LeakRecordingResult()
3231
result.startTestRun()
3233
result.stopTestRun()
3234
self.assertEqual(result._tests_leaking_threads_count, 0)
3235
self.assertEqual(result.leaks, [])
3237
def test_thread_leak(self):
3238
"""Ensure a thread that outlives the running of a test is reported
3240
Uses a thread that blocks on an event, and is started by the inner
3241
test case. As the thread outlives the inner case's run, it should be
3242
detected as a leak, but the event is then set so that the thread can
3243
be safely joined in cleanup so it's not leaked for real.
3245
event = threading.Event()
3246
thread = threading.Thread(name="Leaker", target=event.wait)
3247
class Test(tests.TestCase):
3248
def test_leak(self):
3250
result = self.LeakRecordingResult()
3251
test = Test("test_leak")
3252
self.addCleanup(thread.join)
3253
self.addCleanup(event.set)
3254
result.startTestRun()
3256
result.stopTestRun()
3257
self.assertEqual(result._tests_leaking_threads_count, 1)
3258
self.assertEqual(result._first_thread_leaker_id, test.id())
3259
self.assertEqual(result.leaks, [(test, set([thread]))])
3260
self.assertContainsString(result.stream.getvalue(), "leaking threads")
3262
def test_multiple_leaks(self):
3263
"""Check multiple leaks are blamed on the test cases at fault
3265
Same concept as the previous test, but has one inner test method that
3266
leaks two threads, and one that doesn't leak at all.
3268
event = threading.Event()
3269
thread_a = threading.Thread(name="LeakerA", target=event.wait)
3270
thread_b = threading.Thread(name="LeakerB", target=event.wait)
3271
thread_c = threading.Thread(name="LeakerC", target=event.wait)
3272
class Test(tests.TestCase):
3273
def test_first_leak(self):
3275
def test_second_no_leak(self):
3277
def test_third_leak(self):
3280
result = self.LeakRecordingResult()
3281
first_test = Test("test_first_leak")
3282
third_test = Test("test_third_leak")
3283
self.addCleanup(thread_a.join)
3284
self.addCleanup(thread_b.join)
3285
self.addCleanup(thread_c.join)
3286
self.addCleanup(event.set)
3287
result.startTestRun()
3289
[first_test, Test("test_second_no_leak"), third_test]
3291
result.stopTestRun()
3292
self.assertEqual(result._tests_leaking_threads_count, 2)
3293
self.assertEqual(result._first_thread_leaker_id, first_test.id())
3294
self.assertEqual(result.leaks, [
3295
(first_test, set([thread_b])),
3296
(third_test, set([thread_a, thread_c]))])
3297
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
class TestRunSuite(tests.TestCase):
2337
class TestRunSuite(TestCase):
3372
2339
def test_runner_class(self):
3373
2340
"""run_suite accepts and uses a runner_class keyword argument."""
3374
class Stub(tests.TestCase):
2341
class Stub(TestCase):
3375
2342
def test_foo(self):
3377
2344
suite = Stub("test_foo")
3379
class MyRunner(tests.TextTestRunner):
2346
class MyRunner(TextTestRunner):
3380
2347
def run(self, test):
3381
2348
calls.append(test)
3382
return tests.ExtendedTestResult(self.stream, self.descriptions,
3384
tests.run_suite(suite, runner_class=MyRunner, stream=StringIO())
3385
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')
2349
return ExtendedTestResult(self.stream, self.descriptions,
2351
run_suite(suite, runner_class=MyRunner)
2352
self.assertEqual(calls, [suite])