/brz/remove-bazaar

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

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

  • Committer: Martin Pool
  • Date: 2008-07-17 02:49:32 UTC
  • mto: This revision was merged to the branch mainline in revision 3552.
  • Revision ID: mbp@sourcefrog.net-20080717024932-um071rheljrlwepd
doc     

Show diffs side-by-side

added added

removed removed

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