/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

  • Committer: Robert Collins
  • Date: 2007-06-28 04:25:15 UTC
  • mto: (2553.2.13 integration)
  • mto: This revision was merged to the branch mainline in revision 2568.
  • Revision ID: robertc@robertcollins.net-20070628042515-7uktaa31hsky2nw8
Treat InterRepositoryTestProviderAdapter like RepositoryTestProviderAdapter

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006, 2007 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 as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""Tests for the test framework."""
 
18
 
 
19
import cStringIO
 
20
import os
 
21
from StringIO import StringIO
 
22
import sys
 
23
import time
 
24
import unittest
 
25
import warnings
 
26
 
 
27
import bzrlib
 
28
from bzrlib import (
 
29
    bzrdir,
 
30
    errors,
 
31
    memorytree,
 
32
    osutils,
 
33
    repository,
 
34
    symbol_versioning,
 
35
    )
 
36
from bzrlib.progress import _BaseProgressBar
 
37
from bzrlib.repofmt import weaverepo
 
38
from bzrlib.symbol_versioning import zero_ten, zero_eleven
 
39
from bzrlib.tests import (
 
40
                          ChrootedTestCase,
 
41
                          ExtendedTestResult,
 
42
                          Feature,
 
43
                          KnownFailure,
 
44
                          TestCase,
 
45
                          TestCaseInTempDir,
 
46
                          TestCaseWithMemoryTransport,
 
47
                          TestCaseWithTransport,
 
48
                          TestSkipped,
 
49
                          TestSuite,
 
50
                          TestUtil,
 
51
                          TextTestRunner,
 
52
                          UnavailableFeature,
 
53
                          clean_selftest_output,
 
54
                          iter_suite_tests,
 
55
                          filter_suite_by_re,
 
56
                          sort_suite_by_re,
 
57
                          test_lsprof,
 
58
                          test_suite,
 
59
                          )
 
60
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
 
61
from bzrlib.tests.TestUtil import _load_module_by_name
 
62
from bzrlib.trace import note
 
63
from bzrlib.transport.memory import MemoryServer, MemoryTransport
 
64
from bzrlib.version import _get_bzr_source_tree
 
65
 
 
66
 
 
67
class SelftestTests(TestCase):
 
68
 
 
69
    def test_import_tests(self):
 
70
        mod = _load_module_by_name('bzrlib.tests.test_selftest')
 
71
        self.assertEqual(mod.SelftestTests, SelftestTests)
 
72
 
 
73
    def test_import_test_failure(self):
 
74
        self.assertRaises(ImportError,
 
75
                          _load_module_by_name,
 
76
                          'bzrlib.no-name-yet')
 
77
 
 
78
class MetaTestLog(TestCase):
 
79
 
 
80
    def test_logging(self):
 
81
        """Test logs are captured when a test fails."""
 
82
        self.log('a test message')
 
83
        self._log_file.flush()
 
84
        self.assertContainsRe(self._get_log(keep_log_file=True),
 
85
                              'a test message\n')
 
86
 
 
87
 
 
88
class TestTreeShape(TestCaseInTempDir):
 
89
 
 
90
    def test_unicode_paths(self):
 
91
        filename = u'hell\u00d8'
 
92
        try:
 
93
            self.build_tree_contents([(filename, 'contents of hello')])
 
94
        except UnicodeEncodeError:
 
95
            raise TestSkipped("can't build unicode working tree in "
 
96
                "filesystem encoding %s" % sys.getfilesystemencoding())
 
97
        self.failUnlessExists(filename)
 
98
 
 
99
 
 
100
class TestTransportProviderAdapter(TestCase):
 
101
    """A group of tests that test the transport implementation adaption core.
 
102
 
 
103
    This is a meta test that the tests are applied to all available 
 
104
    transports.
 
105
 
 
106
    This will be generalised in the future which is why it is in this 
 
107
    test file even though it is specific to transport tests at the moment.
 
