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.tests.HttpServer import HttpServer
490
from bzrlib.transport import get_transport
491
from bzrlib.transport.local import LocalRelpathServer
492
from bzrlib.transport.http import HttpTransportBase
493
self.transport_server = LocalRelpathServer
494
self.transport_readonly_server = HttpServer
495
# calling get_readonly_transport() gives us a HTTP server instance.
496
url = self.get_readonly_url()
497
url2 = self.get_readonly_url('foo/bar')
498
# the transport returned may be any HttpTransportBase subclass
499
t = get_transport(url)
500
t2 = get_transport(url2)
501
self.failUnless(isinstance(t, HttpTransportBase))
502
self.failUnless(isinstance(t2, HttpTransportBase))
503
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
505
def test_is_directory(self):
506
"""Test assertIsDirectory assertion"""
507
t = self.get_transport()
508
self.build_tree(['a_dir/', 'a_file'], transport=t)
509
self.assertIsDirectory('a_dir', t)
510
self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
511
self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
514
class TestTestCaseTransports(TestCaseWithTransport):
517
super(TestTestCaseTransports, self).setUp()
518
self.transport_server = MemoryServer
520
def test_make_bzrdir_preserves_transport(self):
521
t = self.get_transport()
522
result_bzrdir = self.make_bzrdir('subdir')
523
self.assertIsInstance(result_bzrdir.transport,
525
# should not be on disk, should only be in memory
526
self.failIfExists('subdir')
529
class TestChrootedTest(ChrootedTestCase):
531
def test_root_is_root(self):
532
from bzrlib.transport import get_transport
533
t = get_transport(self.get_readonly_url())
535
self.assertEqual(url, t.clone('..').base)
538
class MockProgress(_BaseProgressBar):
539
"""Progress-bar standin that records calls.
541
Useful for testing pb using code.
545
_BaseProgressBar.__init__(self)
549
self.calls.append(('tick',))
551
def update(self, msg=None, current=None, total=None):
552
self.calls.append(('update', msg, current, total))
555
self.calls.append(('clear',))
557
def note(self, msg, *args):
558
self.calls.append(('note', msg, args))
561
class TestTestResult(TestCase):
563
def test_progress_bar_style_quiet(self):
564
# test using a progress bar.
565
dummy_test = TestTestResult('test_progress_bar_style_quiet')
566
dummy_error = (Exception, None, [])
567
mypb = MockProgress()
568
mypb.update('Running tests', 0, 4)
569
last_calls = mypb.calls[:]
571
result = bzrlib.tests._MyResult(self._log_file,
575
self.assertEqual(last_calls, mypb.calls)
578
"""Shorten a string based on the terminal width"""
579
return result._ellipsise_unimportant_words(s,
580
osutils.terminal_width())
583
result.startTest(dummy_test)
584
# starting a test prints the test name
585
last_calls += [('update', '...tyle_quiet', 0, None)]
586
self.assertEqual(last_calls, mypb.calls)
587
result.addError(dummy_test, dummy_error)
588
last_calls += [('update', 'ERROR ', 1, None),
589
('note', shorten(dummy_test.id() + ': ERROR'), ())
591
self.assertEqual(last_calls, mypb.calls)
594
result.startTest(dummy_test)
595
last_calls += [('update', '...tyle_quiet', 1, None)]
596
self.assertEqual(last_calls, mypb.calls)
597
last_calls += [('update', 'FAIL ', 2, None),
598
('note', shorten(dummy_test.id() + ': FAIL'), ())
600
result.addFailure(dummy_test, dummy_error)
601
self.assertEqual(last_calls, mypb.calls)
604
result.startTest(dummy_test)
605
last_calls += [('update', '...tyle_quiet', 2, None)]
606
self.assertEqual(last_calls, mypb.calls)
607
result.addSuccess(dummy_test)
608
last_calls += [('update', 'OK ', 3, None)]
609
self.assertEqual(last_calls, mypb.calls)
612
result.startTest(dummy_test)
613
last_calls += [('update', '...tyle_quiet', 3, None)]
614
self.assertEqual(last_calls, mypb.calls)
615
result.addSkipped(dummy_test, dummy_error)
616
last_calls += [('update', 'SKIP ', 4, None)]
617
self.assertEqual(last_calls, mypb.calls)
619
def test_elapsed_time_with_benchmarking(self):
620
result = bzrlib.tests._MyResult(self._log_file,
624
result._recordTestStartTime()
626
result.extractBenchmarkTime(self)
627
timed_string = result._testTimeString()
628
# without explicit benchmarking, we should get a simple time.
629
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms$")
630
# if a benchmark time is given, we want a x of y style result.
631
self.time(time.sleep, 0.001)
632
result.extractBenchmarkTime(self)
633
timed_string = result._testTimeString()
634
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms/ [ 1-9][0-9]ms$")
635
# extracting the time from a non-bzrlib testcase sets to None
636
result._recordTestStartTime()
637
result.extractBenchmarkTime(
638
unittest.FunctionTestCase(self.test_elapsed_time_with_benchmarking))
639
timed_string = result._testTimeString()
640
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms$")
641
# cheat. Yes, wash thy mouth out with soap.
642
self._benchtime = None
644
def test_assigned_benchmark_file_stores_date(self):
646
result = bzrlib.tests._MyResult(self._log_file,
651
output_string = output.getvalue()
652
# if you are wondering about the regexp please read the comment in
653
# test_bench_history (bzrlib.tests.test_selftest.TestRunner)
654
# XXX: what comment? -- Andrew Bennetts
655
self.assertContainsRe(output_string, "--date [0-9.]+")
657
def test_benchhistory_records_test_times(self):
658
result_stream = StringIO()
659
result = bzrlib.tests._MyResult(
663
bench_history=result_stream
666
# we want profile a call and check that its test duration is recorded
667
# make a new test instance that when run will generate a benchmark
668
example_test_case = TestTestResult("_time_hello_world_encoding")
669
# execute the test, which should succeed and record times
670
example_test_case.run(result)
671
lines = result_stream.getvalue().splitlines()
672
self.assertEqual(2, len(lines))
673
self.assertContainsRe(lines[1],
674
" *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
675
"._time_hello_world_encoding")
677
def _time_hello_world_encoding(self):
678
"""Profile two sleep calls
680
This is used to exercise the test framework.
682
self.time(unicode, 'hello', errors='replace')
683
self.time(unicode, 'world', errors='replace')
685
def test_lsprofiling(self):
686
"""Verbose test result prints lsprof statistics from test cases."""
690
raise TestSkipped("lsprof not installed.")
691
result_stream = StringIO()
692
result = bzrlib.tests._MyResult(
693
unittest._WritelnDecorator(result_stream),
697
# we want profile a call of some sort and check it is output by
698
# addSuccess. We dont care about addError or addFailure as they
699
# are not that interesting for performance tuning.
700
# make a new test instance that when run will generate a profile
701
example_test_case = TestTestResult("_time_hello_world_encoding")
702
example_test_case._gather_lsprof_in_benchmarks = True
703
# execute the test, which should succeed and record profiles
704
example_test_case.run(result)
705
# lsprofile_something()
706
# if this worked we want
707
# LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
708
# CallCount Recursive Total(ms) Inline(ms) module:lineno(function)
709
# (the lsprof header)
710
# ... an arbitrary number of lines
711
# and the function call which is time.sleep.
712
# 1 0 ??? ??? ???(sleep)
713
# and then repeated but with 'world', rather than 'hello'.
714
# this should appear in the output stream of our test result.
715
output = result_stream.getvalue()
716
self.assertContainsRe(output,
717
r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
718
self.assertContainsRe(output,
719
r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
720
self.assertContainsRe(output,
721
r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
722
self.assertContainsRe(output,
723
r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
726
class TestRunner(TestCase):
728
def dummy_test(self):
731
def run_test_runner(self, testrunner, test):
732
"""Run suite in testrunner, saving global state and restoring it.
734
This current saves and restores:
735
TestCaseInTempDir.TEST_ROOT
737
There should be no tests in this file that use bzrlib.tests.TextTestRunner
738
without using this convenience method, because of our use of global state.
740
old_root = TestCaseInTempDir.TEST_ROOT
742
TestCaseInTempDir.TEST_ROOT = None
743
return testrunner.run(test)
745
TestCaseInTempDir.TEST_ROOT = old_root
747
def test_accepts_and_uses_pb_parameter(self):
748
test = TestRunner('dummy_test')
749
mypb = MockProgress()
750
self.assertEqual([], mypb.calls)
751
runner = TextTestRunner(stream=self._log_file, pb=mypb)
752
result = self.run_test_runner(runner, test)
753
self.assertEqual(1, result.testsRun)
754
self.assertEqual(('update', 'Running tests', 0, 1), mypb.calls[0])
755
self.assertEqual(('update', '...dummy_test', 0, None), mypb.calls[1])
756
self.assertEqual(('update', 'OK ', 1, None), mypb.calls[2])
757
self.assertEqual(('update', 'Cleaning up', 0, 1), mypb.calls[3])
758
self.assertEqual(('clear',), mypb.calls[4])
759
self.assertEqual(5, len(mypb.calls))
761
def test_skipped_test(self):
762
# run a test that is skipped, and check the suite as a whole still
764
# skipping_test must be hidden in here so it's not run as a real test
766
raise TestSkipped('test intentionally skipped')
767
runner = TextTestRunner(stream=self._log_file, keep_output=True)
768
test = unittest.FunctionTestCase(skipping_test)
769
result = self.run_test_runner(runner, test)
770
self.assertTrue(result.wasSuccessful())
772
def test_bench_history(self):
773
# tests that the running the benchmark produces a history file
774
# containing a timestamp and the revision id of the bzrlib source which
776
workingtree = _get_bzr_source_tree()
777
test = TestRunner('dummy_test')
779
runner = TextTestRunner(stream=self._log_file, bench_history=output)
780
result = self.run_test_runner(runner, test)
781
output_string = output.getvalue()
782
self.assertContainsRe(output_string, "--date [0-9.]+")
783
if workingtree is not None:
784
revision_id = workingtree.get_parent_ids()[0]
785
self.assertEndsWith(output_string.rstrip(), revision_id)
787
def test_success_log_deleted(self):
788
"""Successful tests have their log deleted"""
790
class LogTester(TestCase):
792
def test_success(self):
793
self.log('this will be removed\n')
795
sio = cStringIO.StringIO()
796
runner = TextTestRunner(stream=sio)
797
test = LogTester('test_success')
798
result = self.run_test_runner(runner, test)
800
log = test._get_log()
801
self.assertEqual("DELETED log file to reduce memory footprint", log)
802
self.assertEqual('', test._log_contents)
803
self.assertIs(None, test._log_file_name)
805
def test_fail_log_kept(self):
806
"""Failed tests have their log kept"""
808
class LogTester(TestCase):
811
self.log('this will be kept\n')
812
self.fail('this test fails')
814
sio = cStringIO.StringIO()
815
runner = TextTestRunner(stream=sio)
816
test = LogTester('test_fail')
817
result = self.run_test_runner(runner, test)
819
text = sio.getvalue()
820
self.assertContainsRe(text, 'this will be kept')
821
self.assertContainsRe(text, 'this test fails')
823
log = test._get_log()
824
self.assertContainsRe(log, 'this will be kept')
825
self.assertEqual(log, test._log_contents)
827
def test_error_log_kept(self):
828
"""Tests with errors have their log kept"""
830
class LogTester(TestCase):
832
def test_error(self):
833
self.log('this will be kept\n')
834
raise ValueError('random exception raised')
836
sio = cStringIO.StringIO()
837
runner = TextTestRunner(stream=sio)
838
test = LogTester('test_error')
839
result = self.run_test_runner(runner, test)
841
text = sio.getvalue()
842
self.assertContainsRe(text, 'this will be kept')
843
self.assertContainsRe(text, 'random exception raised')
845
log = test._get_log()
846
self.assertContainsRe(log, 'this will be kept')
847
self.assertEqual(log, test._log_contents)
850
class TestTestCase(TestCase):
851
"""Tests that test the core bzrlib TestCase."""
853
def inner_test(self):
854
# the inner child test
857
def outer_child(self):
858
# the outer child test
860
self.inner_test = TestTestCase("inner_child")
861
result = bzrlib.tests._MyResult(self._log_file,
864
self.inner_test.run(result)
867
def test_trace_nesting(self):
868
# this tests that each test case nests its trace facility correctly.
869
# we do this by running a test case manually. That test case (A)
870
# should setup a new log, log content to it, setup a child case (B),
871
# which should log independently, then case (A) should log a trailer
873
# we do two nested children so that we can verify the state of the
874
# logs after the outer child finishes is correct, which a bad clean
875
# up routine in tearDown might trigger a fault in our test with only
876
# one child, we should instead see the bad result inside our test with
878
# the outer child test
879
original_trace = bzrlib.trace._trace_file
880
outer_test = TestTestCase("outer_child")
881
result = bzrlib.tests._MyResult(self._log_file,
884
outer_test.run(result)
885
self.assertEqual(original_trace, bzrlib.trace._trace_file)
887
def method_that_times_a_bit_twice(self):
888
# call self.time twice to ensure it aggregates
889
self.time(time.sleep, 0.007)
890
self.time(time.sleep, 0.007)
892
def test_time_creates_benchmark_in_result(self):
893
"""Test that the TestCase.time() method accumulates a benchmark time."""
894
sample_test = TestTestCase("method_that_times_a_bit_twice")
895
output_stream = StringIO()
896
result = bzrlib.tests._MyResult(
897
unittest._WritelnDecorator(output_stream),
900
sample_test.run(result)
901
self.assertContainsRe(
902
output_stream.getvalue(),
903
"[1-9][0-9]ms/ [1-9][0-9]ms\n$")
905
def test__gather_lsprof_in_benchmarks(self):
906
"""When _gather_lsprof_in_benchmarks is on, accumulate profile data.
908
Each self.time() call is individually and separately profiled.
913
raise TestSkipped("lsprof not installed.")
914
# overrides the class member with an instance member so no cleanup
916
self._gather_lsprof_in_benchmarks = True
917
self.time(time.sleep, 0.000)
918
self.time(time.sleep, 0.003)
919
self.assertEqual(2, len(self._benchcalls))
920
self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
921
self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
922
self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
923
self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
926
@symbol_versioning.deprecated_function(zero_eleven)
927
def sample_deprecated_function():
928
"""A deprecated function to test applyDeprecated with."""
932
def sample_undeprecated_function(a_param):
933
"""A undeprecated function to test applyDeprecated with."""
936
class ApplyDeprecatedHelper(object):
937
"""A helper class for ApplyDeprecated tests."""
939
@symbol_versioning.deprecated_method(zero_eleven)
940
def sample_deprecated_method(self, param_one):
941
"""A deprecated method for testing with."""
944
def sample_normal_method(self):
945
"""A undeprecated method."""
947
@symbol_versioning.deprecated_method(zero_ten)
948
def sample_nested_deprecation(self):
949
return sample_deprecated_function()
952
class TestExtraAssertions(TestCase):
953
"""Tests for new test assertions in bzrlib test suite"""
955
def test_assert_isinstance(self):
956
self.assertIsInstance(2, int)
957
self.assertIsInstance(u'', basestring)
958
self.assertRaises(AssertionError, self.assertIsInstance, None, int)
959
self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
961
def test_assertEndsWith(self):
962
self.assertEndsWith('foo', 'oo')
963
self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
965
def test_applyDeprecated_not_deprecated(self):
966
sample_object = ApplyDeprecatedHelper()
967
# calling an undeprecated callable raises an assertion
968
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
969
sample_object.sample_normal_method)
970
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
971
sample_undeprecated_function, "a param value")
972
# calling a deprecated callable (function or method) with the wrong
973
# expected deprecation fails.
974
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
975
sample_object.sample_deprecated_method, "a param value")
976
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
977
sample_deprecated_function)
978
# calling a deprecated callable (function or method) with the right
979
# expected deprecation returns the functions result.
980
self.assertEqual("a param value", self.applyDeprecated(zero_eleven,
981
sample_object.sample_deprecated_method, "a param value"))
982
self.assertEqual(2, self.applyDeprecated(zero_eleven,
983
sample_deprecated_function))
984
# calling a nested deprecation with the wrong deprecation version
985
# fails even if a deeper nested function was deprecated with the
987
self.assertRaises(AssertionError, self.applyDeprecated,
988
zero_eleven, sample_object.sample_nested_deprecation)
989
# calling a nested deprecation with the right deprecation value
990
# returns the calls result.
991
self.assertEqual(2, self.applyDeprecated(zero_ten,
992
sample_object.sample_nested_deprecation))
994
def test_callDeprecated(self):
995
def testfunc(be_deprecated, result=None):
996
if be_deprecated is True:
997
symbol_versioning.warn('i am deprecated', DeprecationWarning,
1000
result = self.callDeprecated(['i am deprecated'], testfunc, True)
1001
self.assertIs(None, result)
1002
result = self.callDeprecated([], testfunc, False, 'result')
1003
self.assertEqual('result', result)
1004
self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
1005
self.callDeprecated([], testfunc, be_deprecated=False)
1008
class TestConvenienceMakers(TestCaseWithTransport):
1009
"""Test for the make_* convenience functions."""
1011
def test_make_branch_and_tree_with_format(self):
1012
# we should be able to supply a format to make_branch_and_tree
1013
self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
1014
self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
1015
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
1016
bzrlib.bzrdir.BzrDirMetaFormat1)
1017
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
1018
bzrlib.bzrdir.BzrDirFormat6)
1020
def test_make_branch_and_memory_tree(self):
1021
# we should be able to get a new branch and a mutable tree from
1022
# TestCaseWithTransport
1023
tree = self.make_branch_and_memory_tree('a')
1024
self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
1027
class TestSFTPMakeBranchAndTree(TestCaseWithSFTPServer):
1029
def test_make_tree_for_sftp_branch(self):
1030
"""Transports backed by local directories create local trees."""
1032
tree = self.make_branch_and_tree('t1')
1033
base = tree.bzrdir.root_transport.base
1034
self.failIf(base.startswith('sftp'),
1035
'base %r is on sftp but should be local' % base)
1036
self.assertEquals(tree.bzrdir.root_transport,
1037
tree.branch.bzrdir.root_transport)
1038
self.assertEquals(tree.bzrdir.root_transport,
1039
tree.branch.repository.bzrdir.root_transport)
1042
class TestSelftest(TestCase):
1043
"""Tests of bzrlib.tests.selftest."""
1045
def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
1048
factory_called.append(True)
1052
self.apply_redirected(out, err, None, bzrlib.tests.selftest,
1053
test_suite_factory=factory)
1054
self.assertEqual([True], factory_called)