~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

  • Committer: Robert Collins
  • Date: 2006-09-15 02:03:15 UTC
  • mto: (2017.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 2018.
  • Revision ID: robertc@robertcollins.net-20060915020315-9a4b022a6db42940
Update to bzr.dev, which involves adding lock_tree_write to MutableTree and MemoryTree.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006 by Canonical Ltd
 
2
#
 
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.
 
6
#
 
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.
 
11
#
 
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
 
15
 
 
16
"""Tests for the test framework."""
 
17
 
 
18
import os
 
19
from StringIO import StringIO
 
20
import sys
 
21
import time
 
22
import unittest
 
23
import warnings
 
24
 
 
25
from bzrlib import osutils
 
26
import bzrlib
 
27
from bzrlib.progress import _BaseProgressBar
 
28
from bzrlib.tests import (
 
29
                          ChrootedTestCase,
 
30
                          TestCase,
 
31
                          TestCaseInTempDir,
 
32
                          TestCaseWithTransport,
 
33
                          TestSkipped,
 
34
                          TestSuite,
 
35
                          TextTestRunner,
 
36
                          )
 
37
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
 
38
from bzrlib.tests.TestUtil import _load_module_by_name
 
39
import bzrlib.errors as errors
 
40
from bzrlib import symbol_versioning
 
41
from bzrlib.symbol_versioning import zero_ten, zero_eleven
 
42
from bzrlib.trace import note
 
43
from bzrlib.transport.memory import MemoryServer, MemoryTransport
 
44
from bzrlib.version import _get_bzr_source_tree
 
45
 
 
46
 
 
47
class SelftestTests(TestCase):
 
48
 
 
49
    def test_import_tests(self):
 
50
        mod = _load_module_by_name('bzrlib.tests.test_selftest')
 
51
        self.assertEqual(mod.SelftestTests, SelftestTests)
 
52
 
 
53
    def test_import_test_failure(self):
 
54
        self.assertRaises(ImportError,
 
55
                          _load_module_by_name,
 
56
                          'bzrlib.no-name-yet')
 
57
 
 
58
 
 
59
class MetaTestLog(TestCase):
 
60
 
 
61
    def test_logging(self):
 
62
        """Test logs are captured when a test fails."""
 
63
        self.log('a test message')
 
64
        self._log_file.flush()
 
65
        self.assertContainsRe(self._get_log(), 'a test message\n')
 
66
 
 
67
 
 
68
class TestTreeShape(TestCaseInTempDir):
 
69
 
 
70
    def test_unicode_paths(self):
 
71
        filename = u'hell\u00d8'
 
72
        try:
 
73
            self.build_tree_contents([(filename, 'contents of hello')])
 
74
        except UnicodeEncodeError:
 
75
            raise TestSkipped("can't build unicode working tree in "
 
76
                "filesystem encoding %s" % sys.getfilesystemencoding())
 
77
        self.failUnlessExists(filename)
 
78
 
 
79
 
 
80
class TestTransportProviderAdapter(TestCase):
 
81
    """A group of tests that test the transport implementation adaption core.
 
82
 
 
83
    This is a meta test that the tests are applied to all available 
 
84
    transports.
 
85
 
 
86
    This will be generalised in the future which is why it is in this 
 
87
    test file even though it is specific to transport tests at the moment.
 
88
    """
 
89
 
 
90
    def test_get_transport_permutations(self):
 
91
        # this checks that we the module get_test_permutations call
 
92
        # is made by the adapter get_transport_test_permitations method.
 
93
        class MockModule(object):
 
94
            def get_test_permutations(self):
 
95
                return sample_permutation
 
96
        sample_permutation = [(1,2), (3,4)]
 
97
        from bzrlib.transport import TransportTestProviderAdapter
 
98
        adapter = TransportTestProviderAdapter()
 
99
        self.assertEqual(sample_permutation,
 
100
                         adapter.get_transport_test_permutations(MockModule()))
 
101
 
 
102
    def test_adapter_checks_all_modules(self):
 
103
        # this checks that the adapter returns as many permurtations as
 
104
        # there are in all the registered# transport modules for there
 
105
        # - we assume if this matches its probably doing the right thing
 
106
        # especially in combination with the tests for setting the right
 
107
        # classes below.
 
108
        from bzrlib.transport import (TransportTestProviderAdapter,
 
109
                                      _get_transport_modules
 
110
                                      )
 
111
        modules = _get_transport_modules()
 
112
        permutation_count = 0
 
113
        for module in modules:
 
114
            try:
 
115
                permutation_count += len(reduce(getattr, 
 
116
                    (module + ".get_test_permutations").split('.')[1:],
 
117
                     __import__(module))())
 
118
            except errors.DependencyNotPresent:
 
119
                pass
 
120
        input_test = TestTransportProviderAdapter(
 
121
            "test_adapter_sets_transport_class")
 
122
        adapter = TransportTestProviderAdapter()
 
123
        self.assertEqual(permutation_count,
 
124
                         len(list(iter(adapter.adapt(input_test)))))
 
125
 
 
126
    def test_adapter_sets_transport_class(self):
 
127
        # Check that the test adapter inserts a transport and server into the
 
128
        # generated test.
 
129
        #
 
130
        # This test used to know about all the possible transports and the
 
131
        # order they were returned but that seems overly brittle (mbp
 
132
        # 20060307)
 
133
        input_test = TestTransportProviderAdapter(
 
134
            "test_adapter_sets_transport_class")
 
135
        from bzrlib.transport import TransportTestProviderAdapter
 
136
        suite = TransportTestProviderAdapter().adapt(input_test)
 
137
        tests = list(iter(suite))
 
138
        self.assertTrue(len(tests) > 6)
 
139
        # there are at least that many builtin transports
 
140
        one_test = tests[0]
 
141
        self.assertTrue(issubclass(one_test.transport_class, 
 
142
                                   bzrlib.transport.Transport))
 
143
        self.assertTrue(issubclass(one_test.transport_server, 
 
144
                                   bzrlib.transport.Server))
 
145
 
 
146
 
 
147
class TestBranchProviderAdapter(TestCase):
 
148
    """A group of tests that test the branch implementation test adapter."""
 
149
 
 
150
    def test_adapted_tests(self):
 
151
        # check that constructor parameters are passed through to the adapted
 
152
        # test.
 
153
        from bzrlib.branch import BranchTestProviderAdapter
 
154
        input_test = TestBranchProviderAdapter(
 
155
            "test_adapted_tests")
 
156
        server1 = "a"
 
157
        server2 = "b"
 
158
        formats = [("c", "C"), ("d", "D")]
 
159
        adapter = BranchTestProviderAdapter(server1, server2, formats)
 
160
        suite = adapter.adapt(input_test)
 
161
        tests = list(iter(suite))
 
162
        self.assertEqual(2, len(tests))
 
163
        self.assertEqual(tests[0].branch_format, formats[0][0])
 
164
        self.assertEqual(tests[0].bzrdir_format, formats[0][1])
 
165
        self.assertEqual(tests[0].transport_server, server1)
 
166
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
167
        self.assertEqual(tests[1].branch_format, formats[1][0])
 
168
        self.assertEqual(tests[1].bzrdir_format, formats[1][1])
 
169
        self.assertEqual(tests[1].transport_server, server1)
 
170
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
171
 
 
172
 
 
173
class TestBzrDirProviderAdapter(TestCase):
 
174
    """A group of tests that test the bzr dir implementation test adapter."""
 
175
 
 
176
    def test_adapted_tests(self):
 
177
        # check that constructor parameters are passed through to the adapted
 
178
        # test.
 
179
        from bzrlib.bzrdir import BzrDirTestProviderAdapter
 
180
        input_test = TestBzrDirProviderAdapter(
 
181
            "test_adapted_tests")
 
182
        server1 = "a"
 
183
        server2 = "b"
 
184
        formats = ["c", "d"]
 
185
        adapter = BzrDirTestProviderAdapter(server1, server2, formats)
 
186
        suite = adapter.adapt(input_test)
 
187
        tests = list(iter(suite))
 
188
        self.assertEqual(2, len(tests))
 
189
        self.assertEqual(tests[0].bzrdir_format, formats[0])
 
190
        self.assertEqual(tests[0].transport_server, server1)
 
191
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
192
        self.assertEqual(tests[1].bzrdir_format, formats[1])
 
193
        self.assertEqual(tests[1].transport_server, server1)
 
194
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
195
 
 
196
 
 
197
class TestRepositoryProviderAdapter(TestCase):
 
198
    """A group of tests that test the repository implementation test adapter."""
 
199
 
 
200
    def test_adapted_tests(self):
 
201
        # check that constructor parameters are passed through to the adapted
 
202
        # test.
 
203
        from bzrlib.repository import RepositoryTestProviderAdapter
 
204
        input_test = TestRepositoryProviderAdapter(
 
205
            "test_adapted_tests")
 
206
        server1 = "a"
 
207
        server2 = "b"
 
208
        formats = [("c", "C"), ("d", "D")]
 
209
        adapter = RepositoryTestProviderAdapter(server1, server2, formats)
 
210
        suite = adapter.adapt(input_test)
 
211
        tests = list(iter(suite))
 
212
        self.assertEqual(2, len(tests))
 
213
        self.assertEqual(tests[0].bzrdir_format, formats[0][1])
 
214
        self.assertEqual(tests[0].repository_format, formats[0][0])
 
215
        self.assertEqual(tests[0].transport_server, server1)
 
216
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
217
        self.assertEqual(tests[1].bzrdir_format, formats[1][1])
 
218
        self.assertEqual(tests[1].repository_format, formats[1][0])
 
219
        self.assertEqual(tests[1].transport_server, server1)
 
220
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
221
 
 
222
 
 
223
class TestInterRepositoryProviderAdapter(TestCase):
 
224
    """A group of tests that test the InterRepository test adapter."""
 
225
 
 
226
    def test_adapted_tests(self):
 
227
        # check that constructor parameters are passed through to the adapted
 
228
        # test.
 
229
        from bzrlib.repository import InterRepositoryTestProviderAdapter
 
230
        input_test = TestInterRepositoryProviderAdapter(
 
231
            "test_adapted_tests")
 
232
        server1 = "a"
 
233
        server2 = "b"
 
234
        formats = [(str, "C1", "C2"), (int, "D1", "D2")]
 
235
        adapter = InterRepositoryTestProviderAdapter(server1, server2, formats)
 
236
        suite = adapter.adapt(input_test)
 
237
        tests = list(iter(suite))
 
238
        self.assertEqual(2, len(tests))
 
239
        self.assertEqual(tests[0].interrepo_class, formats[0][0])
 
240
        self.assertEqual(tests[0].repository_format, formats[0][1])
 
241
        self.assertEqual(tests[0].repository_format_to, formats[0][2])
 
242
        self.assertEqual(tests[0].transport_server, server1)
 
243
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
244
        self.assertEqual(tests[1].interrepo_class, formats[1][0])
 
245
        self.assertEqual(tests[1].repository_format, formats[1][1])
 
246
        self.assertEqual(tests[1].repository_format_to, formats[1][2])
 
247
        self.assertEqual(tests[1].transport_server, server1)
 
248
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
249
 
 
250
 
 
251
class TestInterVersionedFileProviderAdapter(TestCase):
 
252
    """A group of tests that test the InterVersionedFile test adapter."""
 
253
 
 
254
    def test_adapted_tests(self):
 
255
        # check that constructor parameters are passed through to the adapted
 
256
        # test.
 
257
        from bzrlib.versionedfile import InterVersionedFileTestProviderAdapter
 
258
        input_test = TestInterRepositoryProviderAdapter(
 
259
            "test_adapted_tests")
 
260
        server1 = "a"
 
261
        server2 = "b"
 
262
        formats = [(str, "C1", "C2"), (int, "D1", "D2")]
 
263
        adapter = InterVersionedFileTestProviderAdapter(server1, server2, formats)
 
264
        suite = adapter.adapt(input_test)
 
265
        tests = list(iter(suite))
 
266
        self.assertEqual(2, len(tests))
 
267
        self.assertEqual(tests[0].interversionedfile_class, formats[0][0])
 
268
        self.assertEqual(tests[0].versionedfile_factory, formats[0][1])
 
269
        self.assertEqual(tests[0].versionedfile_factory_to, formats[0][2])
 
270
        self.assertEqual(tests[0].transport_server, server1)
 
271
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
272
        self.assertEqual(tests[1].interversionedfile_class, formats[1][0])
 
273
        self.assertEqual(tests[1].versionedfile_factory, formats[1][1])
 
274
        self.assertEqual(tests[1].versionedfile_factory_to, formats[1][2])
 
275
        self.assertEqual(tests[1].transport_server, server1)
 
276
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
277
 
 
278
 
 
279
class TestRevisionStoreProviderAdapter(TestCase):
 
280
    """A group of tests that test the RevisionStore test adapter."""
 
281
 
 
282
    def test_adapted_tests(self):
 
283
        # check that constructor parameters are passed through to the adapted
 
284
        # test.
 
285
        from bzrlib.store.revision import RevisionStoreTestProviderAdapter
 
286
        input_test = TestRevisionStoreProviderAdapter(
 
287
            "test_adapted_tests")
 
288
        # revision stores need a store factory - i.e. RevisionKnit
 
289
        #, a readonly and rw transport 
 
290
        # transport servers:
 
291
        server1 = "a"
 
292
        server2 = "b"
 
293
        store_factories = ["c", "d"]
 
294
        adapter = RevisionStoreTestProviderAdapter(server1, server2, store_factories)
 
295
        suite = adapter.adapt(input_test)
 
296
        tests = list(iter(suite))
 
297
        self.assertEqual(2, len(tests))
 
298
        self.assertEqual(tests[0].store_factory, store_factories[0][0])
 
299
        self.assertEqual(tests[0].transport_server, server1)
 
300
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
301
        self.assertEqual(tests[1].store_factory, store_factories[1][0])
 
302
        self.assertEqual(tests[1].transport_server, server1)
 
303
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
304
 
 
305
 
 
306
class TestWorkingTreeProviderAdapter(TestCase):
 
307
    """A group of tests that test the workingtree implementation test adapter."""
 
308
 
 
309
    def test_adapted_tests(self):
 
310
        # check that constructor parameters are passed through to the adapted
 
311
        # test.
 
312
        from bzrlib.workingtree import WorkingTreeTestProviderAdapter
 
313
        input_test = TestWorkingTreeProviderAdapter(
 
314
            "test_adapted_tests")
 
315
        server1 = "a"
 
316
        server2 = "b"
 
317
        formats = [("c", "C"), ("d", "D")]
 
318
        adapter = WorkingTreeTestProviderAdapter(server1, server2, formats)
 
319
        suite = adapter.adapt(input_test)
 
320
        tests = list(iter(suite))
 
321
        self.assertEqual(2, len(tests))
 
322
        self.assertEqual(tests[0].workingtree_format, formats[0][0])
 
323
        self.assertEqual(tests[0].bzrdir_format, formats[0][1])
 
324
        self.assertEqual(tests[0].transport_server, server1)
 
325
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
326
        self.assertEqual(tests[1].workingtree_format, formats[1][0])
 
327
        self.assertEqual(tests[1].bzrdir_format, formats[1][1])
 
328
        self.assertEqual(tests[1].transport_server, server1)
 
329
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
330
 
 
331
 
 
332
class TestTreeProviderAdapter(TestCase):
 
333
    """Test the setup of tree_implementation tests."""
 
334
 
 
335
    def test_adapted_tests(self):
 
336
        # the tree implementation adapter is meant to setup one instance for
 
337
        # each working tree format, and one additional instance that will
 
338
        # use the default wt format, but create a revision tree for the tests.
 
339
        # this means that the wt ones should have the workingtree_to_test_tree
 
340
        # attribute set to 'return_parameter' and the revision one set to
 
341
        # revision_tree_from_workingtree.
 
342
 
 
343
        from bzrlib.tests.tree_implementations import (
 
344
            TreeTestProviderAdapter,
 
345
            return_parameter,
 
346
            revision_tree_from_workingtree
 
347
            )
 
348
        from bzrlib.workingtree import WorkingTreeFormat
 
349
        input_test = TestTreeProviderAdapter(
 
350
            "test_adapted_tests")
 
351
        server1 = "a"
 
352
        server2 = "b"
 
353
        formats = [("c", "C"), ("d", "D")]
 
354
        adapter = TreeTestProviderAdapter(server1, server2, formats)
 
355
        suite = adapter.adapt(input_test)
 
356
        tests = list(iter(suite))
 
357
        self.assertEqual(3, len(tests))
 
358
        default_format = WorkingTreeFormat.get_default_format()
 
359
        self.assertEqual(tests[0].workingtree_format, formats[0][0])
 
360
        self.assertEqual(tests[0].bzrdir_format, formats[0][1])
 
361
        self.assertEqual(tests[0].transport_server, server1)
 
362
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
363
        self.assertEqual(tests[0].workingtree_to_test_tree, return_parameter)
 
364
        self.assertEqual(tests[1].workingtree_format, formats[1][0])
 
365
        self.assertEqual(tests[1].bzrdir_format, formats[1][1])
 
366
        self.assertEqual(tests[1].transport_server, server1)
 
367
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
368
        self.assertEqual(tests[1].workingtree_to_test_tree, return_parameter)
 
369
        self.assertEqual(tests[2].workingtree_format, default_format)
 
370
        self.assertEqual(tests[2].bzrdir_format, default_format._matchingbzrdir)
 
371
        self.assertEqual(tests[2].transport_server, server1)
 
372
        self.assertEqual(tests[2].transport_readonly_server, server2)
 
373
        self.assertEqual(tests[2].workingtree_to_test_tree,
 
374
            revision_tree_from_workingtree)
 
375
 
 
376
 
 
377
class TestInterTreeProviderAdapter(TestCase):
 
378
    """A group of tests that test the InterTreeTestAdapter."""
 
379
 
 
380
    def test_adapted_tests(self):
 
381
        # check that constructor parameters are passed through to the adapted
 
382
        # test.
 
383
        # for InterTree tests we want the machinery to bring up two trees in
 
384
        # each instance: the base one, and the one we are interacting with.
 
385
        # because each optimiser can be direction specific, we need to test
 
386
        # each optimiser in its chosen direction.
 
387
        # unlike the TestProviderAdapter we dont want to automatically add a
 
388
        # parameterised one for WorkingTree - the optimisers will tell us what
 
389
        # ones to add.
 
390
        from bzrlib.tests.tree_implementations import (
 
391
            return_parameter,
 
392
            revision_tree_from_workingtree
 
393
            )
 
394
        from bzrlib.tests.intertree_implementations import (
 
395
            InterTreeTestProviderAdapter,
 
396
            )
 
397
        from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
 
398
        input_test = TestInterTreeProviderAdapter(
 
399
            "test_adapted_tests")
 
400
        server1 = "a"
 
401
        server2 = "b"
 
402
        format1 = WorkingTreeFormat2()
 
403
        format2 = WorkingTreeFormat3()
 
404
        formats = [(str, format1, format2, False, True),
 
405
            (int, format2, format1, False, True)]
 
406
        adapter = InterTreeTestProviderAdapter(server1, server2, formats)
 
407
        suite = adapter.adapt(input_test)
 
408
        tests = list(iter(suite))
 
409
        self.assertEqual(2, len(tests))
 
410
        self.assertEqual(tests[0].intertree_class, formats[0][0])
 
411
        self.assertEqual(tests[0].workingtree_format, formats[0][1])
 
412
        self.assertEqual(tests[0].workingtree_to_test_tree, formats[0][2])
 
413
        self.assertEqual(tests[0].workingtree_format_to, formats[0][3])
 
414
        self.assertEqual(tests[0].workingtree_to_test_tree_to, formats[0][4])
 
415
        self.assertEqual(tests[0].transport_server, server1)
 
416
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
417
        self.assertEqual(tests[1].intertree_class, formats[1][0])
 
418
        self.assertEqual(tests[1].workingtree_format, formats[1][1])
 
419
        self.assertEqual(tests[1].workingtree_to_test_tree, formats[1][2])
 
420
        self.assertEqual(tests[1].workingtree_format_to, formats[1][3])
 
421
        self.assertEqual(tests[1].workingtree_to_test_tree_to, formats[1][4])
 
422
        self.assertEqual(tests[1].transport_server, server1)
 
423
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
424
 
 
425
 
 
426
class TestTestCaseInTempDir(TestCaseInTempDir):
 
427
 
 
428
    def test_home_is_not_working(self):
 
429
        self.assertNotEqual(self.test_dir, self.test_home_dir)
 
430
        cwd = osutils.getcwd()
 
431
        self.assertEqual(self.test_dir, cwd)
 
432
        self.assertEqual(self.test_home_dir, os.environ['HOME'])
 
433
 
 
434
 
 
435
class TestTestCaseWithTransport(TestCaseWithTransport):
 
436
    """Tests for the convenience functions TestCaseWithTransport introduces."""
 
437
 
 
438
    def test_get_readonly_url_none(self):
 
439
        from bzrlib.transport import get_transport
 
440
        from bzrlib.transport.memory import MemoryServer
 
441
        from bzrlib.transport.readonly import ReadonlyTransportDecorator
 
442
        self.transport_server = MemoryServer
 
443
        self.transport_readonly_server = None
 
444
        # calling get_readonly_transport() constructs a decorator on the url
 
445
        # for the server
 
446
        url = self.get_readonly_url()
 
447
        url2 = self.get_readonly_url('foo/bar')
 
448
        t = get_transport(url)
 
449
        t2 = get_transport(url2)
 
450
        self.failUnless(isinstance(t, ReadonlyTransportDecorator))
 
451
        self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
 
452
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
 
453
 
 
454
    def test_get_readonly_url_http(self):
 
455
        from bzrlib.transport import get_transport
 
456
        from bzrlib.transport.local import LocalRelpathServer
 
457
        from bzrlib.transport.http import HttpServer, HttpTransportBase
 
458
        self.transport_server = LocalRelpathServer
 
459
        self.transport_readonly_server = HttpServer
 
460
        # calling get_readonly_transport() gives us a HTTP server instance.
 
461
        url = self.get_readonly_url()
 
462
        url2 = self.get_readonly_url('foo/bar')
 
463
        # the transport returned may be any HttpTransportBase subclass
 
464
        t = get_transport(url)
 
465
        t2 = get_transport(url2)
 
466
        self.failUnless(isinstance(t, HttpTransportBase))
 
467
        self.failUnless(isinstance(t2, HttpTransportBase))
 
468
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
 
469
 
 
470
    def test_is_directory(self):
 
471
        """Test assertIsDirectory assertion"""
 
472
        t = self.get_transport()
 
473
        self.build_tree(['a_dir/', 'a_file'], transport=t)
 
474
        self.assertIsDirectory('a_dir', t)
 
475
        self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
 
476
        self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
 
477
 
 
478
 
 
479
class TestTestCaseTransports(TestCaseWithTransport):
 
480
 
 
481
    def setUp(self):
 
482
        super(TestTestCaseTransports, self).setUp()
 
483
        self.transport_server = MemoryServer
 
484
 
 
485
    def test_make_bzrdir_preserves_transport(self):
 
486
        t = self.get_transport()
 
487
        result_bzrdir = self.make_bzrdir('subdir')
 
488
        self.assertIsInstance(result_bzrdir.transport, 
 
489
                              MemoryTransport)
 
490
        # should not be on disk, should only be in memory
 
491
        self.failIfExists('subdir')
 
492
 
 
493
 
 
494
class TestChrootedTest(ChrootedTestCase):
 
495
 
 
496
    def test_root_is_root(self):
 
497
        from bzrlib.transport import get_transport
 
498
        t = get_transport(self.get_readonly_url())
 
499
        url = t.base
 
500
        self.assertEqual(url, t.clone('..').base)
 
501
 
 
502
 
 
503
class MockProgress(_BaseProgressBar):
 
504
    """Progress-bar standin that records calls.
 
505
 
 
506
    Useful for testing pb using code.
 
507
    """
 
508
 
 
509
    def __init__(self):
 
510
        _BaseProgressBar.__init__(self)
 
511
        self.calls = []
 
512
 
 
513
    def tick(self):
 
514
        self.calls.append(('tick',))
 
515
 
 
516
    def update(self, msg=None, current=None, total=None):
 
517
        self.calls.append(('update', msg, current, total))
 
518
 
 
519
    def clear(self):
 
520
        self.calls.append(('clear',))
 
521
 
 
522
    def note(self, msg, *args):
 
523
        self.calls.append(('note', msg, args))
 
524
 
 
525
 
 
526
class TestTestResult(TestCase):
 
527
 
 
528
    def test_progress_bar_style_quiet(self):
 
529
        # test using a progress bar.
 
530
        dummy_test = TestTestResult('test_progress_bar_style_quiet')
 
531
        dummy_error = (Exception, None, [])
 
532
        mypb = MockProgress()
 
533
        mypb.update('Running tests', 0, 4)
 
534
        last_calls = mypb.calls[:]
 
535
 
 
536
        result = bzrlib.tests._MyResult(self._log_file,
 
537
                                        descriptions=0,
 
538
                                        verbosity=1,
 
539
                                        pb=mypb)
 
540
        self.assertEqual(last_calls, mypb.calls)
 
541
 
 
542
        def shorten(s):
 
543
            """Shorten a string based on the terminal width"""
 
544
            return result._ellipsise_unimportant_words(s,
 
545
                                 osutils.terminal_width())
 
546
 
 
547
        # an error 
 
548
        result.startTest(dummy_test)
 
549
        # starting a test prints the test name
 
550
        last_calls += [('update', '...tyle_quiet', 0, None)]
 
551
        self.assertEqual(last_calls, mypb.calls)
 
552
        result.addError(dummy_test, dummy_error)
 
553
        last_calls += [('update', 'ERROR        ', 1, None),
 
554
                       ('note', shorten(dummy_test.id() + ': ERROR'), ())
 
555
                      ]
 
556
        self.assertEqual(last_calls, mypb.calls)
 
557
 
 
558
        # a failure
 
559
        result.startTest(dummy_test)
 
560
        last_calls += [('update', '...tyle_quiet', 1, None)]
 
561
        self.assertEqual(last_calls, mypb.calls)
 
562
        last_calls += [('update', 'FAIL         ', 2, None),
 
563
                       ('note', shorten(dummy_test.id() + ': FAIL'), ())
 
564
                      ]
 
565
        result.addFailure(dummy_test, dummy_error)
 
566
        self.assertEqual(last_calls, mypb.calls)
 
567
 
 
568
        # a success
 
569
        result.startTest(dummy_test)
 
570
        last_calls += [('update', '...tyle_quiet', 2, None)]
 
571
        self.assertEqual(last_calls, mypb.calls)
 
572
        result.addSuccess(dummy_test)
 
573
        last_calls += [('update', 'OK           ', 3, None)]
 
574
        self.assertEqual(last_calls, mypb.calls)
 
575
 
 
576
        # a skip
 
577
        result.startTest(dummy_test)
 
578
        last_calls += [('update', '...tyle_quiet', 3, None)]
 
579
        self.assertEqual(last_calls, mypb.calls)
 
580
        result.addSkipped(dummy_test, dummy_error)
 
581
        last_calls += [('update', 'SKIP         ', 4, None)]
 
582
        self.assertEqual(last_calls, mypb.calls)
 
583
 
 
584
    def test_elapsed_time_with_benchmarking(self):
 
585
        result = bzrlib.tests._MyResult(self._log_file,
 
586
                                        descriptions=0,
 
587
                                        verbosity=1,
 
588
                                        )
 
589
        result._recordTestStartTime()
 
590
        time.sleep(0.003)
 
591
        result.extractBenchmarkTime(self)
 
592
        timed_string = result._testTimeString()
 
593
        # without explicit benchmarking, we should get a simple time.
 
594
        self.assertContainsRe(timed_string, "^         [ 1-9][0-9]ms$")
 
595
        # if a benchmark time is given, we want a x of y style result.
 
596
        self.time(time.sleep, 0.001)
 
597
        result.extractBenchmarkTime(self)
 
598
        timed_string = result._testTimeString()
 
599
        self.assertContainsRe(timed_string, "^   [ 1-9][0-9]ms/   [ 1-9][0-9]ms$")
 
600
        # extracting the time from a non-bzrlib testcase sets to None
 
601
        result._recordTestStartTime()
 
602
        result.extractBenchmarkTime(
 
603
            unittest.FunctionTestCase(self.test_elapsed_time_with_benchmarking))
 
604
        timed_string = result._testTimeString()
 
605
        self.assertContainsRe(timed_string, "^         [ 1-9][0-9]ms$")
 
606
        # cheat. Yes, wash thy mouth out with soap.
 
607
        self._benchtime = None
 
608
 
 
609
    def test_assigned_benchmark_file_stores_date(self):
 
610
        output = StringIO()
 
611
        result = bzrlib.tests._MyResult(self._log_file,
 
612
                                        descriptions=0,
 
613
                                        verbosity=1,
 
614
                                        bench_history=output
 
615
                                        )
 
616
        output_string = output.getvalue()
 
617
        # if you are wondering about the regexp please read the comment in
 
618
        # test_bench_history (bzrlib.tests.test_selftest.TestRunner)
 
619
        # XXX: what comment?  -- Andrew Bennetts
 
620
        self.assertContainsRe(output_string, "--date [0-9.]+")
 
621
 
 
622
    def test_benchhistory_records_test_times(self):
 
623
        result_stream = StringIO()
 
624
        result = bzrlib.tests._MyResult(
 
625
            self._log_file,
 
626
            descriptions=0,
 
627
            verbosity=1,
 
628
            bench_history=result_stream
 
629
            )
 
630
 
 
631
        # we want profile a call and check that its test duration is recorded
 
632
        # make a new test instance that when run will generate a benchmark
 
633
        example_test_case = TestTestResult("_time_hello_world_encoding")
 
634
        # execute the test, which should succeed and record times
 
635
        example_test_case.run(result)
 
636
        lines = result_stream.getvalue().splitlines()
 
637
        self.assertEqual(2, len(lines))
 
638
        self.assertContainsRe(lines[1],
 
639
            " *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
 
640
            "._time_hello_world_encoding")
 
641
 
 
642
    def _time_hello_world_encoding(self):
 
643
        """Profile two sleep calls
 
644
        
 
645
        This is used to exercise the test framework.
 
646
        """
 
647
        self.time(unicode, 'hello', errors='replace')
 
648
        self.time(unicode, 'world', errors='replace')
 
649
 
 
650
    def test_lsprofiling(self):
 
651
        """Verbose test result prints lsprof statistics from test cases."""
 
652
        try:
 
653
            import bzrlib.lsprof
 
654
        except ImportError:
 
655
            raise TestSkipped("lsprof not installed.")
 
656
        result_stream = StringIO()
 
657
        result = bzrlib.tests._MyResult(
 
658
            unittest._WritelnDecorator(result_stream),
 
659
            descriptions=0,
 
660
            verbosity=2,
 
661
            )
 
662
        # we want profile a call of some sort and check it is output by
 
663
        # addSuccess. We dont care about addError or addFailure as they
 
664
        # are not that interesting for performance tuning.
 
665
        # make a new test instance that when run will generate a profile
 
666
        example_test_case = TestTestResult("_time_hello_world_encoding")
 
667
        example_test_case._gather_lsprof_in_benchmarks = True
 
668
        # execute the test, which should succeed and record profiles
 
669
        example_test_case.run(result)
 
670
        # lsprofile_something()
 
671
        # if this worked we want 
 
672
        # LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
 
673
        #    CallCount    Recursive    Total(ms)   Inline(ms) module:lineno(function)
 
674
        # (the lsprof header)
 
675
        # ... an arbitrary number of lines
 
676
        # and the function call which is time.sleep.
 
677
        #           1        0            ???         ???       ???(sleep) 
 
678
        # and then repeated but with 'world', rather than 'hello'.
 
679
        # this should appear in the output stream of our test result.
 
680
        output = result_stream.getvalue()
 
681
        self.assertContainsRe(output,
 
682
            r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
 
683
        self.assertContainsRe(output,
 
684
            r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
 
685
        self.assertContainsRe(output,
 
686
            r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
 
687
        self.assertContainsRe(output,
 
688
            r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
 
689
 
 
690
 
 
691
class TestRunner(TestCase):
 
692
 
 
693
    def dummy_test(self):
 
694
        pass
 
695
 
 
696
    def run_test_runner(self, testrunner, test):
 
697
        """Run suite in testrunner, saving global state and restoring it.
 
698
 
 
699
        This current saves and restores:
 
700
        TestCaseInTempDir.TEST_ROOT
 
701
        
 
702
        There should be no tests in this file that use bzrlib.tests.TextTestRunner
 
703
        without using this convenience method, because of our use of global state.
 
704
        """
 
705
        old_root = TestCaseInTempDir.TEST_ROOT
 
706
        try:
 
707
            TestCaseInTempDir.TEST_ROOT = None
 
708
            return testrunner.run(test)
 
709
        finally:
 
710
            TestCaseInTempDir.TEST_ROOT = old_root
 
711
 
 
712
    def test_accepts_and_uses_pb_parameter(self):
 
713
        test = TestRunner('dummy_test')
 
714
        mypb = MockProgress()
 
715
        self.assertEqual([], mypb.calls)
 
716
        runner = TextTestRunner(stream=self._log_file, pb=mypb)
 
717
        result = self.run_test_runner(runner, test)
 
718
        self.assertEqual(1, result.testsRun)
 
719
        self.assertEqual(('update', 'Running tests', 0, 1), mypb.calls[0])
 
720
        self.assertEqual(('update', '...dummy_test', 0, None), mypb.calls[1])
 
721
        self.assertEqual(('update', 'OK           ', 1, None), mypb.calls[2])
 
722
        self.assertEqual(('update', 'Cleaning up', 0, 1), mypb.calls[3])
 
723
        self.assertEqual(('clear',), mypb.calls[4])
 
724
        self.assertEqual(5, len(mypb.calls))
 
725
 
 
726
    def test_skipped_test(self):
 
727
        # run a test that is skipped, and check the suite as a whole still
 
728
        # succeeds.
 
729
        # skipping_test must be hidden in here so it's not run as a real test
 
730
        def skipping_test():
 
731
            raise TestSkipped('test intentionally skipped')
 
732
        runner = TextTestRunner(stream=self._log_file, keep_output=True)
 
733
        test = unittest.FunctionTestCase(skipping_test)
 
734
        result = self.run_test_runner(runner, test)
 
735
        self.assertTrue(result.wasSuccessful())
 
736
 
 
737
    def test_bench_history(self):
 
738
        # tests that the running the benchmark produces a history file
 
739
        # containing a timestamp and the revision id of the bzrlib source which
 
740
        # was tested.
 
741
        workingtree = _get_bzr_source_tree()
 
742
        test = TestRunner('dummy_test')
 
743
        output = StringIO()
 
744
        runner = TextTestRunner(stream=self._log_file, bench_history=output)
 
745
        result = self.run_test_runner(runner, test)
 
746
        output_string = output.getvalue()
 
747
        self.assertContainsRe(output_string, "--date [0-9.]+")
 
748
        if workingtree is not None:
 
749
            revision_id = workingtree.get_parent_ids()[0]
 
750
            self.assertEndsWith(output_string.rstrip(), revision_id)
 
751
 
 
752
 
 
753
class TestTestCase(TestCase):
 
754
    """Tests that test the core bzrlib TestCase."""
 
755
 
 
756
    def inner_test(self):
 
757
        # the inner child test
 
758
        note("inner_test")
 
759
 
 
760
    def outer_child(self):
 
761
        # the outer child test
 
762
        note("outer_start")
 
763
        self.inner_test = TestTestCase("inner_child")
 
764
        result = bzrlib.tests._MyResult(self._log_file,
 
765
                                        descriptions=0,
 
766
                                        verbosity=1)
 
767
        self.inner_test.run(result)
 
768
        note("outer finish")
 
769
 
 
770
    def test_trace_nesting(self):
 
771
        # this tests that each test case nests its trace facility correctly.
 
772
        # we do this by running a test case manually. That test case (A)
 
773
        # should setup a new log, log content to it, setup a child case (B),
 
774
        # which should log independently, then case (A) should log a trailer
 
775
        # and return.
 
776
        # we do two nested children so that we can verify the state of the 
 
777
        # logs after the outer child finishes is correct, which a bad clean
 
778
        # up routine in tearDown might trigger a fault in our test with only
 
779
        # one child, we should instead see the bad result inside our test with
 
780
        # the two children.
 
781
        # the outer child test
 
782
        original_trace = bzrlib.trace._trace_file
 
783
        outer_test = TestTestCase("outer_child")
 
784
        result = bzrlib.tests._MyResult(self._log_file,
 
785
                                        descriptions=0,
 
786
                                        verbosity=1)
 
787
        outer_test.run(result)
 
788
        self.assertEqual(original_trace, bzrlib.trace._trace_file)
 
789
 
 
790
    def method_that_times_a_bit_twice(self):
 
791
        # call self.time twice to ensure it aggregates
 
792
        self.time(time.sleep, 0.007)
 
793
        self.time(time.sleep, 0.007)
 
794
 
 
795
    def test_time_creates_benchmark_in_result(self):
 
796
        """Test that the TestCase.time() method accumulates a benchmark time."""
 
797
        sample_test = TestTestCase("method_that_times_a_bit_twice")
 
798
        output_stream = StringIO()
 
799
        result = bzrlib.tests._MyResult(
 
800
            unittest._WritelnDecorator(output_stream),
 
801
            descriptions=0,
 
802
            verbosity=2)
 
803
        sample_test.run(result)
 
804
        self.assertContainsRe(
 
805
            output_stream.getvalue(),
 
806
            "[1-9][0-9]ms/   [1-9][0-9]ms\n$")
 
807
        
 
808
    def test__gather_lsprof_in_benchmarks(self):
 
809
        """When _gather_lsprof_in_benchmarks is on, accumulate profile data.
 
810
        
 
811
        Each self.time() call is individually and separately profiled.
 
812
        """
 
813
        try:
 
814
            import bzrlib.lsprof
 
815
        except ImportError:
 
816
            raise TestSkipped("lsprof not installed.")
 
817
        # overrides the class member with an instance member so no cleanup 
 
818
        # needed.
 
819
        self._gather_lsprof_in_benchmarks = True
 
820
        self.time(time.sleep, 0.000)
 
821
        self.time(time.sleep, 0.003)
 
822
        self.assertEqual(2, len(self._benchcalls))
 
823
        self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
 
824
        self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
 
825
        self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
 
826
        self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
 
827
 
 
828
 
 
829
@symbol_versioning.deprecated_function(zero_eleven)
 
830
def sample_deprecated_function():
 
831
    """A deprecated function to test applyDeprecated with."""
 
832
    return 2
 
833
 
 
834
 
 
835
def sample_undeprecated_function(a_param):
 
836
    """A undeprecated function to test applyDeprecated with."""
 
837
 
 
838
 
 
839
class ApplyDeprecatedHelper(object):
 
840
    """A helper class for ApplyDeprecated tests."""
 
841
 
 
842
    @symbol_versioning.deprecated_method(zero_eleven)
 
843
    def sample_deprecated_method(self, param_one):
 
844
        """A deprecated method for testing with."""
 
845
        return param_one
 
846
 
 
847
    def sample_normal_method(self):
 
848
        """A undeprecated method."""
 
849
 
 
850
    @symbol_versioning.deprecated_method(zero_ten)
 
851
    def sample_nested_deprecation(self):
 
852
        return sample_deprecated_function()
 
853
 
 
854
 
 
855
class TestExtraAssertions(TestCase):
 
856
    """Tests for new test assertions in bzrlib test suite"""
 
857
 
 
858
    def test_assert_isinstance(self):
 
859
        self.assertIsInstance(2, int)
 
860
        self.assertIsInstance(u'', basestring)
 
861
        self.assertRaises(AssertionError, self.assertIsInstance, None, int)
 
862
        self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
 
863
 
 
864
    def test_assertEndsWith(self):
 
865
        self.assertEndsWith('foo', 'oo')
 
866
        self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
 
867
 
 
868
    def test_applyDeprecated_not_deprecated(self):
 
869
        sample_object = ApplyDeprecatedHelper()
 
870
        # calling an undeprecated callable raises an assertion
 
871
        self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
 
872
            sample_object.sample_normal_method)
 
873
        self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
 
874
            sample_undeprecated_function, "a param value")
 
875
        # calling a deprecated callable (function or method) with the wrong
 
876
        # expected deprecation fails.
 
877
        self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
 
878
            sample_object.sample_deprecated_method, "a param value")
 
879
        self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
 
880
            sample_deprecated_function)
 
881
        # calling a deprecated callable (function or method) with the right
 
882
        # expected deprecation returns the functions result.
 
883
        self.assertEqual("a param value", self.applyDeprecated(zero_eleven,
 
884
            sample_object.sample_deprecated_method, "a param value"))
 
885
        self.assertEqual(2, self.applyDeprecated(zero_eleven,
 
886
            sample_deprecated_function))
 
887
        # calling a nested deprecation with the wrong deprecation version
 
888
        # fails even if a deeper nested function was deprecated with the 
 
889
        # supplied version.
 
890
        self.assertRaises(AssertionError, self.applyDeprecated,
 
891
            zero_eleven, sample_object.sample_nested_deprecation)
 
892
        # calling a nested deprecation with the right deprecation value
 
893
        # returns the calls result.
 
894
        self.assertEqual(2, self.applyDeprecated(zero_ten,
 
895
            sample_object.sample_nested_deprecation))
 
896
 
 
897
    def test_callDeprecated(self):
 
898
        def testfunc(be_deprecated, result=None):
 
899
            if be_deprecated is True:
 
900
                symbol_versioning.warn('i am deprecated', DeprecationWarning, 
 
901
                                       stacklevel=1)
 
902
            return result
 
903
        result = self.callDeprecated(['i am deprecated'], testfunc, True)
 
904
        self.assertIs(None, result)
 
905
        result = self.callDeprecated([], testfunc, False, 'result')
 
906
        self.assertEqual('result', result)
 
907
        self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
 
908
        self.callDeprecated([], testfunc, be_deprecated=False)
 
909
 
 
910
 
 
911
class TestConvenienceMakers(TestCaseWithTransport):
 
912
    """Test for the make_* convenience functions."""
 
913
 
 
914
    def test_make_branch_and_tree_with_format(self):
 
915
        # we should be able to supply a format to make_branch_and_tree
 
916
        self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
 
917
        self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
 
918
        self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
 
919
                              bzrlib.bzrdir.BzrDirMetaFormat1)
 