108
    """
 
109
 
 
110
    def test_get_transport_permutations(self):
 
111
        # this checks that we the module get_test_permutations call
 
112
        # is made by the adapter get_transport_test_permitations method.
 
113
        class MockModule(object):
 
114
            def get_test_permutations(self):
 
115
                return sample_permutation
 
116
        sample_permutation = [(1,2), (3,4)]
 
117
        from bzrlib.transport import TransportTestProviderAdapter
 
118
        adapter = TransportTestProviderAdapter()
 
119
        self.assertEqual(sample_permutation,
 
120
                         adapter.get_transport_test_permutations(MockModule()))
 
121
 
 
122
    def test_adapter_checks_all_modules(self):
 
123
        # this checks that the adapter returns as many permurtations as
 
124
        # there are in all the registered# transport modules for there
 
125
        # - we assume if this matches its probably doing the right thing
 
126
        # especially in combination with the tests for setting the right
 
127
        # classes below.
 
128
        from bzrlib.transport import (TransportTestProviderAdapter,
 
129
                                      _get_transport_modules
 
130
                                      )
 
131
        modules = _get_transport_modules()
 
132
        permutation_count = 0
 
133
        for module in modules:
 
134
            try:
 
135
                permutation_count += len(reduce(getattr, 
 
136
                    (module + ".get_test_permutations").split('.')[1:],
 
137
                     __import__(module))())
 
138
            except errors.DependencyNotPresent:
 
139
                pass
 
140
        input_test = TestTransportProviderAdapter(
 
141
            "test_adapter_sets_transport_class")
 
142
        adapter = TransportTestProviderAdapter()
 
143
        self.assertEqual(permutation_count,
 
144
                         len(list(iter(adapter.adapt(input_test)))))
 
145
 
 
146
    def test_adapter_sets_transport_class(self):
 
147
        # Check that the test adapter inserts a transport and server into the
 
148
        # generated test.
 
149
        #
 
150
        # This test used to know about all the possible transports and the
 
151
        # order they were returned but that seems overly brittle (mbp
 
152
        # 20060307)
 
153
        input_test = TestTransportProviderAdapter(
 
154
            "test_adapter_sets_transport_class")
 
155
        from bzrlib.transport import TransportTestProviderAdapter
 
156
        suite = TransportTestProviderAdapter().adapt(input_test)
 
157
        tests = list(iter(suite))
 
158
        self.assertTrue(len(tests) > 6)
 
159
        # there are at least that many builtin transports
 
160
        one_test = tests[0]
 
161
        self.assertTrue(issubclass(one_test.transport_class, 
 
162
                                   bzrlib.transport.Transport))
 
163
        self.assertTrue(issubclass(one_test.transport_server, 
 
164
                                   bzrlib.transport.Server))
 
165
 
 
166
 
 
167
class TestBranchProviderAdapter(TestCase):
 
168
    """A group of tests that test the branch implementation test adapter."""
 
169
 
 
170
    def test_adapted_tests(self):
 
171
        # check that constructor parameters are passed through to the adapted
 
172
        # test.
 
173
        from bzrlib.branch import BranchTestProviderAdapter
 
174
        input_test = TestBranchProviderAdapter(
 
175
            "test_adapted_tests")
 
176
        server1 = "a"
 
177
        server2 = "b"
 
178
        formats = [("c", "C"), ("d", "D")]
 
179
        adapter = BranchTestProviderAdapter(server1, server2, formats)
 
180
        suite = adapter.adapt(input_test)
 
181
        tests = list(iter(suite))
 
182
        self.assertEqual(2, len(tests))
 
183
        self.assertEqual(tests[0].branch_format, formats[0][0])
 
184
        self.assertEqual(tests[0].bzrdir_format, formats[0][1])
 
185
        self.assertEqual(tests[0].transport_server, server1)
 
186
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
187
        self.assertEqual(tests[1].branch_format, formats[1][0])
 
188
        self.assertEqual(tests[1].bzrdir_format, formats[1][1])
 
189
        self.assertEqual(tests[1].transport_server, server1)
 
190
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
191
 
 
192
 
 
193
class TestBzrDirProviderAdapter(TestCase):
 
194
    """A group of tests that test the bzr dir implementation test adapter."""
 
195
 
 
196
    def test_adapted_tests(self):
 
197
        # check that constructor parameters are passed through to the adapted
 
198
        # test.
 
199
        from bzrlib.bzrdir import BzrDirTestProviderAdapter
 
200
        input_test = TestBzrDirProviderAdapter(
 
201
            "test_adapted_tests")
 
202
        vfs_factory = "v"
 
203
        server1 = "a"
 
204
        server2 = "b"
 
205
        formats = ["c", "d"]
 
206
        adapter = BzrDirTestProviderAdapter(vfs_factory,
 
207
            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])
 
212
        self.assertEqual(tests[0].vfs_transport_factory, vfs_factory)
 
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])
 
216
        self.assertEqual(tests[1].vfs_transport_factory, vfs_factory)
 
217
        self.assertEqual(tests[1].transport_server, server1)
 
218
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
219
 
 
220
 
 
221
class TestRepositoryProviderAdapter(TestCase):
 
222
    """A group of tests that test the repository implementation test adapter."""
 
223
 
 
224
    def test_constructor(self):
 
225
        # check that constructor parameters are passed through to the
 
226
        # scenarios.
 
227
        from bzrlib.tests.repository_implementations import RepositoryTestProviderAdapter
 
228
        server1 = "a"
 
229
        server2 = "b"
 
230
        formats = [("c", "C"), ("d", "D")]
 
231
        adapter = RepositoryTestProviderAdapter(server1, server2, formats)
 
232
        self.assertEqual([
 
233
            ('str',
 
234
             {'bzrdir_format': 'C',
 
235
              'repository_format': 'c',
 
236
              'transport_readonly_server': 'b',
 
237
              'transport_server': 'a'}),
 
238
            ('str',
 
239
             {'bzrdir_format': 'D',
 
240
              'repository_format': 'd',
 
241
              'transport_readonly_server': 'b',
 
242
              'transport_server': 'a'})],
 
243
            adapter.scenarios)
 
244
 
 
245
    def test_setting_vfs_transport(self):
 
246
        """The vfs_transport_factory can be set optionally."""
 
247
        from bzrlib.tests.repository_implementations import RepositoryTestProviderAdapter
 
248
        formats = [("a", "b"), ("c", "d")]
 
249
        adapter = RepositoryTestProviderAdapter(None, None, formats,
 
250
            vfs_transport_factory="vfs")
 
251
        self.assertEqual([
 
252
            ('str',
 
253
             {'bzrdir_format': 'b',
 
254
              'repository_format': 'a',
 
255
              'transport_readonly_server': None,
 
256
              'transport_server': None,
 
257
              'vfs_transport_factory': 'vfs'}),
 
258
            ('str',
 
259
             {'bzrdir_format': 'd',
 
260
              'repository_format': 'c',
 
261
              'transport_readonly_server': None,
 
262
              'transport_server': None,
 
263
              'vfs_transport_factory': 'vfs'})],
 
264
            adapter.scenarios)
 
265
 
 
266
    def test_formats_to_scenarios(self):
 
267
        """The adapter can generate all the scenarios needed."""
 
268
        from bzrlib.tests.repository_implementations import RepositoryTestProviderAdapter
 
269
        no_vfs_adapter = RepositoryTestProviderAdapter("server", "readonly",
 
270
            [], None)
 
271
        vfs_adapter = RepositoryTestProviderAdapter("server", "readonly",
 
272
            [], vfs_transport_factory="vfs")
 
273
        # no_vfs generate scenarios without vfs_transport_factor
 
274
        formats = [("c", "C"), (1, "D")]
 
275
        self.assertEqual([
 
276
            ('str',
 
277
             {'bzrdir_format': 'C',
 
278
              'repository_format': 'c',
 
279
              'transport_readonly_server': 'readonly',
 
280
              'transport_server': 'server'}),
 
281
            ('int',
 
282
             {'bzrdir_format': 'D',
 
283
              'repository_format': 1,
 
284
              'transport_readonly_server': 'readonly',
 
285
              'transport_server': 'server'})],
 
286
            no_vfs_adapter.formats_to_scenarios(formats))
 
287
        self.assertEqual([
 
288
            ('str',
 
289
             {'bzrdir_format': 'C',
 
290
              'repository_format': 'c',
 
291
              'transport_readonly_server': 'readonly',
 
292
              'transport_server': 'server',
 
293
              'vfs_transport_factory': 'vfs'}),
 
294
            ('int',
 
295
             {'bzrdir_format': 'D',
 
296
              'repository_format': 1,
 
297
              'transport_readonly_server': 'readonly',
 
298
              'transport_server': 'server',
 
299
              'vfs_transport_factory': 'vfs'})],
 
300
            vfs_adapter.formats_to_scenarios(formats))
 
301
 
 
302
 
 
303
class TestTestScenarioApplier(TestCase):
 
304
    """Tests for the test adaption facilities."""
 
305
 
 
306
    def test_adapt_applies_scenarios(self):
 
307
        from bzrlib.tests.repository_implementations import TestScenarioApplier
 
308
        input_test = TestTestScenarioApplier("test_adapt_test_to_scenario")
 
309
        adapter = TestScenarioApplier()
 
310
        adapter.scenarios = [("1", "dict"), ("2", "settings")]
 
311
        calls = []
 
312
        def capture_call(test, scenario):
 
313
            calls.append((test, scenario))
 
314
            return test
 
315
        adapter.adapt_test_to_scenario = capture_call
 
316
        adapter.adapt(input_test)
 
317
        self.assertEqual([(input_test, ("1", "dict")),
 
318
            (input_test, ("2", "settings"))], calls)
 
319
 
 
320
    def test_adapt_test_to_scenario(self):
 
321
        from bzrlib.tests.repository_implementations import TestScenarioApplier
 
322
        input_test = TestTestScenarioApplier("test_adapt_test_to_scenario")
 
323
        adapter = TestScenarioApplier()
 
324
        # setup two adapted tests
 
325
        adapted_test1 = adapter.adapt_test_to_scenario(input_test,
 
326
            ("new id",
 
327
            {"bzrdir_format":"bzr_format",
 
328
             "repository_format":"repo_fmt",
 
329
             "transport_server":"transport_server",
 
330
             "transport_readonly_server":"readonly-server"}))
 
331
        adapted_test2 = adapter.adapt_test_to_scenario(input_test,
 
332
            ("new id 2", {"bzrdir_format":None}))
 
333
        # input_test should have been altered.
 
334
        self.assertRaises(AttributeError, getattr, input_test, "bzrdir_format")
 
335
        # the new tests are mutually incompatible, ensuring it has 
 
336
        # made new ones, and unspecified elements in the scenario
 
337
        # should not have been altered.
 
338
        self.assertEqual("bzr_format", adapted_test1.bzrdir_format)
 
339
        self.assertEqual("repo_fmt", adapted_test1.repository_format)
 
340
        self.assertEqual("transport_server", adapted_test1.transport_server)
 
341
        self.assertEqual("readonly-server",
 
342
            adapted_test1.transport_readonly_server)
 
343
        self.assertEqual(
 
344
            "bzrlib.tests.test_selftest.TestTestScenarioApplier."
 
345
            "test_adapt_test_to_scenario(new id)",
 
346
            adapted_test1.id())
 
347
        self.assertEqual(None, adapted_test2.bzrdir_format)
 
348
        self.assertEqual(
 
349
            "bzrlib.tests.test_selftest.TestTestScenarioApplier."
 
350
            "test_adapt_test_to_scenario(new id 2)",
 
351
            adapted_test2.id())
 
352
 
 
353
 
 
354
class TestInterRepositoryProviderAdapter(TestCase):
 
355
    """A group of tests that test the InterRepository test adapter."""
 
356
 
 
357
    def test_adapted_tests(self):
 
358
        # check that constructor parameters are passed through to the adapted
 
359
        # test.
 
360
        from bzrlib.tests.interrepository_implementations import \
 
361
            InterRepositoryTestProviderAdapter
 
362
        server1 = "a"
 
363
        server2 = "b"
 
364
        formats = [(str, "C1", "C2"), (int, "D1", "D2")]
 
365
        adapter = InterRepositoryTestProviderAdapter(server1, server2, formats)
 
366
        self.assertEqual([
 
367
            ('str',
 
368
             {'interrepo_class': str,
 
369
              'repository_format': 'C1',
 
370
              'repository_format_to': 'C2',
 
371
              'transport_readonly_server': 'b',
 
372
              'transport_server': 'a'}),
 
373
            ('int',
 
374
             {'interrepo_class': int,
 
375
              'repository_format': 'D1',
 
376
              'repository_format_to': 'D2',
 
377
              'transport_readonly_server': 'b',
 
378
              'transport_server': 'a'})],
 
379
            adapter.formats_to_scenarios(formats))
 
380
 
 
381
 
 
382
class TestInterVersionedFileProviderAdapter(TestCase):
 
383
    """A group of tests that test the InterVersionedFile test adapter."""
 
384
 
 
385
    def test_adapted_tests(self):
 
386
        # check that constructor parameters are passed through to the adapted
 
387
        # test.
 
388
        from bzrlib.versionedfile import InterVersionedFileTestProviderAdapter
 
389
        input_test = TestInterRepositoryProviderAdapter(
 
390
            "test_adapted_tests")
 
391
        server1 = "a"
 
392
        server2 = "b"
 
393
        formats = [(str, "C1", "C2"), (int, "D1", "D2")]
 
394
        adapter = InterVersionedFileTestProviderAdapter(server1, server2, formats)
 
395
        suite = adapter.adapt(input_test)
 
396
        tests = list(iter(suite))
 
397
        self.assertEqual(2, len(tests))
 
398
        self.assertEqual(tests[0].interversionedfile_class, formats[0][0])
 
399
        self.assertEqual(tests[0].versionedfile_factory, formats[0][1])
 
400
        self.assertEqual(tests[0].versionedfile_factory_to, formats[0][2])
 
401
        self.assertEqual(tests[0].transport_server, server1)
 
402
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
403
        self.assertEqual(tests[1].interversionedfile_class, formats[1][0])
 
404
        self.assertEqual(tests[1].versionedfile_factory, formats[1][1])
 
405
        self.assertEqual(tests[1].versionedfile_factory_to, formats[1][2])
 
406
        self.assertEqual(tests[1].transport_server, server1)
 
407
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
408
 
 
409
 
 
410
class TestRevisionStoreProviderAdapter(TestCase):
 
411
    """A group of tests that test the RevisionStore test adapter."""
 
412
 
 
413
    def test_adapted_tests(self):
 
414
        # check that constructor parameters are passed through to the adapted
 
415
        # test.
 
416
        from bzrlib.store.revision import RevisionStoreTestProviderAdapter
 
417
        input_test = TestRevisionStoreProviderAdapter(
 
418
            "test_adapted_tests")
 
419
        # revision stores need a store factory - i.e. RevisionKnit
 
420
        #, a readonly and rw transport 
 
421
        # transport servers:
 
422
        server1 = "a"
 
423
        server2 = "b"
 
424
        store_factories = ["c", "d"]
 
425
        adapter = RevisionStoreTestProviderAdapter(server1, server2, store_factories)
 
426
        suite = adapter.adapt(input_test)
 
427
        tests = list(iter(suite))
 
428
        self.assertEqual(2, len(tests))
 
429
        self.assertEqual(tests[0].store_factory, store_factories[0][0])
 
430
        self.assertEqual(tests[0].transport_server, server1)
 
431
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
432
        self.assertEqual(tests[1].store_factory, store_factories[1][0])
 
433
        self.assertEqual(tests[1].transport_server, server1)
 
434
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
435
 
 
436
 
 
437
class TestWorkingTreeProviderAdapter(TestCase):
 
438
    """A group of tests that test the workingtree implementation test adapter."""
 
439
 
 
440
    def test_adapted_tests(self):
 
441
        # check that constructor parameters are passed through to the adapted
 
442
        # test.
 
443
        from bzrlib.workingtree import WorkingTreeTestProviderAdapter
 
444
        input_test = TestWorkingTreeProviderAdapter(
 
445
            "test_adapted_tests")
 
446
        server1 = "a"
 
447
        server2 = "b"
 
448
        formats = [("c", "C"), ("d", "D")]
 
449
        adapter = WorkingTreeTestProviderAdapter(server1, server2, formats)
 
450
        suite = adapter.adapt(input_test)
 
451
        tests = list(iter(suite))
 
452
        self.assertEqual(2, len(tests))
 
453
        self.assertEqual(tests[0].workingtree_format, formats[0][0])
 
454
        self.assertEqual(tests[0].bzrdir_format, formats[0][1])
 
455
        self.assertEqual(tests[0].transport_server, server1)
 
456
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
457
        self.assertEqual(tests[1].workingtree_format, formats[1][0])
 
458
        self.assertEqual(tests[1].bzrdir_format, formats[1][1])
 
459
        self.assertEqual(tests[1].transport_server, server1)
 
460
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
461
 
 
462
 
 
463
class TestTreeProviderAdapter(TestCase):
 
464
    """Test the setup of tree_implementation tests."""
 
465
 
 
466
    def test_adapted_tests(self):
 
467
        # the tree implementation adapter is meant to setup one instance for
 
468
        # each working tree format, and one additional instance that will
 
469
        # use the default wt format, but create a revision tree for the tests.
 
470
        # this means that the wt ones should have the workingtree_to_test_tree
 
471
        # attribute set to 'return_parameter' and the revision one set to
 
472
        # revision_tree_from_workingtree.
 
473
 
 
474
        from bzrlib.tests.tree_implementations import (
 
475
            TreeTestProviderAdapter,
 
476
            return_parameter,
 
477
            revision_tree_from_workingtree
 
478
            )
 
479
        from bzrlib.workingtree import WorkingTreeFormat, WorkingTreeFormat3
 
480
        input_test = TestTreeProviderAdapter(
 
481
            "test_adapted_tests")
 
482
        server1 = "a"
 
483
        server2 = "b"
 
484
        formats = [("c", "C"), ("d", "D")]
 
485
        adapter = TreeTestProviderAdapter(server1, server2, formats)
 
486
        suite = adapter.adapt(input_test)
 
487
        tests = list(iter(suite))
 
488
        self.assertEqual(4, len(tests))
 
489
        # this must match the default format setp up in
 
490
        # TreeTestProviderAdapter.adapt
 
491
        default_format = WorkingTreeFormat3
 
492
        self.assertEqual(tests[0].workingtree_format, formats[0][0])
 
493
        self.assertEqual(tests[0].bzrdir_format, formats[0][1])
 
494
        self.assertEqual(tests[0].transport_server, server1)
 
495
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
496
        self.assertEqual(tests[0].workingtree_to_test_tree, return_parameter)
 
497
        self.assertEqual(tests[1].workingtree_format, formats[1][0])
 
498
        self.assertEqual(tests[1].bzrdir_format, formats[1][1])
 
499
        self.assertEqual(tests[1].transport_server, server1)
 
500
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
501
        self.assertEqual(tests[1].workingtree_to_test_tree, return_parameter)
 
502
        self.assertIsInstance(tests[2].workingtree_format, default_format)
 
503
        #self.assertEqual(tests[2].bzrdir_format,
 
504
        #                 default_format._matchingbzrdir)
 
505
        self.assertEqual(tests[2].transport_server, server1)
 
506
        self.assertEqual(tests[2].transport_readonly_server, server2)
 
507
        self.assertEqual(tests[2].workingtree_to_test_tree,
 
508
            revision_tree_from_workingtree)
 
509
 
 
510
 
 
511
class TestInterTreeProviderAdapter(TestCase):
 
512
    """A group of tests that test the InterTreeTestAdapter."""
 
513
 
 
514
    def test_adapted_tests(self):
 
515
        # check that constructor parameters are passed through to the adapted
 
516
        # test.
 
517
        # for InterTree tests we want the machinery to bring up two trees in
 
518
        # each instance: the base one, and the one we are interacting with.
 
519
        # because each optimiser can be direction specific, we need to test
 
520
        # each optimiser in its chosen direction.
 
521
        # unlike the TestProviderAdapter we dont want to automatically add a
 
522
        # parameterised one for WorkingTree - the optimisers will tell us what
 
523
        # ones to add.
 
524
        from bzrlib.tests.tree_implementations import (
 
525
            return_parameter,
 
526
            revision_tree_from_workingtree
 
527
            )
 
528
        from bzrlib.tests.intertree_implementations import (
 
529
            InterTreeTestProviderAdapter,
 
530
            )
 
531
        from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
 
532
        input_test = TestInterTreeProviderAdapter(
 
533
            "test_adapted_tests")
 
534
        server1 = "a"
 
535
        server2 = "b"
 
536
        format1 = WorkingTreeFormat2()
 
537
        format2 = WorkingTreeFormat3()
 
538
        formats = [(str, format1, format2, "converter1"),
 
539
            (int, format2, format1, "converter2")]
 
540
        adapter = InterTreeTestProviderAdapter(server1, server2, formats)
 
541
        suite = adapter.adapt(input_test)
 
542
        tests = list(iter(suite))
 
543
        self.assertEqual(2, len(tests))
 
544
        self.assertEqual(tests[0].intertree_class, formats[0][0])
 
545
        self.assertEqual(tests[0].workingtree_format, formats[0][1])
 
546
        self.assertEqual(tests[0].workingtree_format_to, formats[0][2])
 
547
        self.assertEqual(tests[0].mutable_trees_to_test_trees, formats[0][3])
 
548
        self.assertEqual(tests[0].workingtree_to_test_tree, return_parameter)
 
549
        self.assertEqual(tests[0].transport_server, server1)
 
550
        self.assertEqual(tests[0].transport_readonly_server, server2)
 
551
        self.assertEqual(tests[1].intertree_class, formats[1][0])
 
552
        self.assertEqual(tests[1].workingtree_format, formats[1][1])
 
553
        self.assertEqual(tests[1].workingtree_format_to, formats[1][2])
 
554
        self.assertEqual(tests[1].mutable_trees_to_test_trees, formats[1][3])
 
555
        self.assertEqual(tests[1].workingtree_to_test_tree, return_parameter)
 
556
        self.assertEqual(tests[1].transport_server, server1)
 
557
        self.assertEqual(tests[1].transport_readonly_server, server2)
 
558
 
 
559
 
 
560
class TestTestCaseInTempDir(TestCaseInTempDir):
 
561
 
 
562
    def test_home_is_not_working(self):
 
563
        self.assertNotEqual(self.test_dir, self.test_home_dir)
 
564
        cwd = osutils.getcwd()
 
565
        self.assertEqual(self.test_dir, cwd)
 
566
        self.assertEqual(self.test_home_dir, os.environ['HOME'])
 
567
 
 
568
 
 
569
class TestTestCaseWithMemoryTransport(TestCaseWithMemoryTransport):
 
570
 
 
571
    def test_home_is_non_existant_dir_under_root(self):
 
572
        """The test_home_dir for TestCaseWithMemoryTransport is missing.
 
