/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

Fix test_commit for use with 2a as the default repository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""Tests for the test framework."""
 
18
 
 
19
from cStringIO import StringIO
 
20
import os
 
21
import sys
 
22
import time
 
23
import unittest
 
24
import warnings
 
25
 
 
26
import bzrlib
 
27
from bzrlib import (
 
28
    branchbuilder,
 
29
    bzrdir,
 
30
    debug,
 
31
    errors,
 
32
    lockdir,
 
33
    memorytree,
 
34
    osutils,
 
35
    progress,
 
36
    remote,
 
37
    repository,
 
38
    symbol_versioning,
 
39
    tests,
 
40
    workingtree,
 
41
    )
 
42
from bzrlib.repofmt import (
 
43
    pack_repo,
 
44
    weaverepo,
 
45
    )
 
46
from bzrlib.symbol_versioning import (
 
47
    deprecated_function,
 
48
    deprecated_in,
 
49
    deprecated_method,
 
50
    )
 
51
from bzrlib.tests import (
 
52
    test_lsprof,
 
53
    test_sftp_transport,
 
54
    TestUtil,
 
55
    )
 
56
from bzrlib.trace import note
 
57
from bzrlib.transport.memory import MemoryServer, MemoryTransport
 
58
from bzrlib.version import _get_bzr_source_tree
 
59
 
 
60
 
 
61
def _test_ids(test_suite):
 
62
    """Get the ids for the tests in a test suite."""
 
63
    return [t.id() for t in tests.iter_suite_tests(test_suite)]
 
64
 
 
65
 
 
66
class SelftestTests(tests.TestCase):
 
67
 
 
68
    def test_import_tests(self):
 
69
        mod = TestUtil._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
                          TestUtil._load_module_by_name,
 
75
                          'bzrlib.no-name-yet')
 
76
 
 
77
class MetaTestLog(tests.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 TestUnicodeFilename(tests.TestCase):
 
88
 
 
89
    def test_probe_passes(self):
 
90
        """UnicodeFilename._probe passes."""
 
91
        # We can't test much more than that because the behaviour depends
 
92
        # on the platform.
 
93
        tests.UnicodeFilename._probe()
 
94
 
 
95
 
 
96
class TestTreeShape(tests.TestCaseInTempDir):
 
97
 
 
98
    def test_unicode_paths(self):
 
99
        self.requireFeature(tests.UnicodeFilename)
 
100
 
 
101
        filename = u'hell\u00d8'
 
102
        self.build_tree_contents([(filename, 'contents of hello')])
 
103
        self.failUnlessExists(filename)
 
104
 
 
105
 
 
106
class TestTransportScenarios(tests.TestCase):
 
107
    """A group of tests that test the transport implementation adaption core.
 
108
 
 
109
    This is a meta test that the tests are applied to all available
 
110
    transports.
 
111
 
 
112
    This will be generalised in the future which is why it is in this
 
113
    test file even though it is specific to transport tests at the moment.
 
114
    """
 
115
 
 
116
    def test_get_transport_permutations(self):
 
117
        # this checks that get_test_permutations defined by the module is
 
118
        # called by the get_transport_test_permutations function.
 
119
        class MockModule(object):
 
120
            def get_test_permutations(self):
 
121
                return sample_permutation
 
122
        sample_permutation = [(1,2), (3,4)]
 
123
        from bzrlib.tests.per_transport import get_transport_test_permutations
 
124
        self.assertEqual(sample_permutation,
 
125
                         get_transport_test_permutations(MockModule()))
 
126
 
 
127
    def test_scenarios_include_all_modules(self):
 
128
        # this checks that the scenario generator returns as many permutations
 
129
        # as there are in all the registered transport modules - we assume if
 
130
        # this matches its probably doing the right thing especially in
 
131
        # combination with the tests for setting the right classes below.
 
132
        from bzrlib.tests.per_transport import transport_test_permutations
 
133
        from bzrlib.transport import _get_transport_modules
 
134
        modules = _get_transport_modules()
 
135
        permutation_count = 0
 
136
        for module in modules:
 
137
            try:
 
138
                permutation_count += len(reduce(getattr,
 
139
                    (module + ".get_test_permutations").split('.')[1:],
 
140
                     __import__(module))())
 
141
            except errors.DependencyNotPresent:
 
142
                pass
 
143
        scenarios = transport_test_permutations()
 
144
        self.assertEqual(permutation_count, len(scenarios))
 
145
 
 
146
    def test_scenarios_include_transport_class(self):
 
147
        # This test used to know about all the possible transports and the
 
148
        # order they were returned but that seems overly brittle (mbp
 
149
        # 20060307)
 
150
        from bzrlib.tests.per_transport import transport_test_permutations
 
151
        scenarios = transport_test_permutations()
 
152
        # there are at least that many builtin transports
 
153
        self.assertTrue(len(scenarios) > 6)
 
154
        one_scenario = scenarios[0]
 
155
        self.assertIsInstance(one_scenario[0], str)
 
156
        self.assertTrue(issubclass(one_scenario[1]["transport_class"],
 
157
                                   bzrlib.transport.Transport))
 
158
        self.assertTrue(issubclass(one_scenario[1]["transport_server"],
 
159
                                   bzrlib.transport.Server))
 
160
 
 
161
 
 
162
class TestBranchScenarios(tests.TestCase):
 
163
 
 
164
    def test_scenarios(self):
 
165
        # check that constructor parameters are passed through to the adapted
 
166
        # test.
 
167
        from bzrlib.tests.per_branch import make_scenarios
 
168
        server1 = "a"
 
169
        server2 = "b"
 
170
        formats = [("c", "C"), ("d", "D")]
 
171
        scenarios = make_scenarios(server1, server2, formats)
 
172
        self.assertEqual(2, len(scenarios))
 
173
        self.assertEqual([
 
174
            ('str',
 
175
             {'branch_format': 'c',
 
176
              'bzrdir_format': 'C',
 
177
              'transport_readonly_server': 'b',
 
178
              'transport_server': 'a'}),
 
179
            ('str',
 
180
             {'branch_format': 'd',
 
181
              'bzrdir_format': 'D',
 
182
              'transport_readonly_server': 'b',
 
183
              'transport_server': 'a'})],
 
184
            scenarios)
 
185
 
 
186
 
 
187
class TestBzrDirScenarios(tests.TestCase):
 
188
 
 
189
    def test_scenarios(self):
 
190
        # check that constructor parameters are passed through to the adapted
 
191
        # test.
 
192
        from bzrlib.tests.per_bzrdir import make_scenarios
 
193
        vfs_factory = "v"
 
194
        server1 = "a"
 
195
        server2 = "b"
 
196
        formats = ["c", "d"]
 
197
        scenarios = make_scenarios(vfs_factory, server1, server2, formats)
 
198
        self.assertEqual([
 
199
            ('str',
 
200
             {'bzrdir_format': 'c',
 
201
              'transport_readonly_server': 'b',
 
202
              'transport_server': 'a',
 
203
              'vfs_transport_factory': 'v'}),
 
204
            ('str',
 
205
             {'bzrdir_format': 'd',
 
206
              'transport_readonly_server': 'b',
 
207
              'transport_server': 'a',
 
208
              'vfs_transport_factory': 'v'})],
 
209
            scenarios)
 
210
 
 
211
 
 
212
class TestRepositoryScenarios(tests.TestCase):
 
213
 
 
214
    def test_formats_to_scenarios(self):
 
215
        from bzrlib.tests.per_repository import formats_to_scenarios
 
216
        formats = [("(c)", remote.RemoteRepositoryFormat()),
 
217
                   ("(d)", repository.format_registry.get(
 
218
                        'Bazaar pack repository format 1 (needs bzr 0.92)\n'))]
 
219
        no_vfs_scenarios = formats_to_scenarios(formats, "server", "readonly",
 
220
            None)
 
221
        vfs_scenarios = formats_to_scenarios(formats, "server", "readonly",
 
222
            vfs_transport_factory="vfs")
 
223
        # no_vfs generate scenarios without vfs_transport_factory
 
224
        self.assertEqual([
 
225
            ('RemoteRepositoryFormat(c)',
 
226
             {'bzrdir_format': remote.RemoteBzrDirFormat(),
 
227
              'repository_format': remote.RemoteRepositoryFormat(),
 
228
              'transport_readonly_server': 'readonly',
 
229
              'transport_server': 'server'}),
 
230
            ('RepositoryFormatKnitPack1(d)',
 
231
             {'bzrdir_format': bzrdir.BzrDirMetaFormat1(),
 
232
              'repository_format': pack_repo.RepositoryFormatKnitPack1(),
 
233
              'transport_readonly_server': 'readonly',
 
234
              'transport_server': 'server'})],
 
235
            no_vfs_scenarios)
 
236
        self.assertEqual([
 
237
            ('RemoteRepositoryFormat(c)',
 
238
             {'bzrdir_format': remote.RemoteBzrDirFormat(),
 
239
              'repository_format': remote.RemoteRepositoryFormat(),
 
240
              'transport_readonly_server': 'readonly',
 
241
              'transport_server': 'server',
 
242
              'vfs_transport_factory': 'vfs'}),
 
243
            ('RepositoryFormatKnitPack1(d)',
 
244
             {'bzrdir_format': bzrdir.BzrDirMetaFormat1(),
 
245
              'repository_format': pack_repo.RepositoryFormatKnitPack1(),
 
246
              'transport_readonly_server': 'readonly',
 
247
              'transport_server': 'server',
 
248
              'vfs_transport_factory': 'vfs'})],
 
249
            vfs_scenarios)
 
250
 
 
251
 
 
252
class TestTestScenarioApplication(tests.TestCase):
 
253
    """Tests for the test adaption facilities."""
 
254
 
 
255
    def test_apply_scenario(self):
 
256
        from bzrlib.tests import apply_scenario
 
257
        input_test = TestTestScenarioApplication("test_apply_scenario")
 
258
        # setup two adapted tests
 
259
        adapted_test1 = apply_scenario(input_test,
 
260
            ("new id",
 
261
            {"bzrdir_format":"bzr_format",
 
262
             "repository_format":"repo_fmt",
 
263
             "transport_server":"transport_server",
 
264
             "transport_readonly_server":"readonly-server"}))
 
265
        adapted_test2 = apply_scenario(input_test,
 
266
            ("new id 2", {"bzrdir_format":None}))
 
267
        # input_test should have been altered.
 
268
        self.assertRaises(AttributeError, getattr, input_test, "bzrdir_format")
 
269
        # the new tests are mutually incompatible, ensuring it has
 
270
        # made new ones, and unspecified elements in the scenario
 
271
        # should not have been altered.
 
272
        self.assertEqual("bzr_format", adapted_test1.bzrdir_format)
 
273
        self.assertEqual("repo_fmt", adapted_test1.repository_format)
 
274
        self.assertEqual("transport_server", adapted_test1.transport_server)
 
275
        self.assertEqual("readonly-server",
 
276
            adapted_test1.transport_readonly_server)
 
277
        self.assertEqual(
 
278
            "bzrlib.tests.test_selftest.TestTestScenarioApplication."
 
279
            "test_apply_scenario(new id)",
 
280
            adapted_test1.id())
 
281
        self.assertEqual(None, adapted_test2.bzrdir_format)
 
282
        self.assertEqual(
 
283
            "bzrlib.tests.test_selftest.TestTestScenarioApplication."
 
284
            "test_apply_scenario(new id 2)",
 
285
            adapted_test2.id())
 
286
 
 
287
 
 
288
class TestInterRepositoryScenarios(tests.TestCase):
 
289
 
 
290
    def test_scenarios(self):
 
291
        # check that constructor parameters are passed through to the adapted
 
292
        # test.
 
293
        from bzrlib.tests.per_interrepository import make_scenarios
 
294
        server1 = "a"
 
295
        server2 = "b"
 
296
        formats = [("C0", "C1", "C2"), ("D0", "D1", "D2")]
 
297
        scenarios = make_scenarios(server1, server2, formats)
 
298
        self.assertEqual([
 
299
            ('C0,str,str',
 
300
             {'repository_format': 'C1',
 
301
              'repository_format_to': 'C2',
 
302
              'transport_readonly_server': 'b',
 
303
              'transport_server': 'a'}),
 
304
            ('D0,str,str',
 
305
             {'repository_format': 'D1',
 
306
              'repository_format_to': 'D2',
 
307
              'transport_readonly_server': 'b',
 
308
              'transport_server': 'a'})],
 
309
            scenarios)
 
310
 
 
311
 
 
312
class TestWorkingTreeScenarios(tests.TestCase):
 
313
 
 
314
    def test_scenarios(self):
 
315
        # check that constructor parameters are passed through to the adapted
 
316
        # test.
 
317
        from bzrlib.tests.per_workingtree import make_scenarios
 
318
        server1 = "a"
 
319
        server2 = "b"
 
320
        formats = [workingtree.WorkingTreeFormat2(),
 
321
                   workingtree.WorkingTreeFormat3(),]
 
322
        scenarios = make_scenarios(server1, server2, formats)
 
323
        self.assertEqual([
 
324
            ('WorkingTreeFormat2',
 
325
             {'bzrdir_format': formats[0]._matchingbzrdir,
 
326
              'transport_readonly_server': 'b',
 
327
              'transport_server': 'a',
 
328
              'workingtree_format': formats[0]}),
 
329
            ('WorkingTreeFormat3',
 
330
             {'bzrdir_format': formats[1]._matchingbzrdir,
 
331
              'transport_readonly_server': 'b',
 
332
              'transport_server': 'a',
 
333
              'workingtree_format': formats[1]})],
 
334
            scenarios)
 
335
 
 
336
 
 
337
class TestTreeScenarios(tests.TestCase):
 
338
 
 
339
    def test_scenarios(self):
 
340
        # the tree implementation scenario generator is meant to setup one
 
341
        # instance for each working tree format, and one additional instance
 
342
        # that will use the default wt format, but create a revision tree for
 
343
        # the tests.  this means that the wt ones should have the
 
344
        # workingtree_to_test_tree attribute set to 'return_parameter' and the
 
345
        # revision one set to revision_tree_from_workingtree.
 
346
 
 
347
        from bzrlib.tests.per_tree import (
 
348
            _dirstate_tree_from_workingtree,
 
349
            make_scenarios,
 
350
            preview_tree_pre,
 
351
            preview_tree_post,
 
352
            return_parameter,
 
353
            revision_tree_from_workingtree
 
354
            )
 
355
        server1 = "a"
 
356
        server2 = "b"
 
357
        formats = [workingtree.WorkingTreeFormat2(),
 
358
                   workingtree.WorkingTreeFormat3(),]
 
359
        scenarios = make_scenarios(server1, server2, formats)
 
360
        self.assertEqual(7, len(scenarios))
 
361
        default_wt_format = workingtree.WorkingTreeFormat4._default_format
 
362
        wt4_format = workingtree.WorkingTreeFormat4()
 
363
        wt5_format = workingtree.WorkingTreeFormat5()
 
364
        expected_scenarios = [
 
365
            ('WorkingTreeFormat2',
 
366
             {'bzrdir_format': formats[0]._matchingbzrdir,
 
367
              'transport_readonly_server': 'b',
 
368
              'transport_server': 'a',
 
369
              'workingtree_format': formats[0],
 
370
              '_workingtree_to_test_tree': return_parameter,
 
371
              }),
 
372
            ('WorkingTreeFormat3',
 
373
             {'bzrdir_format': formats[1]._matchingbzrdir,
 
374
              'transport_readonly_server': 'b',
 
375
              'transport_server': 'a',
 
376
              'workingtree_format': formats[1],
 
377
              '_workingtree_to_test_tree': return_parameter,
 
378
             }),
 
379
            ('RevisionTree',
 
380
             {'_workingtree_to_test_tree': revision_tree_from_workingtree,
 
381
              'bzrdir_format': default_wt_format._matchingbzrdir,
 
382
              'transport_readonly_server': 'b',
 
383
              'transport_server': 'a',
 
384
              'workingtree_format': default_wt_format,
 
385
             }),
 
386
            ('DirStateRevisionTree,WT4',
 
387
             {'_workingtree_to_test_tree': _dirstate_tree_from_workingtree,
 
388
              'bzrdir_format': wt4_format._matchingbzrdir,
 
389
              'transport_readonly_server': 'b',
 
390
              'transport_server': 'a',
 
391
              'workingtree_format': wt4_format,
 
392
             }),
 
393
            ('DirStateRevisionTree,WT5',
 
394
             {'_workingtree_to_test_tree': _dirstate_tree_from_workingtree,
 
395
              'bzrdir_format': wt5_format._matchingbzrdir,
 
396
              'transport_readonly_server': 'b',
 
397
              'transport_server': 'a',
 
398
              'workingtree_format': wt5_format,
 
399
             }),
 
400
            ('PreviewTree',
 
401
             {'_workingtree_to_test_tree': preview_tree_pre,
 
402
              'bzrdir_format': default_wt_format._matchingbzrdir,
 
403
              'transport_readonly_server': 'b',
 
404
              'transport_server': 'a',
 
405
              'workingtree_format': default_wt_format}),
 
406
            ('PreviewTreePost',
 
407
             {'_workingtree_to_test_tree': preview_tree_post,
 
408
              'bzrdir_format': default_wt_format._matchingbzrdir,
 
409
              'transport_readonly_server': 'b',
 
410
              'transport_server': 'a',
 
411
              'workingtree_format': default_wt_format}),
 
412
             ]
 
413
        self.assertEqual(expected_scenarios, scenarios)
 
414
 
 
415
 
 
416
class TestInterTreeScenarios(tests.TestCase):
 
417
    """A group of tests that test the InterTreeTestAdapter."""
 
418
 
 
419
    def test_scenarios(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
        # parameterized one for WorkingTree - the optimisers will tell us what
 
428
        # ones to add.
 
429
        from bzrlib.tests.per_tree import (
 
430
            return_parameter,
 
431
            revision_tree_from_workingtree
 
432
            )
 
433
        from bzrlib.tests.per_intertree import (
 
434
            make_scenarios,
 
435
            )
 
436
        from bzrlib.workingtree import WorkingTreeFormat2, WorkingTreeFormat3
 
437
        input_test = TestInterTreeScenarios(
 
438
            "test_scenarios")
 
439
        server1 = "a"
 
440
        server2 = "b"
 
441
        format1 = WorkingTreeFormat2()
 
442
        format2 = WorkingTreeFormat3()
 
443
        formats = [("1", str, format1, format2, "converter1"),
 
444
            ("2", int, format2, format1, "converter2")]
 
445
        scenarios = make_scenarios(server1, server2, formats)
 
446
        self.assertEqual(2, len(scenarios))
 
447
        expected_scenarios = [
 
448
            ("1", {
 
449
                "bzrdir_format": format1._matchingbzrdir,
 
450
                "intertree_class": formats[0][1],
 
451
                "workingtree_format": formats[0][2],
 
452
                "workingtree_format_to": formats[0][3],
 
453
                "mutable_trees_to_test_trees": formats[0][4],
 
454
                "_workingtree_to_test_tree": return_parameter,
 
455
                "transport_server": server1,
 
456
                "transport_readonly_server": server2,
 
457
                }),
 
458
            ("2", {
 
459
                "bzrdir_format": format2._matchingbzrdir,
 
460
                "intertree_class": formats[1][1],
 
461
                "workingtree_format": formats[1][2],
 
462
                "workingtree_format_to": formats[1][3],
 
463
                "mutable_trees_to_test_trees": formats[1][4],
 
464
                "_workingtree_to_test_tree": return_parameter,
 
465
                "transport_server": server1,
 
466
                "transport_readonly_server": server2,
 
467
                }),
 
468
            ]
 
469
        self.assertEqual(scenarios, expected_scenarios)
 
470
 
 
471
 
 
472
class TestTestCaseInTempDir(tests.TestCaseInTempDir):
 
473
 
 
474
    def test_home_is_not_working(self):
 
475
        self.assertNotEqual(self.test_dir, self.test_home_dir)
 
476
        cwd = osutils.getcwd()
 
477
        self.assertIsSameRealPath(self.test_dir, cwd)
 
478
        self.assertIsSameRealPath(self.test_home_dir, os.environ['HOME'])
 
479
 
 
480
    def test_assertEqualStat_equal(self):
 
481
        from bzrlib.tests.test_dirstate import _FakeStat
 
482
        self.build_tree(["foo"])
 
483
        real = os.lstat("foo")
 
484
        fake = _FakeStat(real.st_size, real.st_mtime, real.st_ctime,
 
485
            real.st_dev, real.st_ino, real.st_mode)
 
486
        self.assertEqualStat(real, fake)
 
487
 
 
488
    def test_assertEqualStat_notequal(self):
 
489
        self.build_tree(["foo", "bar"])
 
490
        self.assertRaises(AssertionError, self.assertEqualStat,
 
491
            os.lstat("foo"), os.lstat("bar"))
 
492
 
 
493
 
 
494
class TestTestCaseWithMemoryTransport(tests.TestCaseWithMemoryTransport):
 
495
 
 
496
    def test_home_is_non_existant_dir_under_root(self):
 
497
        """The test_home_dir for TestCaseWithMemoryTransport is missing.
 
