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."""
19
from StringIO import StringIO
25
from bzrlib import osutils
27
from bzrlib.progress import _BaseProgressBar
28
from bzrlib.tests import (
32
TestCaseWithTransport,
37
from bzrlib.tests.TestUtil import _load_module_by_name
38
import bzrlib.errors as errors
39
from bzrlib import symbol_versioning
40
from bzrlib.symbol_versioning import zero_ten, zero_eleven
41
from bzrlib.trace import note
42
from bzrlib.version import _get_bzr_source_tree
45
class SelftestTests(TestCase):
47
def test_import_tests(self):
48
mod = _load_module_by_name('bzrlib.tests.test_selftest')
49
self.assertEqual(mod.SelftestTests, SelftestTests)
51
def test_import_test_failure(self):
52
self.assertRaises(ImportError,
57
class MetaTestLog(TestCase):
59
def test_logging(self):
60
"""Test logs are captured when a test fails."""
61
self.log('a test message')
62
self._log_file.flush()
63
self.assertContainsRe(self._get_log(), 'a test message\n')
66
class TestTreeShape(TestCaseInTempDir):
68
def test_unicode_paths(self):
69
filename = u'hell\u00d8'
71
self.build_tree_contents([(filename, 'contents of hello')])
72
except UnicodeEncodeError:
73
raise TestSkipped("can't build unicode working tree in "
74
"filesystem encoding %s" % sys.getfilesystemencoding())
75
self.failUnlessExists(filename)
78
class TestTransportProviderAdapter(TestCase):
79
"""A group of tests that test the transport implementation adaption core.
81
This is a meta test that the tests are applied to all available
84
This will be generalised in the future which is why it is in this
85
test file even though it is specific to transport tests at the moment.
88
def test_get_transport_permutations(self):
89
# this checks that we the module get_test_permutations call
90
# is made by the adapter get_transport_test_permitations method.
91
class MockModule(object):
92
def get_test_permutations(self):
93
return sample_permutation
94
sample_permutation = [(1,2), (3,4)]
95
from bzrlib.transport import TransportTestProviderAdapter
96
adapter = TransportTestProviderAdapter()
97
self.assertEqual(sample_permutation,
98
adapter.get_transport_test_permutations(MockModule()))
100
def test_adapter_checks_all_modules(self):
101
# this checks that the adapter returns as many permurtations as
102
# there are in all the registered# transport modules for there
103
# - we assume if this matches its probably doing the right thing
104
# especially in combination with the tests for setting the right
106
from bzrlib.transport import (TransportTestProviderAdapter,
107
_get_transport_modules
109
modules = _get_transport_modules()
110
permutation_count = 0
111
for module in modules:
113
permutation_count += len(reduce(getattr,
114
(module + ".get_test_permutations").split('.')[1:],
115
__import__(module))())
116
except errors.DependencyNotPresent:
118
input_test = TestTransportProviderAdapter(
119
"test_adapter_sets_transport_class")
120
adapter = TransportTestProviderAdapter()
121
self.assertEqual(permutation_count,
122
len(list(iter(adapter.adapt(input_test)))))
124
def test_adapter_sets_transport_class(self):
125
# Check that the test adapter inserts a transport and server into the
128
# This test used to know about all the possible transports and the
129
# order they were returned but that seems overly brittle (mbp
131
input_test = TestTransportProviderAdapter(
132
"test_adapter_sets_transport_class")
133
from bzrlib.transport import TransportTestProviderAdapter
134
suite = TransportTestProviderAdapter().adapt(input_test)
135
tests = list(iter(suite))
136
self.assertTrue(len(tests) > 6)
137
# there are at least that many builtin transports
139
self.assertTrue(issubclass(one_test.transport_class,
140
bzrlib.transport.Transport))
141
self.assertTrue(issubclass(one_test.transport_server,
142
bzrlib.transport.Server))
145
class TestBranchProviderAdapter(TestCase):
146
"""A group of tests that test the branch implementation test adapter."""
148
def test_adapted_tests(self):
149
# check that constructor parameters are passed through to the adapted
151
from bzrlib.branch import BranchTestProviderAdapter
152
input_test = TestBranchProviderAdapter(
153
"test_adapted_tests")
156
formats = [("c", "C"), ("d", "D")]
157
adapter = BranchTestProviderAdapter(server1, server2, formats)
158
suite = adapter.adapt(input_test)
159
tests = list(iter(suite))
160
self.assertEqual(2, len(tests))
161
self.assertEqual(tests[0].branch_format, formats[0][0])
162
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
163
self.assertEqual(tests[0].transport_server, server1)
164
self.assertEqual(tests[0].transport_readonly_server, server2)
165
self.assertEqual(tests[1].branch_format, formats[1][0])
166
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
167
self.assertEqual(tests[1].transport_server, server1)
168
self.assertEqual(tests[1].transport_readonly_server, server2)
171
class TestBzrDirProviderAdapter(TestCase):
172
"""A group of tests that test the bzr dir implementation test adapter."""
174
def test_adapted_tests(self):
175
# check that constructor parameters are passed through to the adapted
177
from bzrlib.bzrdir import BzrDirTestProviderAdapter
178
input_test = TestBzrDirProviderAdapter(
179
"test_adapted_tests")
183
adapter = BzrDirTestProviderAdapter(server1, server2, formats)
184
suite = adapter.adapt(input_test)
185
tests = list(iter(suite))
186
self.assertEqual(2, len(tests))
187
self.assertEqual(tests[0].bzrdir_format, formats[0])
188
self.assertEqual(tests[0].transport_server, server1)
189
self.assertEqual(tests[0].transport_readonly_server, server2)
190
self.assertEqual(tests[1].bzrdir_format, formats[1])
191
self.assertEqual(tests[1].transport_server, server1)
192
self.assertEqual(tests[1].transport_readonly_server, server2)
195
class TestRepositoryProviderAdapter(TestCase):
196
"""A group of tests that test the repository implementation test adapter."""
198
def test_adapted_tests(self):
199
# check that constructor parameters are passed through to the adapted
201
from bzrlib.repository import RepositoryTestProviderAdapter
202
input_test = TestRepositoryProviderAdapter(
203
"test_adapted_tests")
206
formats = [("c", "C"), ("d", "D")]
207
adapter = RepositoryTestProviderAdapter(server1, server2, formats)
208
suite = adapter.adapt(input_test)
209
tests = list(iter(suite))
210
self.assertEqual(2, len(tests))
211
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
212
self.assertEqual(tests[0].repository_format, formats[0][0])
213
self.assertEqual(tests[0].transport_server, server1)
214
self.assertEqual(tests[0].transport_readonly_server, server2)
215
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
216
self.assertEqual(tests[1].repository_format, formats[1][0])
217
self.assertEqual(tests[1].transport_server, server1)
218
self.assertEqual(tests[1].transport_readonly_server, server2)
221
class TestInterRepositoryProviderAdapter(TestCase):
222
"""A group of tests that test the InterRepository test adapter."""
224
def test_adapted_tests(self):
225
# check that constructor parameters are passed through to the adapted
227
from bzrlib.repository import InterRepositoryTestProviderAdapter
228
input_test = TestInterRepositoryProviderAdapter(
229
"test_adapted_tests")
232
formats = [(str, "C1", "C2"), (int, "D1", "D2")]
233
adapter = InterRepositoryTestProviderAdapter(server1, server2, formats)
234
suite = adapter.adapt(input_test)
235
tests = list(iter(suite))
236
self.assertEqual(2, len(tests))
237
self.assertEqual(tests[0].interrepo_class, formats[0][0])
238
self.assertEqual(tests[0].repository_format, formats[0][1])
239
self.assertEqual(tests[0].repository_format_to, formats[0][2])
240
self.assertEqual(tests[0].transport_server, server1)
241
self.assertEqual(tests[0].transport_readonly_server, server2)
242
self.assertEqual(tests[1].interrepo_class, formats[1][0])
243
self.assertEqual(tests[1].repository_format, formats[1][1])
244
self.assertEqual(tests[1].repository_format_to, formats[1][2])
245
self.assertEqual(tests[1].transport_server, server1)
246
self.assertEqual(tests[1].transport_readonly_server, server2)
249
class TestInterVersionedFileProviderAdapter(TestCase):
250
"""A group of tests that test the InterVersionedFile test adapter."""
252
def test_adapted_tests(self):
253
# check that constructor parameters are passed through to the adapted
255
from bzrlib.versionedfile import InterVersionedFileTestProviderAdapter
256
input_test = TestInterRepositoryProviderAdapter(
257
"test_adapted_tests")
260
formats = [(str, "C1", "C2"), (int, "D1", "D2")]
261
adapter = InterVersionedFileTestProviderAdapter(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].interversionedfile_class, formats[0][0])
266
self.assertEqual(tests[0].versionedfile_factory, formats[0][1])
267
self.assertEqual(tests[0].versionedfile_factory_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].interversionedfile_class, formats[1][0])
271
self.assertEqual(tests[1].versionedfile_factory, formats[1][1])
272
self.assertEqual(tests[1].versionedfile_factory_to, formats[1][2])
273
self.assertEqual(tests[1].transport_server, server1)
274
self.assertEqual(tests[1].transport_readonly_server, server2)
277
class TestRevisionStoreProviderAdapter(TestCase):
278
"""A group of tests that test the RevisionStore test adapter."""
280
def test_adapted_tests(self):
281
# check that constructor parameters are passed through to the adapted
283
from bzrlib.store.revision import RevisionStoreTestProviderAdapter
284
input_test = TestRevisionStoreProviderAdapter(
285
"test_adapted_tests")
286
# revision stores need a store factory - i.e. RevisionKnit
287
#, a readonly and rw transport
291
store_factories = ["c", "d"]
292
adapter = RevisionStoreTestProviderAdapter(server1, server2, store_factories)
293
suite = adapter.adapt(input_test)
294
tests = list(iter(suite))
295
self.assertEqual(2, len(tests))
296
self.assertEqual(tests[0].store_factory, store_factories[0][0])
297
self.assertEqual(tests[0].transport_server, server1)
298
self.assertEqual(tests[0].transport_readonly_server, server2)
299
self.assertEqual(tests[1].store_factory, store_factories[1][0])
300
self.assertEqual(tests[1].transport_server, server1)
301
self.assertEqual(tests[1].transport_readonly_server, server2)
304
class TestWorkingTreeProviderAdapter(TestCase):
305
"""A group of tests that test the workingtree implementation test adapter."""
307
def test_adapted_tests(self):
308
# check that constructor parameters are passed through to the adapted
310
from bzrlib.workingtree import WorkingTreeTestProviderAdapter
311
input_test = TestWorkingTreeProviderAdapter(
312
"test_adapted_tests")
315
formats = [("c", "C"), ("d", "D")]
316
adapter = WorkingTreeTestProviderAdapter(server1, server2, formats)
317
suite = adapter.adapt(input_test)
318
tests = list(iter(suite))
319
self.assertEqual(2, len(tests))
320
self.assertEqual(tests[0].workingtree_format, formats[0][0])
321
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
322
self.assertEqual(tests[0].transport_server, server1)
323
self.assertEqual(tests[0].transport_readonly_server, server2)
324
self.assertEqual(tests[1].workingtree_format, formats[1][0])
325
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
326
self.assertEqual(tests[1].transport_server, server1)
327
self.assertEqual(tests[1].transport_readonly_server, server2)
330
class TestTreeProviderAdapter(TestCase):
331
"""Test the setup of tree_implementation tests."""
333
def test_adapted_tests(self):
334
# the tree implementation adapter is meant to setup one instance for
335
# each working tree format, and one additional instance that will
336
# use the default wt format, but create a revision tree for the tests.
337
# this means that the wt ones should have the workingtree_to_test_tree
338
# attribute set to 'return_parameter' and the revision one set to
339
# revision_tree_from_workingtree.
341
from bzrlib.tests.tree_implementations import (
342
TreeTestProviderAdapter,
344
revision_tree_from_workingtree
346
from bzrlib.workingtree import WorkingTreeFormat
347
input_test = TestTreeProviderAdapter(
348
"test_adapted_tests")
351
formats = [("c", "C"), ("d", "D")]
352
adapter = TreeTestProviderAdapter(server1, server2, formats)
353
suite = adapter.adapt(input_test)
354
tests = list(iter(suite))
355
self.assertEqual(3, len(tests))
356
default_format = WorkingTreeFormat.get_default_format()
357
self.assertEqual(tests[0].workingtree_format, formats[0][0])
358
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
359
self.assertEqual(tests[0].transport_server, server1)
360
self.assertEqual(tests[0].transport_readonly_server, server2)
361
self.assertEqual(tests[0].workingtree_to_test_tree, return_parameter)
362
self.assertEqual(tests[1].workingtree_format, formats[1][0])
363
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
364
self.assertEqual(tests[1].transport_server, server1)
365
self.assertEqual(tests[1].transport_readonly_server, server2)
366
self.assertEqual(tests[1].workingtree_to_test_tree, return_parameter)
367
self.assertEqual(tests[2].workingtree_format, default_format)
368
self.assertEqual(tests[2].bzrdir_format, default_format._matchingbzrdir)
369
self.assertEqual(tests[2].transport_server, server1)
370
self.assertEqual(tests[2].transport_readonly_server, server2)
371
self.assertEqual(tests[2].workingtree_to_test_tree,
372
revision_tree_from_workingtree)
375
class TestInterTreeProviderAdapter(TestCase):
376
"""A group of tests that test the InterTreeTestAdapter."""
378
def test_adapted_tests(self):
379
# check that constructor parameters are passed through to the adapted
381
# for InterTree tests we want the machinery to bring up two trees in
382
# each instance: the base one, and the one we are interacting with.
383
# because each optimiser can be direction specific, we need to test
384
# each optimiser in its chosen direction.
385
# unlike the TestProviderAdapter we dont want to automatically add a
386
# parameterised one for WorkingTree - the optimisers will tell us what
388
from bzrlib.tests.tree_implementations import (
390
revision_tree_from_workingtree
392
from bzrlib.tests.intertree_implementations import (
393
InterTreeTestProviderAdapter,
395
from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
396
input_test = TestInterTreeProviderAdapter(
397
"test_adapted_tests")
400
format1 = WorkingTreeFormat2()
401
format2 = WorkingTreeFormat3()
402
formats = [(str, format1, format2, False, True),
403
(int, format2, format1, False, True)]
404
adapter = InterTreeTestProviderAdapter(server1, server2, formats)
405
suite = adapter.adapt(input_test)
406
tests = list(iter(suite))
407
self.assertEqual(2, len(tests))
408
self.assertEqual(tests[0].intertree_class, formats[0][0])
409
self.assertEqual(tests[0].workingtree_format, formats[0][1])
410
self.assertEqual(tests[0].workingtree_to_test_tree, formats[0][2])
411
self.assertEqual(tests[0].workingtree_format_to, formats[0][3])
412
self.assertEqual(tests[0].workingtree_to_test_tree_to, formats[0][4])
413
self.assertEqual(tests[0].transport_server, server1)
414
self.assertEqual(tests[0].transport_readonly_server, server2)
415
self.assertEqual(tests[1].intertree_class, formats[1][0])
416
self.assertEqual(tests[1].workingtree_format, formats[1][1])
417
self.assertEqual(tests[1].workingtree_to_test_tree, formats[1][2])
418
self.assertEqual(tests[1].workingtree_format_to, formats[1][3])
419
self.assertEqual(tests[1].workingtree_to_test_tree_to, formats[1][4])
420
self.assertEqual(tests[1].transport_server, server1)
421
self.assertEqual(tests[1].transport_readonly_server, server2)
423
class TestTestCaseWithTransport(TestCaseWithTransport):
424
"""Tests for the convenience functions TestCaseWithTransport introduces."""
426
def test_get_readonly_url_none(self):
427
from bzrlib.transport import get_transport
428
from bzrlib.transport.memory import MemoryServer
429
from bzrlib.transport.readonly import ReadonlyTransportDecorator
430
self.transport_server = MemoryServer
431
self.transport_readonly_server = None
432
# calling get_readonly_transport() constructs a decorator on the url
434
url = self.get_readonly_url()
435
url2 = self.get_readonly_url('foo/bar')
436
t = get_transport(url)
437
t2 = get_transport(url2)
438
self.failUnless(isinstance(t, ReadonlyTransportDecorator))
439
self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
440
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
442
def test_get_readonly_url_http(self):
443
from bzrlib.transport import get_transport
444
from bzrlib.transport.local import LocalRelpathServer
445
from bzrlib.transport.http import HttpServer, HttpTransportBase
446
self.transport_server = LocalRelpathServer
447
self.transport_readonly_server = HttpServer
448
# calling get_readonly_transport() gives us a HTTP server instance.
449
url = self.get_readonly_url()
450
url2 = self.get_readonly_url('foo/bar')
451
# the transport returned may be any HttpTransportBase subclass
452
t = get_transport(url)
453
t2 = get_transport(url2)
454
self.failUnless(isinstance(t, HttpTransportBase))
455
self.failUnless(isinstance(t2, HttpTransportBase))
456
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
458
def test_is_directory(self):
459
"""Test assertIsDirectory assertion"""
460
t = self.get_transport()
461
self.build_tree(['a_dir/', 'a_file'], transport=t)
462
self.assertIsDirectory('a_dir', t)
463
self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
464
self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
467
class TestChrootedTest(ChrootedTestCase):
469
def test_root_is_root(self):
470
from bzrlib.transport import get_transport
471
t = get_transport(self.get_readonly_url())
473
self.assertEqual(url, t.clone('..').base)
476
class MockProgress(_BaseProgressBar):
477
"""Progress-bar standin that records calls.
479
Useful for testing pb using code.
483
_BaseProgressBar.__init__(self)
487
self.calls.append(('tick',))
489
def update(self, msg=None, current=None, total=None):
490
self.calls.append(('update', msg, current, total))
493
self.calls.append(('clear',))
495
def note(self, msg, *args):
496
self.calls.append(('note', msg, args))
499
class TestTestResult(TestCase):
501
def test_progress_bar_style_quiet(self):
502
# test using a progress bar.
503
dummy_test = TestTestResult('test_progress_bar_style_quiet')
504
dummy_error = (Exception, None, [])
505
mypb = MockProgress()
506
mypb.update('Running tests', 0, 4)
507
last_calls = mypb.calls[:]
509
result = bzrlib.tests._MyResult(self._log_file,
513
self.assertEqual(last_calls, mypb.calls)
516
"""Shorten a string based on the terminal width"""
517
return result._ellipsise_unimportant_words(s,
518
osutils.terminal_width())
521
result.startTest(dummy_test)
522
# starting a test prints the test name
523
last_calls += [('update', '...tyle_quiet', 0, None)]
524
self.assertEqual(last_calls, mypb.calls)
525
result.addError(dummy_test, dummy_error)
526
last_calls += [('update', 'ERROR ', 1, None),
527
('note', shorten(dummy_test.id() + ': ERROR'), ())
529
self.assertEqual(last_calls, mypb.calls)
532
result.startTest(dummy_test)
533
last_calls += [('update', '...tyle_quiet', 1, None)]
534
self.assertEqual(last_calls, mypb.calls)
535
last_calls += [('update', 'FAIL ', 2, None),
536
('note', shorten(dummy_test.id() + ': FAIL'), ())
538
result.addFailure(dummy_test, dummy_error)
539
self.assertEqual(last_calls, mypb.calls)
542
result.startTest(dummy_test)
543
last_calls += [('update', '...tyle_quiet', 2, None)]
544
self.assertEqual(last_calls, mypb.calls)
545
result.addSuccess(dummy_test)
546
last_calls += [('update', 'OK ', 3, None)]
547
self.assertEqual(last_calls, mypb.calls)
550
result.startTest(dummy_test)
551
last_calls += [('update', '...tyle_quiet', 3, None)]
552
self.assertEqual(last_calls, mypb.calls)
553
result.addSkipped(dummy_test, dummy_error)
554
last_calls += [('update', 'SKIP ', 4, None)]
555
self.assertEqual(last_calls, mypb.calls)
557
def test_elapsed_time_with_benchmarking(self):
558
result = bzrlib.tests._MyResult(self._log_file,
562
result._recordTestStartTime()
564
result.extractBenchmarkTime(self)
565
timed_string = result._testTimeString()
566
# without explicit benchmarking, we should get a simple time.
567
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms$")
568
# if a benchmark time is given, we want a x of y style result.
569
self.time(time.sleep, 0.001)
570
result.extractBenchmarkTime(self)
571
timed_string = result._testTimeString()
572
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms/ [ 1-9][0-9]ms$")
573
# extracting the time from a non-bzrlib testcase sets to None
574
result._recordTestStartTime()
575
result.extractBenchmarkTime(
576
unittest.FunctionTestCase(self.test_elapsed_time_with_benchmarking))
577
timed_string = result._testTimeString()
578
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms$")
579
# cheat. Yes, wash thy mouth out with soap.
580
self._benchtime = None
582
def test_assigned_benchmark_file_stores_date(self):
584
result = bzrlib.tests._MyResult(self._log_file,
589
output_string = output.getvalue()
590
# if you are wondering about the regexp please read the comment in
591
# test_bench_history (bzrlib.tests.test_selftest.TestRunner)
592
# XXX: what comment? -- Andrew Bennetts
593
self.assertContainsRe(output_string, "--date [0-9.]+")
595
def test_benchhistory_records_test_times(self):
596
result_stream = StringIO()
597
result = bzrlib.tests._MyResult(
601
bench_history=result_stream
604
# we want profile a call and check that its test duration is recorded
605
# make a new test instance that when run will generate a benchmark
606
example_test_case = TestTestResult("_time_hello_world_encoding")
607
# execute the test, which should succeed and record times
608
example_test_case.run(result)
609
lines = result_stream.getvalue().splitlines()
610
self.assertEqual(2, len(lines))
611
self.assertContainsRe(lines[1],
612
" *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
613
"._time_hello_world_encoding")
615
def _time_hello_world_encoding(self):
616
"""Profile two sleep calls
618
This is used to exercise the test framework.
620
self.time(unicode, 'hello', errors='replace')
621
self.time(unicode, 'world', errors='replace')
623
def test_lsprofiling(self):
624
"""Verbose test result prints lsprof statistics from test cases."""
628
raise TestSkipped("lsprof not installed.")
629
result_stream = StringIO()
630
result = bzrlib.tests._MyResult(
631
unittest._WritelnDecorator(result_stream),
635
# we want profile a call of some sort and check it is output by
636
# addSuccess. We dont care about addError or addFailure as they
637
# are not that interesting for performance tuning.
638
# make a new test instance that when run will generate a profile
639
example_test_case = TestTestResult("_time_hello_world_encoding")
640
example_test_case._gather_lsprof_in_benchmarks = True
641
# execute the test, which should succeed and record profiles
642
example_test_case.run(result)
643
# lsprofile_something()
644
# if this worked we want
645
# LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
646
# CallCount Recursive Total(ms) Inline(ms) module:lineno(function)
647
# (the lsprof header)
648
# ... an arbitrary number of lines
649
# and the function call which is time.sleep.
650
# 1 0 ??? ??? ???(sleep)
651
# and then repeated but with 'world', rather than 'hello'.
652
# this should appear in the output stream of our test result.
653
output = result_stream.getvalue()
654
self.assertContainsRe(output,
655
r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
656
self.assertContainsRe(output,
657
r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
658
self.assertContainsRe(output,
659
r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
660
self.assertContainsRe(output,
661
r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
664
class TestRunner(TestCase):
666
def dummy_test(self):
669
def run_test_runner(self, testrunner, test):
670
"""Run suite in testrunner, saving global state and restoring it.
672
This current saves and restores:
673
TestCaseInTempDir.TEST_ROOT
675
There should be no tests in this file that use bzrlib.tests.TextTestRunner
676
without using this convenience method, because of our use of global state.
678
old_root = TestCaseInTempDir.TEST_ROOT
680
TestCaseInTempDir.TEST_ROOT = None
681
return testrunner.run(test)
683
TestCaseInTempDir.TEST_ROOT = old_root
685
def test_accepts_and_uses_pb_parameter(self):
686
test = TestRunner('dummy_test')
687
mypb = MockProgress()
688
self.assertEqual([], mypb.calls)
689
runner = TextTestRunner(stream=self._log_file, pb=mypb)
690
result = self.run_test_runner(runner, test)
691
self.assertEqual(1, result.testsRun)
692
self.assertEqual(('update', 'Running tests', 0, 1), mypb.calls[0])
693
self.assertEqual(('update', '...dummy_test', 0, None), mypb.calls[1])
694
self.assertEqual(('update', 'OK ', 1, None), mypb.calls[2])
695
self.assertEqual(('update', 'Cleaning up', 0, 1), mypb.calls[3])
696
self.assertEqual(('clear',), mypb.calls[4])
697
self.assertEqual(5, len(mypb.calls))
699
def test_skipped_test(self):
700
# run a test that is skipped, and check the suite as a whole still
702
# skipping_test must be hidden in here so it's not run as a real test
704
raise TestSkipped('test intentionally skipped')
705
runner = TextTestRunner(stream=self._log_file, keep_output=True)
706
test = unittest.FunctionTestCase(skipping_test)
707
result = self.run_test_runner(runner, test)
708
self.assertTrue(result.wasSuccessful())
710
def test_bench_history(self):
711
# tests that the running the benchmark produces a history file
712
# containing a timestamp and the revision id of the bzrlib source which
714
workingtree = _get_bzr_source_tree()
715
test = TestRunner('dummy_test')
717
runner = TextTestRunner(stream=self._log_file, bench_history=output)
718
result = self.run_test_runner(runner, test)
719
output_string = output.getvalue()
720
self.assertContainsRe(output_string, "--date [0-9.]+")
721
if workingtree is not None:
722
revision_id = workingtree.last_revision()
723
self.assertEndsWith(output_string.rstrip(), revision_id)
726
class TestTestCase(TestCase):
727
"""Tests that test the core bzrlib TestCase."""
729
def inner_test(self):
730
# the inner child test
733
def outer_child(self):
734
# the outer child test
736
self.inner_test = TestTestCase("inner_child")
737
result = bzrlib.tests._MyResult(self._log_file,
740
self.inner_test.run(result)
743
def test_trace_nesting(self):
744
# this tests that each test case nests its trace facility correctly.
745
# we do this by running a test case manually. That test case (A)
746
# should setup a new log, log content to it, setup a child case (B),
747
# which should log independently, then case (A) should log a trailer
749
# we do two nested children so that we can verify the state of the
750
# logs after the outer child finishes is correct, which a bad clean
751
# up routine in tearDown might trigger a fault in our test with only
752
# one child, we should instead see the bad result inside our test with
754
# the outer child test
755
original_trace = bzrlib.trace._trace_file
756
outer_test = TestTestCase("outer_child")
757
result = bzrlib.tests._MyResult(self._log_file,
760
outer_test.run(result)
761
self.assertEqual(original_trace, bzrlib.trace._trace_file)
763
def method_that_times_a_bit_twice(self):
764
# call self.time twice to ensure it aggregates
765
self.time(time.sleep, 0.007)
766
self.time(time.sleep, 0.007)
768
def test_time_creates_benchmark_in_result(self):
769
"""Test that the TestCase.time() method accumulates a benchmark time."""
770
sample_test = TestTestCase("method_that_times_a_bit_twice")
771
output_stream = StringIO()
772
result = bzrlib.tests._MyResult(
773
unittest._WritelnDecorator(output_stream),
776
sample_test.run(result)
777
self.assertContainsRe(
778
output_stream.getvalue(),
779
"[1-9][0-9]ms/ [1-9][0-9]ms\n$")
781
def test__gather_lsprof_in_benchmarks(self):
782
"""When _gather_lsprof_in_benchmarks is on, accumulate profile data.
784
Each self.time() call is individually and separately profiled.
789
raise TestSkipped("lsprof not installed.")
790
# overrides the class member with an instance member so no cleanup
792
self._gather_lsprof_in_benchmarks = True
793
self.time(time.sleep, 0.000)
794
self.time(time.sleep, 0.003)
795
self.assertEqual(2, len(self._benchcalls))
796
self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
797
self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
798
self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
799
self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
802
@symbol_versioning.deprecated_function(zero_eleven)
803
def sample_deprecated_function():
804
"""A deprecated function to test applyDeprecated with."""
808
def sample_undeprecated_function(a_param):
809
"""A undeprecated function to test applyDeprecated with."""
812
class ApplyDeprecatedHelper(object):
813
"""A helper class for ApplyDeprecated tests."""
815
@symbol_versioning.deprecated_method(zero_eleven)
816
def sample_deprecated_method(self, param_one):
817
"""A deprecated method for testing with."""
820
def sample_normal_method(self):
821
"""A undeprecated method."""
823
@symbol_versioning.deprecated_method(zero_ten)
824
def sample_nested_deprecation(self):
825
return sample_deprecated_function()
828
class TestExtraAssertions(TestCase):
829
"""Tests for new test assertions in bzrlib test suite"""
831
def test_assert_isinstance(self):
832
self.assertIsInstance(2, int)
833
self.assertIsInstance(u'', basestring)
834
self.assertRaises(AssertionError, self.assertIsInstance, None, int)
835
self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
837
def test_assertEndsWith(self):
838
self.assertEndsWith('foo', 'oo')
839
self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
841
def test_applyDeprecated_not_deprecated(self):
842
sample_object = ApplyDeprecatedHelper()
843
# calling an undeprecated callable raises an assertion
844
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
845
sample_object.sample_normal_method)
846
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
847
sample_undeprecated_function, "a param value")
848
# calling a deprecated callable (function or method) with the wrong
849
# expected deprecation fails.
850
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
851
sample_object.sample_deprecated_method, "a param value")
852
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
853
sample_deprecated_function)
854
# calling a deprecated callable (function or method) with the right
855
# expected deprecation returns the functions result.
856
self.assertEqual("a param value", self.applyDeprecated(zero_eleven,
857
sample_object.sample_deprecated_method, "a param value"))
858
self.assertEqual(2, self.applyDeprecated(zero_eleven,
859
sample_deprecated_function))
860
# calling a nested deprecation with the wrong deprecation version
861
# fails even if a deeper nested function was deprecated with the
863
self.assertRaises(AssertionError, self.applyDeprecated,
864
zero_eleven, sample_object.sample_nested_deprecation)
865
# calling a nested deprecation with the right deprecation value
866
# returns the calls result.
867
self.assertEqual(2, self.applyDeprecated(zero_ten,
868
sample_object.sample_nested_deprecation))
870
def test_callDeprecated(self):
871
def testfunc(be_deprecated, result=None):
872
if be_deprecated is True:
873
symbol_versioning.warn('i am deprecated', DeprecationWarning,
876
result = self.callDeprecated(['i am deprecated'], testfunc, True)
877
self.assertIs(None, result)
878
result = self.callDeprecated([], testfunc, False, 'result')
879
self.assertEqual('result', result)
880
self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
881
self.callDeprecated([], testfunc, be_deprecated=False)
884
class TestConvenienceMakers(TestCaseWithTransport):
885
"""Test for the make_* convenience functions."""
887
def test_make_branch_and_tree_with_format(self):
888
# we should be able to supply a format to make_branch_and_tree
889
self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
890
self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
891
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
892
bzrlib.bzrdir.BzrDirMetaFormat1)
893
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
894
bzrlib.bzrdir.BzrDirFormat6)
897
class TestSelftest(TestCase):
898
"""Tests of bzrlib.tests.selftest."""
900
def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
903
factory_called.append(True)
907
self.apply_redirected(out, err, None, bzrlib.tests.selftest,
908
test_suite_factory=factory)
909
self.assertEqual([True], factory_called)