573
 
 
574
        This is because TestCaseWithMemoryTransport is for tests that do not
 
575
        need any disk resources: they should be hooked into bzrlib in such a 
 
576
        way that no global settings are being changed by the test (only a 
 
577
        few tests should need to do that), and having a missing dir as home is
 
578
        an effective way to ensure that this is the case.
 
579
        """
 
580
        self.assertEqual(self.TEST_ROOT + "/MemoryTransportMissingHomeDir",
 
581
            self.test_home_dir)
 
582
        self.assertEqual(self.test_home_dir, os.environ['HOME'])
 
583
        
 
584
    def test_cwd_is_TEST_ROOT(self):
 
585
        self.assertEqual(self.test_dir, self.TEST_ROOT)
 
586
        cwd = osutils.getcwd()
 
587
        self.assertEqual(self.test_dir, cwd)
 
588
 
 
589
    def test_make_branch_and_memory_tree(self):
 
590
        """In TestCaseWithMemoryTransport we should not make the branch on disk.
 
591
 
 
592
        This is hard to comprehensively robustly test, so we settle for making
 
593
        a branch and checking no directory was created at its relpath.
 
594
        """
 
595
        tree = self.make_branch_and_memory_tree('dir')
 
596
        # Guard against regression into MemoryTransport leaking
 
597
        # files to disk instead of keeping them in memory.
 
598
        self.failIf(osutils.lexists('dir'))
 
599
        self.assertIsInstance(tree, memorytree.MemoryTree)
 
600
 
 
601
    def test_make_branch_and_memory_tree_with_format(self):
 
602
        """make_branch_and_memory_tree should accept a format option."""
 
603
        format = bzrdir.BzrDirMetaFormat1()
 
604
        format.repository_format = weaverepo.RepositoryFormat7()
 
605
        tree = self.make_branch_and_memory_tree('dir', format=format)
 
606
        # Guard against regression into MemoryTransport leaking
 
607
        # files to disk instead of keeping them in memory.
 
608
        self.failIf(osutils.lexists('dir'))
 
609
        self.assertIsInstance(tree, memorytree.MemoryTree)
 
610
        self.assertEqual(format.repository_format.__class__,
 
611
            tree.branch.repository._format.__class__)
 
612
 
 
613
 
 
614
class TestTestCaseWithTransport(TestCaseWithTransport):
 
615
    """Tests for the convenience functions TestCaseWithTransport introduces."""
 
616
 
 
617
    def test_get_readonly_url_none(self):
 
618
        from bzrlib.transport import get_transport
 
619
        from bzrlib.transport.memory import MemoryServer
 
620
        from bzrlib.transport.readonly import ReadonlyTransportDecorator
 
621
        self.vfs_transport_factory = MemoryServer
 
622
        self.transport_readonly_server = None
 
623
        # calling get_readonly_transport() constructs a decorator on the url
 
624
        # for the server
 
625
        url = self.get_readonly_url()
 
626
        url2 = self.get_readonly_url('foo/bar')
 
627
        t = get_transport(url)
 
628
        t2 = get_transport(url2)
 
629
        self.failUnless(isinstance(t, ReadonlyTransportDecorator))
 
630
        self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
 
631
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
 
632
 
 
633
    def test_get_readonly_url_http(self):
 
634
        from bzrlib.tests.HttpServer import HttpServer
 
635
        from bzrlib.transport import get_transport
 
636
        from bzrlib.transport.local import LocalURLServer
 
637
        from bzrlib.transport.http import HttpTransportBase
 
638
        self.transport_server = LocalURLServer
 
639
        self.transport_readonly_server = HttpServer
 
640
        # calling get_readonly_transport() gives us a HTTP server instance.
 
641
        url = self.get_readonly_url()
 
642
        url2 = self.get_readonly_url('foo/bar')
 
643
        # the transport returned may be any HttpTransportBase subclass
 
644
        t = get_transport(url)
 
645
        t2 = get_transport(url2)
 
646
        self.failUnless(isinstance(t, HttpTransportBase))
 
647
        self.failUnless(isinstance(t2, HttpTransportBase))
 
648
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
 
649
 
 
650
    def test_is_directory(self):
 
651
        """Test assertIsDirectory assertion"""
 
652
        t = self.get_transport()
 
653
        self.build_tree(['a_dir/', 'a_file'], transport=t)
 
654
        self.assertIsDirectory('a_dir', t)
 
655
        self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
 
656
        self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
 
657
 
 
658
 
 
659
class TestTestCaseTransports(TestCaseWithTransport):
 
660
 
 
661
    def setUp(self):
 
662
        super(TestTestCaseTransports, self).setUp()
 
663
        self.vfs_transport_factory = MemoryServer
 
664
 
 
665
    def test_make_bzrdir_preserves_transport(self):
 
666
        t = self.get_transport()
 
667
        result_bzrdir = self.make_bzrdir('subdir')
 
668
        self.assertIsInstance(result_bzrdir.transport, 
 
669
                              MemoryTransport)
 
670
        # should not be on disk, should only be in memory
 
671
        self.failIfExists('subdir')
 
672
 
 
673
 
 
674
class TestChrootedTest(ChrootedTestCase):
 
675
 
 
676
    def test_root_is_root(self):
 
677
        from bzrlib.transport import get_transport
 
678
        t = get_transport(self.get_readonly_url())
 
679
        url = t.base
 
680
        self.assertEqual(url, t.clone('..').base)
 
681
 
 
682
 
 
683
class MockProgress(_BaseProgressBar):
 
684
    """Progress-bar standin that records calls.
 