498
 
 
499
        This is because TestCaseWithMemoryTransport is for tests that do not
 
500
        need any disk resources: they should be hooked into bzrlib in such a
 
501
        way that no global settings are being changed by the test (only a
 
502
        few tests should need to do that), and having a missing dir as home is
 
503
        an effective way to ensure that this is the case.
 
504
        """
 
505
        self.assertIsSameRealPath(
 
506
            self.TEST_ROOT + "/MemoryTransportMissingHomeDir",
 
507
            self.test_home_dir)
 
508
        self.assertIsSameRealPath(self.test_home_dir, os.environ['HOME'])
 
509
 
 
510
    def test_cwd_is_TEST_ROOT(self):
 
511
        self.assertIsSameRealPath(self.test_dir, self.TEST_ROOT)
 
512
        cwd = osutils.getcwd()
 
513
        self.assertIsSameRealPath(self.test_dir, cwd)
 
514
 
 
515
    def test_make_branch_and_memory_tree(self):
 
516
        """In TestCaseWithMemoryTransport we should not make the branch on disk.
 
517
 
 
518
        This is hard to comprehensively robustly test, so we settle for making
 
519
        a branch and checking no directory was created at its relpath.
 
520
        """
 
521
        tree = self.make_branch_and_memory_tree('dir')
 
522
        # Guard against regression into MemoryTransport leaking
 
523
        # files to disk instead of keeping them in memory.
 
524
        self.failIf(osutils.lexists('dir'))
 
525
        self.assertIsInstance(tree, memorytree.MemoryTree)
 
526
 
 
527
    def test_make_branch_and_memory_tree_with_format(self):
 
528
        """make_branch_and_memory_tree should accept a format option."""
 
529
        format = bzrdir.BzrDirMetaFormat1()
 
530
        format.repository_format = weaverepo.RepositoryFormat7()
 
531
        tree = self.make_branch_and_memory_tree('dir', format=format)
 
532
        # Guard against regression into MemoryTransport leaking
 
533
        # files to disk instead of keeping them in memory.
 
534
        self.failIf(osutils.lexists('dir'))
 
535
        self.assertIsInstance(tree, memorytree.MemoryTree)
 
536
        self.assertEqual(format.repository_format.__class__,
 
537
            tree.branch.repository._format.__class__)
 
538
 
 
539
    def test_make_branch_builder(self):
 
540
        builder = self.make_branch_builder('dir')
 
541
        self.assertIsInstance(builder, branchbuilder.BranchBuilder)
 
542
        # Guard against regression into MemoryTransport leaking
 
543
        # files to disk instead of keeping them in memory.
 
544
        self.failIf(osutils.lexists('dir'))
 
545
 
 
546
    def test_make_branch_builder_with_format(self):
 
547
        # Use a repo layout that doesn't conform to a 'named' layout, to ensure
 
548
        # that the format objects are used.
 
549
        format = bzrdir.BzrDirMetaFormat1()
 
550
        repo_format = weaverepo.RepositoryFormat7()
 
551
        format.repository_format = repo_format
 
552
        builder = self.make_branch_builder('dir', format=format)
 
553
        the_branch = builder.get_branch()
 
554
        # Guard against regression into MemoryTransport leaking
 
555
        # files to disk instead of keeping them in memory.
 
556
        self.failIf(osutils.lexists('dir'))
 
557
        self.assertEqual(format.repository_format.__class__,
 
558
                         the_branch.repository._format.__class__)
 
559
        self.assertEqual(repo_format.get_format_string(),
 
560
                         self.get_transport().get_bytes(
 
561
                            'dir/.bzr/repository/format'))
 
562
 
 
563
    def test_make_branch_builder_with_format_name(self):
 
564
        builder = self.make_branch_builder('dir', format='knit')
 
565
        the_branch = builder.get_branch()
 
566
        # Guard against regression into MemoryTransport leaking
 
567
        # files to disk instead of keeping them in memory.
 
568
        self.failIf(osutils.lexists('dir'))
 
569
        dir_format = bzrdir.format_registry.make_bzrdir('knit')
 
570
        self.assertEqual(dir_format.repository_format.__class__,
 
571
                         the_branch.repository._format.__class__)
 
572
        self.assertEqual('Bazaar-NG Knit Repository Format 1',
 
573
                         self.get_transport().get_bytes(
 
574
                            'dir/.bzr/repository/format'))
 
575
 
 
576
    def test_safety_net(self):
 
577
        """No test should modify the safety .bzr directory.
 
578
 
 
579
        We just test that the _check_safety_net private method raises
 
580
        AssertionError, it's easier than building a test suite with the same
 
581
        test.
 
