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 zero_ten, zero_eleven
39
from bzrlib.tests import (
43
TestCaseWithMemoryTransport,
44
TestCaseWithTransport,
49
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
50
from bzrlib.tests.TestUtil import _load_module_by_name
51
from bzrlib.trace import note
52
from bzrlib.transport.memory import MemoryServer, MemoryTransport
53
from bzrlib.version import _get_bzr_source_tree
56
class SelftestTests(TestCase):
58
def test_import_tests(self):
59
mod = _load_module_by_name('bzrlib.tests.test_selftest')
60
self.assertEqual(mod.SelftestTests, SelftestTests)
62
def test_import_test_failure(self):
63
self.assertRaises(ImportError,
67
class MetaTestLog(TestCase):
69
def test_logging(self):
70
"""Test logs are captured when a test fails."""
71
self.log('a test message')
72
self._log_file.flush()
73
self.assertContainsRe(self._get_log(keep_log_file=True),
77
class TestTreeShape(TestCaseInTempDir):
79
def test_unicode_paths(self):
80
filename = u'hell\u00d8'
82
self.build_tree_contents([(filename, 'contents of hello')])
83
except UnicodeEncodeError:
84
raise TestSkipped("can't build unicode working tree in "
85
"filesystem encoding %s" % sys.getfilesystemencoding())
86
self.failUnlessExists(filename)
89
class TestTransportProviderAdapter(TestCase):
90
"""A group of tests that test the transport implementation adaption core.
92
This is a meta test that the tests are applied to all available
95
This will be generalised in the future which is why it is in this
96
test file even though it is specific to transport tests at the moment.
99
def test_get_transport_permutations(self):
100
# this checks that we the module get_test_permutations call
101
# is made by the adapter get_transport_test_permitations method.
102
class MockModule(object):
103
def get_test_permutations(self):
104
return sample_permutation
105
sample_permutation = [(1,2), (3,4)]
106
from bzrlib.transport import TransportTestProviderAdapter
107
adapter = TransportTestProviderAdapter()
108
self.assertEqual(sample_permutation,
109
adapter.get_transport_test_permutations(MockModule()))
111
def test_adapter_checks_all_modules(self):
112
# this checks that the adapter returns as many permurtations as
113
# there are in all the registered# transport modules for there
114
# - we assume if this matches its probably doing the right thing
115
# especially in combination with the tests for setting the right
117
from bzrlib.transport import (TransportTestProviderAdapter,
118
_get_transport_modules
120
modules = _get_transport_modules()
121
permutation_count = 0
122
for module in modules:
124
permutation_count += len(reduce(getattr,
125
(module + ".get_test_permutations").split('.')[1:],
126
__import__(module))())
127
except errors.DependencyNotPresent:
129
input_test = TestTransportProviderAdapter(
130
"test_adapter_sets_transport_class")
131
adapter = TransportTestProviderAdapter()
132
self.assertEqual(permutation_count,
133
len(list(iter(adapter.adapt(input_test)))))
135
def test_adapter_sets_transport_class(self):
136
# Check that the test adapter inserts a transport and server into the
139
# This test used to know about all the possible transports and the
140
# order they were returned but that seems overly brittle (mbp
142
input_test = TestTransportProviderAdapter(
143
"test_adapter_sets_transport_class")
144
from bzrlib.transport import TransportTestProviderAdapter
145
suite = TransportTestProviderAdapter().adapt(input_test)
146
tests = list(iter(suite))
147
self.assertTrue(len(tests) > 6)
148
# there are at least that many builtin transports
150
self.assertTrue(issubclass(one_test.transport_class,
151
bzrlib.transport.Transport))
152
self.assertTrue(issubclass(one_test.transport_server,
153
bzrlib.transport.Server))
156
class TestBranchProviderAdapter(TestCase):
157
"""A group of tests that test the branch implementation test adapter."""
159
def test_adapted_tests(self):
160
# check that constructor parameters are passed through to the adapted
162
from bzrlib.branch import BranchTestProviderAdapter
163
input_test = TestBranchProviderAdapter(
164
"test_adapted_tests")
167
formats = [("c", "C"), ("d", "D")]
168
adapter = BranchTestProviderAdapter(server1, server2, formats)
169
suite = adapter.adapt(input_test)
170
tests = list(iter(suite))
171
self.assertEqual(2, len(tests))
172
self.assertEqual(tests[0].branch_format, formats[0][0])
173
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
174
self.assertEqual(tests[0].transport_server, server1)
175
self.assertEqual(tests[0].transport_readonly_server, server2)
176
self.assertEqual(tests[1].branch_format, formats[1][0])
177
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
178
self.assertEqual(tests[1].transport_server, server1)
179
self.assertEqual(tests[1].transport_readonly_server, server2)
182
class TestBzrDirProviderAdapter(TestCase):
183
"""A group of tests that test the bzr dir implementation test adapter."""
185
def test_adapted_tests(self):
186
# check that constructor parameters are passed through to the adapted
188
from bzrlib.bzrdir import BzrDirTestProviderAdapter
189
input_test = TestBzrDirProviderAdapter(
190
"test_adapted_tests")
195
adapter = BzrDirTestProviderAdapter(vfs_factory,
196
server1, server2, formats)
197
suite = adapter.adapt(input_test)
198
tests = list(iter(suite))
199
self.assertEqual(2, len(tests))
200
self.assertEqual(tests[0].bzrdir_format, formats[0])
201
self.assertEqual(tests[0].vfs_transport_factory, vfs_factory)
202
self.assertEqual(tests[0].transport_server, server1)
203
self.assertEqual(tests[0].transport_readonly_server, server2)
204
self.assertEqual(tests[1].bzrdir_format, formats[1])
205
self.assertEqual(tests[1].vfs_transport_factory, vfs_factory)
206
self.assertEqual(tests[1].transport_server, server1)
207
self.assertEqual(tests[1].transport_readonly_server, server2)
210
class TestRepositoryProviderAdapter(TestCase):
211
"""A group of tests that test the repository implementation test adapter."""
213
def test_adapted_tests(self):
214
# check that constructor parameters are passed through to the adapted
216
from bzrlib.repository import RepositoryTestProviderAdapter
217
input_test = TestRepositoryProviderAdapter(
218
"test_adapted_tests")
221
formats = [("c", "C"), ("d", "D")]
222
adapter = RepositoryTestProviderAdapter(server1, server2, formats)
223
suite = adapter.adapt(input_test)
224
tests = list(iter(suite))
225
self.assertEqual(2, len(tests))
226
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
227
self.assertEqual(tests[0].repository_format, formats[0][0])
228
self.assertEqual(tests[0].transport_server, server1)
229
self.assertEqual(tests[0].transport_readonly_server, server2)
230
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
231
self.assertEqual(tests[1].repository_format, formats[1][0])
232
self.assertEqual(tests[1].transport_server, server1)
233
self.assertEqual(tests[1].transport_readonly_server, server2)
235
def test_setting_vfs_transport(self):
236
"""The vfs_transport_factory can be set optionally."""
237
from bzrlib.repository import RepositoryTestProviderAdapter
238
input_test = TestRepositoryProviderAdapter(
239
"test_adapted_tests")
240
formats = [("c", "C")]
241
adapter = RepositoryTestProviderAdapter(None, None, formats,
242
vfs_transport_factory="vfs")
243
suite = adapter.adapt(input_test)
244
tests = list(iter(suite))
245
self.assertEqual(1, len(tests))
246
self.assertEqual(tests[0].vfs_transport_factory, "vfs")
249
class TestInterRepositoryProviderAdapter(TestCase):
250
"""A group of tests that test the InterRepository test adapter."""
252
def test_adapted_tests(self):
253
# check that constructor parameters are passed through to the adapted
255
from bzrlib.repository import InterRepositoryTestProviderAdapter
256
input_test = TestInterRepositoryProviderAdapter(
257
"test_adapted_tests")
260
formats = [(str, "C1", "C2"), (int, "D1", "D2")]
261
adapter = InterRepositoryTestProviderAdapter(server1, server2, formats)
262
suite = adapter.adapt(input_test)
263
tests = list(iter(suite))
264
self.assertEqual(2, len(tests))
265
self.assertEqual(tests[0].interrepo_class, formats[0][0])
266
self.assertEqual(tests[0].repository_format, formats[0][1])
267
self.assertEqual(tests[0].repository_format_to, formats[0][2])
268
self.assertEqual(tests[0].transport_server, server1)
269
self.assertEqual(tests[0].transport_readonly_server, server2)
270
self.assertEqual(tests[1].interrepo_class, formats[1][0])
271
self.assertEqual(tests[1].repository_format, formats[1][1])
272
self.assertEqual(tests[1].repository_format_to, formats[1][2])
273
self.assertEqual(tests[1].transport_server, server1)
274
self.assertEqual(tests[1].transport_readonly_server, server2)
277
class TestInterVersionedFileProviderAdapter(TestCase):
278
"""A group of tests that test the InterVersionedFile test adapter."""
280
def test_adapted_tests(self):
281
# check that constructor parameters are passed through to the adapted
283
from bzrlib.versionedfile import InterVersionedFileTestProviderAdapter
284
input_test = TestInterRepositoryProviderAdapter(
285
"test_adapted_tests")
288
formats = [(str, "C1", "C2"), (int, "D1", "D2")]
289
adapter = InterVersionedFileTestProviderAdapter(server1, server2, formats)
290
suite = adapter.adapt(input_test)
291
tests = list(iter(suite))
292
self.assertEqual(2, len(tests))
293
self.assertEqual(tests[0].interversionedfile_class, formats[0][0])
294
self.assertEqual(tests[0].versionedfile_factory, formats[0][1])
295
self.assertEqual(tests[0].versionedfile_factory_to, formats[0][2])
296
self.assertEqual(tests[0].transport_server, server1)
297
self.assertEqual(tests[0].transport_readonly_server, server2)
298
self.assertEqual(tests[1].interversionedfile_class, formats[1][0])
299
self.assertEqual(tests[1].versionedfile_factory, formats[1][1])
300
self.assertEqual(tests[1].versionedfile_factory_to, formats[1][2])
301
self.assertEqual(tests[1].transport_server, server1)
302
self.assertEqual(tests[1].transport_readonly_server, server2)
305
class TestRevisionStoreProviderAdapter(TestCase):
306
"""A group of tests that test the RevisionStore test adapter."""
308
def test_adapted_tests(self):
309
# check that constructor parameters are passed through to the adapted
311
from bzrlib.store.revision import RevisionStoreTestProviderAdapter
312
input_test = TestRevisionStoreProviderAdapter(
313
"test_adapted_tests")
314
# revision stores need a store factory - i.e. RevisionKnit
315
#, a readonly and rw transport
319
store_factories = ["c", "d"]
320
adapter = RevisionStoreTestProviderAdapter(server1, server2, store_factories)
321
suite = adapter.adapt(input_test)
322
tests = list(iter(suite))
323
self.assertEqual(2, len(tests))
324
self.assertEqual(tests[0].store_factory, store_factories[0][0])
325
self.assertEqual(tests[0].transport_server, server1)
326
self.assertEqual(tests[0].transport_readonly_server, server2)
327
self.assertEqual(tests[1].store_factory, store_factories[1][0])
328
self.assertEqual(tests[1].transport_server, server1)
329
self.assertEqual(tests[1].transport_readonly_server, server2)
332
class TestWorkingTreeProviderAdapter(TestCase):
333
"""A group of tests that test the workingtree implementation test adapter."""
335
def test_adapted_tests(self):
336
# check that constructor parameters are passed through to the adapted
338
from bzrlib.workingtree import WorkingTreeTestProviderAdapter
339
input_test = TestWorkingTreeProviderAdapter(
340
"test_adapted_tests")
343
formats = [("c", "C"), ("d", "D")]
344
adapter = WorkingTreeTestProviderAdapter(server1, server2, formats)
345
suite = adapter.adapt(input_test)
346
tests = list(iter(suite))
347
self.assertEqual(2, len(tests))
348
self.assertEqual(tests[0].workingtree_format, formats[0][0])
349
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
350
self.assertEqual(tests[0].transport_server, server1)
351
self.assertEqual(tests[0].transport_readonly_server, server2)
352
self.assertEqual(tests[1].workingtree_format, formats[1][0])
353
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
354
self.assertEqual(tests[1].transport_server, server1)
355
self.assertEqual(tests[1].transport_readonly_server, server2)
358
class TestTreeProviderAdapter(TestCase):
359
"""Test the setup of tree_implementation tests."""
361
def test_adapted_tests(self):
362
# the tree implementation adapter is meant to setup one instance for
363
# each working tree format, and one additional instance that will
364
# use the default wt format, but create a revision tree for the tests.
365
# this means that the wt ones should have the workingtree_to_test_tree
366
# attribute set to 'return_parameter' and the revision one set to
367
# revision_tree_from_workingtree.
369
from bzrlib.tests.tree_implementations import (
370
TreeTestProviderAdapter,
372
revision_tree_from_workingtree
374
from bzrlib.workingtree import WorkingTreeFormat, WorkingTreeFormat3
375
input_test = TestTreeProviderAdapter(
376
"test_adapted_tests")
379
formats = [("c", "C"), ("d", "D")]
380
adapter = TreeTestProviderAdapter(server1, server2, formats)
381
suite = adapter.adapt(input_test)
382
tests = list(iter(suite))
383
self.assertEqual(4, len(tests))
384
# this must match the default format setp up in
385
# TreeTestProviderAdapter.adapt
386
default_format = WorkingTreeFormat3
387
self.assertEqual(tests[0].workingtree_format, formats[0][0])
388
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
389
self.assertEqual(tests[0].transport_server, server1)
390
self.assertEqual(tests[0].transport_readonly_server, server2)
391
self.assertEqual(tests[0].workingtree_to_test_tree, return_parameter)
392
self.assertEqual(tests[1].workingtree_format, formats[1][0])
393
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
394
self.assertEqual(tests[1].transport_server, server1)
395
self.assertEqual(tests[1].transport_readonly_server, server2)
396
self.assertEqual(tests[1].workingtree_to_test_tree, return_parameter)
397
self.assertIsInstance(tests[2].workingtree_format, default_format)
398
#self.assertEqual(tests[2].bzrdir_format,
399
# default_format._matchingbzrdir)
400
self.assertEqual(tests[2].transport_server, server1)
401
self.assertEqual(tests[2].transport_readonly_server, server2)
402
self.assertEqual(tests[2].workingtree_to_test_tree,
403
revision_tree_from_workingtree)
406
class TestInterTreeProviderAdapter(TestCase):
407
"""A group of tests that test the InterTreeTestAdapter."""
409
def test_adapted_tests(self):
410
# check that constructor parameters are passed through to the adapted
412
# for InterTree tests we want the machinery to bring up two trees in
413
# each instance: the base one, and the one we are interacting with.
414
# because each optimiser can be direction specific, we need to test
415
# each optimiser in its chosen direction.
416
# unlike the TestProviderAdapter we dont want to automatically add a
417
# parameterised one for WorkingTree - the optimisers will tell us what
419
from bzrlib.tests.tree_implementations import (
421
revision_tree_from_workingtree
423
from bzrlib.tests.intertree_implementations import (
424
InterTreeTestProviderAdapter,
426
from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
427
input_test = TestInterTreeProviderAdapter(
428
"test_adapted_tests")
431
format1 = WorkingTreeFormat2()
432
format2 = WorkingTreeFormat3()
433
formats = [(str, format1, format2, "converter1"),
434
(int, format2, format1, "converter2")]
435
adapter = InterTreeTestProviderAdapter(server1, server2, formats)
436
suite = adapter.adapt(input_test)
437
tests = list(iter(suite))
438
self.assertEqual(2, len(tests))
439
self.assertEqual(tests[0].intertree_class, formats[0][0])
440
self.assertEqual(tests[0].workingtree_format, formats[0][1])
441
self.assertEqual(tests[0].workingtree_format_to, formats[0][2])
442
self.assertEqual(tests[0].mutable_trees_to_test_trees, formats[0][3])
443
self.assertEqual(tests[0].workingtree_to_test_tree, return_parameter)
444
self.assertEqual(tests[0].transport_server, server1)
445
self.assertEqual(tests[0].transport_readonly_server, server2)
446
self.assertEqual(tests[1].intertree_class, formats[1][0])
447
self.assertEqual(tests[1].workingtree_format, formats[1][1])
448
self.assertEqual(tests[1].workingtree_format_to, formats[1][2])
449
self.assertEqual(tests[1].mutable_trees_to_test_trees, formats[1][3])
450
self.assertEqual(tests[1].workingtree_to_test_tree, return_parameter)
451
self.assertEqual(tests[1].transport_server, server1)
452
self.assertEqual(tests[1].transport_readonly_server, server2)
455
class TestTestCaseInTempDir(TestCaseInTempDir):
457
def test_home_is_not_working(self):
458
self.assertNotEqual(self.test_dir, self.test_home_dir)
459
cwd = osutils.getcwd()
460
self.assertEqual(self.test_dir, cwd)
461
self.assertEqual(self.test_home_dir, os.environ['HOME'])
464
class TestTestCaseWithMemoryTransport(TestCaseWithMemoryTransport):
466
def test_home_is_non_existant_dir_under_root(self):
467
"""The test_home_dir for TestCaseWithMemoryTransport is missing.
469
This is because TestCaseWithMemoryTransport is for tests that do not
470
need any disk resources: they should be hooked into bzrlib in such a
471
way that no global settings are being changed by the test (only a
472
few tests should need to do that), and having a missing dir as home is
473
an effective way to ensure that this is the case.
475
self.assertEqual(self.TEST_ROOT + "/MemoryTransportMissingHomeDir",
477
self.assertEqual(self.test_home_dir, os.environ['HOME'])
479
def test_cwd_is_TEST_ROOT(self):
480
self.assertEqual(self.test_dir, self.TEST_ROOT)
481
cwd = osutils.getcwd()
482
self.assertEqual(self.test_dir, cwd)
484
def test_make_branch_and_memory_tree(self):
485
"""In TestCaseWithMemoryTransport we should not make the branch on disk.
487
This is hard to comprehensively robustly test, so we settle for making
488
a branch and checking no directory was created at its relpath.
490
tree = self.make_branch_and_memory_tree('dir')
491
# Guard against regression into MemoryTransport leaking
492
# files to disk instead of keeping them in memory.
493
self.failIf(osutils.lexists('dir'))
494
self.assertIsInstance(tree, memorytree.MemoryTree)
496
def test_make_branch_and_memory_tree_with_format(self):
497
"""make_branch_and_memory_tree should accept a format option."""
498
format = bzrdir.BzrDirMetaFormat1()
499
format.repository_format = weaverepo.RepositoryFormat7()
500
tree = self.make_branch_and_memory_tree('dir', format=format)
501
# Guard against regression into MemoryTransport leaking
502
# files to disk instead of keeping them in memory.
503
self.failIf(osutils.lexists('dir'))
504
self.assertIsInstance(tree, memorytree.MemoryTree)
505
self.assertEqual(format.repository_format.__class__,
506
tree.branch.repository._format.__class__)
509
class TestTestCaseWithTransport(TestCaseWithTransport):
510
"""Tests for the convenience functions TestCaseWithTransport introduces."""
512
def test_get_readonly_url_none(self):
513
from bzrlib.transport import get_transport
514
from bzrlib.transport.memory import MemoryServer
515
from bzrlib.transport.readonly import ReadonlyTransportDecorator
516
self.vfs_transport_factory = MemoryServer
517
self.transport_readonly_server = None
518
# calling get_readonly_transport() constructs a decorator on the url
520
url = self.get_readonly_url()
521
url2 = self.get_readonly_url('foo/bar')
522
t = get_transport(url)
523
t2 = get_transport(url2)
524
self.failUnless(isinstance(t, ReadonlyTransportDecorator))
525
self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
526
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
528
def test_get_readonly_url_http(self):
529
from bzrlib.tests.HttpServer import HttpServer
530
from bzrlib.transport import get_transport
531
from bzrlib.transport.local import LocalURLServer
532
from bzrlib.transport.http import HttpTransportBase
533
self.transport_server = LocalURLServer
534
self.transport_readonly_server = HttpServer
535
# calling get_readonly_transport() gives us a HTTP server instance.
536
url = self.get_readonly_url()
537
url2 = self.get_readonly_url('foo/bar')
538
# the transport returned may be any HttpTransportBase subclass
539
t = get_transport(url)
540
t2 = get_transport(url2)
541
self.failUnless(isinstance(t, HttpTransportBase))
542
self.failUnless(isinstance(t2, HttpTransportBase))
543
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
545
def test_is_directory(self):
546
"""Test assertIsDirectory assertion"""
547
t = self.get_transport()
548
self.build_tree(['a_dir/', 'a_file'], transport=t)
549
self.assertIsDirectory('a_dir', t)
550
self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
551
self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
554
class TestTestCaseTransports(TestCaseWithTransport):
557
super(TestTestCaseTransports, self).setUp()
558
self.vfs_transport_factory = MemoryServer
560
def test_make_bzrdir_preserves_transport(self):
561
t = self.get_transport()
562
result_bzrdir = self.make_bzrdir('subdir')
563
self.assertIsInstance(result_bzrdir.transport,
565
# should not be on disk, should only be in memory
566
self.failIfExists('subdir')
569
class TestChrootedTest(ChrootedTestCase):
571
def test_root_is_root(self):
572
from bzrlib.transport import get_transport
573
t = get_transport(self.get_readonly_url())
575
self.assertEqual(url, t.clone('..').base)
578
class MockProgress(_BaseProgressBar):
579
"""Progress-bar standin that records calls.
581
Useful for testing pb using code.
585
_BaseProgressBar.__init__(self)
589
self.calls.append(('tick',))
591
def update(self, msg=None, current=None, total=None):
592
self.calls.append(('update', msg, current, total))
595
self.calls.append(('clear',))
597
def note(self, msg, *args):
598
self.calls.append(('note', msg, args))
601
class TestTestResult(TestCase):
603
def test_elapsed_time_with_benchmarking(self):
604
result = bzrlib.tests.TextTestResult(self._log_file,
608
result._recordTestStartTime()
610
result.extractBenchmarkTime(self)
611
timed_string = result._testTimeString()
612
# without explicit benchmarking, we should get a simple time.
613
self.assertContainsRe(timed_string, "^ *[ 1-9][0-9]ms$")
614
# if a benchmark time is given, we want a x of y style result.
615
self.time(time.sleep, 0.001)
616
result.extractBenchmarkTime(self)
617
timed_string = result._testTimeString()
618
self.assertContainsRe(timed_string, "^ *[ 1-9][0-9]ms/ *[ 1-9][0-9]ms$")
619
# extracting the time from a non-bzrlib testcase sets to None
620
result._recordTestStartTime()
621
result.extractBenchmarkTime(
622
unittest.FunctionTestCase(self.test_elapsed_time_with_benchmarking))
623
timed_string = result._testTimeString()
624
self.assertContainsRe(timed_string, "^ *[ 1-9][0-9]ms$")
625
# cheat. Yes, wash thy mouth out with soap.
626
self._benchtime = None
628
def test_assigned_benchmark_file_stores_date(self):
630
result = bzrlib.tests.TextTestResult(self._log_file,
635
output_string = output.getvalue()
637
# if you are wondering about the regexp please read the comment in
638
# test_bench_history (bzrlib.tests.test_selftest.TestRunner)
639
# XXX: what comment? -- Andrew Bennetts
640
self.assertContainsRe(output_string, "--date [0-9.]+")
642
def test_benchhistory_records_test_times(self):
643
result_stream = StringIO()
644
result = bzrlib.tests.TextTestResult(
648
bench_history=result_stream
651
# we want profile a call and check that its test duration is recorded
652
# make a new test instance that when run will generate a benchmark
653
example_test_case = TestTestResult("_time_hello_world_encoding")
654
# execute the test, which should succeed and record times
655
example_test_case.run(result)
656
lines = result_stream.getvalue().splitlines()
657
self.assertEqual(2, len(lines))
658
self.assertContainsRe(lines[1],
659
" *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
660
"._time_hello_world_encoding")
662
def _time_hello_world_encoding(self):
663
"""Profile two sleep calls
665
This is used to exercise the test framework.
667
self.time(unicode, 'hello', errors='replace')
668
self.time(unicode, 'world', errors='replace')
670
def test_lsprofiling(self):
671
"""Verbose test result prints lsprof statistics from test cases."""
675
raise TestSkipped("lsprof not installed.")
676
result_stream = StringIO()
677
result = bzrlib.tests.VerboseTestResult(
678
unittest._WritelnDecorator(result_stream),
682
# we want profile a call of some sort and check it is output by
683
# addSuccess. We dont care about addError or addFailure as they
684
# are not that interesting for performance tuning.
685
# make a new test instance that when run will generate a profile
686
example_test_case = TestTestResult("_time_hello_world_encoding")
687
example_test_case._gather_lsprof_in_benchmarks = True
688
# execute the test, which should succeed and record profiles
689
example_test_case.run(result)
690
# lsprofile_something()
691
# if this worked we want
692
# LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
693
# CallCount Recursive Total(ms) Inline(ms) module:lineno(function)
694
# (the lsprof header)
695
# ... an arbitrary number of lines
696
# and the function call which is time.sleep.
697
# 1 0 ??? ??? ???(sleep)
698
# and then repeated but with 'world', rather than 'hello'.
699
# this should appear in the output stream of our test result.
700
output = result_stream.getvalue()
701
self.assertContainsRe(output,
702
r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
703
self.assertContainsRe(output,
704
r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
705
self.assertContainsRe(output,
706
r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
707
self.assertContainsRe(output,
708
r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
711
class TestRunner(TestCase):
713
def dummy_test(self):
716
def run_test_runner(self, testrunner, test):
717
"""Run suite in testrunner, saving global state and restoring it.
719
This current saves and restores:
720
TestCaseInTempDir.TEST_ROOT
722
There should be no tests in this file that use bzrlib.tests.TextTestRunner
723
without using this convenience method, because of our use of global state.
725
old_root = TestCaseInTempDir.TEST_ROOT
727
TestCaseInTempDir.TEST_ROOT = None
728
return testrunner.run(test)
730
TestCaseInTempDir.TEST_ROOT = old_root
732
def test_skipped_test(self):
733
# run a test that is skipped, and check the suite as a whole still
735
# skipping_test must be hidden in here so it's not run as a real test
737
raise TestSkipped('test intentionally skipped')
739
runner = TextTestRunner(stream=self._log_file, keep_output=True)
740
test = unittest.FunctionTestCase(skipping_test)
741
result = self.run_test_runner(runner, test)
742
self.assertTrue(result.wasSuccessful())
744
def test_skipped_from_setup(self):
745
class SkippedSetupTest(TestCase):
749
self.addCleanup(self.cleanup)
750
raise TestSkipped('skipped setup')
753
self.fail('test reached')
758
runner = TextTestRunner(stream=self._log_file, keep_output=True)
759
test = SkippedSetupTest('test_skip')
760
result = self.run_test_runner(runner, test)
761
self.assertTrue(result.wasSuccessful())
762
# Check if cleanup was called the right number of times.
763
self.assertEqual(0, test.counter)
765
def test_skipped_from_test(self):
766
class SkippedTest(TestCase):
770
self.addCleanup(self.cleanup)
773
raise TestSkipped('skipped test')
778
runner = TextTestRunner(stream=self._log_file, keep_output=True)
779
test = SkippedTest('test_skip')
780
result = self.run_test_runner(runner, test)
781
self.assertTrue(result.wasSuccessful())
782
# Check if cleanup was called the right number of times.
783
self.assertEqual(0, test.counter)
785
def test_bench_history(self):
786
# tests that the running the benchmark produces a history file
787
# containing a timestamp and the revision id of the bzrlib source which
789
workingtree = _get_bzr_source_tree()
790
test = TestRunner('dummy_test')
792
runner = TextTestRunner(stream=self._log_file, bench_history=output)
793
result = self.run_test_runner(runner, test)
794
output_string = output.getvalue()
795
self.assertContainsRe(output_string, "--date [0-9.]+")
796
if workingtree is not None:
797
revision_id = workingtree.get_parent_ids()[0]
798
self.assertEndsWith(output_string.rstrip(), revision_id)
800
def test_success_log_deleted(self):
801
"""Successful tests have their log deleted"""
803
class LogTester(TestCase):
805
def test_success(self):
806
self.log('this will be removed\n')
808
sio = cStringIO.StringIO()
809
runner = TextTestRunner(stream=sio)
810
test = LogTester('test_success')
811
result = self.run_test_runner(runner, test)
813
log = test._get_log()
814
self.assertEqual("DELETED log file to reduce memory footprint", log)
815
self.assertEqual('', test._log_contents)
816
self.assertIs(None, test._log_file_name)
818
def test_fail_log_kept(self):
819
"""Failed tests have their log kept"""
821
class LogTester(TestCase):
824
self.log('this will be kept\n')
825
self.fail('this test fails')
827
sio = cStringIO.StringIO()
828
runner = TextTestRunner(stream=sio)
829
test = LogTester('test_fail')
830
result = self.run_test_runner(runner, test)
832
text = sio.getvalue()
833
self.assertContainsRe(text, 'this will be kept')
834
self.assertContainsRe(text, 'this test fails')
836
log = test._get_log()
837
self.assertContainsRe(log, 'this will be kept')
838
self.assertEqual(log, test._log_contents)
840
def test_error_log_kept(self):
841
"""Tests with errors have their log kept"""
843
class LogTester(TestCase):
845
def test_error(self):
846
self.log('this will be kept\n')
847
raise ValueError('random exception raised')
849
sio = cStringIO.StringIO()
850
runner = TextTestRunner(stream=sio)
851
test = LogTester('test_error')
852
result = self.run_test_runner(runner, test)
854
text = sio.getvalue()
855
self.assertContainsRe(text, 'this will be kept')
856
self.assertContainsRe(text, 'random exception raised')
858
log = test._get_log()
859
self.assertContainsRe(log, 'this will be kept')
860
self.assertEqual(log, test._log_contents)
863
class TestTestCase(TestCase):
864
"""Tests that test the core bzrlib TestCase."""
866
def inner_test(self):
867
# the inner child test
870
def outer_child(self):
871
# the outer child test
873
self.inner_test = TestTestCase("inner_child")
874
result = bzrlib.tests.TextTestResult(self._log_file,
877
self.inner_test.run(result)
880
def test_trace_nesting(self):
881
# this tests that each test case nests its trace facility correctly.
882
# we do this by running a test case manually. That test case (A)
883
# should setup a new log, log content to it, setup a child case (B),
884
# which should log independently, then case (A) should log a trailer
886
# we do two nested children so that we can verify the state of the
887
# logs after the outer child finishes is correct, which a bad clean
888
# up routine in tearDown might trigger a fault in our test with only
889
# one child, we should instead see the bad result inside our test with
891
# the outer child test
892
original_trace = bzrlib.trace._trace_file
893
outer_test = TestTestCase("outer_child")
894
result = bzrlib.tests.TextTestResult(self._log_file,
897
outer_test.run(result)
898
self.assertEqual(original_trace, bzrlib.trace._trace_file)
900
def method_that_times_a_bit_twice(self):
901
# call self.time twice to ensure it aggregates
902
self.time(time.sleep, 0.007)
903
self.time(time.sleep, 0.007)
905
def test_time_creates_benchmark_in_result(self):
906
"""Test that the TestCase.time() method accumulates a benchmark time."""
907
sample_test = TestTestCase("method_that_times_a_bit_twice")
908
output_stream = StringIO()
909
result = bzrlib.tests.VerboseTestResult(
910
unittest._WritelnDecorator(output_stream),
913
num_tests=sample_test.countTestCases())
914
sample_test.run(result)
915
self.assertContainsRe(
916
output_stream.getvalue(),
919
def test_hooks_sanitised(self):
920
"""The bzrlib hooks should be sanitised by setUp."""
921
self.assertEqual(bzrlib.branch.BranchHooks(),
922
bzrlib.branch.Branch.hooks)
924
def test__gather_lsprof_in_benchmarks(self):
925
"""When _gather_lsprof_in_benchmarks is on, accumulate profile data.
927
Each self.time() call is individually and separately profiled.
932
raise TestSkipped("lsprof not installed.")
933
# overrides the class member with an instance member so no cleanup
935
self._gather_lsprof_in_benchmarks = True
936
self.time(time.sleep, 0.000)
937
self.time(time.sleep, 0.003)
938
self.assertEqual(2, len(self._benchcalls))
939
self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
940
self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
941
self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
942
self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
945
@symbol_versioning.deprecated_function(zero_eleven)
946
def sample_deprecated_function():
947
"""A deprecated function to test applyDeprecated with."""
951
def sample_undeprecated_function(a_param):
952
"""A undeprecated function to test applyDeprecated with."""
955
class ApplyDeprecatedHelper(object):
956
"""A helper class for ApplyDeprecated tests."""
958
@symbol_versioning.deprecated_method(zero_eleven)
959
def sample_deprecated_method(self, param_one):
960
"""A deprecated method for testing with."""
963
def sample_normal_method(self):
964
"""A undeprecated method."""
966
@symbol_versioning.deprecated_method(zero_ten)
967
def sample_nested_deprecation(self):
968
return sample_deprecated_function()
971
class TestExtraAssertions(TestCase):
972
"""Tests for new test assertions in bzrlib test suite"""
974
def test_assert_isinstance(self):
975
self.assertIsInstance(2, int)
976
self.assertIsInstance(u'', basestring)
977
self.assertRaises(AssertionError, self.assertIsInstance, None, int)
978
self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
980
def test_assertEndsWith(self):
981
self.assertEndsWith('foo', 'oo')
982
self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
984
def test_applyDeprecated_not_deprecated(self):
985
sample_object = ApplyDeprecatedHelper()
986
# calling an undeprecated callable raises an assertion
987
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
988
sample_object.sample_normal_method)
989
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
990
sample_undeprecated_function, "a param value")
991
# calling a deprecated callable (function or method) with the wrong
992
# expected deprecation fails.
993
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
994
sample_object.sample_deprecated_method, "a param value")
995
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
996
sample_deprecated_function)
997
# calling a deprecated callable (function or method) with the right
998
# expected deprecation returns the functions result.
999
self.assertEqual("a param value", self.applyDeprecated(zero_eleven,
1000
sample_object.sample_deprecated_method, "a param value"))
1001
self.assertEqual(2, self.applyDeprecated(zero_eleven,
1002
sample_deprecated_function))
1003
# calling a nested deprecation with the wrong deprecation version
1004
# fails even if a deeper nested function was deprecated with the
1006
self.assertRaises(AssertionError, self.applyDeprecated,
1007
zero_eleven, sample_object.sample_nested_deprecation)
1008
# calling a nested deprecation with the right deprecation value
1009
# returns the calls result.
1010
self.assertEqual(2, self.applyDeprecated(zero_ten,
1011
sample_object.sample_nested_deprecation))
1013
def test_callDeprecated(self):
1014
def testfunc(be_deprecated, result=None):
1015
if be_deprecated is True:
1016
symbol_versioning.warn('i am deprecated', DeprecationWarning,
1019
result = self.callDeprecated(['i am deprecated'], testfunc, True)
1020
self.assertIs(None, result)
1021
result = self.callDeprecated([], testfunc, False, 'result')
1022
self.assertEqual('result', result)
1023
self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
1024
self.callDeprecated([], testfunc, be_deprecated=False)
1027
class TestConvenienceMakers(TestCaseWithTransport):
1028
"""Test for the make_* convenience functions."""
1030
def test_make_branch_and_tree_with_format(self):
1031
# we should be able to supply a format to make_branch_and_tree
1032
self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
1033
self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
1034
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
1035
bzrlib.bzrdir.BzrDirMetaFormat1)
1036
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
1037
bzrlib.bzrdir.BzrDirFormat6)
1039
def test_make_branch_and_memory_tree(self):
1040
# we should be able to get a new branch and a mutable tree from
1041
# TestCaseWithTransport
1042
tree = self.make_branch_and_memory_tree('a')
1043
self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
1046
class TestSFTPMakeBranchAndTree(TestCaseWithSFTPServer):
1048
def test_make_tree_for_sftp_branch(self):
1049
"""Transports backed by local directories create local trees."""
1051
tree = self.make_branch_and_tree('t1')
1052
base = tree.bzrdir.root_transport.base
1053
self.failIf(base.startswith('sftp'),
1054
'base %r is on sftp but should be local' % base)
1055
self.assertEquals(tree.bzrdir.root_transport,
1056
tree.branch.bzrdir.root_transport)
1057
self.assertEquals(tree.bzrdir.root_transport,
1058
tree.branch.repository.bzrdir.root_transport)
1061
class TestSelftest(TestCase):
1062
"""Tests of bzrlib.tests.selftest."""
1064
def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
1067
factory_called.append(True)
1071
self.apply_redirected(out, err, None, bzrlib.tests.selftest,
1072
test_suite_factory=factory)
1073
self.assertEqual([True], factory_called)
1076
class TestSelftestCleanOutput(TestCaseInTempDir):
1078
def test_clean_output(self):
1079
# test functionality of clean_selftest_output()
1080
from bzrlib.tests import clean_selftest_output
1082
dirs = ('test0000.tmp', 'test0001.tmp', 'bzrlib', 'tests')
1083
files = ('bzr', 'setup.py', 'test9999.tmp')
1088
f.write('content of ')
1093
before = os.listdir(root)
1095
self.assertEquals(['bzr','bzrlib','setup.py',
1096
'test0000.tmp','test0001.tmp',
1097
'test9999.tmp','tests'],
1099
clean_selftest_output(root, quiet=True)
1100
after = os.listdir(root)
1102
self.assertEquals(['bzr','bzrlib','setup.py',
1103
'test9999.tmp','tests'],