685
 
 
686
    Useful for testing pb using code.
 
687
    """
 
688
 
 
689
    def __init__(self):
 
690
        _BaseProgressBar.__init__(self)
 
691
        self.calls = []
 
692
 
 
693
    def tick(self):
 
694
        self.calls.append(('tick',))
 
695
 
 
696
    def update(self, msg=None, current=None, total=None):
 
697
        self.calls.append(('update', msg, current, total))
 
698
 
 
699
    def clear(self):
 
700
        self.calls.append(('clear',))
 
701
 
 
702
    def note(self, msg, *args):
 
703
        self.calls.append(('note', msg, args))
 
704
 
 
705
 
 
706
class TestTestResult(TestCase):
 
707
 
 
708
    def test_elapsed_time_with_benchmarking(self):
 
709
        result = bzrlib.tests.TextTestResult(self._log_file,
 
710
                                        descriptions=0,
 
711
                                        verbosity=1,
 
712
                                        )
 
713
        result._recordTestStartTime()
 
714
        time.sleep(0.003)
 
715
        result.extractBenchmarkTime(self)
 
716
        timed_string = result._testTimeString()
 
717
        # without explicit benchmarking, we should get a simple time.
 
718
        self.assertContainsRe(timed_string, "^ +[0-9]+ms$")
 
719
        # if a benchmark time is given, we want a x of y style result.
 
720
        self.time(time.sleep, 0.001)
 
721
        result.extractBenchmarkTime(self)
 
722
        timed_string = result._testTimeString()
 
723
        self.assertContainsRe(
 
724
            timed_string, "^ +[0-9]+ms/ +[0-9]+ms$")
 
725
        # extracting the time from a non-bzrlib testcase sets to None
 
726
        result._recordTestStartTime()
 
727
        result.extractBenchmarkTime(
 
728
            unittest.FunctionTestCase(self.test_elapsed_time_with_benchmarking))
 
729
        timed_string = result._testTimeString()
 
730
        self.assertContainsRe(timed_string, "^ +[0-9]+ms$")
 
731
        # cheat. Yes, wash thy mouth out with soap.
 
732
        self._benchtime = None
 
733
 
 
734
    def test_assigned_benchmark_file_stores_date(self):
 
735
        output = StringIO()
 
736
        result = bzrlib.tests.TextTestResult(self._log_file,
 
737
                                        descriptions=0,
 
738
                                        verbosity=1,
 
739
                                        bench_history=output
 
740
                                        )
 
741
        output_string = output.getvalue()
 
742
        
 
743
        # if you are wondering about the regexp please read the comment in
 
744
        # test_bench_history (bzrlib.tests.test_selftest.TestRunner)
 
745
        # XXX: what comment?  -- Andrew Bennetts
 
746
        self.assertContainsRe(output_string, "--date [0-9.]+")
 
747
 
 
748
    def test_benchhistory_records_test_times(self):
 
749
        result_stream = StringIO()
 
750
        result = bzrlib.tests.TextTestResult(
 
751
            self._log_file,
 
752
            descriptions=0,
 
753
            verbosity=1,
 
754
            bench_history=result_stream
 
755
            )
 
756
 
 
757
        # we want profile a call and check that its test duration is recorded
 
758
        # make a new test instance that when run will generate a benchmark
 
759
        example_test_case = TestTestResult("_time_hello_world_encoding")
 
760
        # execute the test, which should succeed and record times
 
761
        example_test_case.run(result)
 
762
        lines = result_stream.getvalue().splitlines()
 
763
        self.assertEqual(2, len(lines))
 
764
        self.assertContainsRe(lines[1],
 
765
            " *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
 
766
            "._time_hello_world_encoding")
 
767
 
 
768
    def _time_hello_world_encoding(self):
 
769
        """Profile two sleep calls
 
770
        
 
771
        This is used to exercise the test framework.
 
