1
# Copyright (C) 2005, 2006 by 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 version 2 as published by
5
# the Free Software Foundation.
7
# This program is distributed in the hope that it will be useful,
8
# but WITHOUT ANY WARRANTY; without even the implied warranty of
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
# GNU General Public License for more details.
12
# You should have received a copy of the GNU General Public License
13
# along with this program; if not, write to the Free Software
14
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
"""Tests for the test framework."""
20
from StringIO import StringIO
26
from bzrlib import osutils, memorytree
28
from bzrlib.progress import _BaseProgressBar
29
from bzrlib.tests import (
33
TestCaseWithMemoryTransport,
34
TestCaseWithTransport,
39
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
40
from bzrlib.tests.TestUtil import _load_module_by_name
41
import bzrlib.errors as errors
42
from bzrlib import symbol_versioning
43
from bzrlib.symbol_versioning import zero_ten, zero_eleven
44
from bzrlib.trace import note
45
from bzrlib.transport.memory import MemoryServer, MemoryTransport
46
from bzrlib.version import _get_bzr_source_tree
49
class SelftestTests(TestCase):
51
def test_import_tests(self):
52
mod = _load_module_by_name('bzrlib.tests.test_selftest')
53
self.assertEqual(mod.SelftestTests, SelftestTests)
55
def test_import_test_failure(self):
56
self.assertRaises(ImportError,
61
class MetaTestLog(TestCase):
63
def test_logging(self):
64
"""Test logs are captured when a test fails."""
65
self.log('a test message')
66
self._log_file.flush()
67
self.assertContainsRe(self._get_log(keep_log_file=True),
71
class TestTreeShape(TestCaseInTempDir):
73
def test_unicode_paths(self):
74
filename = u'hell\u00d8'
76
self.build_tree_contents([(filename, 'contents of hello')])
77
except UnicodeEncodeError:
78
raise TestSkipped("can't build unicode working tree in "
79
"filesystem encoding %s" % sys.getfilesystemencoding())
80
self.failUnlessExists(filename)
83
class TestTransportProviderAdapter(TestCase):
84
"""A group of tests that test the transport implementation adaption core.
86
This is a meta test that the tests are applied to all available
89
This will be generalised in the future which is why it is in this
90
test file even though it is specific to transport tests at the moment.
93
def test_get_transport_permutations(self):
94
# this checks that we the module get_test_permutations call
95
# is made by the adapter get_transport_test_permitations method.
96
class MockModule(object):
97
def get_test_permutations(self):
98
return sample_permutation
99
sample_permutation = [(1,2), (3,4)]
100
from bzrlib.transport import TransportTestProviderAdapter
101
adapter = TransportTestProviderAdapter()
102
self.assertEqual(sample_permutation,
103
adapter.get_transport_test_permutations(MockModule()))
105
def test_adapter_checks_all_modules(self):
106
# this checks that the adapter returns as many permurtations as
107
# there are in all the registered# transport modules for there
108
# - we assume if this matches its probably doing the right thing
109
# especially in combination with the tests for setting the right
111
from bzrlib.transport import (TransportTestProviderAdapter,
112
_get_transport_modules
114
modules = _get_transport_modules()
115
permutation_count = 0
116
for module in modules:
118
permutation_count += len(reduce(getattr,
119
(module + ".get_test_permutations").split('.')[1:],
120
__import__(module))())
121
except errors.DependencyNotPresent:
123
input_test = TestTransportProviderAdapter(
124
"test_adapter_sets_transport_class")
125
adapter = TransportTestProviderAdapter()
126
self.assertEqual(permutation_count,
127
len(list(iter(adapter.adapt(input_test)))))
129
def test_adapter_sets_transport_class(self):
130
# Check that the test adapter inserts a transport and server into the
133
# This test used to know about all the possible transports and the
134
# order they were returned but that seems overly brittle (mbp
136
input_test = TestTransportProviderAdapter(
137
"test_adapter_sets_transport_class")
138
from bzrlib.transport import TransportTestProviderAdapter
139
suite = TransportTestProviderAdapter().adapt(input_test)
140
tests = list(iter(suite))
141
self.assertTrue(len(tests) > 6)
142
# there are at least that many builtin transports
144
self.assertTrue(issubclass(one_test.transport_class,
145
bzrlib.transport.Transport))
146
self.assertTrue(issubclass(one_test.transport_server,
147
bzrlib.transport.Server))
150
class TestBranchProviderAdapter(TestCase):
151
"""A group of tests that test the branch implementation test adapter."""
153
def test_adapted_tests(self):
154
# check that constructor parameters are passed through to the adapted
156
from bzrlib.branch import BranchTestProviderAdapter
157
input_test = TestBranchProviderAdapter(
158
"test_adapted_tests")
161
formats = [("c", "C"), ("d", "D")]
162
adapter = BranchTestProviderAdapter(server1, server2, formats)
163
suite = adapter.adapt(input_test)
164
tests = list(iter(suite))
165
self.assertEqual(2, len(tests))
166
self.assertEqual(tests[0].branch_format, formats[0][0])
167
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
168
self.assertEqual(tests[0].transport_server, server1)
169
self.assertEqual(tests[0].transport_readonly_server, server2)
170
self.assertEqual(tests[1].branch_format, formats[1][0])
171
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
172
self.assertEqual(tests[1].transport_server, server1)
173
self.assertEqual(tests[1].transport_readonly_server, server2)
176
class TestBzrDirProviderAdapter(TestCase):
177
"""A group of tests that test the bzr dir implementation test adapter."""
179
def test_adapted_tests(self):
180
# check that constructor parameters are passed through to the adapted
182
from bzrlib.bzrdir import BzrDirTestProviderAdapter
183
input_test = TestBzrDirProviderAdapter(
184
"test_adapted_tests")
188
adapter = BzrDirTestProviderAdapter(server1, server2, formats)
189
suite = adapter.adapt(input_test)
190
tests = list(iter(suite))
191
self.assertEqual(2, len(tests))
192
self.assertEqual(tests[0].bzrdir_format, formats[0])
193
self.assertEqual(tests[0].transport_server, server1)
194
self.assertEqual(tests[0].transport_readonly_server, server2)
195
self.assertEqual(tests[1].bzrdir_format, formats[1])
196
self.assertEqual(tests[1].transport_server, server1)
197
self.assertEqual(tests[1].transport_readonly_server, server2)
200
class TestRepositoryProviderAdapter(TestCase):
201
"""A group of tests that test the repository implementation test adapter."""
203
def test_adapted_tests(self):
204
# check that constructor parameters are passed through to the adapted
206
from bzrlib.repository import RepositoryTestProviderAdapter
207
input_test = TestRepositoryProviderAdapter(
208
"test_adapted_tests")
211
formats = [("c", "C"), ("d", "D")]
212
adapter = RepositoryTestProviderAdapter(server1, server2, formats)
213
suite = adapter.adapt(input_test)
214
tests = list(iter(suite))
215
self.assertEqual(2, len(tests))
216
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
217
self.assertEqual(tests[0].repository_format, formats[0][0])
218
self.assertEqual(tests[0].transport_server, server1)
219
self.assertEqual(tests[0].transport_readonly_server, server2)
220
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
221
self.assertEqual(tests[1].repository_format, formats[1][0])
222
self.assertEqual(tests[1].transport_server, server1)
223
self.assertEqual(tests[1].transport_readonly_server, server2)
226
class TestInterRepositoryProviderAdapter(TestCase):
227
"""A group of tests that test the InterRepository test adapter."""
229
def test_adapted_tests(self):
230
# check that constructor parameters are passed through to the adapted
232
from bzrlib.repository import InterRepositoryTestProviderAdapter
233
input_test = TestInterRepositoryProviderAdapter(
234
"test_adapted_tests")
237
formats = [(str, "C1", "C2"), (int, "D1", "D2")]
238
adapter = InterRepositoryTestProviderAdapter(server1, server2, formats)
239
suite = adapter.adapt(input_test)
240
tests = list(iter(suite))
241
self.assertEqual(2, len(tests))
242
self.assertEqual(tests[0].interrepo_class, formats[0][0])
243
self.assertEqual(tests[0].repository_format, formats[0][1])
244
self.assertEqual(tests[0].repository_format_to, formats[0][2])
245
self.assertEqual(tests[0].transport_server, server1)
246
self.assertEqual(tests[0].transport_readonly_server, server2)
247
self.assertEqual(tests[1].interrepo_class, formats[1][0])
248
self.assertEqual(tests[1].repository_format, formats[1][1])
249
self.assertEqual(tests[1].repository_format_to, formats[1][2])
250
self.assertEqual(tests[1].transport_server, server1)
251
self.assertEqual(tests[1].transport_readonly_server, server2)
254
class TestInterVersionedFileProviderAdapter(TestCase):
255
"""A group of tests that test the InterVersionedFile test adapter."""
257
def test_adapted_tests(self):
258
# check that constructor parameters are passed through to the adapted
260
from bzrlib.versionedfile import InterVersionedFileTestProviderAdapter
261
input_test = TestInterRepositoryProviderAdapter(
262
"test_adapted_tests")
265
formats = [(str, "C1", "C2"), (int, "D1", "D2")]
266
adapter = InterVersionedFileTestProviderAdapter(server1, server2, formats)
267
suite = adapter.adapt(input_test)
268
tests = list(iter(suite))
269
self.assertEqual(2, len(tests))
270
self.assertEqual(tests[0].interversionedfile_class, formats[0][0])
271
self.assertEqual(tests[0].versionedfile_factory, formats[0][1])
272
self.assertEqual(tests[0].versionedfile_factory_to, formats[0][2])
273
self.assertEqual(tests[0].transport_server, server1)
274
self.assertEqual(tests[0].transport_readonly_server, server2)
275
self.assertEqual(tests[1].interversionedfile_class, formats[1][0])
276
self.assertEqual(tests[1].versionedfile_factory, formats[1][1])
277
self.assertEqual(tests[1].versionedfile_factory_to, formats[1][2])
278
self.assertEqual(tests[1].transport_server, server1)
279
self.assertEqual(tests[1].transport_readonly_server, server2)
282
class TestRevisionStoreProviderAdapter(TestCase):
283
"""A group of tests that test the RevisionStore test adapter."""
285
def test_adapted_tests(self):
286
# check that constructor parameters are passed through to the adapted
288
from bzrlib.store.revision import RevisionStoreTestProviderAdapter
289
input_test = TestRevisionStoreProviderAdapter(
290
"test_adapted_tests")
291
# revision stores need a store factory - i.e. RevisionKnit
292
#, a readonly and rw transport
296
store_factories = ["c", "d"]
297
adapter = RevisionStoreTestProviderAdapter(server1, server2, store_factories)
298
suite = adapter.adapt(input_test)
299
tests = list(iter(suite))
300
self.assertEqual(2, len(tests))
301
self.assertEqual(tests[0].store_factory, store_factories[0][0])
302
self.assertEqual(tests[0].transport_server, server1)
303
self.assertEqual(tests[0].transport_readonly_server, server2)
304
self.assertEqual(tests[1].store_factory, store_factories[1][0])
305
self.assertEqual(tests[1].transport_server, server1)
306
self.assertEqual(tests[1].transport_readonly_server, server2)
309
class TestWorkingTreeProviderAdapter(TestCase):
310
"""A group of tests that test the workingtree implementation test adapter."""
312
def test_adapted_tests(self):
313
# check that constructor parameters are passed through to the adapted
315
from bzrlib.workingtree import WorkingTreeTestProviderAdapter
316
input_test = TestWorkingTreeProviderAdapter(
317
"test_adapted_tests")
320
formats = [("c", "C"), ("d", "D")]
321
adapter = WorkingTreeTestProviderAdapter(server1, server2, formats)
322
suite = adapter.adapt(input_test)
323
tests = list(iter(suite))
324
self.assertEqual(2, len(tests))
325
self.assertEqual(tests[0].workingtree_format, formats[0][0])
326
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
327
self.assertEqual(tests[0].transport_server, server1)
328
self.assertEqual(tests[0].transport_readonly_server, server2)
329
self.assertEqual(tests[1].workingtree_format, formats[1][0])
330
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
331
self.assertEqual(tests[1].transport_server, server1)
332
self.assertEqual(tests[1].transport_readonly_server, server2)
335
class TestTreeProviderAdapter(TestCase):
336
"""Test the setup of tree_implementation tests."""
338
def test_adapted_tests(self):
339
# the tree implementation adapter is meant to setup one instance for
340
# each working tree format, and one additional instance that will
341
# use the default wt format, but create a revision tree for the tests.
342
# this means that the wt ones should have the workingtree_to_test_tree
343
# attribute set to 'return_parameter' and the revision one set to
344
# revision_tree_from_workingtree.
346
from bzrlib.tests.tree_implementations import (
347
TreeTestProviderAdapter,
349
revision_tree_from_workingtree
351
from bzrlib.workingtree import WorkingTreeFormat
352
input_test = TestTreeProviderAdapter(
353
"test_adapted_tests")
356
formats = [("c", "C"), ("d", "D")]
357
adapter = TreeTestProviderAdapter(server1, server2, formats)
358
suite = adapter.adapt(input_test)
359
tests = list(iter(suite))
360
self.assertEqual(3, len(tests))
361
default_format = WorkingTreeFormat.get_default_format()
362
self.assertEqual(tests[0].workingtree_format, formats[0][0])
363
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
364
self.assertEqual(tests[0].transport_server, server1)
365
self.assertEqual(tests[0].transport_readonly_server, server2)
366
self.assertEqual(tests[0].workingtree_to_test_tree, return_parameter)
367
self.assertEqual(tests[1].workingtree_format, formats[1][0])
368
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
369
self.assertEqual(tests[1].transport_server, server1)
370
self.assertEqual(tests[1].transport_readonly_server, server2)
371
self.assertEqual(tests[1].workingtree_to_test_tree, return_parameter)
372
self.assertEqual(tests[2].workingtree_format, default_format)
373
self.assertEqual(tests[2].bzrdir_format, default_format._matchingbzrdir)
374
self.assertEqual(tests[2].transport_server, server1)
375
self.assertEqual(tests[2].transport_readonly_server, server2)
376
self.assertEqual(tests[2].workingtree_to_test_tree,
377
revision_tree_from_workingtree)
380
class TestInterTreeProviderAdapter(TestCase):
381
"""A group of tests that test the InterTreeTestAdapter."""
383
def test_adapted_tests(self):
384
# check that constructor parameters are passed through to the adapted
386
# for InterTree tests we want the machinery to bring up two trees in
387
# each instance: the base one, and the one we are interacting with.
388
# because each optimiser can be direction specific, we need to test
389
# each optimiser in its chosen direction.
390
# unlike the TestProviderAdapter we dont want to automatically add a
391
# parameterised one for WorkingTree - the optimisers will tell us what
393
from bzrlib.tests.tree_implementations import (
395
revision_tree_from_workingtree
397
from bzrlib.tests.intertree_implementations import (
398
InterTreeTestProviderAdapter,
400
from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
401
input_test = TestInterTreeProviderAdapter(
402
"test_adapted_tests")
405
format1 = WorkingTreeFormat2()
406
format2 = WorkingTreeFormat3()
407
formats = [(str, format1, format2, False, True),
408
(int, format2, format1, False, True)]
409
adapter = InterTreeTestProviderAdapter(server1, server2, formats)
410
suite = adapter.adapt(input_test)
411
tests = list(iter(suite))
412
self.assertEqual(2, len(tests))
413
self.assertEqual(tests[0].intertree_class, formats[0][0])
414
self.assertEqual(tests[0].workingtree_format, formats[0][1])
415
self.assertEqual(tests[0].workingtree_to_test_tree, formats[0][2])
416
self.assertEqual(tests[0].workingtree_format_to, formats[0][3])
417
self.assertEqual(tests[0].workingtree_to_test_tree_to, formats[0][4])
418
self.assertEqual(tests[0].transport_server, server1)
419
self.assertEqual(tests[0].transport_readonly_server, server2)
420
self.assertEqual(tests[1].intertree_class, formats[1][0])
421
self.assertEqual(tests[1].workingtree_format, formats[1][1])
422
self.assertEqual(tests[1].workingtree_to_test_tree, formats[1][2])
423
self.assertEqual(tests[1].workingtree_format_to, formats[1][3])
424
self.assertEqual(tests[1].workingtree_to_test_tree_to, formats[1][4])
425
self.assertEqual(tests[1].transport_server, server1)
426
self.assertEqual(tests[1].transport_readonly_server, server2)
429
class TestTestCaseInTempDir(TestCaseInTempDir):
431
def test_home_is_not_working(self):
432
self.assertNotEqual(self.test_dir, self.test_home_dir)
433
cwd = osutils.getcwd()
434
self.assertEqual(self.test_dir, cwd)
435
self.assertEqual(self.test_home_dir, os.environ['HOME'])
438
class TestTestCaseWithMemoryTransport(TestCaseWithMemoryTransport):
440
def test_home_is_non_existant_dir_under_root(self):
441
"""The test_home_dir for TestCaseWithMemoryTransport is missing.
443
This is because TestCaseWithMemoryTransport is for tests that do not
444
need any disk resources: they should be hooked into bzrlib in such a
445
way that no global settings are being changed by the test (only a
446
few tests should need to do that), and having a missing dir as home is
447
an effective way to ensure that this is the case.
449
self.assertEqual(self.TEST_ROOT + "/MemoryTransportMissingHomeDir",
451
self.assertEqual(self.test_home_dir, os.environ['HOME'])
453
def test_cwd_is_TEST_ROOT(self):
454
self.assertEqual(self.test_dir, self.TEST_ROOT)
455
cwd = osutils.getcwd()
456
self.assertEqual(self.test_dir, cwd)
458
def test_make_branch_and_memory_tree(self):
459
"""In TestCaseWithMemoryTransport we should not make the branch on disk.
461
This is hard to comprehensively robustly test, so we settle for making
462
a branch and checking no directory was created at its relpath.
464
tree = self.make_branch_and_memory_tree('dir')
465
self.failIfExists('dir')
466
self.assertIsInstance(tree, memorytree.MemoryTree)
469
class TestTestCaseWithTransport(TestCaseWithTransport):
470
"""Tests for the convenience functions TestCaseWithTransport introduces."""
472
def test_get_readonly_url_none(self):
473
from bzrlib.transport import get_transport
474
from bzrlib.transport.memory import MemoryServer
475
from bzrlib.transport.readonly import ReadonlyTransportDecorator
476
self.transport_server = MemoryServer
477
self.transport_readonly_server = None
478
# calling get_readonly_transport() constructs a decorator on the url
480
url = self.get_readonly_url()
481
url2 = self.get_readonly_url('foo/bar')
482
t = get_transport(url)
483
t2 = get_transport(url2)
484
self.failUnless(isinstance(t, ReadonlyTransportDecorator))
485
self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
486
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
488
def test_get_readonly_url_http(self):
489
from bzrlib.transport import get_transport
490
from bzrlib.transport.local import LocalRelpathServer
491
from bzrlib.transport.http import HttpServer, HttpTransportBase
492
self.transport_server = LocalRelpathServer
493
self.transport_readonly_server = HttpServer
494
# calling get_readonly_transport() gives us a HTTP server instance.
495
url = self.get_readonly_url()
496
url2 = self.get_readonly_url('foo/bar')
497
# the transport returned may be any HttpTransportBase subclass
498
t = get_transport(url)
499
t2 = get_transport(url2)
500
self.failUnless(isinstance(t, HttpTransportBase))
501
self.failUnless(isinstance(t2, HttpTransportBase))
502
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
504
def test_is_directory(self):
505
"""Test assertIsDirectory assertion"""
506
t = self.get_transport()
507
self.build_tree(['a_dir/', 'a_file'], transport=t)
508
self.assertIsDirectory('a_dir', t)
509
self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
510
self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
513
class TestTestCaseTransports(TestCaseWithTransport):
516
super(TestTestCaseTransports, self).setUp()
517
self.transport_server = MemoryServer
519
def test_make_bzrdir_preserves_transport(self):
520
t = self.get_transport()
521
result_bzrdir = self.make_bzrdir('subdir')
522
self.assertIsInstance(result_bzrdir.transport,
524
# should not be on disk, should only be in memory
525
self.failIfExists('subdir')
528
class TestChrootedTest(ChrootedTestCase):
530
def test_root_is_root(self):
531
from bzrlib.transport import get_transport
532
t = get_transport(self.get_readonly_url())
534
self.assertEqual(url, t.clone('..').base)
537
class MockProgress(_BaseProgressBar):
538
"""Progress-bar standin that records calls.
540
Useful for testing pb using code.
544
_BaseProgressBar.__init__(self)
548
self.calls.append(('tick',))
550
def update(self, msg=None, current=None, total=None):
551
self.calls.append(('update', msg, current, total))
554
self.calls.append(('clear',))
556
def note(self, msg, *args):
557
self.calls.append(('note', msg, args))
560
class TestTestResult(TestCase):
562
def test_progress_bar_style_quiet(self):
563
# test using a progress bar.
564
dummy_test = TestTestResult('test_progress_bar_style_quiet')
565
dummy_error = (Exception, None, [])
566
mypb = MockProgress()
567
mypb.update('Running tests', 0, 4)
568
last_calls = mypb.calls[:]
570
result = bzrlib.tests._MyResult(self._log_file,
574
self.assertEqual(last_calls, mypb.calls)
577
"""Shorten a string based on the terminal width"""
578
return result._ellipsise_unimportant_words(s,
579
osutils.terminal_width())
582
result.startTest(dummy_test)
583
# starting a test prints the test name
584
last_calls += [('update', '...tyle_quiet', 0, None)]
585
self.assertEqual(last_calls, mypb.calls)
586
result.addError(dummy_test, dummy_error)
587
last_calls += [('update', 'ERROR ', 1, None),
588
('note', shorten(dummy_test.id() + ': ERROR'), ())
590
self.assertEqual(last_calls, mypb.calls)
593
result.startTest(dummy_test)
594
last_calls += [('update', '...tyle_quiet', 1, None)]
595
self.assertEqual(last_calls, mypb.calls)
596
last_calls += [('update', 'FAIL ', 2, None),
597
('note', shorten(dummy_test.id() + ': FAIL'), ())
599
result.addFailure(dummy_test, dummy_error)
600
self.assertEqual(last_calls, mypb.calls)
603
result.startTest(dummy_test)
604
last_calls += [('update', '...tyle_quiet', 2, None)]
605
self.assertEqual(last_calls, mypb.calls)
606
result.addSuccess(dummy_test)
607
last_calls += [('update', 'OK ', 3, None)]
608
self.assertEqual(last_calls, mypb.calls)
611
result.startTest(dummy_test)
612
last_calls += [('update', '...tyle_quiet', 3, None)]
613
self.assertEqual(last_calls, mypb.calls)
614
result.addSkipped(dummy_test, dummy_error)
615
last_calls += [('update', 'SKIP ', 4, None)]
616
self.assertEqual(last_calls, mypb.calls)
618
def test_elapsed_time_with_benchmarking(self):
619
result = bzrlib.tests._MyResult(self._log_file,
623
result._recordTestStartTime()
625
result.extractBenchmarkTime(self)
626
timed_string = result._testTimeString()
627
# without explicit benchmarking, we should get a simple time.
628
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms$")
629
# if a benchmark time is given, we want a x of y style result.
630
self.time(time.sleep, 0.001)
631
result.extractBenchmarkTime(self)
632
timed_string = result._testTimeString()
633
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms/ [ 1-9][0-9]ms$")
634
# extracting the time from a non-bzrlib testcase sets to None
635
result._recordTestStartTime()
636
result.extractBenchmarkTime(
637
unittest.FunctionTestCase(self.test_elapsed_time_with_benchmarking))
638
timed_string = result._testTimeString()
639
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms$")
640
# cheat. Yes, wash thy mouth out with soap.
641
self._benchtime = None
643
def test_assigned_benchmark_file_stores_date(self):
645
result = bzrlib.tests._MyResult(self._log_file,
650
output_string = output.getvalue()
651
# if you are wondering about the regexp please read the comment in
652
# test_bench_history (bzrlib.tests.test_selftest.TestRunner)
653
# XXX: what comment? -- Andrew Bennetts
654
self.assertContainsRe(output_string, "--date [0-9.]+")
656
def test_benchhistory_records_test_times(self):
657
result_stream = StringIO()
658
result = bzrlib.tests._MyResult(
662
bench_history=result_stream
665
# we want profile a call and check that its test duration is recorded
666
# make a new test instance that when run will generate a benchmark
667
example_test_case = TestTestResult("_time_hello_world_encoding")
668
# execute the test, which should succeed and record times
669
example_test_case.run(result)
670
lines = result_stream.getvalue().splitlines()
671
self.assertEqual(2, len(lines))
672
self.assertContainsRe(lines[1],
673
" *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
674
"._time_hello_world_encoding")
676
def _time_hello_world_encoding(self):
677
"""Profile two sleep calls
679
This is used to exercise the test framework.
681
self.time(unicode, 'hello', errors='replace')
682
self.time(unicode, 'world', errors='replace')
684
def test_lsprofiling(self):
685
"""Verbose test result prints lsprof statistics from test cases."""
689
raise TestSkipped("lsprof not installed.")
690
result_stream = StringIO()
691
result = bzrlib.tests._MyResult(
692
unittest._WritelnDecorator(result_stream),
696
# we want profile a call of some sort and check it is output by
697
# addSuccess. We dont care about addError or addFailure as they
698
# are not that interesting for performance tuning.
699
# make a new test instance that when run will generate a profile
700
example_test_case = TestTestResult("_time_hello_world_encoding")
701
example_test_case._gather_lsprof_in_benchmarks = True
702
# execute the test, which should succeed and record profiles
703
example_test_case.run(result)
704
# lsprofile_something()
705
# if this worked we want
706
# LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
707
# CallCount Recursive Total(ms) Inline(ms) module:lineno(function)
708
# (the lsprof header)
709
# ... an arbitrary number of lines
710
# and the function call which is time.sleep.
711
# 1 0 ??? ??? ???(sleep)
712
# and then repeated but with 'world', rather than 'hello'.
713
# this should appear in the output stream of our test result.
714
output = result_stream.getvalue()
715
self.assertContainsRe(output,
716
r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
717
self.assertContainsRe(output,
718
r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
719
self.assertContainsRe(output,
720
r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
721
self.assertContainsRe(output,
722
r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
725
class TestRunner(TestCase):
727
def dummy_test(self):
730
def run_test_runner(self, testrunner, test):
731
"""Run suite in testrunner, saving global state and restoring it.
733
This current saves and restores:
734
TestCaseInTempDir.TEST_ROOT
736
There should be no tests in this file that use bzrlib.tests.TextTestRunner
737
without using this convenience method, because of our use of global state.
739
old_root = TestCaseInTempDir.TEST_ROOT
741
TestCaseInTempDir.TEST_ROOT = None
742
return testrunner.run(test)
744
TestCaseInTempDir.TEST_ROOT = old_root
746
def test_accepts_and_uses_pb_parameter(self):
747
test = TestRunner('dummy_test')
748
mypb = MockProgress()
749
self.assertEqual([], mypb.calls)
750
runner = TextTestRunner(stream=self._log_file, pb=mypb)
751
result = self.run_test_runner(runner, test)
752
self.assertEqual(1, result.testsRun)
753
self.assertEqual(('update', 'Running tests', 0, 1), mypb.calls[0])
754
self.assertEqual(('update', '...dummy_test', 0, None), mypb.calls[1])
755
self.assertEqual(('update', 'OK ', 1, None), mypb.calls[2])
756
self.assertEqual(('update', 'Cleaning up', 0, 1), mypb.calls[3])
757
self.assertEqual(('clear',), mypb.calls[4])
758
self.assertEqual(5, len(mypb.calls))
760
def test_skipped_test(self):
761
# run a test that is skipped, and check the suite as a whole still
763
# skipping_test must be hidden in here so it's not run as a real test
765
raise TestSkipped('test intentionally skipped')
766
runner = TextTestRunner(stream=self._log_file, keep_output=True)
767
test = unittest.FunctionTestCase(skipping_test)
768
result = self.run_test_runner(runner, test)
769
self.assertTrue(result.wasSuccessful())
771
def test_bench_history(self):
772
# tests that the running the benchmark produces a history file
773
# containing a timestamp and the revision id of the bzrlib source which
775
workingtree = _get_bzr_source_tree()
776
test = TestRunner('dummy_test')
778
runner = TextTestRunner(stream=self._log_file, bench_history=output)
779
result = self.run_test_runner(runner, test)
780
output_string = output.getvalue()
781
self.assertContainsRe(output_string, "--date [0-9.]+")
782
if workingtree is not None:
783
revision_id = workingtree.get_parent_ids()[0]
784
self.assertEndsWith(output_string.rstrip(), revision_id)
786
def test_success_log_deleted(self):
787
"""Successful tests have their log deleted"""
789
class LogTester(TestCase):
791
def test_success(self):
792
self.log('this will be removed\n')
794
sio = cStringIO.StringIO()
795
runner = TextTestRunner(stream=sio)
796
test = LogTester('test_success')
797
result = self.run_test_runner(runner, test)
799
log = test._get_log()
800
self.assertEqual("DELETED log file to reduce memory footprint", log)
801
self.assertEqual('', test._log_contents)
802
self.assertIs(None, test._log_file_name)
804
def test_fail_log_kept(self):
805
"""Failed tests have their log kept"""
807
class LogTester(TestCase):
810
self.log('this will be kept\n')
811
self.fail('this test fails')
813
sio = cStringIO.StringIO()
814
runner = TextTestRunner(stream=sio)
815
test = LogTester('test_fail')
816
result = self.run_test_runner(runner, test)
818
text = sio.getvalue()
819
self.assertContainsRe(text, 'this will be kept')
820
self.assertContainsRe(text, 'this test fails')
822
log = test._get_log()
823
self.assertContainsRe(log, 'this will be kept')
824
self.assertEqual(log, test._log_contents)
826
def test_error_log_kept(self):
827
"""Tests with errors have their log kept"""
829
class LogTester(TestCase):
831
def test_error(self):
832
self.log('this will be kept\n')
833
raise ValueError('random exception raised')
835
sio = cStringIO.StringIO()
836
runner = TextTestRunner(stream=sio)
837
test = LogTester('test_error')
838
result = self.run_test_runner(runner, test)
840
text = sio.getvalue()
841
self.assertContainsRe(text, 'this will be kept')
842
self.assertContainsRe(text, 'random exception raised')
844
log = test._get_log()
845
self.assertContainsRe(log, 'this will be kept')
846
self.assertEqual(log, test._log_contents)
849
class TestTestCase(TestCase):
850
"""Tests that test the core bzrlib TestCase."""
852
def inner_test(self):
853
# the inner child test
856
def outer_child(self):
857
# the outer child test
859
self.inner_test = TestTestCase("inner_child")
860
result = bzrlib.tests._MyResult(self._log_file,
863
self.inner_test.run(result)
866
def test_trace_nesting(self):
867
# this tests that each test case nests its trace facility correctly.
868
# we do this by running a test case manually. That test case (A)
869
# should setup a new log, log content to it, setup a child case (B),
870
# which should log independently, then case (A) should log a trailer
872
# we do two nested children so that we can verify the state of the
873
# logs after the outer child finishes is correct, which a bad clean
874
# up routine in tearDown might trigger a fault in our test with only
875
# one child, we should instead see the bad result inside our test with
877
# the outer child test
878
original_trace = bzrlib.trace._trace_file
879
outer_test = TestTestCase("outer_child")
880
result = bzrlib.tests._MyResult(self._log_file,
883
outer_test.run(result)
884
self.assertEqual(original_trace, bzrlib.trace._trace_file)
886
def method_that_times_a_bit_twice(self):
887
# call self.time twice to ensure it aggregates
888
self.time(time.sleep, 0.007)
889
self.time(time.sleep, 0.007)
891
def test_time_creates_benchmark_in_result(self):
892
"""Test that the TestCase.time() method accumulates a benchmark time."""
893
sample_test = TestTestCase("method_that_times_a_bit_twice")
894
output_stream = StringIO()
895
result = bzrlib.tests._MyResult(
896
unittest._WritelnDecorator(output_stream),
899
sample_test.run(result)
900
self.assertContainsRe(
901
output_stream.getvalue(),
902
"[1-9][0-9]ms/ [1-9][0-9]ms\n$")
904
def test__gather_lsprof_in_benchmarks(self):
905
"""When _gather_lsprof_in_benchmarks is on, accumulate profile data.
907
Each self.time() call is individually and separately profiled.
912
raise TestSkipped("lsprof not installed.")
913
# overrides the class member with an instance member so no cleanup
915
self._gather_lsprof_in_benchmarks = True
916
self.time(time.sleep, 0.000)
917
self.time(time.sleep, 0.003)
918
self.assertEqual(2, len(self._benchcalls))
919
self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
920
self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
921
self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
922
self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
925
@symbol_versioning.deprecated_function(zero_eleven)
926
def sample_deprecated_function():
927
"""A deprecated function to test applyDeprecated with."""
931
def sample_undeprecated_function(a_param):
932
"""A undeprecated function to test applyDeprecated with."""
935
class ApplyDeprecatedHelper(object):
936
"""A helper class for ApplyDeprecated tests."""
938
@symbol_versioning.deprecated_method(zero_eleven)
939
def sample_deprecated_method(self, param_one):
940
"""A deprecated method for testing with."""
943
def sample_normal_method(self):
944
"""A undeprecated method."""
946
@symbol_versioning.deprecated_method(zero_ten)
947
def sample_nested_deprecation(self):
948
return sample_deprecated_function()
951
class TestExtraAssertions(TestCase):
952
"""Tests for new test assertions in bzrlib test suite"""
954
def test_assert_isinstance(self):
955
self.assertIsInstance(2, int)
956
self.assertIsInstance(u'', basestring)
957
self.assertRaises(AssertionError, self.assertIsInstance, None, int)
958
self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
960
def test_assertEndsWith(self):
961
self.assertEndsWith('foo', 'oo')
962
self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
964
def test_applyDeprecated_not_deprecated(self):
965
sample_object = ApplyDeprecatedHelper()
966
# calling an undeprecated callable raises an assertion
967
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
968
sample_object.sample_normal_method)
969
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
970
sample_undeprecated_function, "a param value")
971
# calling a deprecated callable (function or method) with the wrong
972
# expected deprecation fails.
973
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
974
sample_object.sample_deprecated_method, "a param value")
975
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
976
sample_deprecated_function)
977
# calling a deprecated callable (function or method) with the right
978
# expected deprecation returns the functions result.
979
self.assertEqual("a param value", self.applyDeprecated(zero_eleven,
980
sample_object.sample_deprecated_method, "a param value"))
981
self.assertEqual(2, self.applyDeprecated(zero_eleven,
982
sample_deprecated_function))
983
# calling a nested deprecation with the wrong deprecation version
984
# fails even if a deeper nested function was deprecated with the
986
self.assertRaises(AssertionError, self.applyDeprecated,
987
zero_eleven, sample_object.sample_nested_deprecation)
988
# calling a nested deprecation with the right deprecation value
989
# returns the calls result.
990
self.assertEqual(2, self.applyDeprecated(zero_ten,
991
sample_object.sample_nested_deprecation))
993
def test_callDeprecated(self):
994
def testfunc(be_deprecated, result=None):
995
if be_deprecated is True:
996
symbol_versioning.warn('i am deprecated', DeprecationWarning,
999
result = self.callDeprecated(['i am deprecated'], testfunc, True)
1000
self.assertIs(None, result)
1001
result = self.callDeprecated([], testfunc, False, 'result')
1002
self.assertEqual('result', result)
1003
self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
1004
self.callDeprecated([], testfunc, be_deprecated=False)
1007
class TestConvenienceMakers(TestCaseWithTransport):
1008
"""Test for the make_* convenience functions."""
1010
def test_make_branch_and_tree_with_format(self):
1011
# we should be able to supply a format to make_branch_and_tree
1012
self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
1013
self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
1014
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
1015
bzrlib.bzrdir.BzrDirMetaFormat1)
1016
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
1017
bzrlib.bzrdir.BzrDirFormat6)
1019
def test_make_branch_and_memory_tree(self):
1020
# we should be able to get a new branch and a mutable tree from
1021
# TestCaseWithTransport
1022
tree = self.make_branch_and_memory_tree('a')
1023
self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
1026
class TestSFTPMakeBranchAndTree(TestCaseWithSFTPServer):
1028
def test_make_tree_for_sftp_branch(self):
1029
"""Transports backed by local directories create local trees."""
1031
tree = self.make_branch_and_tree('t1')
1032
base = tree.bzrdir.root_transport.base
1033
self.failIf(base.startswith('sftp'),
1034
'base %r is on sftp but should be local' % base)
1035
self.assertEquals(tree.bzrdir.root_transport,
1036
tree.branch.bzrdir.root_transport)
1037
self.assertEquals(tree.bzrdir.root_transport,
1038
tree.branch.repository.bzrdir.root_transport)
1041
class TestSelftest(TestCase):
1042
"""Tests of bzrlib.tests.selftest."""
1044
def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
1047
factory_called.append(True)
1051
self.apply_redirected(out, err, None, bzrlib.tests.selftest,
1052
test_suite_factory=factory)
1053
self.assertEqual([True], factory_called)