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 (
42
from bzrlib.tests import (
49
TestCaseWithMemoryTransport,
50
TestCaseWithTransport,
63
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
64
from bzrlib.tests.TestUtil import _load_module_by_name
65
from bzrlib.trace import note
66
from bzrlib.transport.memory import MemoryServer, MemoryTransport
67
from bzrlib.version import _get_bzr_source_tree
70
class SelftestTests(TestCase):
72
def test_import_tests(self):
73
mod = _load_module_by_name('bzrlib.tests.test_selftest')
74
self.assertEqual(mod.SelftestTests, SelftestTests)
76
def test_import_test_failure(self):
77
self.assertRaises(ImportError,
81
class MetaTestLog(TestCase):
83
def test_logging(self):
84
"""Test logs are captured when a test fails."""
85
self.log('a test message')
86
self._log_file.flush()
87
self.assertContainsRe(self._get_log(keep_log_file=True),
91
class TestTreeShape(TestCaseInTempDir):
93
def test_unicode_paths(self):
94
filename = u'hell\u00d8'
96
self.build_tree_contents([(filename, 'contents of hello')])
97
except UnicodeEncodeError:
98
raise TestSkipped("can't build unicode working tree in "
99
"filesystem encoding %s" % sys.getfilesystemencoding())
100
self.failUnlessExists(filename)
103
class TestTransportProviderAdapter(TestCase):
104
"""A group of tests that test the transport implementation adaption core.
106
This is a meta test that the tests are applied to all available
109
This will be generalised in the future which is why it is in this
110
test file even though it is specific to transport tests at the moment.
113
def test_get_transport_permutations(self):
114
# this checks that we the module get_test_permutations call
115
# is made by the adapter get_transport_test_permitations method.
116
class MockModule(object):
117
def get_test_permutations(self):
118
return sample_permutation
119
sample_permutation = [(1,2), (3,4)]
120
from bzrlib.tests.test_transport_implementations \
121
import TransportTestProviderAdapter
122
adapter = TransportTestProviderAdapter()
123
self.assertEqual(sample_permutation,
124
adapter.get_transport_test_permutations(MockModule()))
126
def test_adapter_checks_all_modules(self):
127
# this checks that the adapter returns as many permurtations as
128
# there are in all the registered# transport modules for there
129
# - we assume if this matches its probably doing the right thing
130
# especially in combination with the tests for setting the right
132
from bzrlib.tests.test_transport_implementations \
133
import TransportTestProviderAdapter
134
from bzrlib.transport import _get_transport_modules
135
modules = _get_transport_modules()
136
permutation_count = 0
137
for module in modules:
139
permutation_count += len(reduce(getattr,
140
(module + ".get_test_permutations").split('.')[1:],
141
__import__(module))())
142
except errors.DependencyNotPresent:
144
input_test = TestTransportProviderAdapter(
145
"test_adapter_sets_transport_class")
146
adapter = TransportTestProviderAdapter()
147
self.assertEqual(permutation_count,
148
len(list(iter(adapter.adapt(input_test)))))
150
def test_adapter_sets_transport_class(self):
151
# Check that the test adapter inserts a transport and server into the
154
# This test used to know about all the possible transports and the
155
# order they were returned but that seems overly brittle (mbp
157
from bzrlib.tests.test_transport_implementations \
158
import TransportTestProviderAdapter
159
scenarios = TransportTestProviderAdapter().scenarios
160
# there are at least that many builtin transports
161
self.assertTrue(len(scenarios) > 6)
162
one_scenario = scenarios[0]
163
self.assertIsInstance(one_scenario[0], str)
164
self.assertTrue(issubclass(one_scenario[1]["transport_class"],
165
bzrlib.transport.Transport))
166
self.assertTrue(issubclass(one_scenario[1]["transport_server"],
167
bzrlib.transport.Server))
170
class TestBranchProviderAdapter(TestCase):
171
"""A group of tests that test the branch implementation test adapter."""
173
def test_constructor(self):
174
# check that constructor parameters are passed through to the adapted
176
from bzrlib.tests.branch_implementations import BranchTestProviderAdapter
179
formats = [("c", "C"), ("d", "D")]
180
adapter = BranchTestProviderAdapter(server1, server2, formats)
181
self.assertEqual(2, len(adapter.scenarios))
184
{'branch_format': 'c',
185
'bzrdir_format': 'C',
186
'transport_readonly_server': 'b',
187
'transport_server': 'a'}),
189
{'branch_format': 'd',
190
'bzrdir_format': 'D',
191
'transport_readonly_server': 'b',
192
'transport_server': 'a'})],
196
class TestBzrDirProviderAdapter(TestCase):
197
"""A group of tests that test the bzr dir implementation test adapter."""
199
def test_adapted_tests(self):
200
# check that constructor parameters are passed through to the adapted
202
from bzrlib.tests.bzrdir_implementations import BzrDirTestProviderAdapter
207
adapter = BzrDirTestProviderAdapter(vfs_factory,
208
server1, server2, formats)
211
{'bzrdir_format': 'c',
212
'transport_readonly_server': 'b',
213
'transport_server': 'a',
214
'vfs_transport_factory': 'v'}),
216
{'bzrdir_format': 'd',
217
'transport_readonly_server': 'b',
218
'transport_server': 'a',
219
'vfs_transport_factory': 'v'})],
223
class TestRepositoryProviderAdapter(TestCase):
224
"""A group of tests that test the repository implementation test adapter."""
226
def test_constructor(self):
227
# check that constructor parameters are passed through to the
229
from bzrlib.tests.repository_implementations import RepositoryTestProviderAdapter
232
formats = [("c", "C"), ("d", "D")]
233
adapter = RepositoryTestProviderAdapter(server1, server2, formats)
236
{'bzrdir_format': 'C',
237
'repository_format': 'c',
238
'transport_readonly_server': 'b',
239
'transport_server': 'a'}),
241
{'bzrdir_format': 'D',
242
'repository_format': 'd',
243
'transport_readonly_server': 'b',
244
'transport_server': 'a'})],
247
def test_setting_vfs_transport(self):
248
"""The vfs_transport_factory can be set optionally."""
249
from bzrlib.tests.repository_implementations import RepositoryTestProviderAdapter
250
formats = [("a", "b"), ("c", "d")]
251
adapter = RepositoryTestProviderAdapter(None, None, formats,
252
vfs_transport_factory="vfs")
255
{'bzrdir_format': 'b',
256
'repository_format': 'a',
257
'transport_readonly_server': None,
258
'transport_server': None,
259
'vfs_transport_factory': 'vfs'}),
261
{'bzrdir_format': 'd',
262
'repository_format': 'c',
263
'transport_readonly_server': None,
264
'transport_server': None,
265
'vfs_transport_factory': 'vfs'})],
268
def test_formats_to_scenarios(self):
269
"""The adapter can generate all the scenarios needed."""
270
from bzrlib.tests.repository_implementations import RepositoryTestProviderAdapter
271
no_vfs_adapter = RepositoryTestProviderAdapter("server", "readonly",
273
vfs_adapter = RepositoryTestProviderAdapter("server", "readonly",
274
[], vfs_transport_factory="vfs")
275
# no_vfs generate scenarios without vfs_transport_factor
276
formats = [("c", "C"), (1, "D")]
279
{'bzrdir_format': 'C',
280
'repository_format': 'c',
281
'transport_readonly_server': 'readonly',
282
'transport_server': 'server'}),
284
{'bzrdir_format': 'D',
285
'repository_format': 1,
286
'transport_readonly_server': 'readonly',
287
'transport_server': 'server'})],
288
no_vfs_adapter.formats_to_scenarios(formats))
291
{'bzrdir_format': 'C',
292
'repository_format': 'c',
293
'transport_readonly_server': 'readonly',
294
'transport_server': 'server',
295
'vfs_transport_factory': 'vfs'}),
297
{'bzrdir_format': 'D',
298
'repository_format': 1,
299
'transport_readonly_server': 'readonly',
300
'transport_server': 'server',
301
'vfs_transport_factory': 'vfs'})],
302
vfs_adapter.formats_to_scenarios(formats))
305
class TestTestScenarioApplier(TestCase):
306
"""Tests for the test adaption facilities."""
308
def test_adapt_applies_scenarios(self):
309
from bzrlib.tests.repository_implementations import TestScenarioApplier
310
input_test = TestTestScenarioApplier("test_adapt_test_to_scenario")
311
adapter = TestScenarioApplier()
312
adapter.scenarios = [("1", "dict"), ("2", "settings")]
314
def capture_call(test, scenario):
315
calls.append((test, scenario))
317
adapter.adapt_test_to_scenario = capture_call
318
adapter.adapt(input_test)
319
self.assertEqual([(input_test, ("1", "dict")),
320
(input_test, ("2", "settings"))], calls)
322
def test_adapt_test_to_scenario(self):
323
from bzrlib.tests.repository_implementations import TestScenarioApplier
324
input_test = TestTestScenarioApplier("test_adapt_test_to_scenario")
325
adapter = TestScenarioApplier()
326
# setup two adapted tests
327
adapted_test1 = adapter.adapt_test_to_scenario(input_test,
329
{"bzrdir_format":"bzr_format",
330
"repository_format":"repo_fmt",
331
"transport_server":"transport_server",
332
"transport_readonly_server":"readonly-server"}))
333
adapted_test2 = adapter.adapt_test_to_scenario(input_test,
334
("new id 2", {"bzrdir_format":None}))
335
# input_test should have been altered.
336
self.assertRaises(AttributeError, getattr, input_test, "bzrdir_format")
337
# the new tests are mutually incompatible, ensuring it has
338
# made new ones, and unspecified elements in the scenario
339
# should not have been altered.
340
self.assertEqual("bzr_format", adapted_test1.bzrdir_format)
341
self.assertEqual("repo_fmt", adapted_test1.repository_format)
342
self.assertEqual("transport_server", adapted_test1.transport_server)
343
self.assertEqual("readonly-server",
344
adapted_test1.transport_readonly_server)
346
"bzrlib.tests.test_selftest.TestTestScenarioApplier."
347
"test_adapt_test_to_scenario(new id)",
349
self.assertEqual(None, adapted_test2.bzrdir_format)
351
"bzrlib.tests.test_selftest.TestTestScenarioApplier."
352
"test_adapt_test_to_scenario(new id 2)",
356
class TestInterRepositoryProviderAdapter(TestCase):
357
"""A group of tests that test the InterRepository test adapter."""
359
def test_adapted_tests(self):
360
# check that constructor parameters are passed through to the adapted
362
from bzrlib.tests.interrepository_implementations import \
363
InterRepositoryTestProviderAdapter
366
formats = [(str, "C1", "C2"), (int, "D1", "D2")]
367
adapter = InterRepositoryTestProviderAdapter(server1, server2, formats)
370
{'interrepo_class': str,
371
'repository_format': 'C1',
372
'repository_format_to': 'C2',
373
'transport_readonly_server': 'b',
374
'transport_server': 'a'}),
376
{'interrepo_class': int,
377
'repository_format': 'D1',
378
'repository_format_to': 'D2',
379
'transport_readonly_server': 'b',
380
'transport_server': 'a'})],
381
adapter.formats_to_scenarios(formats))
384
class TestInterVersionedFileProviderAdapter(TestCase):
385
"""A group of tests that test the InterVersionedFile test adapter."""
387
def test_scenarios(self):
388
# check that constructor parameters are passed through to the adapted
390
from bzrlib.tests.interversionedfile_implementations \
391
import InterVersionedFileTestProviderAdapter
394
formats = [(str, "C1", "C2"), (int, "D1", "D2")]
395
adapter = InterVersionedFileTestProviderAdapter(server1, server2, formats)
398
{'interversionedfile_class':str,
399
'transport_readonly_server': 'b',
400
'transport_server': 'a',
401
'versionedfile_factory': 'C1',
402
'versionedfile_factory_to': 'C2'}),
404
{'interversionedfile_class': int,
405
'transport_readonly_server': 'b',
406
'transport_server': 'a',
407
'versionedfile_factory': 'D1',
408
'versionedfile_factory_to': 'D2'})],
412
class TestRevisionStoreProviderAdapter(TestCase):
413
"""A group of tests that test the RevisionStore test adapter."""
415
def test_scenarios(self):
416
# check that constructor parameters are passed through to the adapted
418
from bzrlib.tests.revisionstore_implementations \
419
import RevisionStoreTestProviderAdapter
420
# revision stores need a store factory - i.e. RevisionKnit
421
#, a readonly and rw transport
425
store_factories = ["c", "d"]
426
adapter = RevisionStoreTestProviderAdapter(server1, server2, store_factories)
429
{'store_factory': 'c',
430
'transport_readonly_server': 'b',
431
'transport_server': 'a'}),
433
{'store_factory': 'd',
434
'transport_readonly_server': 'b',
435
'transport_server': 'a'})],
439
class TestWorkingTreeProviderAdapter(TestCase):
440
"""A group of tests that test the workingtree implementation test adapter."""
442
def test_scenarios(self):
443
# check that constructor parameters are passed through to the adapted
445
from bzrlib.tests.workingtree_implementations \
446
import WorkingTreeTestProviderAdapter
449
formats = [("c", "C"), ("d", "D")]
450
adapter = WorkingTreeTestProviderAdapter(server1, server2, formats)
453
{'bzrdir_format': 'C',
454
'transport_readonly_server': 'b',
455
'transport_server': 'a',
456
'workingtree_format': 'c'}),
458
{'bzrdir_format': 'D',
459
'transport_readonly_server': 'b',
460
'transport_server': 'a',
461
'workingtree_format': 'd'})],
465
class TestTreeProviderAdapter(TestCase):
466
"""Test the setup of tree_implementation tests."""
468
def test_adapted_tests(self):
469
# the tree implementation adapter is meant to setup one instance for
470
# each working tree format, and one additional instance that will
471
# use the default wt format, but create a revision tree for the tests.
472
# this means that the wt ones should have the workingtree_to_test_tree
473
# attribute set to 'return_parameter' and the revision one set to
474
# revision_tree_from_workingtree.
476
from bzrlib.tests.tree_implementations import (
477
TreeTestProviderAdapter,
479
revision_tree_from_workingtree
481
from bzrlib.workingtree import WorkingTreeFormat, WorkingTreeFormat3
482
input_test = TestTreeProviderAdapter(
483
"test_adapted_tests")
486
formats = [("c", "C"), ("d", "D")]
487
adapter = TreeTestProviderAdapter(server1, server2, formats)
488
suite = adapter.adapt(input_test)
489
tests = list(iter(suite))
490
self.assertEqual(4, len(tests))
491
# this must match the default format setp up in
492
# TreeTestProviderAdapter.adapt
493
default_format = WorkingTreeFormat3
494
self.assertEqual(tests[0].workingtree_format, formats[0][0])
495
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
496
self.assertEqual(tests[0].transport_server, server1)
497
self.assertEqual(tests[0].transport_readonly_server, server2)
498
self.assertEqual(tests[0].workingtree_to_test_tree, return_parameter)
499
self.assertEqual(tests[1].workingtree_format, formats[1][0])
500
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
501
self.assertEqual(tests[1].transport_server, server1)
502
self.assertEqual(tests[1].transport_readonly_server, server2)
503
self.assertEqual(tests[1].workingtree_to_test_tree, return_parameter)
504
self.assertIsInstance(tests[2].workingtree_format, default_format)
505
#self.assertEqual(tests[2].bzrdir_format,
506
# default_format._matchingbzrdir)
507
self.assertEqual(tests[2].transport_server, server1)
508
self.assertEqual(tests[2].transport_readonly_server, server2)
509
self.assertEqual(tests[2].workingtree_to_test_tree,
510
revision_tree_from_workingtree)
513
class TestInterTreeProviderAdapter(TestCase):
514
"""A group of tests that test the InterTreeTestAdapter."""
516
def test_adapted_tests(self):
517
# check that constructor parameters are passed through to the adapted
519
# for InterTree tests we want the machinery to bring up two trees in
520
# each instance: the base one, and the one we are interacting with.
521
# because each optimiser can be direction specific, we need to test
522
# each optimiser in its chosen direction.
523
# unlike the TestProviderAdapter we dont want to automatically add a
524
# parameterised one for WorkingTree - the optimisers will tell us what
526
from bzrlib.tests.tree_implementations import (
528
revision_tree_from_workingtree
530
from bzrlib.tests.intertree_implementations import (
531
InterTreeTestProviderAdapter,
533
from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
534
input_test = TestInterTreeProviderAdapter(
535
"test_adapted_tests")
538
format1 = WorkingTreeFormat2()
539
format2 = WorkingTreeFormat3()
540
formats = [(str, format1, format2, "converter1"),
541
(int, format2, format1, "converter2")]
542
adapter = InterTreeTestProviderAdapter(server1, server2, formats)
543
suite = adapter.adapt(input_test)
544
tests = list(iter(suite))
545
self.assertEqual(2, len(tests))
546
self.assertEqual(tests[0].intertree_class, formats[0][0])
547
self.assertEqual(tests[0].workingtree_format, formats[0][1])
548
self.assertEqual(tests[0].workingtree_format_to, formats[0][2])
549
self.assertEqual(tests[0].mutable_trees_to_test_trees, formats[0][3])
550
self.assertEqual(tests[0].workingtree_to_test_tree, return_parameter)
551
self.assertEqual(tests[0].transport_server, server1)
552
self.assertEqual(tests[0].transport_readonly_server, server2)
553
self.assertEqual(tests[1].intertree_class, formats[1][0])
554
self.assertEqual(tests[1].workingtree_format, formats[1][1])
555
self.assertEqual(tests[1].workingtree_format_to, formats[1][2])
556
self.assertEqual(tests[1].mutable_trees_to_test_trees, formats[1][3])
557
self.assertEqual(tests[1].workingtree_to_test_tree, return_parameter)
558
self.assertEqual(tests[1].transport_server, server1)
559
self.assertEqual(tests[1].transport_readonly_server, server2)
562
class TestTestCaseInTempDir(TestCaseInTempDir):
564
def test_home_is_not_working(self):
565
self.assertNotEqual(self.test_dir, self.test_home_dir)
566
cwd = osutils.getcwd()
567
self.assertIsSameRealPath(self.test_dir, cwd)
568
self.assertIsSameRealPath(self.test_home_dir, os.environ['HOME'])
571
class TestTestCaseWithMemoryTransport(TestCaseWithMemoryTransport):
573
def test_home_is_non_existant_dir_under_root(self):
574
"""The test_home_dir for TestCaseWithMemoryTransport is missing.
576
This is because TestCaseWithMemoryTransport is for tests that do not
577
need any disk resources: they should be hooked into bzrlib in such a
578
way that no global settings are being changed by the test (only a
579
few tests should need to do that), and having a missing dir as home is
580
an effective way to ensure that this is the case.
582
self.assertIsSameRealPath(
583
self.TEST_ROOT + "/MemoryTransportMissingHomeDir",
585
self.assertIsSameRealPath(self.test_home_dir, os.environ['HOME'])
587
def test_cwd_is_TEST_ROOT(self):
588
self.assertIsSameRealPath(self.test_dir, self.TEST_ROOT)
589
cwd = osutils.getcwd()
590
self.assertIsSameRealPath(self.test_dir, cwd)
592
def test_make_branch_and_memory_tree(self):
593
"""In TestCaseWithMemoryTransport we should not make the branch on disk.
595
This is hard to comprehensively robustly test, so we settle for making
596
a branch and checking no directory was created at its relpath.
598
tree = self.make_branch_and_memory_tree('dir')
599
# Guard against regression into MemoryTransport leaking
600
# files to disk instead of keeping them in memory.
601
self.failIf(osutils.lexists('dir'))
602
self.assertIsInstance(tree, memorytree.MemoryTree)
604
def test_make_branch_and_memory_tree_with_format(self):
605
"""make_branch_and_memory_tree should accept a format option."""
606
format = bzrdir.BzrDirMetaFormat1()
607
format.repository_format = weaverepo.RepositoryFormat7()
608
tree = self.make_branch_and_memory_tree('dir', format=format)
609
# Guard against regression into MemoryTransport leaking
610
# files to disk instead of keeping them in memory.
611
self.failIf(osutils.lexists('dir'))
612
self.assertIsInstance(tree, memorytree.MemoryTree)
613
self.assertEqual(format.repository_format.__class__,
614
tree.branch.repository._format.__class__)
617
class TestTestCaseWithTransport(TestCaseWithTransport):
618
"""Tests for the convenience functions TestCaseWithTransport introduces."""
620
def test_get_readonly_url_none(self):
621
from bzrlib.transport import get_transport
622
from bzrlib.transport.memory import MemoryServer
623
from bzrlib.transport.readonly import ReadonlyTransportDecorator
624
self.vfs_transport_factory = MemoryServer
625
self.transport_readonly_server = None
626
# calling get_readonly_transport() constructs a decorator on the url
628
url = self.get_readonly_url()
629
url2 = self.get_readonly_url('foo/bar')
630
t = get_transport(url)
631
t2 = get_transport(url2)
632
self.failUnless(isinstance(t, ReadonlyTransportDecorator))
633
self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
634
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
636
def test_get_readonly_url_http(self):
637
from bzrlib.tests.HttpServer import HttpServer
638
from bzrlib.transport import get_transport
639
from bzrlib.transport.local import LocalURLServer
640
from bzrlib.transport.http import HttpTransportBase
641
self.transport_server = LocalURLServer
642
self.transport_readonly_server = HttpServer
643
# calling get_readonly_transport() gives us a HTTP server instance.
644
url = self.get_readonly_url()
645
url2 = self.get_readonly_url('foo/bar')
646
# the transport returned may be any HttpTransportBase subclass
647
t = get_transport(url)
648
t2 = get_transport(url2)
649
self.failUnless(isinstance(t, HttpTransportBase))
650
self.failUnless(isinstance(t2, HttpTransportBase))
651
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
653
def test_is_directory(self):
654
"""Test assertIsDirectory assertion"""
655
t = self.get_transport()
656
self.build_tree(['a_dir/', 'a_file'], transport=t)
657
self.assertIsDirectory('a_dir', t)
658
self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
659
self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
662
class TestTestCaseTransports(TestCaseWithTransport):
665
super(TestTestCaseTransports, self).setUp()
666
self.vfs_transport_factory = MemoryServer
668
def test_make_bzrdir_preserves_transport(self):
669
t = self.get_transport()
670
result_bzrdir = self.make_bzrdir('subdir')
671
self.assertIsInstance(result_bzrdir.transport,
673
# should not be on disk, should only be in memory
674
self.failIfExists('subdir')
677
class TestChrootedTest(ChrootedTestCase):
679
def test_root_is_root(self):
680
from bzrlib.transport import get_transport
681
t = get_transport(self.get_readonly_url())
683
self.assertEqual(url, t.clone('..').base)
686
class MockProgress(_BaseProgressBar):
687
"""Progress-bar standin that records calls.
689
Useful for testing pb using code.
693
_BaseProgressBar.__init__(self)
697
self.calls.append(('tick',))
699
def update(self, msg=None, current=None, total=None):
700
self.calls.append(('update', msg, current, total))
703
self.calls.append(('clear',))
705
def note(self, msg, *args):
706
self.calls.append(('note', msg, args))
709
class TestTestResult(TestCase):
711
def check_timing(self, test_case, expected_re):
712
result = bzrlib.tests.TextTestResult(self._log_file,
716
test_case.run(result)
717
timed_string = result._testTimeString(test_case)
718
self.assertContainsRe(timed_string, expected_re)
720
def test_test_reporting(self):
721
class ShortDelayTestCase(TestCase):
722
def test_short_delay(self):
724
def test_short_benchmark(self):
725
self.time(time.sleep, 0.003)
726
self.check_timing(ShortDelayTestCase('test_short_delay'),
728
# if a benchmark time is given, we want a x of y style result.
729
self.check_timing(ShortDelayTestCase('test_short_benchmark'),
730
r"^ +[0-9]+ms/ +[0-9]+ms$")
732
def test_unittest_reporting_unittest_class(self):
733
# getting the time from a non-bzrlib test works ok
734
class ShortDelayTestCase(unittest.TestCase):
735
def test_short_delay(self):
737
self.check_timing(ShortDelayTestCase('test_short_delay'),
740
def test_assigned_benchmark_file_stores_date(self):
742
result = bzrlib.tests.TextTestResult(self._log_file,
747
output_string = output.getvalue()
748
# if you are wondering about the regexp please read the comment in
749
# test_bench_history (bzrlib.tests.test_selftest.TestRunner)
750
# XXX: what comment? -- Andrew Bennetts
751
self.assertContainsRe(output_string, "--date [0-9.]+")
753
def test_benchhistory_records_test_times(self):
754
result_stream = StringIO()
755
result = bzrlib.tests.TextTestResult(
759
bench_history=result_stream
762
# we want profile a call and check that its test duration is recorded
763
# make a new test instance that when run will generate a benchmark
764
example_test_case = TestTestResult("_time_hello_world_encoding")
765
# execute the test, which should succeed and record times
766
example_test_case.run(result)
767
lines = result_stream.getvalue().splitlines()
768
self.assertEqual(2, len(lines))
769
self.assertContainsRe(lines[1],
770
" *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
771
"._time_hello_world_encoding")
773
def _time_hello_world_encoding(self):
774
"""Profile two sleep calls
776
This is used to exercise the test framework.
778
self.time(unicode, 'hello', errors='replace')
779
self.time(unicode, 'world', errors='replace')
781
def test_lsprofiling(self):
782
"""Verbose test result prints lsprof statistics from test cases."""
783
self.requireFeature(test_lsprof.LSProfFeature)
784
result_stream = StringIO()
785
result = bzrlib.tests.VerboseTestResult(
786
unittest._WritelnDecorator(result_stream),
790
# we want profile a call of some sort and check it is output by
791
# addSuccess. We dont care about addError or addFailure as they
792
# are not that interesting for performance tuning.
793
# make a new test instance that when run will generate a profile
794
example_test_case = TestTestResult("_time_hello_world_encoding")
795
example_test_case._gather_lsprof_in_benchmarks = True
796
# execute the test, which should succeed and record profiles
797
example_test_case.run(result)
798
# lsprofile_something()
799
# if this worked we want
800
# LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
801
# CallCount Recursive Total(ms) Inline(ms) module:lineno(function)
802
# (the lsprof header)
803
# ... an arbitrary number of lines
804
# and the function call which is time.sleep.
805
# 1 0 ??? ??? ???(sleep)
806
# and then repeated but with 'world', rather than 'hello'.
807
# this should appear in the output stream of our test result.
808
output = result_stream.getvalue()
809
self.assertContainsRe(output,
810
r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
811
self.assertContainsRe(output,
812
r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
813
self.assertContainsRe(output,
814
r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
815
self.assertContainsRe(output,
816
r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
818
def test_known_failure(self):
819
"""A KnownFailure being raised should trigger several result actions."""
820
class InstrumentedTestResult(ExtendedTestResult):
822
def report_test_start(self, test): pass
823
def report_known_failure(self, test, err):
824
self._call = test, err
825
result = InstrumentedTestResult(None, None, None, None)
827
raise KnownFailure('failed!')
828
test = unittest.FunctionTestCase(test_function)
830
# it should invoke 'report_known_failure'.
831
self.assertEqual(2, len(result._call))
832
self.assertEqual(test, result._call[0])
833
self.assertEqual(KnownFailure, result._call[1][0])
834
self.assertIsInstance(result._call[1][1], KnownFailure)
835
# we dont introspec the traceback, if the rest is ok, it would be
836
# exceptional for it not to be.
837
# it should update the known_failure_count on the object.
838
self.assertEqual(1, result.known_failure_count)
839
# the result should be successful.
840
self.assertTrue(result.wasSuccessful())
842
def test_verbose_report_known_failure(self):
843
# verbose test output formatting
844
result_stream = StringIO()
845
result = bzrlib.tests.VerboseTestResult(
846
unittest._WritelnDecorator(result_stream),
850
test = self.get_passing_test()
851
result.startTest(test)
852
prefix = len(result_stream.getvalue())
853
# the err parameter has the shape:
854
# (class, exception object, traceback)
855
# KnownFailures dont get their tracebacks shown though, so we
857
err = (KnownFailure, KnownFailure('foo'), None)
858
result.report_known_failure(test, err)
859
output = result_stream.getvalue()[prefix:]
860
lines = output.splitlines()
861
self.assertContainsRe(lines[0], r'XFAIL *\d+ms$')
862
self.assertEqual(lines[1], ' foo')
863
self.assertEqual(2, len(lines))
865
def test_text_report_known_failure(self):
866
# text test output formatting
868
result = bzrlib.tests.TextTestResult(
874
test = self.get_passing_test()
875
# this seeds the state to handle reporting the test.
876
result.startTest(test)
877
# the err parameter has the shape:
878
# (class, exception object, traceback)
879
# KnownFailures dont get their tracebacks shown though, so we
881
err = (KnownFailure, KnownFailure('foo'), None)
882
result.report_known_failure(test, err)
885
('update', '[1 in 0s] passing_test', None, None),
886
('note', 'XFAIL: %s\n%s\n', ('passing_test', err[1]))
889
# known_failures should be printed in the summary, so if we run a test
890
# after there are some known failures, the update prefix should match
892
result.known_failure_count = 3
896
('update', '[2 in 0s, 3 known failures] passing_test', None, None),
900
def get_passing_test(self):
901
"""Return a test object that can't be run usefully."""
904
return unittest.FunctionTestCase(passing_test)
906
def test_add_not_supported(self):
907
"""Test the behaviour of invoking addNotSupported."""
908
class InstrumentedTestResult(ExtendedTestResult):
909
def report_test_start(self, test): pass
910
def report_unsupported(self, test, feature):
911
self._call = test, feature
912
result = InstrumentedTestResult(None, None, None, None)
913
test = SampleTestCase('_test_pass')
915
result.startTest(test)
916
result.addNotSupported(test, feature)
917
# it should invoke 'report_unsupported'.
918
self.assertEqual(2, len(result._call))
919
self.assertEqual(test, result._call[0])
920
self.assertEqual(feature, result._call[1])
921
# the result should be successful.
922
self.assertTrue(result.wasSuccessful())
923
# it should record the test against a count of tests not run due to
925
self.assertEqual(1, result.unsupported['Feature'])
926
# and invoking it again should increment that counter
927
result.addNotSupported(test, feature)
928
self.assertEqual(2, result.unsupported['Feature'])
930
def test_verbose_report_unsupported(self):
931
# verbose test output formatting
932
result_stream = StringIO()
933
result = bzrlib.tests.VerboseTestResult(
934
unittest._WritelnDecorator(result_stream),
938
test = self.get_passing_test()
940
result.startTest(test)
941
prefix = len(result_stream.getvalue())
942
result.report_unsupported(test, feature)
943
output = result_stream.getvalue()[prefix:]
944
lines = output.splitlines()
945
self.assertEqual(lines, ['NODEP 0ms', " The feature 'Feature' is not available."])
947
def test_text_report_unsupported(self):
948
# text test output formatting
950
result = bzrlib.tests.TextTestResult(
956
test = self.get_passing_test()
958
# this seeds the state to handle reporting the test.
959
result.startTest(test)
960
result.report_unsupported(test, feature)
961
# no output on unsupported features
963
[('update', '[1 in 0s] passing_test', None, None)
966
# the number of missing features should be printed in the progress
967
# summary, so check for that.
968
result.unsupported = {'foo':0, 'bar':0}
972
('update', '[2 in 0s, 2 missing features] passing_test', None, None),
976
def test_unavailable_exception(self):
977
"""An UnavailableFeature being raised should invoke addNotSupported."""
978
class InstrumentedTestResult(ExtendedTestResult):
980
def report_test_start(self, test): pass
981
def addNotSupported(self, test, feature):
982
self._call = test, feature
983
result = InstrumentedTestResult(None, None, None, None)
986
raise UnavailableFeature(feature)
987
test = unittest.FunctionTestCase(test_function)
989
# it should invoke 'addNotSupported'.
990
self.assertEqual(2, len(result._call))
991
self.assertEqual(test, result._call[0])
992
self.assertEqual(feature, result._call[1])
993
# and not count as an error
994
self.assertEqual(0, result.error_count)
996
def test_strict_with_unsupported_feature(self):
997
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
999
test = self.get_passing_test()
1000
feature = "Unsupported Feature"
1001
result.addNotSupported(test, feature)
1002
self.assertFalse(result.wasStrictlySuccessful())
1003
self.assertEqual(None, result._extractBenchmarkTime(test))
1005
def test_strict_with_known_failure(self):
1006
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
1008
test = self.get_passing_test()
1009
err = (KnownFailure, KnownFailure('foo'), None)
1010
result._addKnownFailure(test, err)
1011
self.assertFalse(result.wasStrictlySuccessful())
1012
self.assertEqual(None, result._extractBenchmarkTime(test))
1014
def test_strict_with_success(self):
1015
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
1017
test = self.get_passing_test()
1018
result.addSuccess(test)
1019
self.assertTrue(result.wasStrictlySuccessful())
1020
self.assertEqual(None, result._extractBenchmarkTime(test))
1023
class TestRunner(TestCase):
1025
def dummy_test(self):
1028
def run_test_runner(self, testrunner, test):
1029
"""Run suite in testrunner, saving global state and restoring it.
1031
This current saves and restores:
1032
TestCaseInTempDir.TEST_ROOT
1034
There should be no tests in this file that use bzrlib.tests.TextTestRunner
1035
without using this convenience method, because of our use of global state.
1037
old_root = TestCaseInTempDir.TEST_ROOT
1039
TestCaseInTempDir.TEST_ROOT = None
1040
return testrunner.run(test)
1042
TestCaseInTempDir.TEST_ROOT = old_root
1044
def test_known_failure_failed_run(self):
1045
# run a test that generates a known failure which should be printed in
1046
# the final output when real failures occur.
1047
def known_failure_test():
1048
raise KnownFailure('failed')
1049
test = unittest.TestSuite()
1050
test.addTest(unittest.FunctionTestCase(known_failure_test))
1052
raise AssertionError('foo')
1053
test.addTest(unittest.FunctionTestCase(failing_test))
1055
runner = TextTestRunner(stream=stream)
1056
result = self.run_test_runner(runner, test)
1057
lines = stream.getvalue().splitlines()
1060
'======================================================================',
1061
'FAIL: unittest.FunctionTestCase (failing_test)',
1062
'----------------------------------------------------------------------',
1063
'Traceback (most recent call last):',
1064
' raise AssertionError(\'foo\')',
1065
'AssertionError: foo',
1067
'----------------------------------------------------------------------',
1069
'FAILED (failures=1, known_failure_count=1)'],
1070
lines[0:5] + lines[6:10] + lines[11:])
1072
def test_known_failure_ok_run(self):
1073
# run a test that generates a known failure which should be printed in the final output.
1074
def known_failure_test():
1075
raise KnownFailure('failed')
1076
test = unittest.FunctionTestCase(known_failure_test)
1078
runner = TextTestRunner(stream=stream)
1079
result = self.run_test_runner(runner, test)
1080
self.assertContainsRe(stream.getvalue(),
1083
'Ran 1 test in .*\n'
1085
'OK \\(known_failures=1\\)\n')
1087
def test_skipped_test(self):
1088
# run a test that is skipped, and check the suite as a whole still
1090
# skipping_test must be hidden in here so it's not run as a real test
1091
def skipping_test():
1092
raise TestSkipped('test intentionally skipped')
1094
runner = TextTestRunner(stream=self._log_file)
1095
test = unittest.FunctionTestCase(skipping_test)
1096
result = self.run_test_runner(runner, test)
1097
self.assertTrue(result.wasSuccessful())
1099
def test_skipped_from_setup(self):
1100
class SkippedSetupTest(TestCase):
1104
self.addCleanup(self.cleanup)
1105
raise TestSkipped('skipped setup')
1107
def test_skip(self):
1108
self.fail('test reached')
1113
runner = TextTestRunner(stream=self._log_file)
1114
test = SkippedSetupTest('test_skip')
1115
result = self.run_test_runner(runner, test)
1116
self.assertTrue(result.wasSuccessful())
1117
# Check if cleanup was called the right number of times.
1118
self.assertEqual(0, test.counter)
1120
def test_skipped_from_test(self):
1121
class SkippedTest(TestCase):
1125
self.addCleanup(self.cleanup)
1127
def test_skip(self):
1128
raise TestSkipped('skipped test')
1133
runner = TextTestRunner(stream=self._log_file)
1134
test = SkippedTest('test_skip')
1135
result = self.run_test_runner(runner, test)
1136
self.assertTrue(result.wasSuccessful())
1137
# Check if cleanup was called the right number of times.
1138
self.assertEqual(0, test.counter)
1140
def test_not_applicable(self):
1141
# run a test that is skipped because it's not applicable
1142
def not_applicable_test():
1143
from bzrlib.tests import TestNotApplicable
1144
raise TestNotApplicable('this test never runs')
1146
runner = TextTestRunner(stream=out, verbosity=2)
1147
test = unittest.FunctionTestCase(not_applicable_test)
1148
result = self.run_test_runner(runner, test)
1149
self._log_file.write(out.getvalue())
1150
self.assertTrue(result.wasSuccessful())
1151
self.assertTrue(result.wasStrictlySuccessful())
1152
self.assertContainsRe(out.getvalue(),
1153
r'(?m)not_applicable_test * N/A')
1154
self.assertContainsRe(out.getvalue(),
1155
r'(?m)^ this test never runs')
1157
def test_not_applicable_demo(self):
1158
# just so you can see it in the test output
1159
raise TestNotApplicable('this test is just a demonstation')
1161
def test_unsupported_features_listed(self):
1162
"""When unsupported features are encountered they are detailed."""
1163
class Feature1(Feature):
1164
def _probe(self): return False
1165
class Feature2(Feature):
1166
def _probe(self): return False
1167
# create sample tests
1168
test1 = SampleTestCase('_test_pass')
1169
test1._test_needs_features = [Feature1()]
1170
test2 = SampleTestCase('_test_pass')
1171
test2._test_needs_features = [Feature2()]
1172
test = unittest.TestSuite()
1176
runner = TextTestRunner(stream=stream)
1177
result = self.run_test_runner(runner, test)
1178
lines = stream.getvalue().splitlines()
1181
"Missing feature 'Feature1' skipped 1 tests.",
1182
"Missing feature 'Feature2' skipped 1 tests.",
1186
def test_bench_history(self):
1187
# tests that the running the benchmark produces a history file
1188
# containing a timestamp and the revision id of the bzrlib source which
1190
workingtree = _get_bzr_source_tree()
1191
test = TestRunner('dummy_test')
1193
runner = TextTestRunner(stream=self._log_file, bench_history=output)
1194
result = self.run_test_runner(runner, test)
1195
output_string = output.getvalue()
1196
self.assertContainsRe(output_string, "--date [0-9.]+")
1197
if workingtree is not None:
1198
revision_id = workingtree.get_parent_ids()[0]
1199
self.assertEndsWith(output_string.rstrip(), revision_id)
1201
def test_success_log_deleted(self):
1202
"""Successful tests have their log deleted"""
1204
class LogTester(TestCase):
1206
def test_success(self):
1207
self.log('this will be removed\n')
1209
sio = cStringIO.StringIO()
1210
runner = TextTestRunner(stream=sio)
1211
test = LogTester('test_success')
1212
result = self.run_test_runner(runner, test)
1214
log = test._get_log()
1215
self.assertEqual("DELETED log file to reduce memory footprint", log)
1216
self.assertEqual('', test._log_contents)
1217
self.assertIs(None, test._log_file_name)
1219
def test_fail_log_kept(self):
1220
"""Failed tests have their log kept"""
1222
class LogTester(TestCase):
1224
def test_fail(self):
1225
self.log('this will be kept\n')
1226
self.fail('this test fails')
1228
sio = cStringIO.StringIO()
1229
runner = TextTestRunner(stream=sio)
1230
test = LogTester('test_fail')
1231
result = self.run_test_runner(runner, test)
1233
text = sio.getvalue()
1234
self.assertContainsRe(text, 'this will be kept')
1235
self.assertContainsRe(text, 'this test fails')
1237
log = test._get_log()
1238
self.assertContainsRe(log, 'this will be kept')
1239
self.assertEqual(log, test._log_contents)
1241
def test_error_log_kept(self):
1242
"""Tests with errors have their log kept"""
1244
class LogTester(TestCase):
1246
def test_error(self):
1247
self.log('this will be kept\n')
1248
raise ValueError('random exception raised')
1250
sio = cStringIO.StringIO()
1251
runner = TextTestRunner(stream=sio)
1252
test = LogTester('test_error')
1253
result = self.run_test_runner(runner, test)
1255
text = sio.getvalue()
1256
self.assertContainsRe(text, 'this will be kept')
1257
self.assertContainsRe(text, 'random exception raised')
1259
log = test._get_log()
1260
self.assertContainsRe(log, 'this will be kept')
1261
self.assertEqual(log, test._log_contents)
1264
class SampleTestCase(TestCase):
1266
def _test_pass(self):
1270
class TestTestCase(TestCase):
1271
"""Tests that test the core bzrlib TestCase."""
1273
def test_debug_flags_sanitised(self):
1274
"""The bzrlib debug flags should be sanitised by setUp."""
1275
# we could set something and run a test that will check
1276
# it gets santised, but this is probably sufficient for now:
1277
# if someone runs the test with -Dsomething it will error.
1278
self.assertEqual(set(), bzrlib.debug.debug_flags)
1280
def inner_test(self):
1281
# the inner child test
1284
def outer_child(self):
1285
# the outer child test
1287
self.inner_test = TestTestCase("inner_child")
1288
result = bzrlib.tests.TextTestResult(self._log_file,
1291
self.inner_test.run(result)
1292
note("outer finish")
1294
def test_trace_nesting(self):
1295
# this tests that each test case nests its trace facility correctly.
1296
# we do this by running a test case manually. That test case (A)
1297
# should setup a new log, log content to it, setup a child case (B),
1298
# which should log independently, then case (A) should log a trailer
1300
# we do two nested children so that we can verify the state of the
1301
# logs after the outer child finishes is correct, which a bad clean
1302
# up routine in tearDown might trigger a fault in our test with only
1303
# one child, we should instead see the bad result inside our test with
1305
# the outer child test
1306
original_trace = bzrlib.trace._trace_file
1307
outer_test = TestTestCase("outer_child")
1308
result = bzrlib.tests.TextTestResult(self._log_file,
1311
outer_test.run(result)
1312
self.assertEqual(original_trace, bzrlib.trace._trace_file)
1314
def method_that_times_a_bit_twice(self):
1315
# call self.time twice to ensure it aggregates
1316
self.time(time.sleep, 0.007)
1317
self.time(time.sleep, 0.007)
1319
def test_time_creates_benchmark_in_result(self):
1320
"""Test that the TestCase.time() method accumulates a benchmark time."""
1321
sample_test = TestTestCase("method_that_times_a_bit_twice")
1322
output_stream = StringIO()
1323
result = bzrlib.tests.VerboseTestResult(
1324
unittest._WritelnDecorator(output_stream),
1327
num_tests=sample_test.countTestCases())
1328
sample_test.run(result)
1329
self.assertContainsRe(
1330
output_stream.getvalue(),
1331
r"\d+ms/ +\d+ms\n$")
1333
def test_hooks_sanitised(self):
1334
"""The bzrlib hooks should be sanitised by setUp."""
1335
self.assertEqual(bzrlib.branch.BranchHooks(),
1336
bzrlib.branch.Branch.hooks)
1337
self.assertEqual(bzrlib.smart.server.SmartServerHooks(),
1338
bzrlib.smart.server.SmartTCPServer.hooks)
1340
def test__gather_lsprof_in_benchmarks(self):
1341
"""When _gather_lsprof_in_benchmarks is on, accumulate profile data.
1343
Each self.time() call is individually and separately profiled.
1345
self.requireFeature(test_lsprof.LSProfFeature)
1346
# overrides the class member with an instance member so no cleanup
1348
self._gather_lsprof_in_benchmarks = True
1349
self.time(time.sleep, 0.000)
1350
self.time(time.sleep, 0.003)
1351
self.assertEqual(2, len(self._benchcalls))
1352
self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
1353
self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
1354
self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
1355
self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
1357
def test_knownFailure(self):
1358
"""Self.knownFailure() should raise a KnownFailure exception."""
1359
self.assertRaises(KnownFailure, self.knownFailure, "A Failure")
1361
def test_requireFeature_available(self):
1362
"""self.requireFeature(available) is a no-op."""
1363
class Available(Feature):
1364
def _probe(self):return True
1365
feature = Available()
1366
self.requireFeature(feature)
1368
def test_requireFeature_unavailable(self):
1369
"""self.requireFeature(unavailable) raises UnavailableFeature."""
1370
class Unavailable(Feature):
1371
def _probe(self):return False
1372
feature = Unavailable()
1373
self.assertRaises(UnavailableFeature, self.requireFeature, feature)
1375
def test_run_no_parameters(self):
1376
test = SampleTestCase('_test_pass')
1379
def test_run_enabled_unittest_result(self):
1380
"""Test we revert to regular behaviour when the test is enabled."""
1381
test = SampleTestCase('_test_pass')
1382
class EnabledFeature(object):
1383
def available(self):
1385
test._test_needs_features = [EnabledFeature()]
1386
result = unittest.TestResult()
1388
self.assertEqual(1, result.testsRun)
1389
self.assertEqual([], result.errors)
1390
self.assertEqual([], result.failures)
1392
def test_run_disabled_unittest_result(self):
1393
"""Test our compatability for disabled tests with unittest results."""
1394
test = SampleTestCase('_test_pass')
1395
class DisabledFeature(object):
1396
def available(self):
1398
test._test_needs_features = [DisabledFeature()]
1399
result = unittest.TestResult()
1401
self.assertEqual(1, result.testsRun)
1402
self.assertEqual([], result.errors)
1403
self.assertEqual([], result.failures)
1405
def test_run_disabled_supporting_result(self):
1406
"""Test disabled tests behaviour with support aware results."""
1407
test = SampleTestCase('_test_pass')
1408
class DisabledFeature(object):
1409
def available(self):
1411
the_feature = DisabledFeature()
1412
test._test_needs_features = [the_feature]
1413
class InstrumentedTestResult(unittest.TestResult):
1415
unittest.TestResult.__init__(self)
1417
def startTest(self, test):
1418
self.calls.append(('startTest', test))
1419
def stopTest(self, test):
1420
self.calls.append(('stopTest', test))
1421
def addNotSupported(self, test, feature):
1422
self.calls.append(('addNotSupported', test, feature))
1423
result = InstrumentedTestResult()
1426
('startTest', test),
1427
('addNotSupported', test, the_feature),
1433
@symbol_versioning.deprecated_function(zero_eleven)
1434
def sample_deprecated_function():
1435
"""A deprecated function to test applyDeprecated with."""
1439
def sample_undeprecated_function(a_param):
1440
"""A undeprecated function to test applyDeprecated with."""
1443
class ApplyDeprecatedHelper(object):
1444
"""A helper class for ApplyDeprecated tests."""
1446
@symbol_versioning.deprecated_method(zero_eleven)
1447
def sample_deprecated_method(self, param_one):
1448
"""A deprecated method for testing with."""
1451
def sample_normal_method(self):
1452
"""A undeprecated method."""
1454
@symbol_versioning.deprecated_method(zero_ten)
1455
def sample_nested_deprecation(self):
1456
return sample_deprecated_function()
1459
class TestExtraAssertions(TestCase):
1460
"""Tests for new test assertions in bzrlib test suite"""
1462
def test_assert_isinstance(self):
1463
self.assertIsInstance(2, int)
1464
self.assertIsInstance(u'', basestring)
1465
self.assertRaises(AssertionError, self.assertIsInstance, None, int)
1466
self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
1468
def test_assertEndsWith(self):
1469
self.assertEndsWith('foo', 'oo')
1470
self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
1472
def test_applyDeprecated_not_deprecated(self):
1473
sample_object = ApplyDeprecatedHelper()
1474
# calling an undeprecated callable raises an assertion
1475
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
1476
sample_object.sample_normal_method)
1477
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
1478
sample_undeprecated_function, "a param value")
1479
# calling a deprecated callable (function or method) with the wrong
1480
# expected deprecation fails.
1481
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
1482
sample_object.sample_deprecated_method, "a param value")
1483
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
1484
sample_deprecated_function)
1485
# calling a deprecated callable (function or method) with the right
1486
# expected deprecation returns the functions result.
1487
self.assertEqual("a param value", self.applyDeprecated(zero_eleven,
1488
sample_object.sample_deprecated_method, "a param value"))
1489
self.assertEqual(2, self.applyDeprecated(zero_eleven,
1490
sample_deprecated_function))
1491
# calling a nested deprecation with the wrong deprecation version
1492
# fails even if a deeper nested function was deprecated with the
1494
self.assertRaises(AssertionError, self.applyDeprecated,
1495
zero_eleven, sample_object.sample_nested_deprecation)
1496
# calling a nested deprecation with the right deprecation value
1497
# returns the calls result.
1498
self.assertEqual(2, self.applyDeprecated(zero_ten,
1499
sample_object.sample_nested_deprecation))
1501
def test_callDeprecated(self):
1502
def testfunc(be_deprecated, result=None):
1503
if be_deprecated is True:
1504
symbol_versioning.warn('i am deprecated', DeprecationWarning,
1507
result = self.callDeprecated(['i am deprecated'], testfunc, True)
1508
self.assertIs(None, result)
1509
result = self.callDeprecated([], testfunc, False, 'result')
1510
self.assertEqual('result', result)
1511
self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
1512
self.callDeprecated([], testfunc, be_deprecated=False)
1515
class TestConvenienceMakers(TestCaseWithTransport):
1516
"""Test for the make_* convenience functions."""
1518
def test_make_branch_and_tree_with_format(self):
1519
# we should be able to supply a format to make_branch_and_tree
1520
self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
1521
self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
1522
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
1523
bzrlib.bzrdir.BzrDirMetaFormat1)
1524
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
1525
bzrlib.bzrdir.BzrDirFormat6)
1527
def test_make_branch_and_memory_tree(self):
1528
# we should be able to get a new branch and a mutable tree from
1529
# TestCaseWithTransport
1530
tree = self.make_branch_and_memory_tree('a')
1531
self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
1534
class TestSFTPMakeBranchAndTree(TestCaseWithSFTPServer):
1536
def test_make_tree_for_sftp_branch(self):
1537
"""Transports backed by local directories create local trees."""
1539
tree = self.make_branch_and_tree('t1')
1540
base = tree.bzrdir.root_transport.base
1541
self.failIf(base.startswith('sftp'),
1542
'base %r is on sftp but should be local' % base)
1543
self.assertEquals(tree.bzrdir.root_transport,
1544
tree.branch.bzrdir.root_transport)
1545
self.assertEquals(tree.bzrdir.root_transport,
1546
tree.branch.repository.bzrdir.root_transport)
1549
class TestSelftest(TestCase):
1550
"""Tests of bzrlib.tests.selftest."""
1552
def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
1555
factory_called.append(True)
1559
self.apply_redirected(out, err, None, bzrlib.tests.selftest,
1560
test_suite_factory=factory)
1561
self.assertEqual([True], factory_called)
1564
class TestKnownFailure(TestCase):
1566
def test_known_failure(self):
1567
"""Check that KnownFailure is defined appropriately."""
1568
# a KnownFailure is an assertion error for compatability with unaware
1570
self.assertIsInstance(KnownFailure(""), AssertionError)
1572
def test_expect_failure(self):
1574
self.expectFailure("Doomed to failure", self.assertTrue, False)
1575
except KnownFailure, e:
1576
self.assertEqual('Doomed to failure', e.args[0])
1578
self.expectFailure("Doomed to failure", self.assertTrue, True)
1579
except AssertionError, e:
1580
self.assertEqual('Unexpected success. Should have failed:'
1581
' Doomed to failure', e.args[0])
1583
self.fail('Assertion not raised')
1586
class TestFeature(TestCase):
1588
def test_caching(self):
1589
"""Feature._probe is called by the feature at most once."""
1590
class InstrumentedFeature(Feature):
1592
Feature.__init__(self)
1595
self.calls.append('_probe')
1597
feature = InstrumentedFeature()
1599
self.assertEqual(['_probe'], feature.calls)
1601
self.assertEqual(['_probe'], feature.calls)
1603
def test_named_str(self):
1604
"""Feature.__str__ should thunk to feature_name()."""
1605
class NamedFeature(Feature):
1606
def feature_name(self):
1608
feature = NamedFeature()
1609
self.assertEqual('symlinks', str(feature))
1611
def test_default_str(self):
1612
"""Feature.__str__ should default to __class__.__name__."""
1613
class NamedFeature(Feature):
1615
feature = NamedFeature()
1616
self.assertEqual('NamedFeature', str(feature))
1619
class TestUnavailableFeature(TestCase):
1621
def test_access_feature(self):
1623
exception = UnavailableFeature(feature)
1624
self.assertIs(feature, exception.args[0])
1627
class TestSelftestFiltering(TestCase):
1630
self.suite = TestUtil.TestSuite()
1631
self.loader = TestUtil.TestLoader()
1632
self.suite.addTest(self.loader.loadTestsFromModuleNames([
1633
'bzrlib.tests.test_selftest']))
1634
self.all_names = [t.id() for t in iter_suite_tests(self.suite)]
1636
def test_filter_suite_by_re(self):
1637
filtered_suite = filter_suite_by_re(self.suite, 'test_filter')
1638
filtered_names = [t.id() for t in iter_suite_tests(filtered_suite)]
1639
self.assertEqual(filtered_names, ['bzrlib.tests.test_selftest.'
1640
'TestSelftestFiltering.test_filter_suite_by_re'])
1642
def test_sort_suite_by_re(self):
1643
sorted_suite = sort_suite_by_re(self.suite, 'test_filter')
1644
sorted_names = [t.id() for t in iter_suite_tests(sorted_suite)]
1645
self.assertEqual(sorted_names[0], 'bzrlib.tests.test_selftest.'
1646
'TestSelftestFiltering.test_filter_suite_by_re')
1647
self.assertEquals(sorted(self.all_names), sorted(sorted_names))
1650
class TestCheckInventoryShape(TestCaseWithTransport):
1652
def test_check_inventory_shape(self):
1653
files = ['a', 'b/', 'b/c']
1654
tree = self.make_branch_and_tree('.')
1655
self.build_tree(files)
1659
self.check_inventory_shape(tree.inventory, files)