582
        """
 
583
        # Oops, a commit in the current directory (i.e. without local .bzr
 
584
        # directory) will crawl up the hierarchy to find a .bzr directory.
 
585
        self.run_bzr(['commit', '-mfoo', '--unchanged'])
 
586
        # But we have a safety net in place.
 
587
        self.assertRaises(AssertionError, self._check_safety_net)
 
588
 
 
589
    def test_dangling_locks_cause_failures(self):
 
590
        class TestDanglingLock(tests.TestCaseWithMemoryTransport):
 
591
            def test_function(self):
 
592
                t = self.get_transport('.')
 
593
                l = lockdir.LockDir(t, 'lock')
 
594
                l.create()
 
595
                l.attempt_lock()
 
596
        test = TestDanglingLock('test_function')
 
597
        result = test.run()
 
598
        if self._lock_check_thorough:
 
599
            self.assertEqual(1, len(result.errors))
 
600
        else:
 
601
            # When _lock_check_thorough is disabled, then we don't trigger a
 
602
            # failure
 
603
            self.assertEqual(0, len(result.errors))
 
604
 
 
605
 
 
606
class TestTestCaseWithTransport(tests.TestCaseWithTransport):
 
607
    """Tests for the convenience functions TestCaseWithTransport introduces."""
 
608
 
 
609
    def test_get_readonly_url_none(self):
 
610
        from bzrlib.transport import get_transport
 
611
        from bzrlib.transport.memory import MemoryServer
 
612
        from bzrlib.transport.readonly import ReadonlyTransportDecorator
 
613
        self.vfs_transport_factory = MemoryServer
 
614
        self.transport_readonly_server = None
 
615
        # calling get_readonly_transport() constructs a decorator on the url
 
616
        # for the server
 
617
        url = self.get_readonly_url()
 
618
        url2 = self.get_readonly_url('foo/bar')
 
619
        t = get_transport(url)
 
620
        t2 = get_transport(url2)
 
621
        self.failUnless(isinstance(t, ReadonlyTransportDecorator))
 
622
        self.failUnless(isinstance(t2, ReadonlyTransportDecorator))
 
623
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
 
624
 
 
625
    def test_get_readonly_url_http(self):
 
626
        from bzrlib.tests.http_server import HttpServer
 
627
        from bzrlib.transport import get_transport
 
628
        from bzrlib.transport.local import LocalURLServer
 
629
        from bzrlib.transport.http import HttpTransportBase
 
630
        self.transport_server = LocalURLServer
 
631
        self.transport_readonly_server = HttpServer
 
632
        # calling get_readonly_transport() gives us a HTTP server instance.
 
633
        url = self.get_readonly_url()
 
634
        url2 = self.get_readonly_url('foo/bar')
 
635
        # the transport returned may be any HttpTransportBase subclass
 
636
        t = get_transport(url)
 
637
        t2 = get_transport(url2)
 
638
        self.failUnless(isinstance(t, HttpTransportBase))
 
639
        self.failUnless(isinstance(t2, HttpTransportBase))
 
640
        self.assertEqual(t2.base[:-1], t.abspath('foo/bar'))
 
641
 
 
642
    def test_is_directory(self):
 
643
        """Test assertIsDirectory assertion"""
 
644
        t = self.get_transport()
 
645
        self.build_tree(['a_dir/', 'a_file'], transport=t)
 
646
        self.assertIsDirectory('a_dir', t)
 
647
        self.assertRaises(AssertionError, self.assertIsDirectory, 'a_file', t)
 
648
        self.assertRaises(AssertionError, self.assertIsDirectory, 'not_here', t)
 
649
 
 
650
    def test_make_branch_builder(self):
 
651
        builder = self.make_branch_builder('dir')
 
652
        rev_id = builder.build_commit()
 
653
        self.failUnlessExists('dir')
 
654
        a_dir = bzrdir.BzrDir.open('dir')
 
655
        self.assertRaises(errors.NoWorkingTree, a_dir.open_workingtree)
 
656
        a_branch = a_dir.open_branch()
 
657
        builder_branch = builder.get_branch()
 
658
        self.assertEqual(a_branch.base, builder_branch.base)
 
659
        self.assertEqual((1, rev_id), builder_branch.last_revision_info())
 
660
        self.assertEqual((1, rev_id), a_branch.last_revision_info())
 
661
 
 
662
 
 
663
class TestTestCaseTransports(tests.TestCaseWithTransport):
 
664
 
 
665
    def setUp(self):
 
666
        super(TestTestCaseTransports, self).setUp()
 
667
        self.vfs_transport_factory = MemoryServer
 
668
 
 
669
    def test_make_bzrdir_preserves_transport(self):
 
670
        t = self.get_transport()
 
671
        result_bzrdir = self.make_bzrdir('subdir')
 
672
        self.assertIsInstance(result_bzrdir.transport,
 
673
                              MemoryTransport)
 
674
        # should not be on disk, should only be in memory
 
675
        self.failIfExists('subdir')
 
676
 
 
677
 
 
678
class TestChrootedTest(tests.ChrootedTestCase):
 
679
 
 
680
    def test_root_is_root(self):
 
681
        from bzrlib.transport import get_transport
 
682
        t = get_transport(self.get_readonly_url())
 
683
        url = t.base
 
684
        self.assertEqual(url, t.clone('..').base)
 
685
 
 
686
 
 
687
class TestTestResult(tests.TestCase):
 
688
 
 
689
    def check_timing(self, test_case, expected_re):
 
690
        result = bzrlib.tests.TextTestResult(self._log_file,
 
691
                descriptions=0,
 
692
                verbosity=1,
 
693
                )
 
694
        test_case.run(result)
 
695
        timed_string = result._testTimeString(test_case)
 
696
        self.assertContainsRe(timed_string, expected_re)
 
697
 
 
698
    def test_test_reporting(self):
 
699
        class ShortDelayTestCase(tests.TestCase):
 
700
            def test_short_delay(self):
 
701
                time.sleep(0.003)
 
702
            def test_short_benchmark(self):
 
703
                self.time(time.sleep, 0.003)
 
704
        self.check_timing(ShortDelayTestCase('test_short_delay'),
 
705
                          r"^ +[0-9]+ms$")
 
706
        # if a benchmark time is given, we now show just that time followed by
 
707
        # a star
 
708
        self.check_timing(ShortDelayTestCase('test_short_benchmark'),
 
709
                          r"^ +[0-9]+ms\*$")
 
710
 
 
711
    def test_unittest_reporting_unittest_class(self):
 
712
        # getting the time from a non-bzrlib test works ok
 
713
        class ShortDelayTestCase(unittest.TestCase):
 
714
            def test_short_delay(self):
 
715
                time.sleep(0.003)
 
716
        self.check_timing(ShortDelayTestCase('test_short_delay'),
 
717
                          r"^ +[0-9]+ms$")
 
718
 
 
719
    def test_assigned_benchmark_file_stores_date(self):
 
720
        output = StringIO()
 
721
        result = bzrlib.tests.TextTestResult(self._log_file,
 
722
                                        descriptions=0,
 
723
                                        verbosity=1,
 
724
                                        bench_history=output
 
725
                                        )
 
726
        output_string = output.getvalue()
 
727
        # if you are wondering about the regexp please read the comment in
 
728
        # test_bench_history (bzrlib.tests.test_selftest.TestRunner)
 
729
        # XXX: what comment?  -- Andrew Bennetts
 
730
        self.assertContainsRe(output_string, "--date [0-9.]+")
 
731
 
 
732
    def test_benchhistory_records_test_times(self):
 
733
        result_stream = StringIO()
 
734
        result = bzrlib.tests.TextTestResult(
 
735
            self._log_file,
 
736
            descriptions=0,
 
737
            verbosity=1,
 
738
            bench_history=result_stream
 
739
            )
 
740
 
 
741
        # we want profile a call and check that its test duration is recorded
 
742
        # make a new test instance that when run will generate a benchmark
 
743
        example_test_case = TestTestResult("_time_hello_world_encoding")
 
744
        # execute the test, which should succeed and record times
 
745
        example_test_case.run(result)
 
746
        lines = result_stream.getvalue().splitlines()
 
747
        self.assertEqual(2, len(lines))
 
748
        self.assertContainsRe(lines[1],
 
749
            " *[0-9]+ms bzrlib.tests.test_selftest.TestTestResult"
 
750
            "._time_hello_world_encoding")
 
751
 
 
752
    def _time_hello_world_encoding(self):
 
753
        """Profile two sleep calls
 
754
 
 
755
        This is used to exercise the test framework.
 
756
        """
 
757
        self.time(unicode, 'hello', errors='replace')
 
758
        self.time(unicode, 'world', errors='replace')
 
759
 
 
760
    def test_lsprofiling(self):
 
761
        """Verbose test result prints lsprof statistics from test cases."""
 
762
        self.requireFeature(test_lsprof.LSProfFeature)
 
763
        result_stream = StringIO()
 
764
        result = bzrlib.tests.VerboseTestResult(
 
765
            unittest._WritelnDecorator(result_stream),
 
766
            descriptions=0,
 
767
            verbosity=2,
 
768
            )
 
769
        # we want profile a call of some sort and check it is output by
 
770
        # addSuccess. We dont care about addError or addFailure as they
 
771
        # are not that interesting for performance tuning.
 
772
        # make a new test instance that when run will generate a profile
 
773
        example_test_case = TestTestResult("_time_hello_world_encoding")
 
774
        example_test_case._gather_lsprof_in_benchmarks = True
 
775
        # execute the test, which should succeed and record profiles
 
776
        example_test_case.run(result)
 
777
        # lsprofile_something()
 
778
        # if this worked we want
 
779
        # LSProf output for <built in function unicode> (['hello'], {'errors': 'replace'})
 
780
        #    CallCount    Recursive    Total(ms)   Inline(ms) module:lineno(function)
 
781
        # (the lsprof header)
 
782
        # ... an arbitrary number of lines
 
783
        # and the function call which is time.sleep.
 
784
        #           1        0            ???         ???       ???(sleep)
 
785
        # and then repeated but with 'world', rather than 'hello'.
 
786
        # this should appear in the output stream of our test result.
 
787
        output = result_stream.getvalue()
 
788
        self.assertContainsRe(output,
 
789
            r"LSProf output for <type 'unicode'>\(\('hello',\), {'errors': 'replace'}\)")
 
790
        self.assertContainsRe(output,
 
791
            r" *CallCount *Recursive *Total\(ms\) *Inline\(ms\) *module:lineno\(function\)\n")
 
792
        self.assertContainsRe(output,
 
793
            r"( +1 +0 +0\.\d+ +0\.\d+ +<method 'disable' of '_lsprof\.Profiler' objects>\n)?")
 
794
        self.assertContainsRe(output,
 
795
            r"LSProf output for <type 'unicode'>\(\('world',\), {'errors': 'replace'}\)\n")
 
796
 
 
797
    def test_known_failure(self):
 
798
        """A KnownFailure being raised should trigger several result actions."""
 
799
        class InstrumentedTestResult(tests.ExtendedTestResult):
 
800
            def done(self): pass
 
801
            def startTests(self): pass
 
802
            def report_test_start(self, test): pass
 
803
            def report_known_failure(self, test, err):
 
804
                self._call = test, err
 
805
        result = InstrumentedTestResult(None, None, None, None)
 
806
        def test_function():
 
807
            raise tests.KnownFailure('failed!')
 
808
        test = unittest.FunctionTestCase(test_function)
 
809
        test.run(result)
 
810
        # it should invoke 'report_known_failure'.
 
811
        self.assertEqual(2, len(result._call))
 
812
        self.assertEqual(test, result._call[0])
 
813
        self.assertEqual(tests.KnownFailure, result._call[1][0])
 
814
        self.assertIsInstance(result._call[1][1], tests.KnownFailure)
 
815
        # we dont introspec the traceback, if the rest is ok, it would be
 
816
        # exceptional for it not to be.
 
817
        # it should update the known_failure_count on the object.
 
818
        self.assertEqual(1, result.known_failure_count)
 
819
        # the result should be successful.
 
820
        self.assertTrue(result.wasSuccessful())
 
821
 
 
822
    def test_verbose_report_known_failure(self):
 
823
        # verbose test output formatting
 
824
        result_stream = StringIO()
 
825
        result = bzrlib.tests.VerboseTestResult(
 
826
            unittest._WritelnDecorator(result_stream),
 
827
            descriptions=0,
 
828
            verbosity=2,
 
829
            )
 
830
        test = self.get_passing_test()
 
831
        result.startTest(test)
 
832
        prefix = len(result_stream.getvalue())
 
833
        # the err parameter has the shape:
 
834
        # (class, exception object, traceback)
 
835
        # KnownFailures dont get their tracebacks shown though, so we
 
836
        # can skip that.
 
837
        err = (tests.KnownFailure, tests.KnownFailure('foo'), None)
 
838
        result.report_known_failure(test, err)
 
839
        output = result_stream.getvalue()[prefix:]
 
840
        lines = output.splitlines()
 
841
        self.assertContainsRe(lines[0], r'XFAIL *\d+ms$')
 
842
        self.assertEqual(lines[1], '    foo')
 
843
        self.assertEqual(2, len(lines))
 
844
 
 
845
    def get_passing_test(self):
 
846
        """Return a test object that can't be run usefully."""
 
847
        def passing_test():
 
848
            pass
 
849
        return unittest.FunctionTestCase(passing_test)
 
850
 
 
851
    def test_add_not_supported(self):
 
852
        """Test the behaviour of invoking addNotSupported."""
 
853
        class InstrumentedTestResult(tests.ExtendedTestResult):
 
854
            def done(self): pass
 
855
            def startTests(self): pass
 
856
            def report_test_start(self, test): pass
 
857
            def report_unsupported(self, test, feature):
 
858
                self._call = test, feature
 
859
        result = InstrumentedTestResult(None, None, None, None)
 
860
        test = SampleTestCase('_test_pass')
 
861
        feature = tests.Feature()
 
862
        result.startTest(test)
 
863
        result.addNotSupported(test, feature)
 
864
        # it should invoke 'report_unsupported'.
 
865
        self.assertEqual(2, len(result._call))
 
866
        self.assertEqual(test, result._call[0])
 
867
        self.assertEqual(feature, result._call[1])
 
868
        # the result should be successful.
 
869
        self.assertTrue(result.wasSuccessful())
 
870
        # it should record the test against a count of tests not run due to
 
871
        # this feature.
 
872
        self.assertEqual(1, result.unsupported['Feature'])
 
873
        # and invoking it again should increment that counter
 
874
        result.addNotSupported(test, feature)
 
875
        self.assertEqual(2, result.unsupported['Feature'])
 
876
 
 
877
    def test_verbose_report_unsupported(self):
 
878
        # verbose test output formatting
 
879
        result_stream = StringIO()
 
880
        result = bzrlib.tests.VerboseTestResult(
 
881
            unittest._WritelnDecorator(result_stream),
 
882
            descriptions=0,
 
883
            verbosity=2,
 
884
            )
 
885
        test = self.get_passing_test()
 
886
        feature = tests.Feature()
 
887
        result.startTest(test)
 
888
        prefix = len(result_stream.getvalue())
 
889
        result.report_unsupported(test, feature)
 
890
        output = result_stream.getvalue()[prefix:]
 
891
        lines = output.splitlines()
 
892
        self.assertEqual(lines, ['NODEP        0ms',
 
893
                                 "    The feature 'Feature' is not available."])
 
894
 
 
895
    def test_unavailable_exception(self):
 
896
        """An UnavailableFeature being raised should invoke addNotSupported."""
 
897
        class InstrumentedTestResult(tests.ExtendedTestResult):
 
898
            def done(self): pass
 
899
            def startTests(self): pass
 
900
            def report_test_start(self, test): pass
 
901
            def addNotSupported(self, test, feature):
 
902
                self._call = test, feature
 
903
        result = InstrumentedTestResult(None, None, None, None)
 
904
        feature = tests.Feature()
 
905
        def test_function():
 
906
            raise tests.UnavailableFeature(feature)
 
907
        test = unittest.FunctionTestCase(test_function)
 
908
        test.run(result)
 
909
        # it should invoke 'addNotSupported'.
 
910
        self.assertEqual(2, len(result._call))
 
911
        self.assertEqual(test, result._call[0])
 
912
        self.assertEqual(feature, result._call[1])
 
913
        # and not count as an error
 
914
        self.assertEqual(0, result.error_count)
 
915
 
 
916
    def test_strict_with_unsupported_feature(self):
 
917
        result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
 
918
                                             verbosity=1)
 
919
        test = self.get_passing_test()
 
