1
# Copyright (C) 2005-2011 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
"""Tests for the test framework."""
19
from cStringIO import StringIO
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 (
59
from bzrlib.symbol_versioning import (
64
from bzrlib.tests import (
70
from bzrlib.trace import note, mutter
71
from bzrlib.transport import memory
74
def _test_ids(test_suite):
75
"""Get the ids for the tests in a test suite."""
76
return [t.id() for t in tests.iter_suite_tests(test_suite)]
79
class MetaTestLog(tests.TestCase):
81
def test_logging(self):
82
"""Test logs are captured when a test fails."""
83
self.log('a test message')
84
details = self.getDetails()
86
self.assertThat(log.content_type, Equals(ContentType(
87
"text", "plain", {"charset": "utf8"})))
88
self.assertThat(u"".join(log.iter_text()), Equals(self.get_log()))
89
self.assertThat(self.get_log(),
90
DocTestMatches(u"...a test message\n", doctest.ELLIPSIS))
93
class TestUnicodeFilename(tests.TestCase):
95
def test_probe_passes(self):
96
"""UnicodeFilename._probe passes."""
97
# We can't test much more than that because the behaviour depends
99
tests.UnicodeFilename._probe()
102
class TestTreeShape(tests.TestCaseInTempDir):
104
def test_unicode_paths(self):
105
self.requireFeature(tests.UnicodeFilename)
107
filename = u'hell\u00d8'
108
self.build_tree_contents([(filename, 'contents of hello')])
109
self.assertPathExists(filename)
112
class TestClassesAvailable(tests.TestCase):
113
"""As a convenience we expose Test* classes from bzrlib.tests"""
115
def test_test_case(self):
116
from bzrlib.tests import TestCase
118
def test_test_loader(self):
119
from bzrlib.tests import TestLoader
121
def test_test_suite(self):
122
from bzrlib.tests import TestSuite
125
class TestTransportScenarios(tests.TestCase):
126
"""A group of tests that test the transport implementation adaption core.
128
This is a meta test that the tests are applied to all available
131
This will be generalised in the future which is why it is in this
132
test file even though it is specific to transport tests at the moment.
135
def test_get_transport_permutations(self):
136
# this checks that get_test_permutations defined by the module is
137
# called by the get_transport_test_permutations function.
138
class MockModule(object):
139
def get_test_permutations(self):
140
return sample_permutation
141
sample_permutation = [(1,2), (3,4)]
142
from bzrlib.tests.per_transport import get_transport_test_permutations
143
self.assertEqual(sample_permutation,
144
get_transport_test_permutations(MockModule()))
146
def test_scenarios_include_all_modules(self):
147
# this checks that the scenario generator returns as many permutations
148
# as there are in all the registered transport modules - we assume if
149
# this matches its probably doing the right thing especially in
150
# combination with the tests for setting the right classes below.
151
from bzrlib.tests.per_transport import transport_test_permutations
152
from bzrlib.transport import _get_transport_modules
153
modules = _get_transport_modules()
154
permutation_count = 0
155
for module in modules:
157
permutation_count += len(reduce(getattr,
158
(module + ".get_test_permutations").split('.')[1:],
159
__import__(module))())
160
except errors.DependencyNotPresent:
162
scenarios = transport_test_permutations()
163
self.assertEqual(permutation_count, len(scenarios))
165
def test_scenarios_include_transport_class(self):
166
# This test used to know about all the possible transports and the
167
# order they were returned but that seems overly brittle (mbp
169
from bzrlib.tests.per_transport import transport_test_permutations
170
scenarios = transport_test_permutations()
171
# there are at least that many builtin transports
172
self.assertTrue(len(scenarios) > 6)
173
one_scenario = scenarios[0]
174
self.assertIsInstance(one_scenario[0], str)
175
self.assertTrue(issubclass(one_scenario[1]["transport_class"],
176
bzrlib.transport.Transport))
177
self.assertTrue(issubclass(one_scenario[1]["transport_server"],
178
bzrlib.transport.Server))
181
class TestBranchScenarios(tests.TestCase):
183
def test_scenarios(self):
184
# check that constructor parameters are passed through to the adapted
186
from bzrlib.tests.per_branch import make_scenarios
189
formats = [("c", "C"), ("d", "D")]
190
scenarios = make_scenarios(server1, server2, formats)
191
self.assertEqual(2, len(scenarios))
194
{'branch_format': 'c',
195
'bzrdir_format': 'C',
196
'transport_readonly_server': 'b',
197
'transport_server': 'a'}),
199
{'branch_format': 'd',
200
'bzrdir_format': 'D',
201
'transport_readonly_server': 'b',
202
'transport_server': 'a'})],
206
class TestBzrDirScenarios(tests.TestCase):
208
def test_scenarios(self):
209
# check that constructor parameters are passed through to the adapted
211
from bzrlib.tests.per_controldir import make_scenarios
216
scenarios = make_scenarios(vfs_factory, server1, server2, formats)
219
{'bzrdir_format': 'c',
220
'transport_readonly_server': 'b',
221
'transport_server': 'a',
222
'vfs_transport_factory': 'v'}),
224
{'bzrdir_format': 'd',
225
'transport_readonly_server': 'b',
226
'transport_server': 'a',
227
'vfs_transport_factory': 'v'})],
231
class TestRepositoryScenarios(tests.TestCase):
233
def test_formats_to_scenarios(self):
234
from bzrlib.tests.per_repository import formats_to_scenarios
235
formats = [("(c)", remote.RemoteRepositoryFormat()),
236
("(d)", repository.format_registry.get(
237
'Bazaar repository format 2a (needs bzr 1.16 or later)\n'))]
238
no_vfs_scenarios = formats_to_scenarios(formats, "server", "readonly",
240
vfs_scenarios = formats_to_scenarios(formats, "server", "readonly",
241
vfs_transport_factory="vfs")
242
# no_vfs generate scenarios without vfs_transport_factory
244
('RemoteRepositoryFormat(c)',
245
{'bzrdir_format': remote.RemoteBzrDirFormat(),
246
'repository_format': remote.RemoteRepositoryFormat(),
247
'transport_readonly_server': 'readonly',
248
'transport_server': 'server'}),
249
('RepositoryFormat2a(d)',
250
{'bzrdir_format': bzrdir.BzrDirMetaFormat1(),
251
'repository_format': groupcompress_repo.RepositoryFormat2a(),
252
'transport_readonly_server': 'readonly',
253
'transport_server': 'server'})]
254
self.assertEqual(expected, no_vfs_scenarios)
256
('RemoteRepositoryFormat(c)',
257
{'bzrdir_format': remote.RemoteBzrDirFormat(),
258
'repository_format': remote.RemoteRepositoryFormat(),
259
'transport_readonly_server': 'readonly',
260
'transport_server': 'server',
261
'vfs_transport_factory': 'vfs'}),
262
('RepositoryFormat2a(d)',
263
{'bzrdir_format': bzrdir.BzrDirMetaFormat1(),
264
'repository_format': groupcompress_repo.RepositoryFormat2a(),
265
'transport_readonly_server': 'readonly',
266
'transport_server': 'server',
267
'vfs_transport_factory': 'vfs'})],
271
class TestTestScenarioApplication(tests.TestCase):
272
"""Tests for the test adaption facilities."""
274
def test_apply_scenario(self):
275
from bzrlib.tests import apply_scenario
276
input_test = TestTestScenarioApplication("test_apply_scenario")
277
# setup two adapted tests
278
adapted_test1 = apply_scenario(input_test,
280
{"bzrdir_format":"bzr_format",
281
"repository_format":"repo_fmt",
282
"transport_server":"transport_server",
283
"transport_readonly_server":"readonly-server"}))
284
adapted_test2 = apply_scenario(input_test,
285
("new id 2", {"bzrdir_format":None}))
286
# input_test should have been altered.
287
self.assertRaises(AttributeError, getattr, input_test, "bzrdir_format")
288
# the new tests are mutually incompatible, ensuring it has
289
# made new ones, and unspecified elements in the scenario
290
# should not have been altered.
291
self.assertEqual("bzr_format", adapted_test1.bzrdir_format)
292
self.assertEqual("repo_fmt", adapted_test1.repository_format)
293
self.assertEqual("transport_server", adapted_test1.transport_server)
294
self.assertEqual("readonly-server",
295
adapted_test1.transport_readonly_server)
297
"bzrlib.tests.test_selftest.TestTestScenarioApplication."
298
"test_apply_scenario(new id)",
300
self.assertEqual(None, adapted_test2.bzrdir_format)
302
"bzrlib.tests.test_selftest.TestTestScenarioApplication."
303
"test_apply_scenario(new id 2)",
307
class TestInterRepositoryScenarios(tests.TestCase):
309
def test_scenarios(self):
310
# check that constructor parameters are passed through to the adapted
312
from bzrlib.tests.per_interrepository import make_scenarios
315
formats = [("C0", "C1", "C2", "C3"), ("D0", "D1", "D2", "D3")]
316
scenarios = make_scenarios(server1, server2, formats)
319
{'repository_format': 'C1',
320
'repository_format_to': 'C2',
321
'transport_readonly_server': 'b',
322
'transport_server': 'a',
323
'extra_setup': 'C3'}),
325
{'repository_format': 'D1',
326
'repository_format_to': 'D2',
327
'transport_readonly_server': 'b',
328
'transport_server': 'a',
329
'extra_setup': 'D3'})],
333
class TestWorkingTreeScenarios(tests.TestCase):
335
def test_scenarios(self):
336
# check that constructor parameters are passed through to the adapted
338
from bzrlib.tests.per_workingtree import make_scenarios
341
formats = [workingtree.WorkingTreeFormat4(),
342
workingtree.WorkingTreeFormat3(),]
343
scenarios = make_scenarios(server1, server2, formats)
345
('WorkingTreeFormat4',
346
{'bzrdir_format': formats[0]._matchingbzrdir,
347
'transport_readonly_server': 'b',
348
'transport_server': 'a',
349
'workingtree_format': formats[0]}),
350
('WorkingTreeFormat3',
351
{'bzrdir_format': formats[1]._matchingbzrdir,
352
'transport_readonly_server': 'b',
353
'transport_server': 'a',
354
'workingtree_format': formats[1]})],
358
class TestTreeScenarios(tests.TestCase):
360
def test_scenarios(self):
361
# the tree implementation scenario generator is meant to setup one
362
# instance for each working tree format, and one additional instance
363
# that will use the default wt format, but create a revision tree for
364
# the tests. this means that the wt ones should have the
365
# workingtree_to_test_tree attribute set to 'return_parameter' and the
366
# revision one set to revision_tree_from_workingtree.
368
from bzrlib.tests.per_tree import (
369
_dirstate_tree_from_workingtree,
374
revision_tree_from_workingtree
378
formats = [workingtree.WorkingTreeFormat4(),
379
workingtree.WorkingTreeFormat3(),]
380
scenarios = make_scenarios(server1, server2, formats)
381
self.assertEqual(7, len(scenarios))
382
default_wt_format = workingtree.format_registry.get_default()
383
wt4_format = workingtree.WorkingTreeFormat4()
384
wt5_format = workingtree.WorkingTreeFormat5()
385
expected_scenarios = [
386
('WorkingTreeFormat4',
387
{'bzrdir_format': formats[0]._matchingbzrdir,
388
'transport_readonly_server': 'b',
389
'transport_server': 'a',
390
'workingtree_format': formats[0],
391
'_workingtree_to_test_tree': return_parameter,
393
('WorkingTreeFormat3',
394
{'bzrdir_format': formats[1]._matchingbzrdir,
395
'transport_readonly_server': 'b',
396
'transport_server': 'a',
397
'workingtree_format': formats[1],
398
'_workingtree_to_test_tree': return_parameter,
401
{'_workingtree_to_test_tree': revision_tree_from_workingtree,
402
'bzrdir_format': default_wt_format._matchingbzrdir,
403
'transport_readonly_server': 'b',
404
'transport_server': 'a',
405
'workingtree_format': default_wt_format,
407
('DirStateRevisionTree,WT4',
408
{'_workingtree_to_test_tree': _dirstate_tree_from_workingtree,
409
'bzrdir_format': wt4_format._matchingbzrdir,
410
'transport_readonly_server': 'b',
411
'transport_server': 'a',
412
'workingtree_format': wt4_format,
414
('DirStateRevisionTree,WT5',
415
{'_workingtree_to_test_tree': _dirstate_tree_from_workingtree,
416
'bzrdir_format': wt5_format._matchingbzrdir,
417
'transport_readonly_server': 'b',
418
'transport_server': 'a',
419
'workingtree_format': wt5_format,
422
{'_workingtree_to_test_tree': preview_tree_pre,
423
'bzrdir_format': default_wt_format._matchingbzrdir,
424
'transport_readonly_server': 'b',
425
'transport_server': 'a',
426
'workingtree_format': default_wt_format}),
428
{'_workingtree_to_test_tree': preview_tree_post,
429
'bzrdir_format': default_wt_format._matchingbzrdir,
430
'transport_readonly_server': 'b',
431
'transport_server': 'a',
432
'workingtree_format': default_wt_format}),
434
self.assertEqual(expected_scenarios, scenarios)
437
class TestInterTreeScenarios(tests.TestCase):
438
"""A group of tests that test the InterTreeTestAdapter."""
440
def test_scenarios(self):
441
# check that constructor parameters are passed through to the adapted
443
# for InterTree tests we want the machinery to bring up two trees in
444
# each instance: the base one, and the one we are interacting with.
445
# because each optimiser can be direction specific, we need to test
446
# each optimiser in its chosen direction.
447
# unlike the TestProviderAdapter we dont want to automatically add a
448
# parameterized one for WorkingTree - the optimisers will tell us what
450
from bzrlib.tests.per_tree import (
453
from bzrlib.tests.per_intertree import (
456
from bzrlib.workingtree import WorkingTreeFormat3, WorkingTreeFormat4
457
input_test = TestInterTreeScenarios(
461
format1 = WorkingTreeFormat4()
462
format2 = WorkingTreeFormat3()
463
formats = [("1", str, format1, format2, "converter1"),
464
("2", int, format2, format1, "converter2")]
465
scenarios = make_scenarios(server1, server2, formats)
466
self.assertEqual(2, len(scenarios))
467
expected_scenarios = [
469
"bzrdir_format": format1._matchingbzrdir,
470
"intertree_class": formats[0][1],
471
"workingtree_format": formats[0][2],
472
"workingtree_format_to": formats[0][3],
473
"mutable_trees_to_test_trees": formats[0][4],
474
"_workingtree_to_test_tree": return_parameter,
475
"transport_server": server1,
476
"transport_readonly_server": server2,
479
"bzrdir_format": format2._matchingbzrdir,
480
"intertree_class": formats[1][1],
481
"workingtree_format": formats[1][2],
482
"workingtree_format_to": formats[1][3],
483
"mutable_trees_to_test_trees": formats[1][4],
484
"_workingtree_to_test_tree": return_parameter,
485
"transport_server": server1,
486
"transport_readonly_server": server2,
489
self.assertEqual(scenarios, expected_scenarios)
492
class TestTestCaseInTempDir(tests.TestCaseInTempDir):
494
def test_home_is_not_working(self):
495
self.assertNotEqual(self.test_dir, self.test_home_dir)
496
cwd = osutils.getcwd()
497
self.assertIsSameRealPath(self.test_dir, cwd)
498
self.assertIsSameRealPath(self.test_home_dir, os.environ['HOME'])
500
def test_assertEqualStat_equal(self):
501
from bzrlib.tests.test_dirstate import _FakeStat
502
self.build_tree(["foo"])
503
real = os.lstat("foo")
504
fake = _FakeStat(real.st_size, real.st_mtime, real.st_ctime,
505
real.st_dev, real.st_ino, real.st_mode)
506
self.assertEqualStat(real, fake)
508
def test_assertEqualStat_notequal(self):
509
self.build_tree(["foo", "longname"])
510
self.assertRaises(AssertionError, self.assertEqualStat,
511
os.lstat("foo"), os.lstat("longname"))
513
def test_failUnlessExists(self):
514
"""Deprecated failUnlessExists and failIfExists"""
515
self.applyDeprecated(
516
deprecated_in((2, 4)),
517
self.failUnlessExists, '.')
518
self.build_tree(['foo/', 'foo/bar'])
519
self.applyDeprecated(
520
deprecated_in((2, 4)),
521
self.failUnlessExists, 'foo/bar')
522
self.applyDeprecated(
523
deprecated_in((2, 4)),
524
self.failIfExists, 'foo/foo')
526
def test_assertPathExists(self):
527
self.assertPathExists('.')
528
self.build_tree(['foo/', 'foo/bar'])
529
self.assertPathExists('foo/bar')
530
self.assertPathDoesNotExist('foo/foo')
533
class TestTestCaseWithMemoryTransport(tests.TestCaseWithMemoryTransport):
535
def test_home_is_non_existant_dir_under_root(self):
536
"""The test_home_dir for TestCaseWithMemoryTransport is missing.
538
This is because TestCaseWithMemoryTransport is for tests that do not
539
need any disk resources: they should be hooked into bzrlib in such a
540
way that no global settings are being changed by the test (only a
541
few tests should need to do that), and having a missing dir as home is
542
an effective way to ensure that this is the case.
544
self.assertIsSameRealPath(
545
self.TEST_ROOT + "/MemoryTransportMissingHomeDir",
547
self.assertIsSameRealPath(self.test_home_dir, os.environ['HOME'])
549
def test_cwd_is_TEST_ROOT(self):
550
self.assertIsSameRealPath(self.test_dir, self.TEST_ROOT)
551
cwd = osutils.getcwd()
552
self.assertIsSameRealPath(self.test_dir, cwd)
554
def test_BZR_HOME_and_HOME_are_bytestrings(self):
555
"""The $BZR_HOME and $HOME environment variables should not be unicode.
557
See https://bugs.launchpad.net/bzr/+bug/464174
559
self.assertIsInstance(os.environ['BZR_HOME'], str)
560
self.assertIsInstance(os.environ['HOME'], str)
562
def test_make_branch_and_memory_tree(self):
563
"""In TestCaseWithMemoryTransport we should not make the branch on disk.
565
This is hard to comprehensively robustly test, so we settle for making
566
a branch and checking no directory was created at its relpath.
568
tree = self.make_branch_and_memory_tree('dir')
569
# Guard against regression into MemoryTransport leaking
570
# files to disk instead of keeping them in memory.
571
self.assertFalse(osutils.lexists('dir'))
572
self.assertIsInstance(tree, memorytree.MemoryTree)
574
def test_make_branch_and_memory_tree_with_format(self):
575
"""make_branch_and_memory_tree should accept a format option."""
576
format = bzrdir.BzrDirMetaFormat1()
577
format.repository_format = repository.format_registry.get_default()
578
tree = self.make_branch_and_memory_tree('dir', format=format)
579
# Guard against regression into MemoryTransport leaking
580
# files to disk instead of keeping them in memory.
581
self.assertFalse(osutils.lexists('dir'))
582
self.assertIsInstance(tree, memorytree.MemoryTree)
583
self.assertEqual(format.repository_format.__class__,
584
tree.branch.repository._format.__class__)
586
def test_make_branch_builder(self):
587
builder = self.make_branch_builder('dir')
588
self.assertIsInstance(builder, branchbuilder.BranchBuilder)
589
# Guard against regression into MemoryTransport leaking
590
# files to disk instead of keeping them in memory.
591
self.assertFalse(osutils.lexists('dir'))
593
def test_make_branch_builder_with_format(self):
594
# Use a repo layout that doesn't conform to a 'named' layout, to ensure
595
# that the format objects are used.
596
format = bzrdir.BzrDirMetaFormat1()
597
repo_format = repository.format_registry.get_default()
598
format.repository_format = repo_format
599
builder = self.make_branch_builder('dir', format=format)
600
the_branch = builder.get_branch()
601
# Guard against regression into MemoryTransport leaking
602
# files to disk instead of keeping them in memory.
603
self.assertFalse(osutils.lexists('dir'))
604
self.assertEqual(format.repository_format.__class__,
605
the_branch.repository._format.__class__)
606
self.assertEqual(repo_format.get_format_string(),
607
self.get_transport().get_bytes(
608
'dir/.bzr/repository/format'))
610
def test_make_branch_builder_with_format_name(self):
611
builder = self.make_branch_builder('dir', format='knit')
612
the_branch = builder.get_branch()
613
# Guard against regression into MemoryTransport leaking
614
# files to disk instead of keeping them in memory.
615
self.assertFalse(osutils.lexists('dir'))
616
dir_format = bzrdir.format_registry.make_bzrdir('knit')
617
self.assertEqual(dir_format.repository_format.__class__,
618
the_branch.repository._format.__class__)
619
self.assertEqual('Bazaar-NG Knit Repository Format 1',
620
self.get_transport().get_bytes(
621
'dir/.bzr/repository/format'))
623
def test_dangling_locks_cause_failures(self):
624
class TestDanglingLock(tests.TestCaseWithMemoryTransport):
625
def test_function(self):
626
t = self.get_transport('.')
627
l = lockdir.LockDir(t, 'lock')
630
test = TestDanglingLock('test_function')
632
total_failures = result.errors + result.failures
633
if self._lock_check_thorough:
634
self.assertEqual(1, len(total_failures))
636
# When _lock_check_thorough is disabled, then we don't trigger a
638
self.assertEqual(0, len(total_failures))
641
class TestTestCaseWithTransport(tests.TestCaseWithTransport):
642
"""Tests for the convenience functions TestCaseWithTransport introduces."""
644
def test_get_readonly_url_none(self):
645
from bzrlib.transport.readonly import ReadonlyTransportDecorator
646
self.vfs_transport_factory = memory.MemoryServer
647
self.transport_readonly_server = None
648
# calling get_readonly_transport() constructs a decorator on the url
650
url = self.get_readonly_url()
651
url2 = self.get_readonly_url('foo/bar')
652
t = transport.get_transport(url)
653
t2 = transport.get_transport(url2)
654
self.assertIsInstance(t, ReadonlyTransportDecorator)
655
self.assertIsInstance(t2, ReadonlyTransportDecorator)
656
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
658
def test_get_readonly_url_http(self):
659
from bzrlib.tests.http_server import HttpServer
660
from bzrlib.transport.http import HttpTransportBase
661
self.transport_server = test_server.LocalURLServer
662
self.transport_readonly_server = HttpServer
663
# calling get_readonly_transport() gives us a HTTP server instance.
664
url = self.get_readonly_url()
665
url2 = self.get_readonly_url('foo/bar')
666
# the transport returned may be any HttpTransportBase subclass
667
t = transport.get_transport(url)
668
t2 = transport.get_transport(url2)
669
self.assertIsInstance(t, HttpTransportBase)
670
self.assertIsInstance(t2, HttpTransportBase)
671
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
673
def test_is_directory(self):
674
"""Test assertIsDirectory assertion"""
675
t = self.get_transport()
676
self.build_tree(['a_dir/', 'a_file'], transport=t)
677
self.assertIsDirectory('a_dir', t)
678
self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
679
self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
681
def test_make_branch_builder(self):
682
builder = self.make_branch_builder('dir')
683
rev_id = builder.build_commit()
684
self.assertPathExists('dir')
685
a_dir = bzrdir.BzrDir.open('dir')
686
self.assertRaises(errors.NoWorkingTree, a_dir.open_workingtree)
687
a_branch = a_dir.open_branch()
688
builder_branch = builder.get_branch()
689
self.assertEqual(a_branch.base, builder_branch.base)
690
self.assertEqual((1, rev_id), builder_branch.last_revision_info())
691
self.assertEqual((1, rev_id), a_branch.last_revision_info())
694
class TestTestCaseTransports(tests.TestCaseWithTransport):
697
super(TestTestCaseTransports, self).setUp()
698
self.vfs_transport_factory = memory.MemoryServer
700
def test_make_bzrdir_preserves_transport(self):
701
t = self.get_transport()
702
result_bzrdir = self.make_bzrdir('subdir')
703
self.assertIsInstance(result_bzrdir.transport,
704
memory.MemoryTransport)
705
# should not be on disk, should only be in memory
706
self.assertPathDoesNotExist('subdir')
709
class TestChrootedTest(tests.ChrootedTestCase):
711
def test_root_is_root(self):
712
t = transport.get_transport(self.get_readonly_url())
714
self.assertEqual(url, t.clone('..').base)
717
class TestProfileResult(tests.TestCase):
719
def test_profiles_tests(self):
720
self.requireFeature(test_lsprof.LSProfFeature)
721
terminal = testtools.tests.helpers.ExtendedTestResult()
722
result = tests.ProfileResult(terminal)
723
class Sample(tests.TestCase):
725
self.sample_function()
726
def sample_function(self):
730
case = terminal._events[0][1]
731
self.assertLength(1, case._benchcalls)
732
# We must be able to unpack it as the test reporting code wants
733
(_, _, _), stats = case._benchcalls[0]
734
self.assertTrue(callable(stats.pprint))
737
class TestTestResult(tests.TestCase):
739
def check_timing(self, test_case, expected_re):
740
result = bzrlib.tests.TextTestResult(self._log_file,
744
capture = testtools.tests.helpers.ExtendedTestResult()
745
test_case.run(MultiTestResult(result, capture))
746
run_case = capture._events[0][1]
747
timed_string = result._testTimeString(run_case)
748
self.assertContainsRe(timed_string, expected_re)
750
def test_test_reporting(self):
751
class ShortDelayTestCase(tests.TestCase):
752
def test_short_delay(self):
754
def test_short_benchmark(self):
755
self.time(time.sleep, 0.003)
756
self.check_timing(ShortDelayTestCase('test_short_delay'),
758
# if a benchmark time is given, we now show just that time followed by
760
self.check_timing(ShortDelayTestCase('test_short_benchmark'),
763
def test_unittest_reporting_unittest_class(self):
764
# getting the time from a non-bzrlib test works ok
765
class ShortDelayTestCase(unittest.TestCase):
766
def test_short_delay(self):
768
self.check_timing(ShortDelayTestCase('test_short_delay'),
771
def _time_hello_world_encoding(self):
772
"""Profile two sleep calls
774
This is used to exercise the test framework.
776
self.time(unicode, 'hello', errors='replace')
777
self.time(unicode, 'world', errors='replace')
779
def test_lsprofiling(self):
780
"""Verbose test result prints lsprof statistics from test cases."""
781
self.requireFeature(test_lsprof.LSProfFeature)
782
result_stream = StringIO()
783
result = bzrlib.tests.VerboseTestResult(
788
# we want profile a call of some sort and check it is output by
789
# addSuccess. We dont care about addError or addFailure as they
790
# are not that interesting for performance tuning.
791
# make a new test instance that when run will generate a profile
792
example_test_case = TestTestResult("_time_hello_world_encoding")
793
example_test_case._gather_lsprof_in_benchmarks = True
794
# execute the test, which should succeed and record profiles
795
example_test_case.run(result)
796
# lsprofile_something()
797
# if this worked we want
798
# LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
799
# CallCount Recursive Total(ms) Inline(ms) module:lineno(function)
800
# (the lsprof header)
801
# ... an arbitrary number of lines
802
# and the function call which is time.sleep.
803
# 1 0 ??? ??? ???(sleep)
804
# and then repeated but with 'world', rather than 'hello'.
805
# this should appear in the output stream of our test result.
806
output = result_stream.getvalue()
807
self.assertContainsRe(output,
808
r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
809
self.assertContainsRe(output,
810
r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
811
self.assertContainsRe(output,
812
r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
813
self.assertContainsRe(output,
814
r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
816
def test_uses_time_from_testtools(self):
817
"""Test case timings in verbose results should use testtools times"""
819
class TimeAddedVerboseTestResult(tests.VerboseTestResult):
820
def startTest(self, test):
821
self.time(datetime.datetime.utcfromtimestamp(1.145))
822
super(TimeAddedVerboseTestResult, self).startTest(test)
823
def addSuccess(self, test):
824
self.time(datetime.datetime.utcfromtimestamp(51.147))
825
super(TimeAddedVerboseTestResult, self).addSuccess(test)
826
def report_tests_starting(self): pass
828
self.get_passing_test().run(TimeAddedVerboseTestResult(sio, 0, 2))
829
self.assertEndsWith(sio.getvalue(), "OK 50002ms\n")
831
def test_known_failure(self):
832
"""A KnownFailure being raised should trigger several result actions."""
833
class InstrumentedTestResult(tests.ExtendedTestResult):
834
def stopTestRun(self): pass
835
def report_tests_starting(self): pass
836
def report_known_failure(self, test, err=None, details=None):
837
self._call = test, 'known failure'
838
result = InstrumentedTestResult(None, None, None, None)
839
class Test(tests.TestCase):
840
def test_function(self):
841
raise tests.KnownFailure('failed!')
842
test = Test("test_function")
844
# it should invoke 'report_known_failure'.
845
self.assertEqual(2, len(result._call))
846
self.assertEqual(test.id(), result._call[0].id())
847
self.assertEqual('known failure', result._call[1])
848
# we dont introspec the traceback, if the rest is ok, it would be
849
# exceptional for it not to be.
850
# it should update the known_failure_count on the object.
851
self.assertEqual(1, result.known_failure_count)
852
# the result should be successful.
853
self.assertTrue(result.wasSuccessful())
855
def test_verbose_report_known_failure(self):
856
# verbose test output formatting
857
result_stream = StringIO()
858
result = bzrlib.tests.VerboseTestResult(
863
test = self.get_passing_test()
864
result.startTest(test)
865
prefix = len(result_stream.getvalue())
866
# the err parameter has the shape:
867
# (class, exception object, traceback)
868
# KnownFailures dont get their tracebacks shown though, so we
870
err = (tests.KnownFailure, tests.KnownFailure('foo'), None)
871
result.report_known_failure(test, err)
872
output = result_stream.getvalue()[prefix:]
873
lines = output.splitlines()
874
self.assertContainsRe(lines[0], r'XFAIL *\d+ms$')
875
if sys.version_info > (2, 7):
876
self.expectFailure("_ExpectedFailure on 2.7 loses the message",
877
self.assertNotEqual, lines[1], ' ')
878
self.assertEqual(lines[1], ' foo')
879
self.assertEqual(2, len(lines))
881
def get_passing_test(self):
882
"""Return a test object that can't be run usefully."""
885
return unittest.FunctionTestCase(passing_test)
887
def test_add_not_supported(self):
888
"""Test the behaviour of invoking addNotSupported."""
889
class InstrumentedTestResult(tests.ExtendedTestResult):
890
def stopTestRun(self): pass
891
def report_tests_starting(self): pass
892
def report_unsupported(self, test, feature):
893
self._call = test, feature
894
result = InstrumentedTestResult(None, None, None, None)
895
test = SampleTestCase('_test_pass')
896
feature = tests.Feature()
897
result.startTest(test)
898
result.addNotSupported(test, feature)
899
# it should invoke 'report_unsupported'.
900
self.assertEqual(2, len(result._call))
901
self.assertEqual(test, result._call[0])
902
self.assertEqual(feature, result._call[1])
903
# the result should be successful.
904
self.assertTrue(result.wasSuccessful())
905
# it should record the test against a count of tests not run due to
907
self.assertEqual(1, result.unsupported['Feature'])
908
# and invoking it again should increment that counter
909
result.addNotSupported(test, feature)
910
self.assertEqual(2, result.unsupported['Feature'])
912
def test_verbose_report_unsupported(self):
913
# verbose test output formatting
914
result_stream = StringIO()
915
result = bzrlib.tests.VerboseTestResult(
920
test = self.get_passing_test()
921
feature = tests.Feature()
922
result.startTest(test)
923
prefix = len(result_stream.getvalue())
924
result.report_unsupported(test, feature)
925
output = result_stream.getvalue()[prefix:]
926
lines = output.splitlines()
927
# We don't check for the final '0ms' since it may fail on slow hosts
928
self.assertStartsWith(lines[0], 'NODEP')
929
self.assertEqual(lines[1],
930
" The feature 'Feature' is not available.")
932
def test_unavailable_exception(self):
933
"""An UnavailableFeature being raised should invoke addNotSupported."""
934
class InstrumentedTestResult(tests.ExtendedTestResult):
935
def stopTestRun(self): pass
936
def report_tests_starting(self): pass
937
def addNotSupported(self, test, feature):
938
self._call = test, feature
939
result = InstrumentedTestResult(None, None, None, None)
940
feature = tests.Feature()
941
class Test(tests.TestCase):
942
def test_function(self):
943
raise tests.UnavailableFeature(feature)
944
test = Test("test_function")
946
# it should invoke 'addNotSupported'.
947
self.assertEqual(2, len(result._call))
948
self.assertEqual(test.id(), result._call[0].id())
949
self.assertEqual(feature, result._call[1])
950
# and not count as an error
951
self.assertEqual(0, result.error_count)
953
def test_strict_with_unsupported_feature(self):
954
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
956
test = self.get_passing_test()
957
feature = "Unsupported Feature"
958
result.addNotSupported(test, feature)
959
self.assertFalse(result.wasStrictlySuccessful())
960
self.assertEqual(None, result._extractBenchmarkTime(test))
962
def test_strict_with_known_failure(self):
963
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
965
test = self.get_passing_test()
966
err = (tests.KnownFailure, tests.KnownFailure('foo'), None)
967
result.addExpectedFailure(test, err)
968
self.assertFalse(result.wasStrictlySuccessful())
969
self.assertEqual(None, result._extractBenchmarkTime(test))
971
def test_strict_with_success(self):
972
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
974
test = self.get_passing_test()
975
result.addSuccess(test)
976
self.assertTrue(result.wasStrictlySuccessful())
977
self.assertEqual(None, result._extractBenchmarkTime(test))
979
def test_startTests(self):
980
"""Starting the first test should trigger startTests."""
981
class InstrumentedTestResult(tests.ExtendedTestResult):
983
def startTests(self): self.calls += 1
984
result = InstrumentedTestResult(None, None, None, None)
987
test = unittest.FunctionTestCase(test_function)
989
self.assertEquals(1, result.calls)
991
def test_startTests_only_once(self):
992
"""With multiple tests startTests should still only be called once"""
993
class InstrumentedTestResult(tests.ExtendedTestResult):
995
def startTests(self): self.calls += 1
996
result = InstrumentedTestResult(None, None, None, None)
997
suite = unittest.TestSuite([
998
unittest.FunctionTestCase(lambda: None),
999
unittest.FunctionTestCase(lambda: None)])
1001
self.assertEquals(1, result.calls)
1002
self.assertEquals(2, result.count)
1005
class TestUnicodeFilenameFeature(tests.TestCase):
1007
def test_probe_passes(self):
1008
"""UnicodeFilenameFeature._probe passes."""
1009
# We can't test much more than that because the behaviour depends
1011
tests.UnicodeFilenameFeature._probe()
1014
class TestRunner(tests.TestCase):
1016
def dummy_test(self):
1019
def run_test_runner(self, testrunner, test):
1020
"""Run suite in testrunner, saving global state and restoring it.
1022
This current saves and restores:
1023
TestCaseInTempDir.TEST_ROOT
1025
There should be no tests in this file that use
1026
bzrlib.tests.TextTestRunner without using this convenience method,
1027
because of our use of global state.
1029
old_root = tests.TestCaseInTempDir.TEST_ROOT
1031
tests.TestCaseInTempDir.TEST_ROOT = None
1032
return testrunner.run(test)
1034
tests.TestCaseInTempDir.TEST_ROOT = old_root
1036
def test_known_failure_failed_run(self):
1037
# run a test that generates a known failure which should be printed in
1038
# the final output when real failures occur.
1039
class Test(tests.TestCase):
1040
def known_failure_test(self):
1041
self.expectFailure('failed', self.assertTrue, False)
1042
test = unittest.TestSuite()
1043
test.addTest(Test("known_failure_test"))
1046
test.addTest(unittest.FunctionTestCase(failing_test))
1048
runner = tests.TextTestRunner(stream=stream)
1049
result = self.run_test_runner(runner, test)
1050
lines = stream.getvalue().splitlines()
1051
self.assertContainsRe(stream.getvalue(),
1052
'(?sm)^bzr selftest.*$'
1054
'^======================================================================\n'
1055
'^FAIL: failing_test\n'
1056
'^----------------------------------------------------------------------\n'
1057
'Traceback \\(most recent call last\\):\n'
1058
' .*' # File .*, line .*, in failing_test' - but maybe not from .pyc
1059
' self.fail\\(\'foo\'\\)\n'
1061
'^----------------------------------------------------------------------\n'
1063
'FAILED \\(failures=1, known_failure_count=1\\)'
1066
def test_known_failure_ok_run(self):
1067
# run a test that generates a known failure which should be printed in
1069
class Test(tests.TestCase):
1070
def known_failure_test(self):
1071
self.expectFailure('failed', self.assertTrue, False)
1072
test = Test("known_failure_test")
1074
runner = tests.TextTestRunner(stream=stream)
1075
result = self.run_test_runner(runner, test)
1076
self.assertContainsRe(stream.getvalue(),
1079
'Ran 1 test in .*\n'
1081
'OK \\(known_failures=1\\)\n')
1083
def test_result_decorator(self):
1086
class LoggingDecorator(ExtendedToOriginalDecorator):
1087
def startTest(self, test):
1088
ExtendedToOriginalDecorator.startTest(self, test)
1089
calls.append('start')
1090
test = unittest.FunctionTestCase(lambda:None)
1092
runner = tests.TextTestRunner(stream=stream,
1093
result_decorators=[LoggingDecorator])
1094
result = self.run_test_runner(runner, test)
1095
self.assertLength(1, calls)
1097
def test_skipped_test(self):
1098
# run a test that is skipped, and check the suite as a whole still
1100
# skipping_test must be hidden in here so it's not run as a real test
1101
class SkippingTest(tests.TestCase):
1102
def skipping_test(self):
1103
raise tests.TestSkipped('test intentionally skipped')
1104
runner = tests.TextTestRunner(stream=self._log_file)
1105
test = SkippingTest("skipping_test")
1106
result = self.run_test_runner(runner, test)
1107
self.assertTrue(result.wasSuccessful())
1109
def test_skipped_from_setup(self):
1111
class SkippedSetupTest(tests.TestCase):
1114
calls.append('setUp')
1115
self.addCleanup(self.cleanup)
1116
raise tests.TestSkipped('skipped setup')
1118
def test_skip(self):
1119
self.fail('test reached')
1122
calls.append('cleanup')
1124
runner = tests.TextTestRunner(stream=self._log_file)
1125
test = SkippedSetupTest('test_skip')
1126
result = self.run_test_runner(runner, test)
1127
self.assertTrue(result.wasSuccessful())
1128
# Check if cleanup was called the right number of times.
1129
self.assertEqual(['setUp', 'cleanup'], calls)
1131
def test_skipped_from_test(self):
1133
class SkippedTest(tests.TestCase):
1136
tests.TestCase.setUp(self)
1137
calls.append('setUp')
1138
self.addCleanup(self.cleanup)
1140
def test_skip(self):
1141
raise tests.TestSkipped('skipped test')
1144
calls.append('cleanup')
1146
runner = tests.TextTestRunner(stream=self._log_file)
1147
test = SkippedTest('test_skip')
1148
result = self.run_test_runner(runner, test)
1149
self.assertTrue(result.wasSuccessful())
1150
# Check if cleanup was called the right number of times.
1151
self.assertEqual(['setUp', 'cleanup'], calls)
1153
def test_not_applicable(self):
1154
# run a test that is skipped because it's not applicable
1155
class Test(tests.TestCase):
1156
def not_applicable_test(self):
1157
raise tests.TestNotApplicable('this test never runs')
1159
runner = tests.TextTestRunner(stream=out, verbosity=2)
1160
test = Test("not_applicable_test")
1161
result = self.run_test_runner(runner, test)
1162
self._log_file.write(out.getvalue())
1163
self.assertTrue(result.wasSuccessful())
1164
self.assertTrue(result.wasStrictlySuccessful())
1165
self.assertContainsRe(out.getvalue(),
1166
r'(?m)not_applicable_test * N/A')
1167
self.assertContainsRe(out.getvalue(),
1168
r'(?m)^ this test never runs')
1170
def test_unsupported_features_listed(self):
1171
"""When unsupported features are encountered they are detailed."""
1172
class Feature1(tests.Feature):
1173
def _probe(self): return False
1174
class Feature2(tests.Feature):
1175
def _probe(self): return False
1176
# create sample tests
1177
test1 = SampleTestCase('_test_pass')
1178
test1._test_needs_features = [Feature1()]
1179
test2 = SampleTestCase('_test_pass')
1180
test2._test_needs_features = [Feature2()]
1181
test = unittest.TestSuite()
1185
runner = tests.TextTestRunner(stream=stream)
1186
result = self.run_test_runner(runner, test)
1187
lines = stream.getvalue().splitlines()
1190
"Missing feature 'Feature1' skipped 1 tests.",
1191
"Missing feature 'Feature2' skipped 1 tests.",
1195
def test_verbose_test_count(self):
1196
"""A verbose test run reports the right test count at the start"""
1197
suite = TestUtil.TestSuite([
1198
unittest.FunctionTestCase(lambda:None),
1199
unittest.FunctionTestCase(lambda:None)])
1200
self.assertEqual(suite.countTestCases(), 2)
1202
runner = tests.TextTestRunner(stream=stream, verbosity=2)
1203
# Need to use the CountingDecorator as that's what sets num_tests
1204
result = self.run_test_runner(runner, tests.CountingDecorator(suite))
1205
self.assertStartsWith(stream.getvalue(), "running 2 tests")
1207
def test_startTestRun(self):
1208
"""run should call result.startTestRun()"""
1210
class LoggingDecorator(ExtendedToOriginalDecorator):
1211
def startTestRun(self):
1212
ExtendedToOriginalDecorator.startTestRun(self)
1213
calls.append('startTestRun')
1214
test = unittest.FunctionTestCase(lambda:None)
1216
runner = tests.TextTestRunner(stream=stream,
1217
result_decorators=[LoggingDecorator])
1218
result = self.run_test_runner(runner, test)
1219
self.assertLength(1, calls)
1221
def test_stopTestRun(self):
1222
"""run should call result.stopTestRun()"""
1224
class LoggingDecorator(ExtendedToOriginalDecorator):
1225
def stopTestRun(self):
1226
ExtendedToOriginalDecorator.stopTestRun(self)
1227
calls.append('stopTestRun')
1228
test = unittest.FunctionTestCase(lambda:None)
1230
runner = tests.TextTestRunner(stream=stream,
1231
result_decorators=[LoggingDecorator])
1232
result = self.run_test_runner(runner, test)
1233
self.assertLength(1, calls)
1235
def test_unicode_test_output_on_ascii_stream(self):
1236
"""Showing results should always succeed even on an ascii console"""
1237
class FailureWithUnicode(tests.TestCase):
1238
def test_log_unicode(self):
1240
self.fail("Now print that log!")
1242
self.overrideAttr(osutils, "get_terminal_encoding",
1243
lambda trace=False: "ascii")
1244
result = self.run_test_runner(tests.TextTestRunner(stream=out),
1245
FailureWithUnicode("test_log_unicode"))
1246
self.assertContainsRe(out.getvalue(),
1247
"Text attachment: log\n"
1249
"\d+\.\d+ \\\\u2606\n"
1253
class SampleTestCase(tests.TestCase):
1255
def _test_pass(self):
1258
class _TestException(Exception):
1262
class TestTestCase(tests.TestCase):
1263
"""Tests that test the core bzrlib TestCase."""
1265
def test_assertLength_matches_empty(self):
1267
self.assertLength(0, a_list)
1269
def test_assertLength_matches_nonempty(self):
1271
self.assertLength(3, a_list)
1273
def test_assertLength_fails_different(self):
1275
self.assertRaises(AssertionError, self.assertLength, 1, a_list)
1277
def test_assertLength_shows_sequence_in_failure(self):
1279
exception = self.assertRaises(AssertionError, self.assertLength, 2,
1281
self.assertEqual('Incorrect length: wanted 2, got 3 for [1, 2, 3]',
1284
def test_base_setUp_not_called_causes_failure(self):
1285
class TestCaseWithBrokenSetUp(tests.TestCase):
1287
pass # does not call TestCase.setUp
1290
test = TestCaseWithBrokenSetUp('test_foo')
1291
result = unittest.TestResult()
1293
self.assertFalse(result.wasSuccessful())
1294
self.assertEqual(1, result.testsRun)
1296
def test_base_tearDown_not_called_causes_failure(self):
1297
class TestCaseWithBrokenTearDown(tests.TestCase):
1299
pass # does not call TestCase.tearDown
1302
test = TestCaseWithBrokenTearDown('test_foo')
1303
result = unittest.TestResult()
1305
self.assertFalse(result.wasSuccessful())
1306
self.assertEqual(1, result.testsRun)
1308
def test_debug_flags_sanitised(self):
1309
"""The bzrlib debug flags should be sanitised by setUp."""
1310
if 'allow_debug' in tests.selftest_debug_flags:
1311
raise tests.TestNotApplicable(
1312
'-Eallow_debug option prevents debug flag sanitisation')
1313
# we could set something and run a test that will check
1314
# it gets santised, but this is probably sufficient for now:
1315
# if someone runs the test with -Dsomething it will error.
1317
if self._lock_check_thorough:
1318
flags.add('strict_locks')
1319
self.assertEqual(flags, bzrlib.debug.debug_flags)
1321
def change_selftest_debug_flags(self, new_flags):
1322
self.overrideAttr(tests, 'selftest_debug_flags', set(new_flags))
1324
def test_allow_debug_flag(self):
1325
"""The -Eallow_debug flag prevents bzrlib.debug.debug_flags from being
1326
sanitised (i.e. cleared) before running a test.
1328
self.change_selftest_debug_flags(set(['allow_debug']))
1329
bzrlib.debug.debug_flags = set(['a-flag'])
1330
class TestThatRecordsFlags(tests.TestCase):
1331
def test_foo(nested_self):
1332
self.flags = set(bzrlib.debug.debug_flags)
1333
test = TestThatRecordsFlags('test_foo')
1334
test.run(self.make_test_result())
1335
flags = set(['a-flag'])
1336
if 'disable_lock_checks' not in tests.selftest_debug_flags:
1337
flags.add('strict_locks')
1338
self.assertEqual(flags, self.flags)
1340
def test_disable_lock_checks(self):
1341
"""The -Edisable_lock_checks flag disables thorough checks."""
1342
class TestThatRecordsFlags(tests.TestCase):
1343
def test_foo(nested_self):
1344
self.flags = set(bzrlib.debug.debug_flags)
1345
self.test_lock_check_thorough = nested_self._lock_check_thorough
1346
self.change_selftest_debug_flags(set())
1347
test = TestThatRecordsFlags('test_foo')
1348
test.run(self.make_test_result())
1349
# By default we do strict lock checking and thorough lock/unlock
1351
self.assertTrue(self.test_lock_check_thorough)
1352
self.assertEqual(set(['strict_locks']), self.flags)
1353
# Now set the disable_lock_checks flag, and show that this changed.
1354
self.change_selftest_debug_flags(set(['disable_lock_checks']))
1355
test = TestThatRecordsFlags('test_foo')
1356
test.run(self.make_test_result())
1357
self.assertFalse(self.test_lock_check_thorough)
1358
self.assertEqual(set(), self.flags)
1360
def test_this_fails_strict_lock_check(self):
1361
class TestThatRecordsFlags(tests.TestCase):
1362
def test_foo(nested_self):
1363
self.flags1 = set(bzrlib.debug.debug_flags)
1364
self.thisFailsStrictLockCheck()
1365
self.flags2 = set(bzrlib.debug.debug_flags)
1366
# Make sure lock checking is active
1367
self.change_selftest_debug_flags(set())
1368
test = TestThatRecordsFlags('test_foo')
1369
test.run(self.make_test_result())
1370
self.assertEqual(set(['strict_locks']), self.flags1)
1371
self.assertEqual(set(), self.flags2)
1373
def test_debug_flags_restored(self):
1374
"""The bzrlib debug flags should be restored to their original state
1375
after the test was run, even if allow_debug is set.
1377
self.change_selftest_debug_flags(set(['allow_debug']))
1378
# Now run a test that modifies debug.debug_flags.
1379
bzrlib.debug.debug_flags = set(['original-state'])
1380
class TestThatModifiesFlags(tests.TestCase):
1382
bzrlib.debug.debug_flags = set(['modified'])
1383
test = TestThatModifiesFlags('test_foo')
1384
test.run(self.make_test_result())
1385
self.assertEqual(set(['original-state']), bzrlib.debug.debug_flags)
1387
def make_test_result(self):
1388
"""Get a test result that writes to the test log file."""
1389
return tests.TextTestResult(self._log_file, descriptions=0, verbosity=1)
1391
def inner_test(self):
1392
# the inner child test
1395
def outer_child(self):
1396
# the outer child test
1398
self.inner_test = TestTestCase("inner_child")
1399
result = self.make_test_result()
1400
self.inner_test.run(result)
1401
note("outer finish")
1402
self.addCleanup(osutils.delete_any, self._log_file_name)
1404
def test_trace_nesting(self):
1405
# this tests that each test case nests its trace facility correctly.
1406
# we do this by running a test case manually. That test case (A)
1407
# should setup a new log, log content to it, setup a child case (B),
1408
# which should log independently, then case (A) should log a trailer
1410
# we do two nested children so that we can verify the state of the
1411
# logs after the outer child finishes is correct, which a bad clean
1412
# up routine in tearDown might trigger a fault in our test with only
1413
# one child, we should instead see the bad result inside our test with
1415
# the outer child test
1416
original_trace = bzrlib.trace._trace_file
1417
outer_test = TestTestCase("outer_child")
1418
result = self.make_test_result()
1419
outer_test.run(result)
1420
self.assertEqual(original_trace, bzrlib.trace._trace_file)
1422
def method_that_times_a_bit_twice(self):
1423
# call self.time twice to ensure it aggregates
1424
self.time(time.sleep, 0.007)
1425
self.time(time.sleep, 0.007)
1427
def test_time_creates_benchmark_in_result(self):
1428
"""Test that the TestCase.time() method accumulates a benchmark time."""
1429
sample_test = TestTestCase("method_that_times_a_bit_twice")
1430
output_stream = StringIO()
1431
result = bzrlib.tests.VerboseTestResult(
1435
sample_test.run(result)
1436
self.assertContainsRe(
1437
output_stream.getvalue(),
1440
def test_hooks_sanitised(self):
1441
"""The bzrlib hooks should be sanitised by setUp."""
1442
# Note this test won't fail with hooks that the core library doesn't
1443
# use - but it trigger with a plugin that adds hooks, so its still a
1444
# useful warning in that case.
1445
self.assertEqual(bzrlib.branch.BranchHooks(), bzrlib.branch.Branch.hooks)
1447
bzrlib.smart.server.SmartServerHooks(),
1448
bzrlib.smart.server.SmartTCPServer.hooks)
1450
bzrlib.commands.CommandHooks(), bzrlib.commands.Command.hooks)
1452
def test__gather_lsprof_in_benchmarks(self):
1453
"""When _gather_lsprof_in_benchmarks is on, accumulate profile data.
1455
Each self.time() call is individually and separately profiled.
1457
self.requireFeature(test_lsprof.LSProfFeature)
1458
# overrides the class member with an instance member so no cleanup
1460
self._gather_lsprof_in_benchmarks = True
1461
self.time(time.sleep, 0.000)
1462
self.time(time.sleep, 0.003)
1463
self.assertEqual(2, len(self._benchcalls))
1464
self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
1465
self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
1466
self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
1467
self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
1468
del self._benchcalls[:]
1470
def test_knownFailure(self):
1471
"""Self.knownFailure() should raise a KnownFailure exception."""
1472
self.assertRaises(tests.KnownFailure, self.knownFailure, "A Failure")
1474
def test_open_bzrdir_safe_roots(self):
1475
# even a memory transport should fail to open when its url isn't
1477
# Manually set one up (TestCase doesn't and shouldn't provide magic
1479
transport_server = memory.MemoryServer()
1480
transport_server.start_server()
1481
self.addCleanup(transport_server.stop_server)
1482
t = transport.get_transport(transport_server.get_url())
1483
bzrdir.BzrDir.create(t.base)
1484
self.assertRaises(errors.BzrError,
1485
bzrdir.BzrDir.open_from_transport, t)
1486
# But if we declare this as safe, we can open the bzrdir.
1487
self.permit_url(t.base)
1488
self._bzr_selftest_roots.append(t.base)
1489
bzrdir.BzrDir.open_from_transport(t)
1491
def test_requireFeature_available(self):
1492
"""self.requireFeature(available) is a no-op."""
1493
class Available(tests.Feature):
1494
def _probe(self):return True
1495
feature = Available()
1496
self.requireFeature(feature)
1498
def test_requireFeature_unavailable(self):
1499
"""self.requireFeature(unavailable) raises UnavailableFeature."""
1500
class Unavailable(tests.Feature):
1501
def _probe(self):return False
1502
feature = Unavailable()
1503
self.assertRaises(tests.UnavailableFeature,
1504
self.requireFeature, feature)
1506
def test_run_no_parameters(self):
1507
test = SampleTestCase('_test_pass')
1510
def test_run_enabled_unittest_result(self):
1511
"""Test we revert to regular behaviour when the test is enabled."""
1512
test = SampleTestCase('_test_pass')
1513
class EnabledFeature(object):
1514
def available(self):
1516
test._test_needs_features = [EnabledFeature()]
1517
result = unittest.TestResult()
1519
self.assertEqual(1, result.testsRun)
1520
self.assertEqual([], result.errors)
1521
self.assertEqual([], result.failures)
1523
def test_run_disabled_unittest_result(self):
1524
"""Test our compatability for disabled tests with unittest results."""
1525
test = SampleTestCase('_test_pass')
1526
class DisabledFeature(object):
1527
def available(self):
1529
test._test_needs_features = [DisabledFeature()]
1530
result = unittest.TestResult()
1532
self.assertEqual(1, result.testsRun)
1533
self.assertEqual([], result.errors)
1534
self.assertEqual([], result.failures)
1536
def test_run_disabled_supporting_result(self):
1537
"""Test disabled tests behaviour with support aware results."""
1538
test = SampleTestCase('_test_pass')
1539
class DisabledFeature(object):
1540
def __eq__(self, other):
1541
return isinstance(other, DisabledFeature)
1542
def available(self):
1544
the_feature = DisabledFeature()
1545
test._test_needs_features = [the_feature]
1546
class InstrumentedTestResult(unittest.TestResult):
1548
unittest.TestResult.__init__(self)
1550
def startTest(self, test):
1551
self.calls.append(('startTest', test))
1552
def stopTest(self, test):
1553
self.calls.append(('stopTest', test))
1554
def addNotSupported(self, test, feature):
1555
self.calls.append(('addNotSupported', test, feature))
1556
result = InstrumentedTestResult()
1558
case = result.calls[0][1]
1560
('startTest', case),
1561
('addNotSupported', case, the_feature),
1566
def test_start_server_registers_url(self):
1567
transport_server = memory.MemoryServer()
1568
# A little strict, but unlikely to be changed soon.
1569
self.assertEqual([], self._bzr_selftest_roots)
1570
self.start_server(transport_server)
1571
self.assertSubset([transport_server.get_url()],
1572
self._bzr_selftest_roots)
1574
def test_assert_list_raises_on_generator(self):
1575
def generator_which_will_raise():
1576
# This will not raise until after the first yield
1578
raise _TestException()
1580
e = self.assertListRaises(_TestException, generator_which_will_raise)
1581
self.assertIsInstance(e, _TestException)
1583
e = self.assertListRaises(Exception, generator_which_will_raise)
1584
self.assertIsInstance(e, _TestException)
1586
def test_assert_list_raises_on_plain(self):
1587
def plain_exception():
1588
raise _TestException()
1591
e = self.assertListRaises(_TestException, plain_exception)
1592
self.assertIsInstance(e, _TestException)
1594
e = self.assertListRaises(Exception, plain_exception)
1595
self.assertIsInstance(e, _TestException)
1597
def test_assert_list_raises_assert_wrong_exception(self):
1598
class _NotTestException(Exception):
1601
def wrong_exception():
1602
raise _NotTestException()
1604
def wrong_exception_generator():
1607
raise _NotTestException()
1609
# Wrong exceptions are not intercepted
1610
self.assertRaises(_NotTestException,
1611
self.assertListRaises, _TestException, wrong_exception)
1612
self.assertRaises(_NotTestException,
1613
self.assertListRaises, _TestException, wrong_exception_generator)
1615
def test_assert_list_raises_no_exception(self):
1619
def success_generator():
1623
self.assertRaises(AssertionError,
1624
self.assertListRaises, _TestException, success)
1626
self.assertRaises(AssertionError,
1627
self.assertListRaises, _TestException, success_generator)
1629
def test_overrideAttr_without_value(self):
1630
self.test_attr = 'original' # Define a test attribute
1631
obj = self # Make 'obj' visible to the embedded test
1632
class Test(tests.TestCase):
1635
tests.TestCase.setUp(self)
1636
self.orig = self.overrideAttr(obj, 'test_attr')
1638
def test_value(self):
1639
self.assertEqual('original', self.orig)
1640
self.assertEqual('original', obj.test_attr)
1641
obj.test_attr = 'modified'
1642
self.assertEqual('modified', obj.test_attr)
1644
test = Test('test_value')
1645
test.run(unittest.TestResult())
1646
self.assertEqual('original', obj.test_attr)
1648
def test_overrideAttr_with_value(self):
1649
self.test_attr = 'original' # Define a test attribute
1650
obj = self # Make 'obj' visible to the embedded test
1651
class Test(tests.TestCase):
1654
tests.TestCase.setUp(self)
1655
self.orig = self.overrideAttr(obj, 'test_attr', new='modified')
1657
def test_value(self):
1658
self.assertEqual('original', self.orig)
1659
self.assertEqual('modified', obj.test_attr)
1661
test = Test('test_value')
1662
test.run(unittest.TestResult())
1663
self.assertEqual('original', obj.test_attr)
1666
class _MissingFeature(tests.Feature):
1669
missing_feature = _MissingFeature()
1672
def _get_test(name):
1673
"""Get an instance of a specific example test.
1675
We protect this in a function so that they don't auto-run in the test
1679
class ExampleTests(tests.TestCase):
1681
def test_fail(self):
1682
mutter('this was a failing test')
1683
self.fail('this test will fail')
1685
def test_error(self):
1686
mutter('this test errored')
1687
raise RuntimeError('gotcha')
1689
def test_missing_feature(self):
1690
mutter('missing the feature')
1691
self.requireFeature(missing_feature)
1693
def test_skip(self):
1694
mutter('this test will be skipped')
1695
raise tests.TestSkipped('reason')
1697
def test_success(self):
1698
mutter('this test succeeds')
1700
def test_xfail(self):
1701
mutter('test with expected failure')
1702
self.knownFailure('this_fails')
1704
def test_unexpected_success(self):
1705
mutter('test with unexpected success')
1706
self.expectFailure('should_fail', lambda: None)
1708
return ExampleTests(name)
1711
class TestTestCaseLogDetails(tests.TestCase):
1713
def _run_test(self, test_name):
1714
test = _get_test(test_name)
1715
result = testtools.TestResult()
1719
def test_fail_has_log(self):
1720
result = self._run_test('test_fail')
1721
self.assertEqual(1, len(result.failures))
1722
result_content = result.failures[0][1]
1723
self.assertContainsRe(result_content, 'Text attachment: log')
1724
self.assertContainsRe(result_content, 'this was a failing test')
1726
def test_error_has_log(self):
1727
result = self._run_test('test_error')
1728
self.assertEqual(1, len(result.errors))
1729
result_content = result.errors[0][1]
1730
self.assertContainsRe(result_content, 'Text attachment: log')
1731
self.assertContainsRe(result_content, 'this test errored')
1733
def test_skip_has_no_log(self):
1734
result = self._run_test('test_skip')
1735
self.assertEqual(['reason'], result.skip_reasons.keys())
1736
skips = result.skip_reasons['reason']
1737
self.assertEqual(1, len(skips))
1739
self.assertFalse('log' in test.getDetails())
1741
def test_missing_feature_has_no_log(self):
1742
# testtools doesn't know about addNotSupported, so it just gets
1743
# considered as a skip
1744
result = self._run_test('test_missing_feature')
1745
self.assertEqual([missing_feature], result.skip_reasons.keys())
1746
skips = result.skip_reasons[missing_feature]
1747
self.assertEqual(1, len(skips))
1749
self.assertFalse('log' in test.getDetails())
1751
def test_xfail_has_no_log(self):
1752
result = self._run_test('test_xfail')
1753
self.assertEqual(1, len(result.expectedFailures))
1754
result_content = result.expectedFailures[0][1]
1755
self.assertNotContainsRe(result_content, 'Text attachment: log')
1756
self.assertNotContainsRe(result_content, 'test with expected failure')
1758
def test_unexpected_success_has_log(self):
1759
result = self._run_test('test_unexpected_success')
1760
self.assertEqual(1, len(result.unexpectedSuccesses))
1761
# Inconsistency, unexpectedSuccesses is a list of tests,
1762
# expectedFailures is a list of reasons?
1763
test = result.unexpectedSuccesses[0]
1764
details = test.getDetails()
1765
self.assertTrue('log' in details)
1768
class TestTestCloning(tests.TestCase):
1769
"""Tests that test cloning of TestCases (as used by multiply_tests)."""
1771
def test_cloned_testcase_does_not_share_details(self):
1772
"""A TestCase cloned with clone_test does not share mutable attributes
1773
such as details or cleanups.
1775
class Test(tests.TestCase):
1777
self.addDetail('foo', Content('text/plain', lambda: 'foo'))
1778
orig_test = Test('test_foo')
1779
cloned_test = tests.clone_test(orig_test, orig_test.id() + '(cloned)')
1780
orig_test.run(unittest.TestResult())
1781
self.assertEqual('foo', orig_test.getDetails()['foo'].iter_bytes())
1782
self.assertEqual(None, cloned_test.getDetails().get('foo'))
1784
def test_double_apply_scenario_preserves_first_scenario(self):
1785
"""Applying two levels of scenarios to a test preserves the attributes
1786
added by both scenarios.
1788
class Test(tests.TestCase):
1791
test = Test('test_foo')
1792
scenarios_x = [('x=1', {'x': 1}), ('x=2', {'x': 2})]
1793
scenarios_y = [('y=1', {'y': 1}), ('y=2', {'y': 2})]
1794
suite = tests.multiply_tests(test, scenarios_x, unittest.TestSuite())
1795
suite = tests.multiply_tests(suite, scenarios_y, unittest.TestSuite())
1796
all_tests = list(tests.iter_suite_tests(suite))
1797
self.assertLength(4, all_tests)
1798
all_xys = sorted((t.x, t.y) for t in all_tests)
1799
self.assertEqual([(1, 1), (1, 2), (2, 1), (2, 2)], all_xys)
1802
# NB: Don't delete this; it's not actually from 0.11!
1803
@deprecated_function(deprecated_in((0, 11, 0)))
1804
def sample_deprecated_function():
1805
"""A deprecated function to test applyDeprecated with."""
1809
def sample_undeprecated_function(a_param):
1810
"""A undeprecated function to test applyDeprecated with."""
1813
class ApplyDeprecatedHelper(object):
1814
"""A helper class for ApplyDeprecated tests."""
1816
@deprecated_method(deprecated_in((0, 11, 0)))
1817
def sample_deprecated_method(self, param_one):
1818
"""A deprecated method for testing with."""
1821
def sample_normal_method(self):
1822
"""A undeprecated method."""
1824
@deprecated_method(deprecated_in((0, 10, 0)))
1825
def sample_nested_deprecation(self):
1826
return sample_deprecated_function()
1829
class TestExtraAssertions(tests.TestCase):
1830
"""Tests for new test assertions in bzrlib test suite"""
1832
def test_assert_isinstance(self):
1833
self.assertIsInstance(2, int)
1834
self.assertIsInstance(u'', basestring)
1835
e = self.assertRaises(AssertionError, self.assertIsInstance, None, int)
1836
self.assertEquals(str(e),
1837
"None is an instance of <type 'NoneType'> rather than <type 'int'>")
1838
self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
1839
e = self.assertRaises(AssertionError,
1840
self.assertIsInstance, None, int, "it's just not")
1841
self.assertEquals(str(e),
1842
"None is an instance of <type 'NoneType'> rather than <type 'int'>"
1845
def test_assertEndsWith(self):
1846
self.assertEndsWith('foo', 'oo')
1847
self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
1849
def test_assertEqualDiff(self):
1850
e = self.assertRaises(AssertionError,
1851
self.assertEqualDiff, '', '\n')
1852
self.assertEquals(str(e),
1853
# Don't blink ! The '+' applies to the second string
1854
'first string is missing a final newline.\n+ \n')
1855
e = self.assertRaises(AssertionError,
1856
self.assertEqualDiff, '\n', '')
1857
self.assertEquals(str(e),
1858
# Don't blink ! The '-' applies to the second string
1859
'second string is missing a final newline.\n- \n')
1862
class TestDeprecations(tests.TestCase):
1864
def test_applyDeprecated_not_deprecated(self):
1865
sample_object = ApplyDeprecatedHelper()
1866
# calling an undeprecated callable raises an assertion
1867
self.assertRaises(AssertionError, self.applyDeprecated,
1868
deprecated_in((0, 11, 0)),
1869
sample_object.sample_normal_method)
1870
self.assertRaises(AssertionError, self.applyDeprecated,
1871
deprecated_in((0, 11, 0)),
1872
sample_undeprecated_function, "a param value")
1873
# calling a deprecated callable (function or method) with the wrong
1874
# expected deprecation fails.
1875
self.assertRaises(AssertionError, self.applyDeprecated,
1876
deprecated_in((0, 10, 0)),
1877
sample_object.sample_deprecated_method, "a param value")
1878
self.assertRaises(AssertionError, self.applyDeprecated,
1879
deprecated_in((0, 10, 0)),
1880
sample_deprecated_function)
1881
# calling a deprecated callable (function or method) with the right
1882
# expected deprecation returns the functions result.
1883
self.assertEqual("a param value",
1884
self.applyDeprecated(deprecated_in((0, 11, 0)),
1885
sample_object.sample_deprecated_method, "a param value"))
1886
self.assertEqual(2, self.applyDeprecated(deprecated_in((0, 11, 0)),
1887
sample_deprecated_function))
1888
# calling a nested deprecation with the wrong deprecation version
1889
# fails even if a deeper nested function was deprecated with the
1891
self.assertRaises(AssertionError, self.applyDeprecated,
1892
deprecated_in((0, 11, 0)), sample_object.sample_nested_deprecation)
1893
# calling a nested deprecation with the right deprecation value
1894
# returns the calls result.
1895
self.assertEqual(2, self.applyDeprecated(deprecated_in((0, 10, 0)),
1896
sample_object.sample_nested_deprecation))
1898
def test_callDeprecated(self):
1899
def testfunc(be_deprecated, result=None):
1900
if be_deprecated is True:
1901
symbol_versioning.warn('i am deprecated', DeprecationWarning,
1904
result = self.callDeprecated(['i am deprecated'], testfunc, True)
1905
self.assertIs(None, result)
1906
result = self.callDeprecated([], testfunc, False, 'result')
1907
self.assertEqual('result', result)
1908
self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
1909
self.callDeprecated([], testfunc, be_deprecated=False)
1912
class TestWarningTests(tests.TestCase):
1913
"""Tests for calling methods that raise warnings."""
1915
def test_callCatchWarnings(self):
1917
warnings.warn("this is your last warning")
1919
wlist, result = self.callCatchWarnings(meth, 1, 2)
1920
self.assertEquals(3, result)
1921
# would like just to compare them, but UserWarning doesn't implement
1924
self.assertIsInstance(w0, UserWarning)
1925
self.assertEquals("this is your last warning", str(w0))
1928
class TestConvenienceMakers(tests.TestCaseWithTransport):
1929
"""Test for the make_* convenience functions."""
1931
def test_make_branch_and_tree_with_format(self):
1932
# we should be able to supply a format to make_branch_and_tree
1933
self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
1934
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
1935
bzrlib.bzrdir.BzrDirMetaFormat1)
1937
def test_make_branch_and_memory_tree(self):
1938
# we should be able to get a new branch and a mutable tree from
1939
# TestCaseWithTransport
1940
tree = self.make_branch_and_memory_tree('a')
1941
self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
1943
def test_make_tree_for_local_vfs_backed_transport(self):
1944
# make_branch_and_tree has to use local branch and repositories
1945
# when the vfs transport and local disk are colocated, even if
1946
# a different transport is in use for url generation.
1947
self.transport_server = test_server.FakeVFATServer
1948
self.assertFalse(self.get_url('t1').startswith('file://'))
1949
tree = self.make_branch_and_tree('t1')
1950
base = tree.bzrdir.root_transport.base
1951
self.assertStartsWith(base, 'file://')
1952
self.assertEquals(tree.bzrdir.root_transport,
1953
tree.branch.bzrdir.root_transport)
1954
self.assertEquals(tree.bzrdir.root_transport,
1955
tree.branch.repository.bzrdir.root_transport)
1958
class SelfTestHelper(object):
1960
def run_selftest(self, **kwargs):
1961
"""Run selftest returning its output."""
1963
old_transport = bzrlib.tests.default_transport
1964
old_root = tests.TestCaseWithMemoryTransport.TEST_ROOT
1965
tests.TestCaseWithMemoryTransport.TEST_ROOT = None
1967
self.assertEqual(True, tests.selftest(stream=output, **kwargs))
1969
bzrlib.tests.default_transport = old_transport
1970
tests.TestCaseWithMemoryTransport.TEST_ROOT = old_root
1975
class TestSelftest(tests.TestCase, SelfTestHelper):
1976
"""Tests of bzrlib.tests.selftest."""
1978
def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
1981
factory_called.append(True)
1982
return TestUtil.TestSuite()
1985
self.apply_redirected(out, err, None, bzrlib.tests.selftest,
1986
test_suite_factory=factory)
1987
self.assertEqual([True], factory_called)
1990
"""A test suite factory."""
1991
class Test(tests.TestCase):
1998
return TestUtil.TestSuite([Test("a"), Test("b"), Test("c")])
2000
def test_list_only(self):
2001
output = self.run_selftest(test_suite_factory=self.factory,
2003
self.assertEqual(3, len(output.readlines()))
2005
def test_list_only_filtered(self):
2006
output = self.run_selftest(test_suite_factory=self.factory,
2007
list_only=True, pattern="Test.b")
2008
self.assertEndsWith(output.getvalue(), "Test.b\n")
2009
self.assertLength(1, output.readlines())
2011
def test_list_only_excludes(self):
2012
output = self.run_selftest(test_suite_factory=self.factory,
2013
list_only=True, exclude_pattern="Test.b")
2014
self.assertNotContainsRe("Test.b", output.getvalue())
2015
self.assertLength(2, output.readlines())
2017
def test_lsprof_tests(self):
2018
self.requireFeature(test_lsprof.LSProfFeature)
2021
def __call__(test, result):
2023
def run(test, result):
2024
self.assertIsInstance(result, ExtendedToOriginalDecorator)
2025
calls.append("called")
2026
def countTestCases(self):
2028
self.run_selftest(test_suite_factory=Test, lsprof_tests=True)
2029
self.assertLength(1, calls)
2031
def test_random(self):
2032
# test randomising by listing a number of tests.
2033
output_123 = self.run_selftest(test_suite_factory=self.factory,
2034
list_only=True, random_seed="123")
2035
output_234 = self.run_selftest(test_suite_factory=self.factory,
2036
list_only=True, random_seed="234")
2037
self.assertNotEqual(output_123, output_234)
2038
# "Randominzing test order..\n\n
2039
self.assertLength(5, output_123.readlines())
2040
self.assertLength(5, output_234.readlines())
2042
def test_random_reuse_is_same_order(self):
2043
# test randomising by listing a number of tests.
2044
expected = self.run_selftest(test_suite_factory=self.factory,
2045
list_only=True, random_seed="123")
2046
repeated = self.run_selftest(test_suite_factory=self.factory,
2047
list_only=True, random_seed="123")
2048
self.assertEqual(expected.getvalue(), repeated.getvalue())
2050
def test_runner_class(self):
2051
self.requireFeature(features.subunit)
2052
from subunit import ProtocolTestCase
2053
stream = self.run_selftest(runner_class=tests.SubUnitBzrRunner,
2054
test_suite_factory=self.factory)
2055
test = ProtocolTestCase(stream)
2056
result = unittest.TestResult()
2058
self.assertEqual(3, result.testsRun)
2060
def test_starting_with_single_argument(self):
2061
output = self.run_selftest(test_suite_factory=self.factory,
2062
starting_with=['bzrlib.tests.test_selftest.Test.a'],
2064
self.assertEqual('bzrlib.tests.test_selftest.Test.a\n',
2067
def test_starting_with_multiple_argument(self):
2068
output = self.run_selftest(test_suite_factory=self.factory,
2069
starting_with=['bzrlib.tests.test_selftest.Test.a',
2070
'bzrlib.tests.test_selftest.Test.b'],
2072
self.assertEqual('bzrlib.tests.test_selftest.Test.a\n'
2073
'bzrlib.tests.test_selftest.Test.b\n',
2076
def check_transport_set(self, transport_server):
2077
captured_transport = []
2078
def seen_transport(a_transport):
2079
captured_transport.append(a_transport)
2080
class Capture(tests.TestCase):
2082
seen_transport(bzrlib.tests.default_transport)
2084
return TestUtil.TestSuite([Capture("a")])
2085
self.run_selftest(transport=transport_server, test_suite_factory=factory)
2086
self.assertEqual(transport_server, captured_transport[0])
2088
def test_transport_sftp(self):
2089
self.requireFeature(features.paramiko)
2090
from bzrlib.tests import stub_sftp
2091
self.check_transport_set(stub_sftp.SFTPAbsoluteServer)
2093
def test_transport_memory(self):
2094
self.check_transport_set(memory.MemoryServer)
2097
class TestSelftestWithIdList(tests.TestCaseInTempDir, SelfTestHelper):
2098
# Does IO: reads test.list
2100
def test_load_list(self):
2101
# Provide a list with one test - this test.
2102
test_id_line = '%s\n' % self.id()
2103
self.build_tree_contents([('test.list', test_id_line)])
2104
# And generate a list of the tests in the suite.
2105
stream = self.run_selftest(load_list='test.list', list_only=True)
2106
self.assertEqual(test_id_line, stream.getvalue())
2108
def test_load_unknown(self):
2109
# Provide a list with one test - this test.
2110
# And generate a list of the tests in the suite.
2111
err = self.assertRaises(errors.NoSuchFile, self.run_selftest,
2112
load_list='missing file name', list_only=True)
2115
class TestSubunitLogDetails(tests.TestCase, SelfTestHelper):
2117
_test_needs_features = [features.subunit]
2119
def run_subunit_stream(self, test_name):
2120
from subunit import ProtocolTestCase
2122
return TestUtil.TestSuite([_get_test(test_name)])
2123
stream = self.run_selftest(runner_class=tests.SubUnitBzrRunner,
2124
test_suite_factory=factory)
2125
test = ProtocolTestCase(stream)
2126
result = testtools.TestResult()
2128
content = stream.getvalue()
2129
return content, result
2131
def test_fail_has_log(self):
2132
content, result = self.run_subunit_stream('test_fail')
2133
self.assertEqual(1, len(result.failures))
2134
self.assertContainsRe(content, '(?m)^log$')
2135
self.assertContainsRe(content, 'this test will fail')
2137
def test_error_has_log(self):
2138
content, result = self.run_subunit_stream('test_error')
2139
self.assertContainsRe(content, '(?m)^log$')
2140
self.assertContainsRe(content, 'this test errored')
2142
def test_skip_has_no_log(self):
2143
content, result = self.run_subunit_stream('test_skip')
2144
self.assertNotContainsRe(content, '(?m)^log$')
2145
self.assertNotContainsRe(content, 'this test will be skipped')
2146
self.assertEqual(['reason'], result.skip_reasons.keys())
2147
skips = result.skip_reasons['reason']
2148
self.assertEqual(1, len(skips))
2150
# RemotedTestCase doesn't preserve the "details"
2151
## self.assertFalse('log' in test.getDetails())
2153
def test_missing_feature_has_no_log(self):
2154
content, result = self.run_subunit_stream('test_missing_feature')
2155
self.assertNotContainsRe(content, '(?m)^log$')
2156
self.assertNotContainsRe(content, 'missing the feature')
2157
self.assertEqual(['_MissingFeature\n'], result.skip_reasons.keys())
2158
skips = result.skip_reasons['_MissingFeature\n']
2159
self.assertEqual(1, len(skips))
2161
# RemotedTestCase doesn't preserve the "details"
2162
## self.assertFalse('log' in test.getDetails())
2164
def test_xfail_has_no_log(self):
2165
content, result = self.run_subunit_stream('test_xfail')
2166
self.assertNotContainsRe(content, '(?m)^log$')
2167
self.assertNotContainsRe(content, 'test with expected failure')
2168
self.assertEqual(1, len(result.expectedFailures))
2169
result_content = result.expectedFailures[0][1]
2170
self.assertNotContainsRe(result_content, 'Text attachment: log')
2171
self.assertNotContainsRe(result_content, 'test with expected failure')
2173
def test_unexpected_success_has_log(self):
2174
content, result = self.run_subunit_stream('test_unexpected_success')
2175
self.assertContainsRe(content, '(?m)^log$')
2176
self.assertContainsRe(content, 'test with unexpected success')
2177
self.expectFailure('subunit treats "unexpectedSuccess"'
2178
' as a plain success',
2179
self.assertEqual, 1, len(result.unexpectedSuccesses))
2180
self.assertEqual(1, len(result.unexpectedSuccesses))
2181
test = result.unexpectedSuccesses[0]
2182
# RemotedTestCase doesn't preserve the "details"
2183
## self.assertTrue('log' in test.getDetails())
2185
def test_success_has_no_log(self):
2186
content, result = self.run_subunit_stream('test_success')
2187
self.assertEqual(1, result.testsRun)
2188
self.assertNotContainsRe(content, '(?m)^log$')
2189
self.assertNotContainsRe(content, 'this test succeeds')
2192
class TestRunBzr(tests.TestCase):
2197
def _run_bzr_core(self, argv, retcode=0, encoding=None, stdin=None,
2199
"""Override _run_bzr_core to test how it is invoked by run_bzr.
2201
Attempts to run bzr from inside this class don't actually run it.
2203
We test how run_bzr actually invokes bzr in another location. Here we
2204
only need to test that it passes the right parameters to run_bzr.
2206
self.argv = list(argv)
2207
self.retcode = retcode
2208
self.encoding = encoding
2210
self.working_dir = working_dir
2211
return self.retcode, self.out, self.err
2213
def test_run_bzr_error(self):
2214
self.out = "It sure does!\n"
2215
out, err = self.run_bzr_error(['^$'], ['rocks'], retcode=34)
2216
self.assertEqual(['rocks'], self.argv)
2217
self.assertEqual(34, self.retcode)
2218
self.assertEqual('It sure does!\n', out)
2219
self.assertEquals(out, self.out)
2220
self.assertEqual('', err)
2221
self.assertEquals(err, self.err)
2223
def test_run_bzr_error_regexes(self):
2225
self.err = "bzr: ERROR: foobarbaz is not versioned"
2226
out, err = self.run_bzr_error(
2227
["bzr: ERROR: foobarbaz is not versioned"],
2228
['file-id', 'foobarbaz'])
2230
def test_encoding(self):
2231
"""Test that run_bzr passes encoding to _run_bzr_core"""
2232
self.run_bzr('foo bar')
2233
self.assertEqual(None, self.encoding)
2234
self.assertEqual(['foo', 'bar'], self.argv)
2236
self.run_bzr('foo bar', encoding='baz')
2237
self.assertEqual('baz', self.encoding)
2238
self.assertEqual(['foo', 'bar'], self.argv)
2240
def test_retcode(self):
2241
"""Test that run_bzr passes retcode to _run_bzr_core"""
2242
# Default is retcode == 0
2243
self.run_bzr('foo bar')
2244
self.assertEqual(0, self.retcode)
2245
self.assertEqual(['foo', 'bar'], self.argv)
2247
self.run_bzr('foo bar', retcode=1)
2248
self.assertEqual(1, self.retcode)
2249
self.assertEqual(['foo', 'bar'], self.argv)
2251
self.run_bzr('foo bar', retcode=None)
2252
self.assertEqual(None, self.retcode)
2253
self.assertEqual(['foo', 'bar'], self.argv)
2255
self.run_bzr(['foo', 'bar'], retcode=3)
2256
self.assertEqual(3, self.retcode)
2257
self.assertEqual(['foo', 'bar'], self.argv)
2259
def test_stdin(self):
2260
# test that the stdin keyword to run_bzr is passed through to
2261
# _run_bzr_core as-is. We do this by overriding
2262
# _run_bzr_core in this class, and then calling run_bzr,
2263
# which is a convenience function for _run_bzr_core, so
2265
self.run_bzr('foo bar', stdin='gam')
2266
self.assertEqual('gam', self.stdin)
2267
self.assertEqual(['foo', 'bar'], self.argv)
2269
self.run_bzr('foo bar', stdin='zippy')
2270
self.assertEqual('zippy', self.stdin)
2271
self.assertEqual(['foo', 'bar'], self.argv)
2273
def test_working_dir(self):
2274
"""Test that run_bzr passes working_dir to _run_bzr_core"""
2275
self.run_bzr('foo bar')
2276
self.assertEqual(None, self.working_dir)
2277
self.assertEqual(['foo', 'bar'], self.argv)
2279
self.run_bzr('foo bar', working_dir='baz')
2280
self.assertEqual('baz', self.working_dir)
2281
self.assertEqual(['foo', 'bar'], self.argv)
2283
def test_reject_extra_keyword_arguments(self):
2284
self.assertRaises(TypeError, self.run_bzr, "foo bar",
2285
error_regex=['error message'])
2288
class TestRunBzrCaptured(tests.TestCaseWithTransport):
2289
# Does IO when testing the working_dir parameter.
2291
def apply_redirected(self, stdin=None, stdout=None, stderr=None,
2292
a_callable=None, *args, **kwargs):
2294
self.factory_stdin = getattr(bzrlib.ui.ui_factory, "stdin", None)
2295
self.factory = bzrlib.ui.ui_factory
2296
self.working_dir = osutils.getcwd()
2297
stdout.write('foo\n')
2298
stderr.write('bar\n')
2301
def test_stdin(self):
2302
# test that the stdin keyword to _run_bzr_core is passed through to
2303
# apply_redirected as a StringIO. We do this by overriding
2304
# apply_redirected in this class, and then calling _run_bzr_core,
2305
# which calls apply_redirected.
2306
self.run_bzr(['foo', 'bar'], stdin='gam')
2307
self.assertEqual('gam', self.stdin.read())
2308
self.assertTrue(self.stdin is self.factory_stdin)
2309
self.run_bzr(['foo', 'bar'], stdin='zippy')
2310
self.assertEqual('zippy', self.stdin.read())
2311
self.assertTrue(self.stdin is self.factory_stdin)
2313
def test_ui_factory(self):
2314
# each invocation of self.run_bzr should get its
2315
# own UI factory, which is an instance of TestUIFactory,
2316
# with stdin, stdout and stderr attached to the stdin,
2317
# stdout and stderr of the invoked run_bzr
2318
current_factory = bzrlib.ui.ui_factory
2319
self.run_bzr(['foo'])
2320
self.assertFalse(current_factory is self.factory)
2321
self.assertNotEqual(sys.stdout, self.factory.stdout)
2322
self.assertNotEqual(sys.stderr, self.factory.stderr)
2323
self.assertEqual('foo\n', self.factory.stdout.getvalue())
2324
self.assertEqual('bar\n', self.factory.stderr.getvalue())
2325
self.assertIsInstance(self.factory, tests.TestUIFactory)
2327
def test_working_dir(self):
2328
self.build_tree(['one/', 'two/'])
2329
cwd = osutils.getcwd()
2331
# Default is to work in the current directory
2332
self.run_bzr(['foo', 'bar'])
2333
self.assertEqual(cwd, self.working_dir)
2335
self.run_bzr(['foo', 'bar'], working_dir=None)
2336
self.assertEqual(cwd, self.working_dir)
2338
# The function should be run in the alternative directory
2339
# but afterwards the current working dir shouldn't be changed
2340
self.run_bzr(['foo', 'bar'], working_dir='one')
2341
self.assertNotEqual(cwd, self.working_dir)
2342
self.assertEndsWith(self.working_dir, 'one')
2343
self.assertEqual(cwd, osutils.getcwd())
2345
self.run_bzr(['foo', 'bar'], working_dir='two')
2346
self.assertNotEqual(cwd, self.working_dir)
2347
self.assertEndsWith(self.working_dir, 'two')
2348
self.assertEqual(cwd, osutils.getcwd())
2351
class StubProcess(object):
2352
"""A stub process for testing run_bzr_subprocess."""
2354
def __init__(self, out="", err="", retcode=0):
2357
self.returncode = retcode
2359
def communicate(self):
2360
return self.out, self.err
2363
class TestWithFakedStartBzrSubprocess(tests.TestCaseWithTransport):
2364
"""Base class for tests testing how we might run bzr."""
2367
tests.TestCaseWithTransport.setUp(self)
2368
self.subprocess_calls = []
2370
def start_bzr_subprocess(self, process_args, env_changes=None,
2371
skip_if_plan_to_signal=False,
2373
allow_plugins=False):
2374
"""capture what run_bzr_subprocess tries to do."""
2375
self.subprocess_calls.append({'process_args':process_args,
2376
'env_changes':env_changes,
2377
'skip_if_plan_to_signal':skip_if_plan_to_signal,
2378
'working_dir':working_dir, 'allow_plugins':allow_plugins})
2379
return self.next_subprocess
2382
class TestRunBzrSubprocess(TestWithFakedStartBzrSubprocess):
2384
def assertRunBzrSubprocess(self, expected_args, process, *args, **kwargs):
2385
"""Run run_bzr_subprocess with args and kwargs using a stubbed process.
2387
Inside TestRunBzrSubprocessCommands we use a stub start_bzr_subprocess
2388
that will return static results. This assertion method populates those
2389
results and also checks the arguments run_bzr_subprocess generates.
2391
self.next_subprocess = process
2393
result = self.run_bzr_subprocess(*args, **kwargs)
2395
self.next_subprocess = None
2396
for key, expected in expected_args.iteritems():
2397
self.assertEqual(expected, self.subprocess_calls[-1][key])
2400
self.next_subprocess = None
2401
for key, expected in expected_args.iteritems():
2402
self.assertEqual(expected, self.subprocess_calls[-1][key])
2405
def test_run_bzr_subprocess(self):
2406
"""The run_bzr_helper_external command behaves nicely."""
2407
self.assertRunBzrSubprocess({'process_args':['--version']},
2408
StubProcess(), '--version')
2409
self.assertRunBzrSubprocess({'process_args':['--version']},
2410
StubProcess(), ['--version'])
2411
# retcode=None disables retcode checking
2412
result = self.assertRunBzrSubprocess({},
2413
StubProcess(retcode=3), '--version', retcode=None)
2414
result = self.assertRunBzrSubprocess({},
2415
StubProcess(out="is free software"), '--version')
2416
self.assertContainsRe(result[0], 'is free software')
2417
# Running a subcommand that is missing errors
2418
self.assertRaises(AssertionError, self.assertRunBzrSubprocess,
2419
{'process_args':['--versionn']}, StubProcess(retcode=3),
2421
# Unless it is told to expect the error from the subprocess
2422
result = self.assertRunBzrSubprocess({},
2423
StubProcess(retcode=3), '--versionn', retcode=3)
2424
# Or to ignore retcode checking
2425
result = self.assertRunBzrSubprocess({},
2426
StubProcess(err="unknown command", retcode=3), '--versionn',
2428
self.assertContainsRe(result[1], 'unknown command')
2430
def test_env_change_passes_through(self):
2431
self.assertRunBzrSubprocess(
2432
{'env_changes':{'new':'value', 'changed':'newvalue', 'deleted':None}},
2434
env_changes={'new':'value', 'changed':'newvalue', 'deleted':None})
2436
def test_no_working_dir_passed_as_None(self):
2437
self.assertRunBzrSubprocess({'working_dir': None}, StubProcess(), '')
2439
def test_no_working_dir_passed_through(self):
2440
self.assertRunBzrSubprocess({'working_dir': 'dir'}, StubProcess(), '',
2443
def test_run_bzr_subprocess_no_plugins(self):
2444
self.assertRunBzrSubprocess({'allow_plugins': False},
2447
def test_allow_plugins(self):
2448
self.assertRunBzrSubprocess({'allow_plugins': True},
2449
StubProcess(), '', allow_plugins=True)
2452
class TestFinishBzrSubprocess(TestWithFakedStartBzrSubprocess):
2454
def test_finish_bzr_subprocess_with_error(self):
2455
"""finish_bzr_subprocess allows specification of the desired exit code.
2457
process = StubProcess(err="unknown command", retcode=3)
2458
result = self.finish_bzr_subprocess(process, retcode=3)
2459
self.assertEqual('', result[0])
2460
self.assertContainsRe(result[1], 'unknown command')
2462
def test_finish_bzr_subprocess_ignoring_retcode(self):
2463
"""finish_bzr_subprocess allows the exit code to be ignored."""
2464
process = StubProcess(err="unknown command", retcode=3)
2465
result = self.finish_bzr_subprocess(process, retcode=None)
2466
self.assertEqual('', result[0])
2467
self.assertContainsRe(result[1], 'unknown command')
2469
def test_finish_subprocess_with_unexpected_retcode(self):
2470
"""finish_bzr_subprocess raises self.failureException if the retcode is
2471
not the expected one.
2473
process = StubProcess(err="unknown command", retcode=3)
2474
self.assertRaises(self.failureException, self.finish_bzr_subprocess,
2478
class _DontSpawnProcess(Exception):
2479
"""A simple exception which just allows us to skip unnecessary steps"""
2482
class TestStartBzrSubProcess(tests.TestCase):
2484
def check_popen_state(self):
2485
"""Replace to make assertions when popen is called."""
2487
def _popen(self, *args, **kwargs):
2488
"""Record the command that is run, so that we can ensure it is correct"""
2489
self.check_popen_state()
2490
self._popen_args = args
2491
self._popen_kwargs = kwargs
2492
raise _DontSpawnProcess()
2494
def test_run_bzr_subprocess_no_plugins(self):
2495
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [])
2496
command = self._popen_args[0]
2497
self.assertEqual(sys.executable, command[0])
2498
self.assertEqual(self.get_bzr_path(), command[1])
2499
self.assertEqual(['--no-plugins'], command[2:])
2501
def test_allow_plugins(self):
2502
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2504
command = self._popen_args[0]
2505
self.assertEqual([], command[2:])
2507
def test_set_env(self):
2508
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2510
def check_environment():
2511
self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2512
self.check_popen_state = check_environment
2513
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2514
env_changes={'EXISTANT_ENV_VAR':'set variable'})
2515
# not set in theparent
2516
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2518
def test_run_bzr_subprocess_env_del(self):
2519
"""run_bzr_subprocess can remove environment variables too."""
2520
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2521
def check_environment():
2522
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2523
os.environ['EXISTANT_ENV_VAR'] = 'set variable'
2524
self.check_popen_state = check_environment
2525
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2526
env_changes={'EXISTANT_ENV_VAR':None})
2527
# Still set in parent
2528
self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2529
del os.environ['EXISTANT_ENV_VAR']
2531
def test_env_del_missing(self):
2532
self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
2533
def check_environment():
2534
self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
2535
self.check_popen_state = check_environment
2536
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2537
env_changes={'NON_EXISTANT_ENV_VAR':None})
2539
def test_working_dir(self):
2540
"""Test that we can specify the working dir for the child"""
2541
orig_getcwd = osutils.getcwd
2542
orig_chdir = os.chdir
2550
osutils.getcwd = getcwd
2552
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2555
osutils.getcwd = orig_getcwd
2557
os.chdir = orig_chdir
2558
self.assertEqual(['foo', 'current'], chdirs)
2560
def test_get_bzr_path_with_cwd_bzrlib(self):
2561
self.get_source_path = lambda: ""
2562
self.overrideAttr(os.path, "isfile", lambda path: True)
2563
self.assertEqual(self.get_bzr_path(), "bzr")
2566
class TestActuallyStartBzrSubprocess(tests.TestCaseWithTransport):
2567
"""Tests that really need to do things with an external bzr."""
2569
def test_start_and_stop_bzr_subprocess_send_signal(self):
2570
"""finish_bzr_subprocess raises self.failureException if the retcode is
2571
not the expected one.
2573
self.disable_missing_extensions_warning()
2574
process = self.start_bzr_subprocess(['wait-until-signalled'],
2575
skip_if_plan_to_signal=True)
2576
self.assertEqual('running\n', process.stdout.readline())
2577
result = self.finish_bzr_subprocess(process, send_signal=signal.SIGINT,
2579
self.assertEqual('', result[0])
2580
self.assertEqual('bzr: interrupted\n', result[1])
2583
class TestFeature(tests.TestCase):
2585
def test_caching(self):
2586
"""Feature._probe is called by the feature at most once."""
2587
class InstrumentedFeature(tests.Feature):
2589
super(InstrumentedFeature, self).__init__()
2592
self.calls.append('_probe')
2594
feature = InstrumentedFeature()
2596
self.assertEqual(['_probe'], feature.calls)
2598
self.assertEqual(['_probe'], feature.calls)
2600
def test_named_str(self):
2601
"""Feature.__str__ should thunk to feature_name()."""
2602
class NamedFeature(tests.Feature):
2603
def feature_name(self):
2605
feature = NamedFeature()
2606
self.assertEqual('symlinks', str(feature))
2608
def test_default_str(self):
2609
"""Feature.__str__ should default to __class__.__name__."""
2610
class NamedFeature(tests.Feature):
2612
feature = NamedFeature()
2613
self.assertEqual('NamedFeature', str(feature))
2616
class TestUnavailableFeature(tests.TestCase):
2618
def test_access_feature(self):
2619
feature = tests.Feature()
2620
exception = tests.UnavailableFeature(feature)
2621
self.assertIs(feature, exception.args[0])
2624
simple_thunk_feature = tests._CompatabilityThunkFeature(
2625
deprecated_in((2, 1, 0)),
2626
'bzrlib.tests.test_selftest',
2627
'simple_thunk_feature','UnicodeFilename',
2628
replacement_module='bzrlib.tests'
2631
class Test_CompatibilityFeature(tests.TestCase):
2633
def test_does_thunk(self):
2634
res = self.callDeprecated(
2635
['bzrlib.tests.test_selftest.simple_thunk_feature was deprecated'
2636
' in version 2.1.0. Use bzrlib.tests.UnicodeFilename instead.'],
2637
simple_thunk_feature.available)
2638
self.assertEqual(tests.UnicodeFilename.available(), res)
2641
class TestModuleAvailableFeature(tests.TestCase):
2643
def test_available_module(self):
2644
feature = tests.ModuleAvailableFeature('bzrlib.tests')
2645
self.assertEqual('bzrlib.tests', feature.module_name)
2646
self.assertEqual('bzrlib.tests', str(feature))
2647
self.assertTrue(feature.available())
2648
self.assertIs(tests, feature.module)
2650
def test_unavailable_module(self):
2651
feature = tests.ModuleAvailableFeature('bzrlib.no_such_module_exists')
2652
self.assertEqual('bzrlib.no_such_module_exists', str(feature))
2653
self.assertFalse(feature.available())
2654
self.assertIs(None, feature.module)
2657
class TestSelftestFiltering(tests.TestCase):
2660
tests.TestCase.setUp(self)
2661
self.suite = TestUtil.TestSuite()
2662
self.loader = TestUtil.TestLoader()
2663
self.suite.addTest(self.loader.loadTestsFromModule(
2664
sys.modules['bzrlib.tests.test_selftest']))
2665
self.all_names = _test_ids(self.suite)
2667
def test_condition_id_re(self):
2668
test_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2669
'test_condition_id_re')
2670
filtered_suite = tests.filter_suite_by_condition(
2671
self.suite, tests.condition_id_re('test_condition_id_re'))
2672
self.assertEqual([test_name], _test_ids(filtered_suite))
2674
def test_condition_id_in_list(self):
2675
test_names = ['bzrlib.tests.test_selftest.TestSelftestFiltering.'
2676
'test_condition_id_in_list']
2677
id_list = tests.TestIdList(test_names)
2678
filtered_suite = tests.filter_suite_by_condition(
2679
self.suite, tests.condition_id_in_list(id_list))
2680
my_pattern = 'TestSelftestFiltering.*test_condition_id_in_list'
2681
re_filtered = tests.filter_suite_by_re(self.suite, my_pattern)
2682
self.assertEqual(_test_ids(re_filtered), _test_ids(filtered_suite))
2684
def test_condition_id_startswith(self):
2685
klass = 'bzrlib.tests.test_selftest.TestSelftestFiltering.'
2686
start1 = klass + 'test_condition_id_starts'
2687
start2 = klass + 'test_condition_id_in'
2688
test_names = [ klass + 'test_condition_id_in_list',
2689
klass + 'test_condition_id_startswith',
2691
filtered_suite = tests.filter_suite_by_condition(
2692
self.suite, tests.condition_id_startswith([start1, start2]))
2693
self.assertEqual(test_names, _test_ids(filtered_suite))
2695
def test_condition_isinstance(self):
2696
filtered_suite = tests.filter_suite_by_condition(
2697
self.suite, tests.condition_isinstance(self.__class__))
2698
class_pattern = 'bzrlib.tests.test_selftest.TestSelftestFiltering.'
2699
re_filtered = tests.filter_suite_by_re(self.suite, class_pattern)
2700
self.assertEqual(_test_ids(re_filtered), _test_ids(filtered_suite))
2702
def test_exclude_tests_by_condition(self):
2703
excluded_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2704
'test_exclude_tests_by_condition')
2705
filtered_suite = tests.exclude_tests_by_condition(self.suite,
2706
lambda x:x.id() == excluded_name)
2707
self.assertEqual(len(self.all_names) - 1,
2708
filtered_suite.countTestCases())
2709
self.assertFalse(excluded_name in _test_ids(filtered_suite))
2710
remaining_names = list(self.all_names)
2711
remaining_names.remove(excluded_name)
2712
self.assertEqual(remaining_names, _test_ids(filtered_suite))
2714
def test_exclude_tests_by_re(self):
2715
self.all_names = _test_ids(self.suite)
2716
filtered_suite = tests.exclude_tests_by_re(self.suite,
2717
'exclude_tests_by_re')
2718
excluded_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2719
'test_exclude_tests_by_re')
2720
self.assertEqual(len(self.all_names) - 1,
2721
filtered_suite.countTestCases())
2722
self.assertFalse(excluded_name in _test_ids(filtered_suite))
2723
remaining_names = list(self.all_names)
2724
remaining_names.remove(excluded_name)
2725
self.assertEqual(remaining_names, _test_ids(filtered_suite))
2727
def test_filter_suite_by_condition(self):
2728
test_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2729
'test_filter_suite_by_condition')
2730
filtered_suite = tests.filter_suite_by_condition(self.suite,
2731
lambda x:x.id() == test_name)
2732
self.assertEqual([test_name], _test_ids(filtered_suite))
2734
def test_filter_suite_by_re(self):
2735
filtered_suite = tests.filter_suite_by_re(self.suite,
2736
'test_filter_suite_by_r')
2737
filtered_names = _test_ids(filtered_suite)
2738
self.assertEqual(filtered_names, ['bzrlib.tests.test_selftest.'
2739
'TestSelftestFiltering.test_filter_suite_by_re'])
2741
def test_filter_suite_by_id_list(self):
2742
test_list = ['bzrlib.tests.test_selftest.'
2743
'TestSelftestFiltering.test_filter_suite_by_id_list']
2744
filtered_suite = tests.filter_suite_by_id_list(
2745
self.suite, tests.TestIdList(test_list))
2746
filtered_names = _test_ids(filtered_suite)
2749
['bzrlib.tests.test_selftest.'
2750
'TestSelftestFiltering.test_filter_suite_by_id_list'])
2752
def test_filter_suite_by_id_startswith(self):
2753
# By design this test may fail if another test is added whose name also
2754
# begins with one of the start value used.
2755
klass = 'bzrlib.tests.test_selftest.TestSelftestFiltering.'
2756
start1 = klass + 'test_filter_suite_by_id_starts'
2757
start2 = klass + 'test_filter_suite_by_id_li'
2758
test_list = [klass + 'test_filter_suite_by_id_list',
2759
klass + 'test_filter_suite_by_id_startswith',
2761
filtered_suite = tests.filter_suite_by_id_startswith(
2762
self.suite, [start1, start2])
2765
_test_ids(filtered_suite),
2768
def test_preserve_input(self):
2769
# NB: Surely this is something in the stdlib to do this?
2770
self.assertTrue(self.suite is tests.preserve_input(self.suite))
2771
self.assertTrue("@#$" is tests.preserve_input("@#$"))
2773
def test_randomize_suite(self):
2774
randomized_suite = tests.randomize_suite(self.suite)
2775
# randomizing should not add or remove test names.
2776
self.assertEqual(set(_test_ids(self.suite)),
2777
set(_test_ids(randomized_suite)))
2778
# Technically, this *can* fail, because random.shuffle(list) can be
2779
# equal to list. Trying multiple times just pushes the frequency back.
2780
# As its len(self.all_names)!:1, the failure frequency should be low
2781
# enough to ignore. RBC 20071021.
2782
# It should change the order.
2783
self.assertNotEqual(self.all_names, _test_ids(randomized_suite))
2784
# But not the length. (Possibly redundant with the set test, but not
2786
self.assertEqual(len(self.all_names), len(_test_ids(randomized_suite)))
2788
def test_split_suit_by_condition(self):
2789
self.all_names = _test_ids(self.suite)
2790
condition = tests.condition_id_re('test_filter_suite_by_r')
2791
split_suite = tests.split_suite_by_condition(self.suite, condition)
2792
filtered_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2793
'test_filter_suite_by_re')
2794
self.assertEqual([filtered_name], _test_ids(split_suite[0]))
2795
self.assertFalse(filtered_name in _test_ids(split_suite[1]))
2796
remaining_names = list(self.all_names)
2797
remaining_names.remove(filtered_name)
2798
self.assertEqual(remaining_names, _test_ids(split_suite[1]))
2800
def test_split_suit_by_re(self):
2801
self.all_names = _test_ids(self.suite)
2802
split_suite = tests.split_suite_by_re(self.suite,
2803
'test_filter_suite_by_r')
2804
filtered_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2805
'test_filter_suite_by_re')
2806
self.assertEqual([filtered_name], _test_ids(split_suite[0]))
2807
self.assertFalse(filtered_name in _test_ids(split_suite[1]))
2808
remaining_names = list(self.all_names)
2809
remaining_names.remove(filtered_name)
2810
self.assertEqual(remaining_names, _test_ids(split_suite[1]))
2813
class TestCheckInventoryShape(tests.TestCaseWithTransport):
2815
def test_check_inventory_shape(self):
2816
files = ['a', 'b/', 'b/c']
2817
tree = self.make_branch_and_tree('.')
2818
self.build_tree(files)
2822
self.check_inventory_shape(tree.inventory, files)
2827
class TestBlackboxSupport(tests.TestCase):
2828
"""Tests for testsuite blackbox features."""
2830
def test_run_bzr_failure_not_caught(self):
2831
# When we run bzr in blackbox mode, we want any unexpected errors to
2832
# propagate up to the test suite so that it can show the error in the
2833
# usual way, and we won't get a double traceback.
2834
e = self.assertRaises(
2836
self.run_bzr, ['assert-fail'])
2837
# make sure we got the real thing, not an error from somewhere else in
2838
# the test framework
2839
self.assertEquals('always fails', str(e))
2840
# check that there's no traceback in the test log
2841
self.assertNotContainsRe(self.get_log(), r'Traceback')
2843
def test_run_bzr_user_error_caught(self):
2844
# Running bzr in blackbox mode, normal/expected/user errors should be
2845
# caught in the regular way and turned into an error message plus exit
2847
transport_server = memory.MemoryServer()
2848
transport_server.start_server()
2849
self.addCleanup(transport_server.stop_server)
2850
url = transport_server.get_url()
2851
self.permit_url(url)
2852
out, err = self.run_bzr(["log", "%s/nonexistantpath" % url], retcode=3)
2853
self.assertEqual(out, '')
2854
self.assertContainsRe(err,
2855
'bzr: ERROR: Not a branch: ".*nonexistantpath/".\n')
2858
class TestTestLoader(tests.TestCase):
2859
"""Tests for the test loader."""
2861
def _get_loader_and_module(self):
2862
"""Gets a TestLoader and a module with one test in it."""
2863
loader = TestUtil.TestLoader()
2865
class Stub(tests.TestCase):
2868
class MyModule(object):
2870
MyModule.a_class = Stub
2872
return loader, module
2874
def test_module_no_load_tests_attribute_loads_classes(self):
2875
loader, module = self._get_loader_and_module()
2876
self.assertEqual(1, loader.loadTestsFromModule(module).countTestCases())
2878
def test_module_load_tests_attribute_gets_called(self):
2879
loader, module = self._get_loader_and_module()
2880
# 'self' is here because we're faking the module with a class. Regular
2881
# load_tests do not need that :)
2882
def load_tests(self, standard_tests, module, loader):
2883
result = loader.suiteClass()
2884
for test in tests.iter_suite_tests(standard_tests):
2885
result.addTests([test, test])
2887
# add a load_tests() method which multiplies the tests from the module.
2888
module.__class__.load_tests = load_tests
2889
self.assertEqual(2, loader.loadTestsFromModule(module).countTestCases())
2891
def test_load_tests_from_module_name_smoke_test(self):
2892
loader = TestUtil.TestLoader()
2893
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
2894
self.assertEquals(['bzrlib.tests.test_sampler.DemoTest.test_nothing'],
2897
def test_load_tests_from_module_name_with_bogus_module_name(self):
2898
loader = TestUtil.TestLoader()
2899
self.assertRaises(ImportError, loader.loadTestsFromModuleName, 'bogus')
2902
class TestTestIdList(tests.TestCase):
2904
def _create_id_list(self, test_list):
2905
return tests.TestIdList(test_list)
2907
def _create_suite(self, test_id_list):
2909
class Stub(tests.TestCase):
2913
def _create_test_id(id):
2916
suite = TestUtil.TestSuite()
2917
for id in test_id_list:
2918
t = Stub('test_foo')
2919
t.id = _create_test_id(id)
2923
def _test_ids(self, test_suite):
2924
"""Get the ids for the tests in a test suite."""
2925
return [t.id() for t in tests.iter_suite_tests(test_suite)]
2927
def test_empty_list(self):
2928
id_list = self._create_id_list([])
2929
self.assertEquals({}, id_list.tests)
2930
self.assertEquals({}, id_list.modules)
2932
def test_valid_list(self):
2933
id_list = self._create_id_list(
2934
['mod1.cl1.meth1', 'mod1.cl1.meth2',
2935
'mod1.func1', 'mod1.cl2.meth2',
2937
'mod1.submod2.cl1.meth1', 'mod1.submod2.cl2.meth2',
2939
self.assertTrue(id_list.refers_to('mod1'))
2940
self.assertTrue(id_list.refers_to('mod1.submod1'))
2941
self.assertTrue(id_list.refers_to('mod1.submod2'))
2942
self.assertTrue(id_list.includes('mod1.cl1.meth1'))
2943
self.assertTrue(id_list.includes('mod1.submod1'))
2944
self.assertTrue(id_list.includes('mod1.func1'))
2946
def test_bad_chars_in_params(self):
2947
id_list = self._create_id_list(['mod1.cl1.meth1(xx.yy)'])
2948
self.assertTrue(id_list.refers_to('mod1'))
2949
self.assertTrue(id_list.includes('mod1.cl1.meth1(xx.yy)'))
2951
def test_module_used(self):
2952
id_list = self._create_id_list(['mod.class.meth'])
2953
self.assertTrue(id_list.refers_to('mod'))
2954
self.assertTrue(id_list.refers_to('mod.class'))
2955
self.assertTrue(id_list.refers_to('mod.class.meth'))
2957
def test_test_suite_matches_id_list_with_unknown(self):
2958
loader = TestUtil.TestLoader()
2959
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
2960
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing',
2962
not_found, duplicates = tests.suite_matches_id_list(suite, test_list)
2963
self.assertEquals(['bogus'], not_found)
2964
self.assertEquals([], duplicates)
2966
def test_suite_matches_id_list_with_duplicates(self):
2967
loader = TestUtil.TestLoader()
2968
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
2969
dupes = loader.suiteClass()
2970
for test in tests.iter_suite_tests(suite):
2972
dupes.addTest(test) # Add it again
2974
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing',]
2975
not_found, duplicates = tests.suite_matches_id_list(
2977
self.assertEquals([], not_found)
2978
self.assertEquals(['bzrlib.tests.test_sampler.DemoTest.test_nothing'],
2982
class TestTestSuite(tests.TestCase):
2984
def test__test_suite_testmod_names(self):
2985
# Test that a plausible list of test module names are returned
2986
# by _test_suite_testmod_names.
2987
test_list = tests._test_suite_testmod_names()
2989
'bzrlib.tests.blackbox',
2990
'bzrlib.tests.per_transport',
2991
'bzrlib.tests.test_selftest',
2995
def test__test_suite_modules_to_doctest(self):
2996
# Test that a plausible list of modules to doctest is returned
2997
# by _test_suite_modules_to_doctest.
2998
test_list = tests._test_suite_modules_to_doctest()
3000
# When docstrings are stripped, there are no modules to doctest
3001
self.assertEqual([], test_list)
3008
def test_test_suite(self):
3009
# test_suite() loads the entire test suite to operate. To avoid this
3010
# overhead, and yet still be confident that things are happening,
3011
# we temporarily replace two functions used by test_suite with
3012
# test doubles that supply a few sample tests to load, and check they
3015
def testmod_names():
3016
calls.append("testmod_names")
3018
'bzrlib.tests.blackbox.test_branch',
3019
'bzrlib.tests.per_transport',
3020
'bzrlib.tests.test_selftest',
3022
self.overrideAttr(tests, '_test_suite_testmod_names', testmod_names)
3024
calls.append("modules_to_doctest")
3027
return ['bzrlib.timestamp']
3028
self.overrideAttr(tests, '_test_suite_modules_to_doctest', doctests)
3029
expected_test_list = [
3031
'bzrlib.tests.blackbox.test_branch.TestBranch.test_branch',
3032
('bzrlib.tests.per_transport.TransportTests'
3033
'.test_abspath(LocalTransport,LocalURLServer)'),
3034
'bzrlib.tests.test_selftest.TestTestSuite.test_test_suite',
3035
# plugins can't be tested that way since selftest may be run with
3038
if __doc__ is not None:
3039
expected_test_list.extend([
3040
# modules_to_doctest
3041
'bzrlib.timestamp.format_highres_date',
3043
suite = tests.test_suite()
3044
self.assertEqual(set(["testmod_names", "modules_to_doctest"]),
3046
self.assertSubset(expected_test_list, _test_ids(suite))
3048
def test_test_suite_list_and_start(self):
3049
# We cannot test this at the same time as the main load, because we want
3050
# to know that starting_with == None works. So a second load is
3051
# incurred - note that the starting_with parameter causes a partial load
3052
# rather than a full load so this test should be pretty quick.
3053
test_list = ['bzrlib.tests.test_selftest.TestTestSuite.test_test_suite']
3054
suite = tests.test_suite(test_list,
3055
['bzrlib.tests.test_selftest.TestTestSuite'])
3056
# test_test_suite_list_and_start is not included
3057
self.assertEquals(test_list, _test_ids(suite))
3060
class TestLoadTestIdList(tests.TestCaseInTempDir):
3062
def _create_test_list_file(self, file_name, content):
3063
fl = open(file_name, 'wt')
3067
def test_load_unknown(self):
3068
self.assertRaises(errors.NoSuchFile,
3069
tests.load_test_id_list, 'i_do_not_exist')
3071
def test_load_test_list(self):
3072
test_list_fname = 'test.list'
3073
self._create_test_list_file(test_list_fname,
3074
'mod1.cl1.meth1\nmod2.cl2.meth2\n')
3075
tlist = tests.load_test_id_list(test_list_fname)
3076
self.assertEquals(2, len(tlist))
3077
self.assertEquals('mod1.cl1.meth1', tlist[0])
3078
self.assertEquals('mod2.cl2.meth2', tlist[1])
3080
def test_load_dirty_file(self):
3081
test_list_fname = 'test.list'
3082
self._create_test_list_file(test_list_fname,
3083
' mod1.cl1.meth1\n\nmod2.cl2.meth2 \n'
3085
tlist = tests.load_test_id_list(test_list_fname)
3086
self.assertEquals(4, len(tlist))
3087
self.assertEquals('mod1.cl1.meth1', tlist[0])
3088
self.assertEquals('', tlist[1])
3089
self.assertEquals('mod2.cl2.meth2', tlist[2])
3090
self.assertEquals('bar baz', tlist[3])
3093
class TestFilteredByModuleTestLoader(tests.TestCase):
3095
def _create_loader(self, test_list):
3096
id_filter = tests.TestIdList(test_list)
3097
loader = TestUtil.FilteredByModuleTestLoader(id_filter.refers_to)
3100
def test_load_tests(self):
3101
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
3102
loader = self._create_loader(test_list)
3103
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3104
self.assertEquals(test_list, _test_ids(suite))
3106
def test_exclude_tests(self):
3107
test_list = ['bogus']
3108
loader = self._create_loader(test_list)
3109
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3110
self.assertEquals([], _test_ids(suite))
3113
class TestFilteredByNameStartTestLoader(tests.TestCase):
3115
def _create_loader(self, name_start):
3116
def needs_module(name):
3117
return name.startswith(name_start) or name_start.startswith(name)
3118
loader = TestUtil.FilteredByModuleTestLoader(needs_module)
3121
def test_load_tests(self):
3122
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
3123
loader = self._create_loader('bzrlib.tests.test_samp')
3125
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3126
self.assertEquals(test_list, _test_ids(suite))
3128
def test_load_tests_inside_module(self):
3129
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
3130
loader = self._create_loader('bzrlib.tests.test_sampler.Demo')
3132
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3133
self.assertEquals(test_list, _test_ids(suite))
3135
def test_exclude_tests(self):
3136
test_list = ['bogus']
3137
loader = self._create_loader('bogus')
3139
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3140
self.assertEquals([], _test_ids(suite))
3143
class TestTestPrefixRegistry(tests.TestCase):
3145
def _get_registry(self):
3146
tp_registry = tests.TestPrefixAliasRegistry()
3149
def test_register_new_prefix(self):
3150
tpr = self._get_registry()
3151
tpr.register('foo', 'fff.ooo.ooo')
3152
self.assertEquals('fff.ooo.ooo', tpr.get('foo'))
3154
def test_register_existing_prefix(self):
3155
tpr = self._get_registry()
3156
tpr.register('bar', 'bbb.aaa.rrr')
3157
tpr.register('bar', 'bBB.aAA.rRR')
3158
self.assertEquals('bbb.aaa.rrr', tpr.get('bar'))
3159
self.assertThat(self.get_log(),
3160
DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR",
3163
def test_get_unknown_prefix(self):
3164
tpr = self._get_registry()
3165
self.assertRaises(KeyError, tpr.get, 'I am not a prefix')
3167
def test_resolve_prefix(self):
3168
tpr = self._get_registry()
3169
tpr.register('bar', 'bb.aa.rr')
3170
self.assertEquals('bb.aa.rr', tpr.resolve_alias('bar'))
3172
def test_resolve_unknown_alias(self):
3173
tpr = self._get_registry()
3174
self.assertRaises(errors.BzrCommandError,
3175
tpr.resolve_alias, 'I am not a prefix')
3177
def test_predefined_prefixes(self):
3178
tpr = tests.test_prefix_alias_registry
3179
self.assertEquals('bzrlib', tpr.resolve_alias('bzrlib'))
3180
self.assertEquals('bzrlib.doc', tpr.resolve_alias('bd'))
3181
self.assertEquals('bzrlib.utils', tpr.resolve_alias('bu'))
3182
self.assertEquals('bzrlib.tests', tpr.resolve_alias('bt'))
3183
self.assertEquals('bzrlib.tests.blackbox', tpr.resolve_alias('bb'))
3184
self.assertEquals('bzrlib.plugins', tpr.resolve_alias('bp'))
3187
class TestThreadLeakDetection(tests.TestCase):
3188
"""Ensure when tests leak threads we detect and report it"""
3190
class LeakRecordingResult(tests.ExtendedTestResult):
3192
tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
3194
def _report_thread_leak(self, test, leaks, alive):
3195
self.leaks.append((test, leaks))
3197
def test_testcase_without_addCleanups(self):
3198
"""Check old TestCase instances don't break with leak detection"""
3199
class Test(unittest.TestCase):
3202
result = self.LeakRecordingResult()
3204
result.startTestRun()
3206
result.stopTestRun()
3207
self.assertEqual(result._tests_leaking_threads_count, 0)
3208
self.assertEqual(result.leaks, [])
3210
def test_thread_leak(self):
3211
"""Ensure a thread that outlives the running of a test is reported
3213
Uses a thread that blocks on an event, and is started by the inner
3214
test case. As the thread outlives the inner case's run, it should be
3215
detected as a leak, but the event is then set so that the thread can
3216
be safely joined in cleanup so it's not leaked for real.
3218
event = threading.Event()
3219
thread = threading.Thread(name="Leaker", target=event.wait)
3220
class Test(tests.TestCase):
3221
def test_leak(self):
3223
result = self.LeakRecordingResult()
3224
test = Test("test_leak")
3225
self.addCleanup(thread.join)
3226
self.addCleanup(event.set)
3227
result.startTestRun()
3229
result.stopTestRun()
3230
self.assertEqual(result._tests_leaking_threads_count, 1)
3231
self.assertEqual(result._first_thread_leaker_id, test.id())
3232
self.assertEqual(result.leaks, [(test, set([thread]))])
3233
self.assertContainsString(result.stream.getvalue(), "leaking threads")
3235
def test_multiple_leaks(self):
3236
"""Check multiple leaks are blamed on the test cases at fault
3238
Same concept as the previous test, but has one inner test method that
3239
leaks two threads, and one that doesn't leak at all.
3241
event = threading.Event()
3242
thread_a = threading.Thread(name="LeakerA", target=event.wait)
3243
thread_b = threading.Thread(name="LeakerB", target=event.wait)
3244
thread_c = threading.Thread(name="LeakerC", target=event.wait)
3245
class Test(tests.TestCase):
3246
def test_first_leak(self):
3248
def test_second_no_leak(self):
3250
def test_third_leak(self):
3253
result = self.LeakRecordingResult()
3254
first_test = Test("test_first_leak")
3255
third_test = Test("test_third_leak")
3256
self.addCleanup(thread_a.join)
3257
self.addCleanup(thread_b.join)
3258
self.addCleanup(thread_c.join)
3259
self.addCleanup(event.set)
3260
result.startTestRun()
3262
[first_test, Test("test_second_no_leak"), third_test]
3264
result.stopTestRun()
3265
self.assertEqual(result._tests_leaking_threads_count, 2)
3266
self.assertEqual(result._first_thread_leaker_id, first_test.id())
3267
self.assertEqual(result.leaks, [
3268
(first_test, set([thread_b])),
3269
(third_test, set([thread_a, thread_c]))])
3270
self.assertContainsString(result.stream.getvalue(), "leaking threads")
3273
class TestPostMortemDebugging(tests.TestCase):
3274
"""Check post mortem debugging works when tests fail or error"""
3276
class TracebackRecordingResult(tests.ExtendedTestResult):
3278
tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
3279
self.postcode = None
3280
def _post_mortem(self, tb=None):
3281
"""Record the code object at the end of the current traceback"""
3282
tb = tb or sys.exc_info()[2]
3285
while next is not None:
3288
self.postcode = tb.tb_frame.f_code
3289
def report_error(self, test, err):
3291
def report_failure(self, test, err):
3294
def test_location_unittest_error(self):
3295
"""Needs right post mortem traceback with erroring unittest case"""
3296
class Test(unittest.TestCase):
3299
result = self.TracebackRecordingResult()
3301
self.assertEqual(result.postcode, Test.runTest.func_code)
3303
def test_location_unittest_failure(self):
3304
"""Needs right post mortem traceback with failing unittest case"""
3305
class Test(unittest.TestCase):
3307
raise self.failureException
3308
result = self.TracebackRecordingResult()
3310
self.assertEqual(result.postcode, Test.runTest.func_code)
3312
def test_location_bt_error(self):
3313
"""Needs right post mortem traceback with erroring bzrlib.tests case"""
3314
class Test(tests.TestCase):
3315
def test_error(self):
3317
result = self.TracebackRecordingResult()
3318
Test("test_error").run(result)
3319
self.assertEqual(result.postcode, Test.test_error.func_code)
3321
def test_location_bt_failure(self):
3322
"""Needs right post mortem traceback with failing bzrlib.tests case"""
3323
class Test(tests.TestCase):
3324
def test_failure(self):
3325
raise self.failureException
3326
result = self.TracebackRecordingResult()
3327
Test("test_failure").run(result)
3328
self.assertEqual(result.postcode, Test.test_failure.func_code)
3330
def test_env_var_triggers_post_mortem(self):
3331
"""Check pdb.post_mortem is called iff BZR_TEST_PDB is set"""
3333
result = tests.ExtendedTestResult(StringIO(), 0, 1)
3334
post_mortem_calls = []
3335
self.overrideAttr(pdb, "post_mortem", post_mortem_calls.append)
3336
self.overrideEnv('BZR_TEST_PDB', None)
3337
result._post_mortem(1)
3338
self.overrideEnv('BZR_TEST_PDB', 'on')
3339
result._post_mortem(2)
3340
self.assertEqual([2], post_mortem_calls)
3343
class TestRunSuite(tests.TestCase):
3345
def test_runner_class(self):
3346
"""run_suite accepts and uses a runner_class keyword argument."""
3347
class Stub(tests.TestCase):
3350
suite = Stub("test_foo")
3352
class MyRunner(tests.TextTestRunner):
3353
def run(self, test):
3355
return tests.ExtendedTestResult(self.stream, self.descriptions,
3357
tests.run_suite(suite, runner_class=MyRunner, stream=StringIO())
3358
self.assertLength(1, calls)
3361
class TestEnvironHandling(tests.TestCase):
3363
def test_overrideEnv_None_called_twice_doesnt_leak(self):
3364
self.assertFalse('MYVAR' in os.environ)
3365
self.overrideEnv('MYVAR', '42')
3366
# We use an embedded test to make sure we fix the _captureVar bug
3367
class Test(tests.TestCase):
3369
# The first call save the 42 value
3370
self.overrideEnv('MYVAR', None)
3371
self.assertEquals(None, os.environ.get('MYVAR'))
3372
# Make sure we can call it twice
3373
self.overrideEnv('MYVAR', None)
3374
self.assertEquals(None, os.environ.get('MYVAR'))
3376
result = tests.TextTestResult(output, 0, 1)
3377
Test('test_me').run(result)
3378
if not result.wasStrictlySuccessful():
3379
self.fail(output.getvalue())
3380
# We get our value back
3381
self.assertEquals('42', os.environ.get('MYVAR'))
3384
class TestIsolatedEnv(tests.TestCase):
3385
"""Test isolating tests from os.environ.
3387
Since we use tests that are already isolated from os.environ a bit of care
3388
should be taken when designing the tests to avoid bootstrap side-effects.
3389
The tests start an already clean os.environ which allow doing valid
3390
assertions about which variables are present or not and design tests around
3394
class ScratchMonkey(tests.TestCase):
3399
def test_basics(self):
3400
# Make sure we know the definition of BZR_HOME: not part of os.environ
3401
# for tests.TestCase.
3402
self.assertTrue('BZR_HOME' in tests.isolated_environ)
3403
self.assertEquals(None, tests.isolated_environ['BZR_HOME'])
3404
# Being part of isolated_environ, BZR_HOME should not appear here
3405
self.assertFalse('BZR_HOME' in os.environ)
3406
# Make sure we know the definition of LINES: part of os.environ for
3408
self.assertTrue('LINES' in tests.isolated_environ)
3409
self.assertEquals('25', tests.isolated_environ['LINES'])
3410
self.assertEquals('25', os.environ['LINES'])
3412
def test_injecting_unknown_variable(self):
3413
# BZR_HOME is known to be absent from os.environ
3414
test = self.ScratchMonkey('test_me')
3415
tests.override_os_environ(test, {'BZR_HOME': 'foo'})
3416
self.assertEquals('foo', os.environ['BZR_HOME'])
3417
tests.restore_os_environ(test)
3418
self.assertFalse('BZR_HOME' in os.environ)
3420
def test_injecting_known_variable(self):
3421
test = self.ScratchMonkey('test_me')
3422
# LINES is known to be present in os.environ
3423
tests.override_os_environ(test, {'LINES': '42'})
3424
self.assertEquals('42', os.environ['LINES'])
3425
tests.restore_os_environ(test)
3426
self.assertEquals('25', os.environ['LINES'])
3428
def test_deleting_variable(self):
3429
test = self.ScratchMonkey('test_me')
3430
# LINES is known to be present in os.environ
3431
tests.override_os_environ(test, {'LINES': None})
3432
self.assertTrue('LINES' not in os.environ)
3433
tests.restore_os_environ(test)
3434
self.assertEquals('25', os.environ['LINES'])
3437
class TestDocTestSuiteIsolation(tests.TestCase):
3438
"""Test that `tests.DocTestSuite` isolates doc tests from os.environ.
3440
Since tests.TestCase alreay provides an isolation from os.environ, we use
3441
the clean environment as a base for testing. To precisely capture the
3442
isolation provided by tests.DocTestSuite, we use doctest.DocTestSuite to
3445
We want to make sure `tests.DocTestSuite` respect `tests.isolated_environ`,
3446
not `os.environ` so each test overrides it to suit its needs.
3450
def get_doctest_suite_for_string(self, klass, string):
3451
class Finder(doctest.DocTestFinder):
3453
def find(*args, **kwargs):
3454
test = doctest.DocTestParser().get_doctest(
3455
string, {}, 'foo', 'foo.py', 0)
3458
suite = klass(test_finder=Finder())
3461
def run_doctest_suite_for_string(self, klass, string):
3462
suite = self.get_doctest_suite_for_string(klass, string)
3464
result = tests.TextTestResult(output, 0, 1)
3466
return result, output
3468
def assertDocTestStringSucceds(self, klass, string):
3469
result, output = self.run_doctest_suite_for_string(klass, string)
3470
if not result.wasStrictlySuccessful():
3471
self.fail(output.getvalue())
3473
def assertDocTestStringFails(self, klass, string):
3474
result, output = self.run_doctest_suite_for_string(klass, string)
3475
if result.wasStrictlySuccessful():
3476
self.fail(output.getvalue())
3478
def test_injected_variable(self):
3479
self.overrideAttr(tests, 'isolated_environ', {'LINES': '42'})
3482
>>> os.environ['LINES']
3485
# doctest.DocTestSuite fails as it sees '25'
3486
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3487
# tests.DocTestSuite sees '42'
3488
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
3490
def test_deleted_variable(self):
3491
self.overrideAttr(tests, 'isolated_environ', {'LINES': None})
3494
>>> os.environ.get('LINES')
3496
# doctest.DocTestSuite fails as it sees '25'
3497
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3498
# tests.DocTestSuite sees None
3499
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)