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."""
24
from bzrlib.progress import _BaseProgressBar
25
from bzrlib.tests import (
30
TestCaseWithTransport,
34
import bzrlib.errors as errors
37
class SelftestTests(TestCase):
39
def test_import_tests(self):
40
mod = _load_module_by_name('bzrlib.tests.test_selftest')
41
self.assertEqual(mod.SelftestTests, SelftestTests)
43
def test_import_test_failure(self):
44
self.assertRaises(ImportError,
49
class MetaTestLog(TestCase):
51
def test_logging(self):
52
"""Test logs are captured when a test fails."""
53
self.log('a test message')
54
self._log_file.flush()
55
self.assertContainsRe(self._get_log(), 'a test message\n')
58
class TestTreeShape(TestCaseInTempDir):
60
def test_unicode_paths(self):
61
filename = u'hell\u00d8'
63
self.build_tree_contents([(filename, 'contents of hello')])
64
except UnicodeEncodeError:
65
raise TestSkipped("can't build unicode working tree in "
66
"filesystem encoding %s" % sys.getfilesystemencoding())
67
self.failUnlessExists(filename)
70
class TestTransportProviderAdapter(TestCase):
71
"""A group of tests that test the transport implementation adaption core.
73
This is a meta test that the tests are applied to all available
76
This will be generalised in the future which is why it is in this
77
test file even though it is specific to transport tests at the moment.
80
def test_get_transport_permutations(self):
81
# this checks that we the module get_test_permutations call
82
# is made by the adapter get_transport_test_permitations method.
83
class MockModule(object):
84
def get_test_permutations(self):
85
return sample_permutation
86
sample_permutation = [(1,2), (3,4)]
87
from bzrlib.transport import TransportTestProviderAdapter
88
adapter = TransportTestProviderAdapter()
89
self.assertEqual(sample_permutation,
90
adapter.get_transport_test_permutations(MockModule()))
92
def test_adapter_checks_all_modules(self):
93
# this checks that the adapter returns as many permurtations as
94
# there are in all the registered# transport modules for there
95
# - we assume if this matches its probably doing the right thing
96
# especially in combination with the tests for setting the right
98
from bzrlib.transport import (TransportTestProviderAdapter,
99
_get_transport_modules
101
modules = _get_transport_modules()
102
permutation_count = 0
103
for module in modules:
105
permutation_count += len(reduce(getattr,
106
(module + ".get_test_permutations").split('.')[1:],
107
__import__(module))())
108
except errors.DependencyNotPresent:
110
input_test = TestTransportProviderAdapter(
111
"test_adapter_sets_transport_class")
112
adapter = TransportTestProviderAdapter()
113
self.assertEqual(permutation_count,
114
len(list(iter(adapter.adapt(input_test)))))
116
def test_adapter_sets_transport_class(self):
117
# Check that the test adapter inserts a transport and server into the
120
# This test used to know about all the possible transports and the
121
# order they were returned but that seems overly brittle (mbp
123
input_test = TestTransportProviderAdapter(
124
"test_adapter_sets_transport_class")
125
from bzrlib.transport import TransportTestProviderAdapter
126
suite = TransportTestProviderAdapter().adapt(input_test)
127
tests = list(iter(suite))
128
self.assertTrue(len(tests) > 6)
129
# there are at least that many builtin transports
131
self.assertTrue(issubclass(one_test.transport_class,
132
bzrlib.transport.Transport))
133
self.assertTrue(issubclass(one_test.transport_server,
134
bzrlib.transport.Server))
137
class TestBranchProviderAdapter(TestCase):
138
"""A group of tests that test the branch implementation test adapter."""
140
def test_adapted_tests(self):
141
# check that constructor parameters are passed through to the adapted
143
from bzrlib.branch import BranchTestProviderAdapter
144
input_test = TestBranchProviderAdapter(
145
"test_adapted_tests")
148
formats = [("c", "C"), ("d", "D")]
149
adapter = BranchTestProviderAdapter(server1, server2, formats)
150
suite = adapter.adapt(input_test)
151
tests = list(iter(suite))
152
self.assertEqual(2, len(tests))
153
self.assertEqual(tests[0].branch_format, formats[0][0])
154
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
155
self.assertEqual(tests[0].transport_server, server1)
156
self.assertEqual(tests[0].transport_readonly_server, server2)
157
self.assertEqual(tests[1].branch_format, formats[1][0])
158
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
159
self.assertEqual(tests[1].transport_server, server1)
160
self.assertEqual(tests[1].transport_readonly_server, server2)
163
class TestBzrDirProviderAdapter(TestCase):
164
"""A group of tests that test the bzr dir implementation test adapter."""
166
def test_adapted_tests(self):
167
# check that constructor parameters are passed through to the adapted
169
from bzrlib.bzrdir import BzrDirTestProviderAdapter
170
input_test = TestBzrDirProviderAdapter(
171
"test_adapted_tests")
175
adapter = BzrDirTestProviderAdapter(server1, server2, formats)
176
suite = adapter.adapt(input_test)
177
tests = list(iter(suite))
178
self.assertEqual(2, len(tests))
179
self.assertEqual(tests[0].bzrdir_format, formats[0])
180
self.assertEqual(tests[0].transport_server, server1)
181
self.assertEqual(tests[0].transport_readonly_server, server2)
182
self.assertEqual(tests[1].bzrdir_format, formats[1])
183
self.assertEqual(tests[1].transport_server, server1)
184
self.assertEqual(tests[1].transport_readonly_server, server2)
187
class TestRepositoryProviderAdapter(TestCase):
188
"""A group of tests that test the repository implementation test adapter."""
190
def test_adapted_tests(self):
191
# check that constructor parameters are passed through to the adapted
193
from bzrlib.repository import RepositoryTestProviderAdapter
194
input_test = TestRepositoryProviderAdapter(
195
"test_adapted_tests")
198
formats = [("c", "C"), ("d", "D")]
199
adapter = RepositoryTestProviderAdapter(server1, server2, formats)
200
suite = adapter.adapt(input_test)
201
tests = list(iter(suite))
202
self.assertEqual(2, len(tests))
203
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
204
self.assertEqual(tests[0].repository_format, formats[0][0])
205
self.assertEqual(tests[0].transport_server, server1)
206
self.assertEqual(tests[0].transport_readonly_server, server2)
207
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
208
self.assertEqual(tests[1].repository_format, formats[1][0])
209
self.assertEqual(tests[1].transport_server, server1)
210
self.assertEqual(tests[1].transport_readonly_server, server2)
213
class TestInterRepositoryProviderAdapter(TestCase):
214
"""A group of tests that test the InterRepository test adapter."""
216
def test_adapted_tests(self):
217
# check that constructor parameters are passed through to the adapted
219
from bzrlib.repository import InterRepositoryTestProviderAdapter
220
input_test = TestInterRepositoryProviderAdapter(
221
"test_adapted_tests")
224
formats = [(str, "C1", "C2"), (int, "D1", "D2")]
225
adapter = InterRepositoryTestProviderAdapter(server1, server2, formats)
226
suite = adapter.adapt(input_test)
227
tests = list(iter(suite))
228
self.assertEqual(2, len(tests))
229
self.assertEqual(tests[0].interrepo_class, formats[0][0])
230
self.assertEqual(tests[0].repository_format, formats[0][1])
231
self.assertEqual(tests[0].repository_format_to, formats[0][2])
232
self.assertEqual(tests[0].transport_server, server1)
233
self.assertEqual(tests[0].transport_readonly_server, server2)
234
self.assertEqual(tests[1].interrepo_class, formats[1][0])
235
self.assertEqual(tests[1].repository_format, formats[1][1])
236
self.assertEqual(tests[1].repository_format_to, formats[1][2])
237
self.assertEqual(tests[1].transport_server, server1)
238
self.assertEqual(tests[1].transport_readonly_server, server2)
241
class TestInterVersionedFileProviderAdapter(TestCase):
242
"""A group of tests that test the InterVersionedFile test adapter."""
244
def test_adapted_tests(self):
245
# check that constructor parameters are passed through to the adapted
247
from bzrlib.versionedfile import InterVersionedFileTestProviderAdapter
248
input_test = TestInterRepositoryProviderAdapter(
249
"test_adapted_tests")
252
formats = [(str, "C1", "C2"), (int, "D1", "D2")]
253
adapter = InterVersionedFileTestProviderAdapter(server1, server2, formats)
254
suite = adapter.adapt(input_test)
255
tests = list(iter(suite))
256
self.assertEqual(2, len(tests))
257
self.assertEqual(tests[0].interversionedfile_class, formats[0][0])
258
self.assertEqual(tests[0].versionedfile_factory, formats[0][1])
259
self.assertEqual(tests[0].versionedfile_factory_to, formats[0][2])
260
self.assertEqual(tests[0].transport_server, server1)
261
self.assertEqual(tests[0].transport_readonly_server, server2)
262
self.assertEqual(tests[1].interversionedfile_class, formats[1][0])
263
self.assertEqual(tests[1].versionedfile_factory, formats[1][1])
264
self.assertEqual(tests[1].versionedfile_factory_to, formats[1][2])
265
self.assertEqual(tests[1].transport_server, server1)
266
self.assertEqual(tests[1].transport_readonly_server, server2)
269
class TestRevisionStoreProviderAdapter(TestCase):
270
"""A group of tests that test the RevisionStore test adapter."""
272
def test_adapted_tests(self):
273
# check that constructor parameters are passed through to the adapted
275
from bzrlib.store.revision import RevisionStoreTestProviderAdapter
276
input_test = TestRevisionStoreProviderAdapter(
277
"test_adapted_tests")
278
# revision stores need a store factory - i.e. RevisionKnit
279
#, a readonly and rw transport
283
store_factories = ["c", "d"]
284
adapter = RevisionStoreTestProviderAdapter(server1, server2, store_factories)
285
suite = adapter.adapt(input_test)
286
tests = list(iter(suite))
287
self.assertEqual(2, len(tests))
288
self.assertEqual(tests[0].store_factory, store_factories[0][0])
289
self.assertEqual(tests[0].transport_server, server1)
290
self.assertEqual(tests[0].transport_readonly_server, server2)
291
self.assertEqual(tests[1].store_factory, store_factories[1][0])
292
self.assertEqual(tests[1].transport_server, server1)
293
self.assertEqual(tests[1].transport_readonly_server, server2)
296
class TestWorkingTreeProviderAdapter(TestCase):
297
"""A group of tests that test the workingtree implementation test adapter."""
299
def test_adapted_tests(self):
300
# check that constructor parameters are passed through to the adapted
302
from bzrlib.workingtree import WorkingTreeTestProviderAdapter
303
input_test = TestWorkingTreeProviderAdapter(
304
"test_adapted_tests")
307
formats = [("c", "C"), ("d", "D")]
308
adapter = WorkingTreeTestProviderAdapter(server1, server2, formats)
309
suite = adapter.adapt(input_test)
310
tests = list(iter(suite))
311
self.assertEqual(2, len(tests))
312
self.assertEqual(tests[0].workingtree_format, formats[0][0])
313
self.assertEqual(tests[0].bzrdir_format, formats[0][1])
314
self.assertEqual(tests[0].transport_server, server1)
315
self.assertEqual(tests[0].transport_readonly_server, server2)
316
self.assertEqual(tests[1].workingtree_format, formats[1][0])
317
self.assertEqual(tests[1].bzrdir_format, formats[1][1])
318
self.assertEqual(tests[1].transport_server, server1)
319
self.assertEqual(tests[1].transport_readonly_server, server2)
322
class TestTestCaseWithTransport(TestCaseWithTransport):
323
"""Tests for the convenience functions TestCaseWithTransport introduces."""
325
def test_get_readonly_url_none(self):
326
from bzrlib.transport import get_transport
327
from bzrlib.transport.memory import MemoryServer
328
from bzrlib.transport.readonly import ReadonlyTransportDecorator
329
self.transport_server = MemoryServer
330
self.transport_readonly_server = None
331
# calling get_readonly_transport() constructs a decorator on the url
333
url = self.get_readonly_url()
334
url2 = self.get_readonly_url('foo/bar')
335
t = get_transport(url)
336
t2 = get_transport(url2)
337
self.failUnless(isinstance(t, ReadonlyTransportDecorator))
338
self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
339
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
341
def test_get_readonly_url_http(self):
342
from bzrlib.transport import get_transport
343
from bzrlib.transport.local import LocalRelpathServer
344
from bzrlib.transport.http import HttpServer, HttpTransportBase
345
self.transport_server = LocalRelpathServer
346
self.transport_readonly_server = HttpServer
347
# calling get_readonly_transport() gives us a HTTP server instance.
348
url = self.get_readonly_url()
349
url2 = self.get_readonly_url('foo/bar')
350
# the transport returned may be any HttpTransportBase subclass
351
t = get_transport(url)
352
t2 = get_transport(url2)
353
self.failUnless(isinstance(t, HttpTransportBase))
354
self.failUnless(isinstance(t2, HttpTransportBase))
355
self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
357
def test_is_directory(self):
358
"""Test assertIsDirectory assertion"""
359
t = self.get_transport()
360
self.build_tree(['a_dir/', 'a_file'], transport=t)
361
self.assertIsDirectory('a_dir', t)
362
self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
363
self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
366
class TestChrootedTest(ChrootedTestCase):
368
def test_root_is_root(self):
369
from bzrlib.transport import get_transport
370
t = get_transport(self.get_readonly_url())
372
self.assertEqual(url, t.clone('..').base)
375
class MockProgress(_BaseProgressBar):
376
"""Progress-bar standin that records calls.
378
Useful for testing pb using code.
382
_BaseProgressBar.__init__(self)
386
self.calls.append(('tick',))
388
def update(self, msg=None, current=None, total=None):
389
self.calls.append(('update', msg, current, total))
392
self.calls.append(('clear',))
395
class TestResult(TestCase):
397
def test_progress_bar_style_quiet(self):
398
# test using a progress bar.
399
dummy_test = TestResult('test_progress_bar_style_quiet')
400
dummy_error = (Exception, None, [])
401
mypb = MockProgress()
402
mypb.update('Running tests', 0, 4)
403
last_calls = mypb.calls[:]
404
result = bzrlib.tests._MyResult(self._log_file,
408
self.assertEqual(last_calls, mypb.calls)
411
result.startTest(dummy_test)
412
# starting a test prints the test name
413
self.assertEqual(last_calls + [('update', '...tyle_quiet', 0, None)], mypb.calls)
414
last_calls = mypb.calls[:]
415
result.addError(dummy_test, dummy_error)
416
self.assertEqual(last_calls + [('update', 'ERROR ', 1, None)], mypb.calls)
417
last_calls = mypb.calls[:]
420
result.startTest(dummy_test)
421
self.assertEqual(last_calls + [('update', '...tyle_quiet', 1, None)], mypb.calls)
422
last_calls = mypb.calls[:]
423
result.addFailure(dummy_test, dummy_error)
424
self.assertEqual(last_calls + [('update', 'FAIL ', 2, None)], mypb.calls)
425
last_calls = mypb.calls[:]
428
result.startTest(dummy_test)
429
self.assertEqual(last_calls + [('update', '...tyle_quiet', 2, None)], mypb.calls)
430
last_calls = mypb.calls[:]
431
result.addSuccess(dummy_test)
432
self.assertEqual(last_calls + [('update', 'OK ', 3, None)], mypb.calls)
433
last_calls = mypb.calls[:]
436
result.startTest(dummy_test)
437
self.assertEqual(last_calls + [('update', '...tyle_quiet', 3, None)], mypb.calls)
438
last_calls = mypb.calls[:]
439
result.addSkipped(dummy_test, dummy_error)
440
self.assertEqual(last_calls + [('update', 'SKIP ', 4, None)], mypb.calls)
441
last_calls = mypb.calls[:]
444
class TestRunner(TestCase):
446
def dummy_test(self):
449
def run_test_runner(self, testrunner, test):
450
"""Run suite in testrunner, saving global state and restoring it.
452
This current saves and restores:
453
TestCaseInTempDir.TEST_ROOT
455
There should be no tests in this file that use bzrlib.tests.TextTestRunner
456
without using this convenience method, because of our use of global state.
458
old_root = TestCaseInTempDir.TEST_ROOT
460
TestCaseInTempDir.TEST_ROOT = None
461
return testrunner.run(test)
463
TestCaseInTempDir.TEST_ROOT = old_root
465
def test_accepts_and_uses_pb_parameter(self):
466
test = TestRunner('dummy_test')
467
mypb = MockProgress()
468
self.assertEqual([], mypb.calls)
469
runner = TextTestRunner(stream=self._log_file, pb=mypb)
470
result = self.run_test_runner(runner, test)
471
self.assertEqual(1, result.testsRun)
472
self.assertEqual(('update', 'Running tests', 0, 1), mypb.calls[0])
473
self.assertEqual(('update', '...dummy_test', 0, None), mypb.calls[1])
474
self.assertEqual(('update', 'OK ', 1, None), mypb.calls[2])
475
self.assertEqual(('update', 'Cleaning up', 0, 1), mypb.calls[3])
476
self.assertEqual(('clear',), mypb.calls[4])
477
self.assertEqual(5, len(mypb.calls))
479
def test_skipped_test(self):
480
# run a test that is skipped, and check the suite as a whole still
482
# skipping_test must be hidden in here so it's not run as a real test
484
raise TestSkipped('test intentionally skipped')
485
runner = TextTestRunner(stream=self._log_file, keep_output=True)
486
test = unittest.FunctionTestCase(skipping_test)
487
result = self.run_test_runner(runner, test)
488
self.assertTrue(result.wasSuccessful())
491
class TestTestCase(TestCase):
492
"""Tests that test the core bzrlib TestCase."""
494
def inner_test(self):
495
# the inner child test
498
def outer_child(self):
499
# the outer child test
501
self.inner_test = TestTestCase("inner_child")
502
result = bzrlib.tests._MyResult(self._log_file,
505
self.inner_test.run(result)
508
def test_trace_nesting(self):
509
# this tests that each test case nests its trace facility correctly.
510
# we do this by running a test case manually. That test case (A)
511
# should setup a new log, log content to it, setup a child case (B),
512
# which should log independently, then case (A) should log a trailer
514
# we do two nested children so that we can verify the state of the
515
# logs after the outer child finishes is correct, which a bad clean
516
# up routine in tearDown might trigger a fault in our test with only
517
# one child, we should instead see the bad result inside our test with
519
# the outer child test
520
original_trace = bzrlib.trace._trace_file
521
outer_test = TestTestCase("outer_child")
522
result = bzrlib.tests._MyResult(self._log_file,
525
outer_test.run(result)
526
self.assertEqual(original_trace, bzrlib.trace._trace_file)
529
class TestExtraAssertions(TestCase):
530
"""Tests for new test assertions in bzrlib test suite"""
532
def test_assert_isinstance(self):
533
self.assertIsInstance(2, int)
534
self.assertIsInstance(u'', basestring)
535
self.assertRaises(AssertionError, self.assertIsInstance, None, int)
536
self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
538
def test_assertEndsWith(self):
539
self.assertEndsWith('foo', 'oo')
540
self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
543
class TestConvenienceMakers(TestCaseWithTransport):
544
"""Test for the make_* convenience functions."""
546
def test_make_branch_and_tree_with_format(self):
547
# we should be able to supply a format to make_branch_and_tree
548
self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
549
self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
550
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
551
bzrlib.bzrdir.BzrDirMetaFormat1)
552
self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
553
bzrlib.bzrdir.BzrDirFormat6)