920
        feature = "Unsupported Feature"
 
921
        result.addNotSupported(test, feature)
 
922
        self.assertFalse(result.wasStrictlySuccessful())
 
923
        self.assertEqual(None, result._extractBenchmarkTime(test))
 
924
 
 
925
    def test_strict_with_known_failure(self):
 
926
        result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
 
927
                                             verbosity=1)
 
928
        test = self.get_passing_test()
 
929
        err = (tests.KnownFailure, tests.KnownFailure('foo'), None)
 
930
        result._addKnownFailure(test, err)
 
931
        self.assertFalse(result.wasStrictlySuccessful())
 
932
        self.assertEqual(None, result._extractBenchmarkTime(test))
 
933
 
 
934
    def test_strict_with_success(self):
 
935
        result = bzrlib.tests.TextTestResult(self._log_file, descriptions=0,
 
936
                                             verbosity=1)
 
937
        test = self.get_passing_test()
 
938
        result.addSuccess(test)
 
939
        self.assertTrue(result.wasStrictlySuccessful())
 
940
        self.assertEqual(None, result._extractBenchmarkTime(test))
 
941
 
 
942
    def test_startTests(self):
 
943
        """Starting the first test should trigger startTests."""
 
944
        class InstrumentedTestResult(tests.ExtendedTestResult):
 
945
            calls = 0
 
946
            def startTests(self): self.calls += 1
 
947
            def report_test_start(self, test): pass
 
948
        result = InstrumentedTestResult(None, None, None, None)
 
949
        def test_function():
 
950
            pass
 
951
        test = unittest.FunctionTestCase(test_function)
 
952
        test.run(result)
 
953
        self.assertEquals(1, result.calls)
 
954
 
 
955
 
 
956
class TestUnicodeFilenameFeature(tests.TestCase):
 
957
 
 
958
    def test_probe_passes(self):
 
959
        """UnicodeFilenameFeature._probe passes."""
 
960
        # We can't test much more than that because the behaviour depends
 
961
        # on the platform.
 
962
        tests.UnicodeFilenameFeature._probe()
 
963
 
 
964
 
 
965
class TestRunner(tests.TestCase):
 
966
 
 
967
    def dummy_test(self):
 
968
        pass
 
969
 
 
970
    def run_test_runner(self, testrunner, test):
 
971
        """Run suite in testrunner, saving global state and restoring it.
 
972
 
 
973
        This current saves and restores:
 
974
        TestCaseInTempDir.TEST_ROOT
 
975
 
 
976
        There should be no tests in this file that use
 
977
        bzrlib.tests.TextTestRunner without using this convenience method,
 
978
        because of our use of global state.
 
979
        """
 
980
        old_root = tests.TestCaseInTempDir.TEST_ROOT
 
981
        try:
 
982
            tests.TestCaseInTempDir.TEST_ROOT = None
 
983
            return testrunner.run(test)
 
984
        finally:
 
985
            tests.TestCaseInTempDir.TEST_ROOT = old_root
 
986
 
 
987
    def test_known_failure_failed_run(self):
 
988
        # run a test that generates a known failure which should be printed in
 
989
        # the final output when real failures occur.
 
990
        def known_failure_test():
 
991
            raise tests.KnownFailure('failed')
 
992
        test = unittest.TestSuite()
 
993
        test.addTest(unittest.FunctionTestCase(known_failure_test))
 
994
        def failing_test():
 
995
            raise AssertionError('foo')
 
996
        test.addTest(unittest.FunctionTestCase(failing_test))
 
997
        stream = StringIO()
 
998
        runner = tests.TextTestRunner(stream=stream)
 
999
        result = self.run_test_runner(runner, test)
 
1000
        lines = stream.getvalue().splitlines()
 
1001
        self.assertContainsRe(stream.getvalue(),
 
1002
            '(?sm)^testing.*$'
 
1003
            '.*'
 
1004
            '^======================================================================\n'
 
1005
            '^FAIL: unittest.FunctionTestCase \\(failing_test\\)\n'
 
1006
            '^----------------------------------------------------------------------\n'
 
1007
            'Traceback \\(most recent call last\\):\n'
 
1008
            '  .*' # File .*, line .*, in failing_test' - but maybe not from .pyc
 
1009
            '    raise AssertionError\\(\'foo\'\\)\n'
 
1010
            '.*'
 
1011
            '^----------------------------------------------------------------------\n'
 
1012
            '.*'
 
1013
            'FAILED \\(failures=1, known_failure_count=1\\)'
 
1014
            )
 
1015
 
 
1016
    def test_known_failure_ok_run(self):
 
1017
        # run a test that generates a known failure which should be printed in the final output.
 
1018
        def known_failure_test():
 
1019
            raise tests.KnownFailure('failed')
 
1020
        test = unittest.FunctionTestCase(known_failure_test)
 
1021
        stream = StringIO()
 
1022
        runner = tests.TextTestRunner(stream=stream)
 
1023
        result = self.run_test_runner(runner, test)
 
1024
        self.assertContainsRe(stream.getvalue(),
 
1025
            '\n'
 
1026
            '-*\n'
 
1027
            'Ran 1 test in .*\n'
 
1028
            '\n'
 
1029
            'OK \\(known_failures=1\\)\n')
 
1030
 
 
1031
    def test_skipped_test(self):
 
1032
        # run a test that is skipped, and check the suite as a whole still
 
1033
        # succeeds.
 
1034
        # skipping_test must be hidden in here so it's not run as a real test
 
1035
        class SkippingTest(tests.TestCase):
 
1036
            def skipping_test(self):
 
1037
                raise tests.TestSkipped('test intentionally skipped')
 
1038
        runner = tests.TextTestRunner(stream=self._log_file)
 
1039
        test = SkippingTest("skipping_test")
 
1040
        result = self.run_test_runner(runner, test)
 
1041
        self.assertTrue(result.wasSuccessful())
 
1042
 
 
1043
    def test_skipped_from_setup(self):
 
1044
        calls = []
 
1045
        class SkippedSetupTest(tests.TestCase):
 
1046
 
 
1047
            def setUp(self):
 
1048
                calls.append('setUp')
 
1049
                self.addCleanup(self.cleanup)
 
1050
                raise tests.TestSkipped('skipped setup')
 
1051
 
 
1052
            def test_skip(self):
 
1053
                self.fail('test reached')
 
1054
 
 
1055
            def cleanup(self):
 
1056
                calls.append('cleanup')
 
1057
 
 
1058
        runner = tests.TextTestRunner(stream=self._log_file)
 
1059
        test = SkippedSetupTest('test_skip')
 
1060
        result = self.run_test_runner(runner, test)
 
1061
        self.assertTrue(result.wasSuccessful())
 
1062
        # Check if cleanup was called the right number of times.
 
1063
        self.assertEqual(['setUp', 'cleanup'], calls)
 
1064
 
 
1065
    def test_skipped_from_test(self):
 
1066
        calls = []
 
1067
        class SkippedTest(tests.TestCase):
 
1068
 
 
1069
            def setUp(self):
 
1070
                tests.TestCase.setUp(self)
 
1071
                calls.append('setUp')
 
1072
                self.addCleanup(self.cleanup)
 
1073
 
 
1074
            def test_skip(self):
 
1075
                raise tests.TestSkipped('skipped test')
 
1076
 
 
1077
            def cleanup(self):
 
1078
                calls.append('cleanup')
 
1079
 
 
1080
        runner = tests.TextTestRunner(stream=self._log_file)
 
1081
        test = SkippedTest('test_skip')
 
1082
        result = self.run_test_runner(runner, test)
 
1083
        self.assertTrue(result.wasSuccessful())
 
1084
        # Check if cleanup was called the right number of times.
 
1085
        self.assertEqual(['setUp', 'cleanup'], calls)
 
1086
 
 
1087
    def test_not_applicable(self):
 
1088
        # run a test that is skipped because it's not applicable
 
1089
        def not_applicable_test():
 
1090
            raise tests.TestNotApplicable('this test never runs')
 
1091
        out = StringIO()
 
1092
        runner = tests.TextTestRunner(stream=out, verbosity=2)
 
1093
        test = unittest.FunctionTestCase(not_applicable_test)
 
1094
        result = self.run_test_runner(runner, test)
 
1095
        self._log_file.write(out.getvalue())
 
1096
        self.assertTrue(result.wasSuccessful())
 
1097
        self.assertTrue(result.wasStrictlySuccessful())
 
1098
        self.assertContainsRe(out.getvalue(),
 
1099
                r'(?m)not_applicable_test   * N/A')
 
1100
        self.assertContainsRe(out.getvalue(),
 
1101
                r'(?m)^    this test never runs')
 
1102
 
 
1103
    def test_not_applicable_demo(self):
 
1104
        # just so you can see it in the test output
 
1105
        raise tests.TestNotApplicable('this test is just a demonstation')
 
1106
 
 
1107
    def test_unsupported_features_listed(self):
 
1108
        """When unsupported features are encountered they are detailed."""
 
1109
        class Feature1(tests.Feature):
 
1110
            def _probe(self): return False
 
1111
        class Feature2(tests.Feature):
 
1112
            def _probe(self): return False
 
1113
        # create sample tests
 
1114
        test1 = SampleTestCase('_test_pass')
 
1115
        test1._test_needs_features = [Feature1()]
 
1116
        test2 = SampleTestCase('_test_pass')
 
1117
        test2._test_needs_features = [Feature2()]
 
1118
        test = unittest.TestSuite()
 
1119
        test.addTest(test1)
 
1120
        test.addTest(test2)
 
1121
        stream = StringIO()
 
1122
        runner = tests.TextTestRunner(stream=stream)
 
1123
        result = self.run_test_runner(runner, test)
 
1124
        lines = stream.getvalue().splitlines()
 
1125
        self.assertEqual([
 
1126
            'OK',
 
1127
            "Missing feature 'Feature1' skipped 1 tests.",
 
1128
            "Missing feature 'Feature2' skipped 1 tests.",
 
1129
            ],
 
1130
            lines[-3:])
 
1131
 
 
1132
    def test_bench_history(self):
 
1133
        # tests that the running the benchmark produces a history file
 
1134
        # containing a timestamp and the revision id of the bzrlib source which
 
1135
        # was tested.
 
1136
        workingtree = _get_bzr_source_tree()
 
1137
        test = TestRunner('dummy_test')
 
1138
        output = StringIO()
 
1139
        runner = tests.TextTestRunner(stream=self._log_file,
 
1140
                                      bench_history=output)
 
1141
        result = self.run_test_runner(runner, test)
 
1142
        output_string = output.getvalue()
 
1143
        self.assertContainsRe(output_string, "--date [0-9.]+")
 
1144
        if workingtree is not None:
 
1145
            revision_id = workingtree.get_parent_ids()[0]
 
1146
            self.assertEndsWith(output_string.rstrip(), revision_id)
 
1147
 
 
1148
    def assertLogDeleted(self, test):
 
1149
        log = test._get_log()
 
1150
        self.assertEqual("DELETED log file to reduce memory footprint", log)
 
1151
        self.assertEqual('', test._log_contents)
 
1152
        self.assertIs(None, test._log_file_name)
 
1153
 
 
1154
    def test_success_log_deleted(self):
 
1155
        """Successful tests have their log deleted"""
 
1156
 
 
1157
        class LogTester(tests.TestCase):
 
1158
 
 
1159
            def test_success(self):
 
1160
                self.log('this will be removed\n')
 
1161
 
 
1162
        sio = StringIO()
 
1163
        runner = tests.TextTestRunner(stream=sio)
 
1164
        test = LogTester('test_success')
 
1165
        result = self.run_test_runner(runner, test)
 
1166
 
 
1167
        self.assertLogDeleted(test)
 
1168
 
 
1169
    def test_skipped_log_deleted(self):
 
1170
        """Skipped tests have their log deleted"""
 
1171
 
 
1172
        class LogTester(tests.TestCase):
 
1173
 
 
1174
            def test_skipped(self):
 
1175
                self.log('this will be removed\n')
 
1176
                raise tests.TestSkipped()
 
1177
 
 
1178
        sio = StringIO()
 
1179
        runner = tests.TextTestRunner(stream=sio)
 
1180
        test = LogTester('test_skipped')
 
1181
        result = self.run_test_runner(runner, test)
 
1182
 
 
1183
        self.assertLogDeleted(test)
 
1184
 
 
1185
    def test_not_aplicable_log_deleted(self):
 
1186
        """Not applicable tests have their log deleted"""
 
1187
 
 
1188
        class LogTester(tests.TestCase):
 
1189
 
 
1190
            def test_not_applicable(self):
 
1191
                self.log('this will be removed\n')
 
1192
                raise tests.TestNotApplicable()
 
1193
 
 
1194
        sio = StringIO()
 
1195
        runner = tests.TextTestRunner(stream=sio)
 
1196
        test = LogTester('test_not_applicable')
 
1197
        result = self.run_test_runner(runner, test)
 
1198
 
 
1199
        self.assertLogDeleted(test)
 
1200
 
 
1201
    def test_known_failure_log_deleted(self):
 
1202
        """Know failure tests have their log deleted"""
 
1203
 
 
1204
        class LogTester(tests.TestCase):
 
1205
 
 
1206
            def test_known_failure(self):
 
1207
                self.log('this will be removed\n')
 
1208
                raise tests.KnownFailure()
 
1209
 
 
1210
        sio = StringIO()
 
1211
        runner = tests.TextTestRunner(stream=sio)
 
1212
        test = LogTester('test_known_failure')
 
1213
        result = self.run_test_runner(runner, test)
 
1214
 
 
1215
        self.assertLogDeleted(test)
 
1216
 
 
1217
    def test_fail_log_kept(self):
 
1218
        """Failed tests have their log kept"""
 
1219
 
 
1220
        class LogTester(tests.TestCase):
 
1221
 
 
1222
            def test_fail(self):
 
1223
                self.log('this will be kept\n')
 
1224
                self.fail('this test fails')
 
1225
 
 
1226
        sio = StringIO()
 
1227
        runner = tests.TextTestRunner(stream=sio)
 
1228
        test = LogTester('test_fail')
 
