/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 4 more lock-related test failures.

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