772
        """
 
773
        self.time(unicode, 'hello', errors='replace')
 
774
        self.time(unicode, 'world', errors='replace')
 
775
 
 
776
    def test_lsprofiling(self):
 
777
        """Verbose test result prints lsprof statistics from test cases."""
 
778
        self.requireFeature(test_lsprof.LSProfFeature)
 
779
        result_stream = StringIO()
 
780
        result = bzrlib.tests.VerboseTestResult(
 
781
            unittest._WritelnDecorator(result_stream),
 
782
            descriptions=0,
 
783
            verbosity=2,
 
784
            )
 
785
        # we want profile a call of some sort and check it is output by
 
786
        # addSuccess. We dont care about addError or addFailure as they
 
787
        # are not that interesting for performance tuning.
 
788
        # make a new test instance that when run will generate a profile
 
789
        example_test_case = TestTestResult("_time_hello_world_encoding")
 
790
        example_test_case._gather_lsprof_in_benchmarks = True
 
791
        # execute the test, which should succeed and record profiles
 
792
        example_test_case.run(result)
 
793
        # lsprofile_something()
 
794
        # if this worked we want 
 
795
        # LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
 
796
        #    CallCount    Recursive    Total(ms)   Inline(ms) module:lineno(function)
 
797
        # (the lsprof header)
 
798
        # ... an arbitrary number of lines
 
799
        # and the function call which is time.sleep.
 
800
        #           1        0            ???         ???       ???(sleep) 
 
801
        # and then repeated but with 'world', rather than 'hello'.
 
802
        # this should appear in the output stream of our test result.
 
803
        output = result_stream.getvalue()
 
804
        self.assertContainsRe(output,
 
805
            r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
 
806
        self.assertContainsRe(output,
 
807
            r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
 
808
        self.assertContainsRe(output,
 
809
            r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
 
810
        self.assertContainsRe(output,
 
811
            r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
 
812
 
 
813
    def test_known_failure(self):
 
814
        """A KnownFailure being raised should trigger several result actions."""
 
815
        class InstrumentedTestResult(ExtendedTestResult):
 
816
 
 
817
            def report_test_start(self, test): pass
 
818
            def report_known_failure(self, test, err):
 
819
                self._call = test, err
 
820
        result = InstrumentedTestResult(None, None, None, None)
 
821
        def test_function():
 
822
            raise KnownFailure('failed!')
 
823
        test = unittest.FunctionTestCase(test_function)
 
824
        test.run(result)
 
825
        # it should invoke 'report_known_failure'.
 
826
        self.assertEqual(2, len(result._call))
 
827
        self.assertEqual(test, result._call[0])
 
828
        self.assertEqual(KnownFailure, result._call[1][0])
 
829
        self.assertIsInstance(result._call[1][1], KnownFailure)
 
830
        # we dont introspec the traceback, if the rest is ok, it would be
 
831
        # exceptional for it not to be.
 
832
        # it should update the known_failure_count on the object.
 
833
        self.assertEqual(1, result.known_failure_count)
 
834
        # the result should be successful.
 
835
        self.assertTrue(result.wasSuccessful())
 
836
 
 
837
    def test_verbose_report_known_failure(self):
 
838
        # verbose test output formatting
 
839
        result_stream = StringIO()
 
840
        result = bzrlib.tests.VerboseTestResult(
 
841
            unittest._WritelnDecorator(result_stream),
 
842
            descriptions=0,
 
843
            verbosity=2,
 
844
            )
 
845
        test = self.get_passing_test()
 
846
        result.startTest(test)
 
847
        result.extractBenchmarkTime(test)
 
848
        prefix = len(result_stream.getvalue())
 
849
        # the err parameter has the shape:
 
850
        # (class, exception object, traceback)
 
851
        # KnownFailures dont get their tracebacks shown though, so we
 
852
        # can skip that.
 
853
        err = (KnownFailure, KnownFailure('foo'), None)
 
854
        result.report_known_failure(test, err)
 
855
        output = result_stream.getvalue()[prefix:]
 
856
        lines = output.splitlines()
 
857
        self.assertContainsRe(lines[0], r'XFAIL *\d+ms$')
 
858
        self.assertEqual(lines[1], '    foo')
 
859
        self.assertEqual(2, len(lines))
 
860
 
 
861
    def test_text_report_known_failure(self):
 
862
        # text test output formatting
 
863
        pb = MockProgress()
 
864
        result = bzrlib.tests.TextTestResult(
 
865
            None,
 
866
            descriptions=0,
 
867
            verbosity=1,
 
868
            pb=pb,
 
869
            )
 
870
        test = self.get_passing_test()
 
871
        # this seeds the state to handle reporting the test.
 
872
        result.startTest(test)
 
873
        result.extractBenchmarkTime(test)
 
874
        # the err parameter has the shape:
 
875
        # (class, exception object, traceback)
 
876
        # KnownFailures dont get their tracebacks shown though, so we
 
877
        # can skip that.
 
878
        err = (KnownFailure, KnownFailure('foo'), None)
 
879
        result.report_known_failure(test, err)
 
880
        self.assertEqual(
 
881
            [
 
882
            ('update', '[1 in 0s] passing_test', None, None),
 
883
            ('note', 'XFAIL: %s\n%s\n', ('passing_test', err[1]))
 
884
            ],
 
885
            pb.calls)
 
886
        # known_failures should be printed in the summary, so if we run a test
 
887
        # after there are some known failures, the update prefix should match
 
888
        # this.
 
889
        result.known_failure_count = 3
 
890
        test.run(result)
 
891
        self.assertEqual(
 
892
            [
 
893
            ('update', '[2 in 0s, 3 known failures] passing_test', None, None),
 
894
            ],
 
895
            pb.calls[2:])
 
896
 
 
897
    def get_passing_test(self):
 
898
        """Return a test object that can't be run usefully."""
 
899
        def passing_test():
 
900
            pass
 
901
        return unittest.FunctionTestCase(passing_test)
 
902
 
 
903
    def test_add_not_supported(self):
 
904
        """Test the behaviour of invoking addNotSupported."""
 
905
        class InstrumentedTestResult(ExtendedTestResult):
 
906
            def report_test_start(self, test): pass
 
907
            def report_unsupported(self, test, feature):
 
908
                self._call = test, feature
 
909
        result = InstrumentedTestResult(None, None, None, None)
 
910
        test = SampleTestCase('_test_pass')
 
911
        feature = Feature()
 
912
        result.startTest(test)
 
913
        result.addNotSupported(test, feature)
 
914
        # it should invoke 'report_unsupported'.
 
915
        self.assertEqual(2, len(result._call))
 
916
        self.assertEqual(test, result._call[0])
 
917
        self.assertEqual(feature, result._call[1])
 
918
        # the result should be successful.
 
919
        self.assertTrue(result.wasSuccessful())
 
920
        # it should record the test against a count of tests not run due to
 
921
        # this feature.
 
922
        self.assertEqual(1, result.unsupported['Feature'])
 
923
        # and invoking it again should increment that counter
 
924
        result.addNotSupported(test, feature)
 
925
        self.assertEqual(2, result.unsupported['Feature'])
 
926
 
 
927
    def test_verbose_report_unsupported(self):
 
928
        # verbose test output formatting
 
929
        result_stream = StringIO()
 
930
        result = bzrlib.tests.VerboseTestResult(
 
931
            unittest._WritelnDecorator(result_stream),
 
932
            descriptions=0,
 
933
            verbosity=2,
 
934
            )
 
935
        test = self.get_passing_test()
 
936
        feature = Feature()
 
937
        result.startTest(test)
 
938
        result.extractBenchmarkTime(test)
 
939
        prefix = len(result_stream.getvalue())
 
940
        result.report_unsupported(test, feature)
 
941
        output = result_stream.getvalue()[prefix:]
 
942
        lines = output.splitlines()
 
943
        self.assertEqual(lines, ['NODEP                   0ms', "    The feature 'Feature' is not available."])
 
944
    
 
945
    def test_text_report_unsupported(self):
 
946
        # text test output formatting
 
947
        pb = MockProgress()
 
948
        result = bzrlib.tests.TextTestResult(
 
949
            None,
 
950
            descriptions=0,
 
951
            verbosity=1,
 
952
            pb=pb,
 
953
            )
 
954
        test = self.get_passing_test()
 
955
        feature = Feature()
 
956
        # this seeds the state to handle reporting the test.
 
957
        result.startTest(test)
 
958
        result.extractBenchmarkTime(test)
 
959
        result.report_unsupported(test, feature)
 
960
        # no output on unsupported features
 
961
        self.assertEqual(
 
962
            [('update', '[1 in 0s] passing_test', None, None)
 
963
            ],
 
964
            pb.calls)
 
965
        # the number of missing features should be printed in the progress
 
966
        # summary, so check for that.
 
967
        result.unsupported = {'foo':0, 'bar':0}
 
968
        test.run(result)
 
969
        self.assertEqual(
 
970
            [
 
971
            ('update', '[2 in 0s, 2 missing features] passing_test', None, None),
 
972
            ],
 
973
            pb.calls[1:])
 
974
    
 
975
    def test_unavailable_exception(self):
 
976
        """An UnavailableFeature being raised should invoke addNotSupported."""
 
977
        class InstrumentedTestResult(ExtendedTestResult):
 
978
 
 
979
            def report_test_start(self, test): pass
 
980
            def addNotSupported(self, test, feature):
 
981
                self._call = test, feature
 
982
        result = InstrumentedTestResult(None, None, None, None)
 
983
        feature = Feature()
 
984
        def test_function():
 
985
            raise UnavailableFeature(feature)
 
986
        test = unittest.FunctionTestCase(test_function)
 
987
        test.run(result)
 
988
        # it should invoke 'addNotSupported'.
 
989
        self.assertEqual(2, len(result._call))
 
990
        self.assertEqual(test, result._call[0])
 
991
        self.assertEqual(feature, result._call[1])
 
992
        # and not count as an error
 
993
        self.assertEqual(0, result.error_count)
 
994
 
 
995
 
 
996
class TestRunner(TestCase):
 
997
 
 
998
    def dummy_test(self):
 
999
        pass
 
1000
 
 
1001
    def run_test_runner(self, testrunner, test):
 
1002
        """Run suite in testrunner, saving global state and restoring it.
 
1003
 
 
1004
        This current saves and restores:
 
1005
        TestCaseInTempDir.TEST_ROOT
 
1006
        
 
1007
        There should be no tests in this file that use bzrlib.tests.TextTestRunner
 
1008
        without using this convenience method, because of our use of global state.
 
1009
        """
 
1010
        old_root = TestCaseInTempDir.TEST_ROOT
 
1011
        try:
 
1012
            TestCaseInTempDir.TEST_ROOT = None
 
1013
            return testrunner.run(test)
 
1014
        finally:
 
1015
            TestCaseInTempDir.TEST_ROOT = old_root
 
1016
 
 
1017
    def test_known_failure_failed_run(self):
 
