1
# Copyright (C) 2005, 2006, 2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
"""Tests for the test framework."""
21
from StringIO import StringIO
36
from bzrlib.progress import _BaseProgressBar
37
from bzrlib.repofmt import weaverepo
38
from bzrlib.symbol_versioning import (
43
from bzrlib.tests import (
50
TestCaseWithMemoryTransport,
51
TestCaseWithTransport,
60
exclude_tests_by_condition,
62
filter_suite_by_condition,
72
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
73
from bzrlib.tests.TestUtil import _load_module_by_name
74
from bzrlib.trace import note
75
from bzrlib.transport.memory import MemoryServer, MemoryTransport
76
from bzrlib.version import _get_bzr_source_tree
79
class SelftestTests(TestCase):
81
def test_import_tests(self):
82
mod = _load_module_by_name('bzrlib.tests.test_selftest')
83
self.assertEqual(mod.SelftestTests, SelftestTests)
85
def test_import_test_failure(self):
86
self.assertRaises(ImportError,
90
class MetaTestLog(TestCase):
92
def test_logging(self):
93
"""Test logs are captured when a test fails."""
94
self.log('a test message')
95
self._log_file.flush()
96
self.assertContainsRe(self._get_log(keep_log_file=True),
100
class TestTreeShape(TestCaseInTempDir):
102
def test_unicode_paths(self):
103
filename = u'hell\u00d8'
105
self.build_tree_contents([(filename, 'contents of hello')])
106
except UnicodeEncodeError:
107
raise TestSkipped("can't build unicode working tree in "
108
"filesystem encoding %s" % sys.getfilesystemencoding())
109
self.failUnlessExists(filename)
112
class TestTransportProviderAdapter(TestCase):
113
"""A group of tests that test the transport implementation adaption core.
115
This is a meta test that the tests are applied to all available
118
This will be generalised in the future which is why it is in this
119
test file even though it is specific to transport tests at the moment.
122
def test_get_transport_permutations(self):
123
# this checks that we the module get_test_permutations call
124
# is made by the adapter get_transport_test_permitations method.
125
class MockModule(object):
126
def get_test_permutations(self):
127
return sample_permutation
128
sample_permutation = [(1,2), (3,4)]
129
from bzrlib.tests.test_transport_implementations \
130
import TransportTestProviderAdapter
131
adapter = TransportTestProviderAdapter()
132
self.assertEqual(sample_permutation,
133
adapter.get_transport_test_permutations(MockModule()))
135
def test_adapter_checks_all_modules(self):
136
# this checks that the adapter returns as many permurtations as
137
# there are in all the registered# transport modules for there
138
# - we assume if this matches its probably doing the right thing
139
# especially in combination with the tests for setting the right
141
from bzrlib.tests.test_transport_implementations \
142
import TransportTestProviderAdapter
143
from bzrlib.transport import _get_transport_modules
144
modules = _get_transport_modules()
145
permutation_count = 0
146
for module in modules:
148
permutation_count += len(reduce(getattr,
149
(module + ".get_test_permutations").split('.')[1:],
150
__import__(module))())
151
except errors.DependencyNotPresent:
153
input_test = TestTransportProviderAdapter(
154
"test_adapter_sets_transport_class")
155
adapter = TransportTestProviderAdapter()
156
self.assertEqual(permutation_count,
157
len(list(iter(adapter.adapt(input_test)))))
159
def test_adapter_sets_transport_class(self):
160
# Check that the test adapter inserts a transport and server into the
163
# This test used to know about all the possible transports and the
164
# order they were returned but that seems overly brittle (mbp
166
from bzrlib.tests.test_transport_implementations \
167
import TransportTestProviderAdapter
168
scenarios = TransportTestProviderAdapter().scenarios
169
# there are at least that many builtin transports
170
self.assertTrue(len(scenarios) > 6)
171
one_scenario = scenarios[0]
172
self.assertIsInstance(one_scenario[0], str)
173
self.assertTrue(issubclass(one_scenario[1]["transport_class"],
174
bzrlib.transport.Transport))
175
self.assertTrue(issubclass(one_scenario[1]["transport_server"],
176
bzrlib.transport.Server))
179
class TestBranchProviderAdapter(TestCase):
180
"""A group of tests that test the branch implementation test adapter."""
182
def test_constructor(self):
183
# check that constructor parameters are passed through to the adapted
185
from bzrlib.tests.branch_implementations import BranchTestProviderAdapter
188
formats = [("c", "C"), ("d", "D")]
189
adapter = BranchTestProviderAdapter(server1, server2, formats)
190
self.assertEqual(2, len(adapter.scenarios))
193
{'branch_format': 'c',
194
'bzrdir_format': 'C',
195
'transport_readonly_server': 'b',
196
'transport_server': 'a'}),
198
{'branch_format': 'd',
199
'bzrdir_format': 'D',
200
'transport_readonly_server': 'b',
201
'transport_server': 'a'})],
205
class TestBzrDirProviderAdapter(TestCase):
206
"""A group of tests that test the bzr dir implementation test adapter."""
208
def test_adapted_tests(self):
209
# check that constructor parameters are passed through to the adapted
211
from bzrlib.tests.bzrdir_implementations import BzrDirTestProviderAdapter
216
adapter = BzrDirTestProviderAdapter(vfs_factory,
217
server1, server2, formats)
220
{'bzrdir_format': 'c',
221
'transport_readonly_server': 'b',
222
'transport_server': 'a',
223
'vfs_transport_factory': 'v'}),
225
{'bzrdir_format': 'd',
226
'transport_readonly_server': 'b',
227
'transport_server': 'a',
228
'vfs_transport_factory': 'v'})],
232
class TestRepositoryProviderAdapter(TestCase):
233
"""A group of tests that test the repository implementation test adapter."""
235
def test_constructor(self):
236
# check that constructor parameters are passed through to the
238
from bzrlib.tests.repository_implementations import RepositoryTestProviderAdapter
241
formats = [("c", "C"), ("d", "D")]
242
adapter = RepositoryTestProviderAdapter(server1, server2, formats)
245
{'bzrdir_format': 'C',
246
'repository_format': 'c',
247
'transport_readonly_server': 'b',
248
'transport_server': 'a'}),
250
{'bzrdir_format': 'D',
251
'repository_format': 'd',
252
'transport_readonly_server': 'b',
253
'transport_server': 'a'})],
256
def test_setting_vfs_transport(self):
257
"""The vfs_transport_factory can be set optionally."""
258
from bzrlib.tests.repository_implementations import RepositoryTestProviderAdapter
259
formats = [("a", "b"), ("c", "d")]
260
adapter = RepositoryTestProviderAdapter(None, None, formats,
261
vfs_transport_factory="vfs")
264
{'bzrdir_format': 'b',
265
'repository_format': 'a',
266
'transport_readonly_server': None,
267
'transport_server': None,
268
'vfs_transport_factory': 'vfs'}),
270
{'bzrdir_format': 'd',
271
'repository_format': 'c',
272
'transport_readonly_server': None,
273
'transport_server': None,
274
'vfs_transport_factory': 'vfs'})],
277
def test_formats_to_scenarios(self):
278
"""The adapter can generate all the scenarios needed."""
279
from bzrlib.tests.repository_implementations import RepositoryTestProviderAdapter
280
no_vfs_adapter = RepositoryTestProviderAdapter("server", "readonly",
282
vfs_adapter = RepositoryTestProviderAdapter("server", "readonly",
283
[], vfs_transport_factory="vfs")
284
# no_vfs generate scenarios without vfs_transport_factor
285
formats = [("c", "C"), (1, "D")]
288
{'bzrdir_format': 'C',
289
'repository_format': 'c',
290
'transport_readonly_server': 'readonly',
291
'transport_server': 'server'}),
293
{'bzrdir_format': 'D',
294
'repository_format': 1,
295
'transport_readonly_server': 'readonly',
296
'transport_server': 'server'})],
297
no_vfs_adapter.formats_to_scenarios(formats))
300
{'bzrdir_format': 'C',
301
'repository_format': 'c',
302
'transport_readonly_server': 'readonly',
303
'transport_server': 'server',
304
'vfs_transport_factory': 'vfs'}),
306
{'bzrdir_format': 'D',
307
'repository_format': 1,
308
'transport_readonly_server': 'readonly',
309
'transport_server': 'server',
310
'vfs_transport_factory': 'vfs'})],
311
vfs_adapter.formats_to_scenarios(formats))
314
class TestTestScenarioApplier(TestCase):
315
"""Tests for the test adaption facilities."""
317
def test_adapt_applies_scenarios(self):
318
from bzrlib.tests.repository_implementations import TestScenarioApplier
319
input_test = TestTestScenarioApplier("test_adapt_test_to_scenario")
320
adapter = TestScenarioApplier()
321
adapter.scenarios = [("1", "dict"), ("2", "settings")]
323
def capture_call(test, scenario):
324
calls.append((test, scenario))
326
adapter.adapt_test_to_scenario = capture_call
327
adapter.adapt(input_test)
328
self.assertEqual([(input_test, ("1", "dict")),
329
(input_test, ("2", "settings"))], calls)
331
def test_adapt_test_to_scenario(self):
332
from bzrlib.tests.repository_implementations import TestScenarioApplier
333
input_test = TestTestScenarioApplier("test_adapt_test_to_scenario")
334
adapter = TestScenarioApplier()
335
# setup two adapted tests
336
adapted_test1 = adapter.adapt_test_to_scenario(input_test,
338
{"bzrdir_format":"bzr_format",
339
"repository_format":"repo_fmt",
340
"transport_server":"transport_server",
341
"transport_readonly_server":"readonly-server"}))
342
adapted_test2 = adapter.adapt_test_to_scenario(input_test,
343
("new id 2", {"bzrdir_format":None}))
344
# input_test should have been altered.
345
self.assertRaises(AttributeError, getattr, input_test, "bzrdir_format")
346
# the new tests are mutually incompatible, ensuring it has
347
# made new ones, and unspecified elements in the scenario
348
# should not have been altered.
349
self.assertEqual("bzr_format", adapted_test1.bzrdir_format)
350
self.assertEqual("repo_fmt", adapted_test1.repository_format)
351
self.assertEqual("transport_server", adapted_test1.transport_server)
352
self.assertEqual("readonly-server",
353
adapted_test1.transport_readonly_server)
355
"bzrlib.tests.test_selftest.TestTestScenarioApplier."
356
"test_adapt_test_to_scenario(new id)",
358
self.assertEqual(None, adapted_test2.bzrdir_format)
360
"bzrlib.tests.test_selftest.TestTestScenarioApplier."
361
"test_adapt_test_to_scenario(new id 2)",
365
class TestInterRepositoryProviderAdapter(TestCase):
366
"""A group of tests that test the InterRepository test adapter."""
368
def test_adapted_tests(self):
369
# check that constructor parameters are passed through to the adapted
371
from bzrlib.tests.interrepository_implementations import \
372
InterRepositoryTestProviderAdapter
375
formats = [(str, "C1", "C2"), (int, "D1", "D2")]
376
adapter = InterRepositoryTestProviderAdapter(server1, server2, formats)
379
{'interrepo_class': str,
380
'repository_format': 'C1',
381
'repository_format_to': 'C2',
382
'transport_readonly_server': 'b',
383
'transport_server': 'a'}),
385
{'interrepo_class': int,
386
'repository_format': 'D1',
387
'repository_format_to': 'D2',
388
'transport_readonly_server': 'b',
389
'transport_server': 'a'})],
390
adapter.formats_to_scenarios(formats))
393
class TestInterVersionedFileProviderAdapter(TestCase):
394
"""A group of tests that test the InterVersionedFile test adapter."""
396
def test_scenarios(self):
397
# check that constructor parameters are passed through to the adapted
399
from bzrlib.tests.interversionedfile_implementations \
400
import InterVersionedFileTestProviderAdapter
403
formats = [(str, "C1", "C2"), (int, "D1", "D2")]
404
adapter = InterVersionedFileTestProviderAdapter(server1, server2, formats)
407
{'interversionedfile_class':str,
408
'transport_readonly_server': 'b',
409
'transport_server': 'a',
410
'versionedfile_factory': 'C1',
411
'versionedfile_factory_to': 'C2'}),
413
{'interversionedfile_class': int,
414
'transport_readonly_server': 'b',
415
'transport_server': 'a',
416
'versionedfile_factory': 'D1',
417
'versionedfile_factory_to': 'D2'})],
421
class TestRevisionStoreProviderAdapter(TestCase):
422
"""A group of tests that test the RevisionStore test adapter."""
424
def test_scenarios(self):
425
# check that constructor parameters are passed through to the adapted
427
from bzrlib.tests.revisionstore_implementations \
428
import RevisionStoreTestProviderAdapter
429
# revision stores need a store factory - i.e. RevisionKnit
430
#, a readonly and rw transport
434
store_factories = ["c", "d"]
435
adapter = RevisionStoreTestProviderAdapter(server1, server2, store_factories)
438
{'store_factory': 'c',
439
'transport_readonly_server': 'b',
440
'transport_server': 'a'}),
442
{'store_factory': 'd',
443
'transport_readonly_server': 'b',
444
'transport_server': 'a'})],
448
class TestWorkingTreeProviderAdapter(TestCase):
449
"""A group of tests that test the workingtree implementation test adapter."""
451
def test_scenarios(self):
452
# check that constructor parameters are passed through to the adapted
454
from bzrlib.tests.workingtree_implementations \
455
import WorkingTreeTestProviderAdapter
458
formats = [("c", "C"), ("d", "D")]
459
adapter = WorkingTreeTestProviderAdapter(server1, server2, formats)
462
{'bzrdir_format': 'C',
463
'transport_readonly_server': 'b',
464
'transport_server': 'a',
465
'workingtree_format': 'c'}),
467
{'bzrdir_format': 'D',
468
'transport_readonly_server': 'b',
469
'transport_server': 'a',
470
'workingtree_format': 'd'})],
474
class TestTreeProviderAdapter(TestCase):
475
"""Test the setup of tree_implementation tests."""
477
def test_adapted_tests(self):
478
# the tree implementation adapter is meant to setup one instance for
479
# each working tree format, and one additional instance that will
480
# use the default wt format, but create a revision tree for the tests.
481
# this means that the wt ones should have the workingtree_to_test_tree
482
# attribute set to 'return_parameter' and the revision one set to
483
# revision_tree_from_workingtree.
485
from bzrlib.tests.tree_implementations import (
486
TreeTestProviderAdapter,
488
revision_tree_from_workingtree
490
from bzrlib.workingtree import WorkingTreeFormat, WorkingTreeFormat3
491
input_test = TestTreeProviderAdapter(
492
"test_adapted_tests")
495
formats = [("c", "C"), ("d", "D")]
496
adapter = TreeTestProviderAdapter(server1, server2, formats)
497
suite = adapter.adapt(input_test)
498
tests = list(iter(suite))
499
self.assertEqual(4, len(tests))
500
# this must match the default format setp up in
501
# TreeTestProviderAdapter.adapt
502
default_format = WorkingTreeFormat3
503
self.assertEqual(tests[0].workingtree_format, formats[0][0])
504
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
505
self.assertEqual(tests[0].transport_server, server1)
506
self.assertEqual(tests[0].transport_readonly_server, server2)
507
self.assertEqual(tests[0].workingtree_to_test_tree, return_parameter)
508
self.assertEqual(tests[1].workingtree_format, formats[1][0])
509
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
510
self.assertEqual(tests[1].transport_server, server1)
511
self.assertEqual(tests[1].transport_readonly_server, server2)
512
self.assertEqual(tests[1].workingtree_to_test_tree, return_parameter)
513
self.assertIsInstance(tests[2].workingtree_format, default_format)
514
#self.assertEqual(tests[2].bzrdir_format,
515
# default_format._matchingbzrdir)
516
self.assertEqual(tests[2].transport_server, server1)
517
self.assertEqual(tests[2].transport_readonly_server, server2)
518
self.assertEqual(tests[2].workingtree_to_test_tree,
519
revision_tree_from_workingtree)
522
class TestInterTreeProviderAdapter(TestCase):
523
"""A group of tests that test the InterTreeTestAdapter."""
525
def test_adapted_tests(self):
526
# check that constructor parameters are passed through to the adapted
528
# for InterTree tests we want the machinery to bring up two trees in
529
# each instance: the base one, and the one we are interacting with.
530
# because each optimiser can be direction specific, we need to test
531
# each optimiser in its chosen direction.
532
# unlike the TestProviderAdapter we dont want to automatically add a
533
# parameterized one for WorkingTree - the optimisers will tell us what
535
from bzrlib.tests.tree_implementations import (
537
revision_tree_from_workingtree
539
from bzrlib.tests.intertree_implementations import (
540
InterTreeTestProviderAdapter,
542
from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
543
input_test = TestInterTreeProviderAdapter(
544
"test_adapted_tests")
547
format1 = WorkingTreeFormat2()
548
format2 = WorkingTreeFormat3()
549
formats = [(str, format1, format2, "converter1"),
550
(int, format2, format1, "converter2")]
551
adapter = InterTreeTestProviderAdapter(server1, server2, formats)
552
suite = adapter.adapt(input_test)
553
tests = list(iter(suite))
554
self.assertEqual(2, len(tests))
555
self.assertEqual(tests[0].intertree_class, formats[0][0])
556
self.assertEqual(tests[0].workingtree_format, formats[0][1])
557
self.assertEqual(tests[0].workingtree_format_to, formats[0][2])
558
self.assertEqual(tests[0].mutable_trees_to_test_trees, formats[0][3])
559
self.assertEqual(tests[0].workingtree_to_test_tree, return_parameter)
560
self.assertEqual(tests[0].transport_server, server1)
561
self.assertEqual(tests[0].transport_readonly_server, server2)
562
self.assertEqual(tests[1].intertree_class, formats[1][0])
563
self.assertEqual(tests[1].workingtree_format, formats[1][1])
564
self.assertEqual(tests[1].workingtree_format_to, formats[1][2])
565
self.assertEqual(tests[1].mutable_trees_to_test_trees, formats[1][3])
566
self.assertEqual(tests[1].workingtree_to_test_tree, return_parameter)
567
self.assertEqual(tests[1].transport_server, server1)
568
self.assertEqual(tests[1].transport_readonly_server, server2)
571
class TestTestCaseInTempDir(TestCaseInTempDir):
573
def test_home_is_not_working(self):
574
self.assertNotEqual(self.test_dir, self.test_home_dir)
575
cwd = osutils.getcwd()
576
self.assertIsSameRealPath(self.test_dir, cwd)
577
self.assertIsSameRealPath(self.test_home_dir, os.environ['HOME'])
580
class TestTestCaseWithMemoryTransport(TestCaseWithMemoryTransport):
582
def test_home_is_non_existant_dir_under_root(self):
583
"""The test_home_dir for TestCaseWithMemoryTransport is missing.
585
This is because TestCaseWithMemoryTransport is for tests that do not
586
need any disk resources: they should be hooked into bzrlib in such a
587
way that no global settings are being changed by the test (only a
588
few tests should need to do that), and having a missing dir as home is
589
an effective way to ensure that this is the case.
591
self.assertIsSameRealPath(
592
self.TEST_ROOT + "/MemoryTransportMissingHomeDir",
594
self.assertIsSameRealPath(self.test_home_dir, os.environ['HOME'])
596
def test_cwd_is_TEST_ROOT(self):
597
self.assertIsSameRealPath(self.test_dir, self.TEST_ROOT)
598
cwd = osutils.getcwd()
599
self.assertIsSameRealPath(self.test_dir, cwd)
601
def test_make_branch_and_memory_tree(self):
602
"""In TestCaseWithMemoryTransport we should not make the branch on disk.
604
This is hard to comprehensively robustly test, so we settle for making
605
a branch and checking no directory was created at its relpath.
607
tree = self.make_branch_and_memory_tree('dir')
608
# Guard against regression into MemoryTransport leaking
609
# files to disk instead of keeping them in memory.
610
self.failIf(osutils.lexists('dir'))
611
self.assertIsInstance(tree, memorytree.MemoryTree)
613
def test_make_branch_and_memory_tree_with_format(self):
614
"""make_branch_and_memory_tree should accept a format option."""
615
format = bzrdir.BzrDirMetaFormat1()
616
format.repository_format = weaverepo.RepositoryFormat7()
617
tree = self.make_branch_and_memory_tree('dir', format=format)
618
# Guard against regression into MemoryTransport leaking
619
# files to disk instead of keeping them in memory.
620
self.failIf(osutils.lexists('dir'))
621
self.assertIsInstance(tree, memorytree.MemoryTree)
622
self.assertEqual(format.repository_format.__class__,
623
tree.branch.repository._format.__class__)
625
def test_safety_net(self):
626
"""No test should modify the safety .bzr directory.
628
We just test that the _check_safety_net private method raises
629
AssertionError, it's easier than building a test suite with the same
632
# Oops, a commit in the current directory (i.e. without local .bzr
633
# directory) will crawl up the hierarchy to find a .bzr directory.
634
self.run_bzr(['commit', '-mfoo', '--unchanged'])
635
# But we have a safety net in place.
636
self.assertRaises(AssertionError, self._check_safety_net)
639
class TestTestCaseWithTransport(TestCaseWithTransport):
640
"""Tests for the convenience functions TestCaseWithTransport introduces."""
642
def test_get_readonly_url_none(self):
643
from bzrlib.transport import get_transport
644
from bzrlib.transport.memory import MemoryServer
645
from bzrlib.transport.readonly import ReadonlyTransportDecorator
646
self.vfs_transport_factory = MemoryServer
647
self.transport_readonly_server = None
648
# calling get_readonly_transport() constructs a decorator on the url
650
url = self.get_readonly_url()
651
url2 = self.get_readonly_url('foo/bar')
652
t = get_transport(url)
653
t2 = get_transport(url2)
654
self.failUnless(isinstance(t, ReadonlyTransportDecorator))
655
self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
656
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
658
def test_get_readonly_url_http(self):
659
from bzrlib.tests.HttpServer import HttpServer
660
from bzrlib.transport import get_transport
661
from bzrlib.transport.local import LocalURLServer
662
from bzrlib.transport.http import HttpTransportBase
663
self.transport_server = LocalURLServer
664
self.transport_readonly_server = HttpServer
665
# calling get_readonly_transport() gives us a HTTP server instance.
666
url = self.get_readonly_url()
667
url2 = self.get_readonly_url('foo/bar')
668
# the transport returned may be any HttpTransportBase subclass
669
t = get_transport(url)
670
t2 = get_transport(url2)
671
self.failUnless(isinstance(t, HttpTransportBase))
672
self.failUnless(isinstance(t2, HttpTransportBase))
673
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
675
def test_is_directory(self):
676
"""Test assertIsDirectory assertion"""
677
t = self.get_transport()
678
self.build_tree(['a_dir/', 'a_file'], transport=t)
679
self.assertIsDirectory('a_dir', t)
680
self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
681
self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
684
class TestTestCaseTransports(TestCaseWithTransport):
687
super(TestTestCaseTransports, self).setUp()
688
self.vfs_transport_factory = MemoryServer
690
def test_make_bzrdir_preserves_transport(self):
691
t = self.get_transport()
692
result_bzrdir = self.make_bzrdir('subdir')
693
self.assertIsInstance(result_bzrdir.transport,
695
# should not be on disk, should only be in memory
696
self.failIfExists('subdir')
699
class TestChrootedTest(ChrootedTestCase):
701
def test_root_is_root(self):
702
from bzrlib.transport import get_transport
703
t = get_transport(self.get_readonly_url())
705
self.assertEqual(url, t.clone('..').base)
708
class MockProgress(_BaseProgressBar):
709
"""Progress-bar standin that records calls.
711
Useful for testing pb using code.
715
_BaseProgressBar.__init__(self)
719
self.calls.append(('tick',))
721
def update(self, msg=None, current=None, total=None):
722
self.calls.append(('update', msg, current, total))
725
self.calls.append(('clear',))
727
def note(self, msg, *args):
728
self.calls.append(('note', msg, args))
731
class TestTestResult(TestCase):
733
def check_timing(self, test_case, expected_re):
734
result = bzrlib.tests.TextTestResult(self._log_file,
738
test_case.run(result)
739
timed_string = result._testTimeString(test_case)
740
self.assertContainsRe(timed_string, expected_re)
742
def test_test_reporting(self):
743
class ShortDelayTestCase(TestCase):
744
def test_short_delay(self):
746
def test_short_benchmark(self):
747
self.time(time.sleep, 0.003)
748
self.check_timing(ShortDelayTestCase('test_short_delay'),
750
# if a benchmark time is given, we want a x of y style result.
751
self.check_timing(ShortDelayTestCase('test_short_benchmark'),
752
r"^ +[0-9]+ms/ +[0-9]+ms$")
754
def test_unittest_reporting_unittest_class(self):
755
# getting the time from a non-bzrlib test works ok
756
class ShortDelayTestCase(unittest.TestCase):
757
def test_short_delay(self):
759
self.check_timing(ShortDelayTestCase('test_short_delay'),
762
def test_assigned_benchmark_file_stores_date(self):
764
result = bzrlib.tests.TextTestResult(self._log_file,
769
output_string = output.getvalue()
770
# if you are wondering about the regexp please read the comment in
771
# test_bench_history (bzrlib.tests.test_selftest.TestRunner)
772
# XXX: what comment? -- Andrew Bennetts
773
self.assertContainsRe(output_string, "--date [0-9.]+")
775
def test_benchhistory_records_test_times(self):
776
result_stream = StringIO()
777
result = bzrlib.tests.TextTestResult(
781
bench_history=result_stream
784
# we want profile a call and check that its test duration is recorded
785
# make a new test instance that when run will generate a benchmark
786
example_test_case = TestTestResult("_time_hello_world_encoding")
787
# execute the test, which should succeed and record times
788
example_test_case.run(result)
789
lines = result_stream.getvalue().splitlines()
790
self.assertEqual(2, len(lines))
791
self.assertContainsRe(lines[1],
792
" *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
793
"._time_hello_world_encoding")
795
def _time_hello_world_encoding(self):
796
"""Profile two sleep calls
798
This is used to exercise the test framework.
800
self.time(unicode, 'hello', errors='replace')
801
self.time(unicode, 'world', errors='replace')
803
def test_lsprofiling(self):
804
"""Verbose test result prints lsprof statistics from test cases."""
805
self.requireFeature(test_lsprof.LSProfFeature)
806
result_stream = StringIO()
807
result = bzrlib.tests.VerboseTestResult(
808
unittest._WritelnDecorator(result_stream),
812
# we want profile a call of some sort and check it is output by
813
# addSuccess. We dont care about addError or addFailure as they
814
# are not that interesting for performance tuning.
815
# make a new test instance that when run will generate a profile
816
example_test_case = TestTestResult("_time_hello_world_encoding")
817
example_test_case._gather_lsprof_in_benchmarks = True
818
# execute the test, which should succeed and record profiles
819
example_test_case.run(result)
820
# lsprofile_something()
821
# if this worked we want
822
# LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
823
# CallCount Recursive Total(ms) Inline(ms) module:lineno(function)
824
# (the lsprof header)
825
# ... an arbitrary number of lines
826
# and the function call which is time.sleep.
827
# 1 0 ??? ??? ???(sleep)
828
# and then repeated but with 'world', rather than 'hello'.
829
# this should appear in the output stream of our test result.
830
output = result_stream.getvalue()
831
self.assertContainsRe(output,
832
r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
833
self.assertContainsRe(output,
834
r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
835
self.assertContainsRe(output,
836
r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
837
self.assertContainsRe(output,
838
r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
840
def test_known_failure(self):
841
"""A KnownFailure being raised should trigger several result actions."""
842
class InstrumentedTestResult(ExtendedTestResult):
844
def report_test_start(self, test): pass
845
def report_known_failure(self, test, err):
846
self._call = test, err
847
result = InstrumentedTestResult(None, None, None, None)
849
raise KnownFailure('failed!')
850
test = unittest.FunctionTestCase(test_function)
852
# it should invoke 'report_known_failure'.
853
self.assertEqual(2, len(result._call))
854
self.assertEqual(test, result._call[0])
855
self.assertEqual(KnownFailure, result._call[1][0])
856
self.assertIsInstance(result._call[1][1], KnownFailure)
857
# we dont introspec the traceback, if the rest is ok, it would be
858
# exceptional for it not to be.
859
# it should update the known_failure_count on the object.
860
self.assertEqual(1, result.known_failure_count)
861
# the result should be successful.
862
self.assertTrue(result.wasSuccessful())
864
def test_verbose_report_known_failure(self):
865
# verbose test output formatting
866
result_stream = StringIO()
867
result = bzrlib.tests.VerboseTestResult(
868
unittest._WritelnDecorator(result_stream),
872
test = self.get_passing_test()
873
result.startTest(test)
874
prefix = len(result_stream.getvalue())
875
# the err parameter has the shape:
876
# (class, exception object, traceback)
877
# KnownFailures dont get their tracebacks shown though, so we
879
err = (KnownFailure, KnownFailure('foo'), None)
880
result.report_known_failure(test, err)
881
output = result_stream.getvalue()[prefix:]
882
lines = output.splitlines()
883
self.assertContainsRe(lines[0], r'XFAIL *\d+ms$')
884
self.assertEqual(lines[1], ' foo')
885
self.assertEqual(2, len(lines))
887
def test_text_report_known_failure(self):
888
# text test output formatting
890
result = bzrlib.tests.TextTestResult(
896
test = self.get_passing_test()
897
# this seeds the state to handle reporting the test.
898
result.startTest(test)
899
# the err parameter has the shape:
900
# (class, exception object, traceback)
901
# KnownFailures dont get their tracebacks shown though, so we
903
err = (KnownFailure, KnownFailure('foo'), None)
904
result.report_known_failure(test, err)
907
('update', '[1 in 0s] passing_test', None, None),
908
('note', 'XFAIL: %s\n%s\n', ('passing_test', err[1]))
911
# known_failures should be printed in the summary, so if we run a test
912
# after there are some known failures, the update prefix should match
914
result.known_failure_count = 3
918
('update', '[2 in 0s, 3 known failures] passing_test', None, None),
922
def get_passing_test(self):
923
"""Return a test object that can't be run usefully."""
926
return unittest.FunctionTestCase(passing_test)
928
def test_add_not_supported(self):
929
"""Test the behaviour of invoking addNotSupported."""
930
class InstrumentedTestResult(ExtendedTestResult):
931
def report_test_start(self, test): pass
932
def report_unsupported(self, test, feature):
933
self._call = test, feature
934
result = InstrumentedTestResult(None, None, None, None)
935
test = SampleTestCase('_test_pass')
937
result.startTest(test)
938
result.addNotSupported(test, feature)
939
# it should invoke 'report_unsupported'.
940
self.assertEqual(2, len(result._call))
941
self.assertEqual(test, result._call[0])
942
self.assertEqual(feature, result._call[1])
943
# the result should be successful.
944
self.assertTrue(result.wasSuccessful())
945
# it should record the test against a count of tests not run due to
947
self.assertEqual(1, result.unsupported['Feature'])
948
# and invoking it again should increment that counter
949
result.addNotSupported(test, feature)
950
self.assertEqual(2, result.unsupported['Feature'])
952
def test_verbose_report_unsupported(self):
953
# verbose test output formatting
954
result_stream = StringIO()
955
result = bzrlib.tests.VerboseTestResult(
956
unittest._WritelnDecorator(result_stream),
960
test = self.get_passing_test()
962
result.startTest(test)
963
prefix = len(result_stream.getvalue())
964
result.report_unsupported(test, feature)
965
output = result_stream.getvalue()[prefix:]
966
lines = output.splitlines()
967
self.assertEqual(lines, ['NODEP 0ms', " The feature 'Feature' is not available."])
969
def test_text_report_unsupported(self):
970
# text test output formatting
972
result = bzrlib.tests.TextTestResult(
978
test = self.get_passing_test()
980
# this seeds the state to handle reporting the test.
981
result.startTest(test)
982
result.report_unsupported(test, feature)
983
# no output on unsupported features
985
[('update', '[1 in 0s] passing_test', None, None)
988
# the number of missing features should be printed in the progress
989
# summary, so check for that.
990
result.unsupported = {'foo':0, 'bar':0}
994
('update', '[2 in 0s, 2 missing features] passing_test', None, None),
998
def test_unavailable_exception(self):
999
"""An UnavailableFeature being raised should invoke addNotSupported."""
1000
class InstrumentedTestResult(ExtendedTestResult):
1002
def report_test_start(self, test): pass
1003
def addNotSupported(self, test, feature):
1004
self._call = test, feature
1005
result = InstrumentedTestResult(None, None, None, None)
1007
def test_function():
1008
raise UnavailableFeature(feature)
1009
test = unittest.FunctionTestCase(test_function)
1011
# it should invoke 'addNotSupported'.
1012
self.assertEqual(2, len(result._call))
1013
self.assertEqual(test, result._call[0])
1014
self.assertEqual(feature, result._call[1])
1015
# and not count as an error
1016
self.assertEqual(0, result.error_count)
1018
def test_strict_with_unsupported_feature(self):
1019
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
1021
test = self.get_passing_test()
1022
feature = "Unsupported Feature"
1023
result.addNotSupported(test, feature)
1024
self.assertFalse(result.wasStrictlySuccessful())
1025
self.assertEqual(None, result._extractBenchmarkTime(test))
1027
def test_strict_with_known_failure(self):
1028
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
1030
test = self.get_passing_test()
1031
err = (KnownFailure, KnownFailure('foo'), None)
1032
result._addKnownFailure(test, err)
1033
self.assertFalse(result.wasStrictlySuccessful())
1034
self.assertEqual(None, result._extractBenchmarkTime(test))
1036
def test_strict_with_success(self):
1037
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
1039
test = self.get_passing_test()
1040
result.addSuccess(test)
1041
self.assertTrue(result.wasStrictlySuccessful())
1042
self.assertEqual(None, result._extractBenchmarkTime(test))
1045
class TestRunner(TestCase):
1047
def dummy_test(self):
1050
def run_test_runner(self, testrunner, test):
1051
"""Run suite in testrunner, saving global state and restoring it.
1053
This current saves and restores:
1054
TestCaseInTempDir.TEST_ROOT
1056
There should be no tests in this file that use bzrlib.tests.TextTestRunner
1057
without using this convenience method, because of our use of global state.
1059
old_root = TestCaseInTempDir.TEST_ROOT
1061
TestCaseInTempDir.TEST_ROOT = None
1062
return testrunner.run(test)
1064
TestCaseInTempDir.TEST_ROOT = old_root
1066
def test_known_failure_failed_run(self):
1067
# run a test that generates a known failure which should be printed in
1068
# the final output when real failures occur.
1069
def known_failure_test():
1070
raise KnownFailure('failed')
1071
test = unittest.TestSuite()
1072
test.addTest(unittest.FunctionTestCase(known_failure_test))
1074
raise AssertionError('foo')
1075
test.addTest(unittest.FunctionTestCase(failing_test))
1077
runner = TextTestRunner(stream=stream)
1078
result = self.run_test_runner(runner, test)
1079
lines = stream.getvalue().splitlines()
1082
'======================================================================',
1083
'FAIL: unittest.FunctionTestCase (failing_test)',
1084
'----------------------------------------------------------------------',
1085
'Traceback (most recent call last):',
1086
' raise AssertionError(\'foo\')',
1087
'AssertionError: foo',
1089
'----------------------------------------------------------------------',
1091
'FAILED (failures=1, known_failure_count=1)'],
1092
lines[0:5] + lines[6:10] + lines[11:])
1094
def test_known_failure_ok_run(self):
1095
# run a test that generates a known failure which should be printed in the final output.
1096
def known_failure_test():
1097
raise KnownFailure('failed')
1098
test = unittest.FunctionTestCase(known_failure_test)
1100
runner = TextTestRunner(stream=stream)
1101
result = self.run_test_runner(runner, test)
1102
self.assertContainsRe(stream.getvalue(),
1105
'Ran 1 test in .*\n'
1107
'OK \\(known_failures=1\\)\n')
1109
def test_skipped_test(self):
1110
# run a test that is skipped, and check the suite as a whole still
1112
# skipping_test must be hidden in here so it's not run as a real test
1113
def skipping_test():
1114
raise TestSkipped('test intentionally skipped')
1116
runner = TextTestRunner(stream=self._log_file)
1117
test = unittest.FunctionTestCase(skipping_test)
1118
result = self.run_test_runner(runner, test)
1119
self.assertTrue(result.wasSuccessful())
1121
def test_skipped_from_setup(self):
1122
class SkippedSetupTest(TestCase):
1126
self.addCleanup(self.cleanup)
1127
raise TestSkipped('skipped setup')
1129
def test_skip(self):
1130
self.fail('test reached')
1135
runner = TextTestRunner(stream=self._log_file)
1136
test = SkippedSetupTest('test_skip')
1137
result = self.run_test_runner(runner, test)
1138
self.assertTrue(result.wasSuccessful())
1139
# Check if cleanup was called the right number of times.
1140
self.assertEqual(0, test.counter)
1142
def test_skipped_from_test(self):
1143
class SkippedTest(TestCase):
1147
self.addCleanup(self.cleanup)
1149
def test_skip(self):
1150
raise TestSkipped('skipped test')
1155
runner = TextTestRunner(stream=self._log_file)
1156
test = SkippedTest('test_skip')
1157
result = self.run_test_runner(runner, test)
1158
self.assertTrue(result.wasSuccessful())
1159
# Check if cleanup was called the right number of times.
1160
self.assertEqual(0, test.counter)
1162
def test_not_applicable(self):
1163
# run a test that is skipped because it's not applicable
1164
def not_applicable_test():
1165
from bzrlib.tests import TestNotApplicable
1166
raise TestNotApplicable('this test never runs')
1168
runner = TextTestRunner(stream=out, verbosity=2)
1169
test = unittest.FunctionTestCase(not_applicable_test)
1170
result = self.run_test_runner(runner, test)
1171
self._log_file.write(out.getvalue())
1172
self.assertTrue(result.wasSuccessful())
1173
self.assertTrue(result.wasStrictlySuccessful())
1174
self.assertContainsRe(out.getvalue(),
1175
r'(?m)not_applicable_test * N/A')
1176
self.assertContainsRe(out.getvalue(),
1177
r'(?m)^ this test never runs')
1179
def test_not_applicable_demo(self):
1180
# just so you can see it in the test output
1181
raise TestNotApplicable('this test is just a demonstation')
1183
def test_unsupported_features_listed(self):
1184
"""When unsupported features are encountered they are detailed."""
1185
class Feature1(Feature):
1186
def _probe(self): return False
1187
class Feature2(Feature):
1188
def _probe(self): return False
1189
# create sample tests
1190
test1 = SampleTestCase('_test_pass')
1191
test1._test_needs_features = [Feature1()]
1192
test2 = SampleTestCase('_test_pass')
1193
test2._test_needs_features = [Feature2()]
1194
test = unittest.TestSuite()
1198
runner = TextTestRunner(stream=stream)
1199
result = self.run_test_runner(runner, test)
1200
lines = stream.getvalue().splitlines()
1203
"Missing feature 'Feature1' skipped 1 tests.",
1204
"Missing feature 'Feature2' skipped 1 tests.",
1208
def test_bench_history(self):
1209
# tests that the running the benchmark produces a history file
1210
# containing a timestamp and the revision id of the bzrlib source which
1212
workingtree = _get_bzr_source_tree()
1213
test = TestRunner('dummy_test')
1215
runner = TextTestRunner(stream=self._log_file, bench_history=output)
1216
result = self.run_test_runner(runner, test)
1217
output_string = output.getvalue()
1218
self.assertContainsRe(output_string, "--date [0-9.]+")
1219
if workingtree is not None:
1220
revision_id = workingtree.get_parent_ids()[0]
1221
self.assertEndsWith(output_string.rstrip(), revision_id)
1223
def test_success_log_deleted(self):
1224
"""Successful tests have their log deleted"""
1226
class LogTester(TestCase):
1228
def test_success(self):
1229
self.log('this will be removed\n')
1231
sio = cStringIO.StringIO()
1232
runner = TextTestRunner(stream=sio)
1233
test = LogTester('test_success')
1234
result = self.run_test_runner(runner, test)
1236
log = test._get_log()
1237
self.assertEqual("DELETED log file to reduce memory footprint", log)
1238
self.assertEqual('', test._log_contents)
1239
self.assertIs(None, test._log_file_name)
1241
def test_fail_log_kept(self):
1242
"""Failed tests have their log kept"""
1244
class LogTester(TestCase):
1246
def test_fail(self):
1247
self.log('this will be kept\n')
1248
self.fail('this test fails')
1250
sio = cStringIO.StringIO()
1251
runner = TextTestRunner(stream=sio)
1252
test = LogTester('test_fail')
1253
result = self.run_test_runner(runner, test)
1255
text = sio.getvalue()
1256
self.assertContainsRe(text, 'this will be kept')
1257
self.assertContainsRe(text, 'this test fails')
1259
log = test._get_log()
1260
self.assertContainsRe(log, 'this will be kept')
1261
self.assertEqual(log, test._log_contents)
1263
def test_error_log_kept(self):
1264
"""Tests with errors have their log kept"""
1266
class LogTester(TestCase):
1268
def test_error(self):
1269
self.log('this will be kept\n')
1270
raise ValueError('random exception raised')
1272
sio = cStringIO.StringIO()
1273
runner = TextTestRunner(stream=sio)
1274
test = LogTester('test_error')
1275
result = self.run_test_runner(runner, test)
1277
text = sio.getvalue()
1278
self.assertContainsRe(text, 'this will be kept')
1279
self.assertContainsRe(text, 'random exception raised')
1281
log = test._get_log()
1282
self.assertContainsRe(log, 'this will be kept')
1283
self.assertEqual(log, test._log_contents)
1286
class SampleTestCase(TestCase):
1288
def _test_pass(self):
1292
class TestTestCase(TestCase):
1293
"""Tests that test the core bzrlib TestCase."""
1295
def test_debug_flags_sanitised(self):
1296
"""The bzrlib debug flags should be sanitised by setUp."""
1297
# we could set something and run a test that will check
1298
# it gets santised, but this is probably sufficient for now:
1299
# if someone runs the test with -Dsomething it will error.
1300
self.assertEqual(set(), bzrlib.debug.debug_flags)
1302
def inner_test(self):
1303
# the inner child test
1306
def outer_child(self):
1307
# the outer child test
1309
self.inner_test = TestTestCase("inner_child")
1310
result = bzrlib.tests.TextTestResult(self._log_file,
1313
self.inner_test.run(result)
1314
note("outer finish")
1316
def test_trace_nesting(self):
1317
# this tests that each test case nests its trace facility correctly.
1318
# we do this by running a test case manually. That test case (A)
1319
# should setup a new log, log content to it, setup a child case (B),
1320
# which should log independently, then case (A) should log a trailer
1322
# we do two nested children so that we can verify the state of the
1323
# logs after the outer child finishes is correct, which a bad clean
1324
# up routine in tearDown might trigger a fault in our test with only
1325
# one child, we should instead see the bad result inside our test with
1327
# the outer child test
1328
original_trace = bzrlib.trace._trace_file
1329
outer_test = TestTestCase("outer_child")
1330
result = bzrlib.tests.TextTestResult(self._log_file,
1333
outer_test.run(result)
1334
self.assertEqual(original_trace, bzrlib.trace._trace_file)
1336
def method_that_times_a_bit_twice(self):
1337
# call self.time twice to ensure it aggregates
1338
self.time(time.sleep, 0.007)
1339
self.time(time.sleep, 0.007)
1341
def test_time_creates_benchmark_in_result(self):
1342
"""Test that the TestCase.time() method accumulates a benchmark time."""
1343
sample_test = TestTestCase("method_that_times_a_bit_twice")
1344
output_stream = StringIO()
1345
result = bzrlib.tests.VerboseTestResult(
1346
unittest._WritelnDecorator(output_stream),
1349
num_tests=sample_test.countTestCases())
1350
sample_test.run(result)
1351
self.assertContainsRe(
1352
output_stream.getvalue(),
1353
r"\d+ms/ +\d+ms\n$")
1355
def test_hooks_sanitised(self):
1356
"""The bzrlib hooks should be sanitised by setUp."""
1357
self.assertEqual(bzrlib.branch.BranchHooks(),
1358
bzrlib.branch.Branch.hooks)
1359
self.assertEqual(bzrlib.smart.server.SmartServerHooks(),
1360
bzrlib.smart.server.SmartTCPServer.hooks)
1362
def test__gather_lsprof_in_benchmarks(self):
1363
"""When _gather_lsprof_in_benchmarks is on, accumulate profile data.
1365
Each self.time() call is individually and separately profiled.
1367
self.requireFeature(test_lsprof.LSProfFeature)
1368
# overrides the class member with an instance member so no cleanup
1370
self._gather_lsprof_in_benchmarks = True
1371
self.time(time.sleep, 0.000)
1372
self.time(time.sleep, 0.003)
1373
self.assertEqual(2, len(self._benchcalls))
1374
self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
1375
self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
1376
self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
1377
self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
1379
def test_knownFailure(self):
1380
"""Self.knownFailure() should raise a KnownFailure exception."""
1381
self.assertRaises(KnownFailure, self.knownFailure, "A Failure")
1383
def test_requireFeature_available(self):
1384
"""self.requireFeature(available) is a no-op."""
1385
class Available(Feature):
1386
def _probe(self):return True
1387
feature = Available()
1388
self.requireFeature(feature)
1390
def test_requireFeature_unavailable(self):
1391
"""self.requireFeature(unavailable) raises UnavailableFeature."""
1392
class Unavailable(Feature):
1393
def _probe(self):return False
1394
feature = Unavailable()
1395
self.assertRaises(UnavailableFeature, self.requireFeature, feature)
1397
def test_run_no_parameters(self):
1398
test = SampleTestCase('_test_pass')
1401
def test_run_enabled_unittest_result(self):
1402
"""Test we revert to regular behaviour when the test is enabled."""
1403
test = SampleTestCase('_test_pass')
1404
class EnabledFeature(object):
1405
def available(self):
1407
test._test_needs_features = [EnabledFeature()]
1408
result = unittest.TestResult()
1410
self.assertEqual(1, result.testsRun)
1411
self.assertEqual([], result.errors)
1412
self.assertEqual([], result.failures)
1414
def test_run_disabled_unittest_result(self):
1415
"""Test our compatability for disabled tests with unittest results."""
1416
test = SampleTestCase('_test_pass')
1417
class DisabledFeature(object):
1418
def available(self):
1420
test._test_needs_features = [DisabledFeature()]
1421
result = unittest.TestResult()
1423
self.assertEqual(1, result.testsRun)
1424
self.assertEqual([], result.errors)
1425
self.assertEqual([], result.failures)
1427
def test_run_disabled_supporting_result(self):
1428
"""Test disabled tests behaviour with support aware results."""
1429
test = SampleTestCase('_test_pass')
1430
class DisabledFeature(object):
1431
def available(self):
1433
the_feature = DisabledFeature()
1434
test._test_needs_features = [the_feature]
1435
class InstrumentedTestResult(unittest.TestResult):
1437
unittest.TestResult.__init__(self)
1439
def startTest(self, test):
1440
self.calls.append(('startTest', test))
1441
def stopTest(self, test):
1442
self.calls.append(('stopTest', test))
1443
def addNotSupported(self, test, feature):
1444
self.calls.append(('addNotSupported', test, feature))
1445
result = InstrumentedTestResult()
1448
('startTest', test),
1449
('addNotSupported', test, the_feature),
1455
@symbol_versioning.deprecated_function(zero_eleven)
1456
def sample_deprecated_function():
1457
"""A deprecated function to test applyDeprecated with."""
1461
def sample_undeprecated_function(a_param):
1462
"""A undeprecated function to test applyDeprecated with."""
1465
class ApplyDeprecatedHelper(object):
1466
"""A helper class for ApplyDeprecated tests."""
1468
@symbol_versioning.deprecated_method(zero_eleven)
1469
def sample_deprecated_method(self, param_one):
1470
"""A deprecated method for testing with."""
1473
def sample_normal_method(self):
1474
"""A undeprecated method."""
1476
@symbol_versioning.deprecated_method(zero_ten)
1477
def sample_nested_deprecation(self):
1478
return sample_deprecated_function()
1481
class TestExtraAssertions(TestCase):
1482
"""Tests for new test assertions in bzrlib test suite"""
1484
def test_assert_isinstance(self):
1485
self.assertIsInstance(2, int)
1486
self.assertIsInstance(u'', basestring)
1487
self.assertRaises(AssertionError, self.assertIsInstance, None, int)
1488
self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
1490
def test_assertEndsWith(self):
1491
self.assertEndsWith('foo', 'oo')
1492
self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
1494
def test_applyDeprecated_not_deprecated(self):
1495
sample_object = ApplyDeprecatedHelper()
1496
# calling an undeprecated callable raises an assertion
1497
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
1498
sample_object.sample_normal_method)
1499
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
1500
sample_undeprecated_function, "a param value")
1501
# calling a deprecated callable (function or method) with the wrong
1502
# expected deprecation fails.
1503
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
1504
sample_object.sample_deprecated_method, "a param value")
1505
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
1506
sample_deprecated_function)
1507
# calling a deprecated callable (function or method) with the right
1508
# expected deprecation returns the functions result.
1509
self.assertEqual("a param value", self.applyDeprecated(zero_eleven,
1510
sample_object.sample_deprecated_method, "a param value"))
1511
self.assertEqual(2, self.applyDeprecated(zero_eleven,
1512
sample_deprecated_function))
1513
# calling a nested deprecation with the wrong deprecation version
1514
# fails even if a deeper nested function was deprecated with the
1516
self.assertRaises(AssertionError, self.applyDeprecated,
1517
zero_eleven, sample_object.sample_nested_deprecation)
1518
# calling a nested deprecation with the right deprecation value
1519
# returns the calls result.
1520
self.assertEqual(2, self.applyDeprecated(zero_ten,
1521
sample_object.sample_nested_deprecation))
1523
def test_callDeprecated(self):
1524
def testfunc(be_deprecated, result=None):
1525
if be_deprecated is True:
1526
symbol_versioning.warn('i am deprecated', DeprecationWarning,
1529
result = self.callDeprecated(['i am deprecated'], testfunc, True)
1530
self.assertIs(None, result)
1531
result = self.callDeprecated([], testfunc, False, 'result')
1532
self.assertEqual('result', result)
1533
self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
1534
self.callDeprecated([], testfunc, be_deprecated=False)
1537
class TestWarningTests(TestCase):
1538
"""Tests for calling methods that raise warnings."""
1540
def test_callCatchWarnings(self):
1542
warnings.warn("this is your last warning")
1544
wlist, result = self.callCatchWarnings(meth, 1, 2)
1545
self.assertEquals(3, result)
1546
# would like just to compare them, but UserWarning doesn't implement
1549
self.assertIsInstance(w0, UserWarning)
1550
self.assertEquals("this is your last warning", str(w0))
1553
class TestConvenienceMakers(TestCaseWithTransport):
1554
"""Test for the make_* convenience functions."""
1556
def test_make_branch_and_tree_with_format(self):
1557
# we should be able to supply a format to make_branch_and_tree
1558
self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
1559
self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
1560
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
1561
bzrlib.bzrdir.BzrDirMetaFormat1)
1562
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
1563
bzrlib.bzrdir.BzrDirFormat6)
1565
def test_make_branch_and_memory_tree(self):
1566
# we should be able to get a new branch and a mutable tree from
1567
# TestCaseWithTransport
1568
tree = self.make_branch_and_memory_tree('a')
1569
self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
1572
class TestSFTPMakeBranchAndTree(TestCaseWithSFTPServer):
1574
def test_make_tree_for_sftp_branch(self):
1575
"""Transports backed by local directories create local trees."""
1577
tree = self.make_branch_and_tree('t1')
1578
base = tree.bzrdir.root_transport.base
1579
self.failIf(base.startswith('sftp'),
1580
'base %r is on sftp but should be local' % base)
1581
self.assertEquals(tree.bzrdir.root_transport,
1582
tree.branch.bzrdir.root_transport)
1583
self.assertEquals(tree.bzrdir.root_transport,
1584
tree.branch.repository.bzrdir.root_transport)
1587
class TestSelftest(TestCase):
1588
"""Tests of bzrlib.tests.selftest."""
1590
def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
1593
factory_called.append(True)
1597
self.apply_redirected(out, err, None, bzrlib.tests.selftest,
1598
test_suite_factory=factory)
1599
self.assertEqual([True], factory_called)
1602
class TestKnownFailure(TestCase):
1604
def test_known_failure(self):
1605
"""Check that KnownFailure is defined appropriately."""
1606
# a KnownFailure is an assertion error for compatability with unaware
1608
self.assertIsInstance(KnownFailure(""), AssertionError)
1610
def test_expect_failure(self):
1612
self.expectFailure("Doomed to failure", self.assertTrue, False)
1613
except KnownFailure, e:
1614
self.assertEqual('Doomed to failure', e.args[0])
1616
self.expectFailure("Doomed to failure", self.assertTrue, True)
1617
except AssertionError, e:
1618
self.assertEqual('Unexpected success. Should have failed:'
1619
' Doomed to failure', e.args[0])
1621
self.fail('Assertion not raised')
1624
class TestFeature(TestCase):
1626
def test_caching(self):
1627
"""Feature._probe is called by the feature at most once."""
1628
class InstrumentedFeature(Feature):
1630
Feature.__init__(self)
1633
self.calls.append('_probe')
1635
feature = InstrumentedFeature()
1637
self.assertEqual(['_probe'], feature.calls)
1639
self.assertEqual(['_probe'], feature.calls)
1641
def test_named_str(self):
1642
"""Feature.__str__ should thunk to feature_name()."""
1643
class NamedFeature(Feature):
1644
def feature_name(self):
1646
feature = NamedFeature()
1647
self.assertEqual('symlinks', str(feature))
1649
def test_default_str(self):
1650
"""Feature.__str__ should default to __class__.__name__."""
1651
class NamedFeature(Feature):
1653
feature = NamedFeature()
1654
self.assertEqual('NamedFeature', str(feature))
1657
class TestUnavailableFeature(TestCase):
1659
def test_access_feature(self):
1661
exception = UnavailableFeature(feature)
1662
self.assertIs(feature, exception.args[0])
1665
class TestSelftestFiltering(TestCase):
1668
self.suite = TestUtil.TestSuite()
1669
self.loader = TestUtil.TestLoader()
1670
self.suite.addTest(self.loader.loadTestsFromModuleNames([
1671
'bzrlib.tests.test_selftest']))
1672
self.all_names = self._test_ids(self.suite)
1674
def _test_ids(self, test_suite):
1675
"""Get the ids for the tests in a test suite."""
1676
return [t.id() for t in iter_suite_tests(test_suite)]
1678
def test_condition_id_re(self):
1679
test_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
1680
'test_condition_id_re')
1681
filtered_suite = filter_suite_by_condition(self.suite,
1682
condition_id_re('test_condition_id_re'))
1683
self.assertEqual([test_name], self._test_ids(filtered_suite))
1685
def test_condition_isinstance(self):
1686
filtered_suite = filter_suite_by_condition(self.suite,
1687
condition_isinstance(self.__class__))
1688
class_pattern = 'bzrlib.tests.test_selftest.TestSelftestFiltering.'
1689
re_filtered = filter_suite_by_re(self.suite, class_pattern)
1690
self.assertEqual(self._test_ids(re_filtered),
1691
self._test_ids(filtered_suite))
1693
def test_exclude_tests_by_condition(self):
1694
excluded_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
1695
'test_exclude_tests_by_condition')
1696
filtered_suite = exclude_tests_by_condition(self.suite,
1697
lambda x:x.id() == excluded_name)
1698
self.assertEqual(len(self.all_names) - 1,
1699
filtered_suite.countTestCases())
1700
self.assertFalse(excluded_name in self._test_ids(filtered_suite))
1701
remaining_names = list(self.all_names)
1702
remaining_names.remove(excluded_name)
1703
self.assertEqual(remaining_names, self._test_ids(filtered_suite))
1705
def test_exclude_tests_by_re(self):
1706
self.all_names = self._test_ids(self.suite)
1707
filtered_suite = exclude_tests_by_re(self.suite, 'exclude_tests_by_re')
1708
excluded_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
1709
'test_exclude_tests_by_re')
1710
self.assertEqual(len(self.all_names) - 1,
1711
filtered_suite.countTestCases())
1712
self.assertFalse(excluded_name in self._test_ids(filtered_suite))
1713
remaining_names = list(self.all_names)
1714
remaining_names.remove(excluded_name)
1715
self.assertEqual(remaining_names, self._test_ids(filtered_suite))
1717
def test_filter_suite_by_condition(self):
1718
test_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
1719
'test_filter_suite_by_condition')
1720
filtered_suite = filter_suite_by_condition(self.suite,
1721
lambda x:x.id() == test_name)
1722
self.assertEqual([test_name], self._test_ids(filtered_suite))
1724
def test_filter_suite_by_re(self):
1725
filtered_suite = filter_suite_by_re(self.suite, 'test_filter_suite_by_r')
1726
filtered_names = self._test_ids(filtered_suite)
1727
self.assertEqual(filtered_names, ['bzrlib.tests.test_selftest.'
1728
'TestSelftestFiltering.test_filter_suite_by_re'])
1730
def test_preserve_input(self):
1731
# NB: Surely this is something in the stdlib to do this?
1732
self.assertTrue(self.suite is preserve_input(self.suite))
1733
self.assertTrue("@#$" is preserve_input("@#$"))
1735
def test_randomize_suite(self):
1736
randomized_suite = randomize_suite(self.suite)
1737
# randomizing should not add or remove test names.
1738
self.assertEqual(set(self._test_ids(self.suite)),
1739
set(self._test_ids(randomized_suite)))
1740
# Technically, this *can* fail, because random.shuffle(list) can be
1741
# equal to list. Trying multiple times just pushes the frequency back.
1742
# As its len(self.all_names)!:1, the failure frequency should be low
1743
# enough to ignore. RBC 20071021.
1744
# It should change the order.
1745
self.assertNotEqual(self.all_names, self._test_ids(randomized_suite))
1746
# But not the length. (Possibly redundant with the set test, but not
1748
self.assertEqual(len(self.all_names),
1749
len(self._test_ids(randomized_suite)))
1751
def test_sort_suite_by_re(self):
1752
sorted_suite = self.applyDeprecated(one_zero,
1753
sort_suite_by_re, self.suite, 'test_filter_suite_by_r')
1754
sorted_names = self._test_ids(sorted_suite)
1755
self.assertEqual(sorted_names[0], 'bzrlib.tests.test_selftest.'
1756
'TestSelftestFiltering.test_filter_suite_by_re')
1757
self.assertEquals(sorted(self.all_names), sorted(sorted_names))
1759
def test_split_suit_by_re(self):
1760
self.all_names = self._test_ids(self.suite)
1761
split_suite = split_suite_by_re(self.suite, 'test_filter_suite_by_r')
1762
filtered_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
1763
'test_filter_suite_by_re')
1764
self.assertEqual([filtered_name], self._test_ids(split_suite[0]))
1765
self.assertFalse(filtered_name in self._test_ids(split_suite[1]))
1766
remaining_names = list(self.all_names)
1767
remaining_names.remove(filtered_name)
1768
self.assertEqual(remaining_names, self._test_ids(split_suite[1]))
1771
class TestCheckInventoryShape(TestCaseWithTransport):
1773
def test_check_inventory_shape(self):
1774
files = ['a', 'b/', 'b/c']
1775
tree = self.make_branch_and_tree('.')
1776
self.build_tree(files)
1780
self.check_inventory_shape(tree.inventory, files)
1785
class TestBlackboxSupport(TestCase):
1786
"""Tests for testsuite blackbox features."""
1788
def test_run_bzr_failure_not_caught(self):
1789
# When we run bzr in blackbox mode, we want any unexpected errors to
1790
# propagate up to the test suite so that it can show the error in the
1791
# usual way, and we won't get a double traceback.
1792
e = self.assertRaises(
1794
self.run_bzr, ['assert-fail'])
1795
# make sure we got the real thing, not an error from somewhere else in
1796
# the test framework
1797
self.assertEquals('always fails', str(e))
1798
# check that there's no traceback in the test log
1799
self.assertNotContainsRe(self._get_log(keep_log_file=True),
1802
def test_run_bzr_user_error_caught(self):
1803
# Running bzr in blackbox mode, normal/expected/user errors should be
1804
# caught in the regular way and turned into an error message plus exit
1806
out, err = self.run_bzr(["log", "/nonexistantpath"], retcode=3)
1807
self.assertEqual(out, '')
1808
self.assertEqual(err, 'bzr: ERROR: Not a branch: "/nonexistantpath/".\n')
1811
class TestTestLoader(TestCase):
1812
"""Tests for the test loader."""
1814
def _get_loader_and_module(self):
1815
"""Gets a TestLoader and a module with one test in it."""
1816
loader = TestUtil.TestLoader()
1818
class Stub(TestCase):
1821
class MyModule(object):
1823
MyModule.a_class = Stub
1825
return loader, module
1827
def test_module_no_load_tests_attribute_loads_classes(self):
1828
loader, module = self._get_loader_and_module()
1829
self.assertEqual(1, loader.loadTestsFromModule(module).countTestCases())
1831
def test_module_load_tests_attribute_gets_called(self):
1832
loader, module = self._get_loader_and_module()
1833
# 'self' is here because we're faking the module with a class. Regular
1834
# load_tests do not need that :)
1835
def load_tests(self, standard_tests, module, loader):
1836
result = loader.suiteClass()
1837
for test in iter_suite_tests(standard_tests):
1838
result.addTests([test, test])
1840
# add a load_tests() method which multiplies the tests from the module.
1841
module.__class__.load_tests = load_tests
1842
self.assertEqual(2, loader.loadTestsFromModule(module).countTestCases())