920
        self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
 
921
                              bzrlib.bzrdir.BzrDirFormat6)
 
922
 
 
923
    def test_make_branch_and_mutable_tree(self):
 
924
        # we should be able to get a new branch and a mutable tree from
 
925
        # TestCaseWithTransport
 
926
        tree = self.make_branch_and_memory_tree('a')
 
927
        self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
 
928
 
 
929
 
 
930
class TestSFTPMakeBranchAndTree(TestCaseWithSFTPServer):
 
931
 
 
932
    def test_make_tree_for_sftp_branch(self):
 
933
        """Transports backed by local directories create local trees."""
 
934
 
 
935
        tree = self.make_branch_and_tree('t1')
 
936
        base = tree.bzrdir.root_transport.base
 
937
        self.failIf(base.startswith('sftp'),
 
938
                'base %r is on sftp but should be local' % base)
 
939
        self.assertEquals(tree.bzrdir.root_transport,
 
940
                tree.branch.bzrdir.root_transport)
 
941
        self.assertEquals(tree.bzrdir.root_transport,
 
942
                tree.branch.repository.bzrdir.root_transport)
 
943
 
 
944
 
 
945
class TestSelftest(TestCase):
 
946
    """Tests of bzrlib.tests.selftest."""
 
947
 
 
948
    def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
 
949
        factory_called = []
 
950
        def factory():
 
951
            factory_called.append(True)
 
952
            return TestSuite()
 
953
        out = StringIO()
 
954
        err = StringIO()
 
955
        self.apply_redirected(out, err, None, bzrlib.tests.selftest, 
 
956
            test_suite_factory=factory)
 
957
        self.assertEqual([True], factory_called)