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
37
from bzrlib.progress import _BaseProgressBar
38
from bzrlib.repofmt import weaverepo
39
from bzrlib.symbol_versioning import (
44
from bzrlib.tests import (
51
TestCaseWithMemoryTransport,
52
TestCaseWithTransport,
61
exclude_tests_by_condition,
63
filter_suite_by_condition,
68
split_suite_by_condition,
73
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
74
from bzrlib.tests.TestUtil import _load_module_by_name
75
from bzrlib.trace import note
76
from bzrlib.transport.memory import MemoryServer, MemoryTransport
77
from bzrlib.version import _get_bzr_source_tree
80
def _test_ids(test_suite):
81
"""Get the ids for the tests in a test suite."""
82
return [t.id() for t in iter_suite_tests(test_suite)]
85
class SelftestTests(TestCase):
87
def test_import_tests(self):
88
mod = _load_module_by_name('bzrlib.tests.test_selftest')
89
self.assertEqual(mod.SelftestTests, SelftestTests)
91
def test_import_test_failure(self):
92
self.assertRaises(ImportError,
96
class MetaTestLog(TestCase):
98
def test_logging(self):
99
"""Test logs are captured when a test fails."""
100
self.log('a test message')
101
self._log_file.flush()
102
self.assertContainsRe(self._get_log(keep_log_file=True),
106
class TestTreeShape(TestCaseInTempDir):
108
def test_unicode_paths(self):
109
filename = u'hell\u00d8'
111
self.build_tree_contents([(filename, 'contents of hello')])
112
except UnicodeEncodeError:
113
raise TestSkipped("can't build unicode working tree in "
114
"filesystem encoding %s" % sys.getfilesystemencoding())
115
self.failUnlessExists(filename)
118
class TestTransportProviderAdapter(TestCase):
119
"""A group of tests that test the transport implementation adaption core.
121
This is a meta test that the tests are applied to all available
124
This will be generalised in the future which is why it is in this
125
test file even though it is specific to transport tests at the moment.
128
def test_get_transport_permutations(self):
129
# this checks that we the module get_test_permutations call
130
# is made by the adapter get_transport_test_permitations method.
131
class MockModule(object):
132
def get_test_permutations(self):
133
return sample_permutation
134
sample_permutation = [(1,2), (3,4)]
135
from bzrlib.tests.test_transport_implementations \
136
import TransportTestProviderAdapter
137
adapter = TransportTestProviderAdapter()
138
self.assertEqual(sample_permutation,
139
adapter.get_transport_test_permutations(MockModule()))
141
def test_adapter_checks_all_modules(self):
142
# this checks that the adapter returns as many permurtations as
143
# there are in all the registered# transport modules for there
144
# - we assume if this matches its probably doing the right thing
145
# especially in combination with the tests for setting the right
147
from bzrlib.tests.test_transport_implementations \
148
import TransportTestProviderAdapter
149
from bzrlib.transport import _get_transport_modules
150
modules = _get_transport_modules()
151
permutation_count = 0
152
for module in modules:
154
permutation_count += len(reduce(getattr,
155
(module + ".get_test_permutations").split('.')[1:],
156
__import__(module))())
157
except errors.DependencyNotPresent:
159
input_test = TestTransportProviderAdapter(
160
"test_adapter_sets_transport_class")
161
adapter = TransportTestProviderAdapter()
162
self.assertEqual(permutation_count,
163
len(list(iter(adapter.adapt(input_test)))))
165
def test_adapter_sets_transport_class(self):
166
# Check that the test adapter inserts a transport and server into the
169
# This test used to know about all the possible transports and the
170
# order they were returned but that seems overly brittle (mbp
172
from bzrlib.tests.test_transport_implementations \
173
import TransportTestProviderAdapter
174
scenarios = TransportTestProviderAdapter().scenarios
175
# there are at least that many builtin transports
176
self.assertTrue(len(scenarios) > 6)
177
one_scenario = scenarios[0]
178
self.assertIsInstance(one_scenario[0], str)
179
self.assertTrue(issubclass(one_scenario[1]["transport_class"],
180
bzrlib.transport.Transport))
181
self.assertTrue(issubclass(one_scenario[1]["transport_server"],
182
bzrlib.transport.Server))
185
class TestBranchProviderAdapter(TestCase):
186
"""A group of tests that test the branch implementation test adapter."""
188
def test_constructor(self):
189
# check that constructor parameters are passed through to the adapted
191
from bzrlib.tests.branch_implementations import BranchTestProviderAdapter
194
formats = [("c", "C"), ("d", "D")]
195
adapter = BranchTestProviderAdapter(server1, server2, formats)
196
self.assertEqual(2, len(adapter.scenarios))
199
{'branch_format': 'c',
200
'bzrdir_format': 'C',
201
'transport_readonly_server': 'b',
202
'transport_server': 'a'}),
204
{'branch_format': 'd',
205
'bzrdir_format': 'D',
206
'transport_readonly_server': 'b',
207
'transport_server': 'a'})],
211
class TestBzrDirProviderAdapter(TestCase):
212
"""A group of tests that test the bzr dir implementation test adapter."""
214
def test_adapted_tests(self):
215
# check that constructor parameters are passed through to the adapted
217
from bzrlib.tests.bzrdir_implementations import BzrDirTestProviderAdapter
222
adapter = BzrDirTestProviderAdapter(vfs_factory,
223
server1, server2, formats)
226
{'bzrdir_format': 'c',
227
'transport_readonly_server': 'b',
228
'transport_server': 'a',
229
'vfs_transport_factory': 'v'}),
231
{'bzrdir_format': 'd',
232
'transport_readonly_server': 'b',
233
'transport_server': 'a',
234
'vfs_transport_factory': 'v'})],
238
class TestRepositoryProviderAdapter(TestCase):
239
"""A group of tests that test the repository implementation test adapter."""
241
def test_constructor(self):
242
# check that constructor parameters are passed through to the
244
from bzrlib.tests.repository_implementations import RepositoryTestProviderAdapter
247
formats = [("c", "C"), ("d", "D")]
248
adapter = RepositoryTestProviderAdapter(server1, server2, formats)
251
{'bzrdir_format': 'C',
252
'repository_format': 'c',
253
'transport_readonly_server': 'b',
254
'transport_server': 'a'}),
256
{'bzrdir_format': 'D',
257
'repository_format': 'd',
258
'transport_readonly_server': 'b',
259
'transport_server': 'a'})],
262
def test_setting_vfs_transport(self):
263
"""The vfs_transport_factory can be set optionally."""
264
from bzrlib.tests.repository_implementations import RepositoryTestProviderAdapter
265
formats = [("a", "b"), ("c", "d")]
266
adapter = RepositoryTestProviderAdapter(None, None, formats,
267
vfs_transport_factory="vfs")
270
{'bzrdir_format': 'b',
271
'repository_format': 'a',
272
'transport_readonly_server': None,
273
'transport_server': None,
274
'vfs_transport_factory': 'vfs'}),
276
{'bzrdir_format': 'd',
277
'repository_format': 'c',
278
'transport_readonly_server': None,
279
'transport_server': None,
280
'vfs_transport_factory': 'vfs'})],
283
def test_formats_to_scenarios(self):
284
"""The adapter can generate all the scenarios needed."""
285
from bzrlib.tests.repository_implementations import RepositoryTestProviderAdapter
286
no_vfs_adapter = RepositoryTestProviderAdapter("server", "readonly",
288
vfs_adapter = RepositoryTestProviderAdapter("server", "readonly",
289
[], vfs_transport_factory="vfs")
290
# no_vfs generate scenarios without vfs_transport_factor
291
formats = [("c", "C"), (1, "D")]
294
{'bzrdir_format': 'C',
295
'repository_format': 'c',
296
'transport_readonly_server': 'readonly',
297
'transport_server': 'server'}),
299
{'bzrdir_format': 'D',
300
'repository_format': 1,
301
'transport_readonly_server': 'readonly',
302
'transport_server': 'server'})],
303
no_vfs_adapter.formats_to_scenarios(formats))
306
{'bzrdir_format': 'C',
307
'repository_format': 'c',
308
'transport_readonly_server': 'readonly',
309
'transport_server': 'server',
310
'vfs_transport_factory': 'vfs'}),
312
{'bzrdir_format': 'D',
313
'repository_format': 1,
314
'transport_readonly_server': 'readonly',
315
'transport_server': 'server',
316
'vfs_transport_factory': 'vfs'})],
317
vfs_adapter.formats_to_scenarios(formats))
320
class TestTestScenarioApplier(TestCase):
321
"""Tests for the test adaption facilities."""
323
def test_adapt_applies_scenarios(self):
324
from bzrlib.tests.repository_implementations import TestScenarioApplier
325
input_test = TestTestScenarioApplier("test_adapt_test_to_scenario")
326
adapter = TestScenarioApplier()
327
adapter.scenarios = [("1", "dict"), ("2", "settings")]
329
def capture_call(test, scenario):
330
calls.append((test, scenario))
332
adapter.adapt_test_to_scenario = capture_call
333
adapter.adapt(input_test)
334
self.assertEqual([(input_test, ("1", "dict")),
335
(input_test, ("2", "settings"))], calls)
337
def test_adapt_test_to_scenario(self):
338
from bzrlib.tests.repository_implementations import TestScenarioApplier
339
input_test = TestTestScenarioApplier("test_adapt_test_to_scenario")
340
adapter = TestScenarioApplier()
341
# setup two adapted tests
342
adapted_test1 = adapter.adapt_test_to_scenario(input_test,
344
{"bzrdir_format":"bzr_format",
345
"repository_format":"repo_fmt",
346
"transport_server":"transport_server",
347
"transport_readonly_server":"readonly-server"}))
348
adapted_test2 = adapter.adapt_test_to_scenario(input_test,
349
("new id 2", {"bzrdir_format":None}))
350
# input_test should have been altered.
351
self.assertRaises(AttributeError, getattr, input_test, "bzrdir_format")
352
# the new tests are mutually incompatible, ensuring it has
353
# made new ones, and unspecified elements in the scenario
354
# should not have been altered.
355
self.assertEqual("bzr_format", adapted_test1.bzrdir_format)
356
self.assertEqual("repo_fmt", adapted_test1.repository_format)
357
self.assertEqual("transport_server", adapted_test1.transport_server)
358
self.assertEqual("readonly-server",
359
adapted_test1.transport_readonly_server)
361
"bzrlib.tests.test_selftest.TestTestScenarioApplier."
362
"test_adapt_test_to_scenario(new id)",
364
self.assertEqual(None, adapted_test2.bzrdir_format)
366
"bzrlib.tests.test_selftest.TestTestScenarioApplier."
367
"test_adapt_test_to_scenario(new id 2)",
371
class TestInterRepositoryProviderAdapter(TestCase):
372
"""A group of tests that test the InterRepository test adapter."""
374
def test_adapted_tests(self):
375
# check that constructor parameters are passed through to the adapted
377
from bzrlib.tests.interrepository_implementations import \
378
InterRepositoryTestProviderAdapter
381
formats = [(str, "C1", "C2"), (int, "D1", "D2")]
382
adapter = InterRepositoryTestProviderAdapter(server1, server2, formats)
385
{'interrepo_class': str,
386
'repository_format': 'C1',
387
'repository_format_to': 'C2',
388
'transport_readonly_server': 'b',
389
'transport_server': 'a'}),
391
{'interrepo_class': int,
392
'repository_format': 'D1',
393
'repository_format_to': 'D2',
394
'transport_readonly_server': 'b',
395
'transport_server': 'a'})],
396
adapter.formats_to_scenarios(formats))
399
class TestWorkingTreeProviderAdapter(TestCase):
400
"""A group of tests that test the workingtree implementation test adapter."""
402
def test_scenarios(self):
403
# check that constructor parameters are passed through to the adapted
405
from bzrlib.tests.workingtree_implementations \
406
import WorkingTreeTestProviderAdapter
409
formats = [("c", "C"), ("d", "D")]
410
adapter = WorkingTreeTestProviderAdapter(server1, server2, formats)
413
{'bzrdir_format': 'C',
414
'transport_readonly_server': 'b',
415
'transport_server': 'a',
416
'workingtree_format': 'c'}),
418
{'bzrdir_format': 'D',
419
'transport_readonly_server': 'b',
420
'transport_server': 'a',
421
'workingtree_format': 'd'})],
425
class TestTreeProviderAdapter(TestCase):
426
"""Test the setup of tree_implementation tests."""
428
def test_adapted_tests(self):
429
# the tree implementation adapter is meant to setup one instance for
430
# each working tree format, and one additional instance that will
431
# use the default wt format, but create a revision tree for the tests.
432
# this means that the wt ones should have the workingtree_to_test_tree
433
# attribute set to 'return_parameter' and the revision one set to
434
# revision_tree_from_workingtree.
436
from bzrlib.tests.tree_implementations import (
437
TreeTestProviderAdapter,
439
revision_tree_from_workingtree
441
from bzrlib.workingtree import WorkingTreeFormat, WorkingTreeFormat3
442
input_test = TestTreeProviderAdapter(
443
"test_adapted_tests")
446
formats = [("c", "C"), ("d", "D")]
447
adapter = TreeTestProviderAdapter(server1, server2, formats)
448
suite = adapter.adapt(input_test)
449
tests = list(iter(suite))
450
# XXX We should not have tests fail as we add more scenarios
452
self.assertEqual(5, len(tests))
453
# this must match the default format setp up in
454
# TreeTestProviderAdapter.adapt
455
default_format = WorkingTreeFormat3
456
self.assertEqual(tests[0].workingtree_format, formats[0][0])
457
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
458
self.assertEqual(tests[0].transport_server, server1)
459
self.assertEqual(tests[0].transport_readonly_server, server2)
460
self.assertEqual(tests[0]._workingtree_to_test_tree, return_parameter)
461
self.assertEqual(tests[1].workingtree_format, formats[1][0])
462
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
463
self.assertEqual(tests[1].transport_server, server1)
464
self.assertEqual(tests[1].transport_readonly_server, server2)
465
self.assertEqual(tests[1]._workingtree_to_test_tree, return_parameter)
466
self.assertIsInstance(tests[2].workingtree_format, default_format)
467
#self.assertEqual(tests[2].bzrdir_format,
468
# default_format._matchingbzrdir)
469
self.assertEqual(tests[2].transport_server, server1)
470
self.assertEqual(tests[2].transport_readonly_server, server2)
471
self.assertEqual(tests[2]._workingtree_to_test_tree,
472
revision_tree_from_workingtree)
475
class TestInterTreeProviderAdapter(TestCase):
476
"""A group of tests that test the InterTreeTestAdapter."""
478
def test_adapted_tests(self):
479
# check that constructor parameters are passed through to the adapted
481
# for InterTree tests we want the machinery to bring up two trees in
482
# each instance: the base one, and the one we are interacting with.
483
# because each optimiser can be direction specific, we need to test
484
# each optimiser in its chosen direction.
485
# unlike the TestProviderAdapter we dont want to automatically add a
486
# parameterized one for WorkingTree - the optimisers will tell us what
488
from bzrlib.tests.tree_implementations import (
490
revision_tree_from_workingtree
492
from bzrlib.tests.intertree_implementations import (
493
InterTreeTestProviderAdapter,
495
from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
496
input_test = TestInterTreeProviderAdapter(
497
"test_adapted_tests")
500
format1 = WorkingTreeFormat2()
501
format2 = WorkingTreeFormat3()
502
formats = [(str, format1, format2, "converter1"),
503
(int, format2, format1, "converter2")]
504
adapter = InterTreeTestProviderAdapter(server1, server2, formats)
505
suite = adapter.adapt(input_test)
506
tests = list(iter(suite))
507
self.assertEqual(2, len(tests))
508
self.assertEqual(tests[0].intertree_class, formats[0][0])
509
self.assertEqual(tests[0].workingtree_format, formats[0][1])
510
self.assertEqual(tests[0].workingtree_format_to, formats[0][2])
511
self.assertEqual(tests[0].mutable_trees_to_test_trees, formats[0][3])
512
self.assertEqual(tests[0]._workingtree_to_test_tree, return_parameter)
513
self.assertEqual(tests[0].transport_server, server1)
514
self.assertEqual(tests[0].transport_readonly_server, server2)
515
self.assertEqual(tests[1].intertree_class, formats[1][0])
516
self.assertEqual(tests[1].workingtree_format, formats[1][1])
517
self.assertEqual(tests[1].workingtree_format_to, formats[1][2])
518
self.assertEqual(tests[1].mutable_trees_to_test_trees, formats[1][3])
519
self.assertEqual(tests[1]._workingtree_to_test_tree, return_parameter)
520
self.assertEqual(tests[1].transport_server, server1)
521
self.assertEqual(tests[1].transport_readonly_server, server2)
524
class TestTestCaseInTempDir(TestCaseInTempDir):
526
def test_home_is_not_working(self):
527
self.assertNotEqual(self.test_dir, self.test_home_dir)
528
cwd = osutils.getcwd()
529
self.assertIsSameRealPath(self.test_dir, cwd)
530
self.assertIsSameRealPath(self.test_home_dir, os.environ['HOME'])
533
class TestTestCaseWithMemoryTransport(TestCaseWithMemoryTransport):
535
def test_home_is_non_existant_dir_under_root(self):
536
"""The test_home_dir for TestCaseWithMemoryTransport is missing.
538
This is because TestCaseWithMemoryTransport is for tests that do not
539
need any disk resources: they should be hooked into bzrlib in such a
540
way that no global settings are being changed by the test (only a
541
few tests should need to do that), and having a missing dir as home is
542
an effective way to ensure that this is the case.
544
self.assertIsSameRealPath(
545
self.TEST_ROOT + "/MemoryTransportMissingHomeDir",
547
self.assertIsSameRealPath(self.test_home_dir, os.environ['HOME'])
549
def test_cwd_is_TEST_ROOT(self):
550
self.assertIsSameRealPath(self.test_dir, self.TEST_ROOT)
551
cwd = osutils.getcwd()
552
self.assertIsSameRealPath(self.test_dir, cwd)
554
def test_make_branch_and_memory_tree(self):
555
"""In TestCaseWithMemoryTransport we should not make the branch on disk.
557
This is hard to comprehensively robustly test, so we settle for making
558
a branch and checking no directory was created at its relpath.
560
tree = self.make_branch_and_memory_tree('dir')
561
# Guard against regression into MemoryTransport leaking
562
# files to disk instead of keeping them in memory.
563
self.failIf(osutils.lexists('dir'))
564
self.assertIsInstance(tree, memorytree.MemoryTree)
566
def test_make_branch_and_memory_tree_with_format(self):
567
"""make_branch_and_memory_tree should accept a format option."""
568
format = bzrdir.BzrDirMetaFormat1()
569
format.repository_format = weaverepo.RepositoryFormat7()
570
tree = self.make_branch_and_memory_tree('dir', format=format)
571
# Guard against regression into MemoryTransport leaking
572
# files to disk instead of keeping them in memory.
573
self.failIf(osutils.lexists('dir'))
574
self.assertIsInstance(tree, memorytree.MemoryTree)
575
self.assertEqual(format.repository_format.__class__,
576
tree.branch.repository._format.__class__)
578
def test_safety_net(self):
579
"""No test should modify the safety .bzr directory.
581
We just test that the _check_safety_net private method raises
582
AssertionError, it's easier than building a test suite with the same
585
# Oops, a commit in the current directory (i.e. without local .bzr
586
# directory) will crawl up the hierarchy to find a .bzr directory.
587
self.run_bzr(['commit', '-mfoo', '--unchanged'])
588
# But we have a safety net in place.
589
self.assertRaises(AssertionError, self._check_safety_net)
592
class TestTestCaseWithTransport(TestCaseWithTransport):
593
"""Tests for the convenience functions TestCaseWithTransport introduces."""
595
def test_get_readonly_url_none(self):
596
from bzrlib.transport import get_transport
597
from bzrlib.transport.memory import MemoryServer
598
from bzrlib.transport.readonly import ReadonlyTransportDecorator
599
self.vfs_transport_factory = MemoryServer
600
self.transport_readonly_server = None
601
# calling get_readonly_transport() constructs a decorator on the url
603
url = self.get_readonly_url()
604
url2 = self.get_readonly_url('foo/bar')
605
t = get_transport(url)
606
t2 = get_transport(url2)
607
self.failUnless(isinstance(t, ReadonlyTransportDecorator))
608
self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
609
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
611
def test_get_readonly_url_http(self):
612
from bzrlib.tests.http_server import HttpServer
613
from bzrlib.transport import get_transport
614
from bzrlib.transport.local import LocalURLServer
615
from bzrlib.transport.http import HttpTransportBase
616
self.transport_server = LocalURLServer
617
self.transport_readonly_server = HttpServer
618
# calling get_readonly_transport() gives us a HTTP server instance.
619
url = self.get_readonly_url()
620
url2 = self.get_readonly_url('foo/bar')
621
# the transport returned may be any HttpTransportBase subclass
622
t = get_transport(url)
623
t2 = get_transport(url2)
624
self.failUnless(isinstance(t, HttpTransportBase))
625
self.failUnless(isinstance(t2, HttpTransportBase))
626
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
628
def test_is_directory(self):
629
"""Test assertIsDirectory assertion"""
630
t = self.get_transport()
631
self.build_tree(['a_dir/', 'a_file'], transport=t)
632
self.assertIsDirectory('a_dir', t)
633
self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
634
self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
637
class TestTestCaseTransports(TestCaseWithTransport):
640
super(TestTestCaseTransports, self).setUp()
641
self.vfs_transport_factory = MemoryServer
643
def test_make_bzrdir_preserves_transport(self):
644
t = self.get_transport()
645
result_bzrdir = self.make_bzrdir('subdir')
646
self.assertIsInstance(result_bzrdir.transport,
648
# should not be on disk, should only be in memory
649
self.failIfExists('subdir')
652
class TestChrootedTest(ChrootedTestCase):
654
def test_root_is_root(self):
655
from bzrlib.transport import get_transport
656
t = get_transport(self.get_readonly_url())
658
self.assertEqual(url, t.clone('..').base)
661
class MockProgress(_BaseProgressBar):
662
"""Progress-bar standin that records calls.
664
Useful for testing pb using code.
668
_BaseProgressBar.__init__(self)
672
self.calls.append(('tick',))
674
def update(self, msg=None, current=None, total=None):
675
self.calls.append(('update', msg, current, total))
678
self.calls.append(('clear',))
680
def note(self, msg, *args):
681
self.calls.append(('note', msg, args))
684
class TestTestResult(TestCase):
686
def check_timing(self, test_case, expected_re):
687
result = bzrlib.tests.TextTestResult(self._log_file,
691
test_case.run(result)
692
timed_string = result._testTimeString(test_case)
693
self.assertContainsRe(timed_string, expected_re)
695
def test_test_reporting(self):
696
class ShortDelayTestCase(TestCase):
697
def test_short_delay(self):
699
def test_short_benchmark(self):
700
self.time(time.sleep, 0.003)
701
self.check_timing(ShortDelayTestCase('test_short_delay'),
703
# if a benchmark time is given, we want a x of y style result.
704
self.check_timing(ShortDelayTestCase('test_short_benchmark'),
705
r"^ +[0-9]+ms/ +[0-9]+ms$")
707
def test_unittest_reporting_unittest_class(self):
708
# getting the time from a non-bzrlib test works ok
709
class ShortDelayTestCase(unittest.TestCase):
710
def test_short_delay(self):
712
self.check_timing(ShortDelayTestCase('test_short_delay'),
715
def test_assigned_benchmark_file_stores_date(self):
717
result = bzrlib.tests.TextTestResult(self._log_file,
722
output_string = output.getvalue()
723
# if you are wondering about the regexp please read the comment in
724
# test_bench_history (bzrlib.tests.test_selftest.TestRunner)
725
# XXX: what comment? -- Andrew Bennetts
726
self.assertContainsRe(output_string, "--date [0-9.]+")
728
def test_benchhistory_records_test_times(self):
729
result_stream = StringIO()
730
result = bzrlib.tests.TextTestResult(
734
bench_history=result_stream
737
# we want profile a call and check that its test duration is recorded
738
# make a new test instance that when run will generate a benchmark
739
example_test_case = TestTestResult("_time_hello_world_encoding")
740
# execute the test, which should succeed and record times
741
example_test_case.run(result)
742
lines = result_stream.getvalue().splitlines()
743
self.assertEqual(2, len(lines))
744
self.assertContainsRe(lines[1],
745
" *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
746
"._time_hello_world_encoding")
748
def _time_hello_world_encoding(self):
749
"""Profile two sleep calls
751
This is used to exercise the test framework.
753
self.time(unicode, 'hello', errors='replace')
754
self.time(unicode, 'world', errors='replace')
756
def test_lsprofiling(self):
757
"""Verbose test result prints lsprof statistics from test cases."""
758
self.requireFeature(test_lsprof.LSProfFeature)
759
result_stream = StringIO()
760
result = bzrlib.tests.VerboseTestResult(
761
unittest._WritelnDecorator(result_stream),
765
# we want profile a call of some sort and check it is output by
766
# addSuccess. We dont care about addError or addFailure as they
767
# are not that interesting for performance tuning.
768
# make a new test instance that when run will generate a profile
769
example_test_case = TestTestResult("_time_hello_world_encoding")
770
example_test_case._gather_lsprof_in_benchmarks = True
771
# execute the test, which should succeed and record profiles
772
example_test_case.run(result)
773
# lsprofile_something()
774
# if this worked we want
775
# LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
776
# CallCount Recursive Total(ms) Inline(ms) module:lineno(function)
777
# (the lsprof header)
778
# ... an arbitrary number of lines
779
# and the function call which is time.sleep.
780
# 1 0 ??? ??? ???(sleep)
781
# and then repeated but with 'world', rather than 'hello'.
782
# this should appear in the output stream of our test result.
783
output = result_stream.getvalue()
784
self.assertContainsRe(output,
785
r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
786
self.assertContainsRe(output,
787
r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
788
self.assertContainsRe(output,
789
r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
790
self.assertContainsRe(output,
791
r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
793
def test_known_failure(self):
794
"""A KnownFailure being raised should trigger several result actions."""
795
class InstrumentedTestResult(ExtendedTestResult):
797
def report_test_start(self, test): pass
798
def report_known_failure(self, test, err):
799
self._call = test, err
800
result = InstrumentedTestResult(None, None, None, None)
802
raise KnownFailure('failed!')
803
test = unittest.FunctionTestCase(test_function)
805
# it should invoke 'report_known_failure'.
806
self.assertEqual(2, len(result._call))
807
self.assertEqual(test, result._call[0])
808
self.assertEqual(KnownFailure, result._call[1][0])
809
self.assertIsInstance(result._call[1][1], KnownFailure)
810
# we dont introspec the traceback, if the rest is ok, it would be
811
# exceptional for it not to be.
812
# it should update the known_failure_count on the object.
813
self.assertEqual(1, result.known_failure_count)
814
# the result should be successful.
815
self.assertTrue(result.wasSuccessful())
817
def test_verbose_report_known_failure(self):
818
# verbose test output formatting
819
result_stream = StringIO()
820
result = bzrlib.tests.VerboseTestResult(
821
unittest._WritelnDecorator(result_stream),
825
test = self.get_passing_test()
826
result.startTest(test)
827
prefix = len(result_stream.getvalue())
828
# the err parameter has the shape:
829
# (class, exception object, traceback)
830
# KnownFailures dont get their tracebacks shown though, so we
832
err = (KnownFailure, KnownFailure('foo'), None)
833
result.report_known_failure(test, err)
834
output = result_stream.getvalue()[prefix:]
835
lines = output.splitlines()
836
self.assertContainsRe(lines[0], r'XFAIL *\d+ms$')
837
self.assertEqual(lines[1], ' foo')
838
self.assertEqual(2, len(lines))
840
def test_text_report_known_failure(self):
841
# text test output formatting
843
result = bzrlib.tests.TextTestResult(
849
test = self.get_passing_test()
850
# this seeds the state to handle reporting the test.
851
result.startTest(test)
852
# the err parameter has the shape:
853
# (class, exception object, traceback)
854
# KnownFailures dont get their tracebacks shown though, so we
856
err = (KnownFailure, KnownFailure('foo'), None)
857
result.report_known_failure(test, err)
860
('update', '[1 in 0s] passing_test', None, None),
861
('note', 'XFAIL: %s\n%s\n', ('passing_test', err[1]))
864
# known_failures should be printed in the summary, so if we run a test
865
# after there are some known failures, the update prefix should match
867
result.known_failure_count = 3
871
('update', '[2 in 0s] passing_test', None, None),
875
def get_passing_test(self):
876
"""Return a test object that can't be run usefully."""
879
return unittest.FunctionTestCase(passing_test)
881
def test_add_not_supported(self):
882
"""Test the behaviour of invoking addNotSupported."""
883
class InstrumentedTestResult(ExtendedTestResult):
884
def report_test_start(self, test): pass
885
def report_unsupported(self, test, feature):
886
self._call = test, feature
887
result = InstrumentedTestResult(None, None, None, None)
888
test = SampleTestCase('_test_pass')
890
result.startTest(test)
891
result.addNotSupported(test, feature)
892
# it should invoke 'report_unsupported'.
893
self.assertEqual(2, len(result._call))
894
self.assertEqual(test, result._call[0])
895
self.assertEqual(feature, result._call[1])
896
# the result should be successful.
897
self.assertTrue(result.wasSuccessful())
898
# it should record the test against a count of tests not run due to
900
self.assertEqual(1, result.unsupported['Feature'])
901
# and invoking it again should increment that counter
902
result.addNotSupported(test, feature)
903
self.assertEqual(2, result.unsupported['Feature'])
905
def test_verbose_report_unsupported(self):
906
# verbose test output formatting
907
result_stream = StringIO()
908
result = bzrlib.tests.VerboseTestResult(
909
unittest._WritelnDecorator(result_stream),
913
test = self.get_passing_test()
915
result.startTest(test)
916
prefix = len(result_stream.getvalue())
917
result.report_unsupported(test, feature)
918
output = result_stream.getvalue()[prefix:]
919
lines = output.splitlines()
920
self.assertEqual(lines, ['NODEP 0ms', " The feature 'Feature' is not available."])
922
def test_text_report_unsupported(self):
923
# text test output formatting
925
result = bzrlib.tests.TextTestResult(
931
test = self.get_passing_test()
933
# this seeds the state to handle reporting the test.
934
result.startTest(test)
935
result.report_unsupported(test, feature)
936
# no output on unsupported features
938
[('update', '[1 in 0s] passing_test', None, None)
941
# the number of missing features should be printed in the progress
942
# summary, so check for that.
943
result.unsupported = {'foo':0, 'bar':0}
947
('update', '[2 in 0s, 2 missing] passing_test', None, None),
951
def test_unavailable_exception(self):
952
"""An UnavailableFeature being raised should invoke addNotSupported."""
953
class InstrumentedTestResult(ExtendedTestResult):
955
def report_test_start(self, test): pass
956
def addNotSupported(self, test, feature):
957
self._call = test, feature
958
result = InstrumentedTestResult(None, None, None, None)
961
raise UnavailableFeature(feature)
962
test = unittest.FunctionTestCase(test_function)
964
# it should invoke 'addNotSupported'.
965
self.assertEqual(2, len(result._call))
966
self.assertEqual(test, result._call[0])
967
self.assertEqual(feature, result._call[1])
968
# and not count as an error
969
self.assertEqual(0, result.error_count)
971
def test_strict_with_unsupported_feature(self):
972
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
974
test = self.get_passing_test()
975
feature = "Unsupported Feature"
976
result.addNotSupported(test, feature)
977
self.assertFalse(result.wasStrictlySuccessful())
978
self.assertEqual(None, result._extractBenchmarkTime(test))
980
def test_strict_with_known_failure(self):
981
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
983
test = self.get_passing_test()
984
err = (KnownFailure, KnownFailure('foo'), None)
985
result._addKnownFailure(test, err)
986
self.assertFalse(result.wasStrictlySuccessful())
987
self.assertEqual(None, result._extractBenchmarkTime(test))
989
def test_strict_with_success(self):
990
result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
992
test = self.get_passing_test()
993
result.addSuccess(test)
994
self.assertTrue(result.wasStrictlySuccessful())
995
self.assertEqual(None, result._extractBenchmarkTime(test))
998
class TestRunner(TestCase):
1000
def dummy_test(self):
1003
def run_test_runner(self, testrunner, test):
1004
"""Run suite in testrunner, saving global state and restoring it.
1006
This current saves and restores:
1007
TestCaseInTempDir.TEST_ROOT
1009
There should be no tests in this file that use bzrlib.tests.TextTestRunner
1010
without using this convenience method, because of our use of global state.
1012
old_root = TestCaseInTempDir.TEST_ROOT
1014
TestCaseInTempDir.TEST_ROOT = None
1015
return testrunner.run(test)
1017
TestCaseInTempDir.TEST_ROOT = old_root
1019
def test_known_failure_failed_run(self):
1020
# run a test that generates a known failure which should be printed in
1021
# the final output when real failures occur.
1022
def known_failure_test():
1023
raise KnownFailure('failed')
1024
test = unittest.TestSuite()
1025
test.addTest(unittest.FunctionTestCase(known_failure_test))
1027
raise AssertionError('foo')
1028
test.addTest(unittest.FunctionTestCase(failing_test))
1030
runner = TextTestRunner(stream=stream)
1031
result = self.run_test_runner(runner, test)
1032
lines = stream.getvalue().splitlines()
1035
'======================================================================',
1036
'FAIL: unittest.FunctionTestCase (failing_test)',
1037
'----------------------------------------------------------------------',
1038
'Traceback (most recent call last):',
1039
' raise AssertionError(\'foo\')',
1040
'AssertionError: foo',
1042
'----------------------------------------------------------------------',
1044
'FAILED (failures=1, known_failure_count=1)'],
1045
lines[0:5] + lines[6:10] + lines[11:])
1047
def test_known_failure_ok_run(self):
1048
# run a test that generates a known failure which should be printed in the final output.
1049
def known_failure_test():
1050
raise KnownFailure('failed')
1051
test = unittest.FunctionTestCase(known_failure_test)
1053
runner = TextTestRunner(stream=stream)
1054
result = self.run_test_runner(runner, test)
1055
self.assertContainsRe(stream.getvalue(),
1058
'Ran 1 test in .*\n'
1060
'OK \\(known_failures=1\\)\n')
1062
def test_skipped_test(self):
1063
# run a test that is skipped, and check the suite as a whole still
1065
# skipping_test must be hidden in here so it's not run as a real test
1066
def skipping_test():
1067
raise TestSkipped('test intentionally skipped')
1069
runner = TextTestRunner(stream=self._log_file)
1070
test = unittest.FunctionTestCase(skipping_test)
1071
result = self.run_test_runner(runner, test)
1072
self.assertTrue(result.wasSuccessful())
1074
def test_skipped_from_setup(self):
1076
class SkippedSetupTest(TestCase):
1079
calls.append('setUp')
1080
self.addCleanup(self.cleanup)
1081
raise TestSkipped('skipped setup')
1083
def test_skip(self):
1084
self.fail('test reached')
1087
calls.append('cleanup')
1089
runner = TextTestRunner(stream=self._log_file)
1090
test = SkippedSetupTest('test_skip')
1091
result = self.run_test_runner(runner, test)
1092
self.assertTrue(result.wasSuccessful())
1093
# Check if cleanup was called the right number of times.
1094
self.assertEqual(['setUp', 'cleanup'], calls)
1096
def test_skipped_from_test(self):
1098
class SkippedTest(TestCase):
1101
calls.append('setUp')
1102
self.addCleanup(self.cleanup)
1104
def test_skip(self):
1105
raise TestSkipped('skipped test')
1108
calls.append('cleanup')
1110
runner = TextTestRunner(stream=self._log_file)
1111
test = SkippedTest('test_skip')
1112
result = self.run_test_runner(runner, test)
1113
self.assertTrue(result.wasSuccessful())
1114
# Check if cleanup was called the right number of times.
1115
self.assertEqual(['setUp', 'cleanup'], calls)
1117
def test_not_applicable(self):
1118
# run a test that is skipped because it's not applicable
1119
def not_applicable_test():
1120
from bzrlib.tests import TestNotApplicable
1121
raise TestNotApplicable('this test never runs')
1123
runner = TextTestRunner(stream=out, verbosity=2)
1124
test = unittest.FunctionTestCase(not_applicable_test)
1125
result = self.run_test_runner(runner, test)
1126
self._log_file.write(out.getvalue())
1127
self.assertTrue(result.wasSuccessful())
1128
self.assertTrue(result.wasStrictlySuccessful())
1129
self.assertContainsRe(out.getvalue(),
1130
r'(?m)not_applicable_test * N/A')
1131
self.assertContainsRe(out.getvalue(),
1132
r'(?m)^ this test never runs')
1134
def test_not_applicable_demo(self):
1135
# just so you can see it in the test output
1136
raise TestNotApplicable('this test is just a demonstation')
1138
def test_unsupported_features_listed(self):
1139
"""When unsupported features are encountered they are detailed."""
1140
class Feature1(Feature):
1141
def _probe(self): return False
1142
class Feature2(Feature):
1143
def _probe(self): return False
1144
# create sample tests
1145
test1 = SampleTestCase('_test_pass')
1146
test1._test_needs_features = [Feature1()]
1147
test2 = SampleTestCase('_test_pass')
1148
test2._test_needs_features = [Feature2()]
1149
test = unittest.TestSuite()
1153
runner = TextTestRunner(stream=stream)
1154
result = self.run_test_runner(runner, test)
1155
lines = stream.getvalue().splitlines()
1158
"Missing feature 'Feature1' skipped 1 tests.",
1159
"Missing feature 'Feature2' skipped 1 tests.",
1163
def test_bench_history(self):
1164
# tests that the running the benchmark produces a history file
1165
# containing a timestamp and the revision id of the bzrlib source which
1167
workingtree = _get_bzr_source_tree()
1168
test = TestRunner('dummy_test')
1170
runner = TextTestRunner(stream=self._log_file, bench_history=output)
1171
result = self.run_test_runner(runner, test)
1172
output_string = output.getvalue()
1173
self.assertContainsRe(output_string, "--date [0-9.]+")
1174
if workingtree is not None:
1175
revision_id = workingtree.get_parent_ids()[0]
1176
self.assertEndsWith(output_string.rstrip(), revision_id)
1178
def assertLogDeleted(self, test):
1179
log = test._get_log()
1180
self.assertEqual("DELETED log file to reduce memory footprint", log)
1181
self.assertEqual('', test._log_contents)
1182
self.assertIs(None, test._log_file_name)
1184
def test_success_log_deleted(self):
1185
"""Successful tests have their log deleted"""
1187
class LogTester(TestCase):
1189
def test_success(self):
1190
self.log('this will be removed\n')
1192
sio = cStringIO.StringIO()
1193
runner = TextTestRunner(stream=sio)
1194
test = LogTester('test_success')
1195
result = self.run_test_runner(runner, test)
1197
self.assertLogDeleted(test)
1199
def test_skipped_log_deleted(self):
1200
"""Skipped tests have their log deleted"""
1202
class LogTester(TestCase):
1204
def test_skipped(self):
1205
self.log('this will be removed\n')
1206
raise tests.TestSkipped()
1208
sio = cStringIO.StringIO()
1209
runner = TextTestRunner(stream=sio)
1210
test = LogTester('test_skipped')
1211
result = self.run_test_runner(runner, test)
1213
self.assertLogDeleted(test)
1215
def test_not_aplicable_log_deleted(self):
1216
"""Not applicable tests have their log deleted"""
1218
class LogTester(TestCase):
1220
def test_not_applicable(self):
1221
self.log('this will be removed\n')
1222
raise tests.TestNotApplicable()
1224
sio = cStringIO.StringIO()
1225
runner = TextTestRunner(stream=sio)
1226
test = LogTester('test_not_applicable')
1227
result = self.run_test_runner(runner, test)
1229
self.assertLogDeleted(test)
1231
def test_known_failure_log_deleted(self):
1232
"""Know failure tests have their log deleted"""
1234
class LogTester(TestCase):
1236
def test_known_failure(self):
1237
self.log('this will be removed\n')
1238
raise tests.KnownFailure()
1240
sio = cStringIO.StringIO()
1241
runner = TextTestRunner(stream=sio)
1242
test = LogTester('test_known_failure')
1243
result = self.run_test_runner(runner, test)
1245
self.assertLogDeleted(test)
1247
def test_fail_log_kept(self):
1248
"""Failed tests have their log kept"""
1250
class LogTester(TestCase):
1252
def test_fail(self):
1253
self.log('this will be kept\n')
1254
self.fail('this test fails')
1256
sio = cStringIO.StringIO()
1257
runner = TextTestRunner(stream=sio)
1258
test = LogTester('test_fail')
1259
result = self.run_test_runner(runner, test)
1261
text = sio.getvalue()
1262
self.assertContainsRe(text, 'this will be kept')
1263
self.assertContainsRe(text, 'this test fails')
1265
log = test._get_log()
1266
self.assertContainsRe(log, 'this will be kept')
1267
self.assertEqual(log, test._log_contents)
1269
def test_error_log_kept(self):
1270
"""Tests with errors have their log kept"""
1272
class LogTester(TestCase):
1274
def test_error(self):
1275
self.log('this will be kept\n')
1276
raise ValueError('random exception raised')
1278
sio = cStringIO.StringIO()
1279
runner = TextTestRunner(stream=sio)
1280
test = LogTester('test_error')
1281
result = self.run_test_runner(runner, test)
1283
text = sio.getvalue()
1284
self.assertContainsRe(text, 'this will be kept')
1285
self.assertContainsRe(text, 'random exception raised')
1287
log = test._get_log()
1288
self.assertContainsRe(log, 'this will be kept')
1289
self.assertEqual(log, test._log_contents)
1292
class SampleTestCase(TestCase):
1294
def _test_pass(self):
1298
class TestTestCase(TestCase):
1299
"""Tests that test the core bzrlib TestCase."""
1301
def test_debug_flags_sanitised(self):
1302
"""The bzrlib debug flags should be sanitised by setUp."""
1303
# we could set something and run a test that will check
1304
# it gets santised, but this is probably sufficient for now:
1305
# if someone runs the test with -Dsomething it will error.
1306
self.assertEqual(set(), bzrlib.debug.debug_flags)
1308
def inner_test(self):
1309
# the inner child test
1312
def outer_child(self):
1313
# the outer child test
1315
self.inner_test = TestTestCase("inner_child")
1316
result = bzrlib.tests.TextTestResult(self._log_file,
1319
self.inner_test.run(result)
1320
note("outer finish")
1322
def test_trace_nesting(self):
1323
# this tests that each test case nests its trace facility correctly.
1324
# we do this by running a test case manually. That test case (A)
1325
# should setup a new log, log content to it, setup a child case (B),
1326
# which should log independently, then case (A) should log a trailer
1328
# we do two nested children so that we can verify the state of the
1329
# logs after the outer child finishes is correct, which a bad clean
1330
# up routine in tearDown might trigger a fault in our test with only
1331
# one child, we should instead see the bad result inside our test with
1333
# the outer child test
1334
original_trace = bzrlib.trace._trace_file
1335
outer_test = TestTestCase("outer_child")
1336
result = bzrlib.tests.TextTestResult(self._log_file,
1339
outer_test.run(result)
1340
self.assertEqual(original_trace, bzrlib.trace._trace_file)
1342
def method_that_times_a_bit_twice(self):
1343
# call self.time twice to ensure it aggregates
1344
self.time(time.sleep, 0.007)
1345
self.time(time.sleep, 0.007)
1347
def test_time_creates_benchmark_in_result(self):
1348
"""Test that the TestCase.time() method accumulates a benchmark time."""
1349
sample_test = TestTestCase("method_that_times_a_bit_twice")
1350
output_stream = StringIO()
1351
result = bzrlib.tests.VerboseTestResult(
1352
unittest._WritelnDecorator(output_stream),
1355
num_tests=sample_test.countTestCases())
1356
sample_test.run(result)
1357
self.assertContainsRe(
1358
output_stream.getvalue(),
1359
r"\d+ms/ +\d+ms\n$")
1361
def test_hooks_sanitised(self):
1362
"""The bzrlib hooks should be sanitised by setUp."""
1363
self.assertEqual(bzrlib.branch.BranchHooks(),
1364
bzrlib.branch.Branch.hooks)
1365
self.assertEqual(bzrlib.smart.server.SmartServerHooks(),
1366
bzrlib.smart.server.SmartTCPServer.hooks)
1368
def test__gather_lsprof_in_benchmarks(self):
1369
"""When _gather_lsprof_in_benchmarks is on, accumulate profile data.
1371
Each self.time() call is individually and separately profiled.
1373
self.requireFeature(test_lsprof.LSProfFeature)
1374
# overrides the class member with an instance member so no cleanup
1376
self._gather_lsprof_in_benchmarks = True
1377
self.time(time.sleep, 0.000)
1378
self.time(time.sleep, 0.003)
1379
self.assertEqual(2, len(self._benchcalls))
1380
self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
1381
self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
1382
self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
1383
self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
1385
def test_knownFailure(self):
1386
"""Self.knownFailure() should raise a KnownFailure exception."""
1387
self.assertRaises(KnownFailure, self.knownFailure, "A Failure")
1389
def test_requireFeature_available(self):
1390
"""self.requireFeature(available) is a no-op."""
1391
class Available(Feature):
1392
def _probe(self):return True
1393
feature = Available()
1394
self.requireFeature(feature)
1396
def test_requireFeature_unavailable(self):
1397
"""self.requireFeature(unavailable) raises UnavailableFeature."""
1398
class Unavailable(Feature):
1399
def _probe(self):return False
1400
feature = Unavailable()
1401
self.assertRaises(UnavailableFeature, self.requireFeature, feature)
1403
def test_run_no_parameters(self):
1404
test = SampleTestCase('_test_pass')
1407
def test_run_enabled_unittest_result(self):
1408
"""Test we revert to regular behaviour when the test is enabled."""
1409
test = SampleTestCase('_test_pass')
1410
class EnabledFeature(object):
1411
def available(self):
1413
test._test_needs_features = [EnabledFeature()]
1414
result = unittest.TestResult()
1416
self.assertEqual(1, result.testsRun)
1417
self.assertEqual([], result.errors)
1418
self.assertEqual([], result.failures)
1420
def test_run_disabled_unittest_result(self):
1421
"""Test our compatability for disabled tests with unittest results."""
1422
test = SampleTestCase('_test_pass')
1423
class DisabledFeature(object):
1424
def available(self):
1426
test._test_needs_features = [DisabledFeature()]
1427
result = unittest.TestResult()
1429
self.assertEqual(1, result.testsRun)
1430
self.assertEqual([], result.errors)
1431
self.assertEqual([], result.failures)
1433
def test_run_disabled_supporting_result(self):
1434
"""Test disabled tests behaviour with support aware results."""
1435
test = SampleTestCase('_test_pass')
1436
class DisabledFeature(object):
1437
def available(self):
1439
the_feature = DisabledFeature()
1440
test._test_needs_features = [the_feature]
1441
class InstrumentedTestResult(unittest.TestResult):
1443
unittest.TestResult.__init__(self)
1445
def startTest(self, test):
1446
self.calls.append(('startTest', test))
1447
def stopTest(self, test):
1448
self.calls.append(('stopTest', test))
1449
def addNotSupported(self, test, feature):
1450
self.calls.append(('addNotSupported', test, feature))
1451
result = InstrumentedTestResult()
1454
('startTest', test),
1455
('addNotSupported', test, the_feature),
1461
@symbol_versioning.deprecated_function(zero_eleven)
1462
def sample_deprecated_function():
1463
"""A deprecated function to test applyDeprecated with."""
1467
def sample_undeprecated_function(a_param):
1468
"""A undeprecated function to test applyDeprecated with."""
1471
class ApplyDeprecatedHelper(object):
1472
"""A helper class for ApplyDeprecated tests."""
1474
@symbol_versioning.deprecated_method(zero_eleven)
1475
def sample_deprecated_method(self, param_one):
1476
"""A deprecated method for testing with."""
1479
def sample_normal_method(self):
1480
"""A undeprecated method."""
1482
@symbol_versioning.deprecated_method(zero_ten)
1483
def sample_nested_deprecation(self):
1484
return sample_deprecated_function()
1487
class TestExtraAssertions(TestCase):
1488
"""Tests for new test assertions in bzrlib test suite"""
1490
def test_assert_isinstance(self):
1491
self.assertIsInstance(2, int)
1492
self.assertIsInstance(u'', basestring)
1493
self.assertRaises(AssertionError, self.assertIsInstance, None, int)
1494
self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
1496
def test_assertEndsWith(self):
1497
self.assertEndsWith('foo', 'oo')
1498
self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
1500
def test_applyDeprecated_not_deprecated(self):
1501
sample_object = ApplyDeprecatedHelper()
1502
# calling an undeprecated callable raises an assertion
1503
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
1504
sample_object.sample_normal_method)
1505
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
1506
sample_undeprecated_function, "a param value")
1507
# calling a deprecated callable (function or method) with the wrong
1508
# expected deprecation fails.
1509
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
1510
sample_object.sample_deprecated_method, "a param value")
1511
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
1512
sample_deprecated_function)
1513
# calling a deprecated callable (function or method) with the right
1514
# expected deprecation returns the functions result.
1515
self.assertEqual("a param value", self.applyDeprecated(zero_eleven,
1516
sample_object.sample_deprecated_method, "a param value"))
1517
self.assertEqual(2, self.applyDeprecated(zero_eleven,
1518
sample_deprecated_function))
1519
# calling a nested deprecation with the wrong deprecation version
1520
# fails even if a deeper nested function was deprecated with the
1522
self.assertRaises(AssertionError, self.applyDeprecated,
1523
zero_eleven, sample_object.sample_nested_deprecation)
1524
# calling a nested deprecation with the right deprecation value
1525
# returns the calls result.
1526
self.assertEqual(2, self.applyDeprecated(zero_ten,
1527
sample_object.sample_nested_deprecation))
1529
def test_callDeprecated(self):
1530
def testfunc(be_deprecated, result=None):
1531
if be_deprecated is True:
1532
symbol_versioning.warn('i am deprecated', DeprecationWarning,
1535
result = self.callDeprecated(['i am deprecated'], testfunc, True)
1536
self.assertIs(None, result)
1537
result = self.callDeprecated([], testfunc, False, 'result')
1538
self.assertEqual('result', result)
1539
self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
1540
self.callDeprecated([], testfunc, be_deprecated=False)
1543
class TestWarningTests(TestCase):
1544
"""Tests for calling methods that raise warnings."""
1546
def test_callCatchWarnings(self):
1548
warnings.warn("this is your last warning")
1550
wlist, result = self.callCatchWarnings(meth, 1, 2)
1551
self.assertEquals(3, result)
1552
# would like just to compare them, but UserWarning doesn't implement
1555
self.assertIsInstance(w0, UserWarning)
1556
self.assertEquals("this is your last warning", str(w0))
1559
class TestConvenienceMakers(TestCaseWithTransport):
1560
"""Test for the make_* convenience functions."""
1562
def test_make_branch_and_tree_with_format(self):
1563
# we should be able to supply a format to make_branch_and_tree
1564
self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
1565
self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
1566
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
1567
bzrlib.bzrdir.BzrDirMetaFormat1)
1568
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
1569
bzrlib.bzrdir.BzrDirFormat6)
1571
def test_make_branch_and_memory_tree(self):
1572
# we should be able to get a new branch and a mutable tree from
1573
# TestCaseWithTransport
1574
tree = self.make_branch_and_memory_tree('a')
1575
self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
1578
class TestSFTPMakeBranchAndTree(TestCaseWithSFTPServer):
1580
def test_make_tree_for_sftp_branch(self):
1581
"""Transports backed by local directories create local trees."""
1583
tree = self.make_branch_and_tree('t1')
1584
base = tree.bzrdir.root_transport.base
1585
self.failIf(base.startswith('sftp'),
1586
'base %r is on sftp but should be local' % base)
1587
self.assertEquals(tree.bzrdir.root_transport,
1588
tree.branch.bzrdir.root_transport)
1589
self.assertEquals(tree.bzrdir.root_transport,
1590
tree.branch.repository.bzrdir.root_transport)
1593
class TestSelftest(TestCase):
1594
"""Tests of bzrlib.tests.selftest."""
1596
def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
1599
factory_called.append(True)
1603
self.apply_redirected(out, err, None, bzrlib.tests.selftest,
1604
test_suite_factory=factory)
1605
self.assertEqual([True], factory_called)
1608
class TestKnownFailure(TestCase):
1610
def test_known_failure(self):
1611
"""Check that KnownFailure is defined appropriately."""
1612
# a KnownFailure is an assertion error for compatability with unaware
1614
self.assertIsInstance(KnownFailure(""), AssertionError)
1616
def test_expect_failure(self):
1618
self.expectFailure("Doomed to failure", self.assertTrue, False)
1619
except KnownFailure, e:
1620
self.assertEqual('Doomed to failure', e.args[0])
1622
self.expectFailure("Doomed to failure", self.assertTrue, True)
1623
except AssertionError, e:
1624
self.assertEqual('Unexpected success. Should have failed:'
1625
' Doomed to failure', e.args[0])
1627
self.fail('Assertion not raised')
1630
class TestFeature(TestCase):
1632
def test_caching(self):
1633
"""Feature._probe is called by the feature at most once."""
1634
class InstrumentedFeature(Feature):
1636
Feature.__init__(self)
1639
self.calls.append('_probe')
1641
feature = InstrumentedFeature()
1643
self.assertEqual(['_probe'], feature.calls)
1645
self.assertEqual(['_probe'], feature.calls)
1647
def test_named_str(self):
1648
"""Feature.__str__ should thunk to feature_name()."""
1649
class NamedFeature(Feature):
1650
def feature_name(self):
1652
feature = NamedFeature()
1653
self.assertEqual('symlinks', str(feature))
1655
def test_default_str(self):
1656
"""Feature.__str__ should default to __class__.__name__."""
1657
class NamedFeature(Feature):
1659
feature = NamedFeature()
1660
self.assertEqual('NamedFeature', str(feature))
1663
class TestUnavailableFeature(TestCase):
1665
def test_access_feature(self):
1667
exception = UnavailableFeature(feature)
1668
self.assertIs(feature, exception.args[0])
1671
class TestSelftestFiltering(TestCase):
1674
self.suite = TestUtil.TestSuite()
1675
self.loader = TestUtil.TestLoader()
1676
self.suite.addTest(self.loader.loadTestsFromModuleNames([
1677
'bzrlib.tests.test_selftest']))
1678
self.all_names = _test_ids(self.suite)
1680
def test_condition_id_re(self):
1681
test_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
1682
'test_condition_id_re')
1683
filtered_suite = filter_suite_by_condition(self.suite,
1684
condition_id_re('test_condition_id_re'))
1685
self.assertEqual([test_name], _test_ids(filtered_suite))
1687
def test_condition_id_in_list(self):
1688
test_names = ['bzrlib.tests.test_selftest.TestSelftestFiltering.'
1689
'test_condition_id_in_list']
1690
id_list = tests.TestIdList(test_names)
1691
filtered_suite = filter_suite_by_condition(
1692
self.suite, tests.condition_id_in_list(id_list))
1693
my_pattern = 'TestSelftestFiltering.*test_condition_id_in_list'
1694
re_filtered = filter_suite_by_re(self.suite, my_pattern)
1695
self.assertEqual(_test_ids(re_filtered), _test_ids(filtered_suite))
1697
def test_condition_isinstance(self):
1698
filtered_suite = filter_suite_by_condition(self.suite,
1699
condition_isinstance(self.__class__))
1700
class_pattern = 'bzrlib.tests.test_selftest.TestSelftestFiltering.'
1701
re_filtered = filter_suite_by_re(self.suite, class_pattern)
1702
self.assertEqual(_test_ids(re_filtered), _test_ids(filtered_suite))
1704
def test_exclude_tests_by_condition(self):
1705
excluded_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
1706
'test_exclude_tests_by_condition')
1707
filtered_suite = exclude_tests_by_condition(self.suite,
1708
lambda x:x.id() == excluded_name)
1709
self.assertEqual(len(self.all_names) - 1,
1710
filtered_suite.countTestCases())
1711
self.assertFalse(excluded_name in _test_ids(filtered_suite))
1712
remaining_names = list(self.all_names)
1713
remaining_names.remove(excluded_name)
1714
self.assertEqual(remaining_names, _test_ids(filtered_suite))
1716
def test_exclude_tests_by_re(self):
1717
self.all_names = _test_ids(self.suite)
1718
filtered_suite = exclude_tests_by_re(self.suite, 'exclude_tests_by_re')
1719
excluded_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
1720
'test_exclude_tests_by_re')
1721
self.assertEqual(len(self.all_names) - 1,
1722
filtered_suite.countTestCases())
1723
self.assertFalse(excluded_name in _test_ids(filtered_suite))
1724
remaining_names = list(self.all_names)
1725
remaining_names.remove(excluded_name)
1726
self.assertEqual(remaining_names, _test_ids(filtered_suite))
1728
def test_filter_suite_by_condition(self):
1729
test_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
1730
'test_filter_suite_by_condition')
1731
filtered_suite = filter_suite_by_condition(self.suite,
1732
lambda x:x.id() == test_name)
1733
self.assertEqual([test_name], _test_ids(filtered_suite))
1735
def test_filter_suite_by_re(self):
1736
filtered_suite = filter_suite_by_re(self.suite, 'test_filter_suite_by_r')
1737
filtered_names = _test_ids(filtered_suite)
1738
self.assertEqual(filtered_names, ['bzrlib.tests.test_selftest.'
1739
'TestSelftestFiltering.test_filter_suite_by_re'])
1741
def test_filter_suite_by_id_list(self):
1742
test_list = ['bzrlib.tests.test_selftest.'
1743
'TestSelftestFiltering.test_filter_suite_by_id_list']
1744
filtered_suite = tests.filter_suite_by_id_list(
1745
self.suite, tests.TestIdList(test_list))
1746
filtered_names = _test_ids(filtered_suite)
1749
['bzrlib.tests.test_selftest.'
1750
'TestSelftestFiltering.test_filter_suite_by_id_list'])
1752
def test_preserve_input(self):
1753
# NB: Surely this is something in the stdlib to do this?
1754
self.assertTrue(self.suite is preserve_input(self.suite))
1755
self.assertTrue("@#$" is preserve_input("@#$"))
1757
def test_randomize_suite(self):
1758
randomized_suite = randomize_suite(self.suite)
1759
# randomizing should not add or remove test names.
1760
self.assertEqual(set(_test_ids(self.suite)),
1761
set(_test_ids(randomized_suite)))
1762
# Technically, this *can* fail, because random.shuffle(list) can be
1763
# equal to list. Trying multiple times just pushes the frequency back.
1764
# As its len(self.all_names)!:1, the failure frequency should be low
1765
# enough to ignore. RBC 20071021.
1766
# It should change the order.
1767
self.assertNotEqual(self.all_names, _test_ids(randomized_suite))
1768
# But not the length. (Possibly redundant with the set test, but not
1770
self.assertEqual(len(self.all_names), len(_test_ids(randomized_suite)))
1772
def test_split_suit_by_condition(self):
1773
self.all_names = _test_ids(self.suite)
1774
condition = condition_id_re('test_filter_suite_by_r')
1775
split_suite = split_suite_by_condition(self.suite, condition)
1776
filtered_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
1777
'test_filter_suite_by_re')
1778
self.assertEqual([filtered_name], _test_ids(split_suite[0]))
1779
self.assertFalse(filtered_name in _test_ids(split_suite[1]))
1780
remaining_names = list(self.all_names)
1781
remaining_names.remove(filtered_name)
1782
self.assertEqual(remaining_names, _test_ids(split_suite[1]))
1784
def test_split_suit_by_re(self):
1785
self.all_names = _test_ids(self.suite)
1786
split_suite = split_suite_by_re(self.suite, 'test_filter_suite_by_r')
1787
filtered_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
1788
'test_filter_suite_by_re')
1789
self.assertEqual([filtered_name], _test_ids(split_suite[0]))
1790
self.assertFalse(filtered_name in _test_ids(split_suite[1]))
1791
remaining_names = list(self.all_names)
1792
remaining_names.remove(filtered_name)
1793
self.assertEqual(remaining_names, _test_ids(split_suite[1]))
1796
class TestCheckInventoryShape(TestCaseWithTransport):
1798
def test_check_inventory_shape(self):
1799
files = ['a', 'b/', 'b/c']
1800
tree = self.make_branch_and_tree('.')
1801
self.build_tree(files)
1805
self.check_inventory_shape(tree.inventory, files)
1810
class TestBlackboxSupport(TestCase):
1811
"""Tests for testsuite blackbox features."""
1813
def test_run_bzr_failure_not_caught(self):
1814
# When we run bzr in blackbox mode, we want any unexpected errors to
1815
# propagate up to the test suite so that it can show the error in the
1816
# usual way, and we won't get a double traceback.
1817
e = self.assertRaises(
1819
self.run_bzr, ['assert-fail'])
1820
# make sure we got the real thing, not an error from somewhere else in
1821
# the test framework
1822
self.assertEquals('always fails', str(e))
1823
# check that there's no traceback in the test log
1824
self.assertNotContainsRe(self._get_log(keep_log_file=True),
1827
def test_run_bzr_user_error_caught(self):
1828
# Running bzr in blackbox mode, normal/expected/user errors should be
1829
# caught in the regular way and turned into an error message plus exit
1831
out, err = self.run_bzr(["log", "/nonexistantpath"], retcode=3)
1832
self.assertEqual(out, '')
1833
self.assertContainsRe(err,
1834
'bzr: ERROR: Not a branch: ".*nonexistantpath/".\n')
1837
class TestTestLoader(TestCase):
1838
"""Tests for the test loader."""
1840
def _get_loader_and_module(self):
1841
"""Gets a TestLoader and a module with one test in it."""
1842
loader = TestUtil.TestLoader()
1844
class Stub(TestCase):
1847
class MyModule(object):
1849
MyModule.a_class = Stub
1851
return loader, module
1853
def test_module_no_load_tests_attribute_loads_classes(self):
1854
loader, module = self._get_loader_and_module()
1855
self.assertEqual(1, loader.loadTestsFromModule(module).countTestCases())
1857
def test_module_load_tests_attribute_gets_called(self):
1858
loader, module = self._get_loader_and_module()
1859
# 'self' is here because we're faking the module with a class. Regular
1860
# load_tests do not need that :)
1861
def load_tests(self, standard_tests, module, loader):
1862
result = loader.suiteClass()
1863
for test in iter_suite_tests(standard_tests):
1864
result.addTests([test, test])
1866
# add a load_tests() method which multiplies the tests from the module.
1867
module.__class__.load_tests = load_tests
1868
self.assertEqual(2, loader.loadTestsFromModule(module).countTestCases())
1870
def test_load_tests_from_module_name_smoke_test(self):
1871
loader = TestUtil.TestLoader()
1872
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
1873
self.assertEquals(['bzrlib.tests.test_sampler.DemoTest.test_nothing'],
1876
def test_load_tests_from_module_name_with_bogus_module_name(self):
1877
loader = TestUtil.TestLoader()
1878
self.assertRaises(ImportError, loader.loadTestsFromModuleName, 'bogus')
1881
class TestTestIdList(tests.TestCase):
1883
def _create_id_list(self, test_list):
1884
return tests.TestIdList(test_list)
1886
def _create_suite(self, test_id_list):
1888
class Stub(TestCase):
1892
def _create_test_id(id):
1895
suite = TestUtil.TestSuite()
1896
for id in test_id_list:
1897
t = Stub('test_foo')
1898
t.id = _create_test_id(id)
1902
def _test_ids(self, test_suite):
1903
"""Get the ids for the tests in a test suite."""
1904
return [t.id() for t in iter_suite_tests(test_suite)]
1906
def test_empty_list(self):
1907
id_list = self._create_id_list([])
1908
self.assertEquals({}, id_list.tests)
1909
self.assertEquals({}, id_list.modules)
1911
def test_valid_list(self):
1912
id_list = self._create_id_list(
1913
['mod1.cl1.meth1', 'mod1.cl1.meth2',
1914
'mod1.func1', 'mod1.cl2.meth2',
1916
'mod1.submod2.cl1.meth1', 'mod1.submod2.cl2.meth2',
1918
self.assertTrue(id_list.refers_to('mod1'))
1919
self.assertTrue(id_list.refers_to('mod1.submod1'))
1920
self.assertTrue(id_list.refers_to('mod1.submod2'))
1921
self.assertTrue(id_list.includes('mod1.cl1.meth1'))
1922
self.assertTrue(id_list.includes('mod1.submod1'))
1923
self.assertTrue(id_list.includes('mod1.func1'))
1925
def test_bad_chars_in_params(self):
1926
id_list = self._create_id_list(['mod1.cl1.meth1(xx.yy)'])
1927
self.assertTrue(id_list.refers_to('mod1'))
1928
self.assertTrue(id_list.includes('mod1.cl1.meth1(xx.yy)'))
1930
def test_module_used(self):
1931
id_list = self._create_id_list(['mod.class.meth'])
1932
self.assertTrue(id_list.refers_to('mod'))
1933
self.assertTrue(id_list.refers_to('mod.class'))
1934
self.assertTrue(id_list.refers_to('mod.class.meth'))
1936
def test_test_suite(self):
1937
# This test is slow, so we do a single test with one test in each
1941
'bzrlib.tests.blackbox.test_branch.TestBranch.test_branch',
1942
'bzrlib.tests.test_selftest.TestTestIdList.test_test_suite',
1943
# transport implementations
1944
'bzrlib.tests.test_transport_implementations.TransportTests'
1945
'.test_abspath(LocalURLServer)',
1946
# modules_to_doctest
1947
'bzrlib.timestamp.format_highres_date',
1948
# plugins can't be tested that way since selftest may be run with
1951
suite = tests.test_suite(test_list)
1952
self.assertEquals(test_list, _test_ids(suite))
1954
def test_test_suite_matches_id_list_with_unknown(self):
1955
loader = TestUtil.TestLoader()
1956
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
1957
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing',
1959
not_found, duplicates = tests.suite_matches_id_list(suite, test_list)
1960
self.assertEquals(['bogus'], not_found)
1961
self.assertEquals([], duplicates)
1963
def test_suite_matches_id_list_with_duplicates(self):
1964
loader = TestUtil.TestLoader()
1965
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
1966
dupes = loader.suiteClass()
1967
for test in iter_suite_tests(suite):
1969
dupes.addTest(test) # Add it again
1971
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing',]
1972
not_found, duplicates = tests.suite_matches_id_list(
1974
self.assertEquals([], not_found)
1975
self.assertEquals(['bzrlib.tests.test_sampler.DemoTest.test_nothing'],
1979
class TestLoadTestIdList(tests.TestCaseInTempDir):
1981
def _create_test_list_file(self, file_name, content):
1982
fl = open(file_name, 'wt')
1986
def test_load_unknown(self):
1987
self.assertRaises(errors.NoSuchFile,
1988
tests.load_test_id_list, 'i_do_not_exist')
1990
def test_load_test_list(self):
1991
test_list_fname = 'test.list'
1992
self._create_test_list_file(test_list_fname,
1993
'mod1.cl1.meth1\nmod2.cl2.meth2\n')
1994
tlist = tests.load_test_id_list(test_list_fname)
1995
self.assertEquals(2, len(tlist))
1996
self.assertEquals('mod1.cl1.meth1', tlist[0])
1997
self.assertEquals('mod2.cl2.meth2', tlist[1])
1999
def test_load_dirty_file(self):
2000
test_list_fname = 'test.list'
2001
self._create_test_list_file(test_list_fname,
2002
' mod1.cl1.meth1\n\nmod2.cl2.meth2 \n'
2004
tlist = tests.load_test_id_list(test_list_fname)
2005
self.assertEquals(4, len(tlist))
2006
self.assertEquals('mod1.cl1.meth1', tlist[0])
2007
self.assertEquals('', tlist[1])
2008
self.assertEquals('mod2.cl2.meth2', tlist[2])
2009
self.assertEquals('bar baz', tlist[3])
2012
class TestFilteredByModuleTestLoader(tests.TestCase):
2014
def _create_loader(self, test_list):
2015
id_filter = tests.TestIdList(test_list)
2016
loader = TestUtil.FilteredByModuleTestLoader(id_filter.refers_to)
2019
def test_load_tests(self):
2020
test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
2021
loader = self._create_loader(test_list)
2023
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
2024
self.assertEquals(test_list, _test_ids(suite))
2026
def test_exclude_tests(self):
2027
test_list = ['bogus']
2028
loader = self._create_loader(test_list)
2030
suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
2031
self.assertEquals([], _test_ids(suite))