1018
        # run a test that generates a known failure which should be printed in
 
1019
        # the final output when real failures occur.
 
1020
        def known_failure_test():
 
1021
            raise KnownFailure('failed')
 
1022
        test = unittest.TestSuite()
 
1023
        test.addTest(unittest.FunctionTestCase(known_failure_test))
 
1024
        def failing_test():
 
1025
            raise AssertionError('foo')
 
1026
        test.addTest(unittest.FunctionTestCase(failing_test))
 
1027
        stream = StringIO()
 
1028
        runner = TextTestRunner(stream=stream)
 
1029
        result = self.run_test_runner(runner, test)
 
1030
        lines = stream.getvalue().splitlines()
 
1031
        self.assertEqual([
 
1032
            '',
 
1033
            '======================================================================',
 
1034
            'FAIL: unittest.FunctionTestCase (failing_test)',
 
1035
            '----------------------------------------------------------------------',
 
1036
            'Traceback (most recent call last):',
 
1037
            '    raise AssertionError(\'foo\')',
 
1038
            'AssertionError: foo',
 
1039
            '',
 
1040
            '----------------------------------------------------------------------',
 
1041
            '',
 
1042
            'FAILED (failures=1, known_failure_count=1)'],
 
1043
            lines[0:5] + lines[6:10] + lines[11:])
 
1044
 
 
1045
    def test_known_failure_ok_run(self):
 
1046
        # run a test that generates a known failure which should be printed in the final output.
 
1047
        def known_failure_test():
 
1048
            raise KnownFailure('failed')
 
1049
        test = unittest.FunctionTestCase(known_failure_test)
 
1050
        stream = StringIO()
 
1051
        runner = TextTestRunner(stream=stream)
 
1052
        result = self.run_test_runner(runner, test)
 
1053
        self.assertContainsRe(stream.getvalue(),
 
1054
            '\n'
 
1055
            '-*\n'
 
1056
            'Ran 1 test in .*\n'
 
1057
            '\n'
 
1058
            'OK \\(known_failures=1\\)\n')
 
1059
 
 
1060
    def test_skipped_test(self):
 
1061
        # run a test that is skipped, and check the suite as a whole still
 
1062
        # succeeds.
 
1063
        # skipping_test must be hidden in here so it's not run as a real test
 
1064
        def skipping_test():
 
1065
            raise TestSkipped('test intentionally skipped')
 
1066
 
 
1067
        runner = TextTestRunner(stream=self._log_file)
 
1068
        test = unittest.FunctionTestCase(skipping_test)
 
1069
        result = self.run_test_runner(runner, test)
 
1070
        self.assertTrue(result.wasSuccessful())
 
1071
 
 
1072
    def test_skipped_from_setup(self):
 
1073
        class SkippedSetupTest(TestCase):
 
1074
 
 
1075
            def setUp(self):
 
1076
                self.counter = 1
 
1077
                self.addCleanup(self.cleanup)
 
1078
                raise TestSkipped('skipped setup')
 
1079
 
 
1080
            def test_skip(self):
 
1081
                self.fail('test reached')
 
1082
 
 
1083
            def cleanup(self):
 
1084
                self.counter -= 1
 
1085
 
 
1086
        runner = TextTestRunner(stream=self._log_file)
 
1087
        test = SkippedSetupTest('test_skip')
 
1088
        result = self.run_test_runner(runner, test)
 
1089
        self.assertTrue(result.wasSuccessful())
 
1090
        # Check if cleanup was called the right number of times.
 
1091
        self.assertEqual(0, test.counter)
 
1092
 
 
1093
    def test_skipped_from_test(self):
 
1094
        class SkippedTest(TestCase):
 
1095
 
 
1096
            def setUp(self):
 
1097
                self.counter = 1
 
1098
                self.addCleanup(self.cleanup)
 
1099
 
 
1100
            def test_skip(self):
 
1101
                raise TestSkipped('skipped test')
 
1102
 
 
1103
            def cleanup(self):
 
1104
                self.counter -= 1
 
1105
 
 
1106
        runner = TextTestRunner(stream=self._log_file)
 
1107
        test = SkippedTest('test_skip')
 
1108
        result = self.run_test_runner(runner, test)
 
1109
        self.assertTrue(result.wasSuccessful())
 
1110
        # Check if cleanup was called the right number of times.
 
1111
        self.assertEqual(0, test.counter)
 
1112
 
 
1113
    def test_unsupported_features_listed(self):
 
1114
        """When unsupported features are encountered they are detailed."""
 
1115
        class Feature1(Feature):
 
1116
            def _probe(self): return False
 
1117
        class Feature2(Feature):
 
1118
            def _probe(self): return False
 
1119
        # create sample tests
 
1120
        test1 = SampleTestCase('_test_pass')
 
1121
        test1._test_needs_features = [Feature1()]
 
1122
        test2 = SampleTestCase('_test_pass')
 
1123
        test2._test_needs_features = [Feature2()]
 
1124
        test = unittest.TestSuite()
 
1125
        test.addTest(test1)
 
1126
        test.addTest(test2)
 
1127
        stream = StringIO()
 
1128
        runner = TextTestRunner(stream=stream)
 
1129
        result = self.run_test_runner(runner, test)
 
1130
        lines = stream.getvalue().splitlines()
 
1131
        self.assertEqual([
 
1132
            'OK',
 
1133
            "Missing feature 'Feature1' skipped 1 tests.",
 
1134
            "Missing feature 'Feature2' skipped 1 tests.",
 
1135
            ],
 
1136
            lines[-3:])
 
1137
 
 
1138
    def test_bench_history(self):
 
1139
        # tests that the running the benchmark produces a history file
 
1140
        # containing a timestamp and the revision id of the bzrlib source which
 
1141
        # was tested.
 
1142
        workingtree = _get_bzr_source_tree()
 
1143
        test = TestRunner('dummy_test')
 
1144
        output = StringIO()
 
1145
        runner = TextTestRunner(stream=self._log_file, bench_history=output)
 
1146
        result = self.run_test_runner(runner, test)
 
1147
        output_string = output.getvalue()
 
1148
        self.assertContainsRe(output_string, "--date [0-9.]+")
 
1149
        if workingtree is not None:
 
1150
            revision_id = workingtree.get_parent_ids()[0]
 
1151
            self.assertEndsWith(output_string.rstrip(), revision_id)
 
1152
 
 
1153
    def test_success_log_deleted(self):
 
1154
        """Successful tests have their log deleted"""
 
1155
 
 
1156
        class LogTester(TestCase):
 
1157
 
 
1158
            def test_success(self):
 
1159
                self.log('this will be removed\n')
 
1160
 
 
1161
        sio = cStringIO.StringIO()
 
1162
        runner = TextTestRunner(stream=sio)
 
1163
        test = LogTester('test_success')
 
1164
        result = self.run_test_runner(runner, test)
 
1165
 
 
1166
        log = test._get_log()
 
1167
        self.assertEqual("DELETED log file to reduce memory footprint", log)
 
1168
        self.assertEqual('', test._log_contents)
 
1169
        self.assertIs(None, test._log_file_name)
 
1170
 
 
1171
    def test_fail_log_kept(self):
 
1172
        """Failed tests have their log kept"""
 
1173
 
 
1174
        class LogTester(TestCase):
 
1175
 
 
1176
            def test_fail(self):
 
1177
                self.log('this will be kept\n')
 
1178
                self.fail('this test fails')
 
1179
 
 
1180
        sio = cStringIO.StringIO()
 
1181
        runner = TextTestRunner(stream=sio)
 
1182
        test = LogTester('test_fail')
 
1183
        result = self.run_test_runner(runner, test)
 
1184
 
 
1185
        text = sio.getvalue()
 
1186
        self.assertContainsRe(text, 'this will be kept')
 
1187
        self.assertContainsRe(text, 'this test fails')
 
1188
 
 
1189
        log = test._get_log()
 
1190
        self.assertContainsRe(log, 'this will be kept')
 
1191
        self.assertEqual(log, test._log_contents)
 
1192
 
 
1193
    def test_error_log_kept(self):
 
1194
        """Tests with errors have their log kept"""
 
1195
 
 
1196
        class LogTester(TestCase):
 
1197
 
 
1198
            def test_error(self):
 
1199
                self.log('this will be kept\n')
 
1200
                raise ValueError('random exception raised')
 
1201
 
 
1202
        sio = cStringIO.StringIO()
 
1203
        runner = TextTestRunner(stream=sio)
 
1204
        test = LogTester('test_error')
 
1205
        result = self.run_test_runner(runner, test)
 
1206
 
 
1207
        text = sio.getvalue()
 
1208
        self.assertContainsRe(text, 'this will be kept')
 
1209
        self.assertContainsRe(text, 'random exception raised')
 
1210
 
 
1211
        log = test._get_log()
 
1212
        self.assertContainsRe(log, 'this will be kept')
 
1213
        self.assertEqual(log, test._log_contents)
 
1214
 
 
1215
 
 
1216
class SampleTestCase(TestCase):
 
1217
 
 
1218
    def _test_pass(self):
 
1219
        pass
 
1220
 
 
1221
 
 
1222
class TestTestCase(TestCase):
 
1223
    """Tests that test the core bzrlib TestCase."""
 
1224
 
 
1225
    def inner_test(self):
 
1226
        # the inner child test
 
1227
        note("inner_test")
 
1228
 
 
1229
    def outer_child(self):
 
1230
        # the outer child test
 
1231
        note("outer_start")
 
1232
        self.inner_test = TestTestCase("inner_child")
 
