12
13
# You should have received a copy of the GNU General Public License
13
14
# along with this program; if not, write to the Free Software
14
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
"""Tests for the test framework
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
"""Tests for the test framework."""
19
from cStringIO import StringIO
22
from bzrlib.tests import TestCase, _load_module_by_name
25
class SelftestTests(TestCase):
27
def test_import_tests(self):
28
mod = _load_module_by_name('bzrlib.tests.test_selftest')
29
self.assertEqual(mod.SelftestTests, SelftestTests)
31
def test_import_test_failure(self):
32
self.assertRaises(ImportError,
37
class MetaTestLog(TestCase):
29
from testtools import (
30
ExtendedToOriginalDecorator,
33
from testtools.content import Content
34
from testtools.content_type import ContentType
35
from testtools.matchers import (
39
import testtools.tests.helpers
56
from bzrlib.repofmt import (
60
from bzrlib.symbol_versioning import (
65
from bzrlib.tests import (
71
from bzrlib.trace import note, mutter
72
from bzrlib.transport import memory
75
def _test_ids(test_suite):
76
"""Get the ids for the tests in a test suite."""
77
return [t.id() for t in tests.iter_suite_tests(test_suite)]
80
class MetaTestLog(tests.TestCase):
38
82
def test_logging(self):
39
83
"""Test logs are captured when a test fails."""
40
84
self.log('a test message')
41
self._log_file.flush()
42
self.assertContainsRe(self._get_log(), 'a test message\n')
85
details = self.getDetails()
87
self.assertThat(log.content_type, Equals(ContentType(
88
"text", "plain", {"charset": "utf8"})))
89
self.assertThat(u"".join(log.iter_text()), Equals(self.get_log()))
90
self.assertThat(self.get_log(),
91
DocTestMatches(u"...a test message\n", doctest.ELLIPSIS))
94
class TestUnicodeFilename(tests.TestCase):
96
def test_probe_passes(self):
97
"""UnicodeFilename._probe passes."""
98
# We can't test much more than that because the behaviour depends
100
tests.UnicodeFilename._probe()
103
class TestTreeShape(tests.TestCaseInTempDir):
105
def test_unicode_paths(self):
106
self.requireFeature(tests.UnicodeFilename)
108
filename = u'hell\u00d8'
109
self.build_tree_contents([(filename, 'contents of hello')])
110
self.failUnlessExists(filename)
113
class TestClassesAvailable(tests.TestCase):
114
"""As a convenience we expose Test* classes from bzrlib.tests"""
116
def test_test_case(self):
117
from bzrlib.tests import TestCase
119
def test_test_loader(self):
120
from bzrlib.tests import TestLoader
122
def test_test_suite(self):
123
from bzrlib.tests import TestSuite
126
class TestTransportScenarios(tests.TestCase):
127
"""A group of tests that test the transport implementation adaption core.
129
This is a meta test that the tests are applied to all available
132
This will be generalised in the future which is why it is in this
133
test file even though it is specific to transport tests at the moment.
136
def test_get_transport_permutations(self):
137
# this checks that get_test_permutations defined by the module is
138
# called by the get_transport_test_permutations function.
139
class MockModule(object):
140
def get_test_permutations(self):
141
return sample_permutation
142
sample_permutation = [(1,2), (3,4)]
143
from bzrlib.tests.per_transport import get_transport_test_permutations
144
self.assertEqual(sample_permutation,
145
get_transport_test_permutations(MockModule()))
147
def test_scenarios_include_all_modules(self):
148
# this checks that the scenario generator returns as many permutations
149
# as there are in all the registered transport modules - we assume if
150
# this matches its probably doing the right thing especially in
151
# combination with the tests for setting the right classes below.
152
from bzrlib.tests.per_transport import transport_test_permutations
153
from bzrlib.transport import _get_transport_modules
154
modules = _get_transport_modules()
155
permutation_count = 0
156
for module in modules:
158
permutation_count += len(reduce(getattr,
159
(module + ".get_test_permutations").split('.')[1:],
160
__import__(module))())
161
except errors.DependencyNotPresent:
163
scenarios = transport_test_permutations()
164
self.assertEqual(permutation_count, len(scenarios))
166
def test_scenarios_include_transport_class(self):
167
# This test used to know about all the possible transports and the
168
# order they were returned but that seems overly brittle (mbp
170
from bzrlib.tests.per_transport import transport_test_permutations
171
scenarios = transport_test_permutations()
172
# there are at least that many builtin transports
173
self.assertTrue(len(scenarios) > 6)
174
one_scenario = scenarios[0]
175
self.assertIsInstance(one_scenario[0], str)
176
self.assertTrue(issubclass(one_scenario[1]["transport_class"],
177
bzrlib.transport.Transport))
178
self.assertTrue(issubclass(one_scenario[1]["transport_server"],
179
bzrlib.transport.Server))
182
class TestBranchScenarios(tests.TestCase):
184
def test_scenarios(self):
185
# check that constructor parameters are passed through to the adapted
187
from bzrlib.tests.per_branch import make_scenarios
190
formats = [("c", "C"), ("d", "D")]
191
scenarios = make_scenarios(server1, server2, formats)
192
self.assertEqual(2, len(scenarios))
195
{'branch_format': 'c',
196
'bzrdir_format': 'C',
197
'transport_readonly_server': 'b',
198
'transport_server': 'a'}),
200
{'branch_format': 'd',
201
'bzrdir_format': 'D',
202
'transport_readonly_server': 'b',
203
'transport_server': 'a'})],
207
class TestBzrDirScenarios(tests.TestCase):
209
def test_scenarios(self):
210
# check that constructor parameters are passed through to the adapted
212
from bzrlib.tests.per_controldir import make_scenarios
217
scenarios = make_scenarios(vfs_factory, server1, server2, formats)
220
{'bzrdir_format': 'c',
221
'transport_readonly_server': 'b',
222
'transport_server': 'a',
223
'vfs_transport_factory': 'v'}),
225
{'bzrdir_format': 'd',
226
'transport_readonly_server': 'b',
227
'transport_server': 'a',
228
'vfs_transport_factory': 'v'})],
232
class TestRepositoryScenarios(tests.TestCase):
234
def test_formats_to_scenarios(self):
235
from bzrlib.tests.per_repository import formats_to_scenarios
236
formats = [("(c)", remote.RemoteRepositoryFormat()),
237
("(d)", repository.format_registry.get(
238
'Bazaar repository format 2a (needs bzr 1.16 or later)\n'))]
239
no_vfs_scenarios = formats_to_scenarios(formats, "server", "readonly",
241
vfs_scenarios = formats_to_scenarios(formats, "server", "readonly",
242
vfs_transport_factory="vfs")
243
# no_vfs generate scenarios without vfs_transport_factory
245
('RemoteRepositoryFormat(c)',
246
{'bzrdir_format': remote.RemoteBzrDirFormat(),
247
'repository_format': remote.RemoteRepositoryFormat(),
248
'transport_readonly_server': 'readonly',
249
'transport_server': 'server'}),
250
('RepositoryFormat2a(d)',
251
{'bzrdir_format': bzrdir.BzrDirMetaFormat1(),
252
'repository_format': groupcompress_repo.RepositoryFormat2a(),
253
'transport_readonly_server': 'readonly',
254
'transport_server': 'server'})]
255
self.assertEqual(expected, no_vfs_scenarios)
257
('RemoteRepositoryFormat(c)',
258
{'bzrdir_format': remote.RemoteBzrDirFormat(),
259
'repository_format': remote.RemoteRepositoryFormat(),
260
'transport_readonly_server': 'readonly',
261
'transport_server': 'server',
262
'vfs_transport_factory': 'vfs'}),
263
('RepositoryFormat2a(d)',
264
{'bzrdir_format': bzrdir.BzrDirMetaFormat1(),
265
'repository_format': groupcompress_repo.RepositoryFormat2a(),
266
'transport_readonly_server': 'readonly',
267
'transport_server': 'server',
268
'vfs_transport_factory': 'vfs'})],
272
class TestTestScenarioApplication(tests.TestCase):
273
"""Tests for the test adaption facilities."""
275
def test_apply_scenario(self):
276
from bzrlib.tests import apply_scenario
277
input_test = TestTestScenarioApplication("test_apply_scenario")
278
# setup two adapted tests
279
adapted_test1 = apply_scenario(input_test,
281
{"bzrdir_format":"bzr_format",
282
"repository_format":"repo_fmt",
283
"transport_server":"transport_server",
284
"transport_readonly_server":"readonly-server"}))
285
adapted_test2 = apply_scenario(input_test,
286
("new id 2", {"bzrdir_format":None}))
287
# input_test should have been altered.
288
self.assertRaises(AttributeError, getattr, input_test, "bzrdir_format")
289
# the new tests are mutually incompatible, ensuring it has
290
# made new ones, and unspecified elements in the scenario
291
# should not have been altered.
292
self.assertEqual("bzr_format", adapted_test1.bzrdir_format)
293
self.assertEqual("repo_fmt", adapted_test1.repository_format)
294
self.assertEqual("transport_server", adapted_test1.transport_server)
295
self.assertEqual("readonly-server",
296
adapted_test1.transport_readonly_server)
298
"bzrlib.tests.test_selftest.TestTestScenarioApplication."
299
"test_apply_scenario(new id)",
301
self.assertEqual(None, adapted_test2.bzrdir_format)
303
"bzrlib.tests.test_selftest.TestTestScenarioApplication."
304
"test_apply_scenario(new id 2)",
308
class TestInterRepositoryScenarios(tests.TestCase):
310
def test_scenarios(self):
311
# check that constructor parameters are passed through to the adapted
313
from bzrlib.tests.per_interrepository import make_scenarios
316
formats = [("C0", "C1", "C2", "C3"), ("D0", "D1", "D2", "D3")]
317
scenarios = make_scenarios(server1, server2, formats)
320
{'repository_format': 'C1',
321
'repository_format_to': 'C2',
322
'transport_readonly_server': 'b',
323
'transport_server': 'a',
324
'extra_setup': 'C3'}),
326
{'repository_format': 'D1',
327
'repository_format_to': 'D2',
328
'transport_readonly_server': 'b',
329
'transport_server': 'a',
330
'extra_setup': 'D3'})],
334
class TestWorkingTreeScenarios(tests.TestCase):
336
def test_scenarios(self):
337
# check that constructor parameters are passed through to the adapted
339
from bzrlib.tests.per_workingtree import make_scenarios
342
formats = [workingtree.WorkingTreeFormat2(),
343
workingtree.WorkingTreeFormat3(),]
344
scenarios = make_scenarios(server1, server2, formats)
346
('WorkingTreeFormat2',
347
{'bzrdir_format': formats[0]._matchingbzrdir,
348
'transport_readonly_server': 'b',
349
'transport_server': 'a',
350
'workingtree_format': formats[0]}),
351
('WorkingTreeFormat3',
352
{'bzrdir_format': formats[1]._matchingbzrdir,
353
'transport_readonly_server': 'b',
354
'transport_server': 'a',
355
'workingtree_format': formats[1]})],
359
class TestTreeScenarios(tests.TestCase):
361
def test_scenarios(self):
362
# the tree implementation scenario generator is meant to setup one
363
# instance for each working tree format, and one additional instance
364
# that will use the default wt format, but create a revision tree for
365
# the tests. this means that the wt ones should have the
366
# workingtree_to_test_tree attribute set to 'return_parameter' and the
367
# revision one set to revision_tree_from_workingtree.
369
from bzrlib.tests.per_tree import (
370
_dirstate_tree_from_workingtree,
375
revision_tree_from_workingtree
379
formats = [workingtree.WorkingTreeFormat2(),
380
workingtree.WorkingTreeFormat3(),]
381
scenarios = make_scenarios(server1, server2, formats)
382
self.assertEqual(7, len(scenarios))
383
default_wt_format = workingtree.WorkingTreeFormat4._default_format
384
wt4_format = workingtree.WorkingTreeFormat4()
385
wt5_format = workingtree.WorkingTreeFormat5()
386
expected_scenarios = [
387
('WorkingTreeFormat2',
388
{'bzrdir_format': formats[0]._matchingbzrdir,
389
'transport_readonly_server': 'b',
390
'transport_server': 'a',
391
'workingtree_format': formats[0],
392
'_workingtree_to_test_tree': return_parameter,
394
('WorkingTreeFormat3',
395
{'bzrdir_format': formats[1]._matchingbzrdir,
396
'transport_readonly_server': 'b',
397
'transport_server': 'a',
398
'workingtree_format': formats[1],
399
'_workingtree_to_test_tree': return_parameter,
402
{'_workingtree_to_test_tree': revision_tree_from_workingtree,
403
'bzrdir_format': default_wt_format._matchingbzrdir,
404
'transport_readonly_server': 'b',
405
'transport_server': 'a',
406
'workingtree_format': default_wt_format,
408
('DirStateRevisionTree,WT4',
409
{'_workingtree_to_test_tree': _dirstate_tree_from_workingtree,
410
'bzrdir_format': wt4_format._matchingbzrdir,
411
'transport_readonly_server': 'b',
412
'transport_server': 'a',
413
'workingtree_format': wt4_format,
415
('DirStateRevisionTree,WT5',
416
{'_workingtree_to_test_tree': _dirstate_tree_from_workingtree,
417
'bzrdir_format': wt5_format._matchingbzrdir,
418
'transport_readonly_server': 'b',
419
'transport_server': 'a',
420
'workingtree_format': wt5_format,
423
{'_workingtree_to_test_tree': preview_tree_pre,
424
'bzrdir_format': default_wt_format._matchingbzrdir,
425
'transport_readonly_server': 'b',
426
'transport_server': 'a',
427
'workingtree_format': default_wt_format}),
429
{'_workingtree_to_test_tree': preview_tree_post,
430
'bzrdir_format': default_wt_format._matchingbzrdir,
431
'transport_readonly_server': 'b',
432
'transport_server': 'a',
433
'workingtree_format': default_wt_format}),
435
self.assertEqual(expected_scenarios, scenarios)
438
class TestInterTreeScenarios(tests.TestCase):
439
"""A group of tests that test the InterTreeTestAdapter."""
441
def test_scenarios(self):
442
# check that constructor parameters are passed through to the adapted
444
# for InterTree tests we want the machinery to bring up two trees in
445
# each instance: the base one, and the one we are interacting with.
446
# because each optimiser can be direction specific, we need to test
447
# each optimiser in its chosen direction.
448
# unlike the TestProviderAdapter we dont want to automatically add a
449
# parameterized one for WorkingTree - the optimisers will tell us what
451
from bzrlib.tests.per_tree import (
453
revision_tree_from_workingtree
455
from bzrlib.tests.per_intertree import (
458
from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
459
input_test = TestInterTreeScenarios(
463
format1 = WorkingTreeFormat2()
464
format2 = WorkingTreeFormat3()
465
formats = [("1", str, format1, format2, "converter1"),
466
("2", int, format2, format1, "converter2")]
467
scenarios = make_scenarios(server1, server2, formats)
468
self.assertEqual(2, len(scenarios))
469
expected_scenarios = [
471
"bzrdir_format": format1._matchingbzrdir,
472
"intertree_class": formats[0][1],
473
"workingtree_format": formats[0][2],
474
"workingtree_format_to": formats[0][3],
475
"mutable_trees_to_test_trees": formats[0][4],
476
"_workingtree_to_test_tree": return_parameter,
477
"transport_server": server1,
478
"transport_readonly_server": server2,
481
"bzrdir_format": format2._matchingbzrdir,
482
"intertree_class": formats[1][1],
483
"workingtree_format": formats[1][2],
484
"workingtree_format_to": formats[1][3],
485
"mutable_trees_to_test_trees": formats[1][4],
486
"_workingtree_to_test_tree": return_parameter,
487
"transport_server": server1,
488
"transport_readonly_server": server2,
491
self.assertEqual(scenarios, expected_scenarios)
494
class TestTestCaseInTempDir(tests.TestCaseInTempDir):
496
def test_home_is_not_working(self):
497
self.assertNotEqual(self.test_dir, self.test_home_dir)
498
cwd = osutils.getcwd()
499
self.assertIsSameRealPath(self.test_dir, cwd)
500
self.assertIsSameRealPath(self.test_home_dir, os.environ['HOME'])
502
def test_assertEqualStat_equal(self):
503
from bzrlib.tests.test_dirstate import _FakeStat
504
self.build_tree(["foo"])
505
real = os.lstat("foo")
506
fake = _FakeStat(real.st_size, real.st_mtime, real.st_ctime,
507
real.st_dev, real.st_ino, real.st_mode)
508
self.assertEqualStat(real, fake)
510
def test_assertEqualStat_notequal(self):
511
self.build_tree(["foo", "longname"])
512
self.assertRaises(AssertionError, self.assertEqualStat,
513
os.lstat("foo"), os.lstat("longname"))
516
class TestTestCaseWithMemoryTransport(tests.TestCaseWithMemoryTransport):
518
def test_home_is_non_existant_dir_under_root(self):
519
"""The test_home_dir for TestCaseWithMemoryTransport is missing.
521
This is because TestCaseWithMemoryTransport is for tests that do not
522
need any disk resources: they should be hooked into bzrlib in such a
523
way that no global settings are being changed by the test (only a
524
few tests should need to do that), and having a missing dir as home is
525
an effective way to ensure that this is the case.
527
self.assertIsSameRealPath(
528
self.TEST_ROOT + "/MemoryTransportMissingHomeDir",
530
self.assertIsSameRealPath(self.test_home_dir, os.environ['HOME'])
532
def test_cwd_is_TEST_ROOT(self):
533
self.assertIsSameRealPath(self.test_dir, self.TEST_ROOT)
534
cwd = osutils.getcwd()
535
self.assertIsSameRealPath(self.test_dir, cwd)
537
def test_BZR_HOME_and_HOME_are_bytestrings(self):
538
"""The $BZR_HOME and $HOME environment variables should not be unicode.
540
See https://bugs.launchpad.net/bzr/+bug/464174
542
self.assertIsInstance(os.environ['BZR_HOME'], str)
543
self.assertIsInstance(os.environ['HOME'], str)
545
def test_make_branch_and_memory_tree(self):
546
"""In TestCaseWithMemoryTransport we should not make the branch on disk.
548
This is hard to comprehensively robustly test, so we settle for making
549
a branch and checking no directory was created at its relpath.
551
tree = self.make_branch_and_memory_tree('dir')
552
# Guard against regression into MemoryTransport leaking
553
# files to disk instead of keeping them in memory.
554
self.failIf(osutils.lexists('dir'))
555
self.assertIsInstance(tree, memorytree.MemoryTree)
557
def test_make_branch_and_memory_tree_with_format(self):
558
"""make_branch_and_memory_tree should accept a format option."""
559
format = bzrdir.BzrDirMetaFormat1()
560
format.repository_format = weaverepo.RepositoryFormat7()
561
tree = self.make_branch_and_memory_tree('dir', format=format)
562
# Guard against regression into MemoryTransport leaking
563
# files to disk instead of keeping them in memory.
564
self.failIf(osutils.lexists('dir'))
565
self.assertIsInstance(tree, memorytree.MemoryTree)
566
self.assertEqual(format.repository_format.__class__,
567
tree.branch.repository._format.__class__)
569
def test_make_branch_builder(self):
570
builder = self.make_branch_builder('dir')
571
self.assertIsInstance(builder, branchbuilder.BranchBuilder)
572
# Guard against regression into MemoryTransport leaking
573
# files to disk instead of keeping them in memory.
574
self.failIf(osutils.lexists('dir'))
576
def test_make_branch_builder_with_format(self):
577
# Use a repo layout that doesn't conform to a 'named' layout, to ensure
578
# that the format objects are used.
579
format = bzrdir.BzrDirMetaFormat1()
580
repo_format = weaverepo.RepositoryFormat7()
581
format.repository_format = repo_format
582
builder = self.make_branch_builder('dir', format=format)
583
the_branch = builder.get_branch()
584
# Guard against regression into MemoryTransport leaking
585
# files to disk instead of keeping them in memory.
586
self.failIf(osutils.lexists('dir'))
587
self.assertEqual(format.repository_format.__class__,
588
the_branch.repository._format.__class__)
589
self.assertEqual(repo_format.get_format_string(),
590
self.get_transport().get_bytes(
591
'dir/.bzr/repository/format'))
593
def test_make_branch_builder_with_format_name(self):
594
builder = self.make_branch_builder('dir', format='knit')
595
the_branch = builder.get_branch()
596
# Guard against regression into MemoryTransport leaking
597
# files to disk instead of keeping them in memory.
598
self.failIf(osutils.lexists('dir'))
599
dir_format = bzrdir.format_registry.make_bzrdir('knit')
600
self.assertEqual(dir_format.repository_format.__class__,
601
the_branch.repository._format.__class__)
602
self.assertEqual('Bazaar-NG Knit Repository Format 1',
603
self.get_transport().get_bytes(
604
'dir/.bzr/repository/format'))
606
def test_dangling_locks_cause_failures(self):
607
class TestDanglingLock(tests.TestCaseWithMemoryTransport):
608
def test_function(self):
609
t = self.get_transport('.')
610
l = lockdir.LockDir(t, 'lock')
613
test = TestDanglingLock('test_function')
615
total_failures = result.errors + result.failures
616
if self._lock_check_thorough:
617
self.assertEqual(1, len(total_failures))
619
# When _lock_check_thorough is disabled, then we don't trigger a
621
self.assertEqual(0, len(total_failures))
624
class TestTestCaseWithTransport(tests.TestCaseWithTransport):
625
"""Tests for the convenience functions TestCaseWithTransport introduces."""
627
def test_get_readonly_url_none(self):
628
from bzrlib.transport.readonly import ReadonlyTransportDecorator
629
self.vfs_transport_factory = memory.MemoryServer
630
self.transport_readonly_server = None
631
# calling get_readonly_transport() constructs a decorator on the url
633
url = self.get_readonly_url()
634
url2 = self.get_readonly_url('foo/bar')
635
t = transport.get_transport(url)
636
t2 = transport.get_transport(url2)
637
self.failUnless(isinstance(t, ReadonlyTransportDecorator))
638
self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
639
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
641
def test_get_readonly_url_http(self):
642
from bzrlib.tests.http_server import HttpServer
643
from bzrlib.transport.http import HttpTransportBase
644
self.transport_server = test_server.LocalURLServer
645
self.transport_readonly_server = HttpServer
646
# calling get_readonly_transport() gives us a HTTP server instance.
647
url = self.get_readonly_url()
648
url2 = self.get_readonly_url('foo/bar')
649
# the transport returned may be any HttpTransportBase subclass
650
t = transport.get_transport(url)
651
t2 = transport.get_transport(url2)
652
self.failUnless(isinstance(t, HttpTransportBase))
653
self.failUnless(isinstance(t2, HttpTransportBase))
654
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
656
def test_is_directory(self):
657
"""Test assertIsDirectory assertion"""
658
t = self.get_transport()
659
self.build_tree(['a_dir/', 'a_file'], transport=t)
660
self.assertIsDirectory('a_dir', t)
661
self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
662
self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
664
def test_make_branch_builder(self):
665
builder = self.make_branch_builder('dir')
666
rev_id = builder.build_commit()
667
self.failUnlessExists('dir')
668
a_dir = bzrdir.BzrDir.open('dir')
669
self.assertRaises(errors.NoWorkingTree, a_dir.open_workingtree)
670
a_branch = a_dir.open_branch()
671
builder_branch = builder.get_branch()
672
self.assertEqual(a_branch.base, builder_branch.base)
673
self.assertEqual((1, rev_id), builder_branch.last_revision_info())
674
self.assertEqual((1, rev_id), a_branch.last_revision_info())
677
class TestTestCaseTransports(tests.TestCaseWithTransport):
680
super(TestTestCaseTransports, self).setUp()
681
self.vfs_transport_factory = memory.MemoryServer
683
def test_make_bzrdir_preserves_transport(self):
684
t = self.get_transport()
685
result_bzrdir = self.make_bzrdir('subdir')
686
self.assertIsInstance(result_bzrdir.transport,
687
memory.MemoryTransport)
688
# should not be on disk, should only be in memory
689
self.failIfExists('subdir')
692
class TestChrootedTest(tests.ChrootedTestCase):
694
def test_root_is_root(self):
695
t = transport.get_transport(self.get_readonly_url())
697
self.assertEqual(url, t.clone('..').base)
700
class TestProfileResult(tests.TestCase):
702
def test_profiles_tests(self):
703
self.requireFeature(test_lsprof.LSProfFeature)
704
terminal = testtools.tests.helpers.ExtendedTestResult()
705
result = tests.ProfileResult(terminal)
706
class Sample(tests.TestCase):
708
self.sample_function()
709
def sample_function(self):
713
case = terminal._events[0][1]
714
self.assertLength(1, case._benchcalls)
715
# We must be able to unpack it as the test reporting code wants
716
(_, _, _), stats = case._benchcalls[0]
717
self.assertTrue(callable(stats.pprint))
720
class TestTestResult(tests.TestCase):
722
def check_timing(self, test_case, expected_re):
723
result = bzrlib.tests.TextTestResult(self._log_file,
727
capture = testtools.tests.helpers.ExtendedTestResult()
728
test_case.run(MultiTestResult(result, capture))
729
run_case = capture._events[0][1]
730
timed_string = result._testTimeString(run_case)
731
self.assertContainsRe(timed_string, expected_re)
733
def test_test_reporting(self):
734
class ShortDelayTestCase(tests.TestCase):
735
def test_short_delay(self):
737
def test_short_benchmark(self):
738
self.time(time.sleep, 0.003)
739
self.check_timing(ShortDelayTestCase('test_short_delay'),
741
# if a benchmark time is given, we now show just that time followed by
743
self.check_timing(ShortDelayTestCase('test_short_benchmark'),
746
def test_unittest_reporting_unittest_class(self):
747
# getting the time from a non-bzrlib test works ok
748
class ShortDelayTestCase(unittest.TestCase):
749
def test_short_delay(self):
751
self.check_timing(ShortDelayTestCase('test_short_delay'),
754
def _patch_get_bzr_source_tree(self):
755
# Reading from the actual source tree breaks isolation, but we don't
756
# want to assume that thats *all* that would happen.
757
self.overrideAttr(bzrlib.version, '_get_bzr_source_tree', lambda: None)
759
def test_assigned_benchmark_file_stores_date(self):
760
self._patch_get_bzr_source_tree()
762
result = bzrlib.tests.TextTestResult(self._log_file,
767
output_string = output.getvalue()
768
# if you are wondering about the regexp please read the comment in
769
# test_bench_history (bzrlib.tests.test_selftest.TestRunner)
770
# XXX: what comment? -- Andrew Bennetts
771
self.assertContainsRe(output_string, "--date [0-9.]+")
773
def test_benchhistory_records_test_times(self):
774
self._patch_get_bzr_source_tree()
775
result_stream = StringIO()
776
result = bzrlib.tests.TextTestResult(
780
bench_history=result_stream
783
# we want profile a call and check that its test duration is recorded
784
# make a new test instance that when run will generate a benchmark
785
example_test_case = TestTestResult("_time_hello_world_encoding")
786
# execute the test, which should succeed and record times
787
example_test_case.run(result)
788
lines = result_stream.getvalue().splitlines()
789
self.assertEqual(2, len(lines))
790
self.assertContainsRe(lines[1],
791
" *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
792
"._time_hello_world_encoding")
794
def _time_hello_world_encoding(self):
795
"""Profile two sleep calls
797
This is used to exercise the test framework.
799
self.time(unicode, 'hello', errors='replace')
800
self.time(unicode, 'world', errors='replace')
802
def test_lsprofiling(self):
803
"""Verbose test result prints lsprof statistics from test cases."""
804
self.requireFeature(test_lsprof.LSProfFeature)
805
result_stream = StringIO()
806
result = bzrlib.tests.VerboseTestResult(
811
# we want profile a call of some sort and check it is output by
812
# addSuccess. We dont care about addError or addFailure as they
813
# are not that interesting for performance tuning.
814
# make a new test instance that when run will generate a profile
815
example_test_case = TestTestResult("_time_hello_world_encoding")
816
example_test_case._gather_lsprof_in_benchmarks = True
817
# execute the test, which should succeed and record profiles
818
example_test_case.run(result)
819
# lsprofile_something()
820
# if this worked we want
821
# LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
822
# CallCount Recursive Total(ms) Inline(ms) module:lineno(function)
823
# (the lsprof header)
824
# ... an arbitrary number of lines
825
# and the function call which is time.sleep.
826
# 1 0 ??? ??? ???(sleep)
827
# and then repeated but with 'world', rather than 'hello'.
828
# this should appear in the output stream of our test result.
829
output = result_stream.getvalue()
830
self.assertContainsRe(output,
831
r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
832
self.assertContainsRe(output,
833
r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
834
self.assertContainsRe(output,
835
r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
836
self.assertContainsRe(output,
837
r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
839
def test_uses_time_from_testtools(self):
840
"""Test case timings in verbose results should use testtools times"""
842
class TimeAddedVerboseTestResult(tests.VerboseTestResult):
843
def startTest(self, test):
844
self.time(datetime.datetime.utcfromtimestamp(1.145))
845
super(TimeAddedVerboseTestResult, self).startTest(test)
846
def addSuccess(self, test):
847
self.time(datetime.datetime.utcfromtimestamp(51.147))
848
super(TimeAddedVerboseTestResult, self).addSuccess(test)
849
def report_tests_starting(self): pass
851
self.get_passing_test().run(TimeAddedVerboseTestResult(sio, 0, 2))
852
self.assertEndsWith(sio.getvalue(), "OK 50002ms\n")
854
def test_known_failure(self):
855
"""A KnownFailure being raised should trigger several result actions."""
856
class InstrumentedTestResult(tests.ExtendedTestResult):
857
def stopTestRun(self): pass
858
def report_tests_starting(self): pass
859
def report_known_failure(self, test, err=None, details=None):
860
self._call = test, 'known failure'
861
result = InstrumentedTestResult(None, None, None, None)
862
class Test(tests.TestCase):
863
def test_function(self):
864
raise tests.KnownFailure('failed!')
865
test = Test("test_function")
867
# it should invoke 'report_known_failure'.
868
self.assertEqual(2, len(result._call))
869
self.assertEqual(test.id(), result._call[0].id())
870
self.assertEqual('known failure', result._call[1])
871
# we dont introspec the traceback, if the rest is ok, it would be
872
# exceptional for it not to be.
873
# it should update the known_failure_count on the object.
874
self.assertEqual(1, result.known_failure_count)
875
# the result should be successful.
876
self.assertTrue(result.wasSuccessful())
878
def test_verbose_report_known_failure(self):
879
# verbose test output formatting
880
result_stream = StringIO()
881
result = bzrlib.tests.VerboseTestResult(
886
test = self.get_passing_test()
887
result.startTest(test)
888
prefix = len(result_stream.getvalue())
889
# the err parameter has the shape:
890
# (class, exception object, traceback)
891
# KnownFailures dont get their tracebacks shown though, so we
893
err = (tests.KnownFailure, tests.KnownFailure('foo'), None)
894
result.report_known_failure(test, err)
895
output = result_stream.getvalue()[prefix:]
896
lines = output.splitlines()
897
self.assertContainsRe(lines[0], r'XFAIL *\d+ms$')
898
if sys.version_info > (2, 7):
899
self.expectFailure("_ExpectedFailure on 2.7 loses the message",
900
self.assertNotEqual, lines[1], ' ')
901
self.assertEqual(lines[1], ' foo')
902
self.assertEqual(2, len(lines))
904
def get_passing_test(self):
905
"""Return a test object that can't be run usefully."""
908
return unittest.FunctionTestCase(passing_test)
910
def test_add_not_supported(self):
911
"""Test the behaviour of invoking addNotSupported."""
912
class InstrumentedTestResult(tests.ExtendedTestResult):
913
def stopTestRun(self): pass
914
def report_tests_starting(self): pass
915
def report_unsupported(self, test, feature):
916
self._call = test, feature
917
result = InstrumentedTestResult(None, None, None, None)
918
test = SampleTestCase('_test_pass')
919
feature = tests.Feature()
920
result.startTest(test)
921
result.addNotSupported(test, feature)
922
# it should invoke 'report_unsupported'.
923
self.assertEqual(2, len(result._call))
924
self.assertEqual(test, result._call[0])
925
self.assertEqual(feature, result._call[1])
926
# the result should be successful.
927
self.assertTrue(result.wasSuccessful())
928
# it should record the test against a count of tests not run due to
930
self.assertEqual(1, result.unsupported['Feature'])
931
# and invoking it again should increment that counter
932
result.addNotSupported(test, feature)
933
self.assertEqual(2, result.unsupported['Feature'])
935
def test_verbose_report_unsupported(self):
936
# verbose test output formatting
937
result_stream = StringIO()
938
result = bzrlib.tests.VerboseTestResult(
943
test = self.get_passing_test()
944
feature = tests.Feature()
945
result.startTest(test)
946
prefix = len(result_stream.getvalue())
947
result.report_unsupported(test, feature)
948
output = result_stream.getvalue()[prefix:]
949
lines = output.splitlines()
950
# We don't check for the final '0ms' since it may fail on slow hosts
951
self.assertStartsWith(lines[0], 'NODEP')
952
self.assertEqual(lines[1],
953
" The feature 'Feature' is not available.")
955
def test_unavailable_exception(self):
956
"""An UnavailableFeature being raised should invoke addNotSupported."""
957
class InstrumentedTestResult(tests.ExtendedTestResult):
958
def stopTestRun(self): pass
959
def report_tests_starting(self): pass
960
def addNotSupported(self, test, feature):
961
self._call = test, feature
962
result = InstrumentedTestResult(None, None, None, None)
963
feature = tests.Feature()
964
class Test(tests.TestCase):
965
def test_function(self):
966
raise tests.UnavailableFeature(feature)
967
test = Test("test_function")
969
# it should invoke 'addNotSupported'.
970
self.assertEqual(2, len(result._call))
971
self.assertEqual(test.id(), result._call[0].id())
972
self.assertEqual(feature, result._call[1])
973
# and not count as an error
974
self.assertEqual(0, result.error_count)
976
def test_strict_with_unsupported_feature(self):
977
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
979
test = self.get_passing_test()
980
feature = "Unsupported Feature"
981
result.addNotSupported(test, feature)
982
self.assertFalse(result.wasStrictlySuccessful())
983
self.assertEqual(None, result._extractBenchmarkTime(test))
985
def test_strict_with_known_failure(self):
986
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
988
test = self.get_passing_test()
989
err = (tests.KnownFailure, tests.KnownFailure('foo'), None)
990
result.addExpectedFailure(test, err)
991
self.assertFalse(result.wasStrictlySuccessful())
992
self.assertEqual(None, result._extractBenchmarkTime(test))
994
def test_strict_with_success(self):
995
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
997
test = self.get_passing_test()
998
result.addSuccess(test)
999
self.assertTrue(result.wasStrictlySuccessful())
1000
self.assertEqual(None, result._extractBenchmarkTime(test))
1002
def test_startTests(self):
1003
"""Starting the first test should trigger startTests."""
1004
class InstrumentedTestResult(tests.ExtendedTestResult):
1006
def startTests(self): self.calls += 1
1007
result = InstrumentedTestResult(None, None, None, None)
1008
def test_function():
1010
test = unittest.FunctionTestCase(test_function)
1012
self.assertEquals(1, result.calls)
1014
def test_startTests_only_once(self):
1015
"""With multiple tests startTests should still only be called once"""
1016
class InstrumentedTestResult(tests.ExtendedTestResult):
1018
def startTests(self): self.calls += 1
1019
result = InstrumentedTestResult(None, None, None, None)
1020
suite = unittest.TestSuite([
1021
unittest.FunctionTestCase(lambda: None),
1022
unittest.FunctionTestCase(lambda: None)])
1024
self.assertEquals(1, result.calls)
1025
self.assertEquals(2, result.count)
1028
class TestUnicodeFilenameFeature(tests.TestCase):
1030
def test_probe_passes(self):
1031
"""UnicodeFilenameFeature._probe passes."""
1032
# We can't test much more than that because the behaviour depends
1034
tests.UnicodeFilenameFeature._probe()
1037
class TestRunner(tests.TestCase):
1039
def dummy_test(self):
1042
def run_test_runner(self, testrunner, test):
1043
"""Run suite in testrunner, saving global state and restoring it.
1045
This current saves and restores:
1046
TestCaseInTempDir.TEST_ROOT
1048
There should be no tests in this file that use
1049
bzrlib.tests.TextTestRunner without using this convenience method,
1050
because of our use of global state.
1052
old_root = tests.TestCaseInTempDir.TEST_ROOT
1054
tests.TestCaseInTempDir.TEST_ROOT = None
1055
return testrunner.run(test)
1057
tests.TestCaseInTempDir.TEST_ROOT = old_root
1059
def test_known_failure_failed_run(self):
1060
# run a test that generates a known failure which should be printed in
1061
# the final output when real failures occur.
1062
class Test(tests.TestCase):
1063
def known_failure_test(self):
1064
self.expectFailure('failed', self.assertTrue, False)
1065
test = unittest.TestSuite()
1066
test.addTest(Test("known_failure_test"))
1069
test.addTest(unittest.FunctionTestCase(failing_test))
1071
runner = tests.TextTestRunner(stream=stream)
1072
result = self.run_test_runner(runner, test)
1073
lines = stream.getvalue().splitlines()
1074
self.assertContainsRe(stream.getvalue(),
1075
'(?sm)^bzr selftest.*$'
1077
'^======================================================================\n'
1078
'^FAIL: failing_test\n'
1079
'^----------------------------------------------------------------------\n'
1080
'Traceback \\(most recent call last\\):\n'
1081
' .*' # File .*, line .*, in failing_test' - but maybe not from .pyc
1082
' self.fail\\(\'foo\'\\)\n'
1084
'^----------------------------------------------------------------------\n'
1086
'FAILED \\(failures=1, known_failure_count=1\\)'
1089
def test_known_failure_ok_run(self):
1090
# run a test that generates a known failure which should be printed in
1092
class Test(tests.TestCase):
1093
def known_failure_test(self):
1094
self.expectFailure('failed', self.assertTrue, False)
1095
test = Test("known_failure_test")
1097
runner = tests.TextTestRunner(stream=stream)
1098
result = self.run_test_runner(runner, test)
1099
self.assertContainsRe(stream.getvalue(),
1102
'Ran 1 test in .*\n'
1104
'OK \\(known_failures=1\\)\n')
1106
def test_result_decorator(self):
1109
class LoggingDecorator(ExtendedToOriginalDecorator):
1110
def startTest(self, test):
1111
ExtendedToOriginalDecorator.startTest(self, test)
1112
calls.append('start')
1113
test = unittest.FunctionTestCase(lambda:None)
1115
runner = tests.TextTestRunner(stream=stream,
1116
result_decorators=[LoggingDecorator])
1117
result = self.run_test_runner(runner, test)
1118
self.assertLength(1, calls)
1120
def test_skipped_test(self):
1121
# run a test that is skipped, and check the suite as a whole still
1123
# skipping_test must be hidden in here so it's not run as a real test
1124
class SkippingTest(tests.TestCase):
1125
def skipping_test(self):
1126
raise tests.TestSkipped('test intentionally skipped')
1127
runner = tests.TextTestRunner(stream=self._log_file)
1128
test = SkippingTest("skipping_test")
1129
result = self.run_test_runner(runner, test)
1130
self.assertTrue(result.wasSuccessful())
1132
def test_skipped_from_setup(self):
1134
class SkippedSetupTest(tests.TestCase):
1137
calls.append('setUp')
1138
self.addCleanup(self.cleanup)
1139
raise tests.TestSkipped('skipped setup')
1141
def test_skip(self):
1142
self.fail('test reached')
1145
calls.append('cleanup')
1147
runner = tests.TextTestRunner(stream=self._log_file)
1148
test = SkippedSetupTest('test_skip')
1149
result = self.run_test_runner(runner, test)
1150
self.assertTrue(result.wasSuccessful())
1151
# Check if cleanup was called the right number of times.
1152
self.assertEqual(['setUp', 'cleanup'], calls)
1154
def test_skipped_from_test(self):
1156
class SkippedTest(tests.TestCase):
1159
tests.TestCase.setUp(self)
1160
calls.append('setUp')
1161
self.addCleanup(self.cleanup)
1163
def test_skip(self):
1164
raise tests.TestSkipped('skipped test')
1167
calls.append('cleanup')
1169
runner = tests.TextTestRunner(stream=self._log_file)
1170
test = SkippedTest('test_skip')
1171
result = self.run_test_runner(runner, test)
1172
self.assertTrue(result.wasSuccessful())
1173
# Check if cleanup was called the right number of times.
1174
self.assertEqual(['setUp', 'cleanup'], calls)
1176
def test_not_applicable(self):
1177
# run a test that is skipped because it's not applicable
1178
class Test(tests.TestCase):
1179
def not_applicable_test(self):
1180
raise tests.TestNotApplicable('this test never runs')
1182
runner = tests.TextTestRunner(stream=out, verbosity=2)
1183
test = Test("not_applicable_test")
1184
result = self.run_test_runner(runner, test)
1185
self._log_file.write(out.getvalue())
1186
self.assertTrue(result.wasSuccessful())
1187
self.assertTrue(result.wasStrictlySuccessful())
1188
self.assertContainsRe(out.getvalue(),
1189
r'(?m)not_applicable_test * N/A')
1190
self.assertContainsRe(out.getvalue(),
1191
r'(?m)^ this test never runs')
1193
def test_unsupported_features_listed(self):
1194
"""When unsupported features are encountered they are detailed."""
1195
class Feature1(tests.Feature):
1196
def _probe(self): return False
1197
class Feature2(tests.Feature):
1198
def _probe(self): return False
1199
# create sample tests
1200
test1 = SampleTestCase('_test_pass')
1201
test1._test_needs_features = [Feature1()]
1202
test2 = SampleTestCase('_test_pass')
1203
test2._test_needs_features = [Feature2()]
1204
test = unittest.TestSuite()
1208
runner = tests.TextTestRunner(stream=stream)
1209
result = self.run_test_runner(runner, test)
1210
lines = stream.getvalue().splitlines()
1213
"Missing feature 'Feature1' skipped 1 tests.",
1214
"Missing feature 'Feature2' skipped 1 tests.",
1218
def _patch_get_bzr_source_tree(self):
1219
# Reading from the actual source tree breaks isolation, but we don't
1220
# want to assume that thats *all* that would happen.
1221
self._get_source_tree_calls = []
1223
self._get_source_tree_calls.append("called")
1225
self.overrideAttr(bzrlib.version, '_get_bzr_source_tree', new_get)
1227
def test_bench_history(self):
1228
# tests that the running the benchmark passes bench_history into
1229
# the test result object. We can tell that happens if
1230
# _get_bzr_source_tree is called.
1231
self._patch_get_bzr_source_tree()
1232
test = TestRunner('dummy_test')
1234
runner = tests.TextTestRunner(stream=self._log_file,
1235
bench_history=output)
1236
result = self.run_test_runner(runner, test)
1237
output_string = output.getvalue()
1238
self.assertContainsRe(output_string, "--date [0-9.]+")
1239
self.assertLength(1, self._get_source_tree_calls)
1241
def test_verbose_test_count(self):
1242
"""A verbose test run reports the right test count at the start"""
1243
suite = TestUtil.TestSuite([
1244
unittest.FunctionTestCase(lambda:None),
1245
unittest.FunctionTestCase(lambda:None)])
1246
self.assertEqual(suite.countTestCases(), 2)
1248
runner = tests.TextTestRunner(stream=stream, verbosity=2)
1249
# Need to use the CountingDecorator as that's what sets num_tests
1250
result = self.run_test_runner(runner, tests.CountingDecorator(suite))
1251
self.assertStartsWith(stream.getvalue(), "running 2 tests")
1253
def test_startTestRun(self):
1254
"""run should call result.startTestRun()"""
1256
class LoggingDecorator(ExtendedToOriginalDecorator):
1257
def startTestRun(self):
1258
ExtendedToOriginalDecorator.startTestRun(self)
1259
calls.append('startTestRun')
1260
test = unittest.FunctionTestCase(lambda:None)
1262
runner = tests.TextTestRunner(stream=stream,
1263
result_decorators=[LoggingDecorator])
1264
result = self.run_test_runner(runner, test)
1265
self.assertLength(1, calls)
1267
def test_stopTestRun(self):
1268
"""run should call result.stopTestRun()"""
1270
class LoggingDecorator(ExtendedToOriginalDecorator):
1271
def stopTestRun(self):
1272
ExtendedToOriginalDecorator.stopTestRun(self)
1273
calls.append('stopTestRun')
1274
test = unittest.FunctionTestCase(lambda:None)
1276
runner = tests.TextTestRunner(stream=stream,
1277
result_decorators=[LoggingDecorator])
1278
result = self.run_test_runner(runner, test)
1279
self.assertLength(1, calls)
1281
def test_unicode_test_output_on_ascii_stream(self):
1282
"""Showing results should always succeed even on an ascii console"""
1283
class FailureWithUnicode(tests.TestCase):
1284
def test_log_unicode(self):
1286
self.fail("Now print that log!")
1288
self.overrideAttr(osutils, "get_terminal_encoding",
1289
lambda trace=False: "ascii")
1290
result = self.run_test_runner(tests.TextTestRunner(stream=out),
1291
FailureWithUnicode("test_log_unicode"))
1292
self.assertContainsRe(out.getvalue(),
1293
"Text attachment: log\n"
1295
"\d+\.\d+ \\\\u2606\n"
1299
class SampleTestCase(tests.TestCase):
1301
def _test_pass(self):
1304
class _TestException(Exception):
1308
class TestTestCase(tests.TestCase):
1309
"""Tests that test the core bzrlib TestCase."""
1311
def test_assertLength_matches_empty(self):
1313
self.assertLength(0, a_list)
1315
def test_assertLength_matches_nonempty(self):
1317
self.assertLength(3, a_list)
1319
def test_assertLength_fails_different(self):
1321
self.assertRaises(AssertionError, self.assertLength, 1, a_list)
1323
def test_assertLength_shows_sequence_in_failure(self):
1325
exception = self.assertRaises(AssertionError, self.assertLength, 2,
1327
self.assertEqual('Incorrect length: wanted 2, got 3 for [1, 2, 3]',
1330
def test_base_setUp_not_called_causes_failure(self):
1331
class TestCaseWithBrokenSetUp(tests.TestCase):
1333
pass # does not call TestCase.setUp
1336
test = TestCaseWithBrokenSetUp('test_foo')
1337
result = unittest.TestResult()
1339
self.assertFalse(result.wasSuccessful())
1340
self.assertEqual(1, result.testsRun)
1342
def test_base_tearDown_not_called_causes_failure(self):
1343
class TestCaseWithBrokenTearDown(tests.TestCase):
1345
pass # does not call TestCase.tearDown
1348
test = TestCaseWithBrokenTearDown('test_foo')
1349
result = unittest.TestResult()
1351
self.assertFalse(result.wasSuccessful())
1352
self.assertEqual(1, result.testsRun)
1354
def test_debug_flags_sanitised(self):
1355
"""The bzrlib debug flags should be sanitised by setUp."""
1356
if 'allow_debug' in tests.selftest_debug_flags:
1357
raise tests.TestNotApplicable(
1358
'-Eallow_debug option prevents debug flag sanitisation')
1359
# we could set something and run a test that will check
1360
# it gets santised, but this is probably sufficient for now:
1361
# if someone runs the test with -Dsomething it will error.
1363
if self._lock_check_thorough:
1364
flags.add('strict_locks')
1365
self.assertEqual(flags, bzrlib.debug.debug_flags)
1367
def change_selftest_debug_flags(self, new_flags):
1368
self.overrideAttr(tests, 'selftest_debug_flags', set(new_flags))
1370
def test_allow_debug_flag(self):
1371
"""The -Eallow_debug flag prevents bzrlib.debug.debug_flags from being
1372
sanitised (i.e. cleared) before running a test.
1374
self.change_selftest_debug_flags(set(['allow_debug']))
1375
bzrlib.debug.debug_flags = set(['a-flag'])
1376
class TestThatRecordsFlags(tests.TestCase):
1377
def test_foo(nested_self):
1378
self.flags = set(bzrlib.debug.debug_flags)
1379
test = TestThatRecordsFlags('test_foo')
1380
test.run(self.make_test_result())
1381
flags = set(['a-flag'])
1382
if 'disable_lock_checks' not in tests.selftest_debug_flags:
1383
flags.add('strict_locks')
1384
self.assertEqual(flags, self.flags)
1386
def test_disable_lock_checks(self):
1387
"""The -Edisable_lock_checks flag disables thorough checks."""
1388
class TestThatRecordsFlags(tests.TestCase):
1389
def test_foo(nested_self):
1390
self.flags = set(bzrlib.debug.debug_flags)
1391
self.test_lock_check_thorough = nested_self._lock_check_thorough
1392
self.change_selftest_debug_flags(set())
1393
test = TestThatRecordsFlags('test_foo')
1394
test.run(self.make_test_result())
1395
# By default we do strict lock checking and thorough lock/unlock
1397
self.assertTrue(self.test_lock_check_thorough)
1398
self.assertEqual(set(['strict_locks']), self.flags)
1399
# Now set the disable_lock_checks flag, and show that this changed.
1400
self.change_selftest_debug_flags(set(['disable_lock_checks']))
1401
test = TestThatRecordsFlags('test_foo')
1402
test.run(self.make_test_result())
1403
self.assertFalse(self.test_lock_check_thorough)
1404
self.assertEqual(set(), self.flags)
1406
def test_this_fails_strict_lock_check(self):
1407
class TestThatRecordsFlags(tests.TestCase):
1408
def test_foo(nested_self):
1409
self.flags1 = set(bzrlib.debug.debug_flags)
1410
self.thisFailsStrictLockCheck()
1411
self.flags2 = set(bzrlib.debug.debug_flags)
1412
# Make sure lock checking is active
1413
self.change_selftest_debug_flags(set())
1414
test = TestThatRecordsFlags('test_foo')
1415
test.run(self.make_test_result())
1416
self.assertEqual(set(['strict_locks']), self.flags1)
1417
self.assertEqual(set(), self.flags2)
1419
def test_debug_flags_restored(self):
1420
"""The bzrlib debug flags should be restored to their original state
1421
after the test was run, even if allow_debug is set.
1423
self.change_selftest_debug_flags(set(['allow_debug']))
1424
# Now run a test that modifies debug.debug_flags.
1425
bzrlib.debug.debug_flags = set(['original-state'])
1426
class TestThatModifiesFlags(tests.TestCase):
1428
bzrlib.debug.debug_flags = set(['modified'])
1429
test = TestThatModifiesFlags('test_foo')
1430
test.run(self.make_test_result())
1431
self.assertEqual(set(['original-state']), bzrlib.debug.debug_flags)
1433
def make_test_result(self):
1434
"""Get a test result that writes to the test log file."""
1435
return tests.TextTestResult(self._log_file, descriptions=0, verbosity=1)
1437
def inner_test(self):
1438
# the inner child test
1441
def outer_child(self):
1442
# the outer child test
1444
self.inner_test = TestTestCase("inner_child")
1445
result = self.make_test_result()
1446
self.inner_test.run(result)
1447
note("outer finish")
1448
self.addCleanup(osutils.delete_any, self._log_file_name)
1450
def test_trace_nesting(self):
1451
# this tests that each test case nests its trace facility correctly.
1452
# we do this by running a test case manually. That test case (A)
1453
# should setup a new log, log content to it, setup a child case (B),
1454
# which should log independently, then case (A) should log a trailer
1456
# we do two nested children so that we can verify the state of the
1457
# logs after the outer child finishes is correct, which a bad clean
1458
# up routine in tearDown might trigger a fault in our test with only
1459
# one child, we should instead see the bad result inside our test with
1461
# the outer child test
1462
original_trace = bzrlib.trace._trace_file
1463
outer_test = TestTestCase("outer_child")
1464
result = self.make_test_result()
1465
outer_test.run(result)
1466
self.assertEqual(original_trace, bzrlib.trace._trace_file)
1468
def method_that_times_a_bit_twice(self):
1469
# call self.time twice to ensure it aggregates
1470
self.time(time.sleep, 0.007)
1471
self.time(time.sleep, 0.007)
1473
def test_time_creates_benchmark_in_result(self):
1474
"""Test that the TestCase.time() method accumulates a benchmark time."""
1475
sample_test = TestTestCase("method_that_times_a_bit_twice")
1476
output_stream = StringIO()
1477
result = bzrlib.tests.VerboseTestResult(
1481
sample_test.run(result)
1482
self.assertContainsRe(
1483
output_stream.getvalue(),
1486
def test_hooks_sanitised(self):
1487
"""The bzrlib hooks should be sanitised by setUp."""
1488
# Note this test won't fail with hooks that the core library doesn't
1489
# use - but it trigger with a plugin that adds hooks, so its still a
1490
# useful warning in that case.
1491
self.assertEqual(bzrlib.branch.BranchHooks(),
1492
bzrlib.branch.Branch.hooks)
1493
self.assertEqual(bzrlib.smart.server.SmartServerHooks(),
1494
bzrlib.smart.server.SmartTCPServer.hooks)
1495
self.assertEqual(bzrlib.commands.CommandHooks(),
1496
bzrlib.commands.Command.hooks)
1498
def test__gather_lsprof_in_benchmarks(self):
1499
"""When _gather_lsprof_in_benchmarks is on, accumulate profile data.
1501
Each self.time() call is individually and separately profiled.
1503
self.requireFeature(test_lsprof.LSProfFeature)
1504
# overrides the class member with an instance member so no cleanup
1506
self._gather_lsprof_in_benchmarks = True
1507
self.time(time.sleep, 0.000)
1508
self.time(time.sleep, 0.003)
1509
self.assertEqual(2, len(self._benchcalls))
1510
self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
1511
self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
1512
self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
1513
self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
1514
del self._benchcalls[:]
1516
def test_knownFailure(self):
1517
"""Self.knownFailure() should raise a KnownFailure exception."""
1518
self.assertRaises(tests.KnownFailure, self.knownFailure, "A Failure")
1520
def test_open_bzrdir_safe_roots(self):
1521
# even a memory transport should fail to open when its url isn't
1523
# Manually set one up (TestCase doesn't and shouldn't provide magic
1525
transport_server = memory.MemoryServer()
1526
transport_server.start_server()
1527
self.addCleanup(transport_server.stop_server)
1528
t = transport.get_transport(transport_server.get_url())
1529
bzrdir.BzrDir.create(t.base)
1530
self.assertRaises(errors.BzrError,
1531
bzrdir.BzrDir.open_from_transport, t)
1532
# But if we declare this as safe, we can open the bzrdir.
1533
self.permit_url(t.base)
1534
self._bzr_selftest_roots.append(t.base)
1535
bzrdir.BzrDir.open_from_transport(t)
1537
def test_requireFeature_available(self):
1538
"""self.requireFeature(available) is a no-op."""
1539
class Available(tests.Feature):
1540
def _probe(self):return True
1541
feature = Available()
1542
self.requireFeature(feature)
1544
def test_requireFeature_unavailable(self):
1545
"""self.requireFeature(unavailable) raises UnavailableFeature."""
1546
class Unavailable(tests.Feature):
1547
def _probe(self):return False
1548
feature = Unavailable()
1549
self.assertRaises(tests.UnavailableFeature,
1550
self.requireFeature, feature)
1552
def test_run_no_parameters(self):
1553
test = SampleTestCase('_test_pass')
1556
def test_run_enabled_unittest_result(self):
1557
"""Test we revert to regular behaviour when the test is enabled."""
1558
test = SampleTestCase('_test_pass')
1559
class EnabledFeature(object):
1560
def available(self):
1562
test._test_needs_features = [EnabledFeature()]
1563
result = unittest.TestResult()
1565
self.assertEqual(1, result.testsRun)
1566
self.assertEqual([], result.errors)
1567
self.assertEqual([], result.failures)
1569
def test_run_disabled_unittest_result(self):
1570
"""Test our compatability for disabled tests with unittest results."""
1571
test = SampleTestCase('_test_pass')
1572
class DisabledFeature(object):
1573
def available(self):
1575
test._test_needs_features = [DisabledFeature()]
1576
result = unittest.TestResult()
1578
self.assertEqual(1, result.testsRun)
1579
self.assertEqual([], result.errors)
1580
self.assertEqual([], result.failures)
1582
def test_run_disabled_supporting_result(self):
1583
"""Test disabled tests behaviour with support aware results."""
1584
test = SampleTestCase('_test_pass')
1585
class DisabledFeature(object):
1586
def __eq__(self, other):
1587
return isinstance(other, DisabledFeature)
1588
def available(self):
1590
the_feature = DisabledFeature()
1591
test._test_needs_features = [the_feature]
1592
class InstrumentedTestResult(unittest.TestResult):
1594
unittest.TestResult.__init__(self)
1596
def startTest(self, test):
1597
self.calls.append(('startTest', test))
1598
def stopTest(self, test):
1599
self.calls.append(('stopTest', test))
1600
def addNotSupported(self, test, feature):
1601
self.calls.append(('addNotSupported', test, feature))
1602
result = InstrumentedTestResult()
1604
case = result.calls[0][1]
1606
('startTest', case),
1607
('addNotSupported', case, the_feature),
1612
def test_start_server_registers_url(self):
1613
transport_server = memory.MemoryServer()
1614
# A little strict, but unlikely to be changed soon.
1615
self.assertEqual([], self._bzr_selftest_roots)
1616
self.start_server(transport_server)
1617
self.assertSubset([transport_server.get_url()],
1618
self._bzr_selftest_roots)
1620
def test_assert_list_raises_on_generator(self):
1621
def generator_which_will_raise():
1622
# This will not raise until after the first yield
1624
raise _TestException()
1626
e = self.assertListRaises(_TestException, generator_which_will_raise)
1627
self.assertIsInstance(e, _TestException)
1629
e = self.assertListRaises(Exception, generator_which_will_raise)
1630
self.assertIsInstance(e, _TestException)
1632
def test_assert_list_raises_on_plain(self):
1633
def plain_exception():
1634
raise _TestException()
1637
e = self.assertListRaises(_TestException, plain_exception)
1638
self.assertIsInstance(e, _TestException)
1640
e = self.assertListRaises(Exception, plain_exception)
1641
self.assertIsInstance(e, _TestException)
1643
def test_assert_list_raises_assert_wrong_exception(self):
1644
class _NotTestException(Exception):
1647
def wrong_exception():
1648
raise _NotTestException()
1650
def wrong_exception_generator():
1653
raise _NotTestException()
1655
# Wrong exceptions are not intercepted
1656
self.assertRaises(_NotTestException,
1657
self.assertListRaises, _TestException, wrong_exception)
1658
self.assertRaises(_NotTestException,
1659
self.assertListRaises, _TestException, wrong_exception_generator)
1661
def test_assert_list_raises_no_exception(self):
1665
def success_generator():
1669
self.assertRaises(AssertionError,
1670
self.assertListRaises, _TestException, success)
1672
self.assertRaises(AssertionError,
1673
self.assertListRaises, _TestException, success_generator)
1675
def test_overrideAttr_without_value(self):
1676
self.test_attr = 'original' # Define a test attribute
1677
obj = self # Make 'obj' visible to the embedded test
1678
class Test(tests.TestCase):
1681
tests.TestCase.setUp(self)
1682
self.orig = self.overrideAttr(obj, 'test_attr')
1684
def test_value(self):
1685
self.assertEqual('original', self.orig)
1686
self.assertEqual('original', obj.test_attr)
1687
obj.test_attr = 'modified'
1688
self.assertEqual('modified', obj.test_attr)
1690
test = Test('test_value')
1691
test.run(unittest.TestResult())
1692
self.assertEqual('original', obj.test_attr)
1694
def test_overrideAttr_with_value(self):
1695
self.test_attr = 'original' # Define a test attribute
1696
obj = self # Make 'obj' visible to the embedded test
1697
class Test(tests.TestCase):
1700
tests.TestCase.setUp(self)
1701
self.orig = self.overrideAttr(obj, 'test_attr', new='modified')
1703
def test_value(self):
1704
self.assertEqual('original', self.orig)
1705
self.assertEqual('modified', obj.test_attr)
1707
test = Test('test_value')
1708
test.run(unittest.TestResult())
1709
self.assertEqual('original', obj.test_attr)
1712
class _MissingFeature(tests.Feature):
1715
missing_feature = _MissingFeature()
1718
def _get_test(name):
1719
"""Get an instance of a specific example test.
1721
We protect this in a function so that they don't auto-run in the test
1725
class ExampleTests(tests.TestCase):
1727
def test_fail(self):
1728
mutter('this was a failing test')
1729
self.fail('this test will fail')
1731
def test_error(self):
1732
mutter('this test errored')
1733
raise RuntimeError('gotcha')
1735
def test_missing_feature(self):
1736
mutter('missing the feature')
1737
self.requireFeature(missing_feature)
1739
def test_skip(self):
1740
mutter('this test will be skipped')
1741
raise tests.TestSkipped('reason')
1743
def test_success(self):
1744
mutter('this test succeeds')
1746
def test_xfail(self):
1747
mutter('test with expected failure')
1748
self.knownFailure('this_fails')
1750
def test_unexpected_success(self):
1751
mutter('test with unexpected success')
1752
self.expectFailure('should_fail', lambda: None)
1754
return ExampleTests(name)
1757
class TestTestCaseLogDetails(tests.TestCase):
1759
def _run_test(self, test_name):
1760
test = _get_test(test_name)
1761
result = testtools.TestResult()
1765
def test_fail_has_log(self):
1766
result = self._run_test('test_fail')
1767
self.assertEqual(1, len(result.failures))
1768
result_content = result.failures[0][1]
1769
self.assertContainsRe(result_content, 'Text attachment: log')
1770
self.assertContainsRe(result_content, 'this was a failing test')
1772
def test_error_has_log(self):
1773
result = self._run_test('test_error')
1774
self.assertEqual(1, len(result.errors))
1775
result_content = result.errors[0][1]
1776
self.assertContainsRe(result_content, 'Text attachment: log')
1777
self.assertContainsRe(result_content, 'this test errored')
1779
def test_skip_has_no_log(self):
1780
result = self._run_test('test_skip')
1781
self.assertEqual(['reason'], result.skip_reasons.keys())
1782
skips = result.skip_reasons['reason']
1783
self.assertEqual(1, len(skips))
1785
self.assertFalse('log' in test.getDetails())
1787
def test_missing_feature_has_no_log(self):
1788
# testtools doesn't know about addNotSupported, so it just gets
1789
# considered as a skip
1790
result = self._run_test('test_missing_feature')
1791
self.assertEqual([missing_feature], result.skip_reasons.keys())
1792
skips = result.skip_reasons[missing_feature]
1793
self.assertEqual(1, len(skips))
1795
self.assertFalse('log' in test.getDetails())
1797
def test_xfail_has_no_log(self):
1798
result = self._run_test('test_xfail')
1799
self.assertEqual(1, len(result.expectedFailures))
1800
result_content = result.expectedFailures[0][1]
1801
self.assertNotContainsRe(result_content, 'Text attachment: log')
1802
self.assertNotContainsRe(result_content, 'test with expected failure')
1804
def test_unexpected_success_has_log(self):
1805
result = self._run_test('test_unexpected_success')
1806
self.assertEqual(1, len(result.unexpectedSuccesses))
1807
# Inconsistency, unexpectedSuccesses is a list of tests,
1808
# expectedFailures is a list of reasons?
1809
test = result.unexpectedSuccesses[0]
1810
details = test.getDetails()
1811
self.assertTrue('log' in details)
1814
class TestTestCloning(tests.TestCase):
1815
"""Tests that test cloning of TestCases (as used by multiply_tests)."""
1817
def test_cloned_testcase_does_not_share_details(self):
1818
"""A TestCase cloned with clone_test does not share mutable attributes
1819
such as details or cleanups.
1821
class Test(tests.TestCase):
1823
self.addDetail('foo', Content('text/plain', lambda: 'foo'))
1824
orig_test = Test('test_foo')
1825
cloned_test = tests.clone_test(orig_test, orig_test.id() + '(cloned)')
1826
orig_test.run(unittest.TestResult())
1827
self.assertEqual('foo', orig_test.getDetails()['foo'].iter_bytes())
1828
self.assertEqual(None, cloned_test.getDetails().get('foo'))
1830
def test_double_apply_scenario_preserves_first_scenario(self):
1831
"""Applying two levels of scenarios to a test preserves the attributes
1832
added by both scenarios.
1834
class Test(tests.TestCase):
1837
test = Test('test_foo')
1838
scenarios_x = [('x=1', {'x': 1}), ('x=2', {'x': 2})]
1839
scenarios_y = [('y=1', {'y': 1}), ('y=2', {'y': 2})]
1840
suite = tests.multiply_tests(test, scenarios_x, unittest.TestSuite())
1841
suite = tests.multiply_tests(suite, scenarios_y, unittest.TestSuite())
1842
all_tests = list(tests.iter_suite_tests(suite))
1843
self.assertLength(4, all_tests)
1844
all_xys = sorted((t.x, t.y) for t in all_tests)
1845
self.assertEqual([(1, 1), (1, 2), (2, 1), (2, 2)], all_xys)
1848
# NB: Don't delete this; it's not actually from 0.11!
1849
@deprecated_function(deprecated_in((0, 11, 0)))
1850
def sample_deprecated_function():
1851
"""A deprecated function to test applyDeprecated with."""
1855
def sample_undeprecated_function(a_param):
1856
"""A undeprecated function to test applyDeprecated with."""
1859
class ApplyDeprecatedHelper(object):
1860
"""A helper class for ApplyDeprecated tests."""
1862
@deprecated_method(deprecated_in((0, 11, 0)))
1863
def sample_deprecated_method(self, param_one):
1864
"""A deprecated method for testing with."""
1867
def sample_normal_method(self):
1868
"""A undeprecated method."""
1870
@deprecated_method(deprecated_in((0, 10, 0)))
1871
def sample_nested_deprecation(self):
1872
return sample_deprecated_function()
1875
class TestExtraAssertions(tests.TestCase):
1876
"""Tests for new test assertions in bzrlib test suite"""
1878
def test_assert_isinstance(self):
1879
self.assertIsInstance(2, int)
1880
self.assertIsInstance(u'', basestring)
1881
e = self.assertRaises(AssertionError, self.assertIsInstance, None, int)
1882
self.assertEquals(str(e),
1883
"None is an instance of <type 'NoneType'> rather than <type 'int'>")
1884
self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
1885
e = self.assertRaises(AssertionError,
1886
self.assertIsInstance, None, int, "it's just not")
1887
self.assertEquals(str(e),
1888
"None is an instance of <type 'NoneType'> rather than <type 'int'>"
1891
def test_assertEndsWith(self):
1892
self.assertEndsWith('foo', 'oo')
1893
self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
1895
def test_assertEqualDiff(self):
1896
e = self.assertRaises(AssertionError,
1897
self.assertEqualDiff, '', '\n')
1898
self.assertEquals(str(e),
1899
# Don't blink ! The '+' applies to the second string
1900
'first string is missing a final newline.\n+ \n')
1901
e = self.assertRaises(AssertionError,
1902
self.assertEqualDiff, '\n', '')
1903
self.assertEquals(str(e),
1904
# Don't blink ! The '-' applies to the second string
1905
'second string is missing a final newline.\n- \n')
1908
class TestDeprecations(tests.TestCase):
1910
def test_applyDeprecated_not_deprecated(self):
1911
sample_object = ApplyDeprecatedHelper()
1912
# calling an undeprecated callable raises an assertion
1913
self.assertRaises(AssertionError, self.applyDeprecated,
1914
deprecated_in((0, 11, 0)),
1915
sample_object.sample_normal_method)
1916
self.assertRaises(AssertionError, self.applyDeprecated,
1917
deprecated_in((0, 11, 0)),
1918
sample_undeprecated_function, "a param value")
1919
# calling a deprecated callable (function or method) with the wrong
1920
# expected deprecation fails.
1921
self.assertRaises(AssertionError, self.applyDeprecated,
1922
deprecated_in((0, 10, 0)),
1923
sample_object.sample_deprecated_method, "a param value")
1924
self.assertRaises(AssertionError, self.applyDeprecated,
1925
deprecated_in((0, 10, 0)),
1926
sample_deprecated_function)
1927
# calling a deprecated callable (function or method) with the right
1928
# expected deprecation returns the functions result.
1929
self.assertEqual("a param value",
1930
self.applyDeprecated(deprecated_in((0, 11, 0)),
1931
sample_object.sample_deprecated_method, "a param value"))
1932
self.assertEqual(2, self.applyDeprecated(deprecated_in((0, 11, 0)),
1933
sample_deprecated_function))
1934
# calling a nested deprecation with the wrong deprecation version
1935
# fails even if a deeper nested function was deprecated with the
1937
self.assertRaises(AssertionError, self.applyDeprecated,
1938
deprecated_in((0, 11, 0)), sample_object.sample_nested_deprecation)
1939
# calling a nested deprecation with the right deprecation value
1940
# returns the calls result.
1941
self.assertEqual(2, self.applyDeprecated(deprecated_in((0, 10, 0)),
1942
sample_object.sample_nested_deprecation))
1944
def test_callDeprecated(self):
1945
def testfunc(be_deprecated, result=None):
1946
if be_deprecated is True:
1947
symbol_versioning.warn('i am deprecated', DeprecationWarning,
1950
result = self.callDeprecated(['i am deprecated'], testfunc, True)
1951
self.assertIs(None, result)
1952
result = self.callDeprecated([], testfunc, False, 'result')
1953
self.assertEqual('result', result)
1954
self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
1955
self.callDeprecated([], testfunc, be_deprecated=False)
1958
class TestWarningTests(tests.TestCase):
1959
"""Tests for calling methods that raise warnings."""
1961
def test_callCatchWarnings(self):
1963
warnings.warn("this is your last warning")
1965
wlist, result = self.callCatchWarnings(meth, 1, 2)
1966
self.assertEquals(3, result)
1967
# would like just to compare them, but UserWarning doesn't implement
1970
self.assertIsInstance(w0, UserWarning)
1971
self.assertEquals("this is your last warning", str(w0))
1974
class TestConvenienceMakers(tests.TestCaseWithTransport):
1975
"""Test for the make_* convenience functions."""
1977
def test_make_branch_and_tree_with_format(self):
1978
# we should be able to supply a format to make_branch_and_tree
1979
self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
1980
self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
1981
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
1982
bzrlib.bzrdir.BzrDirMetaFormat1)
1983
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
1984
bzrlib.bzrdir.BzrDirFormat6)
1986
def test_make_branch_and_memory_tree(self):
1987
# we should be able to get a new branch and a mutable tree from
1988
# TestCaseWithTransport
1989
tree = self.make_branch_and_memory_tree('a')
1990
self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
1992
def test_make_tree_for_local_vfs_backed_transport(self):
1993
# make_branch_and_tree has to use local branch and repositories
1994
# when the vfs transport and local disk are colocated, even if
1995
# a different transport is in use for url generation.
1996
self.transport_server = test_server.FakeVFATServer
1997
self.assertFalse(self.get_url('t1').startswith('file://'))
1998
tree = self.make_branch_and_tree('t1')
1999
base = tree.bzrdir.root_transport.base
2000
self.assertStartsWith(base, 'file://')
2001
self.assertEquals(tree.bzrdir.root_transport,
2002
tree.branch.bzrdir.root_transport)
2003
self.assertEquals(tree.bzrdir.root_transport,
2004
tree.branch.repository.bzrdir.root_transport)
2007
class SelfTestHelper(object):
2009
def run_selftest(self, **kwargs):
2010
"""Run selftest returning its output."""
2012
old_transport = bzrlib.tests.default_transport
2013
old_root = tests.TestCaseWithMemoryTransport.TEST_ROOT
2014
tests.TestCaseWithMemoryTransport.TEST_ROOT = None
2016
self.assertEqual(True, tests.selftest(stream=output, **kwargs))
2018
bzrlib.tests.default_transport = old_transport
2019
tests.TestCaseWithMemoryTransport.TEST_ROOT = old_root
2024
class TestSelftest(tests.TestCase, SelfTestHelper):
2025
"""Tests of bzrlib.tests.selftest."""
2027
def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
2030
factory_called.append(True)
2031
return TestUtil.TestSuite()
2034
self.apply_redirected(out, err, None, bzrlib.tests.selftest,
2035
test_suite_factory=factory)
2036
self.assertEqual([True], factory_called)
2039
"""A test suite factory."""
2040
class Test(tests.TestCase):
2047
return TestUtil.TestSuite([Test("a"), Test("b"), Test("c")])
2049
def test_list_only(self):
2050
output = self.run_selftest(test_suite_factory=self.factory,
2052
self.assertEqual(3, len(output.readlines()))
2054
def test_list_only_filtered(self):
2055
output = self.run_selftest(test_suite_factory=self.factory,
2056
list_only=True, pattern="Test.b")
2057
self.assertEndsWith(output.getvalue(), "Test.b\n")
2058
self.assertLength(1, output.readlines())
2060
def test_list_only_excludes(self):
2061
output = self.run_selftest(test_suite_factory=self.factory,
2062
list_only=True, exclude_pattern="Test.b")
2063
self.assertNotContainsRe("Test.b", output.getvalue())
2064
self.assertLength(2, output.readlines())
2066
def test_lsprof_tests(self):
2067
self.requireFeature(test_lsprof.LSProfFeature)
2070
def __call__(test, result):
2072
def run(test, result):
2073
self.assertIsInstance(result, ExtendedToOriginalDecorator)
2074
calls.append("called")
2075
def countTestCases(self):
2077
self.run_selftest(test_suite_factory=Test, lsprof_tests=True)
2078
self.assertLength(1, calls)
2080
def test_random(self):
2081
# test randomising by listing a number of tests.
2082
output_123 = self.run_selftest(test_suite_factory=self.factory,
2083
list_only=True, random_seed="123")
2084
output_234 = self.run_selftest(test_suite_factory=self.factory,
2085
list_only=True, random_seed="234")
2086
self.assertNotEqual(output_123, output_234)
2087
# "Randominzing test order..\n\n
2088
self.assertLength(5, output_123.readlines())
2089
self.assertLength(5, output_234.readlines())
2091
def test_random_reuse_is_same_order(self):
2092
# test randomising by listing a number of tests.
2093
expected = self.run_selftest(test_suite_factory=self.factory,
2094
list_only=True, random_seed="123")
2095
repeated = self.run_selftest(test_suite_factory=self.factory,
2096
list_only=True, random_seed="123")
2097
self.assertEqual(expected.getvalue(), repeated.getvalue())
2099
def test_runner_class(self):
2100
self.requireFeature(features.subunit)
2101
from subunit import ProtocolTestCase
2102
stream = self.run_selftest(runner_class=tests.SubUnitBzrRunner,
2103
test_suite_factory=self.factory)
2104
test = ProtocolTestCase(stream)
2105
result = unittest.TestResult()
2107
self.assertEqual(3, result.testsRun)
2109
def test_starting_with_single_argument(self):
2110
output = self.run_selftest(test_suite_factory=self.factory,
2111
starting_with=['bzrlib.tests.test_selftest.Test.a'],
2113
self.assertEqual('bzrlib.tests.test_selftest.Test.a\n',
2116
def test_starting_with_multiple_argument(self):
2117
output = self.run_selftest(test_suite_factory=self.factory,
2118
starting_with=['bzrlib.tests.test_selftest.Test.a',
2119
'bzrlib.tests.test_selftest.Test.b'],
2121
self.assertEqual('bzrlib.tests.test_selftest.Test.a\n'
2122
'bzrlib.tests.test_selftest.Test.b\n',
2125
def check_transport_set(self, transport_server):
2126
captured_transport = []
2127
def seen_transport(a_transport):
2128
captured_transport.append(a_transport)
2129
class Capture(tests.TestCase):
2131
seen_transport(bzrlib.tests.default_transport)
2133
return TestUtil.TestSuite([Capture("a")])
2134
self.run_selftest(transport=transport_server, test_suite_factory=factory)
2135
self.assertEqual(transport_server, captured_transport[0])
2137
def test_transport_sftp(self):
2138
self.requireFeature(features.paramiko)
2139
from bzrlib.tests import stub_sftp
2140
self.check_transport_set(stub_sftp.SFTPAbsoluteServer)
2142
def test_transport_memory(self):
2143
self.check_transport_set(memory.MemoryServer)
2146
class TestSelftestWithIdList(tests.TestCaseInTempDir, SelfTestHelper):
2147
# Does IO: reads test.list
2149
def test_load_list(self):
2150
# Provide a list with one test - this test.
2151
test_id_line = '%s\n' % self.id()
2152
self.build_tree_contents([('test.list', test_id_line)])
2153
# And generate a list of the tests in the suite.
2154
stream = self.run_selftest(load_list='test.list', list_only=True)
2155
self.assertEqual(test_id_line, stream.getvalue())
2157
def test_load_unknown(self):
2158
# Provide a list with one test - this test.
2159
# And generate a list of the tests in the suite.
2160
err = self.assertRaises(errors.NoSuchFile, self.run_selftest,
2161
load_list='missing file name', list_only=True)
2164
class TestSubunitLogDetails(tests.TestCase, SelfTestHelper):
2166
_test_needs_features = [features.subunit]
2168
def run_subunit_stream(self, test_name):
2169
from subunit import ProtocolTestCase
2171
return TestUtil.TestSuite([_get_test(test_name)])
2172
stream = self.run_selftest(runner_class=tests.SubUnitBzrRunner,
2173
test_suite_factory=factory)
2174
test = ProtocolTestCase(stream)
2175
result = testtools.TestResult()
2177
content = stream.getvalue()
2178
return content, result
2180
def test_fail_has_log(self):
2181
content, result = self.run_subunit_stream('test_fail')
2182
self.assertEqual(1, len(result.failures))
2183
self.assertContainsRe(content, '(?m)^log$')
2184
self.assertContainsRe(content, 'this test will fail')
2186
def test_error_has_log(self):
2187
content, result = self.run_subunit_stream('test_error')
2188
self.assertContainsRe(content, '(?m)^log$')
2189
self.assertContainsRe(content, 'this test errored')
2191
def test_skip_has_no_log(self):
2192
content, result = self.run_subunit_stream('test_skip')
2193
self.assertNotContainsRe(content, '(?m)^log$')
2194
self.assertNotContainsRe(content, 'this test will be skipped')
2195
self.assertEqual(['reason'], result.skip_reasons.keys())
2196
skips = result.skip_reasons['reason']
2197
self.assertEqual(1, len(skips))
2199
# RemotedTestCase doesn't preserve the "details"
2200
## self.assertFalse('log' in test.getDetails())
2202
def test_missing_feature_has_no_log(self):
2203
content, result = self.run_subunit_stream('test_missing_feature')
2204
self.assertNotContainsRe(content, '(?m)^log$')
2205
self.assertNotContainsRe(content, 'missing the feature')
2206
self.assertEqual(['_MissingFeature\n'], result.skip_reasons.keys())
2207
skips = result.skip_reasons['_MissingFeature\n']
2208
self.assertEqual(1, len(skips))
2210
# RemotedTestCase doesn't preserve the "details"
2211
## self.assertFalse('log' in test.getDetails())
2213
def test_xfail_has_no_log(self):
2214
content, result = self.run_subunit_stream('test_xfail')
2215
self.assertNotContainsRe(content, '(?m)^log$')
2216
self.assertNotContainsRe(content, 'test with expected failure')
2217
self.assertEqual(1, len(result.expectedFailures))
2218
result_content = result.expectedFailures[0][1]
2219
self.assertNotContainsRe(result_content, 'Text attachment: log')
2220
self.assertNotContainsRe(result_content, 'test with expected failure')
2222
def test_unexpected_success_has_log(self):
2223
content, result = self.run_subunit_stream('test_unexpected_success')
2224
self.assertContainsRe(content, '(?m)^log$')
2225
self.assertContainsRe(content, 'test with unexpected success')
2226
self.expectFailure('subunit treats "unexpectedSuccess"'
2227
' as a plain success',
2228
self.assertEqual, 1, len(result.unexpectedSuccesses))
2229
self.assertEqual(1, len(result.unexpectedSuccesses))
2230
test = result.unexpectedSuccesses[0]
2231
# RemotedTestCase doesn't preserve the "details"
2232
## self.assertTrue('log' in test.getDetails())
2234
def test_success_has_no_log(self):
2235
content, result = self.run_subunit_stream('test_success')
2236
self.assertEqual(1, result.testsRun)
2237
self.assertNotContainsRe(content, '(?m)^log$')
2238
self.assertNotContainsRe(content, 'this test succeeds')
2241
class TestRunBzr(tests.TestCase):
2246
def _run_bzr_core(self, argv, retcode=0, encoding=None, stdin=None,
2248
"""Override _run_bzr_core to test how it is invoked by run_bzr.
2250
Attempts to run bzr from inside this class don't actually run it.
2252
We test how run_bzr actually invokes bzr in another location. Here we
2253
only need to test that it passes the right parameters to run_bzr.
2255
self.argv = list(argv)
2256
self.retcode = retcode
2257
self.encoding = encoding
2259
self.working_dir = working_dir
2260
return self.retcode, self.out, self.err
2262
def test_run_bzr_error(self):
2263
self.out = "It sure does!\n"
2264
out, err = self.run_bzr_error(['^$'], ['rocks'], retcode=34)
2265
self.assertEqual(['rocks'], self.argv)
2266
self.assertEqual(34, self.retcode)
2267
self.assertEqual('It sure does!\n', out)
2268
self.assertEquals(out, self.out)
2269
self.assertEqual('', err)
2270
self.assertEquals(err, self.err)
2272
def test_run_bzr_error_regexes(self):
2274
self.err = "bzr: ERROR: foobarbaz is not versioned"
2275
out, err = self.run_bzr_error(
2276
["bzr: ERROR: foobarbaz is not versioned"],
2277
['file-id', 'foobarbaz'])
2279
def test_encoding(self):
2280
"""Test that run_bzr passes encoding to _run_bzr_core"""
2281
self.run_bzr('foo bar')
2282
self.assertEqual(None, self.encoding)
2283
self.assertEqual(['foo', 'bar'], self.argv)
2285
self.run_bzr('foo bar', encoding='baz')
2286
self.assertEqual('baz', self.encoding)
2287
self.assertEqual(['foo', 'bar'], self.argv)
2289
def test_retcode(self):
2290
"""Test that run_bzr passes retcode to _run_bzr_core"""
2291
# Default is retcode == 0
2292
self.run_bzr('foo bar')
2293
self.assertEqual(0, self.retcode)
2294
self.assertEqual(['foo', 'bar'], self.argv)
2296
self.run_bzr('foo bar', retcode=1)
2297
self.assertEqual(1, self.retcode)
2298
self.assertEqual(['foo', 'bar'], self.argv)
2300
self.run_bzr('foo bar', retcode=None)
2301
self.assertEqual(None, self.retcode)
2302
self.assertEqual(['foo', 'bar'], self.argv)
2304
self.run_bzr(['foo', 'bar'], retcode=3)
2305
self.assertEqual(3, self.retcode)
2306
self.assertEqual(['foo', 'bar'], self.argv)
2308
def test_stdin(self):
2309
# test that the stdin keyword to run_bzr is passed through to
2310
# _run_bzr_core as-is. We do this by overriding
2311
# _run_bzr_core in this class, and then calling run_bzr,
2312
# which is a convenience function for _run_bzr_core, so
2314
self.run_bzr('foo bar', stdin='gam')
2315
self.assertEqual('gam', self.stdin)
2316
self.assertEqual(['foo', 'bar'], self.argv)
2318
self.run_bzr('foo bar', stdin='zippy')
2319
self.assertEqual('zippy', self.stdin)
2320
self.assertEqual(['foo', 'bar'], self.argv)
2322
def test_working_dir(self):
2323
"""Test that run_bzr passes working_dir to _run_bzr_core"""
2324
self.run_bzr('foo bar')
2325
self.assertEqual(None, self.working_dir)
2326
self.assertEqual(['foo', 'bar'], self.argv)
2328
self.run_bzr('foo bar', working_dir='baz')
2329
self.assertEqual('baz', self.working_dir)
2330
self.assertEqual(['foo', 'bar'], self.argv)
2332
def test_reject_extra_keyword_arguments(self):
2333
self.assertRaises(TypeError, self.run_bzr, "foo bar",
2334
error_regex=['error message'])
2337
class TestRunBzrCaptured(tests.TestCaseWithTransport):
2338
# Does IO when testing the working_dir parameter.
2340
def apply_redirected(self, stdin=None, stdout=None, stderr=None,
2341
a_callable=None, *args, **kwargs):
2343
self.factory_stdin = getattr(bzrlib.ui.ui_factory, "stdin", None)
2344
self.factory = bzrlib.ui.ui_factory
2345
self.working_dir = osutils.getcwd()
2346
stdout.write('foo\n')
2347
stderr.write('bar\n')
2350
def test_stdin(self):
2351
# test that the stdin keyword to _run_bzr_core is passed through to
2352
# apply_redirected as a StringIO. We do this by overriding
2353
# apply_redirected in this class, and then calling _run_bzr_core,
2354
# which calls apply_redirected.
2355
self.run_bzr(['foo', 'bar'], stdin='gam')
2356
self.assertEqual('gam', self.stdin.read())
2357
self.assertTrue(self.stdin is self.factory_stdin)
2358
self.run_bzr(['foo', 'bar'], stdin='zippy')
2359
self.assertEqual('zippy', self.stdin.read())
2360
self.assertTrue(self.stdin is self.factory_stdin)
2362
def test_ui_factory(self):
2363
# each invocation of self.run_bzr should get its
2364
# own UI factory, which is an instance of TestUIFactory,
2365
# with stdin, stdout and stderr attached to the stdin,
2366
# stdout and stderr of the invoked run_bzr
2367
current_factory = bzrlib.ui.ui_factory
2368
self.run_bzr(['foo'])
2369
self.failIf(current_factory is self.factory)
2370
self.assertNotEqual(sys.stdout, self.factory.stdout)
2371
self.assertNotEqual(sys.stderr, self.factory.stderr)
2372
self.assertEqual('foo\n', self.factory.stdout.getvalue())
2373
self.assertEqual('bar\n', self.factory.stderr.getvalue())
2374
self.assertIsInstance(self.factory, tests.TestUIFactory)
2376
def test_working_dir(self):
2377
self.build_tree(['one/', 'two/'])
2378
cwd = osutils.getcwd()
2380
# Default is to work in the current directory
2381
self.run_bzr(['foo', 'bar'])
2382
self.assertEqual(cwd, self.working_dir)
2384
self.run_bzr(['foo', 'bar'], working_dir=None)
2385
self.assertEqual(cwd, self.working_dir)
2387
# The function should be run in the alternative directory
2388
# but afterwards the current working dir shouldn't be changed
2389
self.run_bzr(['foo', 'bar'], working_dir='one')
2390
self.assertNotEqual(cwd, self.working_dir)
2391
self.assertEndsWith(self.working_dir, 'one')
2392
self.assertEqual(cwd, osutils.getcwd())
2394
self.run_bzr(['foo', 'bar'], working_dir='two')
2395
self.assertNotEqual(cwd, self.working_dir)
2396
self.assertEndsWith(self.working_dir, 'two')
2397
self.assertEqual(cwd, osutils.getcwd())
2400
class StubProcess(object):
2401
"""A stub process for testing run_bzr_subprocess."""
2403
def __init__(self, out="", err="", retcode=0):
2406
self.returncode = retcode
2408
def communicate(self):
2409
return self.out, self.err
2412
class TestWithFakedStartBzrSubprocess(tests.TestCaseWithTransport):
2413
"""Base class for tests testing how we might run bzr."""
2416
tests.TestCaseWithTransport.setUp(self)
2417
self.subprocess_calls = []
2419
def start_bzr_subprocess(self, process_args, env_changes=None,
2420
skip_if_plan_to_signal=False,
2422
allow_plugins=False):
2423
"""capture what run_bzr_subprocess tries to do."""
2424
self.subprocess_calls.append({'process_args':process_args,
2425
'env_changes':env_changes,
2426
'skip_if_plan_to_signal':skip_if_plan_to_signal,
2427
'working_dir':working_dir, 'allow_plugins':allow_plugins})
2428
return self.next_subprocess
2431
class TestRunBzrSubprocess(TestWithFakedStartBzrSubprocess):
2433
def assertRunBzrSubprocess(self, expected_args, process, *args, **kwargs):
2434
"""Run run_bzr_subprocess with args and kwargs using a stubbed process.
2436
Inside TestRunBzrSubprocessCommands we use a stub start_bzr_subprocess
2437
that will return static results. This assertion method populates those
2438
results and also checks the arguments run_bzr_subprocess generates.
2440
self.next_subprocess = process
2442
result = self.run_bzr_subprocess(*args, **kwargs)
2444
self.next_subprocess = None
2445
for key, expected in expected_args.iteritems():
2446
self.assertEqual(expected, self.subprocess_calls[-1][key])
2449
self.next_subprocess = None
2450
for key, expected in expected_args.iteritems():
2451
self.assertEqual(expected, self.subprocess_calls[-1][key])
2454
def test_run_bzr_subprocess(self):
2455
"""The run_bzr_helper_external command behaves nicely."""
2456
self.assertRunBzrSubprocess({'process_args':['--version']},
2457
StubProcess(), '--version')
2458
self.assertRunBzrSubprocess({'process_args':['--version']},
2459
StubProcess(), ['--version'])
2460
# retcode=None disables retcode checking
2461
result = self.assertRunBzrSubprocess({},
2462
StubProcess(retcode=3), '--version', retcode=None)
2463
result = self.assertRunBzrSubprocess({},
2464
StubProcess(out="is free software"), '--version')
2465
self.assertContainsRe(result[0], 'is free software')
2466
# Running a subcommand that is missing errors
2467
self.assertRaises(AssertionError, self.assertRunBzrSubprocess,
2468
{'process_args':['--versionn']}, StubProcess(retcode=3),
2470
# Unless it is told to expect the error from the subprocess
2471
result = self.assertRunBzrSubprocess({},
2472
StubProcess(retcode=3), '--versionn', retcode=3)
2473
# Or to ignore retcode checking
2474
result = self.assertRunBzrSubprocess({},
2475
StubProcess(err="unknown command", retcode=3), '--versionn',
2477
self.assertContainsRe(result[1], 'unknown command')
2479
def test_env_change_passes_through(self):
2480
self.assertRunBzrSubprocess(
2481
{'env_changes':{'new':'value', 'changed':'newvalue', 'deleted':None}},
2483
env_changes={'new':'value', 'changed':'newvalue', 'deleted':None})
2485
def test_no_working_dir_passed_as_None(self):
2486
self.assertRunBzrSubprocess({'working_dir': None}, StubProcess(), '')
2488
def test_no_working_dir_passed_through(self):
2489
self.assertRunBzrSubprocess({'working_dir': 'dir'}, StubProcess(), '',
2492
def test_run_bzr_subprocess_no_plugins(self):
2493
self.assertRunBzrSubprocess({'allow_plugins': False},
2496
def test_allow_plugins(self):
2497
self.assertRunBzrSubprocess({'allow_plugins': True},
2498
StubProcess(), '', allow_plugins=True)
2501
class TestFinishBzrSubprocess(TestWithFakedStartBzrSubprocess):
2503
def test_finish_bzr_subprocess_with_error(self):
2504
"""finish_bzr_subprocess allows specification of the desired exit code.
2506
process = StubProcess(err="unknown command", retcode=3)
2507
result = self.finish_bzr_subprocess(process, retcode=3)
2508
self.assertEqual('', result[0])
2509
self.assertContainsRe(result[1], 'unknown command')
2511
def test_finish_bzr_subprocess_ignoring_retcode(self):
2512
"""finish_bzr_subprocess allows the exit code to be ignored."""
2513
process = StubProcess(err="unknown command", retcode=3)
2514
result = self.finish_bzr_subprocess(process, retcode=None)
2515
self.assertEqual('', result[0])
2516
self.assertContainsRe(result[1], 'unknown command')
2518
def test_finish_subprocess_with_unexpected_retcode(self):
2519
"""finish_bzr_subprocess raises self.failureException if the retcode is
2520
not the expected one.
2522
process = StubProcess(err="unknown command", retcode=3)
2523
self.assertRaises(self.failureException, self.finish_bzr_subprocess,
2527
class _DontSpawnProcess(Exception):
2528
"""A simple exception which just allows us to skip unnecessary steps"""
2531
class TestStartBzrSubProcess(tests.TestCase):
2533
def check_popen_state(self):
2534
"""Replace to make assertions when popen is called."""
2536
def _popen(self, *args, **kwargs):
2537
"""Record the command that is run, so that we can ensure it is correct"""
2538
self.check_popen_state()
2539
self._popen_args = args
2540
self._popen_kwargs = kwargs
2541
raise _DontSpawnProcess()
2543
def test_run_bzr_subprocess_no_plugins(self):
2544
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [])
2545
command = self._popen_args[0]
2546
self.assertEqual(sys.executable, command[0])
2547
self.assertEqual(self.get_bzr_path(), command[1])
2548
self.assertEqual(['--no-plugins'], command[2:])
2550
def test_allow_plugins(self):
2551
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2553
command = self._popen_args[0]
2554
self.assertEqual([], command[2:])
2556
def test_set_env(self):
2557
self.failIf('EXISTANT_ENV_VAR' in os.environ)
2559
def check_environment():
2560
self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2561
self.check_popen_state = check_environment
2562
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2563
env_changes={'EXISTANT_ENV_VAR':'set variable'})
2564
# not set in theparent
2565
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2567
def test_run_bzr_subprocess_env_del(self):
2568
"""run_bzr_subprocess can remove environment variables too."""
2569
self.failIf('EXISTANT_ENV_VAR' in os.environ)
2570
def check_environment():
2571
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2572
os.environ['EXISTANT_ENV_VAR'] = 'set variable'
2573
self.check_popen_state = check_environment
2574
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2575
env_changes={'EXISTANT_ENV_VAR':None})
2576
# Still set in parent
2577
self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2578
del os.environ['EXISTANT_ENV_VAR']
2580
def test_env_del_missing(self):
2581
self.failIf('NON_EXISTANT_ENV_VAR' in os.environ)
2582
def check_environment():
2583
self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
2584
self.check_popen_state = check_environment
2585
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2586
env_changes={'NON_EXISTANT_ENV_VAR':None})
2588
def test_working_dir(self):
2589
"""Test that we can specify the working dir for the child"""
2590
orig_getcwd = osutils.getcwd
2591
orig_chdir = os.chdir
2599
osutils.getcwd = getcwd
2601
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2604
osutils.getcwd = orig_getcwd
2606
os.chdir = orig_chdir
2607
self.assertEqual(['foo', 'current'], chdirs)
2609
def test_get_bzr_path_with_cwd_bzrlib(self):
2610
self.get_source_path = lambda: ""
2611
self.overrideAttr(os.path, "isfile", lambda path: True)
2612
self.assertEqual(self.get_bzr_path(), "bzr")
2615
class TestActuallyStartBzrSubprocess(tests.TestCaseWithTransport):
2616
"""Tests that really need to do things with an external bzr."""
2618
def test_start_and_stop_bzr_subprocess_send_signal(self):
2619
"""finish_bzr_subprocess raises self.failureException if the retcode is
2620
not the expected one.
2622
self.disable_missing_extensions_warning()
2623
process = self.start_bzr_subprocess(['wait-until-signalled'],
2624
skip_if_plan_to_signal=True)
2625
self.assertEqual('running\n', process.stdout.readline())
2626
result = self.finish_bzr_subprocess(process, send_signal=signal.SIGINT,
2628
self.assertEqual('', result[0])
2629
self.assertEqual('bzr: interrupted\n', result[1])
2632
class TestFeature(tests.TestCase):
2634
def test_caching(self):
2635
"""Feature._probe is called by the feature at most once."""
2636
class InstrumentedFeature(tests.Feature):
2638
super(InstrumentedFeature, self).__init__()
2641
self.calls.append('_probe')
2643
feature = InstrumentedFeature()
2645
self.assertEqual(['_probe'], feature.calls)
2647
self.assertEqual(['_probe'], feature.calls)
2649
def test_named_str(self):
2650
"""Feature.__str__ should thunk to feature_name()."""
2651
class NamedFeature(tests.Feature):
2652
def feature_name(self):
2654
feature = NamedFeature()
2655
self.assertEqual('symlinks', str(feature))
2657
def test_default_str(self):
2658
"""Feature.__str__ should default to __class__.__name__."""
2659
class NamedFeature(tests.Feature):
2661
feature = NamedFeature()
2662
self.assertEqual('NamedFeature', str(feature))
2665
class TestUnavailableFeature(tests.TestCase):
2667
def test_access_feature(self):
2668
feature = tests.Feature()
2669
exception = tests.UnavailableFeature(feature)
2670
self.assertIs(feature, exception.args[0])
2673
simple_thunk_feature = tests._CompatabilityThunkFeature(
2674
deprecated_in((2, 1, 0)),
2675
'bzrlib.tests.test_selftest',
2676
'simple_thunk_feature','UnicodeFilename',
2677
replacement_module='bzrlib.tests'
2680
class Test_CompatibilityFeature(tests.TestCase):
2682
def test_does_thunk(self):
2683
res = self.callDeprecated(
2684
['bzrlib.tests.test_selftest.simple_thunk_feature was deprecated'
2685
' in version 2.1.0. Use bzrlib.tests.UnicodeFilename instead.'],
2686
simple_thunk_feature.available)
2687
self.assertEqual(tests.UnicodeFilename.available(), res)
2690
class TestModuleAvailableFeature(tests.TestCase):
2692
def test_available_module(self):
2693
feature = tests.ModuleAvailableFeature('bzrlib.tests')
2694
self.assertEqual('bzrlib.tests', feature.module_name)
2695
self.assertEqual('bzrlib.tests', str(feature))
2696
self.assertTrue(feature.available())
2697
self.assertIs(tests, feature.module)
2699
def test_unavailable_module(self):
2700
feature = tests.ModuleAvailableFeature('bzrlib.no_such_module_exists')
2701
self.assertEqual('bzrlib.no_such_module_exists', str(feature))
2702
self.assertFalse(feature.available())
2703
self.assertIs(None, feature.module)
2706
class TestSelftestFiltering(tests.TestCase):
2709
tests.TestCase.setUp(self)
2710
self.suite = TestUtil.TestSuite()
2711
self.loader = TestUtil.TestLoader()
2712
self.suite.addTest(self.loader.loadTestsFromModule(
2713
sys.modules['bzrlib.tests.test_selftest']))
2714
self.all_names = _test_ids(self.suite)
2716
def test_condition_id_re(self):
2717
test_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2718
'test_condition_id_re')
2719
filtered_suite = tests.filter_suite_by_condition(
2720
self.suite, tests.condition_id_re('test_condition_id_re'))
2721
self.assertEqual([test_name], _test_ids(filtered_suite))
2723
def test_condition_id_in_list(self):
2724
test_names = ['bzrlib.tests.test_selftest.TestSelftestFiltering.'
2725
'test_condition_id_in_list']
2726
id_list = tests.TestIdList(test_names)
2727
filtered_suite = tests.filter_suite_by_condition(
2728
self.suite, tests.condition_id_in_list(id_list))
2729
my_pattern = 'TestSelftestFiltering.*test_condition_id_in_list'
2730
re_filtered = tests.filter_suite_by_re(self.suite, my_pattern)
2731
self.assertEqual(_test_ids(re_filtered), _test_ids(filtered_suite))
2733
def test_condition_id_startswith(self):
2734
klass = 'bzrlib.tests.test_selftest.TestSelftestFiltering.'
2735
start1 = klass + 'test_condition_id_starts'
2736
start2 = klass + 'test_condition_id_in'
2737
test_names = [ klass + 'test_condition_id_in_list',
2738
klass + 'test_condition_id_startswith',
2740
filtered_suite = tests.filter_suite_by_condition(
2741
self.suite, tests.condition_id_startswith([start1, start2]))
2742
self.assertEqual(test_names, _test_ids(filtered_suite))
2744
def test_condition_isinstance(self):
2745
filtered_suite = tests.filter_suite_by_condition(
2746
self.suite, tests.condition_isinstance(self.__class__))
2747
class_pattern = 'bzrlib.tests.test_selftest.TestSelftestFiltering.'
2748
re_filtered = tests.filter_suite_by_re(self.suite, class_pattern)
2749
self.assertEqual(_test_ids(re_filtered), _test_ids(filtered_suite))
2751
def test_exclude_tests_by_condition(self):
2752
excluded_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2753
'test_exclude_tests_by_condition')
2754
filtered_suite = tests.exclude_tests_by_condition(self.suite,
2755
lambda x:x.id() == excluded_name)
2756
self.assertEqual(len(self.all_names) - 1,
2757
filtered_suite.countTestCases())
2758
self.assertFalse(excluded_name in _test_ids(filtered_suite))
2759
remaining_names = list(self.all_names)
2760
remaining_names.remove(excluded_name)
2761
self.assertEqual(remaining_names, _test_ids(filtered_suite))
2763
def test_exclude_tests_by_re(self):
2764
self.all_names = _test_ids(self.suite)
2765
filtered_suite = tests.exclude_tests_by_re(self.suite,
2766
'exclude_tests_by_re')
2767
excluded_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2768
'test_exclude_tests_by_re')
2769
self.assertEqual(len(self.all_names) - 1,
2770
filtered_suite.countTestCases())
2771
self.assertFalse(excluded_name in _test_ids(filtered_suite))
2772
remaining_names = list(self.all_names)
2773
remaining_names.remove(excluded_name)
2774
self.assertEqual(remaining_names, _test_ids(filtered_suite))
2776
def test_filter_suite_by_condition(self):
2777
test_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2778
'test_filter_suite_by_condition')
2779
filtered_suite = tests.filter_suite_by_condition(self.suite,
2780
lambda x:x.id() == test_name)
2781
self.assertEqual([test_name], _test_ids(filtered_suite))
2783
def test_filter_suite_by_re(self):
2784
filtered_suite = tests.filter_suite_by_re(self.suite,
2785
'test_filter_suite_by_r')
2786
filtered_names = _test_ids(filtered_suite)
2787
self.assertEqual(filtered_names, ['bzrlib.tests.test_selftest.'
2788
'TestSelftestFiltering.test_filter_suite_by_re'])
2790
def test_filter_suite_by_id_list(self):
2791
test_list = ['bzrlib.tests.test_selftest.'
2792
'TestSelftestFiltering.test_filter_suite_by_id_list']
2793
filtered_suite = tests.filter_suite_by_id_list(
2794
self.suite, tests.TestIdList(test_list))
2795
filtered_names = _test_ids(filtered_suite)
2798
['bzrlib.tests.test_selftest.'
2799
'TestSelftestFiltering.test_filter_suite_by_id_list'])
2801
def test_filter_suite_by_id_startswith(self):
2802
# By design this test may fail if another test is added whose name also
2803
# begins with one of the start value used.
2804
klass = 'bzrlib.tests.test_selftest.TestSelftestFiltering.'
2805
start1 = klass + 'test_filter_suite_by_id_starts'
2806
start2 = klass + 'test_filter_suite_by_id_li'
2807
test_list = [klass + 'test_filter_suite_by_id_list',
2808
klass + 'test_filter_suite_by_id_startswith',
2810
filtered_suite = tests.filter_suite_by_id_startswith(
2811
self.suite, [start1, start2])
2814
_test_ids(filtered_suite),
2817
def test_preserve_input(self):
2818
# NB: Surely this is something in the stdlib to do this?
2819
self.assertTrue(self.suite is tests.preserve_input(self.suite))
2820
self.assertTrue("@#$" is tests.preserve_input("@#$"))
2822
def test_randomize_suite(self):
2823
randomized_suite = tests.randomize_suite(self.suite)
2824
# randomizing should not add or remove test names.
2825
self.assertEqual(set(_test_ids(self.suite)),
2826
set(_test_ids(randomized_suite)))
2827
# Technically, this *can* fail, because random.shuffle(list) can be
2828
# equal to list. Trying multiple times just pushes the frequency back.
2829
# As its len(self.all_names)!:1, the failure frequency should be low
2830
# enough to ignore. RBC 20071021.
2831
# It should change the order.
2832
self.assertNotEqual(self.all_names, _test_ids(randomized_suite))
2833
# But not the length. (Possibly redundant with the set test, but not
2835
self.assertEqual(len(self.all_names), len(_test_ids(randomized_suite)))
2837
def test_split_suit_by_condition(self):
2838
self.all_names = _test_ids(self.suite)
2839
condition = tests.condition_id_re('test_filter_suite_by_r')
2840
split_suite = tests.split_suite_by_condition(self.suite, condition)
2841
filtered_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2842
'test_filter_suite_by_re')
2843
self.assertEqual([filtered_name], _test_ids(split_suite[0]))
2844
self.assertFalse(filtered_name in _test_ids(split_suite[1]))
2845
remaining_names = list(self.all_names)
2846
remaining_names.remove(filtered_name)
2847
self.assertEqual(remaining_names, _test_ids(split_suite[1]))
2849
def test_split_suit_by_re(self):
2850
self.all_names = _test_ids(self.suite)
2851
split_suite = tests.split_suite_by_re(self.suite,
2852
'test_filter_suite_by_r')
2853
filtered_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2854
'test_filter_suite_by_re')
2855
self.assertEqual([filtered_name], _test_ids(split_suite[0]))
2856
self.assertFalse(filtered_name in _test_ids(split_suite[1]))
2857
remaining_names = list(self.all_names)
2858
remaining_names.remove(filtered_name)
2859
self.assertEqual(remaining_names, _test_ids(split_suite[1]))
2862
class TestCheckInventoryShape(tests.TestCaseWithTransport):
2864
def test_check_inventory_shape(self):
2865
files = ['a', 'b/', 'b/c']
2866
tree = self.make_branch_and_tree('.')
2867
self.build_tree(files)
2871
self.check_inventory_shape(tree.inventory, files)
2876
class TestBlackboxSupport(tests.TestCase):
2877
"""Tests for testsuite blackbox features."""
2879
def test_run_bzr_failure_not_caught(self):
2880
# When we run bzr in blackbox mode, we want any unexpected errors to
2881
# propagate up to the test suite so that it can show the error in the
2882
# usual way, and we won't get a double traceback.
2883
e = self.assertRaises(
2885
self.run_bzr, ['assert-fail'])
2886
# make sure we got the real thing, not an error from somewhere else in
2887
# the test framework
2888
self.assertEquals('always fails', str(e))
2889
# check that there's no traceback in the test log
2890
self.assertNotContainsRe(self.get_log(), r'Traceback')
2892
def test_run_bzr_user_error_caught(self):
2893
# Running bzr in blackbox mode, normal/expected/user errors should be
2894
# caught in the regular way and turned into an error message plus exit
2896
transport_server = memory.MemoryServer()
2897
transport_server.start_server()
2898
self.addCleanup(transport_server.stop_server)
2899
url = transport_server.get_url()
2900
self.permit_url(url)
2901
out, err = self.run_bzr(["log", "%s/nonexistantpath" % url], retcode=3)
2902
self.assertEqual(out, '')
2903
self.assertContainsRe(err,
2904
'bzr: ERROR: Not a branch: ".*nonexistantpath/".\n')
2907
class TestTestLoader(tests.TestCase):
2908
"""Tests for the test loader."""
2910
def _get_loader_and_module(self):
2911
"""Gets a TestLoader and a module with one test in it."""
2912
loader = TestUtil.TestLoader()
2914
class Stub(tests.TestCase):
2917
class MyModule(object):
2919
MyModule.a_class = Stub
2921
return loader, module
2923
def test_module_no_load_tests_attribute_loads_classes(self):
2924
loader, module = self._get_loader_and_module()
2925
self.assertEqual(1, loader.loadTestsFromModule(module).countTestCases())
2927
def test_module_load_tests_attribute_gets_called(self):
2928
loader, module = self._get_loader_and_module()
2929
# 'self' is here because we're faking the module with a class. Regular
2930
# load_tests do not need that :)
2931
def load_tests(self, standard_tests, module, loader):
2932
result = loader.suiteClass()
2933
for test in tests.iter_suite_tests(standard_tests):
2934
result.addTests([test, test])
2936
# add a load_tests() method which multiplies the tests from the module.
2937
module.__class__.load_tests = load_tests
2938
self.assertEqual(2, loader.loadTestsFromModule(module).countTestCases())
2940
def test_load_tests_from_module_name_smoke_test(self):
2941
loader = TestUtil.TestLoader()
2942
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
2943
self.assertEquals(['bzrlib.tests.test_sampler.DemoTest.test_nothing'],
2946
def test_load_tests_from_module_name_with_bogus_module_name(self):
2947
loader = TestUtil.TestLoader()
2948
self.assertRaises(ImportError, loader.loadTestsFromModuleName, 'bogus')
2951
class TestTestIdList(tests.TestCase):
2953
def _create_id_list(self, test_list):
2954
return tests.TestIdList(test_list)
2956
def _create_suite(self, test_id_list):
2958
class Stub(tests.TestCase):
2962
def _create_test_id(id):
2965
suite = TestUtil.TestSuite()
2966
for id in test_id_list:
2967
t = Stub('test_foo')
2968
t.id = _create_test_id(id)
2972
def _test_ids(self, test_suite):
2973
"""Get the ids for the tests in a test suite."""
2974
return [t.id() for t in tests.iter_suite_tests(test_suite)]
2976
def test_empty_list(self):
2977
id_list = self._create_id_list([])
2978
self.assertEquals({}, id_list.tests)
2979
self.assertEquals({}, id_list.modules)
2981
def test_valid_list(self):
2982
id_list = self._create_id_list(
2983
['mod1.cl1.meth1', 'mod1.cl1.meth2',
2984
'mod1.func1', 'mod1.cl2.meth2',
2986
'mod1.submod2.cl1.meth1', 'mod1.submod2.cl2.meth2',
2988
self.assertTrue(id_list.refers_to('mod1'))
2989
self.assertTrue(id_list.refers_to('mod1.submod1'))
2990
self.assertTrue(id_list.refers_to('mod1.submod2'))
2991
self.assertTrue(id_list.includes('mod1.cl1.meth1'))
2992
self.assertTrue(id_list.includes('mod1.submod1'))
2993
self.assertTrue(id_list.includes('mod1.func1'))
2995
def test_bad_chars_in_params(self):
2996
id_list = self._create_id_list(['mod1.cl1.meth1(xx.yy)'])
2997
self.assertTrue(id_list.refers_to('mod1'))
2998
self.assertTrue(id_list.includes('mod1.cl1.meth1(xx.yy)'))
3000
def test_module_used(self):
3001
id_list = self._create_id_list(['mod.class.meth'])
3002
self.assertTrue(id_list.refers_to('mod'))
3003
self.assertTrue(id_list.refers_to('mod.class'))
3004
self.assertTrue(id_list.refers_to('mod.class.meth'))
3006
def test_test_suite_matches_id_list_with_unknown(self):
3007
loader = TestUtil.TestLoader()
3008
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3009
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing',
3011
not_found, duplicates = tests.suite_matches_id_list(suite, test_list)
3012
self.assertEquals(['bogus'], not_found)
3013
self.assertEquals([], duplicates)
3015
def test_suite_matches_id_list_with_duplicates(self):
3016
loader = TestUtil.TestLoader()
3017
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3018
dupes = loader.suiteClass()
3019
for test in tests.iter_suite_tests(suite):
3021
dupes.addTest(test) # Add it again
3023
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing',]
3024
not_found, duplicates = tests.suite_matches_id_list(
3026
self.assertEquals([], not_found)
3027
self.assertEquals(['bzrlib.tests.test_sampler.DemoTest.test_nothing'],
3031
class TestTestSuite(tests.TestCase):
3033
def test__test_suite_testmod_names(self):
3034
# Test that a plausible list of test module names are returned
3035
# by _test_suite_testmod_names.
3036
test_list = tests._test_suite_testmod_names()
3038
'bzrlib.tests.blackbox',
3039
'bzrlib.tests.per_transport',
3040
'bzrlib.tests.test_selftest',
3044
def test__test_suite_modules_to_doctest(self):
3045
# Test that a plausible list of modules to doctest is returned
3046
# by _test_suite_modules_to_doctest.
3047
test_list = tests._test_suite_modules_to_doctest()
3049
# When docstrings are stripped, there are no modules to doctest
3050
self.assertEqual([], test_list)
3057
def test_test_suite(self):
3058
# test_suite() loads the entire test suite to operate. To avoid this
3059
# overhead, and yet still be confident that things are happening,
3060
# we temporarily replace two functions used by test_suite with
3061
# test doubles that supply a few sample tests to load, and check they
3064
def testmod_names():
3065
calls.append("testmod_names")
3067
'bzrlib.tests.blackbox.test_branch',
3068
'bzrlib.tests.per_transport',
3069
'bzrlib.tests.test_selftest',
3071
self.overrideAttr(tests, '_test_suite_testmod_names', testmod_names)
3073
calls.append("modules_to_doctest")
3076
return ['bzrlib.timestamp']
3077
self.overrideAttr(tests, '_test_suite_modules_to_doctest', doctests)
3078
expected_test_list = [
3080
'bzrlib.tests.blackbox.test_branch.TestBranch.test_branch',
3081
('bzrlib.tests.per_transport.TransportTests'
3082
'.test_abspath(LocalTransport,LocalURLServer)'),
3083
'bzrlib.tests.test_selftest.TestTestSuite.test_test_suite',
3084
# plugins can't be tested that way since selftest may be run with
3087
if __doc__ is not None:
3088
expected_test_list.extend([
3089
# modules_to_doctest
3090
'bzrlib.timestamp.format_highres_date',
3092
suite = tests.test_suite()
3093
self.assertEqual(set(["testmod_names", "modules_to_doctest"]),
3095
self.assertSubset(expected_test_list, _test_ids(suite))
3097
def test_test_suite_list_and_start(self):
3098
# We cannot test this at the same time as the main load, because we want
3099
# to know that starting_with == None works. So a second load is
3100
# incurred - note that the starting_with parameter causes a partial load
3101
# rather than a full load so this test should be pretty quick.
3102
test_list = ['bzrlib.tests.test_selftest.TestTestSuite.test_test_suite']
3103
suite = tests.test_suite(test_list,
3104
['bzrlib.tests.test_selftest.TestTestSuite'])
3105
# test_test_suite_list_and_start is not included
3106
self.assertEquals(test_list, _test_ids(suite))
3109
class TestLoadTestIdList(tests.TestCaseInTempDir):
3111
def _create_test_list_file(self, file_name, content):
3112
fl = open(file_name, 'wt')
3116
def test_load_unknown(self):
3117
self.assertRaises(errors.NoSuchFile,
3118
tests.load_test_id_list, 'i_do_not_exist')
3120
def test_load_test_list(self):
3121
test_list_fname = 'test.list'
3122
self._create_test_list_file(test_list_fname,
3123
'mod1.cl1.meth1\nmod2.cl2.meth2\n')
3124
tlist = tests.load_test_id_list(test_list_fname)
3125
self.assertEquals(2, len(tlist))
3126
self.assertEquals('mod1.cl1.meth1', tlist[0])
3127
self.assertEquals('mod2.cl2.meth2', tlist[1])
3129
def test_load_dirty_file(self):
3130
test_list_fname = 'test.list'
3131
self._create_test_list_file(test_list_fname,
3132
' mod1.cl1.meth1\n\nmod2.cl2.meth2 \n'
3134
tlist = tests.load_test_id_list(test_list_fname)
3135
self.assertEquals(4, len(tlist))
3136
self.assertEquals('mod1.cl1.meth1', tlist[0])
3137
self.assertEquals('', tlist[1])
3138
self.assertEquals('mod2.cl2.meth2', tlist[2])
3139
self.assertEquals('bar baz', tlist[3])
3142
class TestFilteredByModuleTestLoader(tests.TestCase):
3144
def _create_loader(self, test_list):
3145
id_filter = tests.TestIdList(test_list)
3146
loader = TestUtil.FilteredByModuleTestLoader(id_filter.refers_to)
3149
def test_load_tests(self):
3150
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
3151
loader = self._create_loader(test_list)
3152
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3153
self.assertEquals(test_list, _test_ids(suite))
3155
def test_exclude_tests(self):
3156
test_list = ['bogus']
3157
loader = self._create_loader(test_list)
3158
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3159
self.assertEquals([], _test_ids(suite))
3162
class TestFilteredByNameStartTestLoader(tests.TestCase):
3164
def _create_loader(self, name_start):
3165
def needs_module(name):
3166
return name.startswith(name_start) or name_start.startswith(name)
3167
loader = TestUtil.FilteredByModuleTestLoader(needs_module)
3170
def test_load_tests(self):
3171
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
3172
loader = self._create_loader('bzrlib.tests.test_samp')
3174
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3175
self.assertEquals(test_list, _test_ids(suite))
3177
def test_load_tests_inside_module(self):
3178
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
3179
loader = self._create_loader('bzrlib.tests.test_sampler.Demo')
3181
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3182
self.assertEquals(test_list, _test_ids(suite))
3184
def test_exclude_tests(self):
3185
test_list = ['bogus']
3186
loader = self._create_loader('bogus')
3188
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3189
self.assertEquals([], _test_ids(suite))
3192
class TestTestPrefixRegistry(tests.TestCase):
3194
def _get_registry(self):
3195
tp_registry = tests.TestPrefixAliasRegistry()
3198
def test_register_new_prefix(self):
3199
tpr = self._get_registry()
3200
tpr.register('foo', 'fff.ooo.ooo')
3201
self.assertEquals('fff.ooo.ooo', tpr.get('foo'))
3203
def test_register_existing_prefix(self):
3204
tpr = self._get_registry()
3205
tpr.register('bar', 'bbb.aaa.rrr')
3206
tpr.register('bar', 'bBB.aAA.rRR')
3207
self.assertEquals('bbb.aaa.rrr', tpr.get('bar'))
3208
self.assertThat(self.get_log(),
3209
DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR",
3212
def test_get_unknown_prefix(self):
3213
tpr = self._get_registry()
3214
self.assertRaises(KeyError, tpr.get, 'I am not a prefix')
3216
def test_resolve_prefix(self):
3217
tpr = self._get_registry()
3218
tpr.register('bar', 'bb.aa.rr')
3219
self.assertEquals('bb.aa.rr', tpr.resolve_alias('bar'))
3221
def test_resolve_unknown_alias(self):
3222
tpr = self._get_registry()
3223
self.assertRaises(errors.BzrCommandError,
3224
tpr.resolve_alias, 'I am not a prefix')
3226
def test_predefined_prefixes(self):
3227
tpr = tests.test_prefix_alias_registry
3228
self.assertEquals('bzrlib', tpr.resolve_alias('bzrlib'))
3229
self.assertEquals('bzrlib.doc', tpr.resolve_alias('bd'))
3230
self.assertEquals('bzrlib.utils', tpr.resolve_alias('bu'))
3231
self.assertEquals('bzrlib.tests', tpr.resolve_alias('bt'))
3232
self.assertEquals('bzrlib.tests.blackbox', tpr.resolve_alias('bb'))
3233
self.assertEquals('bzrlib.plugins', tpr.resolve_alias('bp'))
3236
class TestThreadLeakDetection(tests.TestCase):
3237
"""Ensure when tests leak threads we detect and report it"""
3239
class LeakRecordingResult(tests.ExtendedTestResult):
3241
tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
3243
def _report_thread_leak(self, test, leaks, alive):
3244
self.leaks.append((test, leaks))
3246
def test_testcase_without_addCleanups(self):
3247
"""Check old TestCase instances don't break with leak detection"""
3248
class Test(unittest.TestCase):
3251
result = self.LeakRecordingResult()
3253
result.startTestRun()
3255
result.stopTestRun()
3256
self.assertEqual(result._tests_leaking_threads_count, 0)
3257
self.assertEqual(result.leaks, [])
3259
def test_thread_leak(self):
3260
"""Ensure a thread that outlives the running of a test is reported
3262
Uses a thread that blocks on an event, and is started by the inner
3263
test case. As the thread outlives the inner case's run, it should be
3264
detected as a leak, but the event is then set so that the thread can
3265
be safely joined in cleanup so it's not leaked for real.
3267
event = threading.Event()
3268
thread = threading.Thread(name="Leaker", target=event.wait)
3269
class Test(tests.TestCase):
3270
def test_leak(self):
3272
result = self.LeakRecordingResult()
3273
test = Test("test_leak")
3274
self.addCleanup(thread.join)
3275
self.addCleanup(event.set)
3276
result.startTestRun()
3278
result.stopTestRun()
3279
self.assertEqual(result._tests_leaking_threads_count, 1)
3280
self.assertEqual(result._first_thread_leaker_id, test.id())
3281
self.assertEqual(result.leaks, [(test, set([thread]))])
3282
self.assertContainsString(result.stream.getvalue(), "leaking threads")
3284
def test_multiple_leaks(self):
3285
"""Check multiple leaks are blamed on the test cases at fault
3287
Same concept as the previous test, but has one inner test method that
3288
leaks two threads, and one that doesn't leak at all.
3290
event = threading.Event()
3291
thread_a = threading.Thread(name="LeakerA", target=event.wait)
3292
thread_b = threading.Thread(name="LeakerB", target=event.wait)
3293
thread_c = threading.Thread(name="LeakerC", target=event.wait)
3294
class Test(tests.TestCase):
3295
def test_first_leak(self):
3297
def test_second_no_leak(self):
3299
def test_third_leak(self):
3302
result = self.LeakRecordingResult()
3303
first_test = Test("test_first_leak")
3304
third_test = Test("test_third_leak")
3305
self.addCleanup(thread_a.join)
3306
self.addCleanup(thread_b.join)
3307
self.addCleanup(thread_c.join)
3308
self.addCleanup(event.set)
3309
result.startTestRun()
3311
[first_test, Test("test_second_no_leak"), third_test]
3313
result.stopTestRun()
3314
self.assertEqual(result._tests_leaking_threads_count, 2)
3315
self.assertEqual(result._first_thread_leaker_id, first_test.id())
3316
self.assertEqual(result.leaks, [
3317
(first_test, set([thread_b])),
3318
(third_test, set([thread_a, thread_c]))])
3319
self.assertContainsString(result.stream.getvalue(), "leaking threads")
3322
class TestPostMortemDebugging(tests.TestCase):
3323
"""Check post mortem debugging works when tests fail or error"""
3325
class TracebackRecordingResult(tests.ExtendedTestResult):
3327
tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
3328
self.postcode = None
3329
def _post_mortem(self, tb=None):
3330
"""Record the code object at the end of the current traceback"""
3331
tb = tb or sys.exc_info()[2]
3334
while next is not None:
3337
self.postcode = tb.tb_frame.f_code
3338
def report_error(self, test, err):
3340
def report_failure(self, test, err):
3343
def test_location_unittest_error(self):
3344
"""Needs right post mortem traceback with erroring unittest case"""
3345
class Test(unittest.TestCase):
3348
result = self.TracebackRecordingResult()
3350
self.assertEqual(result.postcode, Test.runTest.func_code)
3352
def test_location_unittest_failure(self):
3353
"""Needs right post mortem traceback with failing unittest case"""
3354
class Test(unittest.TestCase):
3356
raise self.failureException
3357
result = self.TracebackRecordingResult()
3359
self.assertEqual(result.postcode, Test.runTest.func_code)
3361
def test_location_bt_error(self):
3362
"""Needs right post mortem traceback with erroring bzrlib.tests case"""
3363
class Test(tests.TestCase):
3364
def test_error(self):
3366
result = self.TracebackRecordingResult()
3367
Test("test_error").run(result)
3368
self.assertEqual(result.postcode, Test.test_error.func_code)
3370
def test_location_bt_failure(self):
3371
"""Needs right post mortem traceback with failing bzrlib.tests case"""
3372
class Test(tests.TestCase):
3373
def test_failure(self):
3374
raise self.failureException
3375
result = self.TracebackRecordingResult()
3376
Test("test_failure").run(result)
3377
self.assertEqual(result.postcode, Test.test_failure.func_code)
3379
def test_env_var_triggers_post_mortem(self):
3380
"""Check pdb.post_mortem is called iff BZR_TEST_PDB is set"""
3382
result = tests.ExtendedTestResult(StringIO(), 0, 1)
3383
post_mortem_calls = []
3384
self.overrideAttr(pdb, "post_mortem", post_mortem_calls.append)
3385
self.overrideEnv('BZR_TEST_PDB', None)
3386
result._post_mortem(1)
3387
self.overrideEnv('BZR_TEST_PDB', 'on')
3388
result._post_mortem(2)
3389
self.assertEqual([2], post_mortem_calls)
3392
class TestRunSuite(tests.TestCase):
3394
def test_runner_class(self):
3395
"""run_suite accepts and uses a runner_class keyword argument."""
3396
class Stub(tests.TestCase):
3399
suite = Stub("test_foo")
3401
class MyRunner(tests.TextTestRunner):
3402
def run(self, test):
3404
return tests.ExtendedTestResult(self.stream, self.descriptions,
3406
tests.run_suite(suite, runner_class=MyRunner, stream=StringIO())
3407
self.assertLength(1, calls)
3410
class TestEnvironHandling(tests.TestCase):
3412
def test_overrideEnv_None_called_twice_doesnt_leak(self):
3413
self.failIf('MYVAR' in os.environ)
3414
self.overrideEnv('MYVAR', '42')
3415
# We use an embedded test to make sure we fix the _captureVar bug
3416
class Test(tests.TestCase):
3418
# The first call save the 42 value
3419
self.overrideEnv('MYVAR', None)
3420
self.assertEquals(None, os.environ.get('MYVAR'))
3421
# Make sure we can call it twice
3422
self.overrideEnv('MYVAR', None)
3423
self.assertEquals(None, os.environ.get('MYVAR'))
3425
result = tests.TextTestResult(output, 0, 1)
3426
Test('test_me').run(result)
3427
if not result.wasStrictlySuccessful():
3428
self.fail(output.getvalue())
3429
# We get our value back
3430
self.assertEquals('42', os.environ.get('MYVAR'))
3433
class TestIsolatedEnv(tests.TestCase):
3434
"""Test isolating tests from os.environ.
3436
Since we use tests that are already isolated from os.environ a bit of care
3437
should be taken when designing the tests to avoid bootstrap side-effects.
3438
The tests start an already clean os.environ which allow doing valid
3439
assertions about which variables are present or not and design tests around
3443
class ScratchMonkey(tests.TestCase):
3448
def test_basics(self):
3449
# Make sure we know the definition of BZR_HOME: not part of os.environ
3450
# for tests.TestCase.
3451
self.assertTrue('BZR_HOME' in tests.isolated_environ)
3452
self.assertEquals(None, tests.isolated_environ['BZR_HOME'])
3453
# Being part of isolated_environ, BZR_HOME should not appear here
3454
self.assertFalse('BZR_HOME' in os.environ)
3455
# Make sure we know the definition of LINES: part of os.environ for
3457
self.assertTrue('LINES' in tests.isolated_environ)
3458
self.assertEquals('25', tests.isolated_environ['LINES'])
3459
self.assertEquals('25', os.environ['LINES'])
3461
def test_injecting_unknown_variable(self):
3462
# BZR_HOME is known to be absent from os.environ
3463
test = self.ScratchMonkey('test_me')
3464
tests.override_os_environ(test, {'BZR_HOME': 'foo'})
3465
self.assertEquals('foo', os.environ['BZR_HOME'])
3466
tests.restore_os_environ(test)
3467
self.assertFalse('BZR_HOME' in os.environ)
3469
def test_injecting_known_variable(self):
3470
test = self.ScratchMonkey('test_me')
3471
# LINES is known to be present in os.environ
3472
tests.override_os_environ(test, {'LINES': '42'})
3473
self.assertEquals('42', os.environ['LINES'])
3474
tests.restore_os_environ(test)
3475
self.assertEquals('25', os.environ['LINES'])
3477
def test_deleting_variable(self):
3478
test = self.ScratchMonkey('test_me')
3479
# LINES is known to be present in os.environ
3480
tests.override_os_environ(test, {'LINES': None})
3481
self.assertTrue('LINES' not in os.environ)
3482
tests.restore_os_environ(test)
3483
self.assertEquals('25', os.environ['LINES'])
3486
class TestDocTestSuiteIsolation(tests.TestCase):
3487
"""Test that `tests.DocTestSuite` isolates doc tests from os.environ.
3489
Since tests.TestCase alreay provides an isolation from os.environ, we use
3490
the clean environment as a base for testing. To precisely capture the
3491
isolation provided by tests.DocTestSuite, we use doctest.DocTestSuite to
3494
We want to make sure `tests.DocTestSuite` respect `tests.isolated_environ`,
3495
not `os.environ` so each test overrides it to suit its needs.
3499
def get_doctest_suite_for_string(self, klass, string):
3500
class Finder(doctest.DocTestFinder):
3502
def find(*args, **kwargs):
3503
test = doctest.DocTestParser().get_doctest(
3504
string, {}, 'foo', 'foo.py', 0)
3507
suite = klass(test_finder=Finder())
3510
def run_doctest_suite_for_string(self, klass, string):
3511
suite = self.get_doctest_suite_for_string(klass, string)
3513
result = tests.TextTestResult(output, 0, 1)
3515
return result, output
3517
def assertDocTestStringSucceds(self, klass, string):
3518
result, output = self.run_doctest_suite_for_string(klass, string)
3519
if not result.wasStrictlySuccessful():
3520
self.fail(output.getvalue())
3522
def assertDocTestStringFails(self, klass, string):
3523
result, output = self.run_doctest_suite_for_string(klass, string)
3524
if result.wasStrictlySuccessful():
3525
self.fail(output.getvalue())
3527
def test_injected_variable(self):
3528
self.overrideAttr(tests, 'isolated_environ', {'LINES': '42'})
3531
>>> os.environ['LINES']
3534
# doctest.DocTestSuite fails as it sees '25'
3535
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3536
# tests.DocTestSuite sees '42'
3537
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
3539
def test_deleted_variable(self):
3540
self.overrideAttr(tests, 'isolated_environ', {'LINES': None})
3543
>>> os.environ.get('LINES')
3545
# doctest.DocTestSuite fails as it sees '25'
3546
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3547
# tests.DocTestSuite sees None
3548
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)