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)
424
class TestTestCaseInTempDir(TestCaseInTempDir):
426
def test_home_is_not_working(self):
427
self.assertNotEqual(self.test_dir, self.test_home_dir)
428
cwd = osutils.getcwd()
429
self.assertEqual(self.test_dir, cwd)
430
self.assertEqual(self.test_home_dir, os.environ['HOME'])
433
class TestTestCaseWithTransport(TestCaseWithTransport):
434
"""Tests for the convenience functions TestCaseWithTransport introduces."""
436
def test_get_readonly_url_none(self):
437
from bzrlib.transport import get_transport
438
from bzrlib.transport.memory import MemoryServer
439
from bzrlib.transport.readonly import ReadonlyTransportDecorator
440
self.transport_server = MemoryServer
441
self.transport_readonly_server = None
442
# calling get_readonly_transport() constructs a decorator on the url
444
url = self.get_readonly_url()
445
url2 = self.get_readonly_url('foo/bar')
446
t = get_transport(url)
447
t2 = get_transport(url2)
448
self.failUnless(isinstance(t, ReadonlyTransportDecorator))
449
self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
450
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
452
def test_get_readonly_url_http(self):
453
from bzrlib.transport import get_transport
454
from bzrlib.transport.local import LocalRelpathServer
455
from bzrlib.transport.http import HttpServer, HttpTransportBase
456
self.transport_server = LocalRelpathServer
457
self.transport_readonly_server = HttpServer
458
# calling get_readonly_transport() gives us a HTTP server instance.
459
url = self.get_readonly_url()
460
url2 = self.get_readonly_url('foo/bar')
461
# the transport returned may be any HttpTransportBase subclass
462
t = get_transport(url)
463
t2 = get_transport(url2)
464
self.failUnless(isinstance(t, HttpTransportBase))
465
self.failUnless(isinstance(t2, HttpTransportBase))
466
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
468
def test_is_directory(self):
469
"""Test assertIsDirectory assertion"""
470
t = self.get_transport()
471
self.build_tree(['a_dir/', 'a_file'], transport=t)
472
self.assertIsDirectory('a_dir', t)
473
self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
474
self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
477
class TestChrootedTest(ChrootedTestCase):
479
def test_root_is_root(self):
480
from bzrlib.transport import get_transport
481
t = get_transport(self.get_readonly_url())
483
self.assertEqual(url, t.clone('..').base)
486
class MockProgress(_BaseProgressBar):
487
"""Progress-bar standin that records calls.
489
Useful for testing pb using code.
493
_BaseProgressBar.__init__(self)
497
self.calls.append(('tick',))
499
def update(self, msg=None, current=None, total=None):
500
self.calls.append(('update', msg, current, total))
503
self.calls.append(('clear',))
505
def note(self, msg, *args):
506
self.calls.append(('note', msg, args))
509
class TestTestResult(TestCase):
511
def test_progress_bar_style_quiet(self):
512
# test using a progress bar.
513
dummy_test = TestTestResult('test_progress_bar_style_quiet')
514
dummy_error = (Exception, None, [])
515
mypb = MockProgress()
516
mypb.update('Running tests', 0, 4)
517
last_calls = mypb.calls[:]
519
result = bzrlib.tests._MyResult(self._log_file,
523
self.assertEqual(last_calls, mypb.calls)
526
"""Shorten a string based on the terminal width"""
527
return result._ellipsise_unimportant_words(s,
528
osutils.terminal_width())
531
result.startTest(dummy_test)
532
# starting a test prints the test name
533
last_calls += [('update', '...tyle_quiet', 0, None)]
534
self.assertEqual(last_calls, mypb.calls)
535
result.addError(dummy_test, dummy_error)
536
last_calls += [('update', 'ERROR ', 1, None),
537
('note', shorten(dummy_test.id() + ': ERROR'), ())
539
self.assertEqual(last_calls, mypb.calls)
542
result.startTest(dummy_test)
543
last_calls += [('update', '...tyle_quiet', 1, None)]
544
self.assertEqual(last_calls, mypb.calls)
545
last_calls += [('update', 'FAIL ', 2, None),
546
('note', shorten(dummy_test.id() + ': FAIL'), ())
548
result.addFailure(dummy_test, dummy_error)
549
self.assertEqual(last_calls, mypb.calls)
552
result.startTest(dummy_test)
553
last_calls += [('update', '...tyle_quiet', 2, None)]
554
self.assertEqual(last_calls, mypb.calls)
555
result.addSuccess(dummy_test)
556
last_calls += [('update', 'OK ', 3, None)]
557
self.assertEqual(last_calls, mypb.calls)
560
result.startTest(dummy_test)
561
last_calls += [('update', '...tyle_quiet', 3, None)]
562
self.assertEqual(last_calls, mypb.calls)
563
result.addSkipped(dummy_test, dummy_error)
564
last_calls += [('update', 'SKIP ', 4, None)]
565
self.assertEqual(last_calls, mypb.calls)
567
def test_elapsed_time_with_benchmarking(self):
568
result = bzrlib.tests._MyResult(self._log_file,
572
result._recordTestStartTime()
574
result.extractBenchmarkTime(self)
575
timed_string = result._testTimeString()
576
# without explicit benchmarking, we should get a simple time.
577
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms$")
578
# if a benchmark time is given, we want a x of y style result.
579
self.time(time.sleep, 0.001)
580
result.extractBenchmarkTime(self)
581
timed_string = result._testTimeString()
582
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms/ [ 1-9][0-9]ms$")
583
# extracting the time from a non-bzrlib testcase sets to None
584
result._recordTestStartTime()
585
result.extractBenchmarkTime(
586
unittest.FunctionTestCase(self.test_elapsed_time_with_benchmarking))
587
timed_string = result._testTimeString()
588
self.assertContainsRe(timed_string, "^ [ 1-9][0-9]ms$")
589
# cheat. Yes, wash thy mouth out with soap.
590
self._benchtime = None
592
def test_assigned_benchmark_file_stores_date(self):
594
result = bzrlib.tests._MyResult(self._log_file,
599
output_string = output.getvalue()
600
# if you are wondering about the regexp please read the comment in
601
# test_bench_history (bzrlib.tests.test_selftest.TestRunner)
602
# XXX: what comment? -- Andrew Bennetts
603
self.assertContainsRe(output_string, "--date [0-9.]+")
605
def test_benchhistory_records_test_times(self):
606
result_stream = StringIO()
607
result = bzrlib.tests._MyResult(
611
bench_history=result_stream
614
# we want profile a call and check that its test duration is recorded
615
# make a new test instance that when run will generate a benchmark
616
example_test_case = TestTestResult("_time_hello_world_encoding")
617
# execute the test, which should succeed and record times
618
example_test_case.run(result)
619
lines = result_stream.getvalue().splitlines()
620
self.assertEqual(2, len(lines))
621
self.assertContainsRe(lines[1],
622
" *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
623
"._time_hello_world_encoding")
625
def _time_hello_world_encoding(self):
626
"""Profile two sleep calls
628
This is used to exercise the test framework.
630
self.time(unicode, 'hello', errors='replace')
631
self.time(unicode, 'world', errors='replace')
633
def test_lsprofiling(self):
634
"""Verbose test result prints lsprof statistics from test cases."""
638
raise TestSkipped("lsprof not installed.")
639
result_stream = StringIO()
640
result = bzrlib.tests._MyResult(
641
unittest._WritelnDecorator(result_stream),
645
# we want profile a call of some sort and check it is output by
646
# addSuccess. We dont care about addError or addFailure as they
647
# are not that interesting for performance tuning.
648
# make a new test instance that when run will generate a profile
649
example_test_case = TestTestResult("_time_hello_world_encoding")
650
example_test_case._gather_lsprof_in_benchmarks = True
651
# execute the test, which should succeed and record profiles
652
example_test_case.run(result)
653
# lsprofile_something()
654
# if this worked we want
655
# LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
656
# CallCount Recursive Total(ms) Inline(ms) module:lineno(function)
657
# (the lsprof header)
658
# ... an arbitrary number of lines
659
# and the function call which is time.sleep.
660
# 1 0 ??? ??? ???(sleep)
661
# and then repeated but with 'world', rather than 'hello'.
662
# this should appear in the output stream of our test result.
663
output = result_stream.getvalue()
664
self.assertContainsRe(output,
665
r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
666
self.assertContainsRe(output,
667
r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
668
self.assertContainsRe(output,
669
r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
670
self.assertContainsRe(output,
671
r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
674
class TestRunner(TestCase):
676
def dummy_test(self):
679
def run_test_runner(self, testrunner, test):
680
"""Run suite in testrunner, saving global state and restoring it.
682
This current saves and restores:
683
TestCaseInTempDir.TEST_ROOT
685
There should be no tests in this file that use bzrlib.tests.TextTestRunner
686
without using this convenience method, because of our use of global state.
688
old_root = TestCaseInTempDir.TEST_ROOT
690
TestCaseInTempDir.TEST_ROOT = None
691
return testrunner.run(test)
693
TestCaseInTempDir.TEST_ROOT = old_root
695
def test_accepts_and_uses_pb_parameter(self):
696
test = TestRunner('dummy_test')
697
mypb = MockProgress()
698
self.assertEqual([], mypb.calls)
699
runner = TextTestRunner(stream=self._log_file, pb=mypb)
700
result = self.run_test_runner(runner, test)
701
self.assertEqual(1, result.testsRun)
702
self.assertEqual(('update', 'Running tests', 0, 1), mypb.calls[0])
703
self.assertEqual(('update', '...dummy_test', 0, None), mypb.calls[1])
704
self.assertEqual(('update', 'OK ', 1, None), mypb.calls[2])
705
self.assertEqual(('update', 'Cleaning up', 0, 1), mypb.calls[3])
706
self.assertEqual(('clear',), mypb.calls[4])
707
self.assertEqual(5, len(mypb.calls))
709
def test_skipped_test(self):
710
# run a test that is skipped, and check the suite as a whole still
712
# skipping_test must be hidden in here so it's not run as a real test
714
raise TestSkipped('test intentionally skipped')
715
runner = TextTestRunner(stream=self._log_file, keep_output=True)
716
test = unittest.FunctionTestCase(skipping_test)
717
result = self.run_test_runner(runner, test)
718
self.assertTrue(result.wasSuccessful())
720
def test_bench_history(self):
721
# tests that the running the benchmark produces a history file
722
# containing a timestamp and the revision id of the bzrlib source which
724
workingtree = _get_bzr_source_tree()
725
test = TestRunner('dummy_test')
727
runner = TextTestRunner(stream=self._log_file, bench_history=output)
728
result = self.run_test_runner(runner, test)
729
output_string = output.getvalue()
730
self.assertContainsRe(output_string, "--date [0-9.]+")
731
if workingtree is not None:
732
revision_id = workingtree.get_parent_ids()[0]
733
self.assertEndsWith(output_string.rstrip(), revision_id)
736
class TestTestCase(TestCase):
737
"""Tests that test the core bzrlib TestCase."""
739
def inner_test(self):
740
# the inner child test
743
def outer_child(self):
744
# the outer child test
746
self.inner_test = TestTestCase("inner_child")
747
result = bzrlib.tests._MyResult(self._log_file,
750
self.inner_test.run(result)
753
def test_trace_nesting(self):
754
# this tests that each test case nests its trace facility correctly.
755
# we do this by running a test case manually. That test case (A)
756
# should setup a new log, log content to it, setup a child case (B),
757
# which should log independently, then case (A) should log a trailer
759
# we do two nested children so that we can verify the state of the
760
# logs after the outer child finishes is correct, which a bad clean
761
# up routine in tearDown might trigger a fault in our test with only
762
# one child, we should instead see the bad result inside our test with
764
# the outer child test
765
original_trace = bzrlib.trace._trace_file
766
outer_test = TestTestCase("outer_child")
767
result = bzrlib.tests._MyResult(self._log_file,
770
outer_test.run(result)
771
self.assertEqual(original_trace, bzrlib.trace._trace_file)
773
def method_that_times_a_bit_twice(self):
774
# call self.time twice to ensure it aggregates
775
self.time(time.sleep, 0.007)
776
self.time(time.sleep, 0.007)
778
def test_time_creates_benchmark_in_result(self):
779
"""Test that the TestCase.time() method accumulates a benchmark time."""
780
sample_test = TestTestCase("method_that_times_a_bit_twice")
781
output_stream = StringIO()
782
result = bzrlib.tests._MyResult(
783
unittest._WritelnDecorator(output_stream),
786
sample_test.run(result)
787
self.assertContainsRe(
788
output_stream.getvalue(),
789
"[1-9][0-9]ms/ [1-9][0-9]ms\n$")
791
def test__gather_lsprof_in_benchmarks(self):
792
"""When _gather_lsprof_in_benchmarks is on, accumulate profile data.
794
Each self.time() call is individually and separately profiled.
799
raise TestSkipped("lsprof not installed.")
800
# overrides the class member with an instance member so no cleanup
802
self._gather_lsprof_in_benchmarks = True
803
self.time(time.sleep, 0.000)
804
self.time(time.sleep, 0.003)
805
self.assertEqual(2, len(self._benchcalls))
806
self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
807
self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
808
self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
809
self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
812
@symbol_versioning.deprecated_function(zero_eleven)
813
def sample_deprecated_function():
814
"""A deprecated function to test applyDeprecated with."""
818
def sample_undeprecated_function(a_param):
819
"""A undeprecated function to test applyDeprecated with."""
822
class ApplyDeprecatedHelper(object):
823
"""A helper class for ApplyDeprecated tests."""
825
@symbol_versioning.deprecated_method(zero_eleven)
826
def sample_deprecated_method(self, param_one):
827
"""A deprecated method for testing with."""
830
def sample_normal_method(self):
831
"""A undeprecated method."""
833
@symbol_versioning.deprecated_method(zero_ten)
834
def sample_nested_deprecation(self):
835
return sample_deprecated_function()
838
class TestExtraAssertions(TestCase):
839
"""Tests for new test assertions in bzrlib test suite"""
841
def test_assert_isinstance(self):
842
self.assertIsInstance(2, int)
843
self.assertIsInstance(u'', basestring)
844
self.assertRaises(AssertionError, self.assertIsInstance, None, int)
845
self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
847
def test_assertEndsWith(self):
848
self.assertEndsWith('foo', 'oo')
849
self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
851
def test_applyDeprecated_not_deprecated(self):
852
sample_object = ApplyDeprecatedHelper()
853
# calling an undeprecated callable raises an assertion
854
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
855
sample_object.sample_normal_method)
856
self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
857
sample_undeprecated_function, "a param value")
858
# calling a deprecated callable (function or method) with the wrong
859
# expected deprecation fails.
860
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
861
sample_object.sample_deprecated_method, "a param value")
862
self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
863
sample_deprecated_function)
864
# calling a deprecated callable (function or method) with the right
865
# expected deprecation returns the functions result.
866
self.assertEqual("a param value", self.applyDeprecated(zero_eleven,
867
sample_object.sample_deprecated_method, "a param value"))
868
self.assertEqual(2, self.applyDeprecated(zero_eleven,
869
sample_deprecated_function))
870
# calling a nested deprecation with the wrong deprecation version
871
# fails even if a deeper nested function was deprecated with the
873
self.assertRaises(AssertionError, self.applyDeprecated,
874
zero_eleven, sample_object.sample_nested_deprecation)
875
# calling a nested deprecation with the right deprecation value
876
# returns the calls result.
877
self.assertEqual(2, self.applyDeprecated(zero_ten,
878
sample_object.sample_nested_deprecation))
880
def test_callDeprecated(self):
881
def testfunc(be_deprecated, result=None):
882
if be_deprecated is True:
883
symbol_versioning.warn('i am deprecated', DeprecationWarning,
886
result = self.callDeprecated(['i am deprecated'], testfunc, True)
887
self.assertIs(None, result)
888
result = self.callDeprecated([], testfunc, False, 'result')
889
self.assertEqual('result', result)
890
self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
891
self.callDeprecated([], testfunc, be_deprecated=False)
894
class TestConvenienceMakers(TestCaseWithTransport):
895
"""Test for the make_* convenience functions."""
897
def test_make_branch_and_tree_with_format(self):
898
# we should be able to supply a format to make_branch_and_tree
899
self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
900
self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
901
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
902
bzrlib.bzrdir.BzrDirMetaFormat1)
903
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
904
bzrlib.bzrdir.BzrDirFormat6)
907
class TestSelftest(TestCase):
908
"""Tests of bzrlib.tests.selftest."""
910
def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
913
factory_called.append(True)
917
self.apply_redirected(out, err, None, bzrlib.tests.selftest,
918
test_suite_factory=factory)
919
self.assertEqual([True], factory_called)