1233
        result = bzrlib.tests.TextTestResult(self._log_file,
 
1234
                                        descriptions=0,
 
1235
                                        verbosity=1)
 
1236
        self.inner_test.run(result)
 
1237
        note("outer finish")
 
1238
 
 
1239
    def test_trace_nesting(self):
 
1240
        # this tests that each test case nests its trace facility correctly.
 
1241
        # we do this by running a test case manually. That test case (A)
 
1242
        # should setup a new log, log content to it, setup a child case (B),
 
1243
        # which should log independently, then case (A) should log a trailer
 
1244
        # and return.
 
1245
        # we do two nested children so that we can verify the state of the 
 
1246
        # logs after the outer child finishes is correct, which a bad clean
 
1247
        # up routine in tearDown might trigger a fault in our test with only
 
1248
        # one child, we should instead see the bad result inside our test with
 
1249
        # the two children.
 
1250
        # the outer child test
 
1251
        original_trace = bzrlib.trace._trace_file
 
1252
        outer_test = TestTestCase("outer_child")
 
1253
        result = bzrlib.tests.TextTestResult(self._log_file,
 
1254
                                        descriptions=0,
 
1255
                                        verbosity=1)
 
1256
        outer_test.run(result)
 
1257
        self.assertEqual(original_trace, bzrlib.trace._trace_file)
 
1258
 
 
1259
    def method_that_times_a_bit_twice(self):
 
1260
        # call self.time twice to ensure it aggregates
 
1261
        self.time(time.sleep, 0.007)
 
1262
        self.time(time.sleep, 0.007)
 
1263
 
 
1264
    def test_time_creates_benchmark_in_result(self):
 
1265
        """Test that the TestCase.time() method accumulates a benchmark time."""
 
1266
        sample_test = TestTestCase("method_that_times_a_bit_twice")
 
1267
        output_stream = StringIO()
 
1268
        result = bzrlib.tests.VerboseTestResult(
 
1269
            unittest._WritelnDecorator(output_stream),
 
1270
            descriptions=0,
 
1271
            verbosity=2,
 
1272
            num_tests=sample_test.countTestCases())
 
1273
        sample_test.run(result)
 
1274
        self.assertContainsRe(
 
1275
            output_stream.getvalue(),
 
1276
            r"\d+ms/ +\d+ms\n$")
 
1277
 
 
1278
    def test_hooks_sanitised(self):
 
1279
        """The bzrlib hooks should be sanitised by setUp."""
 
1280
        self.assertEqual(bzrlib.branch.BranchHooks(),
 
1281
            bzrlib.branch.Branch.hooks)
 
1282
        self.assertEqual(bzrlib.smart.server.SmartServerHooks(),
 
1283
            bzrlib.smart.server.SmartTCPServer.hooks)
 
1284
 
 
1285
    def test__gather_lsprof_in_benchmarks(self):
 
1286
        """When _gather_lsprof_in_benchmarks is on, accumulate profile data.
 
1287
        
 
1288
        Each self.time() call is individually and separately profiled.
 
1289
        """
 
1290
        self.requireFeature(test_lsprof.LSProfFeature)
 
1291
        # overrides the class member with an instance member so no cleanup 
 
1292
        # needed.
 
1293
        self._gather_lsprof_in_benchmarks = True
 
1294
        self.time(time.sleep, 0.000)
 
1295
        self.time(time.sleep, 0.003)
 
1296
        self.assertEqual(2, len(self._benchcalls))
 
1297
        self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
 
1298
        self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
 
1299
        self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
 
1300
        self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
 
1301
 
 
1302
    def test_knownFailure(self):
 
1303
        """Self.knownFailure() should raise a KnownFailure exception."""
 
1304
        self.assertRaises(KnownFailure, self.knownFailure, "A Failure")
 
1305
 
 
1306
    def test_requireFeature_available(self):
 
1307
        """self.requireFeature(available) is a no-op."""
 
1308
        class Available(Feature):
 
1309
            def _probe(self):return True
 
1310
        feature = Available()
 
1311
        self.requireFeature(feature)
 
1312
 
 
1313
    def test_requireFeature_unavailable(self):
 
1314
        """self.requireFeature(unavailable) raises UnavailableFeature."""
 
1315
        class Unavailable(Feature):
 
1316
            def _probe(self):return False
 
1317
        feature = Unavailable()
 
1318
        self.assertRaises(UnavailableFeature, self.requireFeature, feature)
 
1319
 
 
1320
    def test_run_no_parameters(self):
 
1321
        test = SampleTestCase('_test_pass')
 
1322
        test.run()
 
1323
    
 
1324
    def test_run_enabled_unittest_result(self):
 
1325
        """Test we revert to regular behaviour when the test is enabled."""
 
1326
        test = SampleTestCase('_test_pass')
 
1327
        class EnabledFeature(object):
 
1328
            def available(self):
 
1329
                return True
 
1330
        test._test_needs_features = [EnabledFeature()]
 
1331
        result = unittest.TestResult()
 
1332
        test.run(result)
 
1333
        self.assertEqual(1, result.testsRun)
 
1334
        self.assertEqual([], result.errors)
 
1335
        self.assertEqual([], result.failures)
 
1336
 
 
1337
    def test_run_disabled_unittest_result(self):
 
1338
        """Test our compatability for disabled tests with unittest results."""
 
1339
        test = SampleTestCase('_test_pass')
 
1340
        class DisabledFeature(object):
 
1341
            def available(self):
 
1342
                return False
 
1343
        test._test_needs_features = [DisabledFeature()]
 
1344
        result = unittest.TestResult()
 
1345
        test.run(result)
 
1346
        self.assertEqual(1, result.testsRun)
 
1347
        self.assertEqual([], result.errors)
 
1348
        self.assertEqual([], result.failures)
 
1349
 
 
1350
    def test_run_disabled_supporting_result(self):
 
1351
        """Test disabled tests behaviour with support aware results."""
 
1352
        test = SampleTestCase('_test_pass')
 
1353
        class DisabledFeature(object):
 
1354
            def available(self):
 
1355
                return False
 
1356
        the_feature = DisabledFeature()
 
1357
        test._test_needs_features = [the_feature]
 
1358
        class InstrumentedTestResult(unittest.TestResult):
 
1359
            def __init__(self):
 
1360
                unittest.TestResult.__init__(self)
 
1361
                self.calls = []
 
1362
            def startTest(self, test):
 
1363
                self.calls.append(('startTest', test))
 
1364
            def stopTest(self, test):
 
1365
                self.calls.append(('stopTest', test))
 
1366
            def addNotSupported(self, test, feature):
 
1367
                self.calls.append(('addNotSupported', test, feature))
 
1368
        result = InstrumentedTestResult()
 
1369
        test.run(result)
 
1370
        self.assertEqual([
 
1371
            ('startTest', test),
 
1372
            ('addNotSupported', test, the_feature),
 
1373
            ('stopTest', test),
 
1374
            ],
 
1375
            result.calls)
 
1376
 
 
1377
 
 
1378
@symbol_versioning.deprecated_function(zero_eleven)
 
1379
def sample_deprecated_function():
 
1380
    """A deprecated function to test applyDeprecated with."""
 
1381
    return 2
 
1382
 
 
1383
 
 
1384
def sample_undeprecated_function(a_param):
 
1385
    """A undeprecated function to test applyDeprecated with."""
 
1386
 
 
1387
 
 
1388
class ApplyDeprecatedHelper(object):
 
1389
    """A helper class for ApplyDeprecated tests."""
 
1390
 
 
1391
    @symbol_versioning.deprecated_method(zero_eleven)
 
1392
    def sample_deprecated_method(self, param_one):
 
1393
        """A deprecated method for testing with."""
 
1394
        return param_one
 
1395
 
 
1396
    def sample_normal_method(self):
 
1397
        """A undeprecated method."""
 
1398
 
 
1399
    @symbol_versioning.deprecated_method(zero_ten)
 
1400
    def sample_nested_deprecation(self):
 
1401
        return sample_deprecated_function()
 
1402
 
 
1403
 
 
1404
class TestExtraAssertions(TestCase):
 
1405
    """Tests for new test assertions in bzrlib test suite"""
 
1406
 
 
1407
    def test_assert_isinstance(self):
 
1408
        self.assertIsInstance(2, int)
 
1409
        self.assertIsInstance(u'', basestring)
 
1410
        self.assertRaises(AssertionError, self.assertIsInstance, None, int)
 
1411
        self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
 
1412
 
 
1413
    def test_assertEndsWith(self):
 
1414
        self.assertEndsWith('foo', 'oo')
 
1415
        self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
 
1416
 
 
1417
    def test_applyDeprecated_not_deprecated(self):
 
1418
        sample_object = ApplyDeprecatedHelper()
 
1419
        # calling an undeprecated callable raises an assertion
 
1420
        self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
 
1421
            sample_object.sample_normal_method)
 
1422
        self.assertRaises(AssertionError, self.applyDeprecated, zero_eleven,
 
1423
            sample_undeprecated_function, "a param value")
 
1424
        # calling a deprecated callable (function or method) with the wrong
 
1425
        # expected deprecation fails.
 
1426
        self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
 
1427
            sample_object.sample_deprecated_method, "a param value")
 
1428
        self.assertRaises(AssertionError, self.applyDeprecated, zero_ten,
 
1429
            sample_deprecated_function)
 
1430
        # calling a deprecated callable (function or method) with the right
 
1431
        # expected deprecation returns the functions result.
 
