~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_selftest.py

  • Committer: Aaron Bentley
  • Date: 2007-12-20 20:44:45 UTC
  • mto: This revision was merged to the branch mainline in revision 3235.
  • Revision ID: abentley@panoramicfeedback.com-20071220204445-9o2f10gvvd8e4rks
Implement hard-link support for branch and checkout

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