1229
        result = self.run_test_runner(runner, test)
 
1230
 
 
1231
        text = sio.getvalue()
 
1232
        self.assertContainsRe(text, 'this will be kept')
 
1233
        self.assertContainsRe(text, 'this test fails')
 
1234
 
 
1235
        log = test._get_log()
 
1236
        self.assertContainsRe(log, 'this will be kept')
 
1237
        self.assertEqual(log, test._log_contents)
 
1238
 
 
1239
    def test_error_log_kept(self):
 
1240
        """Tests with errors have their log kept"""
 
1241
 
 
1242
        class LogTester(tests.TestCase):
 
1243
 
 
1244
            def test_error(self):
 
1245
                self.log('this will be kept\n')
 
1246
                raise ValueError('random exception raised')
 
1247
 
 
1248
        sio = StringIO()
 
1249
        runner = tests.TextTestRunner(stream=sio)
 
1250
        test = LogTester('test_error')
 
1251
        result = self.run_test_runner(runner, test)
 
1252
 
 
1253
        text = sio.getvalue()
 
1254
        self.assertContainsRe(text, 'this will be kept')
 
1255
        self.assertContainsRe(text, 'random exception raised')
 
1256
 
 
1257
        log = test._get_log()
 
1258
        self.assertContainsRe(log, 'this will be kept')
 
1259
        self.assertEqual(log, test._log_contents)
 
1260
 
 
1261
 
 
1262
class SampleTestCase(tests.TestCase):
 
1263
 
 
1264
    def _test_pass(self):
 
1265
        pass
 
1266
 
 
1267
class _TestException(Exception):
 
1268
    pass
 
1269
 
 
1270
 
 
1271
class TestTestCase(tests.TestCase):
 
1272
    """Tests that test the core bzrlib TestCase."""
 
1273
 
 
1274
    def test_assertLength_matches_empty(self):
 
1275
        a_list = []
 
1276
        self.assertLength(0, a_list)
 
1277
 
 
1278
    def test_assertLength_matches_nonempty(self):
 
1279
        a_list = [1, 2, 3]
 
1280
        self.assertLength(3, a_list)
 
1281
 
 
1282
    def test_assertLength_fails_different(self):
 
1283
        a_list = []
 
1284
        self.assertRaises(AssertionError, self.assertLength, 1, a_list)
 
1285
 
 
1286
    def test_assertLength_shows_sequence_in_failure(self):
 
1287
        a_list = [1, 2, 3]
 
1288
        exception = self.assertRaises(AssertionError, self.assertLength, 2,
 
1289
            a_list)
 
1290
        self.assertEqual('Incorrect length: wanted 2, got 3 for [1, 2, 3]',
 
1291
            exception.args[0])
 
1292
 
 
1293
    def test_base_setUp_not_called_causes_failure(self):
 
1294
        class TestCaseWithBrokenSetUp(tests.TestCase):
 
1295
            def setUp(self):
 
1296
                pass # does not call TestCase.setUp
 
1297
            def test_foo(self):
 
1298
                pass
 
1299
        test = TestCaseWithBrokenSetUp('test_foo')
 
1300
        result = unittest.TestResult()
 
1301
        test.run(result)
 
1302
        self.assertFalse(result.wasSuccessful())
 
1303
        self.assertEqual(1, result.testsRun)
 
1304
 
 
1305
    def test_base_tearDown_not_called_causes_failure(self):
 
1306
        class TestCaseWithBrokenTearDown(tests.TestCase):
 
1307
            def tearDown(self):
 
1308
                pass # does not call TestCase.tearDown
 
1309
            def test_foo(self):
 
1310
                pass
 
1311
        test = TestCaseWithBrokenTearDown('test_foo')
 
1312
        result = unittest.TestResult()
 
1313
        test.run(result)
 
1314
        self.assertFalse(result.wasSuccessful())
 
1315
        self.assertEqual(1, result.testsRun)
 
1316
 
 
1317
    def test_debug_flags_sanitised(self):
 
1318
        """The bzrlib debug flags should be sanitised by setUp."""
 
1319
        if 'allow_debug' in tests.selftest_debug_flags:
 
1320
            raise tests.TestNotApplicable(
 
1321
                '-Eallow_debug option prevents debug flag sanitisation')
 
1322
        # we could set something and run a test that will check
 
1323
        # it gets santised, but this is probably sufficient for now:
 
1324
        # if someone runs the test with -Dsomething it will error.
 
1325
        flags = set()
 
1326
        if self._lock_check_thorough:
 
1327
            flags.add('strict_locks')
 
1328
        self.assertEqual(flags, bzrlib.debug.debug_flags)
 
1329
 
 
1330
    def change_selftest_debug_flags(self, new_flags):
 
1331
        orig_selftest_flags = tests.selftest_debug_flags
 
1332
        self.addCleanup(self._restore_selftest_debug_flags, orig_selftest_flags)
 
1333
        tests.selftest_debug_flags = set(new_flags)
 
1334
 
 
1335
    def _restore_selftest_debug_flags(self, flags):
 
1336
        tests.selftest_debug_flags = flags
 
1337
 
 
1338
    def test_allow_debug_flag(self):
 
1339
        """The -Eallow_debug flag prevents bzrlib.debug.debug_flags from being
 
1340
        sanitised (i.e. cleared) before running a test.
 
1341
        """
 
1342
        self.change_selftest_debug_flags(set(['allow_debug']))
 
1343
        bzrlib.debug.debug_flags = set(['a-flag'])
 
1344
        class TestThatRecordsFlags(tests.TestCase):
 
1345
            def test_foo(nested_self):
 
1346
                self.flags = set(bzrlib.debug.debug_flags)
 
1347
        test = TestThatRecordsFlags('test_foo')
 
1348
        test.run(self.make_test_result())
 
1349
        flags = set(['a-flag'])
 
1350
        if 'disable_lock_checks' not in tests.selftest_debug_flags:
 
1351
            flags.add('strict_locks')
 
1352
        self.assertEqual(flags, self.flags)
 
1353
 
 
1354
    def test_disable_lock_checks(self):
 
1355
        """The -Edisable_lock_checks flag disables thorough checks."""
 
1356
        class TestThatRecordsFlags(tests.TestCase):
 
1357
            def test_foo(nested_self):
 
1358
                self.flags = set(bzrlib.debug.debug_flags)
 
1359
                self.test_lock_check_thorough = nested_self._lock_check_thorough
 
1360
        self.change_selftest_debug_flags(set())
 
1361
        test = TestThatRecordsFlags('test_foo')
 
1362
        test.run(self.make_test_result())
 
1363
        # By default we do strict lock checking and thorough lock/unlock
 
1364
        # tracking.
 
1365
        self.assertTrue(self.test_lock_check_thorough)
 
1366
        self.assertEqual(set(['strict_locks']), self.flags)
 
1367
        # Now set the disable_lock_checks flag, and show that this changed.
 
1368
        self.change_selftest_debug_flags(set(['disable_lock_checks']))
 
1369
        test = TestThatRecordsFlags('test_foo')
 
1370
        test.run(self.make_test_result())
 
1371
        self.assertFalse(self.test_lock_check_thorough)
 
1372
        self.assertEqual(set(), self.flags)
 
1373
 
 
1374
    def test_this_fails_strict_lock_check(self):
 
1375
        class TestThatRecordsFlags(tests.TestCase):
 
1376
            def test_foo(nested_self):
 
1377
                self.flags1 = set(bzrlib.debug.debug_flags)
 
1378
                self.thisFailsStrictLockCheck()
 
1379
                self.flags2 = set(bzrlib.debug.debug_flags)
 
1380
        # Make sure lock checking is active
 
1381
        self.change_selftest_debug_flags(set())
 
1382
        test = TestThatRecordsFlags('test_foo')
 
1383
        test.run(self.make_test_result())
 
1384
        self.assertEqual(set(['strict_locks']), self.flags1)
 
1385
        self.assertEqual(set(), self.flags2)
 
1386
 
 
1387
    def test_debug_flags_restored(self):
 
1388
        """The bzrlib debug flags should be restored to their original state
 
1389
        after the test was run, even if allow_debug is set.
 
1390
        """
 
1391
        self.change_selftest_debug_flags(set(['allow_debug']))
 
1392
        # Now run a test that modifies debug.debug_flags.
 
1393
        bzrlib.debug.debug_flags = set(['original-state'])
 
1394
        class TestThatModifiesFlags(tests.TestCase):
 
1395
            def test_foo(self):
 
1396
                bzrlib.debug.debug_flags = set(['modified'])
 
1397
        test = TestThatModifiesFlags('test_foo')
 
1398
        test.run(self.make_test_result())
 
1399
        self.assertEqual(set(['original-state']), bzrlib.debug.debug_flags)
 
1400
 
 
1401
    def make_test_result(self):
 
1402
        return tests.TextTestResult(self._log_file, descriptions=0, verbosity=1)
 
1403
 
 
1404
    def inner_test(self):
 
1405
        # the inner child test
 
1406
        note("inner_test")
 
1407
 
 
1408
    def outer_child(self):
 
1409
        # the outer child test
 
1410
        note("outer_start")
 
1411
        self.inner_test = TestTestCase("inner_child")
 
1412
        result = self.make_test_result()
 
1413
        self.inner_test.run(result)
 
1414
        note("outer finish")
 
1415
 
 
1416
    def test_trace_nesting(self):
 
1417
        # this tests that each test case nests its trace facility correctly.
 
1418
        # we do this by running a test case manually. That test case (A)
 
1419
        # should setup a new log, log content to it, setup a child case (B),
 
1420
        # which should log independently, then case (A) should log a trailer
 
1421
        # and return.
 
1422
        # we do two nested children so that we can verify the state of the
 
1423
        # logs after the outer child finishes is correct, which a bad clean
 
1424
        # up routine in tearDown might trigger a fault in our test with only
 
1425
        # one child, we should instead see the bad result inside our test with
 
1426
        # the two children.
 
1427
        # the outer child test
 
1428
        original_trace = bzrlib.trace._trace_file
 
1429
        outer_test = TestTestCase("outer_child")
 
1430
        result = self.make_test_result()
 
1431
        outer_test.run(result)
 
1432
        self.assertEqual(original_trace, bzrlib.trace._trace_file)
 
1433
 
 
1434
    def method_that_times_a_bit_twice(self):
 
1435
        # call self.time twice to ensure it aggregates
 
1436
        self.time(time.sleep, 0.007)
 
1437
        self.time(time.sleep, 0.007)
 
1438
 
 
1439
    def test_time_creates_benchmark_in_result(self):
 
1440
        """Test that the TestCase.time() method accumulates a benchmark time."""
 
1441
        sample_test = TestTestCase("method_that_times_a_bit_twice")
 
1442
        output_stream = StringIO()
 
1443
        result = bzrlib.tests.VerboseTestResult(
 
1444
            unittest._WritelnDecorator(output_stream),
 
1445
            descriptions=0,
 
1446
            verbosity=2)
 
1447
        sample_test.run(result)
 
1448
        self.assertContainsRe(
 
1449
            output_stream.getvalue(),
 
1450
            r"\d+ms\*\n$")
 
1451
 
 
1452
    def test_hooks_sanitised(self):
 
1453
        """The bzrlib hooks should be sanitised by setUp."""
 
1454
        # Note this test won't fail with hooks that the core library doesn't
 
1455
        # use - but it trigger with a plugin that adds hooks, so its still a
 
1456
        # useful warning in that case.
 
1457
        self.assertEqual(bzrlib.branch.BranchHooks(),
 
1458
            bzrlib.branch.Branch.hooks)
 
1459
        self.assertEqual(bzrlib.smart.server.SmartServerHooks(),
 
1460
            bzrlib.smart.server.SmartTCPServer.hooks)
 
1461
        self.assertEqual(bzrlib.commands.CommandHooks(),
 
1462
            bzrlib.commands.Command.hooks)
 
1463
 
 
1464
    def test__gather_lsprof_in_benchmarks(self):
 
1465
        """When _gather_lsprof_in_benchmarks is on, accumulate profile data.
 
1466
 
 
1467
        Each self.time() call is individually and separately profiled.
 
1468
        """
 
1469
        self.requireFeature(test_lsprof.LSProfFeature)
 
1470
        # overrides the class member with an instance member so no cleanup
 
1471
        # needed.
 
1472
        self._gather_lsprof_in_benchmarks = True
 
1473
        self.time(time.sleep, 0.000)
 
1474
        self.time(time.sleep, 0.003)
 
1475
        self.assertEqual(2, len(self._benchcalls))
 
1476
        self.assertEqual((time.sleep, (0.000,), {}), self._benchcalls[0][0])
 
1477
        self.assertEqual((time.sleep, (0.003,), {}), self._benchcalls[1][0])
 
1478
        self.assertIsInstance(self._benchcalls[0][1], bzrlib.lsprof.Stats)
 
1479
        self.assertIsInstance(self._benchcalls[1][1], bzrlib.lsprof.Stats)
 
1480
 
 
1481
    def test_knownFailure(self):
 
1482
        """Self.knownFailure() should raise a KnownFailure exception."""
 
1483
        self.assertRaises(tests.KnownFailure, self.knownFailure, "A Failure")
 
1484
 
 
1485
    def test_requireFeature_available(self):
 
1486
        """self.requireFeature(available) is a no-op."""
 
1487
        class Available(tests.Feature):
 
1488
            def _probe(self):return True
 
1489
        feature = Available()
 
1490
        self.requireFeature(feature)
 
1491
 
 
1492
    def test_requireFeature_unavailable(self):
 
1493
        """self.requireFeature(unavailable) raises UnavailableFeature."""
 
1494
        class Unavailable(tests.Feature):
 
1495
            def _probe(self):return False
 
1496
        feature = Unavailable()
 
1497
        self.assertRaises(tests.UnavailableFeature,
 
1498
                          self.requireFeature, feature)
 
1499
 
 
1500
    def test_run_no_parameters(self):
 
1501
        test = SampleTestCase('_test_pass')
 
1502
        test.run()
 
1503
 
 
1504
    def test_run_enabled_unittest_result(self):
 
1505
        """Test we revert to regular behaviour when the test is enabled."""
 
