/brz/remove-bazaar

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

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

  • Committer: Martin Pool
  • Date: 2009-08-14 11:11:29 UTC
  • mto: (4599.4.26 bug-398668)
  • mto: This revision was merged to the branch mainline in revision 4622.
  • Revision ID: mbp@sourcefrog.net-20090814111129-ozigh3o0jjfojiix
Remove redundant overrides of check_conversion_target

Show diffs side-by-side

added added

removed removed

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