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
30
from testtools import (
31
ExtendedToOriginalDecorator,
34
from testtools.content import Content
35
from testtools.content_type import ContentType
36
from testtools.matchers import (
40
import testtools.testresult.doubles
61
from bzrlib.repofmt import (
64
from bzrlib.symbol_versioning import (
69
from bzrlib.tests import (
75
from bzrlib.trace import note, mutter
76
from bzrlib.transport import memory
79
def _test_ids(test_suite):
80
"""Get the ids for the tests in a test suite."""
81
return [t.id() for t in tests.iter_suite_tests(test_suite)]
84
class MetaTestLog(tests.TestCase):
86
def test_logging(self):
87
"""Test logs are captured when a test fails."""
88
self.log('a test message')
89
details = self.getDetails()
91
self.assertThat(log.content_type, Equals(ContentType(
92
"text", "plain", {"charset": "utf8"})))
93
self.assertThat(u"".join(log.iter_text()), Equals(self.get_log()))
94
self.assertThat(self.get_log(),
95
DocTestMatches(u"...a test message\n", doctest.ELLIPSIS))
98
class TestTreeShape(tests.TestCaseInTempDir):
100
def test_unicode_paths(self):
101
self.requireFeature(features.UnicodeFilenameFeature)
103
filename = u'hell\u00d8'
104
self.build_tree_contents([(filename, 'contents of hello')])
105
self.assertPathExists(filename)
108
class TestClassesAvailable(tests.TestCase):
109
"""As a convenience we expose Test* classes from bzrlib.tests"""
111
def test_test_case(self):
112
from bzrlib.tests import TestCase
114
def test_test_loader(self):
115
from bzrlib.tests import TestLoader
117
def test_test_suite(self):
118
from bzrlib.tests import TestSuite
121
class TestTransportScenarios(tests.TestCase):
122
"""A group of tests that test the transport implementation adaption core.
124
This is a meta test that the tests are applied to all available
127
This will be generalised in the future which is why it is in this
128
test file even though it is specific to transport tests at the moment.
131
def test_get_transport_permutations(self):
132
# this checks that get_test_permutations defined by the module is
133
# called by the get_transport_test_permutations function.
134
class MockModule(object):
135
def get_test_permutations(self):
136
return sample_permutation
137
sample_permutation = [(1,2), (3,4)]
138
from bzrlib.tests.per_transport import get_transport_test_permutations
139
self.assertEqual(sample_permutation,
140
get_transport_test_permutations(MockModule()))
142
def test_scenarios_include_all_modules(self):
143
# this checks that the scenario generator returns as many permutations
144
# as there are in all the registered transport modules - we assume if
145
# this matches its probably doing the right thing especially in
146
# combination with the tests for setting the right classes below.
147
from bzrlib.tests.per_transport import transport_test_permutations
148
from bzrlib.transport import _get_transport_modules
149
modules = _get_transport_modules()
150
permutation_count = 0
151
for module in modules:
153
permutation_count += len(reduce(getattr,
154
(module + ".get_test_permutations").split('.')[1:],
155
__import__(module))())
156
except errors.DependencyNotPresent:
158
scenarios = transport_test_permutations()
159
self.assertEqual(permutation_count, len(scenarios))
161
def test_scenarios_include_transport_class(self):
162
# This test used to know about all the possible transports and the
163
# order they were returned but that seems overly brittle (mbp
165
from bzrlib.tests.per_transport import transport_test_permutations
166
scenarios = transport_test_permutations()
167
# there are at least that many builtin transports
168
self.assertTrue(len(scenarios) > 6)
169
one_scenario = scenarios[0]
170
self.assertIsInstance(one_scenario[0], str)
171
self.assertTrue(issubclass(one_scenario[1]["transport_class"],
172
bzrlib.transport.Transport))
173
self.assertTrue(issubclass(one_scenario[1]["transport_server"],
174
bzrlib.transport.Server))
177
class TestBranchScenarios(tests.TestCase):
179
def test_scenarios(self):
180
# check that constructor parameters are passed through to the adapted
182
from bzrlib.tests.per_branch import make_scenarios
185
formats = [("c", "C"), ("d", "D")]
186
scenarios = make_scenarios(server1, server2, formats)
187
self.assertEqual(2, len(scenarios))
190
{'branch_format': 'c',
191
'bzrdir_format': 'C',
192
'transport_readonly_server': 'b',
193
'transport_server': 'a'}),
195
{'branch_format': 'd',
196
'bzrdir_format': 'D',
197
'transport_readonly_server': 'b',
198
'transport_server': 'a'})],
202
class TestBzrDirScenarios(tests.TestCase):
204
def test_scenarios(self):
205
# check that constructor parameters are passed through to the adapted
207
from bzrlib.tests.per_controldir import make_scenarios
212
scenarios = make_scenarios(vfs_factory, server1, server2, formats)
215
{'bzrdir_format': 'c',
216
'transport_readonly_server': 'b',
217
'transport_server': 'a',
218
'vfs_transport_factory': 'v'}),
220
{'bzrdir_format': 'd',
221
'transport_readonly_server': 'b',
222
'transport_server': 'a',
223
'vfs_transport_factory': 'v'})],
227
class TestRepositoryScenarios(tests.TestCase):
229
def test_formats_to_scenarios(self):
230
from bzrlib.tests.per_repository import formats_to_scenarios
231
formats = [("(c)", remote.RemoteRepositoryFormat()),
232
("(d)", repository.format_registry.get(
233
'Bazaar repository format 2a (needs bzr 1.16 or later)\n'))]
234
no_vfs_scenarios = formats_to_scenarios(formats, "server", "readonly",
236
vfs_scenarios = formats_to_scenarios(formats, "server", "readonly",
237
vfs_transport_factory="vfs")
238
# no_vfs generate scenarios without vfs_transport_factory
240
('RemoteRepositoryFormat(c)',
241
{'bzrdir_format': remote.RemoteBzrDirFormat(),
242
'repository_format': remote.RemoteRepositoryFormat(),
243
'transport_readonly_server': 'readonly',
244
'transport_server': 'server'}),
245
('RepositoryFormat2a(d)',
246
{'bzrdir_format': bzrdir.BzrDirMetaFormat1(),
247
'repository_format': groupcompress_repo.RepositoryFormat2a(),
248
'transport_readonly_server': 'readonly',
249
'transport_server': 'server'})]
250
self.assertEqual(expected, no_vfs_scenarios)
252
('RemoteRepositoryFormat(c)',
253
{'bzrdir_format': remote.RemoteBzrDirFormat(),
254
'repository_format': remote.RemoteRepositoryFormat(),
255
'transport_readonly_server': 'readonly',
256
'transport_server': 'server',
257
'vfs_transport_factory': 'vfs'}),
258
('RepositoryFormat2a(d)',
259
{'bzrdir_format': bzrdir.BzrDirMetaFormat1(),
260
'repository_format': groupcompress_repo.RepositoryFormat2a(),
261
'transport_readonly_server': 'readonly',
262
'transport_server': 'server',
263
'vfs_transport_factory': 'vfs'})],
267
class TestTestScenarioApplication(tests.TestCase):
268
"""Tests for the test adaption facilities."""
270
def test_apply_scenario(self):
271
from bzrlib.tests import apply_scenario
272
input_test = TestTestScenarioApplication("test_apply_scenario")
273
# setup two adapted tests
274
adapted_test1 = apply_scenario(input_test,
276
{"bzrdir_format":"bzr_format",
277
"repository_format":"repo_fmt",
278
"transport_server":"transport_server",
279
"transport_readonly_server":"readonly-server"}))
280
adapted_test2 = apply_scenario(input_test,
281
("new id 2", {"bzrdir_format":None}))
282
# input_test should have been altered.
283
self.assertRaises(AttributeError, getattr, input_test, "bzrdir_format")
284
# the new tests are mutually incompatible, ensuring it has
285
# made new ones, and unspecified elements in the scenario
286
# should not have been altered.
287
self.assertEqual("bzr_format", adapted_test1.bzrdir_format)
288
self.assertEqual("repo_fmt", adapted_test1.repository_format)
289
self.assertEqual("transport_server", adapted_test1.transport_server)
290
self.assertEqual("readonly-server",
291
adapted_test1.transport_readonly_server)
293
"bzrlib.tests.test_selftest.TestTestScenarioApplication."
294
"test_apply_scenario(new id)",
296
self.assertEqual(None, adapted_test2.bzrdir_format)
298
"bzrlib.tests.test_selftest.TestTestScenarioApplication."
299
"test_apply_scenario(new id 2)",
303
class TestInterRepositoryScenarios(tests.TestCase):
305
def test_scenarios(self):
306
# check that constructor parameters are passed through to the adapted
308
from bzrlib.tests.per_interrepository import make_scenarios
311
formats = [("C0", "C1", "C2", "C3"), ("D0", "D1", "D2", "D3")]
312
scenarios = make_scenarios(server1, server2, formats)
315
{'repository_format': 'C1',
316
'repository_format_to': 'C2',
317
'transport_readonly_server': 'b',
318
'transport_server': 'a',
319
'extra_setup': 'C3'}),
321
{'repository_format': 'D1',
322
'repository_format_to': 'D2',
323
'transport_readonly_server': 'b',
324
'transport_server': 'a',
325
'extra_setup': 'D3'})],
329
class TestWorkingTreeScenarios(tests.TestCase):
331
def test_scenarios(self):
332
# check that constructor parameters are passed through to the adapted
334
from bzrlib.tests.per_workingtree import make_scenarios
337
formats = [workingtree_4.WorkingTreeFormat4(),
338
workingtree_3.WorkingTreeFormat3(),]
339
scenarios = make_scenarios(server1, server2, formats)
341
('WorkingTreeFormat4',
342
{'bzrdir_format': formats[0]._matchingbzrdir,
343
'transport_readonly_server': 'b',
344
'transport_server': 'a',
345
'workingtree_format': formats[0]}),
346
('WorkingTreeFormat3',
347
{'bzrdir_format': formats[1]._matchingbzrdir,
348
'transport_readonly_server': 'b',
349
'transport_server': 'a',
350
'workingtree_format': formats[1]})],
354
class TestTreeScenarios(tests.TestCase):
356
def test_scenarios(self):
357
# the tree implementation scenario generator is meant to setup one
358
# instance for each working tree format, and one additional instance
359
# that will use the default wt format, but create a revision tree for
360
# the tests. this means that the wt ones should have the
361
# workingtree_to_test_tree attribute set to 'return_parameter' and the
362
# revision one set to revision_tree_from_workingtree.
364
from bzrlib.tests.per_tree import (
365
_dirstate_tree_from_workingtree,
370
revision_tree_from_workingtree
374
formats = [workingtree_4.WorkingTreeFormat4(),
375
workingtree_3.WorkingTreeFormat3(),]
376
scenarios = make_scenarios(server1, server2, formats)
377
self.assertEqual(7, len(scenarios))
378
default_wt_format = workingtree.format_registry.get_default()
379
wt4_format = workingtree_4.WorkingTreeFormat4()
380
wt5_format = workingtree_4.WorkingTreeFormat5()
381
expected_scenarios = [
382
('WorkingTreeFormat4',
383
{'bzrdir_format': formats[0]._matchingbzrdir,
384
'transport_readonly_server': 'b',
385
'transport_server': 'a',
386
'workingtree_format': formats[0],
387
'_workingtree_to_test_tree': return_parameter,
389
('WorkingTreeFormat3',
390
{'bzrdir_format': formats[1]._matchingbzrdir,
391
'transport_readonly_server': 'b',
392
'transport_server': 'a',
393
'workingtree_format': formats[1],
394
'_workingtree_to_test_tree': return_parameter,
397
{'_workingtree_to_test_tree': revision_tree_from_workingtree,
398
'bzrdir_format': default_wt_format._matchingbzrdir,
399
'transport_readonly_server': 'b',
400
'transport_server': 'a',
401
'workingtree_format': default_wt_format,
403
('DirStateRevisionTree,WT4',
404
{'_workingtree_to_test_tree': _dirstate_tree_from_workingtree,
405
'bzrdir_format': wt4_format._matchingbzrdir,
406
'transport_readonly_server': 'b',
407
'transport_server': 'a',
408
'workingtree_format': wt4_format,
410
('DirStateRevisionTree,WT5',
411
{'_workingtree_to_test_tree': _dirstate_tree_from_workingtree,
412
'bzrdir_format': wt5_format._matchingbzrdir,
413
'transport_readonly_server': 'b',
414
'transport_server': 'a',
415
'workingtree_format': wt5_format,
418
{'_workingtree_to_test_tree': preview_tree_pre,
419
'bzrdir_format': default_wt_format._matchingbzrdir,
420
'transport_readonly_server': 'b',
421
'transport_server': 'a',
422
'workingtree_format': default_wt_format}),
424
{'_workingtree_to_test_tree': preview_tree_post,
425
'bzrdir_format': default_wt_format._matchingbzrdir,
426
'transport_readonly_server': 'b',
427
'transport_server': 'a',
428
'workingtree_format': default_wt_format}),
430
self.assertEqual(expected_scenarios, scenarios)
433
class TestInterTreeScenarios(tests.TestCase):
434
"""A group of tests that test the InterTreeTestAdapter."""
436
def test_scenarios(self):
437
# check that constructor parameters are passed through to the adapted
439
# for InterTree tests we want the machinery to bring up two trees in
440
# each instance: the base one, and the one we are interacting with.
441
# because each optimiser can be direction specific, we need to test
442
# each optimiser in its chosen direction.
443
# unlike the TestProviderAdapter we dont want to automatically add a
444
# parameterized one for WorkingTree - the optimisers will tell us what
446
from bzrlib.tests.per_tree import (
449
from bzrlib.tests.per_intertree import (
452
from bzrlib.workingtree_3 import WorkingTreeFormat3
453
from bzrlib.workingtree_4 import WorkingTreeFormat4
454
input_test = TestInterTreeScenarios(
458
format1 = WorkingTreeFormat4()
459
format2 = WorkingTreeFormat3()
460
formats = [("1", str, format1, format2, "converter1"),
461
("2", int, format2, format1, "converter2")]
462
scenarios = make_scenarios(server1, server2, formats)
463
self.assertEqual(2, len(scenarios))
464
expected_scenarios = [
466
"bzrdir_format": format1._matchingbzrdir,
467
"intertree_class": formats[0][1],
468
"workingtree_format": formats[0][2],
469
"workingtree_format_to": formats[0][3],
470
"mutable_trees_to_test_trees": formats[0][4],
471
"_workingtree_to_test_tree": return_parameter,
472
"transport_server": server1,
473
"transport_readonly_server": server2,
476
"bzrdir_format": format2._matchingbzrdir,
477
"intertree_class": formats[1][1],
478
"workingtree_format": formats[1][2],
479
"workingtree_format_to": formats[1][3],
480
"mutable_trees_to_test_trees": formats[1][4],
481
"_workingtree_to_test_tree": return_parameter,
482
"transport_server": server1,
483
"transport_readonly_server": server2,
486
self.assertEqual(scenarios, expected_scenarios)
489
class TestTestCaseInTempDir(tests.TestCaseInTempDir):
491
def test_home_is_not_working(self):
492
self.assertNotEqual(self.test_dir, self.test_home_dir)
493
cwd = osutils.getcwd()
494
self.assertIsSameRealPath(self.test_dir, cwd)
495
self.assertIsSameRealPath(self.test_home_dir, os.environ['HOME'])
497
def test_assertEqualStat_equal(self):
498
from bzrlib.tests.test_dirstate import _FakeStat
499
self.build_tree(["foo"])
500
real = os.lstat("foo")
501
fake = _FakeStat(real.st_size, real.st_mtime, real.st_ctime,
502
real.st_dev, real.st_ino, real.st_mode)
503
self.assertEqualStat(real, fake)
505
def test_assertEqualStat_notequal(self):
506
self.build_tree(["foo", "longname"])
507
self.assertRaises(AssertionError, self.assertEqualStat,
508
os.lstat("foo"), os.lstat("longname"))
510
def test_failUnlessExists(self):
511
"""Deprecated failUnlessExists and failIfExists"""
512
self.applyDeprecated(
513
deprecated_in((2, 4)),
514
self.failUnlessExists, '.')
515
self.build_tree(['foo/', 'foo/bar'])
516
self.applyDeprecated(
517
deprecated_in((2, 4)),
518
self.failUnlessExists, 'foo/bar')
519
self.applyDeprecated(
520
deprecated_in((2, 4)),
521
self.failIfExists, 'foo/foo')
523
def test_assertPathExists(self):
524
self.assertPathExists('.')
525
self.build_tree(['foo/', 'foo/bar'])
526
self.assertPathExists('foo/bar')
527
self.assertPathDoesNotExist('foo/foo')
530
class TestTestCaseWithMemoryTransport(tests.TestCaseWithMemoryTransport):
532
def test_home_is_non_existant_dir_under_root(self):
533
"""The test_home_dir for TestCaseWithMemoryTransport is missing.
535
This is because TestCaseWithMemoryTransport is for tests that do not
536
need any disk resources: they should be hooked into bzrlib in such a
537
way that no global settings are being changed by the test (only a
538
few tests should need to do that), and having a missing dir as home is
539
an effective way to ensure that this is the case.
541
self.assertIsSameRealPath(
542
self.TEST_ROOT + "/MemoryTransportMissingHomeDir",
544
self.assertIsSameRealPath(self.test_home_dir, os.environ['HOME'])
546
def test_cwd_is_TEST_ROOT(self):
547
self.assertIsSameRealPath(self.test_dir, self.TEST_ROOT)
548
cwd = osutils.getcwd()
549
self.assertIsSameRealPath(self.test_dir, cwd)
551
def test_BZR_HOME_and_HOME_are_bytestrings(self):
552
"""The $BZR_HOME and $HOME environment variables should not be unicode.
554
See https://bugs.launchpad.net/bzr/+bug/464174
556
self.assertIsInstance(os.environ['BZR_HOME'], str)
557
self.assertIsInstance(os.environ['HOME'], str)
559
def test_make_branch_and_memory_tree(self):
560
"""In TestCaseWithMemoryTransport we should not make the branch on disk.
562
This is hard to comprehensively robustly test, so we settle for making
563
a branch and checking no directory was created at its relpath.
565
tree = self.make_branch_and_memory_tree('dir')
566
# Guard against regression into MemoryTransport leaking
567
# files to disk instead of keeping them in memory.
568
self.assertFalse(osutils.lexists('dir'))
569
self.assertIsInstance(tree, memorytree.MemoryTree)
571
def test_make_branch_and_memory_tree_with_format(self):
572
"""make_branch_and_memory_tree should accept a format option."""
573
format = bzrdir.BzrDirMetaFormat1()
574
format.repository_format = repository.format_registry.get_default()
575
tree = self.make_branch_and_memory_tree('dir', format=format)
576
# Guard against regression into MemoryTransport leaking
577
# files to disk instead of keeping them in memory.
578
self.assertFalse(osutils.lexists('dir'))
579
self.assertIsInstance(tree, memorytree.MemoryTree)
580
self.assertEqual(format.repository_format.__class__,
581
tree.branch.repository._format.__class__)
583
def test_make_branch_builder(self):
584
builder = self.make_branch_builder('dir')
585
self.assertIsInstance(builder, branchbuilder.BranchBuilder)
586
# Guard against regression into MemoryTransport leaking
587
# files to disk instead of keeping them in memory.
588
self.assertFalse(osutils.lexists('dir'))
590
def test_make_branch_builder_with_format(self):
591
# Use a repo layout that doesn't conform to a 'named' layout, to ensure
592
# that the format objects are used.
593
format = bzrdir.BzrDirMetaFormat1()
594
repo_format = repository.format_registry.get_default()
595
format.repository_format = repo_format
596
builder = self.make_branch_builder('dir', format=format)
597
the_branch = builder.get_branch()
598
# Guard against regression into MemoryTransport leaking
599
# files to disk instead of keeping them in memory.
600
self.assertFalse(osutils.lexists('dir'))
601
self.assertEqual(format.repository_format.__class__,
602
the_branch.repository._format.__class__)
603
self.assertEqual(repo_format.get_format_string(),
604
self.get_transport().get_bytes(
605
'dir/.bzr/repository/format'))
607
def test_make_branch_builder_with_format_name(self):
608
builder = self.make_branch_builder('dir', format='knit')
609
the_branch = builder.get_branch()
610
# Guard against regression into MemoryTransport leaking
611
# files to disk instead of keeping them in memory.
612
self.assertFalse(osutils.lexists('dir'))
613
dir_format = controldir.format_registry.make_bzrdir('knit')
614
self.assertEqual(dir_format.repository_format.__class__,
615
the_branch.repository._format.__class__)
616
self.assertEqual('Bazaar-NG Knit Repository Format 1',
617
self.get_transport().get_bytes(
618
'dir/.bzr/repository/format'))
620
def test_dangling_locks_cause_failures(self):
621
class TestDanglingLock(tests.TestCaseWithMemoryTransport):
622
def test_function(self):
623
t = self.get_transport_from_path('.')
624
l = lockdir.LockDir(t, 'lock')
627
test = TestDanglingLock('test_function')
629
total_failures = result.errors + result.failures
630
if self._lock_check_thorough:
631
self.assertEqual(1, len(total_failures))
633
# When _lock_check_thorough is disabled, then we don't trigger a
635
self.assertEqual(0, len(total_failures))
638
class TestTestCaseWithTransport(tests.TestCaseWithTransport):
639
"""Tests for the convenience functions TestCaseWithTransport introduces."""
641
def test_get_readonly_url_none(self):
642
from bzrlib.transport.readonly import ReadonlyTransportDecorator
643
self.vfs_transport_factory = memory.MemoryServer
644
self.transport_readonly_server = None
645
# calling get_readonly_transport() constructs a decorator on the url
647
url = self.get_readonly_url()
648
url2 = self.get_readonly_url('foo/bar')
649
t = transport.get_transport_from_url(url)
650
t2 = transport.get_transport_from_url(url2)
651
self.assertIsInstance(t, ReadonlyTransportDecorator)
652
self.assertIsInstance(t2, ReadonlyTransportDecorator)
653
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
655
def test_get_readonly_url_http(self):
656
from bzrlib.tests.http_server import HttpServer
657
from bzrlib.transport.http import HttpTransportBase
658
self.transport_server = test_server.LocalURLServer
659
self.transport_readonly_server = HttpServer
660
# calling get_readonly_transport() gives us a HTTP server instance.
661
url = self.get_readonly_url()
662
url2 = self.get_readonly_url('foo/bar')
663
# the transport returned may be any HttpTransportBase subclass
664
t = transport.get_transport_from_url(url)
665
t2 = transport.get_transport_from_url(url2)
666
self.assertIsInstance(t, HttpTransportBase)
667
self.assertIsInstance(t2, HttpTransportBase)
668
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
670
def test_is_directory(self):
671
"""Test assertIsDirectory assertion"""
672
t = self.get_transport()
673
self.build_tree(['a_dir/', 'a_file'], transport=t)
674
self.assertIsDirectory('a_dir', t)
675
self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
676
self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
678
def test_make_branch_builder(self):
679
builder = self.make_branch_builder('dir')
680
rev_id = builder.build_commit()
681
self.assertPathExists('dir')
682
a_dir = controldir.ControlDir.open('dir')
683
self.assertRaises(errors.NoWorkingTree, a_dir.open_workingtree)
684
a_branch = a_dir.open_branch()
685
builder_branch = builder.get_branch()
686
self.assertEqual(a_branch.base, builder_branch.base)
687
self.assertEqual((1, rev_id), builder_branch.last_revision_info())
688
self.assertEqual((1, rev_id), a_branch.last_revision_info())
691
class TestTestCaseTransports(tests.TestCaseWithTransport):
694
super(TestTestCaseTransports, self).setUp()
695
self.vfs_transport_factory = memory.MemoryServer
697
def test_make_bzrdir_preserves_transport(self):
698
t = self.get_transport()
699
result_bzrdir = self.make_bzrdir('subdir')
700
self.assertIsInstance(result_bzrdir.transport,
701
memory.MemoryTransport)
702
# should not be on disk, should only be in memory
703
self.assertPathDoesNotExist('subdir')
706
class TestChrootedTest(tests.ChrootedTestCase):
708
def test_root_is_root(self):
709
t = transport.get_transport_from_url(self.get_readonly_url())
711
self.assertEqual(url, t.clone('..').base)
714
class TestProfileResult(tests.TestCase):
716
def test_profiles_tests(self):
717
self.requireFeature(features.lsprof_feature)
718
terminal = testtools.testresult.doubles.ExtendedTestResult()
719
result = tests.ProfileResult(terminal)
720
class Sample(tests.TestCase):
722
self.sample_function()
723
def sample_function(self):
727
case = terminal._events[0][1]
728
self.assertLength(1, case._benchcalls)
729
# We must be able to unpack it as the test reporting code wants
730
(_, _, _), stats = case._benchcalls[0]
731
self.assertTrue(callable(stats.pprint))
734
class TestTestResult(tests.TestCase):
736
def check_timing(self, test_case, expected_re):
737
result = bzrlib.tests.TextTestResult(self._log_file,
741
capture = testtools.testresult.doubles.ExtendedTestResult()
742
test_case.run(MultiTestResult(result, capture))
743
run_case = capture._events[0][1]
744
timed_string = result._testTimeString(run_case)
745
self.assertContainsRe(timed_string, expected_re)
747
def test_test_reporting(self):
748
class ShortDelayTestCase(tests.TestCase):
749
def test_short_delay(self):
751
def test_short_benchmark(self):
752
self.time(time.sleep, 0.003)
753
self.check_timing(ShortDelayTestCase('test_short_delay'),
755
# if a benchmark time is given, we now show just that time followed by
757
self.check_timing(ShortDelayTestCase('test_short_benchmark'),
760
def test_unittest_reporting_unittest_class(self):
761
# getting the time from a non-bzrlib test works ok
762
class ShortDelayTestCase(unittest.TestCase):
763
def test_short_delay(self):
765
self.check_timing(ShortDelayTestCase('test_short_delay'),
768
def _time_hello_world_encoding(self):
769
"""Profile two sleep calls
771
This is used to exercise the test framework.
773
self.time(unicode, 'hello', errors='replace')
774
self.time(unicode, 'world', errors='replace')
776
def test_lsprofiling(self):
777
"""Verbose test result prints lsprof statistics from test cases."""
778
self.requireFeature(features.lsprof_feature)
779
result_stream = StringIO()
780
result = bzrlib.tests.VerboseTestResult(
785
# we want profile a call of some sort and check it is output by
786
# addSuccess. We dont care about addError or addFailure as they
787
# are not that interesting for performance tuning.
788
# make a new test instance that when run will generate a profile
789
example_test_case = TestTestResult("_time_hello_world_encoding")
790
example_test_case._gather_lsprof_in_benchmarks = True
791
# execute the test, which should succeed and record profiles
792
example_test_case.run(result)
793
# lsprofile_something()
794
# if this worked we want
795
# LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
796
# CallCount Recursive Total(ms) Inline(ms) module:lineno(function)
797
# (the lsprof header)
798
# ... an arbitrary number of lines
799
# and the function call which is time.sleep.
800
# 1 0 ??? ??? ???(sleep)
801
# and then repeated but with 'world', rather than 'hello'.
802
# this should appear in the output stream of our test result.
803
output = result_stream.getvalue()
804
self.assertContainsRe(output,
805
r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
806
self.assertContainsRe(output,
807
r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
808
self.assertContainsRe(output,
809
r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
810
self.assertContainsRe(output,
811
r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
813
def test_uses_time_from_testtools(self):
814
"""Test case timings in verbose results should use testtools times"""
816
class TimeAddedVerboseTestResult(tests.VerboseTestResult):
817
def startTest(self, test):
818
self.time(datetime.datetime.utcfromtimestamp(1.145))
819
super(TimeAddedVerboseTestResult, self).startTest(test)
820
def addSuccess(self, test):
821
self.time(datetime.datetime.utcfromtimestamp(51.147))
822
super(TimeAddedVerboseTestResult, self).addSuccess(test)
823
def report_tests_starting(self): pass
825
self.get_passing_test().run(TimeAddedVerboseTestResult(sio, 0, 2))
826
self.assertEndsWith(sio.getvalue(), "OK 50002ms\n")
828
def test_known_failure(self):
829
"""Using knownFailure should trigger several result actions."""
830
class InstrumentedTestResult(tests.ExtendedTestResult):
831
def stopTestRun(self): pass
832
def report_tests_starting(self): pass
833
def report_known_failure(self, test, err=None, details=None):
834
self._call = test, 'known failure'
835
result = InstrumentedTestResult(None, None, None, None)
836
class Test(tests.TestCase):
837
def test_function(self):
838
self.knownFailure('failed!')
839
test = Test("test_function")
841
# it should invoke 'report_known_failure'.
842
self.assertEqual(2, len(result._call))
843
self.assertEqual(test.id(), result._call[0].id())
844
self.assertEqual('known failure', result._call[1])
845
# we dont introspec the traceback, if the rest is ok, it would be
846
# exceptional for it not to be.
847
# it should update the known_failure_count on the object.
848
self.assertEqual(1, result.known_failure_count)
849
# the result should be successful.
850
self.assertTrue(result.wasSuccessful())
852
def test_verbose_report_known_failure(self):
853
# verbose test output formatting
854
result_stream = StringIO()
855
result = bzrlib.tests.VerboseTestResult(
860
_get_test("test_xfail").run(result)
861
self.assertContainsRe(result_stream.getvalue(),
862
"\n\\S+\\.test_xfail\\s+XFAIL\\s+\\d+ms\n"
863
"\\s*(?:Text attachment: )?reason"
868
def get_passing_test(self):
869
"""Return a test object that can't be run usefully."""
872
return unittest.FunctionTestCase(passing_test)
874
def test_add_not_supported(self):
875
"""Test the behaviour of invoking addNotSupported."""
876
class InstrumentedTestResult(tests.ExtendedTestResult):
877
def stopTestRun(self): pass
878
def report_tests_starting(self): pass
879
def report_unsupported(self, test, feature):
880
self._call = test, feature
881
result = InstrumentedTestResult(None, None, None, None)
882
test = SampleTestCase('_test_pass')
883
feature = features.Feature()
884
result.startTest(test)
885
result.addNotSupported(test, feature)
886
# it should invoke 'report_unsupported'.
887
self.assertEqual(2, len(result._call))
888
self.assertEqual(test, result._call[0])
889
self.assertEqual(feature, result._call[1])
890
# the result should be successful.
891
self.assertTrue(result.wasSuccessful())
892
# it should record the test against a count of tests not run due to
894
self.assertEqual(1, result.unsupported['Feature'])
895
# and invoking it again should increment that counter
896
result.addNotSupported(test, feature)
897
self.assertEqual(2, result.unsupported['Feature'])
899
def test_verbose_report_unsupported(self):
900
# verbose test output formatting
901
result_stream = StringIO()
902
result = bzrlib.tests.VerboseTestResult(
907
test = self.get_passing_test()
908
feature = features.Feature()
909
result.startTest(test)
910
prefix = len(result_stream.getvalue())
911
result.report_unsupported(test, feature)
912
output = result_stream.getvalue()[prefix:]
913
lines = output.splitlines()
914
# We don't check for the final '0ms' since it may fail on slow hosts
915
self.assertStartsWith(lines[0], 'NODEP')
916
self.assertEqual(lines[1],
917
" The feature 'Feature' is not available.")
919
def test_unavailable_exception(self):
920
"""An UnavailableFeature being raised should invoke addNotSupported."""
921
class InstrumentedTestResult(tests.ExtendedTestResult):
922
def stopTestRun(self): pass
923
def report_tests_starting(self): pass
924
def addNotSupported(self, test, feature):
925
self._call = test, feature
926
result = InstrumentedTestResult(None, None, None, None)
927
feature = features.Feature()
928
class Test(tests.TestCase):
929
def test_function(self):
930
raise tests.UnavailableFeature(feature)
931
test = Test("test_function")
933
# it should invoke 'addNotSupported'.
934
self.assertEqual(2, len(result._call))
935
self.assertEqual(test.id(), result._call[0].id())
936
self.assertEqual(feature, result._call[1])
937
# and not count as an error
938
self.assertEqual(0, result.error_count)
940
def test_strict_with_unsupported_feature(self):
941
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
943
test = self.get_passing_test()
944
feature = "Unsupported Feature"
945
result.addNotSupported(test, feature)
946
self.assertFalse(result.wasStrictlySuccessful())
947
self.assertEqual(None, result._extractBenchmarkTime(test))
949
def test_strict_with_known_failure(self):
950
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
952
test = _get_test("test_xfail")
954
self.assertFalse(result.wasStrictlySuccessful())
955
self.assertEqual(None, result._extractBenchmarkTime(test))
957
def test_strict_with_success(self):
958
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
960
test = self.get_passing_test()
961
result.addSuccess(test)
962
self.assertTrue(result.wasStrictlySuccessful())
963
self.assertEqual(None, result._extractBenchmarkTime(test))
965
def test_startTests(self):
966
"""Starting the first test should trigger startTests."""
967
class InstrumentedTestResult(tests.ExtendedTestResult):
969
def startTests(self): self.calls += 1
970
result = InstrumentedTestResult(None, None, None, None)
973
test = unittest.FunctionTestCase(test_function)
975
self.assertEquals(1, result.calls)
977
def test_startTests_only_once(self):
978
"""With multiple tests startTests should still only be called once"""
979
class InstrumentedTestResult(tests.ExtendedTestResult):
981
def startTests(self): self.calls += 1
982
result = InstrumentedTestResult(None, None, None, None)
983
suite = unittest.TestSuite([
984
unittest.FunctionTestCase(lambda: None),
985
unittest.FunctionTestCase(lambda: None)])
987
self.assertEquals(1, result.calls)
988
self.assertEquals(2, result.count)
991
class TestRunner(tests.TestCase):
993
def dummy_test(self):
996
def run_test_runner(self, testrunner, test):
997
"""Run suite in testrunner, saving global state and restoring it.
999
This current saves and restores:
1000
TestCaseInTempDir.TEST_ROOT
1002
There should be no tests in this file that use
1003
bzrlib.tests.TextTestRunner without using this convenience method,
1004
because of our use of global state.
1006
old_root = tests.TestCaseInTempDir.TEST_ROOT
1008
tests.TestCaseInTempDir.TEST_ROOT = None
1009
return testrunner.run(test)
1011
tests.TestCaseInTempDir.TEST_ROOT = old_root
1013
def test_known_failure_failed_run(self):
1014
# run a test that generates a known failure which should be printed in
1015
# the final output when real failures occur.
1016
class Test(tests.TestCase):
1017
def known_failure_test(self):
1018
self.expectFailure('failed', self.assertTrue, False)
1019
test = unittest.TestSuite()
1020
test.addTest(Test("known_failure_test"))
1022
raise AssertionError('foo')
1023
test.addTest(unittest.FunctionTestCase(failing_test))
1025
runner = tests.TextTestRunner(stream=stream)
1026
result = self.run_test_runner(runner, test)
1027
lines = stream.getvalue().splitlines()
1028
self.assertContainsRe(stream.getvalue(),
1029
'(?sm)^bzr selftest.*$'
1031
'^======================================================================\n'
1032
'^FAIL: failing_test\n'
1033
'^----------------------------------------------------------------------\n'
1034
'Traceback \\(most recent call last\\):\n'
1035
' .*' # File .*, line .*, in failing_test' - but maybe not from .pyc
1036
' raise AssertionError\\(\'foo\'\\)\n'
1038
'^----------------------------------------------------------------------\n'
1040
'FAILED \\(failures=1, known_failure_count=1\\)'
1043
def test_known_failure_ok_run(self):
1044
# run a test that generates a known failure which should be printed in
1046
class Test(tests.TestCase):
1047
def known_failure_test(self):
1048
self.knownFailure("Never works...")
1049
test = Test("known_failure_test")
1051
runner = tests.TextTestRunner(stream=stream)
1052
result = self.run_test_runner(runner, test)
1053
self.assertContainsRe(stream.getvalue(),
1056
'Ran 1 test in .*\n'
1058
'OK \\(known_failures=1\\)\n')
1060
def test_unexpected_success_bad(self):
1061
class Test(tests.TestCase):
1062
def test_truth(self):
1063
self.expectFailure("No absolute truth", self.assertTrue, True)
1064
runner = tests.TextTestRunner(stream=StringIO())
1065
result = self.run_test_runner(runner, Test("test_truth"))
1066
self.assertContainsRe(runner.stream.getvalue(),
1068
"FAIL: \\S+\.test_truth\n"
1071
"\\s*(?:Text attachment: )?reason"
1077
"Ran 1 test in .*\n"
1079
"FAILED \\(failures=1\\)\n\\Z")
1081
def test_result_decorator(self):
1084
class LoggingDecorator(ExtendedToOriginalDecorator):
1085
def startTest(self, test):
1086
ExtendedToOriginalDecorator.startTest(self, test)
1087
calls.append('start')
1088
test = unittest.FunctionTestCase(lambda:None)
1090
runner = tests.TextTestRunner(stream=stream,
1091
result_decorators=[LoggingDecorator])
1092
result = self.run_test_runner(runner, test)
1093
self.assertLength(1, calls)
1095
def test_skipped_test(self):
1096
# run a test that is skipped, and check the suite as a whole still
1098
# skipping_test must be hidden in here so it's not run as a real test
1099
class SkippingTest(tests.TestCase):
1100
def skipping_test(self):
1101
raise tests.TestSkipped('test intentionally skipped')
1102
runner = tests.TextTestRunner(stream=self._log_file)
1103
test = SkippingTest("skipping_test")
1104
result = self.run_test_runner(runner, test)
1105
self.assertTrue(result.wasSuccessful())
1107
def test_skipped_from_setup(self):
1109
class SkippedSetupTest(tests.TestCase):
1112
calls.append('setUp')
1113
self.addCleanup(self.cleanup)
1114
raise tests.TestSkipped('skipped setup')
1116
def test_skip(self):
1117
self.fail('test reached')
1120
calls.append('cleanup')
1122
runner = tests.TextTestRunner(stream=self._log_file)
1123
test = SkippedSetupTest('test_skip')
1124
result = self.run_test_runner(runner, test)
1125
self.assertTrue(result.wasSuccessful())
1126
# Check if cleanup was called the right number of times.
1127
self.assertEqual(['setUp', 'cleanup'], calls)
1129
def test_skipped_from_test(self):
1131
class SkippedTest(tests.TestCase):
1134
tests.TestCase.setUp(self)
1135
calls.append('setUp')
1136
self.addCleanup(self.cleanup)
1138
def test_skip(self):
1139
raise tests.TestSkipped('skipped test')
1142
calls.append('cleanup')
1144
runner = tests.TextTestRunner(stream=self._log_file)
1145
test = SkippedTest('test_skip')
1146
result = self.run_test_runner(runner, test)
1147
self.assertTrue(result.wasSuccessful())
1148
# Check if cleanup was called the right number of times.
1149
self.assertEqual(['setUp', 'cleanup'], calls)
1151
def test_not_applicable(self):
1152
# run a test that is skipped because it's not applicable
1153
class Test(tests.TestCase):
1154
def not_applicable_test(self):
1155
raise tests.TestNotApplicable('this test never runs')
1157
runner = tests.TextTestRunner(stream=out, verbosity=2)
1158
test = Test("not_applicable_test")
1159
result = self.run_test_runner(runner, test)
1160
self._log_file.write(out.getvalue())
1161
self.assertTrue(result.wasSuccessful())
1162
self.assertTrue(result.wasStrictlySuccessful())
1163
self.assertContainsRe(out.getvalue(),
1164
r'(?m)not_applicable_test * N/A')
1165
self.assertContainsRe(out.getvalue(),
1166
r'(?m)^ this test never runs')
1168
def test_unsupported_features_listed(self):
1169
"""When unsupported features are encountered they are detailed."""
1170
class Feature1(features.Feature):
1171
def _probe(self): return False
1172
class Feature2(features.Feature):
1173
def _probe(self): return False
1174
# create sample tests
1175
test1 = SampleTestCase('_test_pass')
1176
test1._test_needs_features = [Feature1()]
1177
test2 = SampleTestCase('_test_pass')
1178
test2._test_needs_features = [Feature2()]
1179
test = unittest.TestSuite()
1183
runner = tests.TextTestRunner(stream=stream)
1184
result = self.run_test_runner(runner, test)
1185
lines = stream.getvalue().splitlines()
1188
"Missing feature 'Feature1' skipped 1 tests.",
1189
"Missing feature 'Feature2' skipped 1 tests.",
1193
def test_verbose_test_count(self):
1194
"""A verbose test run reports the right test count at the start"""
1195
suite = TestUtil.TestSuite([
1196
unittest.FunctionTestCase(lambda:None),
1197
unittest.FunctionTestCase(lambda:None)])
1198
self.assertEqual(suite.countTestCases(), 2)
1200
runner = tests.TextTestRunner(stream=stream, verbosity=2)
1201
# Need to use the CountingDecorator as that's what sets num_tests
1202
result = self.run_test_runner(runner, tests.CountingDecorator(suite))
1203
self.assertStartsWith(stream.getvalue(), "running 2 tests")
1205
def test_startTestRun(self):
1206
"""run should call result.startTestRun()"""
1208
class LoggingDecorator(ExtendedToOriginalDecorator):
1209
def startTestRun(self):
1210
ExtendedToOriginalDecorator.startTestRun(self)
1211
calls.append('startTestRun')
1212
test = unittest.FunctionTestCase(lambda:None)
1214
runner = tests.TextTestRunner(stream=stream,
1215
result_decorators=[LoggingDecorator])
1216
result = self.run_test_runner(runner, test)
1217
self.assertLength(1, calls)
1219
def test_stopTestRun(self):
1220
"""run should call result.stopTestRun()"""
1222
class LoggingDecorator(ExtendedToOriginalDecorator):
1223
def stopTestRun(self):
1224
ExtendedToOriginalDecorator.stopTestRun(self)
1225
calls.append('stopTestRun')
1226
test = unittest.FunctionTestCase(lambda:None)
1228
runner = tests.TextTestRunner(stream=stream,
1229
result_decorators=[LoggingDecorator])
1230
result = self.run_test_runner(runner, test)
1231
self.assertLength(1, calls)
1233
def test_unicode_test_output_on_ascii_stream(self):
1234
"""Showing results should always succeed even on an ascii console"""
1235
class FailureWithUnicode(tests.TestCase):
1236
def test_log_unicode(self):
1238
self.fail("Now print that log!")
1240
self.overrideAttr(osutils, "get_terminal_encoding",
1241
lambda trace=False: "ascii")
1242
result = self.run_test_runner(tests.TextTestRunner(stream=out),
1243
FailureWithUnicode("test_log_unicode"))
1244
self.assertContainsRe(out.getvalue(),
1245
"(?:Text attachment: )?log"
1247
"\d+\.\d+ \\\\u2606"
1251
class SampleTestCase(tests.TestCase):
1253
def _test_pass(self):
1256
class _TestException(Exception):
1260
class TestTestCase(tests.TestCase):
1261
"""Tests that test the core bzrlib TestCase."""
1263
def test_assertLength_matches_empty(self):
1265
self.assertLength(0, a_list)
1267
def test_assertLength_matches_nonempty(self):
1269
self.assertLength(3, a_list)
1271
def test_assertLength_fails_different(self):
1273
self.assertRaises(AssertionError, self.assertLength, 1, a_list)
1275
def test_assertLength_shows_sequence_in_failure(self):
1277
exception = self.assertRaises(AssertionError, self.assertLength, 2,
1279
self.assertEqual('Incorrect length: wanted 2, got 3 for [1, 2, 3]',
1282
def test_base_setUp_not_called_causes_failure(self):
1283
class TestCaseWithBrokenSetUp(tests.TestCase):
1285
pass # does not call TestCase.setUp
1288
test = TestCaseWithBrokenSetUp('test_foo')
1289
result = unittest.TestResult()
1291
self.assertFalse(result.wasSuccessful())
1292
self.assertEqual(1, result.testsRun)
1294
def test_base_tearDown_not_called_causes_failure(self):
1295
class TestCaseWithBrokenTearDown(tests.TestCase):
1297
pass # does not call TestCase.tearDown
1300
test = TestCaseWithBrokenTearDown('test_foo')
1301
result = unittest.TestResult()
1303
self.assertFalse(result.wasSuccessful())
1304
self.assertEqual(1, result.testsRun)
1306
def test_debug_flags_sanitised(self):
1307
"""The bzrlib debug flags should be sanitised by setUp."""
1308
if 'allow_debug' in tests.selftest_debug_flags:
1309
raise tests.TestNotApplicable(
1310
'-Eallow_debug option prevents debug flag sanitisation')
1311
# we could set something and run a test that will check
1312
# it gets santised, but this is probably sufficient for now:
1313
# if someone runs the test with -Dsomething it will error.
1315
if self._lock_check_thorough:
1316
flags.add('strict_locks')
1317
self.assertEqual(flags, bzrlib.debug.debug_flags)
1319
def change_selftest_debug_flags(self, new_flags):
1320
self.overrideAttr(tests, 'selftest_debug_flags', set(new_flags))
1322
def test_allow_debug_flag(self):
1323
"""The -Eallow_debug flag prevents bzrlib.debug.debug_flags from being
1324
sanitised (i.e. cleared) before running a test.
1326
self.change_selftest_debug_flags(set(['allow_debug']))
1327
bzrlib.debug.debug_flags = set(['a-flag'])
1328
class TestThatRecordsFlags(tests.TestCase):
1329
def test_foo(nested_self):
1330
self.flags = set(bzrlib.debug.debug_flags)
1331
test = TestThatRecordsFlags('test_foo')
1332
test.run(self.make_test_result())
1333
flags = set(['a-flag'])
1334
if 'disable_lock_checks' not in tests.selftest_debug_flags:
1335
flags.add('strict_locks')
1336
self.assertEqual(flags, self.flags)
1338
def test_disable_lock_checks(self):
1339
"""The -Edisable_lock_checks flag disables thorough checks."""
1340
class TestThatRecordsFlags(tests.TestCase):
1341
def test_foo(nested_self):
1342
self.flags = set(bzrlib.debug.debug_flags)
1343
self.test_lock_check_thorough = nested_self._lock_check_thorough
1344
self.change_selftest_debug_flags(set())
1345
test = TestThatRecordsFlags('test_foo')
1346
test.run(self.make_test_result())
1347
# By default we do strict lock checking and thorough lock/unlock
1349
self.assertTrue(self.test_lock_check_thorough)
1350
self.assertEqual(set(['strict_locks']), self.flags)
1351
# Now set the disable_lock_checks flag, and show that this changed.
1352
self.change_selftest_debug_flags(set(['disable_lock_checks']))
1353
test = TestThatRecordsFlags('test_foo')
1354
test.run(self.make_test_result())
1355
self.assertFalse(self.test_lock_check_thorough)
1356
self.assertEqual(set(), self.flags)
1358
def test_this_fails_strict_lock_check(self):
1359
class TestThatRecordsFlags(tests.TestCase):
1360
def test_foo(nested_self):
1361
self.flags1 = set(bzrlib.debug.debug_flags)
1362
self.thisFailsStrictLockCheck()
1363
self.flags2 = set(bzrlib.debug.debug_flags)
1364
# Make sure lock checking is active
1365
self.change_selftest_debug_flags(set())
1366
test = TestThatRecordsFlags('test_foo')
1367
test.run(self.make_test_result())
1368
self.assertEqual(set(['strict_locks']), self.flags1)
1369
self.assertEqual(set(), self.flags2)
1371
def test_debug_flags_restored(self):
1372
"""The bzrlib debug flags should be restored to their original state
1373
after the test was run, even if allow_debug is set.
1375
self.change_selftest_debug_flags(set(['allow_debug']))
1376
# Now run a test that modifies debug.debug_flags.
1377
bzrlib.debug.debug_flags = set(['original-state'])
1378
class TestThatModifiesFlags(tests.TestCase):
1380
bzrlib.debug.debug_flags = set(['modified'])
1381
test = TestThatModifiesFlags('test_foo')
1382
test.run(self.make_test_result())
1383
self.assertEqual(set(['original-state']), bzrlib.debug.debug_flags)
1385
def make_test_result(self):
1386
"""Get a test result that writes to the test log file."""
1387
return tests.TextTestResult(self._log_file, descriptions=0, verbosity=1)
1389
def inner_test(self):
1390
# the inner child test
1393
def outer_child(self):
1394
# the outer child test
1396
self.inner_test = TestTestCase("inner_child")
1397
result = self.make_test_result()
1398
self.inner_test.run(result)
1399
note("outer finish")
1400
self.addCleanup(osutils.delete_any, self._log_file_name)
1402
def test_trace_nesting(self):
1403
# this tests that each test case nests its trace facility correctly.
1404
# we do this by running a test case manually. That test case (A)
1405
# should setup a new log, log content to it, setup a child case (B),
1406
# which should log independently, then case (A) should log a trailer
1408
# we do two nested children so that we can verify the state of the
1409
# logs after the outer child finishes is correct, which a bad clean
1410
# up routine in tearDown might trigger a fault in our test with only
1411
# one child, we should instead see the bad result inside our test with
1413
# the outer child test
1414
original_trace = bzrlib.trace._trace_file
1415
outer_test = TestTestCase("outer_child")
1416
result = self.make_test_result()
1417
outer_test.run(result)
1418
self.assertEqual(original_trace, bzrlib.trace._trace_file)
1420
def method_that_times_a_bit_twice(self):
1421
# call self.time twice to ensure it aggregates
1422
self.time(time.sleep, 0.007)
1423
self.time(time.sleep, 0.007)
1425
def test_time_creates_benchmark_in_result(self):
1426
"""Test that the TestCase.time() method accumulates a benchmark time."""
1427
sample_test = TestTestCase("method_that_times_a_bit_twice")
1428
output_stream = StringIO()
1429
result = bzrlib.tests.VerboseTestResult(
1433
sample_test.run(result)
1434
self.assertContainsRe(
1435
output_stream.getvalue(),
1438
def test_hooks_sanitised(self):
1439
"""The bzrlib hooks should be sanitised by setUp."""
1440
# Note this test won't fail with hooks that the core library doesn't
1441
# use - but it trigger with a plugin that adds hooks, so its still a
1442
# useful warning in that case.
1443
self.assertEqual(bzrlib.branch.BranchHooks(), bzrlib.branch.Branch.hooks)
1445
bzrlib.smart.server.SmartServerHooks(),
1446
bzrlib.smart.server.SmartTCPServer.hooks)
1448
bzrlib.commands.CommandHooks(), bzrlib.commands.Command.hooks)
1450
def test__gather_lsprof_in_benchmarks(self):
1451
"""When _gather_lsprof_in_benchmarks is on, accumulate profile data.
1453
Each self.time() call is individually and separately profiled.
1455
self.requireFeature(features.lsprof_feature)
1456
# overrides the class member with an instance member so no cleanup
1458
self._gather_lsprof_in_benchmarks = True
1459
self.time(time.sleep, 0.000)
1460
self.time(time.sleep, 0.003)
1461
self.assertEqual(2, len(self._benchcalls))
1462
self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
1463
self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
1464
self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
1465
self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
1466
del self._benchcalls[:]
1468
def test_knownFailure(self):
1469
"""Self.knownFailure() should raise a KnownFailure exception."""
1470
self.assertRaises(tests.KnownFailure, self.knownFailure, "A Failure")
1472
def test_open_bzrdir_safe_roots(self):
1473
# even a memory transport should fail to open when its url isn't
1475
# Manually set one up (TestCase doesn't and shouldn't provide magic
1477
transport_server = memory.MemoryServer()
1478
transport_server.start_server()
1479
self.addCleanup(transport_server.stop_server)
1480
t = transport.get_transport_from_url(transport_server.get_url())
1481
controldir.ControlDir.create(t.base)
1482
self.assertRaises(errors.BzrError,
1483
controldir.ControlDir.open_from_transport, t)
1484
# But if we declare this as safe, we can open the bzrdir.
1485
self.permit_url(t.base)
1486
self._bzr_selftest_roots.append(t.base)
1487
controldir.ControlDir.open_from_transport(t)
1489
def test_requireFeature_available(self):
1490
"""self.requireFeature(available) is a no-op."""
1491
class Available(features.Feature):
1492
def _probe(self):return True
1493
feature = Available()
1494
self.requireFeature(feature)
1496
def test_requireFeature_unavailable(self):
1497
"""self.requireFeature(unavailable) raises UnavailableFeature."""
1498
class Unavailable(features.Feature):
1499
def _probe(self):return False
1500
feature = Unavailable()
1501
self.assertRaises(tests.UnavailableFeature,
1502
self.requireFeature, feature)
1504
def test_run_no_parameters(self):
1505
test = SampleTestCase('_test_pass')
1508
def test_run_enabled_unittest_result(self):
1509
"""Test we revert to regular behaviour when the test is enabled."""
1510
test = SampleTestCase('_test_pass')
1511
class EnabledFeature(object):
1512
def available(self):
1514
test._test_needs_features = [EnabledFeature()]
1515
result = unittest.TestResult()
1517
self.assertEqual(1, result.testsRun)
1518
self.assertEqual([], result.errors)
1519
self.assertEqual([], result.failures)
1521
def test_run_disabled_unittest_result(self):
1522
"""Test our compatability for disabled tests with unittest results."""
1523
test = SampleTestCase('_test_pass')
1524
class DisabledFeature(object):
1525
def available(self):
1527
test._test_needs_features = [DisabledFeature()]
1528
result = unittest.TestResult()
1530
self.assertEqual(1, result.testsRun)
1531
self.assertEqual([], result.errors)
1532
self.assertEqual([], result.failures)
1534
def test_run_disabled_supporting_result(self):
1535
"""Test disabled tests behaviour with support aware results."""
1536
test = SampleTestCase('_test_pass')
1537
class DisabledFeature(object):
1538
def __eq__(self, other):
1539
return isinstance(other, DisabledFeature)
1540
def available(self):
1542
the_feature = DisabledFeature()
1543
test._test_needs_features = [the_feature]
1544
class InstrumentedTestResult(unittest.TestResult):
1546
unittest.TestResult.__init__(self)
1548
def startTest(self, test):
1549
self.calls.append(('startTest', test))
1550
def stopTest(self, test):
1551
self.calls.append(('stopTest', test))
1552
def addNotSupported(self, test, feature):
1553
self.calls.append(('addNotSupported', test, feature))
1554
result = InstrumentedTestResult()
1556
case = result.calls[0][1]
1558
('startTest', case),
1559
('addNotSupported', case, the_feature),
1564
def test_start_server_registers_url(self):
1565
transport_server = memory.MemoryServer()
1566
# A little strict, but unlikely to be changed soon.
1567
self.assertEqual([], self._bzr_selftest_roots)
1568
self.start_server(transport_server)
1569
self.assertSubset([transport_server.get_url()],
1570
self._bzr_selftest_roots)
1572
def test_assert_list_raises_on_generator(self):
1573
def generator_which_will_raise():
1574
# This will not raise until after the first yield
1576
raise _TestException()
1578
e = self.assertListRaises(_TestException, generator_which_will_raise)
1579
self.assertIsInstance(e, _TestException)
1581
e = self.assertListRaises(Exception, generator_which_will_raise)
1582
self.assertIsInstance(e, _TestException)
1584
def test_assert_list_raises_on_plain(self):
1585
def plain_exception():
1586
raise _TestException()
1589
e = self.assertListRaises(_TestException, plain_exception)
1590
self.assertIsInstance(e, _TestException)
1592
e = self.assertListRaises(Exception, plain_exception)
1593
self.assertIsInstance(e, _TestException)
1595
def test_assert_list_raises_assert_wrong_exception(self):
1596
class _NotTestException(Exception):
1599
def wrong_exception():
1600
raise _NotTestException()
1602
def wrong_exception_generator():
1605
raise _NotTestException()
1607
# Wrong exceptions are not intercepted
1608
self.assertRaises(_NotTestException,
1609
self.assertListRaises, _TestException, wrong_exception)
1610
self.assertRaises(_NotTestException,
1611
self.assertListRaises, _TestException, wrong_exception_generator)
1613
def test_assert_list_raises_no_exception(self):
1617
def success_generator():
1621
self.assertRaises(AssertionError,
1622
self.assertListRaises, _TestException, success)
1624
self.assertRaises(AssertionError,
1625
self.assertListRaises, _TestException, success_generator)
1627
def test_overrideAttr_without_value(self):
1628
self.test_attr = 'original' # Define a test attribute
1629
obj = self # Make 'obj' visible to the embedded test
1630
class Test(tests.TestCase):
1633
tests.TestCase.setUp(self)
1634
self.orig = self.overrideAttr(obj, 'test_attr')
1636
def test_value(self):
1637
self.assertEqual('original', self.orig)
1638
self.assertEqual('original', obj.test_attr)
1639
obj.test_attr = 'modified'
1640
self.assertEqual('modified', obj.test_attr)
1642
test = Test('test_value')
1643
test.run(unittest.TestResult())
1644
self.assertEqual('original', obj.test_attr)
1646
def test_overrideAttr_with_value(self):
1647
self.test_attr = 'original' # Define a test attribute
1648
obj = self # Make 'obj' visible to the embedded test
1649
class Test(tests.TestCase):
1652
tests.TestCase.setUp(self)
1653
self.orig = self.overrideAttr(obj, 'test_attr', new='modified')
1655
def test_value(self):
1656
self.assertEqual('original', self.orig)
1657
self.assertEqual('modified', obj.test_attr)
1659
test = Test('test_value')
1660
test.run(unittest.TestResult())
1661
self.assertEqual('original', obj.test_attr)
1663
def test_recordCalls(self):
1664
from bzrlib.tests import test_selftest
1665
calls = self.recordCalls(
1666
test_selftest, '_add_numbers')
1667
self.assertEqual(test_selftest._add_numbers(2, 10),
1669
self.assertEquals(calls, [((2, 10), {})])
1672
def _add_numbers(a, b):
1676
class _MissingFeature(features.Feature):
1679
missing_feature = _MissingFeature()
1682
def _get_test(name):
1683
"""Get an instance of a specific example test.
1685
We protect this in a function so that they don't auto-run in the test
1689
class ExampleTests(tests.TestCase):
1691
def test_fail(self):
1692
mutter('this was a failing test')
1693
self.fail('this test will fail')
1695
def test_error(self):
1696
mutter('this test errored')
1697
raise RuntimeError('gotcha')
1699
def test_missing_feature(self):
1700
mutter('missing the feature')
1701
self.requireFeature(missing_feature)
1703
def test_skip(self):
1704
mutter('this test will be skipped')
1705
raise tests.TestSkipped('reason')
1707
def test_success(self):
1708
mutter('this test succeeds')
1710
def test_xfail(self):
1711
mutter('test with expected failure')
1712
self.knownFailure('this_fails')
1714
def test_unexpected_success(self):
1715
mutter('test with unexpected success')
1716
self.expectFailure('should_fail', lambda: None)
1718
return ExampleTests(name)
1721
class TestTestCaseLogDetails(tests.TestCase):
1723
def _run_test(self, test_name):
1724
test = _get_test(test_name)
1725
result = testtools.TestResult()
1729
def test_fail_has_log(self):
1730
result = self._run_test('test_fail')
1731
self.assertEqual(1, len(result.failures))
1732
result_content = result.failures[0][1]
1733
self.assertContainsRe(result_content,
1734
'(?m)^(?:Text attachment: )?log(?:$|: )')
1735
self.assertContainsRe(result_content, 'this was a failing test')
1737
def test_error_has_log(self):
1738
result = self._run_test('test_error')
1739
self.assertEqual(1, len(result.errors))
1740
result_content = result.errors[0][1]
1741
self.assertContainsRe(result_content,
1742
'(?m)^(?:Text attachment: )?log(?:$|: )')
1743
self.assertContainsRe(result_content, 'this test errored')
1745
def test_skip_has_no_log(self):
1746
result = self._run_test('test_skip')
1747
self.assertEqual(['reason'], result.skip_reasons.keys())
1748
skips = result.skip_reasons['reason']
1749
self.assertEqual(1, len(skips))
1751
self.assertFalse('log' in test.getDetails())
1753
def test_missing_feature_has_no_log(self):
1754
# testtools doesn't know about addNotSupported, so it just gets
1755
# considered as a skip
1756
result = self._run_test('test_missing_feature')
1757
self.assertEqual([missing_feature], result.skip_reasons.keys())
1758
skips = result.skip_reasons[missing_feature]
1759
self.assertEqual(1, len(skips))
1761
self.assertFalse('log' in test.getDetails())
1763
def test_xfail_has_no_log(self):
1764
result = self._run_test('test_xfail')
1765
self.assertEqual(1, len(result.expectedFailures))
1766
result_content = result.expectedFailures[0][1]
1767
self.assertNotContainsRe(result_content,
1768
'(?m)^(?:Text attachment: )?log(?:$|: )')
1769
self.assertNotContainsRe(result_content, 'test with expected failure')
1771
def test_unexpected_success_has_log(self):
1772
result = self._run_test('test_unexpected_success')
1773
self.assertEqual(1, len(result.unexpectedSuccesses))
1774
# Inconsistency, unexpectedSuccesses is a list of tests,
1775
# expectedFailures is a list of reasons?
1776
test = result.unexpectedSuccesses[0]
1777
details = test.getDetails()
1778
self.assertTrue('log' in details)
1781
class TestTestCloning(tests.TestCase):
1782
"""Tests that test cloning of TestCases (as used by multiply_tests)."""
1784
def test_cloned_testcase_does_not_share_details(self):
1785
"""A TestCase cloned with clone_test does not share mutable attributes
1786
such as details or cleanups.
1788
class Test(tests.TestCase):
1790
self.addDetail('foo', Content('text/plain', lambda: 'foo'))
1791
orig_test = Test('test_foo')
1792
cloned_test = tests.clone_test(orig_test, orig_test.id() + '(cloned)')
1793
orig_test.run(unittest.TestResult())
1794
self.assertEqual('foo', orig_test.getDetails()['foo'].iter_bytes())
1795
self.assertEqual(None, cloned_test.getDetails().get('foo'))
1797
def test_double_apply_scenario_preserves_first_scenario(self):
1798
"""Applying two levels of scenarios to a test preserves the attributes
1799
added by both scenarios.
1801
class Test(tests.TestCase):
1804
test = Test('test_foo')
1805
scenarios_x = [('x=1', {'x': 1}), ('x=2', {'x': 2})]
1806
scenarios_y = [('y=1', {'y': 1}), ('y=2', {'y': 2})]
1807
suite = tests.multiply_tests(test, scenarios_x, unittest.TestSuite())
1808
suite = tests.multiply_tests(suite, scenarios_y, unittest.TestSuite())
1809
all_tests = list(tests.iter_suite_tests(suite))
1810
self.assertLength(4, all_tests)
1811
all_xys = sorted((t.x, t.y) for t in all_tests)
1812
self.assertEqual([(1, 1), (1, 2), (2, 1), (2, 2)], all_xys)
1815
# NB: Don't delete this; it's not actually from 0.11!
1816
@deprecated_function(deprecated_in((0, 11, 0)))
1817
def sample_deprecated_function():
1818
"""A deprecated function to test applyDeprecated with."""
1822
def sample_undeprecated_function(a_param):
1823
"""A undeprecated function to test applyDeprecated with."""
1826
class ApplyDeprecatedHelper(object):
1827
"""A helper class for ApplyDeprecated tests."""
1829
@deprecated_method(deprecated_in((0, 11, 0)))
1830
def sample_deprecated_method(self, param_one):
1831
"""A deprecated method for testing with."""
1834
def sample_normal_method(self):
1835
"""A undeprecated method."""
1837
@deprecated_method(deprecated_in((0, 10, 0)))
1838
def sample_nested_deprecation(self):
1839
return sample_deprecated_function()
1842
class TestExtraAssertions(tests.TestCase):
1843
"""Tests for new test assertions in bzrlib test suite"""
1845
def test_assert_isinstance(self):
1846
self.assertIsInstance(2, int)
1847
self.assertIsInstance(u'', basestring)
1848
e = self.assertRaises(AssertionError, self.assertIsInstance, None, int)
1849
self.assertEquals(str(e),
1850
"None is an instance of <type 'NoneType'> rather than <type 'int'>")
1851
self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
1852
e = self.assertRaises(AssertionError,
1853
self.assertIsInstance, None, int, "it's just not")
1854
self.assertEquals(str(e),
1855
"None is an instance of <type 'NoneType'> rather than <type 'int'>"
1858
def test_assertEndsWith(self):
1859
self.assertEndsWith('foo', 'oo')
1860
self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
1862
def test_assertEqualDiff(self):
1863
e = self.assertRaises(AssertionError,
1864
self.assertEqualDiff, '', '\n')
1865
self.assertEquals(str(e),
1866
# Don't blink ! The '+' applies to the second string
1867
'first string is missing a final newline.\n+ \n')
1868
e = self.assertRaises(AssertionError,
1869
self.assertEqualDiff, '\n', '')
1870
self.assertEquals(str(e),
1871
# Don't blink ! The '-' applies to the second string
1872
'second string is missing a final newline.\n- \n')
1875
class TestDeprecations(tests.TestCase):
1877
def test_applyDeprecated_not_deprecated(self):
1878
sample_object = ApplyDeprecatedHelper()
1879
# calling an undeprecated callable raises an assertion
1880
self.assertRaises(AssertionError, self.applyDeprecated,
1881
deprecated_in((0, 11, 0)),
1882
sample_object.sample_normal_method)
1883
self.assertRaises(AssertionError, self.applyDeprecated,
1884
deprecated_in((0, 11, 0)),
1885
sample_undeprecated_function, "a param value")
1886
# calling a deprecated callable (function or method) with the wrong
1887
# expected deprecation fails.
1888
self.assertRaises(AssertionError, self.applyDeprecated,
1889
deprecated_in((0, 10, 0)),
1890
sample_object.sample_deprecated_method, "a param value")
1891
self.assertRaises(AssertionError, self.applyDeprecated,
1892
deprecated_in((0, 10, 0)),
1893
sample_deprecated_function)
1894
# calling a deprecated callable (function or method) with the right
1895
# expected deprecation returns the functions result.
1896
self.assertEqual("a param value",
1897
self.applyDeprecated(deprecated_in((0, 11, 0)),
1898
sample_object.sample_deprecated_method, "a param value"))
1899
self.assertEqual(2, self.applyDeprecated(deprecated_in((0, 11, 0)),
1900
sample_deprecated_function))
1901
# calling a nested deprecation with the wrong deprecation version
1902
# fails even if a deeper nested function was deprecated with the
1904
self.assertRaises(AssertionError, self.applyDeprecated,
1905
deprecated_in((0, 11, 0)), sample_object.sample_nested_deprecation)
1906
# calling a nested deprecation with the right deprecation value
1907
# returns the calls result.
1908
self.assertEqual(2, self.applyDeprecated(deprecated_in((0, 10, 0)),
1909
sample_object.sample_nested_deprecation))
1911
def test_callDeprecated(self):
1912
def testfunc(be_deprecated, result=None):
1913
if be_deprecated is True:
1914
symbol_versioning.warn('i am deprecated', DeprecationWarning,
1917
result = self.callDeprecated(['i am deprecated'], testfunc, True)
1918
self.assertIs(None, result)
1919
result = self.callDeprecated([], testfunc, False, 'result')
1920
self.assertEqual('result', result)
1921
self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
1922
self.callDeprecated([], testfunc, be_deprecated=False)
1925
class TestWarningTests(tests.TestCase):
1926
"""Tests for calling methods that raise warnings."""
1928
def test_callCatchWarnings(self):
1930
warnings.warn("this is your last warning")
1932
wlist, result = self.callCatchWarnings(meth, 1, 2)
1933
self.assertEquals(3, result)
1934
# would like just to compare them, but UserWarning doesn't implement
1937
self.assertIsInstance(w0, UserWarning)
1938
self.assertEquals("this is your last warning", str(w0))
1941
class TestConvenienceMakers(tests.TestCaseWithTransport):
1942
"""Test for the make_* convenience functions."""
1944
def test_make_branch_and_tree_with_format(self):
1945
# we should be able to supply a format to make_branch_and_tree
1946
self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
1947
self.assertIsInstance(bzrlib.controldir.ControlDir.open('a')._format,
1948
bzrlib.bzrdir.BzrDirMetaFormat1)
1950
def test_make_branch_and_memory_tree(self):
1951
# we should be able to get a new branch and a mutable tree from
1952
# TestCaseWithTransport
1953
tree = self.make_branch_and_memory_tree('a')
1954
self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
1956
def test_make_tree_for_local_vfs_backed_transport(self):
1957
# make_branch_and_tree has to use local branch and repositories
1958
# when the vfs transport and local disk are colocated, even if
1959
# a different transport is in use for url generation.
1960
self.transport_server = test_server.FakeVFATServer
1961
self.assertFalse(self.get_url('t1').startswith('file://'))
1962
tree = self.make_branch_and_tree('t1')
1963
base = tree.bzrdir.root_transport.base
1964
self.assertStartsWith(base, 'file://')
1965
self.assertEquals(tree.bzrdir.root_transport,
1966
tree.branch.bzrdir.root_transport)
1967
self.assertEquals(tree.bzrdir.root_transport,
1968
tree.branch.repository.bzrdir.root_transport)
1971
class SelfTestHelper(object):
1973
def run_selftest(self, **kwargs):
1974
"""Run selftest returning its output."""
1976
old_transport = bzrlib.tests.default_transport
1977
old_root = tests.TestCaseWithMemoryTransport.TEST_ROOT
1978
tests.TestCaseWithMemoryTransport.TEST_ROOT = None
1980
self.assertEqual(True, tests.selftest(stream=output, **kwargs))
1982
bzrlib.tests.default_transport = old_transport
1983
tests.TestCaseWithMemoryTransport.TEST_ROOT = old_root
1988
class TestSelftest(tests.TestCase, SelfTestHelper):
1989
"""Tests of bzrlib.tests.selftest."""
1991
def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
1994
factory_called.append(True)
1995
return TestUtil.TestSuite()
1998
self.apply_redirected(out, err, None, bzrlib.tests.selftest,
1999
test_suite_factory=factory)
2000
self.assertEqual([True], factory_called)
2003
"""A test suite factory."""
2004
class Test(tests.TestCase):
2011
return TestUtil.TestSuite([Test("a"), Test("b"), Test("c")])
2013
def test_list_only(self):
2014
output = self.run_selftest(test_suite_factory=self.factory,
2016
self.assertEqual(3, len(output.readlines()))
2018
def test_list_only_filtered(self):
2019
output = self.run_selftest(test_suite_factory=self.factory,
2020
list_only=True, pattern="Test.b")
2021
self.assertEndsWith(output.getvalue(), "Test.b\n")
2022
self.assertLength(1, output.readlines())
2024
def test_list_only_excludes(self):
2025
output = self.run_selftest(test_suite_factory=self.factory,
2026
list_only=True, exclude_pattern="Test.b")
2027
self.assertNotContainsRe("Test.b", output.getvalue())
2028
self.assertLength(2, output.readlines())
2030
def test_lsprof_tests(self):
2031
self.requireFeature(features.lsprof_feature)
2034
def __call__(test, result):
2036
def run(test, result):
2037
results.append(result)
2038
def countTestCases(self):
2040
self.run_selftest(test_suite_factory=Test, lsprof_tests=True)
2041
self.assertLength(1, results)
2042
self.assertIsInstance(results.pop(), ExtendedToOriginalDecorator)
2044
def test_random(self):
2045
# test randomising by listing a number of tests.
2046
output_123 = self.run_selftest(test_suite_factory=self.factory,
2047
list_only=True, random_seed="123")
2048
output_234 = self.run_selftest(test_suite_factory=self.factory,
2049
list_only=True, random_seed="234")
2050
self.assertNotEqual(output_123, output_234)
2051
# "Randominzing test order..\n\n
2052
self.assertLength(5, output_123.readlines())
2053
self.assertLength(5, output_234.readlines())
2055
def test_random_reuse_is_same_order(self):
2056
# test randomising by listing a number of tests.
2057
expected = self.run_selftest(test_suite_factory=self.factory,
2058
list_only=True, random_seed="123")
2059
repeated = self.run_selftest(test_suite_factory=self.factory,
2060
list_only=True, random_seed="123")
2061
self.assertEqual(expected.getvalue(), repeated.getvalue())
2063
def test_runner_class(self):
2064
self.requireFeature(features.subunit)
2065
from subunit import ProtocolTestCase
2066
stream = self.run_selftest(runner_class=tests.SubUnitBzrRunner,
2067
test_suite_factory=self.factory)
2068
test = ProtocolTestCase(stream)
2069
result = unittest.TestResult()
2071
self.assertEqual(3, result.testsRun)
2073
def test_starting_with_single_argument(self):
2074
output = self.run_selftest(test_suite_factory=self.factory,
2075
starting_with=['bzrlib.tests.test_selftest.Test.a'],
2077
self.assertEqual('bzrlib.tests.test_selftest.Test.a\n',
2080
def test_starting_with_multiple_argument(self):
2081
output = self.run_selftest(test_suite_factory=self.factory,
2082
starting_with=['bzrlib.tests.test_selftest.Test.a',
2083
'bzrlib.tests.test_selftest.Test.b'],
2085
self.assertEqual('bzrlib.tests.test_selftest.Test.a\n'
2086
'bzrlib.tests.test_selftest.Test.b\n',
2089
def check_transport_set(self, transport_server):
2090
captured_transport = []
2091
def seen_transport(a_transport):
2092
captured_transport.append(a_transport)
2093
class Capture(tests.TestCase):
2095
seen_transport(bzrlib.tests.default_transport)
2097
return TestUtil.TestSuite([Capture("a")])
2098
self.run_selftest(transport=transport_server, test_suite_factory=factory)
2099
self.assertEqual(transport_server, captured_transport[0])
2101
def test_transport_sftp(self):
2102
self.requireFeature(features.paramiko)
2103
from bzrlib.tests import stub_sftp
2104
self.check_transport_set(stub_sftp.SFTPAbsoluteServer)
2106
def test_transport_memory(self):
2107
self.check_transport_set(memory.MemoryServer)
2110
class TestSelftestWithIdList(tests.TestCaseInTempDir, SelfTestHelper):
2111
# Does IO: reads test.list
2113
def test_load_list(self):
2114
# Provide a list with one test - this test.
2115
test_id_line = '%s\n' % self.id()
2116
self.build_tree_contents([('test.list', test_id_line)])
2117
# And generate a list of the tests in the suite.
2118
stream = self.run_selftest(load_list='test.list', list_only=True)
2119
self.assertEqual(test_id_line, stream.getvalue())
2121
def test_load_unknown(self):
2122
# Provide a list with one test - this test.
2123
# And generate a list of the tests in the suite.
2124
err = self.assertRaises(errors.NoSuchFile, self.run_selftest,
2125
load_list='missing file name', list_only=True)
2128
class TestSubunitLogDetails(tests.TestCase, SelfTestHelper):
2130
_test_needs_features = [features.subunit]
2132
def run_subunit_stream(self, test_name):
2133
from subunit import ProtocolTestCase
2135
return TestUtil.TestSuite([_get_test(test_name)])
2136
stream = self.run_selftest(runner_class=tests.SubUnitBzrRunner,
2137
test_suite_factory=factory)
2138
test = ProtocolTestCase(stream)
2139
result = testtools.TestResult()
2141
content = stream.getvalue()
2142
return content, result
2144
def test_fail_has_log(self):
2145
content, result = self.run_subunit_stream('test_fail')
2146
self.assertEqual(1, len(result.failures))
2147
self.assertContainsRe(content, '(?m)^log$')
2148
self.assertContainsRe(content, 'this test will fail')
2150
def test_error_has_log(self):
2151
content, result = self.run_subunit_stream('test_error')
2152
self.assertContainsRe(content, '(?m)^log$')
2153
self.assertContainsRe(content, 'this test errored')
2155
def test_skip_has_no_log(self):
2156
content, result = self.run_subunit_stream('test_skip')
2157
self.assertNotContainsRe(content, '(?m)^log$')
2158
self.assertNotContainsRe(content, 'this test will be skipped')
2159
self.assertEqual(['reason'], result.skip_reasons.keys())
2160
skips = result.skip_reasons['reason']
2161
self.assertEqual(1, len(skips))
2163
# RemotedTestCase doesn't preserve the "details"
2164
## self.assertFalse('log' in test.getDetails())
2166
def test_missing_feature_has_no_log(self):
2167
content, result = self.run_subunit_stream('test_missing_feature')
2168
self.assertNotContainsRe(content, '(?m)^log$')
2169
self.assertNotContainsRe(content, 'missing the feature')
2170
self.assertEqual(['_MissingFeature\n'], result.skip_reasons.keys())
2171
skips = result.skip_reasons['_MissingFeature\n']
2172
self.assertEqual(1, len(skips))
2174
# RemotedTestCase doesn't preserve the "details"
2175
## self.assertFalse('log' in test.getDetails())
2177
def test_xfail_has_no_log(self):
2178
content, result = self.run_subunit_stream('test_xfail')
2179
self.assertNotContainsRe(content, '(?m)^log$')
2180
self.assertNotContainsRe(content, 'test with expected failure')
2181
self.assertEqual(1, len(result.expectedFailures))
2182
result_content = result.expectedFailures[0][1]
2183
self.assertNotContainsRe(result_content,
2184
'(?m)^(?:Text attachment: )?log(?:$|: )')
2185
self.assertNotContainsRe(result_content, 'test with expected failure')
2187
def test_unexpected_success_has_log(self):
2188
content, result = self.run_subunit_stream('test_unexpected_success')
2189
self.assertContainsRe(content, '(?m)^log$')
2190
self.assertContainsRe(content, 'test with unexpected success')
2191
# GZ 2011-05-18: Old versions of subunit treat unexpected success as a
2192
# success, if a min version check is added remove this
2193
from subunit import TestProtocolClient as _Client
2194
if _Client.addUnexpectedSuccess.im_func is _Client.addSuccess.im_func:
2195
self.expectFailure('subunit treats "unexpectedSuccess"'
2196
' as a plain success',
2197
self.assertEqual, 1, len(result.unexpectedSuccesses))
2198
self.assertEqual(1, len(result.unexpectedSuccesses))
2199
test = result.unexpectedSuccesses[0]
2200
# RemotedTestCase doesn't preserve the "details"
2201
## self.assertTrue('log' in test.getDetails())
2203
def test_success_has_no_log(self):
2204
content, result = self.run_subunit_stream('test_success')
2205
self.assertEqual(1, result.testsRun)
2206
self.assertNotContainsRe(content, '(?m)^log$')
2207
self.assertNotContainsRe(content, 'this test succeeds')
2210
class TestRunBzr(tests.TestCase):
2215
def _run_bzr_core(self, argv, retcode=0, encoding=None, stdin=None,
2217
"""Override _run_bzr_core to test how it is invoked by run_bzr.
2219
Attempts to run bzr from inside this class don't actually run it.
2221
We test how run_bzr actually invokes bzr in another location. Here we
2222
only need to test that it passes the right parameters to run_bzr.
2224
self.argv = list(argv)
2225
self.retcode = retcode
2226
self.encoding = encoding
2228
self.working_dir = working_dir
2229
return self.retcode, self.out, self.err
2231
def test_run_bzr_error(self):
2232
self.out = "It sure does!\n"
2233
out, err = self.run_bzr_error(['^$'], ['rocks'], retcode=34)
2234
self.assertEqual(['rocks'], self.argv)
2235
self.assertEqual(34, self.retcode)
2236
self.assertEqual('It sure does!\n', out)
2237
self.assertEquals(out, self.out)
2238
self.assertEqual('', err)
2239
self.assertEquals(err, self.err)
2241
def test_run_bzr_error_regexes(self):
2243
self.err = "bzr: ERROR: foobarbaz is not versioned"
2244
out, err = self.run_bzr_error(
2245
["bzr: ERROR: foobarbaz is not versioned"],
2246
['file-id', 'foobarbaz'])
2248
def test_encoding(self):
2249
"""Test that run_bzr passes encoding to _run_bzr_core"""
2250
self.run_bzr('foo bar')
2251
self.assertEqual(None, self.encoding)
2252
self.assertEqual(['foo', 'bar'], self.argv)
2254
self.run_bzr('foo bar', encoding='baz')
2255
self.assertEqual('baz', self.encoding)
2256
self.assertEqual(['foo', 'bar'], self.argv)
2258
def test_retcode(self):
2259
"""Test that run_bzr passes retcode to _run_bzr_core"""
2260
# Default is retcode == 0
2261
self.run_bzr('foo bar')
2262
self.assertEqual(0, self.retcode)
2263
self.assertEqual(['foo', 'bar'], self.argv)
2265
self.run_bzr('foo bar', retcode=1)
2266
self.assertEqual(1, self.retcode)
2267
self.assertEqual(['foo', 'bar'], self.argv)
2269
self.run_bzr('foo bar', retcode=None)
2270
self.assertEqual(None, self.retcode)
2271
self.assertEqual(['foo', 'bar'], self.argv)
2273
self.run_bzr(['foo', 'bar'], retcode=3)
2274
self.assertEqual(3, self.retcode)
2275
self.assertEqual(['foo', 'bar'], self.argv)
2277
def test_stdin(self):
2278
# test that the stdin keyword to run_bzr is passed through to
2279
# _run_bzr_core as-is. We do this by overriding
2280
# _run_bzr_core in this class, and then calling run_bzr,
2281
# which is a convenience function for _run_bzr_core, so
2283
self.run_bzr('foo bar', stdin='gam')
2284
self.assertEqual('gam', self.stdin)
2285
self.assertEqual(['foo', 'bar'], self.argv)
2287
self.run_bzr('foo bar', stdin='zippy')
2288
self.assertEqual('zippy', self.stdin)
2289
self.assertEqual(['foo', 'bar'], self.argv)
2291
def test_working_dir(self):
2292
"""Test that run_bzr passes working_dir to _run_bzr_core"""
2293
self.run_bzr('foo bar')
2294
self.assertEqual(None, self.working_dir)
2295
self.assertEqual(['foo', 'bar'], self.argv)
2297
self.run_bzr('foo bar', working_dir='baz')
2298
self.assertEqual('baz', self.working_dir)
2299
self.assertEqual(['foo', 'bar'], self.argv)
2301
def test_reject_extra_keyword_arguments(self):
2302
self.assertRaises(TypeError, self.run_bzr, "foo bar",
2303
error_regex=['error message'])
2306
class TestRunBzrCaptured(tests.TestCaseWithTransport):
2307
# Does IO when testing the working_dir parameter.
2309
def apply_redirected(self, stdin=None, stdout=None, stderr=None,
2310
a_callable=None, *args, **kwargs):
2312
self.factory_stdin = getattr(bzrlib.ui.ui_factory, "stdin", None)
2313
self.factory = bzrlib.ui.ui_factory
2314
self.working_dir = osutils.getcwd()
2315
stdout.write('foo\n')
2316
stderr.write('bar\n')
2319
def test_stdin(self):
2320
# test that the stdin keyword to _run_bzr_core is passed through to
2321
# apply_redirected as a StringIO. We do this by overriding
2322
# apply_redirected in this class, and then calling _run_bzr_core,
2323
# which calls apply_redirected.
2324
self.run_bzr(['foo', 'bar'], stdin='gam')
2325
self.assertEqual('gam', self.stdin.read())
2326
self.assertTrue(self.stdin is self.factory_stdin)
2327
self.run_bzr(['foo', 'bar'], stdin='zippy')
2328
self.assertEqual('zippy', self.stdin.read())
2329
self.assertTrue(self.stdin is self.factory_stdin)
2331
def test_ui_factory(self):
2332
# each invocation of self.run_bzr should get its
2333
# own UI factory, which is an instance of TestUIFactory,
2334
# with stdin, stdout and stderr attached to the stdin,
2335
# stdout and stderr of the invoked run_bzr
2336
current_factory = bzrlib.ui.ui_factory
2337
self.run_bzr(['foo'])
2338
self.assertFalse(current_factory is self.factory)
2339
self.assertNotEqual(sys.stdout, self.factory.stdout)
2340
self.assertNotEqual(sys.stderr, self.factory.stderr)
2341
self.assertEqual('foo\n', self.factory.stdout.getvalue())
2342
self.assertEqual('bar\n', self.factory.stderr.getvalue())
2343
self.assertIsInstance(self.factory, tests.TestUIFactory)
2345
def test_working_dir(self):
2346
self.build_tree(['one/', 'two/'])
2347
cwd = osutils.getcwd()
2349
# Default is to work in the current directory
2350
self.run_bzr(['foo', 'bar'])
2351
self.assertEqual(cwd, self.working_dir)
2353
self.run_bzr(['foo', 'bar'], working_dir=None)
2354
self.assertEqual(cwd, self.working_dir)
2356
# The function should be run in the alternative directory
2357
# but afterwards the current working dir shouldn't be changed
2358
self.run_bzr(['foo', 'bar'], working_dir='one')
2359
self.assertNotEqual(cwd, self.working_dir)
2360
self.assertEndsWith(self.working_dir, 'one')
2361
self.assertEqual(cwd, osutils.getcwd())
2363
self.run_bzr(['foo', 'bar'], working_dir='two')
2364
self.assertNotEqual(cwd, self.working_dir)
2365
self.assertEndsWith(self.working_dir, 'two')
2366
self.assertEqual(cwd, osutils.getcwd())
2369
class StubProcess(object):
2370
"""A stub process for testing run_bzr_subprocess."""
2372
def __init__(self, out="", err="", retcode=0):
2375
self.returncode = retcode
2377
def communicate(self):
2378
return self.out, self.err
2381
class TestWithFakedStartBzrSubprocess(tests.TestCaseWithTransport):
2382
"""Base class for tests testing how we might run bzr."""
2385
tests.TestCaseWithTransport.setUp(self)
2386
self.subprocess_calls = []
2388
def start_bzr_subprocess(self, process_args, env_changes=None,
2389
skip_if_plan_to_signal=False,
2391
allow_plugins=False):
2392
"""capture what run_bzr_subprocess tries to do."""
2393
self.subprocess_calls.append({'process_args':process_args,
2394
'env_changes':env_changes,
2395
'skip_if_plan_to_signal':skip_if_plan_to_signal,
2396
'working_dir':working_dir, 'allow_plugins':allow_plugins})
2397
return self.next_subprocess
2400
class TestRunBzrSubprocess(TestWithFakedStartBzrSubprocess):
2402
def assertRunBzrSubprocess(self, expected_args, process, *args, **kwargs):
2403
"""Run run_bzr_subprocess with args and kwargs using a stubbed process.
2405
Inside TestRunBzrSubprocessCommands we use a stub start_bzr_subprocess
2406
that will return static results. This assertion method populates those
2407
results and also checks the arguments run_bzr_subprocess generates.
2409
self.next_subprocess = process
2411
result = self.run_bzr_subprocess(*args, **kwargs)
2413
self.next_subprocess = None
2414
for key, expected in expected_args.iteritems():
2415
self.assertEqual(expected, self.subprocess_calls[-1][key])
2418
self.next_subprocess = None
2419
for key, expected in expected_args.iteritems():
2420
self.assertEqual(expected, self.subprocess_calls[-1][key])
2423
def test_run_bzr_subprocess(self):
2424
"""The run_bzr_helper_external command behaves nicely."""
2425
self.assertRunBzrSubprocess({'process_args':['--version']},
2426
StubProcess(), '--version')
2427
self.assertRunBzrSubprocess({'process_args':['--version']},
2428
StubProcess(), ['--version'])
2429
# retcode=None disables retcode checking
2430
result = self.assertRunBzrSubprocess({},
2431
StubProcess(retcode=3), '--version', retcode=None)
2432
result = self.assertRunBzrSubprocess({},
2433
StubProcess(out="is free software"), '--version')
2434
self.assertContainsRe(result[0], 'is free software')
2435
# Running a subcommand that is missing errors
2436
self.assertRaises(AssertionError, self.assertRunBzrSubprocess,
2437
{'process_args':['--versionn']}, StubProcess(retcode=3),
2439
# Unless it is told to expect the error from the subprocess
2440
result = self.assertRunBzrSubprocess({},
2441
StubProcess(retcode=3), '--versionn', retcode=3)
2442
# Or to ignore retcode checking
2443
result = self.assertRunBzrSubprocess({},
2444
StubProcess(err="unknown command", retcode=3), '--versionn',
2446
self.assertContainsRe(result[1], 'unknown command')
2448
def test_env_change_passes_through(self):
2449
self.assertRunBzrSubprocess(
2450
{'env_changes':{'new':'value', 'changed':'newvalue', 'deleted':None}},
2452
env_changes={'new':'value', 'changed':'newvalue', 'deleted':None})
2454
def test_no_working_dir_passed_as_None(self):
2455
self.assertRunBzrSubprocess({'working_dir': None}, StubProcess(), '')
2457
def test_no_working_dir_passed_through(self):
2458
self.assertRunBzrSubprocess({'working_dir': 'dir'}, StubProcess(), '',
2461
def test_run_bzr_subprocess_no_plugins(self):
2462
self.assertRunBzrSubprocess({'allow_plugins': False},
2465
def test_allow_plugins(self):
2466
self.assertRunBzrSubprocess({'allow_plugins': True},
2467
StubProcess(), '', allow_plugins=True)
2470
class TestFinishBzrSubprocess(TestWithFakedStartBzrSubprocess):
2472
def test_finish_bzr_subprocess_with_error(self):
2473
"""finish_bzr_subprocess allows specification of the desired exit code.
2475
process = StubProcess(err="unknown command", retcode=3)
2476
result = self.finish_bzr_subprocess(process, retcode=3)
2477
self.assertEqual('', result[0])
2478
self.assertContainsRe(result[1], 'unknown command')
2480
def test_finish_bzr_subprocess_ignoring_retcode(self):
2481
"""finish_bzr_subprocess allows the exit code to be ignored."""
2482
process = StubProcess(err="unknown command", retcode=3)
2483
result = self.finish_bzr_subprocess(process, retcode=None)
2484
self.assertEqual('', result[0])
2485
self.assertContainsRe(result[1], 'unknown command')
2487
def test_finish_subprocess_with_unexpected_retcode(self):
2488
"""finish_bzr_subprocess raises self.failureException if the retcode is
2489
not the expected one.
2491
process = StubProcess(err="unknown command", retcode=3)
2492
self.assertRaises(self.failureException, self.finish_bzr_subprocess,
2496
class _DontSpawnProcess(Exception):
2497
"""A simple exception which just allows us to skip unnecessary steps"""
2500
class TestStartBzrSubProcess(tests.TestCase):
2501
"""Stub test start_bzr_subprocess."""
2503
def _subprocess_log_cleanup(self):
2504
"""Inhibits the base version as we don't produce a log file."""
2506
def _popen(self, *args, **kwargs):
2507
"""Override the base version to record the command that is run.
2509
From there we can ensure it is correct without spawning a real process.
2511
self.check_popen_state()
2512
self._popen_args = args
2513
self._popen_kwargs = kwargs
2514
raise _DontSpawnProcess()
2516
def check_popen_state(self):
2517
"""Replace to make assertions when popen is called."""
2519
def test_run_bzr_subprocess_no_plugins(self):
2520
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [])
2521
command = self._popen_args[0]
2522
self.assertEqual(sys.executable, command[0])
2523
self.assertEqual(self.get_bzr_path(), command[1])
2524
self.assertEqual(['--no-plugins'], command[2:])
2526
def test_allow_plugins(self):
2527
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2529
command = self._popen_args[0]
2530
self.assertEqual([], command[2:])
2532
def test_set_env(self):
2533
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2535
def check_environment():
2536
self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2537
self.check_popen_state = check_environment
2538
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2539
env_changes={'EXISTANT_ENV_VAR':'set variable'})
2540
# not set in theparent
2541
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2543
def test_run_bzr_subprocess_env_del(self):
2544
"""run_bzr_subprocess can remove environment variables too."""
2545
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2546
def check_environment():
2547
self.assertFalse('EXISTANT_ENV_VAR' in os.environ)
2548
os.environ['EXISTANT_ENV_VAR'] = 'set variable'
2549
self.check_popen_state = check_environment
2550
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2551
env_changes={'EXISTANT_ENV_VAR':None})
2552
# Still set in parent
2553
self.assertEqual('set variable', os.environ['EXISTANT_ENV_VAR'])
2554
del os.environ['EXISTANT_ENV_VAR']
2556
def test_env_del_missing(self):
2557
self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
2558
def check_environment():
2559
self.assertFalse('NON_EXISTANT_ENV_VAR' in os.environ)
2560
self.check_popen_state = check_environment
2561
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2562
env_changes={'NON_EXISTANT_ENV_VAR':None})
2564
def test_working_dir(self):
2565
"""Test that we can specify the working dir for the child"""
2566
orig_getcwd = osutils.getcwd
2567
orig_chdir = os.chdir
2571
self.overrideAttr(os, 'chdir', chdir)
2574
self.overrideAttr(osutils, 'getcwd', getcwd)
2575
self.assertRaises(_DontSpawnProcess, self.start_bzr_subprocess, [],
2577
self.assertEqual(['foo', 'current'], chdirs)
2579
def test_get_bzr_path_with_cwd_bzrlib(self):
2580
self.get_source_path = lambda: ""
2581
self.overrideAttr(os.path, "isfile", lambda path: True)
2582
self.assertEqual(self.get_bzr_path(), "bzr")
2585
class TestActuallyStartBzrSubprocess(tests.TestCaseWithTransport):
2586
"""Tests that really need to do things with an external bzr."""
2588
def test_start_and_stop_bzr_subprocess_send_signal(self):
2589
"""finish_bzr_subprocess raises self.failureException if the retcode is
2590
not the expected one.
2592
self.disable_missing_extensions_warning()
2593
process = self.start_bzr_subprocess(['wait-until-signalled'],
2594
skip_if_plan_to_signal=True)
2595
self.assertEqual('running\n', process.stdout.readline())
2596
result = self.finish_bzr_subprocess(process, send_signal=signal.SIGINT,
2598
self.assertEqual('', result[0])
2599
self.assertEqual('bzr: interrupted\n', result[1])
2602
class TestSelftestFiltering(tests.TestCase):
2605
tests.TestCase.setUp(self)
2606
self.suite = TestUtil.TestSuite()
2607
self.loader = TestUtil.TestLoader()
2608
self.suite.addTest(self.loader.loadTestsFromModule(
2609
sys.modules['bzrlib.tests.test_selftest']))
2610
self.all_names = _test_ids(self.suite)
2612
def test_condition_id_re(self):
2613
test_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2614
'test_condition_id_re')
2615
filtered_suite = tests.filter_suite_by_condition(
2616
self.suite, tests.condition_id_re('test_condition_id_re'))
2617
self.assertEqual([test_name], _test_ids(filtered_suite))
2619
def test_condition_id_in_list(self):
2620
test_names = ['bzrlib.tests.test_selftest.TestSelftestFiltering.'
2621
'test_condition_id_in_list']
2622
id_list = tests.TestIdList(test_names)
2623
filtered_suite = tests.filter_suite_by_condition(
2624
self.suite, tests.condition_id_in_list(id_list))
2625
my_pattern = 'TestSelftestFiltering.*test_condition_id_in_list'
2626
re_filtered = tests.filter_suite_by_re(self.suite, my_pattern)
2627
self.assertEqual(_test_ids(re_filtered), _test_ids(filtered_suite))
2629
def test_condition_id_startswith(self):
2630
klass = 'bzrlib.tests.test_selftest.TestSelftestFiltering.'
2631
start1 = klass + 'test_condition_id_starts'
2632
start2 = klass + 'test_condition_id_in'
2633
test_names = [ klass + 'test_condition_id_in_list',
2634
klass + 'test_condition_id_startswith',
2636
filtered_suite = tests.filter_suite_by_condition(
2637
self.suite, tests.condition_id_startswith([start1, start2]))
2638
self.assertEqual(test_names, _test_ids(filtered_suite))
2640
def test_condition_isinstance(self):
2641
filtered_suite = tests.filter_suite_by_condition(
2642
self.suite, tests.condition_isinstance(self.__class__))
2643
class_pattern = 'bzrlib.tests.test_selftest.TestSelftestFiltering.'
2644
re_filtered = tests.filter_suite_by_re(self.suite, class_pattern)
2645
self.assertEqual(_test_ids(re_filtered), _test_ids(filtered_suite))
2647
def test_exclude_tests_by_condition(self):
2648
excluded_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2649
'test_exclude_tests_by_condition')
2650
filtered_suite = tests.exclude_tests_by_condition(self.suite,
2651
lambda x:x.id() == excluded_name)
2652
self.assertEqual(len(self.all_names) - 1,
2653
filtered_suite.countTestCases())
2654
self.assertFalse(excluded_name in _test_ids(filtered_suite))
2655
remaining_names = list(self.all_names)
2656
remaining_names.remove(excluded_name)
2657
self.assertEqual(remaining_names, _test_ids(filtered_suite))
2659
def test_exclude_tests_by_re(self):
2660
self.all_names = _test_ids(self.suite)
2661
filtered_suite = tests.exclude_tests_by_re(self.suite,
2662
'exclude_tests_by_re')
2663
excluded_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2664
'test_exclude_tests_by_re')
2665
self.assertEqual(len(self.all_names) - 1,
2666
filtered_suite.countTestCases())
2667
self.assertFalse(excluded_name in _test_ids(filtered_suite))
2668
remaining_names = list(self.all_names)
2669
remaining_names.remove(excluded_name)
2670
self.assertEqual(remaining_names, _test_ids(filtered_suite))
2672
def test_filter_suite_by_condition(self):
2673
test_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2674
'test_filter_suite_by_condition')
2675
filtered_suite = tests.filter_suite_by_condition(self.suite,
2676
lambda x:x.id() == test_name)
2677
self.assertEqual([test_name], _test_ids(filtered_suite))
2679
def test_filter_suite_by_re(self):
2680
filtered_suite = tests.filter_suite_by_re(self.suite,
2681
'test_filter_suite_by_r')
2682
filtered_names = _test_ids(filtered_suite)
2683
self.assertEqual(filtered_names, ['bzrlib.tests.test_selftest.'
2684
'TestSelftestFiltering.test_filter_suite_by_re'])
2686
def test_filter_suite_by_id_list(self):
2687
test_list = ['bzrlib.tests.test_selftest.'
2688
'TestSelftestFiltering.test_filter_suite_by_id_list']
2689
filtered_suite = tests.filter_suite_by_id_list(
2690
self.suite, tests.TestIdList(test_list))
2691
filtered_names = _test_ids(filtered_suite)
2694
['bzrlib.tests.test_selftest.'
2695
'TestSelftestFiltering.test_filter_suite_by_id_list'])
2697
def test_filter_suite_by_id_startswith(self):
2698
# By design this test may fail if another test is added whose name also
2699
# begins with one of the start value used.
2700
klass = 'bzrlib.tests.test_selftest.TestSelftestFiltering.'
2701
start1 = klass + 'test_filter_suite_by_id_starts'
2702
start2 = klass + 'test_filter_suite_by_id_li'
2703
test_list = [klass + 'test_filter_suite_by_id_list',
2704
klass + 'test_filter_suite_by_id_startswith',
2706
filtered_suite = tests.filter_suite_by_id_startswith(
2707
self.suite, [start1, start2])
2710
_test_ids(filtered_suite),
2713
def test_preserve_input(self):
2714
# NB: Surely this is something in the stdlib to do this?
2715
self.assertTrue(self.suite is tests.preserve_input(self.suite))
2716
self.assertTrue("@#$" is tests.preserve_input("@#$"))
2718
def test_randomize_suite(self):
2719
randomized_suite = tests.randomize_suite(self.suite)
2720
# randomizing should not add or remove test names.
2721
self.assertEqual(set(_test_ids(self.suite)),
2722
set(_test_ids(randomized_suite)))
2723
# Technically, this *can* fail, because random.shuffle(list) can be
2724
# equal to list. Trying multiple times just pushes the frequency back.
2725
# As its len(self.all_names)!:1, the failure frequency should be low
2726
# enough to ignore. RBC 20071021.
2727
# It should change the order.
2728
self.assertNotEqual(self.all_names, _test_ids(randomized_suite))
2729
# But not the length. (Possibly redundant with the set test, but not
2731
self.assertEqual(len(self.all_names), len(_test_ids(randomized_suite)))
2733
def test_split_suit_by_condition(self):
2734
self.all_names = _test_ids(self.suite)
2735
condition = tests.condition_id_re('test_filter_suite_by_r')
2736
split_suite = tests.split_suite_by_condition(self.suite, condition)
2737
filtered_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2738
'test_filter_suite_by_re')
2739
self.assertEqual([filtered_name], _test_ids(split_suite[0]))
2740
self.assertFalse(filtered_name in _test_ids(split_suite[1]))
2741
remaining_names = list(self.all_names)
2742
remaining_names.remove(filtered_name)
2743
self.assertEqual(remaining_names, _test_ids(split_suite[1]))
2745
def test_split_suit_by_re(self):
2746
self.all_names = _test_ids(self.suite)
2747
split_suite = tests.split_suite_by_re(self.suite,
2748
'test_filter_suite_by_r')
2749
filtered_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
2750
'test_filter_suite_by_re')
2751
self.assertEqual([filtered_name], _test_ids(split_suite[0]))
2752
self.assertFalse(filtered_name in _test_ids(split_suite[1]))
2753
remaining_names = list(self.all_names)
2754
remaining_names.remove(filtered_name)
2755
self.assertEqual(remaining_names, _test_ids(split_suite[1]))
2758
class TestCheckTreeShape(tests.TestCaseWithTransport):
2760
def test_check_tree_shape(self):
2761
files = ['a', 'b/', 'b/c']
2762
tree = self.make_branch_and_tree('.')
2763
self.build_tree(files)
2767
self.check_tree_shape(tree, files)
2772
class TestBlackboxSupport(tests.TestCase):
2773
"""Tests for testsuite blackbox features."""
2775
def test_run_bzr_failure_not_caught(self):
2776
# When we run bzr in blackbox mode, we want any unexpected errors to
2777
# propagate up to the test suite so that it can show the error in the
2778
# usual way, and we won't get a double traceback.
2779
e = self.assertRaises(
2781
self.run_bzr, ['assert-fail'])
2782
# make sure we got the real thing, not an error from somewhere else in
2783
# the test framework
2784
self.assertEquals('always fails', str(e))
2785
# check that there's no traceback in the test log
2786
self.assertNotContainsRe(self.get_log(), r'Traceback')
2788
def test_run_bzr_user_error_caught(self):
2789
# Running bzr in blackbox mode, normal/expected/user errors should be
2790
# caught in the regular way and turned into an error message plus exit
2792
transport_server = memory.MemoryServer()
2793
transport_server.start_server()
2794
self.addCleanup(transport_server.stop_server)
2795
url = transport_server.get_url()
2796
self.permit_url(url)
2797
out, err = self.run_bzr(["log", "%s/nonexistantpath" % url], retcode=3)
2798
self.assertEqual(out, '')
2799
self.assertContainsRe(err,
2800
'bzr: ERROR: Not a branch: ".*nonexistantpath/".\n')
2803
class TestTestLoader(tests.TestCase):
2804
"""Tests for the test loader."""
2806
def _get_loader_and_module(self):
2807
"""Gets a TestLoader and a module with one test in it."""
2808
loader = TestUtil.TestLoader()
2810
class Stub(tests.TestCase):
2813
class MyModule(object):
2815
MyModule.a_class = Stub
2817
return loader, module
2819
def test_module_no_load_tests_attribute_loads_classes(self):
2820
loader, module = self._get_loader_and_module()
2821
self.assertEqual(1, loader.loadTestsFromModule(module).countTestCases())
2823
def test_module_load_tests_attribute_gets_called(self):
2824
loader, module = self._get_loader_and_module()
2825
# 'self' is here because we're faking the module with a class. Regular
2826
# load_tests do not need that :)
2827
def load_tests(self, standard_tests, module, loader):
2828
result = loader.suiteClass()
2829
for test in tests.iter_suite_tests(standard_tests):
2830
result.addTests([test, test])
2832
# add a load_tests() method which multiplies the tests from the module.
2833
module.__class__.load_tests = load_tests
2834
self.assertEqual(2, loader.loadTestsFromModule(module).countTestCases())
2836
def test_load_tests_from_module_name_smoke_test(self):
2837
loader = TestUtil.TestLoader()
2838
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
2839
self.assertEquals(['bzrlib.tests.test_sampler.DemoTest.test_nothing'],
2842
def test_load_tests_from_module_name_with_bogus_module_name(self):
2843
loader = TestUtil.TestLoader()
2844
self.assertRaises(ImportError, loader.loadTestsFromModuleName, 'bogus')
2847
class TestTestIdList(tests.TestCase):
2849
def _create_id_list(self, test_list):
2850
return tests.TestIdList(test_list)
2852
def _create_suite(self, test_id_list):
2854
class Stub(tests.TestCase):
2858
def _create_test_id(id):
2861
suite = TestUtil.TestSuite()
2862
for id in test_id_list:
2863
t = Stub('test_foo')
2864
t.id = _create_test_id(id)
2868
def _test_ids(self, test_suite):
2869
"""Get the ids for the tests in a test suite."""
2870
return [t.id() for t in tests.iter_suite_tests(test_suite)]
2872
def test_empty_list(self):
2873
id_list = self._create_id_list([])
2874
self.assertEquals({}, id_list.tests)
2875
self.assertEquals({}, id_list.modules)
2877
def test_valid_list(self):
2878
id_list = self._create_id_list(
2879
['mod1.cl1.meth1', 'mod1.cl1.meth2',
2880
'mod1.func1', 'mod1.cl2.meth2',
2882
'mod1.submod2.cl1.meth1', 'mod1.submod2.cl2.meth2',
2884
self.assertTrue(id_list.refers_to('mod1'))
2885
self.assertTrue(id_list.refers_to('mod1.submod1'))
2886
self.assertTrue(id_list.refers_to('mod1.submod2'))
2887
self.assertTrue(id_list.includes('mod1.cl1.meth1'))
2888
self.assertTrue(id_list.includes('mod1.submod1'))
2889
self.assertTrue(id_list.includes('mod1.func1'))
2891
def test_bad_chars_in_params(self):
2892
id_list = self._create_id_list(['mod1.cl1.meth1(xx.yy)'])
2893
self.assertTrue(id_list.refers_to('mod1'))
2894
self.assertTrue(id_list.includes('mod1.cl1.meth1(xx.yy)'))
2896
def test_module_used(self):
2897
id_list = self._create_id_list(['mod.class.meth'])
2898
self.assertTrue(id_list.refers_to('mod'))
2899
self.assertTrue(id_list.refers_to('mod.class'))
2900
self.assertTrue(id_list.refers_to('mod.class.meth'))
2902
def test_test_suite_matches_id_list_with_unknown(self):
2903
loader = TestUtil.TestLoader()
2904
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
2905
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing',
2907
not_found, duplicates = tests.suite_matches_id_list(suite, test_list)
2908
self.assertEquals(['bogus'], not_found)
2909
self.assertEquals([], duplicates)
2911
def test_suite_matches_id_list_with_duplicates(self):
2912
loader = TestUtil.TestLoader()
2913
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
2914
dupes = loader.suiteClass()
2915
for test in tests.iter_suite_tests(suite):
2917
dupes.addTest(test) # Add it again
2919
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing',]
2920
not_found, duplicates = tests.suite_matches_id_list(
2922
self.assertEquals([], not_found)
2923
self.assertEquals(['bzrlib.tests.test_sampler.DemoTest.test_nothing'],
2927
class TestTestSuite(tests.TestCase):
2929
def test__test_suite_testmod_names(self):
2930
# Test that a plausible list of test module names are returned
2931
# by _test_suite_testmod_names.
2932
test_list = tests._test_suite_testmod_names()
2934
'bzrlib.tests.blackbox',
2935
'bzrlib.tests.per_transport',
2936
'bzrlib.tests.test_selftest',
2940
def test__test_suite_modules_to_doctest(self):
2941
# Test that a plausible list of modules to doctest is returned
2942
# by _test_suite_modules_to_doctest.
2943
test_list = tests._test_suite_modules_to_doctest()
2945
# When docstrings are stripped, there are no modules to doctest
2946
self.assertEqual([], test_list)
2953
def test_test_suite(self):
2954
# test_suite() loads the entire test suite to operate. To avoid this
2955
# overhead, and yet still be confident that things are happening,
2956
# we temporarily replace two functions used by test_suite with
2957
# test doubles that supply a few sample tests to load, and check they
2960
def testmod_names():
2961
calls.append("testmod_names")
2963
'bzrlib.tests.blackbox.test_branch',
2964
'bzrlib.tests.per_transport',
2965
'bzrlib.tests.test_selftest',
2967
self.overrideAttr(tests, '_test_suite_testmod_names', testmod_names)
2969
calls.append("modules_to_doctest")
2972
return ['bzrlib.timestamp']
2973
self.overrideAttr(tests, '_test_suite_modules_to_doctest', doctests)
2974
expected_test_list = [
2976
'bzrlib.tests.blackbox.test_branch.TestBranch.test_branch',
2977
('bzrlib.tests.per_transport.TransportTests'
2978
'.test_abspath(LocalTransport,LocalURLServer)'),
2979
'bzrlib.tests.test_selftest.TestTestSuite.test_test_suite',
2980
# plugins can't be tested that way since selftest may be run with
2983
if __doc__ is not None:
2984
expected_test_list.extend([
2985
# modules_to_doctest
2986
'bzrlib.timestamp.format_highres_date',
2988
suite = tests.test_suite()
2989
self.assertEqual(set(["testmod_names", "modules_to_doctest"]),
2991
self.assertSubset(expected_test_list, _test_ids(suite))
2993
def test_test_suite_list_and_start(self):
2994
# We cannot test this at the same time as the main load, because we want
2995
# to know that starting_with == None works. So a second load is
2996
# incurred - note that the starting_with parameter causes a partial load
2997
# rather than a full load so this test should be pretty quick.
2998
test_list = ['bzrlib.tests.test_selftest.TestTestSuite.test_test_suite']
2999
suite = tests.test_suite(test_list,
3000
['bzrlib.tests.test_selftest.TestTestSuite'])
3001
# test_test_suite_list_and_start is not included
3002
self.assertEquals(test_list, _test_ids(suite))
3005
class TestLoadTestIdList(tests.TestCaseInTempDir):
3007
def _create_test_list_file(self, file_name, content):
3008
fl = open(file_name, 'wt')
3012
def test_load_unknown(self):
3013
self.assertRaises(errors.NoSuchFile,
3014
tests.load_test_id_list, 'i_do_not_exist')
3016
def test_load_test_list(self):
3017
test_list_fname = 'test.list'
3018
self._create_test_list_file(test_list_fname,
3019
'mod1.cl1.meth1\nmod2.cl2.meth2\n')
3020
tlist = tests.load_test_id_list(test_list_fname)
3021
self.assertEquals(2, len(tlist))
3022
self.assertEquals('mod1.cl1.meth1', tlist[0])
3023
self.assertEquals('mod2.cl2.meth2', tlist[1])
3025
def test_load_dirty_file(self):
3026
test_list_fname = 'test.list'
3027
self._create_test_list_file(test_list_fname,
3028
' mod1.cl1.meth1\n\nmod2.cl2.meth2 \n'
3030
tlist = tests.load_test_id_list(test_list_fname)
3031
self.assertEquals(4, len(tlist))
3032
self.assertEquals('mod1.cl1.meth1', tlist[0])
3033
self.assertEquals('', tlist[1])
3034
self.assertEquals('mod2.cl2.meth2', tlist[2])
3035
self.assertEquals('bar baz', tlist[3])
3038
class TestFilteredByModuleTestLoader(tests.TestCase):
3040
def _create_loader(self, test_list):
3041
id_filter = tests.TestIdList(test_list)
3042
loader = TestUtil.FilteredByModuleTestLoader(id_filter.refers_to)
3045
def test_load_tests(self):
3046
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
3047
loader = self._create_loader(test_list)
3048
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3049
self.assertEquals(test_list, _test_ids(suite))
3051
def test_exclude_tests(self):
3052
test_list = ['bogus']
3053
loader = self._create_loader(test_list)
3054
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3055
self.assertEquals([], _test_ids(suite))
3058
class TestFilteredByNameStartTestLoader(tests.TestCase):
3060
def _create_loader(self, name_start):
3061
def needs_module(name):
3062
return name.startswith(name_start) or name_start.startswith(name)
3063
loader = TestUtil.FilteredByModuleTestLoader(needs_module)
3066
def test_load_tests(self):
3067
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
3068
loader = self._create_loader('bzrlib.tests.test_samp')
3070
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3071
self.assertEquals(test_list, _test_ids(suite))
3073
def test_load_tests_inside_module(self):
3074
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
3075
loader = self._create_loader('bzrlib.tests.test_sampler.Demo')
3077
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3078
self.assertEquals(test_list, _test_ids(suite))
3080
def test_exclude_tests(self):
3081
test_list = ['bogus']
3082
loader = self._create_loader('bogus')
3084
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
3085
self.assertEquals([], _test_ids(suite))
3088
class TestTestPrefixRegistry(tests.TestCase):
3090
def _get_registry(self):
3091
tp_registry = tests.TestPrefixAliasRegistry()
3094
def test_register_new_prefix(self):
3095
tpr = self._get_registry()
3096
tpr.register('foo', 'fff.ooo.ooo')
3097
self.assertEquals('fff.ooo.ooo', tpr.get('foo'))
3099
def test_register_existing_prefix(self):
3100
tpr = self._get_registry()
3101
tpr.register('bar', 'bbb.aaa.rrr')
3102
tpr.register('bar', 'bBB.aAA.rRR')
3103
self.assertEquals('bbb.aaa.rrr', tpr.get('bar'))
3104
self.assertThat(self.get_log(),
3105
DocTestMatches("...bar...bbb.aaa.rrr...BB.aAA.rRR",
3108
def test_get_unknown_prefix(self):
3109
tpr = self._get_registry()
3110
self.assertRaises(KeyError, tpr.get, 'I am not a prefix')
3112
def test_resolve_prefix(self):
3113
tpr = self._get_registry()
3114
tpr.register('bar', 'bb.aa.rr')
3115
self.assertEquals('bb.aa.rr', tpr.resolve_alias('bar'))
3117
def test_resolve_unknown_alias(self):
3118
tpr = self._get_registry()
3119
self.assertRaises(errors.BzrCommandError,
3120
tpr.resolve_alias, 'I am not a prefix')
3122
def test_predefined_prefixes(self):
3123
tpr = tests.test_prefix_alias_registry
3124
self.assertEquals('bzrlib', tpr.resolve_alias('bzrlib'))
3125
self.assertEquals('bzrlib.doc', tpr.resolve_alias('bd'))
3126
self.assertEquals('bzrlib.utils', tpr.resolve_alias('bu'))
3127
self.assertEquals('bzrlib.tests', tpr.resolve_alias('bt'))
3128
self.assertEquals('bzrlib.tests.blackbox', tpr.resolve_alias('bb'))
3129
self.assertEquals('bzrlib.plugins', tpr.resolve_alias('bp'))
3132
class TestThreadLeakDetection(tests.TestCase):
3133
"""Ensure when tests leak threads we detect and report it"""
3135
class LeakRecordingResult(tests.ExtendedTestResult):
3137
tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
3139
def _report_thread_leak(self, test, leaks, alive):
3140
self.leaks.append((test, leaks))
3142
def test_testcase_without_addCleanups(self):
3143
"""Check old TestCase instances don't break with leak detection"""
3144
class Test(unittest.TestCase):
3147
result = self.LeakRecordingResult()
3149
result.startTestRun()
3151
result.stopTestRun()
3152
self.assertEqual(result._tests_leaking_threads_count, 0)
3153
self.assertEqual(result.leaks, [])
3155
def test_thread_leak(self):
3156
"""Ensure a thread that outlives the running of a test is reported
3158
Uses a thread that blocks on an event, and is started by the inner
3159
test case. As the thread outlives the inner case's run, it should be
3160
detected as a leak, but the event is then set so that the thread can
3161
be safely joined in cleanup so it's not leaked for real.
3163
event = threading.Event()
3164
thread = threading.Thread(name="Leaker", target=event.wait)
3165
class Test(tests.TestCase):
3166
def test_leak(self):
3168
result = self.LeakRecordingResult()
3169
test = Test("test_leak")
3170
self.addCleanup(thread.join)
3171
self.addCleanup(event.set)
3172
result.startTestRun()
3174
result.stopTestRun()
3175
self.assertEqual(result._tests_leaking_threads_count, 1)
3176
self.assertEqual(result._first_thread_leaker_id, test.id())
3177
self.assertEqual(result.leaks, [(test, set([thread]))])
3178
self.assertContainsString(result.stream.getvalue(), "leaking threads")
3180
def test_multiple_leaks(self):
3181
"""Check multiple leaks are blamed on the test cases at fault
3183
Same concept as the previous test, but has one inner test method that
3184
leaks two threads, and one that doesn't leak at all.
3186
event = threading.Event()
3187
thread_a = threading.Thread(name="LeakerA", target=event.wait)
3188
thread_b = threading.Thread(name="LeakerB", target=event.wait)
3189
thread_c = threading.Thread(name="LeakerC", target=event.wait)
3190
class Test(tests.TestCase):
3191
def test_first_leak(self):
3193
def test_second_no_leak(self):
3195
def test_third_leak(self):
3198
result = self.LeakRecordingResult()
3199
first_test = Test("test_first_leak")
3200
third_test = Test("test_third_leak")
3201
self.addCleanup(thread_a.join)
3202
self.addCleanup(thread_b.join)
3203
self.addCleanup(thread_c.join)
3204
self.addCleanup(event.set)
3205
result.startTestRun()
3207
[first_test, Test("test_second_no_leak"), third_test]
3209
result.stopTestRun()
3210
self.assertEqual(result._tests_leaking_threads_count, 2)
3211
self.assertEqual(result._first_thread_leaker_id, first_test.id())
3212
self.assertEqual(result.leaks, [
3213
(first_test, set([thread_b])),
3214
(third_test, set([thread_a, thread_c]))])
3215
self.assertContainsString(result.stream.getvalue(), "leaking threads")
3218
class TestPostMortemDebugging(tests.TestCase):
3219
"""Check post mortem debugging works when tests fail or error"""
3221
class TracebackRecordingResult(tests.ExtendedTestResult):
3223
tests.ExtendedTestResult.__init__(self, StringIO(), 0, 1)
3224
self.postcode = None
3225
def _post_mortem(self, tb=None):
3226
"""Record the code object at the end of the current traceback"""
3227
tb = tb or sys.exc_info()[2]
3230
while next is not None:
3233
self.postcode = tb.tb_frame.f_code
3234
def report_error(self, test, err):
3236
def report_failure(self, test, err):
3239
def test_location_unittest_error(self):
3240
"""Needs right post mortem traceback with erroring unittest case"""
3241
class Test(unittest.TestCase):
3244
result = self.TracebackRecordingResult()
3246
self.assertEqual(result.postcode, Test.runTest.func_code)
3248
def test_location_unittest_failure(self):
3249
"""Needs right post mortem traceback with failing unittest case"""
3250
class Test(unittest.TestCase):
3252
raise self.failureException
3253
result = self.TracebackRecordingResult()
3255
self.assertEqual(result.postcode, Test.runTest.func_code)
3257
def test_location_bt_error(self):
3258
"""Needs right post mortem traceback with erroring bzrlib.tests case"""
3259
class Test(tests.TestCase):
3260
def test_error(self):
3262
result = self.TracebackRecordingResult()
3263
Test("test_error").run(result)
3264
self.assertEqual(result.postcode, Test.test_error.func_code)
3266
def test_location_bt_failure(self):
3267
"""Needs right post mortem traceback with failing bzrlib.tests case"""
3268
class Test(tests.TestCase):
3269
def test_failure(self):
3270
raise self.failureException
3271
result = self.TracebackRecordingResult()
3272
Test("test_failure").run(result)
3273
self.assertEqual(result.postcode, Test.test_failure.func_code)
3275
def test_env_var_triggers_post_mortem(self):
3276
"""Check pdb.post_mortem is called iff BZR_TEST_PDB is set"""
3278
result = tests.ExtendedTestResult(StringIO(), 0, 1)
3279
post_mortem_calls = []
3280
self.overrideAttr(pdb, "post_mortem", post_mortem_calls.append)
3281
self.overrideEnv('BZR_TEST_PDB', None)
3282
result._post_mortem(1)
3283
self.overrideEnv('BZR_TEST_PDB', 'on')
3284
result._post_mortem(2)
3285
self.assertEqual([2], post_mortem_calls)
3288
class TestRunSuite(tests.TestCase):
3290
def test_runner_class(self):
3291
"""run_suite accepts and uses a runner_class keyword argument."""
3292
class Stub(tests.TestCase):
3295
suite = Stub("test_foo")
3297
class MyRunner(tests.TextTestRunner):
3298
def run(self, test):
3300
return tests.ExtendedTestResult(self.stream, self.descriptions,
3302
tests.run_suite(suite, runner_class=MyRunner, stream=StringIO())
3303
self.assertLength(1, calls)
3306
class _Selftest(object):
3307
"""Mixin for tests needing full selftest output"""
3309
def _inject_stream_into_subunit(self, stream):
3310
"""To be overridden by subclasses that run tests out of process"""
3312
def _run_selftest(self, **kwargs):
3314
self._inject_stream_into_subunit(sio)
3315
tests.selftest(stream=sio, stop_on_failure=False, **kwargs)
3316
return sio.getvalue()
3319
class _ForkedSelftest(_Selftest):
3320
"""Mixin for tests needing full selftest output with forked children"""
3322
_test_needs_features = [features.subunit]
3324
def _inject_stream_into_subunit(self, stream):
3325
"""Monkey-patch subunit so the extra output goes to stream not stdout
3327
Some APIs need rewriting so this kind of bogus hackery can be replaced
3328
by passing the stream param from run_tests down into ProtocolTestCase.
3330
from subunit import ProtocolTestCase
3331
_original_init = ProtocolTestCase.__init__
3332
def _init_with_passthrough(self, *args, **kwargs):
3333
_original_init(self, *args, **kwargs)
3334
self._passthrough = stream
3335
self.overrideAttr(ProtocolTestCase, "__init__", _init_with_passthrough)
3337
def _run_selftest(self, **kwargs):
3338
# GZ 2011-05-26: Add a PosixSystem feature so this check can go away
3339
if getattr(os, "fork", None) is None:
3340
raise tests.TestNotApplicable("Platform doesn't support forking")
3341
# Make sure the fork code is actually invoked by claiming two cores
3342
self.overrideAttr(osutils, "local_concurrency", lambda: 2)
3343
kwargs.setdefault("suite_decorators", []).append(tests.fork_decorator)
3344
return super(_ForkedSelftest, self)._run_selftest(**kwargs)
3347
class TestParallelFork(_ForkedSelftest, tests.TestCase):
3348
"""Check operation of --parallel=fork selftest option"""
3350
def test_error_in_child_during_fork(self):
3351
"""Error in a forked child during test setup should get reported"""
3352
class Test(tests.TestCase):
3353
def testMethod(self):
3355
# We don't care what, just break something that a child will run
3356
self.overrideAttr(tests, "workaround_zealous_crypto_random", None)
3357
out = self._run_selftest(test_suite_factory=Test)
3358
# Lines from the tracebacks of the two child processes may be mixed
3359
# together due to the way subunit parses and forwards the streams,
3360
# so permit extra lines between each part of the error output.
3361
self.assertContainsRe(out,
3364
".+ in fork_for_tests\n"
3366
"\s*workaround_zealous_crypto_random\(\)\n"
3371
class TestUncollectedWarnings(_Selftest, tests.TestCase):
3372
"""Check a test case still alive after being run emits a warning"""
3374
class Test(tests.TestCase):
3375
def test_pass(self):
3377
def test_self_ref(self):
3378
self.also_self = self.test_self_ref
3379
def test_skip(self):
3380
self.skip("Don't need")
3382
def _get_suite(self):
3383
return TestUtil.TestSuite([
3384
self.Test("test_pass"),
3385
self.Test("test_self_ref"),
3386
self.Test("test_skip"),
3389
def _run_selftest_with_suite(self, **kwargs):
3390
old_flags = tests.selftest_debug_flags
3391
tests.selftest_debug_flags = old_flags.union(["uncollected_cases"])
3392
gc_on = gc.isenabled()
3396
output = self._run_selftest(test_suite_factory=self._get_suite,
3401
tests.selftest_debug_flags = old_flags
3402
self.assertNotContainsRe(output, "Uncollected test case.*test_pass")
3403
self.assertContainsRe(output, "Uncollected test case.*test_self_ref")
3406
def test_testsuite(self):
3407
self._run_selftest_with_suite()
3409
def test_pattern(self):
3410
out = self._run_selftest_with_suite(pattern="test_(?:pass|self_ref)$")
3411
self.assertNotContainsRe(out, "test_skip")
3413
def test_exclude_pattern(self):
3414
out = self._run_selftest_with_suite(exclude_pattern="test_skip$")
3415
self.assertNotContainsRe(out, "test_skip")
3417
def test_random_seed(self):
3418
self._run_selftest_with_suite(random_seed="now")
3420
def test_matching_tests_first(self):
3421
self._run_selftest_with_suite(matching_tests_first=True,
3422
pattern="test_self_ref$")
3424
def test_starting_with_and_exclude(self):
3425
out = self._run_selftest_with_suite(starting_with=["bt."],
3426
exclude_pattern="test_skip$")
3427
self.assertNotContainsRe(out, "test_skip")
3429
def test_additonal_decorator(self):
3430
out = self._run_selftest_with_suite(
3431
suite_decorators=[tests.TestDecorator])
3434
class TestUncollectedWarningsSubunit(TestUncollectedWarnings):
3435
"""Check warnings from tests staying alive are emitted with subunit"""
3437
_test_needs_features = [features.subunit]
3439
def _run_selftest_with_suite(self, **kwargs):
3440
return TestUncollectedWarnings._run_selftest_with_suite(self,
3441
runner_class=tests.SubUnitBzrRunner, **kwargs)
3444
class TestUncollectedWarningsForked(_ForkedSelftest, TestUncollectedWarnings):
3445
"""Check warnings from tests staying alive are emitted when forking"""
3448
class TestEnvironHandling(tests.TestCase):
3450
def test_overrideEnv_None_called_twice_doesnt_leak(self):
3451
self.assertFalse('MYVAR' in os.environ)
3452
self.overrideEnv('MYVAR', '42')
3453
# We use an embedded test to make sure we fix the _captureVar bug
3454
class Test(tests.TestCase):
3456
# The first call save the 42 value
3457
self.overrideEnv('MYVAR', None)
3458
self.assertEquals(None, os.environ.get('MYVAR'))
3459
# Make sure we can call it twice
3460
self.overrideEnv('MYVAR', None)
3461
self.assertEquals(None, os.environ.get('MYVAR'))
3463
result = tests.TextTestResult(output, 0, 1)
3464
Test('test_me').run(result)
3465
if not result.wasStrictlySuccessful():
3466
self.fail(output.getvalue())
3467
# We get our value back
3468
self.assertEquals('42', os.environ.get('MYVAR'))
3471
class TestIsolatedEnv(tests.TestCase):
3472
"""Test isolating tests from os.environ.
3474
Since we use tests that are already isolated from os.environ a bit of care
3475
should be taken when designing the tests to avoid bootstrap side-effects.
3476
The tests start an already clean os.environ which allow doing valid
3477
assertions about which variables are present or not and design tests around
3481
class ScratchMonkey(tests.TestCase):
3486
def test_basics(self):
3487
# Make sure we know the definition of BZR_HOME: not part of os.environ
3488
# for tests.TestCase.
3489
self.assertTrue('BZR_HOME' in tests.isolated_environ)
3490
self.assertEquals(None, tests.isolated_environ['BZR_HOME'])
3491
# Being part of isolated_environ, BZR_HOME should not appear here
3492
self.assertFalse('BZR_HOME' in os.environ)
3493
# Make sure we know the definition of LINES: part of os.environ for
3495
self.assertTrue('LINES' in tests.isolated_environ)
3496
self.assertEquals('25', tests.isolated_environ['LINES'])
3497
self.assertEquals('25', os.environ['LINES'])
3499
def test_injecting_unknown_variable(self):
3500
# BZR_HOME is known to be absent from os.environ
3501
test = self.ScratchMonkey('test_me')
3502
tests.override_os_environ(test, {'BZR_HOME': 'foo'})
3503
self.assertEquals('foo', os.environ['BZR_HOME'])
3504
tests.restore_os_environ(test)
3505
self.assertFalse('BZR_HOME' in os.environ)
3507
def test_injecting_known_variable(self):
3508
test = self.ScratchMonkey('test_me')
3509
# LINES is known to be present in os.environ
3510
tests.override_os_environ(test, {'LINES': '42'})
3511
self.assertEquals('42', os.environ['LINES'])
3512
tests.restore_os_environ(test)
3513
self.assertEquals('25', os.environ['LINES'])
3515
def test_deleting_variable(self):
3516
test = self.ScratchMonkey('test_me')
3517
# LINES is known to be present in os.environ
3518
tests.override_os_environ(test, {'LINES': None})
3519
self.assertTrue('LINES' not in os.environ)
3520
tests.restore_os_environ(test)
3521
self.assertEquals('25', os.environ['LINES'])
3524
class TestDocTestSuiteIsolation(tests.TestCase):
3525
"""Test that `tests.DocTestSuite` isolates doc tests from os.environ.
3527
Since tests.TestCase alreay provides an isolation from os.environ, we use
3528
the clean environment as a base for testing. To precisely capture the
3529
isolation provided by tests.DocTestSuite, we use doctest.DocTestSuite to
3532
We want to make sure `tests.DocTestSuite` respect `tests.isolated_environ`,
3533
not `os.environ` so each test overrides it to suit its needs.
3537
def get_doctest_suite_for_string(self, klass, string):
3538
class Finder(doctest.DocTestFinder):
3540
def find(*args, **kwargs):
3541
test = doctest.DocTestParser().get_doctest(
3542
string, {}, 'foo', 'foo.py', 0)
3545
suite = klass(test_finder=Finder())
3548
def run_doctest_suite_for_string(self, klass, string):
3549
suite = self.get_doctest_suite_for_string(klass, string)
3551
result = tests.TextTestResult(output, 0, 1)
3553
return result, output
3555
def assertDocTestStringSucceds(self, klass, string):
3556
result, output = self.run_doctest_suite_for_string(klass, string)
3557
if not result.wasStrictlySuccessful():
3558
self.fail(output.getvalue())
3560
def assertDocTestStringFails(self, klass, string):
3561
result, output = self.run_doctest_suite_for_string(klass, string)
3562
if result.wasStrictlySuccessful():
3563
self.fail(output.getvalue())
3565
def test_injected_variable(self):
3566
self.overrideAttr(tests, 'isolated_environ', {'LINES': '42'})
3569
>>> os.environ['LINES']
3572
# doctest.DocTestSuite fails as it sees '25'
3573
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3574
# tests.DocTestSuite sees '42'
3575
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
3577
def test_deleted_variable(self):
3578
self.overrideAttr(tests, 'isolated_environ', {'LINES': None})
3581
>>> os.environ.get('LINES')
3583
# doctest.DocTestSuite fails as it sees '25'
3584
self.assertDocTestStringFails(doctest.DocTestSuite, test)
3585
# tests.DocTestSuite sees None
3586
self.assertDocTestStringSucceds(tests.IsolatedDocTestSuite, test)
3589
class TestSelftestExcludePatterns(tests.TestCase):
3592
super(TestSelftestExcludePatterns, self).setUp()
3593
self.overrideAttr(tests, 'test_suite', self.suite_factory)
3595
def suite_factory(self, keep_only=None, starting_with=None):
3596
"""A test suite factory with only a few tests."""
3597
class Test(tests.TestCase):
3599
# We don't need the full class path
3600
return self._testMethodName
3607
return TestUtil.TestSuite([Test("a"), Test("b"), Test("c")])
3609
def assertTestList(self, expected, *selftest_args):
3610
# We rely on setUp installing the right test suite factory so we can
3611
# test at the command level without loading the whole test suite
3612
out, err = self.run_bzr(('selftest', '--list') + selftest_args)
3613
actual = out.splitlines()
3614
self.assertEquals(expected, actual)
3616
def test_full_list(self):
3617
self.assertTestList(['a', 'b', 'c'])
3619
def test_single_exclude(self):
3620
self.assertTestList(['b', 'c'], '-x', 'a')
3622
def test_mutiple_excludes(self):
3623
self.assertTestList(['c'], '-x', 'a', '-x', 'b')
3626
class TestCounterHooks(tests.TestCase, SelfTestHelper):
3628
_test_needs_features = [features.subunit]
3631
super(TestCounterHooks, self).setUp()
3632
class Test(tests.TestCase):
3635
super(Test, self).setUp()
3636
self.hooks = hooks.Hooks()
3637
self.hooks.add_hook('myhook', 'Foo bar blah', (2,4))
3638
self.install_counter_hook(self.hooks, 'myhook')
3643
def run_hook_once(self):
3644
for hook in self.hooks['myhook']:
3647
self.test_class = Test
3649
def assertHookCalls(self, expected_calls, test_name):
3650
test = self.test_class(test_name)
3651
result = unittest.TestResult()
3653
self.assertTrue(hasattr(test, '_counters'))
3654
self.assertTrue(test._counters.has_key('myhook'))
3655
self.assertEquals(expected_calls, test._counters['myhook'])
3657
def test_no_hook(self):
3658
self.assertHookCalls(0, 'no_hook')
3660
def test_run_hook_once(self):
3661
tt = features.testtools
3662
if tt.module.__version__ < (0, 9, 8):
3663
raise tests.TestSkipped('testtools-0.9.8 required for addDetail')
3664
self.assertHookCalls(1, 'run_hook_once')