1506
        test = SampleTestCase('_test_pass')
 
1507
        class EnabledFeature(object):
 
1508
            def available(self):
 
1509
                return True
 
1510
        test._test_needs_features = [EnabledFeature()]
 
1511
        result = unittest.TestResult()
 
1512
        test.run(result)
 
1513
        self.assertEqual(1, result.testsRun)
 
1514
        self.assertEqual([], result.errors)
 
1515
        self.assertEqual([], result.failures)
 
1516
 
 
1517
    def test_run_disabled_unittest_result(self):
 
1518
        """Test our compatability for disabled tests with unittest results."""
 
1519
        test = SampleTestCase('_test_pass')
 
1520
        class DisabledFeature(object):
 
1521
            def available(self):
 
1522
                return False
 
1523
        test._test_needs_features = [DisabledFeature()]
 
1524
        result = unittest.TestResult()
 
1525
        test.run(result)
 
1526
        self.assertEqual(1, result.testsRun)
 
1527
        self.assertEqual([], result.errors)
 
1528
        self.assertEqual([], result.failures)
 
1529
 
 
1530
    def test_run_disabled_supporting_result(self):
 
1531
        """Test disabled tests behaviour with support aware results."""
 
1532
        test = SampleTestCase('_test_pass')
 
1533
        class DisabledFeature(object):
 
1534
            def available(self):
 
1535
                return False
 
1536
        the_feature = DisabledFeature()
 
1537
        test._test_needs_features = [the_feature]
 
1538
        class InstrumentedTestResult(unittest.TestResult):
 
1539
            def __init__(self):
 
1540
                unittest.TestResult.__init__(self)
 
1541
                self.calls = []
 
1542
            def startTest(self, test):
 
1543
                self.calls.append(('startTest', test))
 
1544
            def stopTest(self, test):
 
1545
                self.calls.append(('stopTest', test))
 
1546
            def addNotSupported(self, test, feature):
 
1547
                self.calls.append(('addNotSupported', test, feature))
 
1548
        result = InstrumentedTestResult()
 
1549
        test.run(result)
 
1550
        self.assertEqual([
 
1551
            ('startTest', test),
 
1552
            ('addNotSupported', test, the_feature),
 
1553
            ('stopTest', test),
 
1554
            ],
 
1555
            result.calls)
 
1556
 
 
1557
    def test_assert_list_raises_on_generator(self):
 
1558
        def generator_which_will_raise():
 
1559
            # This will not raise until after the first yield
 
1560
            yield 1
 
1561
            raise _TestException()
 
1562
 
 
1563
        e = self.assertListRaises(_TestException, generator_which_will_raise)
 
1564
        self.assertIsInstance(e, _TestException)
 
1565
 
 
1566
        e = self.assertListRaises(Exception, generator_which_will_raise)
 
1567
        self.assertIsInstance(e, _TestException)
 
1568
 
 
1569
    def test_assert_list_raises_on_plain(self):
 
1570
        def plain_exception():
 
1571
            raise _TestException()
 
1572
            return []
 
1573
 
 
1574
        e = self.assertListRaises(_TestException, plain_exception)
 
1575
        self.assertIsInstance(e, _TestException)
 
1576
 
 
1577
        e = self.assertListRaises(Exception, plain_exception)
 
1578
        self.assertIsInstance(e, _TestException)
 
1579
 
 
1580
    def test_assert_list_raises_assert_wrong_exception(self):
 
1581
        class _NotTestException(Exception):
 
1582
            pass
 
1583
 
 
1584
        def wrong_exception():
 
1585
            raise _NotTestException()
 
1586
 
 
1587
        def wrong_exception_generator():
 
1588
            yield 1
 
1589
            yield 2
 
1590
            raise _NotTestException()
 
1591
 
 
1592
        # Wrong exceptions are not intercepted
 
1593
        self.assertRaises(_NotTestException,
 
1594
            self.assertListRaises, _TestException, wrong_exception)
 
1595
        self.assertRaises(_NotTestException,
 
1596
            self.assertListRaises, _TestException, wrong_exception_generator)
 
1597
 
 
1598
    def test_assert_list_raises_no_exception(self):
 
1599
        def success():
 
1600
            return []
 
1601
 
 
1602
        def success_generator():
 
1603
            yield 1
 
1604
            yield 2
 
1605
 
 
1606
        self.assertRaises(AssertionError,
 
1607
            self.assertListRaises, _TestException, success)
 
1608
 
 
1609
        self.assertRaises(AssertionError,
 
1610
            self.assertListRaises, _TestException, success_generator)
 
1611
 
 
1612
 
 
1613
# NB: Don't delete this; it's not actually from 0.11!
 
1614
@deprecated_function(deprecated_in((0, 11, 0)))
 
1615
def sample_deprecated_function():
 
1616
    """A deprecated function to test applyDeprecated with."""
 
1617
    return 2
 
1618
 
 
1619
 
 
1620
def sample_undeprecated_function(a_param):
 
1621
    """A undeprecated function to test applyDeprecated with."""
 
1622
 
 
1623
 
 
1624
class ApplyDeprecatedHelper(object):
 
1625
    """A helper class for ApplyDeprecated tests."""
 
1626
 
 
1627
    @deprecated_method(deprecated_in((0, 11, 0)))
 
1628
    def sample_deprecated_method(self, param_one):
 
1629
        """A deprecated method for testing with."""
 
1630
        return param_one
 
1631
 
 
1632
    def sample_normal_method(self):
 
1633
        """A undeprecated method."""
 
1634
 
 
1635
    @deprecated_method(deprecated_in((0, 10, 0)))
 
1636
    def sample_nested_deprecation(self):
 
1637
        return sample_deprecated_function()
 
1638
 
 
1639
 
 
1640
class TestExtraAssertions(tests.TestCase):
 
1641
    """Tests for new test assertions in bzrlib test suite"""
 
1642
 
 
1643
    def test_assert_isinstance(self):
 
1644
        self.assertIsInstance(2, int)
 
1645
        self.assertIsInstance(u'', basestring)
 
1646
        e = self.assertRaises(AssertionError, self.assertIsInstance, None, int)
 
1647
        self.assertEquals(str(e),
 
1648
            "None is an instance of <type 'NoneType'> rather than <type 'int'>")
 
1649
        self.assertRaises(AssertionError, self.assertIsInstance, 23.3, int)
 
1650
        e = self.assertRaises(AssertionError,
 
1651
            self.assertIsInstance, None, int, "it's just not")
 
1652
        self.assertEquals(str(e),
 
1653
            "None is an instance of <type 'NoneType'> rather than <type 'int'>"
 
1654
            ": it's just not")
 
1655
 
 
1656
    def test_assertEndsWith(self):
 
1657
        self.assertEndsWith('foo', 'oo')
 
1658
        self.assertRaises(AssertionError, self.assertEndsWith, 'o', 'oo')
 
1659
 
 
1660
    def test_applyDeprecated_not_deprecated(self):
 
1661
        sample_object = ApplyDeprecatedHelper()
 
1662
        # calling an undeprecated callable raises an assertion
 
1663
        self.assertRaises(AssertionError, self.applyDeprecated,
 
1664
            deprecated_in((0, 11, 0)),
 
1665
            sample_object.sample_normal_method)
 
1666
        self.assertRaises(AssertionError, self.applyDeprecated,
 
1667
            deprecated_in((0, 11, 0)),
 
1668
            sample_undeprecated_function, "a param value")
 
1669
        # calling a deprecated callable (function or method) with the wrong
 
1670
        # expected deprecation fails.
 
1671
        self.assertRaises(AssertionError, self.applyDeprecated,
 
1672
            deprecated_in((0, 10, 0)),
 
1673
            sample_object.sample_deprecated_method, "a param value")
 
1674
        self.assertRaises(AssertionError, self.applyDeprecated,
 
1675
            deprecated_in((0, 10, 0)),
 
1676
            sample_deprecated_function)
 
1677
        # calling a deprecated callable (function or method) with the right
 
1678
        # expected deprecation returns the functions result.
 
1679
        self.assertEqual("a param value",
 
1680
            self.applyDeprecated(deprecated_in((0, 11, 0)),
 
1681
            sample_object.sample_deprecated_method, "a param value"))
 
1682
        self.assertEqual(2, self.applyDeprecated(deprecated_in((0, 11, 0)),
 
1683
            sample_deprecated_function))
 
1684
        # calling a nested deprecation with the wrong deprecation version
 
1685
        # fails even if a deeper nested function was deprecated with the
 
1686
        # supplied version.
 
1687
        self.assertRaises(AssertionError, self.applyDeprecated,
 
1688
            deprecated_in((0, 11, 0)), sample_object.sample_nested_deprecation)
 
1689
        # calling a nested deprecation with the right deprecation value
 
1690
        # returns the calls result.
 
1691
        self.assertEqual(2, self.applyDeprecated(deprecated_in((0, 10, 0)),
 
1692
            sample_object.sample_nested_deprecation))
 
1693
 
 
1694
    def test_callDeprecated(self):
 
1695
        def testfunc(be_deprecated, result=None):
 
1696
            if be_deprecated is True:
 
1697
                symbol_versioning.warn('i am deprecated', DeprecationWarning,
 
1698
                                       stacklevel=1)
 
1699
            return result
 
1700
        result = self.callDeprecated(['i am deprecated'], testfunc, True)
 
1701
        self.assertIs(None, result)
 
1702
        result = self.callDeprecated([], testfunc, False, 'result')
 
1703
        self.assertEqual('result', result)
 
1704
        self.callDeprecated(['i am deprecated'], testfunc, be_deprecated=True)
 
1705
        self.callDeprecated([], testfunc, be_deprecated=False)
 
1706
 
 
1707
 
 
1708
class TestWarningTests(tests.TestCase):
 
1709
    """Tests for calling methods that raise warnings."""
 
1710
 
 
1711
    def test_callCatchWarnings(self):
 
1712
        def meth(a, b):
 
1713
            warnings.warn("this is your last warning")
 
1714
            return a + b
 
1715
        wlist, result = self.callCatchWarnings(meth, 1, 2)
 
1716
        self.assertEquals(3, result)
 
1717
        # would like just to compare them, but UserWarning doesn't implement
 
1718
        # eq well
 
1719
        w0, = wlist
 
1720
        self.assertIsInstance(w0, UserWarning)
 
1721
        self.assertEquals("this is your last warning", str(w0))
 
1722
 
 
1723
 
 
1724
class TestConvenienceMakers(tests.TestCaseWithTransport):
 
1725
    """Test for the make_* convenience functions."""
 
1726
 
 
1727
    def test_make_branch_and_tree_with_format(self):
 
1728
        # we should be able to supply a format to make_branch_and_tree
 
1729
        self.make_branch_and_tree('a', format=bzrlib.bzrdir.BzrDirMetaFormat1())
 
1730
        self.make_branch_and_tree('b', format=bzrlib.bzrdir.BzrDirFormat6())
 
1731
        self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('a')._format,
 
1732
                              bzrlib.bzrdir.BzrDirMetaFormat1)
 
1733
        self.assertIsInstance(bzrlib.bzrdir.BzrDir.open('b')._format,
 
1734
                              bzrlib.bzrdir.BzrDirFormat6)
 
1735
 
 
1736
    def test_make_branch_and_memory_tree(self):
 
1737
        # we should be able to get a new branch and a mutable tree from
 
1738
        # TestCaseWithTransport
 
1739
        tree = self.make_branch_and_memory_tree('a')
 
1740
        self.assertIsInstance(tree, bzrlib.memorytree.MemoryTree)
 
1741
 
 
1742
 
 
1743
class TestSFTPMakeBranchAndTree(test_sftp_transport.TestCaseWithSFTPServer):
 
1744
 
 
1745
    def test_make_tree_for_sftp_branch(self):
 
1746
        """Transports backed by local directories create local trees."""
 
1747
 
 
1748
        tree = self.make_branch_and_tree('t1')
 
1749
        base = tree.bzrdir.root_transport.base
 
1750
        self.failIf(base.startswith('sftp'),
 
1751
                'base %r is on sftp but should be local' % base)
 
1752
        self.assertEquals(tree.bzrdir.root_transport,
 
1753
                tree.branch.bzrdir.root_transport)
 
1754
        self.assertEquals(tree.bzrdir.root_transport,
 
1755
                tree.branch.repository.bzrdir.root_transport)
 
1756
 
 
1757
 
 
1758
class TestSelftest(tests.TestCase):
 
1759
    """Tests of bzrlib.tests.selftest."""
 
1760
 
 
1761
    def test_selftest_benchmark_parameter_invokes_test_suite__benchmark__(self):
 
1762
        factory_called = []
 
1763
        def factory():
 
1764
            factory_called.append(True)
 
1765
            return TestUtil.TestSuite()
 
1766
        out = StringIO()
 
1767
        err = StringIO()
 
1768
        self.apply_redirected(out, err, None, bzrlib.tests.selftest,
 
1769
            test_suite_factory=factory)
 
1770
        self.assertEqual([True], factory_called)
 
1771
 
 
1772
 
 
1773
class TestKnownFailure(tests.TestCase):
 
1774
 
 
1775
    def test_known_failure(self):
 
1776
        """Check that KnownFailure is defined appropriately."""
 
1777
        # a KnownFailure is an assertion error for compatability with unaware
 
1778
        # runners.
 
1779
        self.assertIsInstance(tests.KnownFailure(""), AssertionError)
 
1780
 
 
1781
    def test_expect_failure(self):
 
1782
        try:
 
1783
            self.expectFailure("Doomed to failure", self.assertTrue, False)
 
1784
        except tests.KnownFailure, e:
 
1785
            self.assertEqual('Doomed to failure', e.args[0])
 
1786
        try:
 
1787
            self.expectFailure("Doomed to failure", self.assertTrue, True)
 
1788
        except AssertionError, e:
 
1789
            self.assertEqual('Unexpected success.  Should have failed:'
 
1790
                             ' Doomed to failure', e.args[0])
 
1791
        else:
 
1792
            self.fail('Assertion not raised')
 
1793
 
 
1794
 
 
1795
class TestFeature(tests.TestCase):
 
1796
 
 
1797
    def test_caching(self):
 
