~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

  • Committer: Martin Pool
  • Date: 2009-06-19 10:00:56 UTC
  • mto: This revision was merged to the branch mainline in revision 4464.
  • Revision ID: mbp@sourcefrog.net-20090619100056-fco5ooae2ybl88ne
Fix copyrights and remove assert statement from doc_generate

Show diffs side-by-side

added added

removed removed

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