~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

Don't encode unicode messages to UTF-8 in mutter() (the stream writer does it).

Use a codec wrapped log file in tests to match the real environment.

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