1798
        """Feature._probe is called by the feature at most once."""
 
1799
        class InstrumentedFeature(tests.Feature):
 
1800
            def __init__(self):
 
1801
                super(InstrumentedFeature, self).__init__()
 
1802
                self.calls = []
 
1803
            def _probe(self):
 
1804
                self.calls.append('_probe')
 
1805
                return False
 
1806
        feature = InstrumentedFeature()
 
1807
        feature.available()
 
1808
        self.assertEqual(['_probe'], feature.calls)
 
1809
        feature.available()
 
1810
        self.assertEqual(['_probe'], feature.calls)
 
1811
 
 
1812
    def test_named_str(self):
 
1813
        """Feature.__str__ should thunk to feature_name()."""
 
1814
        class NamedFeature(tests.Feature):
 
1815
            def feature_name(self):
 
1816
                return 'symlinks'
 
1817
        feature = NamedFeature()
 
1818
        self.assertEqual('symlinks', str(feature))
 
1819
 
 
1820
    def test_default_str(self):
 
1821
        """Feature.__str__ should default to __class__.__name__."""
 
1822
        class NamedFeature(tests.Feature):
 
1823
            pass
 
1824
        feature = NamedFeature()
 
1825
        self.assertEqual('NamedFeature', str(feature))
 
1826
 
 
1827
 
 
1828
class TestUnavailableFeature(tests.TestCase):
 
1829
 
 
1830
    def test_access_feature(self):
 
1831
        feature = tests.Feature()
 
1832
        exception = tests.UnavailableFeature(feature)
 
1833
        self.assertIs(feature, exception.args[0])
 
1834
 
 
1835
 
 
1836
class TestSelftestFiltering(tests.TestCase):
 
1837
 
 
1838
    def setUp(self):
 
1839
        tests.TestCase.setUp(self)
 
1840
        self.suite = TestUtil.TestSuite()
 
1841
        self.loader = TestUtil.TestLoader()
 
1842
        self.suite.addTest(self.loader.loadTestsFromModuleNames([
 
1843
            'bzrlib.tests.test_selftest']))
 
1844
        self.all_names = _test_ids(self.suite)
 
1845
 
 
1846
    def test_condition_id_re(self):
 
1847
        test_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
 
1848
            'test_condition_id_re')
 
1849
        filtered_suite = tests.filter_suite_by_condition(
 
1850
            self.suite, tests.condition_id_re('test_condition_id_re'))
 
1851
        self.assertEqual([test_name], _test_ids(filtered_suite))
 
1852
 
 
1853
    def test_condition_id_in_list(self):
 
1854
        test_names = ['bzrlib.tests.test_selftest.TestSelftestFiltering.'
 
1855
                      'test_condition_id_in_list']
 
1856
        id_list = tests.TestIdList(test_names)
 
1857
        filtered_suite = tests.filter_suite_by_condition(
 
1858
            self.suite, tests.condition_id_in_list(id_list))
 
1859
        my_pattern = 'TestSelftestFiltering.*test_condition_id_in_list'
 
1860
        re_filtered = tests.filter_suite_by_re(self.suite, my_pattern)
 
1861
        self.assertEqual(_test_ids(re_filtered), _test_ids(filtered_suite))
 
1862
 
 
1863
    def test_condition_id_startswith(self):
 
1864
        klass = 'bzrlib.tests.test_selftest.TestSelftestFiltering.'
 
1865
        start1 = klass + 'test_condition_id_starts'
 
1866
        start2 = klass + 'test_condition_id_in'
 
1867
        test_names = [ klass + 'test_condition_id_in_list',
 
1868
                      klass + 'test_condition_id_startswith',
 
1869
                     ]
 
1870
        filtered_suite = tests.filter_suite_by_condition(
 
1871
            self.suite, tests.condition_id_startswith([start1, start2]))
 
1872
        self.assertEqual(test_names, _test_ids(filtered_suite))
 
1873
 
 
1874
    def test_condition_isinstance(self):
 
1875
        filtered_suite = tests.filter_suite_by_condition(
 
1876
            self.suite, tests.condition_isinstance(self.__class__))
 
1877
        class_pattern = 'bzrlib.tests.test_selftest.TestSelftestFiltering.'
 
1878
        re_filtered = tests.filter_suite_by_re(self.suite, class_pattern)
 
1879
        self.assertEqual(_test_ids(re_filtered), _test_ids(filtered_suite))
 
1880
 
 
1881
    def test_exclude_tests_by_condition(self):
 
1882
        excluded_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
 
1883
            'test_exclude_tests_by_condition')
 
1884
        filtered_suite = tests.exclude_tests_by_condition(self.suite,
 
1885
            lambda x:x.id() == excluded_name)
 
1886
        self.assertEqual(len(self.all_names) - 1,
 
1887
            filtered_suite.countTestCases())
 
1888
        self.assertFalse(excluded_name in _test_ids(filtered_suite))
 
1889
        remaining_names = list(self.all_names)
 
1890
        remaining_names.remove(excluded_name)
 
1891
        self.assertEqual(remaining_names, _test_ids(filtered_suite))
 
1892
 
 
1893
    def test_exclude_tests_by_re(self):
 
1894
        self.all_names = _test_ids(self.suite)
 
1895
        filtered_suite = tests.exclude_tests_by_re(self.suite,
 
1896
                                                   'exclude_tests_by_re')
 
1897
        excluded_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
 
1898
            'test_exclude_tests_by_re')
 
1899
        self.assertEqual(len(self.all_names) - 1,
 
1900
            filtered_suite.countTestCases())
 
1901
        self.assertFalse(excluded_name in _test_ids(filtered_suite))
 
1902
        remaining_names = list(self.all_names)
 
1903
        remaining_names.remove(excluded_name)
 
1904
        self.assertEqual(remaining_names, _test_ids(filtered_suite))
 
1905
 
 
1906
    def test_filter_suite_by_condition(self):
 
1907
        test_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
 
1908
            'test_filter_suite_by_condition')
 
1909
        filtered_suite = tests.filter_suite_by_condition(self.suite,
 
1910
            lambda x:x.id() == test_name)
 
1911
        self.assertEqual([test_name], _test_ids(filtered_suite))
 
1912
 
 
1913
    def test_filter_suite_by_re(self):
 
1914
        filtered_suite = tests.filter_suite_by_re(self.suite,
 
1915
                                                  'test_filter_suite_by_r')
 
1916
        filtered_names = _test_ids(filtered_suite)
 
1917
        self.assertEqual(filtered_names, ['bzrlib.tests.test_selftest.'
 
1918
            'TestSelftestFiltering.test_filter_suite_by_re'])
 
1919
 
 
1920
    def test_filter_suite_by_id_list(self):
 
1921
        test_list = ['bzrlib.tests.test_selftest.'
 
1922
                     'TestSelftestFiltering.test_filter_suite_by_id_list']
 
1923
        filtered_suite = tests.filter_suite_by_id_list(
 
1924
            self.suite, tests.TestIdList(test_list))
 
1925
        filtered_names = _test_ids(filtered_suite)
 
1926
        self.assertEqual(
 
1927
            filtered_names,
 
1928
            ['bzrlib.tests.test_selftest.'
 
1929
             'TestSelftestFiltering.test_filter_suite_by_id_list'])
 
1930
 
 
1931
    def test_filter_suite_by_id_startswith(self):
 
1932
        # By design this test may fail if another test is added whose name also
 
1933
        # begins with one of the start value used.
 
1934
        klass = 'bzrlib.tests.test_selftest.TestSelftestFiltering.'
 
1935
        start1 = klass + 'test_filter_suite_by_id_starts'
 
1936
        start2 = klass + 'test_filter_suite_by_id_li'
 
1937
        test_list = [klass + 'test_filter_suite_by_id_list',
 
1938
                     klass + 'test_filter_suite_by_id_startswith',
 
1939
                     ]
 
1940
        filtered_suite = tests.filter_suite_by_id_startswith(
 
1941
            self.suite, [start1, start2])
 
1942
        self.assertEqual(
 
1943
            test_list,
 
1944
            _test_ids(filtered_suite),
 
1945
            )
 
1946
 
 
1947
    def test_preserve_input(self):
 
1948
        # NB: Surely this is something in the stdlib to do this?
 
1949
        self.assertTrue(self.suite is tests.preserve_input(self.suite))
 
1950
        self.assertTrue("@#$" is tests.preserve_input("@#$"))
 
1951
 
 
1952
    def test_randomize_suite(self):
 
1953
        randomized_suite = tests.randomize_suite(self.suite)
 
1954
        # randomizing should not add or remove test names.
 
1955
        self.assertEqual(set(_test_ids(self.suite)),
 
1956
                         set(_test_ids(randomized_suite)))
 
1957
        # Technically, this *can* fail, because random.shuffle(list) can be
 
1958
        # equal to list. Trying multiple times just pushes the frequency back.
 
1959
        # As its len(self.all_names)!:1, the failure frequency should be low
 
1960
        # enough to ignore. RBC 20071021.
 
1961
        # It should change the order.
 
1962
        self.assertNotEqual(self.all_names, _test_ids(randomized_suite))
 
1963
        # But not the length. (Possibly redundant with the set test, but not
 
1964
        # necessarily.)
 
1965
        self.assertEqual(len(self.all_names), len(_test_ids(randomized_suite)))
 
1966
 
 
1967
    def test_split_suit_by_condition(self):
 
1968
        self.all_names = _test_ids(self.suite)
 
1969
        condition = tests.condition_id_re('test_filter_suite_by_r')
 
1970
        split_suite = tests.split_suite_by_condition(self.suite, condition)
 
1971
        filtered_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
 
1972
            'test_filter_suite_by_re')
 
1973
        self.assertEqual([filtered_name], _test_ids(split_suite[0]))
 
1974
        self.assertFalse(filtered_name in _test_ids(split_suite[1]))
 
1975
        remaining_names = list(self.all_names)
 
1976
        remaining_names.remove(filtered_name)
 
1977
        self.assertEqual(remaining_names, _test_ids(split_suite[1]))
 
1978
 
 
1979
    def test_split_suit_by_re(self):
 
1980
        self.all_names = _test_ids(self.suite)
 
1981
        split_suite = tests.split_suite_by_re(self.suite,
 
1982
                                              'test_filter_suite_by_r')
 
1983
        filtered_name = ('bzrlib.tests.test_selftest.TestSelftestFiltering.'
 
1984
            'test_filter_suite_by_re')
 
1985
        self.assertEqual([filtered_name], _test_ids(split_suite[0]))
 
1986
        self.assertFalse(filtered_name in _test_ids(split_suite[1]))
 
1987
        remaining_names = list(self.all_names)
 
1988
        remaining_names.remove(filtered_name)
 
1989
        self.assertEqual(remaining_names, _test_ids(split_suite[1]))
 
1990
 
 
1991
 
 
1992
class TestCheckInventoryShape(tests.TestCaseWithTransport):
 
1993
 
 
1994
    def test_check_inventory_shape(self):
 
1995
        files = ['a', 'b/', 'b/c']
 
1996
        tree = self.make_branch_and_tree('.')
 
1997
        self.build_tree(files)
 
1998
        tree.add(files)
 
1999
        tree.lock_read()
 
2000
        try:
 
2001
            self.check_inventory_shape(tree.inventory, files)
 
2002
        finally:
 
2003
            tree.unlock()
 
2004
 
 
2005
 
 
2006
class TestBlackboxSupport(tests.TestCase):
 
2007
    """Tests for testsuite blackbox features."""
 
2008
 
 
2009
    def test_run_bzr_failure_not_caught(self):
 
2010
        # When we run bzr in blackbox mode, we want any unexpected errors to
 
2011
        # propagate up to the test suite so that it can show the error in the
 
2012
        # usual way, and we won't get a double traceback.
 
2013
        e = self.assertRaises(
 
2014
            AssertionError,
 
2015
            self.run_bzr, ['assert-fail'])
 
2016
        # make sure we got the real thing, not an error from somewhere else in
 
2017
        # the test framework
 
2018
        self.assertEquals('always fails', str(e))
 
2019
        # check that there's no traceback in the test log
 
2020
        self.assertNotContainsRe(self._get_log(keep_log_file=True),
 
2021
            r'Traceback')
 
2022
 
 
2023
    def test_run_bzr_user_error_caught(self):
 
2024
        # Running bzr in blackbox mode, normal/expected/user errors should be
 
2025
        # caught in the regular way and turned into an error message plus exit
 
2026
        # code.
 
2027
        out, err = self.run_bzr(["log", "/nonexistantpath"], retcode=3)
 
2028
        self.assertEqual(out, '')
 
2029
        self.assertContainsRe(err,
 
2030
            'bzr: ERROR: Not a branch: ".*nonexistantpath/".\n')
 
2031
 
 
2032
 
 
2033
class TestTestLoader(tests.TestCase):
 
2034
    """Tests for the test loader."""
 
2035
 
 
2036
    def _get_loader_and_module(self):
 
2037
        """Gets a TestLoader and a module with one test in it."""
 
2038
        loader = TestUtil.TestLoader()
 
2039
        module = {}
 
2040
        class Stub(tests.TestCase):
 
2041
            def test_foo(self):
 
2042
                pass
 
2043
        class MyModule(object):
 
2044
            pass
 
2045
        MyModule.a_class = Stub
 
2046
        module = MyModule()
 
2047
        return loader, module
 
2048
 
 
2049
    def test_module_no_load_tests_attribute_loads_classes(self):
 
2050
        loader, module = self._get_loader_and_module()
 
2051
        self.assertEqual(1, loader.loadTestsFromModule(module).countTestCases())
 
2052
 
 
2053
    def test_module_load_tests_attribute_gets_called(self):
 
2054
        loader, module = self._get_loader_and_module()
 
2055
        # 'self' is here because we're faking the module with a class. Regular
 
2056
        # load_tests do not need that :)
 
2057
        def load_tests(self, standard_tests, module, loader):
 
2058
            result = loader.suiteClass()
 
2059
            for test in tests.iter_suite_tests(standard_tests):
 
2060
                result.addTests([test, test])
 
2061
            return result
 
2062
        # add a load_tests() method which multiplies the tests from the module.
 