1432
        self.assertEqual("a param value", self.applyDeprecated(zero_eleven,
 
1433
            sample_object.sample_deprecated_method, "a param value"))
 
1434
        self.assertEqual(2, self.applyDeprecated(zero_eleven,
 
1435
            sample_deprecated_function))
 
1436
        # calling a nested deprecation with the wrong deprecation version
 
1437
        # fails even if a deeper nested function was deprecated with the 
 
1438
        # supplied version.
 
1439
        self.assertRaises(AssertionError, self.applyDeprecated,
 
1440
            zero_eleven, sample_object.sample_nested_deprecation)
 
1441
        # calling a nested deprecation with the right deprecation value
 
1442
        # returns the calls result.
 
1443
        self.assertEqual(2, self.applyDeprecated(zero_ten,
 
1444
            sample_object.sample_nested_deprecation))
 
1445
 
 
1446
    def test_callDeprecated(self):
 
1447
        def testfunc(be_deprecated, result=None):
 
1448
            if be_deprecated is True:
 
1449
                symbol_versioning.warn('i am deprecated', DeprecationWarning, 
 
1450
                                       stacklevel=1)
 
1451
            return result
 
1452
        result = self.callDeprecated(['i am deprecated'], testfunc, True)
 
1453
        self.assertIs(None, result)
 
1454
        result = self.callDeprecated([], testfunc, False, 'result')
 
1455
        self.assertEqual('result', result)
 
1456
        self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
 
1457
        self.callDeprecated([], testfunc, be_deprecated=False)
 
1458
 
 
1459
 
 
1460
class TestConvenienceMakers(TestCaseWithTransport):
 
1461
    """Test for the make_* convenience functions."""
 
1462
 
 
1463
    def test_make_branch_and_tree_with_format(self):
 
1464
        # we should be able to supply a format to make_branch_and_tree
 
1465
        self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
 
1466
        self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
 
1467
        self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
 
1468
                              bzrlib.bzrdir.BzrDirMetaFormat1)
 
1469
        self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
 
1470
                              bzrlib.bzrdir.BzrDirFormat6)
 
1471
 
 
1472
    def test_make_branch_and_memory_tree(self):
 
1473
        # we should be able to get a new branch and a mutable tree from
 
1474
        # TestCaseWithTransport
 
1475
        tree = self.make_branch_and_memory_tree('a')
 
1476
        self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
 
1477
 
 
1478
 
 
1479
class TestSFTPMakeBranchAndTree(TestCaseWithSFTPServer):
 
1480
 
 
1481
    def test_make_tree_for_sftp_branch(self):
 
1482
        """Transports backed by local directories create local trees."""
 
1483
 
 
1484
        tree = self.make_branch_and_tree('t1')
 
1485
        base = tree.bzrdir.root_transport.base
 
1486
        self.failIf(base.startswith('sftp'),
 
1487
                'base %r is on sftp but should be local' % base)
 
1488
        self.assertEquals(tree.bzrdir.root_transport,
 
1489
                tree.branch.bzrdir.root_transport)
 
1490
        self.assertEquals(tree.bzrdir.root_transport,
 
1491
                tree.branch.repository.bzrdir.root_transport)
 
1492
 
 
1493
 
 
1494
class TestSelftest(TestCase):
 
1495
    """Tests of bzrlib.tests.selftest."""
 
1496
 
 
1497
    def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
 
1498
        factory_called = []
 
1499
        def factory():
 
1500
            factory_called.append(True)
 
1501
            return TestSuite()
 
1502
        out = StringIO()
 
1503
        err = StringIO()
 
1504
        self.apply_redirected(out, err, None, bzrlib.tests.selftest, 
 
1505
            test_suite_factory=factory)
 
1506
        self.assertEqual([True], factory_called)
 
1507
 
 
1508
 
 
1509
class TestSelftestCleanOutput(TestCaseInTempDir):
 
1510
 
 
1511
    def test_clean_output(self):
 
1512
        # test functionality of clean_selftest_output()
 
1513
        self.build_tree(['test0000.tmp/', 'test0001.tmp/',
 
1514
                         'bzrlib/', 'tests/',
 
1515
                         'bzr', 'setup.py', 'test9999.tmp'])
 
1516
 
 
1517
        root = os.getcwdu()
 
1518
        before = os.listdir(root)
 
1519
        before.sort()
 
1520
        self.assertEquals(['bzr','bzrlib','setup.py',
 
1521
                           'test0000.tmp','test0001.tmp',
 
1522
                           'test9999.tmp','tests'],
 
1523
                           before)
 
1524
        clean_selftest_output(root, quiet=True)
 
1525
        after = os.listdir(root)
 
1526
        after.sort()
 
1527
        self.assertEquals(['bzr','bzrlib','setup.py',
 
1528
                           'test9999.tmp','tests'],
 
1529
                           after)
 
1530
 
 
1531
    def test_clean_readonly(self):
 
1532
        # test for delete read-only files
 
1533
        self.build_tree(['test0000.tmp/', 'test0000.tmp/foo'])
 
1534
        osutils.make_readonly('test0000.tmp/foo')
 
1535
        root = os.getcwdu()
 
1536
        before = os.listdir(root);  before.sort()
 
1537
        self.assertEquals(['test0000.tmp'], before)
 
1538
        clean_selftest_output(root, quiet=True)
 
1539
        after = os.listdir(root);   after.sort()
 
1540
        self.assertEquals([], after)
 
1541
 
 
1542
 
 
1543
class TestKnownFailure(TestCase):
 
1544
 
 
1545
    def test_known_failure(self):
 
1546
        """Check that KnownFailure is defined appropriately."""
 
1547
        # a KnownFailure is an assertion error for compatability with unaware
 
1548
        # runners.
 
1549
        self.assertIsInstance(KnownFailure(""), AssertionError)
 
1550
 
 
1551
    def test_expect_failure(self):
 
1552
        try:
 
1553
            self.expectFailure("Doomed to failure", self.assertTrue, False)
 
1554
        except KnownFailure, e:
 
1555
            self.assertEqual('Doomed to failure', e.args[0])
 
1556
        try:
 
1557
            self.expectFailure("Doomed to failure", self.assertTrue, True)
 
1558
        except AssertionError, e:
 
1559
            self.assertEqual('Unexpected success.  Should have failed:'
 
1560
                             ' Doomed to failure', e.args[0])
 
1561
        else:
 
1562
            self.fail('Assertion not raised')
 
1563
 
 
1564
 
 
1565
class TestFeature(TestCase):
 
1566
 
 
1567
    def test_caching(self):
 
1568
        """Feature._probe is called by the feature at most once."""
 
1569
        class InstrumentedFeature(Feature):
 
1570
            def __init__(self):
 
1571
                Feature.__init__(self)
 
1572
                self.calls = []
 
1573
            def _probe(self):
 
1574
                self.calls.append('_probe')
 
1575
                return False
 
1576
        feature = InstrumentedFeature()
 
1577
        feature.available()
 
1578
        self.assertEqual(['_probe'], feature.calls)
 
1579
        feature.available()
 
1580
        self.assertEqual(['_probe'], feature.calls)
 
1581
 
 
1582
    def test_named_str(self):
 
1583
        """Feature.__str__ should thunk to feature_name()."""
 
1584
        class NamedFeature(Feature):
 
1585
            def feature_name(self):
 
1586
                return 'symlinks'
 
1587
        feature = NamedFeature()
 
1588
        self.assertEqual('symlinks', str(feature))
 
1589
 
 
1590
    def test_default_str(self):
 
1591
        """Feature.__str__ should default to __class__.__name__."""
 
1592
        class NamedFeature(Feature):
 
1593
            pass
 
1594
        feature = NamedFeature()
 
1595
        self.assertEqual('NamedFeature', str(feature))
 
1596
 
 
1597
 
 
1598
class TestUnavailableFeature(TestCase):
 
1599
 
 
1600
    def test_access_feature(self):
 
1601
        feature = Feature()
 
1602
        exception = UnavailableFeature(feature)
 
1603
        self.assertIs(feature, exception.args[0])
 
1604
 
 
1605
 
 
1606
class TestSelftestFiltering(TestCase):
 
1607
 
 
1608
    def setUp(self):
 
1609
        self.suite = TestUtil.TestSuite()
 
1610
        self.loader = TestUtil.TestLoader()
 
1611
        self.suite.addTest(self.loader.loadTestsFromModuleNames([
 
1612
            'bzrlib.tests.test_selftest']))
 
1613
        self.all_names = [t.id() for t in iter_suite_tests(self.suite)]
 
1614
 
 
1615
    def test_filter_suite_by_re(self):
 
1616
        filtered_suite = filter_suite_by_re(self.suite, 'test_filter')
 
1617
        filtered_names = [t.id() for t in iter_suite_tests(filtered_suite)]
 
1618
        self.assertEqual(filtered_names, ['bzrlib.tests.test_selftest.'
 
1619
            'TestSelftestFiltering.test_filter_suite_by_re'])
 
1620
            
 
1621
    def test_sort_suite_by_re(self):
 
1622
        sorted_suite = sort_suite_by_re(self.suite, 'test_filter')
 
1623
        sorted_names = [t.id() for t in iter_suite_tests(sorted_suite)]
 
1624
        self.assertEqual(sorted_names[0], 'bzrlib.tests.test_selftest.'
 
1625
            'TestSelftestFiltering.test_filter_suite_by_re')
 
1626
        self.assertEquals(sorted(self.all_names), sorted(sorted_names))
 
1627