2063
        module.__class__.load_tests = load_tests
 
2064
        self.assertEqual(2, loader.loadTestsFromModule(module).countTestCases())
 
2065
 
 
2066
    def test_load_tests_from_module_name_smoke_test(self):
 
2067
        loader = TestUtil.TestLoader()
 
2068
        suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
 
2069
        self.assertEquals(['bzrlib.tests.test_sampler.DemoTest.test_nothing'],
 
2070
                          _test_ids(suite))
 
2071
 
 
2072
    def test_load_tests_from_module_name_with_bogus_module_name(self):
 
2073
        loader = TestUtil.TestLoader()
 
2074
        self.assertRaises(ImportError, loader.loadTestsFromModuleName, 'bogus')
 
2075
 
 
2076
 
 
2077
class TestTestIdList(tests.TestCase):
 
2078
 
 
2079
    def _create_id_list(self, test_list):
 
2080
        return tests.TestIdList(test_list)
 
2081
 
 
2082
    def _create_suite(self, test_id_list):
 
2083
 
 
2084
        class Stub(tests.TestCase):
 
2085
            def test_foo(self):
 
2086
                pass
 
2087
 
 
2088
        def _create_test_id(id):
 
2089
            return lambda: id
 
2090
 
 
2091
        suite = TestUtil.TestSuite()
 
2092
        for id in test_id_list:
 
2093
            t  = Stub('test_foo')
 
2094
            t.id = _create_test_id(id)
 
2095
            suite.addTest(t)
 
2096
        return suite
 
2097
 
 
2098
    def _test_ids(self, test_suite):
 
2099
        """Get the ids for the tests in a test suite."""
 
2100
        return [t.id() for t in tests.iter_suite_tests(test_suite)]
 
2101
 
 
2102
    def test_empty_list(self):
 
2103
        id_list = self._create_id_list([])
 
2104
        self.assertEquals({}, id_list.tests)
 
2105
        self.assertEquals({}, id_list.modules)
 
2106
 
 
2107
    def test_valid_list(self):
 
2108
        id_list = self._create_id_list(
 
2109
            ['mod1.cl1.meth1', 'mod1.cl1.meth2',
 
2110
             'mod1.func1', 'mod1.cl2.meth2',
 
2111
             'mod1.submod1',
 
2112
             'mod1.submod2.cl1.meth1', 'mod1.submod2.cl2.meth2',
 
2113
             ])
 
2114
        self.assertTrue(id_list.refers_to('mod1'))
 
2115
        self.assertTrue(id_list.refers_to('mod1.submod1'))
 
2116
        self.assertTrue(id_list.refers_to('mod1.submod2'))
 
2117
        self.assertTrue(id_list.includes('mod1.cl1.meth1'))
 
2118
        self.assertTrue(id_list.includes('mod1.submod1'))
 
2119
        self.assertTrue(id_list.includes('mod1.func1'))
 
2120
 
 
2121
    def test_bad_chars_in_params(self):
 
2122
        id_list = self._create_id_list(['mod1.cl1.meth1(xx.yy)'])
 
2123
        self.assertTrue(id_list.refers_to('mod1'))
 
2124
        self.assertTrue(id_list.includes('mod1.cl1.meth1(xx.yy)'))
 
2125
 
 
2126
    def test_module_used(self):
 
2127
        id_list = self._create_id_list(['mod.class.meth'])
 
2128
        self.assertTrue(id_list.refers_to('mod'))
 
2129
        self.assertTrue(id_list.refers_to('mod.class'))
 
2130
        self.assertTrue(id_list.refers_to('mod.class.meth'))
 
2131
 
 
2132
    def test_test_suite_matches_id_list_with_unknown(self):
 
2133
        loader = TestUtil.TestLoader()
 
2134
        suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
 
2135
        test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing',
 
2136
                     'bogus']
 
2137
        not_found, duplicates = tests.suite_matches_id_list(suite, test_list)
 
2138
        self.assertEquals(['bogus'], not_found)
 
2139
        self.assertEquals([], duplicates)
 
2140
 
 
2141
    def test_suite_matches_id_list_with_duplicates(self):
 
2142
        loader = TestUtil.TestLoader()
 
2143
        suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
 
2144
        dupes = loader.suiteClass()
 
2145
        for test in tests.iter_suite_tests(suite):
 
2146
            dupes.addTest(test)
 
2147
            dupes.addTest(test) # Add it again
 
2148
 
 
2149
        test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing',]
 
2150
        not_found, duplicates = tests.suite_matches_id_list(
 
2151
            dupes, test_list)
 
2152
        self.assertEquals([], not_found)
 
2153
        self.assertEquals(['bzrlib.tests.test_sampler.DemoTest.test_nothing'],
 
2154
                          duplicates)
 
2155
 
 
2156
 
 
2157
class TestTestSuite(tests.TestCase):
 
2158
 
 
2159
    def test_test_suite(self):
 
2160
        # This test is slow, so we do a single test with one test in each
 
2161
        # category
 
2162
        test_list = [
 
2163
            # testmod_names
 
2164
            'bzrlib.tests.blackbox.test_branch.TestBranch.test_branch',
 
2165
            ('bzrlib.tests.per_transport.TransportTests'
 
2166
             '.test_abspath(LocalURLServer)'),
 
2167
            'bzrlib.tests.test_selftest.TestTestSuite.test_test_suite',
 
2168
            # modules_to_doctest
 
2169
            'bzrlib.timestamp.format_highres_date',
 
2170
            # plugins can't be tested that way since selftest may be run with
 
2171
            # --no-plugins
 
2172
            ]
 
2173
        suite = tests.test_suite(test_list)
 
2174
        self.assertEquals(test_list, _test_ids(suite))
 
2175
 
 
2176
    def test_test_suite_list_and_start(self):
 
2177
        test_list = ['bzrlib.tests.test_selftest.TestTestSuite.test_test_suite']
 
2178
        suite = tests.test_suite(test_list,
 
2179
                                 ['bzrlib.tests.test_selftest.TestTestSuite'])
 
2180
        # test_test_suite_list_and_start is not included 
 
2181
        self.assertEquals(test_list, _test_ids(suite))
 
2182
 
 
2183
 
 
2184
class TestLoadTestIdList(tests.TestCaseInTempDir):
 
2185
 
 
2186
    def _create_test_list_file(self, file_name, content):
 
2187
        fl = open(file_name, 'wt')
 
2188
        fl.write(content)
 
2189
        fl.close()
 
2190
 
 
2191
    def test_load_unknown(self):
 
2192
        self.assertRaises(errors.NoSuchFile,
 
2193
                          tests.load_test_id_list, 'i_do_not_exist')
 
2194
 
 
2195
    def test_load_test_list(self):
 
2196
        test_list_fname = 'test.list'
 
2197
        self._create_test_list_file(test_list_fname,
 
2198
                                    'mod1.cl1.meth1\nmod2.cl2.meth2\n')
 
2199
        tlist = tests.load_test_id_list(test_list_fname)
 
2200
        self.assertEquals(2, len(tlist))
 
2201
        self.assertEquals('mod1.cl1.meth1', tlist[0])
 
2202
        self.assertEquals('mod2.cl2.meth2', tlist[1])
 
2203
 
 
2204
    def test_load_dirty_file(self):
 
2205
        test_list_fname = 'test.list'
 
2206
        self._create_test_list_file(test_list_fname,
 
2207
                                    '  mod1.cl1.meth1\n\nmod2.cl2.meth2  \n'
 
2208
                                    'bar baz\n')
 
2209
        tlist = tests.load_test_id_list(test_list_fname)
 
2210
        self.assertEquals(4, len(tlist))
 
2211
        self.assertEquals('mod1.cl1.meth1', tlist[0])
 
2212
        self.assertEquals('', tlist[1])
 
2213
        self.assertEquals('mod2.cl2.meth2', tlist[2])
 
2214
        self.assertEquals('bar baz', tlist[3])
 
2215
 
 
2216
 
 
2217
class TestFilteredByModuleTestLoader(tests.TestCase):
 
2218
 
 
2219
    def _create_loader(self, test_list):
 
2220
        id_filter = tests.TestIdList(test_list)
 
2221
        loader = TestUtil.FilteredByModuleTestLoader(id_filter.refers_to)
 
2222
        return loader
 
2223
 
 
2224
    def test_load_tests(self):
 
2225
        test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
 
2226
        loader = self._create_loader(test_list)
 
2227
 
 
2228
        suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
 
2229
        self.assertEquals(test_list, _test_ids(suite))
 
2230
 
 
2231
    def test_exclude_tests(self):
 
2232
        test_list = ['bogus']
 
2233
        loader = self._create_loader(test_list)
 
2234
 
 
2235
        suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
 
2236
        self.assertEquals([], _test_ids(suite))
 
2237
 
 
2238
 
 
2239
class TestFilteredByNameStartTestLoader(tests.TestCase):
 
2240
 
 
2241
    def _create_loader(self, name_start):
 
2242
        def needs_module(name):
 
2243
            return name.startswith(name_start) or name_start.startswith(name)
 
2244
        loader = TestUtil.FilteredByModuleTestLoader(needs_module)
 
2245
        return loader
 
2246
 
 
2247
    def test_load_tests(self):
 
2248
        test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
 
2249
        loader = self._create_loader('bzrlib.tests.test_samp')
 
2250
 
 
2251
        suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
 
2252
        self.assertEquals(test_list, _test_ids(suite))
 
2253
 
 
2254
    def test_load_tests_inside_module(self):
 
2255
        test_list = ['bzrlib.tests.test_sampler.DemoTest.test_nothing']
 
2256
        loader = self._create_loader('bzrlib.tests.test_sampler.Demo')
 
2257
 
 
2258
        suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
 
2259
        self.assertEquals(test_list, _test_ids(suite))
 
2260
 
 
2261
    def test_exclude_tests(self):
 
2262
        test_list = ['bogus']
 
2263
        loader = self._create_loader('bogus')
 
2264
 
 
2265
        suite = loader.loadTestsFromModuleName('bzrlib.tests.test_sampler')
 
2266
        self.assertEquals([], _test_ids(suite))
 
2267
 
 
2268
 
 
2269
class TestTestPrefixRegistry(tests.TestCase):
 
2270
 
 
2271
    def _get_registry(self):
 
2272
        tp_registry = tests.TestPrefixAliasRegistry()
 
2273
        return tp_registry
 
2274
 
 
2275
    def test_register_new_prefix(self):
 
2276
        tpr = self._get_registry()
 
2277
        tpr.register('foo', 'fff.ooo.ooo')
 
2278
        self.assertEquals('fff.ooo.ooo', tpr.get('foo'))
 
2279
 
 
2280
    def test_register_existing_prefix(self):
 
2281
        tpr = self._get_registry()
 
2282
        tpr.register('bar', 'bbb.aaa.rrr')
 
2283
        tpr.register('bar', 'bBB.aAA.rRR')
 
2284
        self.assertEquals('bbb.aaa.rrr', tpr.get('bar'))
 
2285
        self.assertContainsRe(self._get_log(keep_log_file=True),
 
2286
                              r'.*bar.*bbb.aaa.rrr.*bBB.aAA.rRR')
 
2287
 
 
2288
    def test_get_unknown_prefix(self):
 
2289
        tpr = self._get_registry()
 
2290
        self.assertRaises(KeyError, tpr.get, 'I am not a prefix')
 
2291
 
 
2292
    def test_resolve_prefix(self):
 
2293
        tpr = self._get_registry()
 
2294
        tpr.register('bar', 'bb.aa.rr')
 
2295
        self.assertEquals('bb.aa.rr', tpr.resolve_alias('bar'))
 
2296
 
 
2297
    def test_resolve_unknown_alias(self):
 
2298
        tpr = self._get_registry()
 
2299
        self.assertRaises(errors.BzrCommandError,
 
2300
                          tpr.resolve_alias, 'I am not a prefix')
 
2301
 
 
2302
    def test_predefined_prefixes(self):
 
2303
        tpr = tests.test_prefix_alias_registry
 
2304
        self.assertEquals('bzrlib', tpr.resolve_alias('bzrlib'))
 
2305
        self.assertEquals('bzrlib.doc', tpr.resolve_alias('bd'))
 
2306
        self.assertEquals('bzrlib.utils', tpr.resolve_alias('bu'))
 
2307
        self.assertEquals('bzrlib.tests', tpr.resolve_alias('bt'))
 
2308
        self.assertEquals('bzrlib.tests.blackbox', tpr.resolve_alias('bb'))
 
2309
        self.assertEquals('bzrlib.plugins', tpr.resolve_alias('bp'))
 
2310
 
 
2311
 
 
2312
class TestRunSuite(tests.TestCase):
 
2313
 
 
2314
    def test_runner_class(self):
 
2315
        """run_suite accepts and uses a runner_class keyword argument."""
 
2316
        class Stub(tests.TestCase):
 
2317
            def test_foo(self):
 
2318
                pass
 
2319
        suite = Stub("test_foo")
 
2320
        calls = []
 
2321
        class MyRunner(tests.TextTestRunner):
 
2322
            def run(self, test):
 
2323
                calls.append(test)
 
2324
                return tests.ExtendedTestResult(self.stream, self.descriptions,
 
2325
                                                self.verbosity)
 
2326
        tests.run_suite(suite, runner_class=MyRunner, stream=StringIO())
 
2327
        self.assertLength(1, calls)
 
2328
 
 
2329
    def test_done(self):
 
2330
        """run_suite should call result.done()"""
 
2331
        self.calls = 0
 
2332
        def one_more_call(): self.calls += 1
 
2333
        def test_function():
 
2334
            pass
 
2335
        test = unittest.FunctionTestCase(test_function)
 
2336
        class InstrumentedTestResult(tests.ExtendedTestResult):
 
2337
            def done(self): one_more_call()
 
2338
        class MyRunner(tests.TextTestRunner):
 
2339
            def run(self, test):
 
2340
                return InstrumentedTestResult(self.stream, self.descriptions,
 
2341
                                              self.verbosity)
 
2342
        tests.run_suite(test, runner_class=MyRunner, stream=StringIO())
 
2343
        self.assertEquals(1, self.calls)