/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/__init__.py

  • Committer: Robert Collins
  • Date: 2008-02-13 03:30:01 UTC
  • mfrom: (3221 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3224.
  • Revision ID: robertc@robertcollins.net-20080213033001-rw70ul0zb02ph856
Merge to fix conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
42
42
from subprocess import Popen, PIPE
43
43
import sys
44
44
import tempfile
 
45
import time
45
46
import unittest
46
 
import time
47
47
import warnings
48
48
 
49
49
 
77
77
import bzrlib.store
78
78
from bzrlib import symbol_versioning
79
79
from bzrlib.symbol_versioning import (
 
80
    DEPRECATED_PARAMETER,
 
81
    deprecated_function,
80
82
    deprecated_method,
 
83
    deprecated_passed,
81
84
    zero_ninetyone,
82
85
    zero_ninetytwo,
 
86
    one_zero,
83
87
    )
84
88
import bzrlib.trace
85
89
from bzrlib.transport import get_transport
89
93
from bzrlib.transport.readonly import ReadonlyServer
90
94
from bzrlib.trace import mutter, note
91
95
from bzrlib.tests import TestUtil
92
 
from bzrlib.tests.HttpServer import HttpServer
 
96
from bzrlib.tests.http_server import HttpServer
93
97
from bzrlib.tests.TestUtil import (
94
98
                          TestSuite,
95
99
                          TestLoader,
96
100
                          )
97
101
from bzrlib.tests.treeshape import build_tree_contents
 
102
import bzrlib.version_info_formats.format_custom
98
103
from bzrlib.workingtree import WorkingTree, WorkingTreeFormat2
99
104
 
100
105
# Mark this python module as being part of the implementation
115
120
        bzrlib.merge3,
116
121
        bzrlib.option,
117
122
        bzrlib.store,
 
123
        bzrlib.version_info_formats.format_custom,
118
124
        # quoted to avoid module-loading circularity
119
125
        'bzrlib.tests',
120
126
        ]
269
275
        elif isinstance(err[1], UnavailableFeature):
270
276
            return self.addNotSupported(test, err[1].args[0])
271
277
        else:
 
278
            self._cleanupLogFile(test)
272
279
            unittest.TestResult.addError(self, test, err)
273
280
            self.error_count += 1
274
281
            self.report_error(test, err)
285
292
        if isinstance(err[1], KnownFailure):
286
293
            return self._addKnownFailure(test, err)
287
294
        else:
 
295
            self._cleanupLogFile(test)
288
296
            unittest.TestResult.addFailure(self, test, err)
289
297
            self.failure_count += 1
290
298
            self.report_failure(test, err)
304
312
                    self._formatTime(benchmark_time),
305
313
                    test.id()))
306
314
        self.report_success(test)
 
315
        self._cleanupLogFile(test)
307
316
        unittest.TestResult.addSuccess(self, test)
308
317
 
309
318
    def _testConcluded(self, test):
311
320
 
312
321
        Called regardless of whether it succeded, failed, etc.
313
322
        """
314
 
        self._cleanupLogFile(test)
 
323
        pass
315
324
 
316
325
    def _addKnownFailure(self, test, err):
317
326
        self.known_failure_count += 1
788
797
    def setUp(self):
789
798
        unittest.TestCase.setUp(self)
790
799
        self._cleanEnvironment()
791
 
        bzrlib.trace.disable_default_logging()
792
800
        self._silenceUI()
793
801
        self._startLogFile()
794
802
        self._benchcalls = []
1032
1040
        else:
1033
1041
            self.fail('Unexpected success.  Should have failed: %s' % reason)
1034
1042
 
 
1043
    def assertFileEqual(self, content, path):
 
1044
        """Fail if path does not contain 'content'."""
 
1045
        self.failUnlessExists(path)
 
1046
        f = file(path, 'rb')
 
1047
        try:
 
1048
            s = f.read()
 
1049
        finally:
 
1050
            f.close()
 
1051
        self.assertEqualDiff(content, s)
 
1052
 
 
1053
    def failUnlessExists(self, path):
 
1054
        """Fail unless path or paths, which may be abs or relative, exist."""
 
1055
        if not isinstance(path, basestring):
 
1056
            for p in path:
 
1057
                self.failUnlessExists(p)
 
1058
        else:
 
1059
            self.failUnless(osutils.lexists(path),path+" does not exist")
 
1060
 
 
1061
    def failIfExists(self, path):
 
1062
        """Fail if path or paths, which may be abs or relative, exist."""
 
1063
        if not isinstance(path, basestring):
 
1064
            for p in path:
 
1065
                self.failIfExists(p)
 
1066
        else:
 
1067
            self.failIf(osutils.lexists(path),path+" exists")
 
1068
 
1035
1069
    def _capture_deprecation_warnings(self, a_callable, *args, **kwargs):
1036
1070
        """A helper for callDeprecated and applyDeprecated.
1037
1071
 
1150
1184
        """
1151
1185
        fileno, name = tempfile.mkstemp(suffix='.log', prefix='testbzr')
1152
1186
        self._log_file = os.fdopen(fileno, 'w+')
1153
 
        self._log_nonce = bzrlib.trace.enable_test_log(self._log_file)
 
1187
        self._log_memento = bzrlib.trace.push_log_file(self._log_file)
1154
1188
        self._log_file_name = name
1155
1189
        self.addCleanup(self._finishLogFile)
1156
1190
 
1161
1195
        """
1162
1196
        if self._log_file is None:
1163
1197
            return
1164
 
        bzrlib.trace.disable_test_log(self._log_nonce)
 
1198
        bzrlib.trace.pop_log_file(self._log_memento)
1165
1199
        self._log_file.close()
1166
1200
        self._log_file = None
1167
1201
        if not self._keep_log_file:
1304
1338
        import bzrlib.trace
1305
1339
        bzrlib.trace._trace_file.flush()
1306
1340
        if self._log_contents:
 
1341
            # XXX: this can hardly contain the content flushed above --vila
 
1342
            # 20080128
1307
1343
            return self._log_contents
1308
1344
        if self._log_file_name is not None:
1309
1345
            logfile = open(self._log_file_name)
1713
1749
    _TEST_NAME = 'test'
1714
1750
 
1715
1751
    def __init__(self, methodName='runTest'):
1716
 
        # allow test parameterisation after test construction and before test
1717
 
        # execution. Variables that the parameteriser sets need to be 
 
1752
        # allow test parameterization after test construction and before test
 
1753
        # execution. Variables that the parameterizer sets need to be 
1718
1754
        # ones that are not set by setUp, or setUp will trash them.
1719
1755
        super(TestCaseWithMemoryTransport, self).__init__(methodName)
1720
1756
        self.vfs_transport_factory = default_transport
2045
2081
 
2046
2082
        This doesn't add anything to a branch.
2047
2083
 
 
2084
        :type shape:    list or tuple.
2048
2085
        :param line_endings: Either 'binary' or 'native'
2049
2086
            in binary mode, exact contents are written in native mode, the
2050
2087
            line endings match the default platform endings.
2052
2089
            If the transport is readonly or None, "." is opened automatically.
2053
2090
        :return: None
2054
2091
        """
 
2092
        if type(shape) not in (list, tuple):
 
2093
            raise AssertionError("Parameter 'shape' should be "
 
2094
                "a list or a tuple. Got %r instead" % (shape,))
2055
2095
        # It's OK to just create them using forward slashes on windows.
2056
2096
        if transport is None or transport.is_readonly():
2057
2097
            transport = get_transport(".")
2073
2113
    def build_tree_contents(self, shape):
2074
2114
        build_tree_contents(shape)
2075
2115
 
2076
 
    def assertFileEqual(self, content, path):
2077
 
        """Fail if path does not contain 'content'."""
2078
 
        self.failUnlessExists(path)
2079
 
        f = file(path, 'rb')
2080
 
        try:
2081
 
            s = f.read()
2082
 
        finally:
2083
 
            f.close()
2084
 
        self.assertEqualDiff(content, s)
2085
 
 
2086
 
    def failUnlessExists(self, path):
2087
 
        """Fail unless path or paths, which may be abs or relative, exist."""
2088
 
        if not isinstance(path, basestring):
2089
 
            for p in path:
2090
 
                self.failUnlessExists(p)
2091
 
        else:
2092
 
            self.failUnless(osutils.lexists(path),path+" does not exist")
2093
 
 
2094
 
    def failIfExists(self, path):
2095
 
        """Fail if path or paths, which may be abs or relative, exist."""
2096
 
        if not isinstance(path, basestring):
2097
 
            for p in path:
2098
 
                self.failIfExists(p)
2099
 
        else:
2100
 
            self.failIf(osutils.lexists(path),path+" exists")
2101
 
 
2102
2116
    def assertInWorkingTree(self, path, root_path='.', tree=None):
2103
2117
        """Assert whether path or paths are in the WorkingTree"""
2104
2118
        if tree is None:
2226
2240
            self.transport_readonly_server = HttpServer
2227
2241
 
2228
2242
 
2229
 
def filter_suite_by_re(suite, pattern, exclude_pattern=None,
2230
 
                       random_order=False):
 
2243
def condition_id_re(pattern):
 
2244
    """Create a condition filter which performs a re check on a test's id.
 
2245
    
 
2246
    :param pattern: A regular expression string.
 
2247
    :return: A callable that returns True if the re matches.
 
2248
    """
 
2249
    filter_re = re.compile(pattern)
 
2250
    def condition(test):
 
2251
        test_id = test.id()
 
2252
        return filter_re.search(test_id)
 
2253
    return condition
 
2254
 
 
2255
 
 
2256
def condition_isinstance(klass_or_klass_list):
 
2257
    """Create a condition filter which returns isinstance(param, klass).
 
2258
    
 
2259
    :return: A callable which when called with one parameter obj return the
 
2260
        result of isinstance(obj, klass_or_klass_list).
 
2261
    """
 
2262
    def condition(obj):
 
2263
        return isinstance(obj, klass_or_klass_list)
 
2264
    return condition
 
2265
 
 
2266
 
 
2267
def condition_id_in_list(id_list):
 
2268
    """Create a condition filter which verify that test's id in a list.
 
2269
    
 
2270
    :param name: A TestIdList object.
 
2271
    :return: A callable that returns True if the test's id appears in the list.
 
2272
    """
 
2273
    def condition(test):
 
2274
        return id_list.test_in(test.id())
 
2275
    return condition
 
2276
 
 
2277
 
 
2278
def exclude_tests_by_condition(suite, condition):
 
2279
    """Create a test suite which excludes some tests from suite.
 
2280
 
 
2281
    :param suite: The suite to get tests from.
 
2282
    :param condition: A callable whose result evaluates True when called with a
 
2283
        test case which should be excluded from the result.
 
2284
    :return: A suite which contains the tests found in suite that fail
 
2285
        condition.
 
2286
    """
 
2287
    result = []
 
2288
    for test in iter_suite_tests(suite):
 
2289
        if not condition(test):
 
2290
            result.append(test)
 
2291
    return TestUtil.TestSuite(result)
 
2292
 
 
2293
 
 
2294
def filter_suite_by_condition(suite, condition):
 
2295
    """Create a test suite by filtering another one.
 
2296
    
 
2297
    :param suite: The source suite.
 
2298
    :param condition: A callable whose result evaluates True when called with a
 
2299
        test case which should be included in the result.
 
2300
    :return: A suite which contains the tests found in suite that pass
 
2301
        condition.
 
2302
    """ 
 
2303
    result = []
 
2304
    for test in iter_suite_tests(suite):
 
2305
        if condition(test):
 
2306
            result.append(test)
 
2307
    return TestUtil.TestSuite(result)
 
2308
 
 
2309
 
 
2310
def filter_suite_by_re(suite, pattern, exclude_pattern=DEPRECATED_PARAMETER,
 
2311
                       random_order=DEPRECATED_PARAMETER):
2231
2312
    """Create a test suite by filtering another one.
2232
2313
    
2233
2314
    :param suite:           the source suite
2234
2315
    :param pattern:         pattern that names must match
2235
 
    :param exclude_pattern: pattern that names must not match, if any
2236
 
    :param random_order:    if True, tests in the new suite will be put in
2237
 
                            random order
 
2316
    :param exclude_pattern: A pattern that names must not match. This parameter
 
2317
        is deprecated as of bzrlib 1.0. Please use the separate function
 
2318
        exclude_tests_by_re instead.
 
2319
    :param random_order:    If True, tests in the new suite will be put in
 
2320
        random order. This parameter is deprecated as of bzrlib 1.0. Please
 
2321
        use the separate function randomize_suite instead.
2238
2322
    :returns: the newly created suite
2239
2323
    """ 
2240
 
    return sort_suite_by_re(suite, pattern, exclude_pattern,
2241
 
        random_order, False)
2242
 
 
2243
 
 
 
2324
    if deprecated_passed(exclude_pattern):
 
2325
        symbol_versioning.warn(
 
2326
            one_zero % "passing exclude_pattern to filter_suite_by_re",
 
2327
                DeprecationWarning, stacklevel=2)
 
2328
        if exclude_pattern is not None:
 
2329
            suite = exclude_tests_by_re(suite, exclude_pattern)
 
2330
    condition = condition_id_re(pattern)
 
2331
    result_suite = filter_suite_by_condition(suite, condition)
 
2332
    if deprecated_passed(random_order):
 
2333
        symbol_versioning.warn(
 
2334
            one_zero % "passing random_order to filter_suite_by_re",
 
2335
                DeprecationWarning, stacklevel=2)
 
2336
        if random_order:
 
2337
            result_suite = randomize_suite(result_suite)
 
2338
    return result_suite
 
2339
 
 
2340
 
 
2341
def filter_suite_by_id_list(suite, test_id_list):
 
2342
    """Create a test suite by filtering another one.
 
2343
 
 
2344
    :param suite: The source suite.
 
2345
    :param test_id_list: A list of the test ids to keep as strings.
 
2346
    :returns: the newly created suite
 
2347
    """
 
2348
    condition = condition_id_in_list(test_id_list)
 
2349
    result_suite = filter_suite_by_condition(suite, condition)
 
2350
    return result_suite
 
2351
 
 
2352
 
 
2353
def exclude_tests_by_re(suite, pattern):
 
2354
    """Create a test suite which excludes some tests from suite.
 
2355
 
 
2356
    :param suite: The suite to get tests from.
 
2357
    :param pattern: A regular expression string. Test ids that match this
 
2358
        pattern will be excluded from the result.
 
2359
    :return: A TestSuite that contains all the tests from suite without the
 
2360
        tests that matched pattern. The order of tests is the same as it was in
 
2361
        suite.
 
2362
    """
 
2363
    return exclude_tests_by_condition(suite, condition_id_re(pattern))
 
2364
 
 
2365
 
 
2366
def preserve_input(something):
 
2367
    """A helper for performing test suite transformation chains.
 
2368
 
 
2369
    :param something: Anything you want to preserve.
 
2370
    :return: Something.
 
2371
    """
 
2372
    return something
 
2373
 
 
2374
 
 
2375
def randomize_suite(suite):
 
2376
    """Return a new TestSuite with suite's tests in random order.
 
2377
    
 
2378
    The tests in the input suite are flattened into a single suite in order to
 
2379
    accomplish this. Any nested TestSuites are removed to provide global
 
2380
    randomness.
 
2381
    """
 
2382
    tests = list(iter_suite_tests(suite))
 
2383
    random.shuffle(tests)
 
2384
    return TestUtil.TestSuite(tests)
 
2385
 
 
2386
 
 
2387
@deprecated_function(one_zero)
2244
2388
def sort_suite_by_re(suite, pattern, exclude_pattern=None,
2245
2389
                     random_order=False, append_rest=True):
2246
 
    """Create a test suite by sorting another one.
 
2390
    """DEPRECATED: Create a test suite by sorting another one.
 
2391
 
 
2392
    This method has been decomposed into separate helper methods that should be
 
2393
    called directly:
 
2394
     - filter_suite_by_re
 
2395
     - exclude_tests_by_re
 
2396
     - randomize_suite
 
2397
     - split_suite_by_re
2247
2398
    
2248
2399
    :param suite:           the source suite
2249
2400
    :param pattern:         pattern that names must match in order to go
2250
2401
                            first in the new suite
2251
2402
    :param exclude_pattern: pattern that names must not match, if any
2252
2403
    :param random_order:    if True, tests in the new suite will be put in
2253
 
                            random order
 
2404
                            random order (with all tests matching pattern
 
2405
                            first).
2254
2406
    :param append_rest:     if False, pattern is a strict filter and not
2255
2407
                            just an ordering directive
2256
2408
    :returns: the newly created suite
2257
2409
    """ 
2258
 
    first = []
2259
 
    second = []
 
2410
    if exclude_pattern is not None:
 
2411
        suite = exclude_tests_by_re(suite, exclude_pattern)
 
2412
    if random_order:
 
2413
        order_changer = randomize_suite
 
2414
    else:
 
2415
        order_changer = preserve_input
 
2416
    if append_rest:
 
2417
        suites = map(order_changer, split_suite_by_re(suite, pattern))
 
2418
        return TestUtil.TestSuite(suites)
 
2419
    else:
 
2420
        return order_changer(filter_suite_by_re(suite, pattern))
 
2421
 
 
2422
 
 
2423
def split_suite_by_re(suite, pattern):
 
2424
    """Split a test suite into two by a regular expression.
 
2425
    
 
2426
    :param suite: The suite to split.
 
2427
    :param pattern: A regular expression string. Test ids that match this
 
2428
        pattern will be in the first test suite returned, and the others in the
 
2429
        second test suite returned.
 
2430
    :return: A tuple of two test suites, where the first contains tests from
 
2431
        suite matching pattern, and the second contains the remainder from
 
2432
        suite. The order within each output suite is the same as it was in
 
2433
        suite.
 
2434
    """ 
 
2435
    matched = []
 
2436
    did_not_match = []
2260
2437
    filter_re = re.compile(pattern)
2261
 
    if exclude_pattern is not None:
2262
 
        exclude_re = re.compile(exclude_pattern)
2263
2438
    for test in iter_suite_tests(suite):
2264
2439
        test_id = test.id()
2265
 
        if exclude_pattern is None or not exclude_re.search(test_id):
2266
 
            if filter_re.search(test_id):
2267
 
                first.append(test)
2268
 
            elif append_rest:
2269
 
                second.append(test)
2270
 
    if random_order:
2271
 
        random.shuffle(first)
2272
 
        random.shuffle(second)
2273
 
    return TestUtil.TestSuite(first + second)
 
2440
        if filter_re.search(test_id):
 
2441
            matched.append(test)
 
2442
        else:
 
2443
            did_not_match.append(test)
 
2444
    return TestUtil.TestSuite(matched), TestUtil.TestSuite(did_not_match)
2274
2445
 
2275
2446
 
2276
2447
def run_suite(suite, name='test', verbose=False, pattern=".*",
2280
2451
              list_only=False,
2281
2452
              random_seed=None,
2282
2453
              exclude_pattern=None,
2283
 
              strict=False,
2284
 
              ):
 
2454
              strict=False):
2285
2455
    TestCase._gather_lsprof_in_benchmarks = lsprof_timed
2286
2456
    if verbose:
2287
2457
        verbosity = 2
2311
2481
            (random_seed))
2312
2482
        random.seed(random_seed)
2313
2483
    # Customise the list of tests if requested
2314
 
    if pattern != '.*' or exclude_pattern is not None or random_order:
 
2484
    if exclude_pattern is not None:
 
2485
        suite = exclude_tests_by_re(suite, exclude_pattern)
 
2486
    if random_order:
 
2487
        order_changer = randomize_suite
 
2488
    else:
 
2489
        order_changer = preserve_input
 
2490
    if pattern != '.*' or random_order:
2315
2491
        if matching_tests_first:
2316
 
            suite = sort_suite_by_re(suite, pattern, exclude_pattern,
2317
 
                random_order)
 
2492
            suites = map(order_changer, split_suite_by_re(suite, pattern))
 
2493
            suite = TestUtil.TestSuite(suites)
2318
2494
        else:
2319
 
            suite = filter_suite_by_re(suite, pattern, exclude_pattern,
2320
 
                random_order)
 
2495
            suite = order_changer(filter_suite_by_re(suite, pattern))
 
2496
 
2321
2497
    result = runner.run(suite)
2322
2498
 
2323
2499
    if strict:
2336
2512
             random_seed=None,
2337
2513
             exclude_pattern=None,
2338
2514
             strict=False,
 
2515
             load_list=None,
2339
2516
             ):
2340
2517
    """Run the whole test suite under the enhanced runner"""
2341
2518
    # XXX: Very ugly way to do this...
2350
2527
    old_transport = default_transport
2351
2528
    default_transport = transport
2352
2529
    try:
 
2530
        if load_list is None:
 
2531
            keep_only = None
 
2532
        else:
 
2533
            keep_only = load_test_id_list(load_list)
2353
2534
        if test_suite_factory is None:
2354
 
            suite = test_suite()
 
2535
            suite = test_suite(keep_only)
2355
2536
        else:
2356
2537
            suite = test_suite_factory()
2357
2538
        return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
2368
2549
        default_transport = old_transport
2369
2550
 
2370
2551
 
2371
 
def test_suite():
 
2552
def load_test_id_list(file_name):
 
2553
    """Load a test id list from a text file.
 
2554
 
 
2555
    The format is one test id by line.  No special care is taken to impose
 
2556
    strict rules, these test ids are used to filter the test suite so a test id
 
2557
    that do not match an existing test will do no harm. This allows user to add
 
2558
    comments, leave blank lines, etc.
 
2559
    """
 
2560
    test_list = []
 
2561
    try:
 
2562
        ftest = open(file_name, 'rt')
 
2563
    except IOError, e:
 
2564
        if e.errno != errno.ENOENT:
 
2565
            raise
 
2566
        else:
 
2567
            raise errors.NoSuchFile(file_name)
 
2568
 
 
2569
    for test_name in ftest.readlines():
 
2570
        test_list.append(test_name.strip())
 
2571
    ftest.close()
 
2572
    return test_list
 
2573
 
 
2574
 
 
2575
class TestIdList(object):
 
2576
    """Test id list to filter a test suite.
 
2577
 
 
2578
    Relying on the assumption that test ids are built as:
 
2579
    <module>[.<class>.<method>][(<param>+)], <module> being in python dotted
 
2580
    notation, this class offers methods to :
 
2581
    - avoid building a test suite for modules not refered to in the test list,
 
2582
    - keep only the tests listed from the module test suite.
 
2583
    """
 
2584
 
 
2585
    def __init__(self, test_id_list):
 
2586
        # When a test suite needs to be filtered against us we compare test ids
 
2587
        # for equality, so a simple dict offers a quick and simple solution.
 
2588
        self.tests = dict().fromkeys(test_id_list, True)
 
2589
 
 
2590
        # While unittest.TestCase have ids like:
 
2591
        # <module>.<class>.<method>[(<param+)],
 
2592
        # doctest.DocTestCase can have ids like:
 
2593
        # <module>
 
2594
        # <module>.<class>
 
2595
        # <module>.<function>
 
2596
        # <module>.<class>.<method>
 
2597
 
 
2598
        # Since we can't predict a test class from its name only, we settle on
 
2599
        # a simple constraint: a test id always begins with its module name.
 
2600
 
 
2601
        modules = {}
 
2602
        for test_id in test_id_list:
 
2603
            parts = test_id.split('.')
 
2604
            mod_name = parts.pop(0)
 
2605
            modules[mod_name] = True
 
2606
            for part in parts:
 
2607
                mod_name += '.' + part
 
2608
                modules[mod_name] = True
 
2609
        self.modules = modules
 
2610
 
 
2611
    def is_module_name_used(self, module_name):
 
2612
        """Is there tests for the module or one of its sub modules."""
 
2613
        return self.modules.has_key(module_name)
 
2614
 
 
2615
    def test_in(self, test_id):
 
2616
        return self.tests.has_key(test_id)
 
2617
 
 
2618
 
 
2619
def test_suite(keep_only=None):
2372
2620
    """Build and return TestSuite for the whole of bzrlib.
2373
 
    
 
2621
 
 
2622
    :param keep_only: A list of test ids limiting the suite returned.
 
2623
 
2374
2624
    This function can be replaced if you need to change the default test
2375
2625
    suite on a global basis, but it is not encouraged.
2376
2626
    """
2415
2665
                   'bzrlib.tests.test_help',
2416
2666
                   'bzrlib.tests.test_hooks',
2417
2667
                   'bzrlib.tests.test_http',
 
2668
                   'bzrlib.tests.test_http_implementations',
2418
2669
                   'bzrlib.tests.test_http_response',
2419
2670
                   'bzrlib.tests.test_https_ca_bundle',
2420
2671
                   'bzrlib.tests.test_identitymap',
2473
2724
                   'bzrlib.tests.test_store',
2474
2725
                   'bzrlib.tests.test_strace',
2475
2726
                   'bzrlib.tests.test_subsume',
 
2727
                   'bzrlib.tests.test_switch',
2476
2728
                   'bzrlib.tests.test_symbol_versioning',
2477
2729
                   'bzrlib.tests.test_tag',
2478
2730
                   'bzrlib.tests.test_testament',
2507
2759
        ]
2508
2760
    suite = TestUtil.TestSuite()
2509
2761
    loader = TestUtil.TestLoader()
2510
 
    suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
 
2762
 
 
2763
    if keep_only is not None:
 
2764
        id_filter = TestIdList(keep_only)
 
2765
 
 
2766
    # modules building their suite with loadTestsFromModuleNames
 
2767
    if keep_only is None:
 
2768
        suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
 
2769
    else:
 
2770
        for mod in [m for m in testmod_names
 
2771
                    if id_filter.is_module_name_used(m)]:
 
2772
            mod_suite = loader.loadTestsFromModuleNames([mod])
 
2773
            mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
 
2774
            suite.addTest(mod_suite)
 
2775
 
 
2776
    # modules adapted for transport implementations
2511
2777
    from bzrlib.tests.test_transport_implementations import TransportTestProviderAdapter
2512
2778
    adapter = TransportTestProviderAdapter()
2513
 
    adapt_modules(test_transport_implementations, adapter, loader, suite)
2514
 
    for package in packages_to_test():
2515
 
        suite.addTest(package.test_suite())
2516
 
    for m in MODULES_TO_TEST:
2517
 
        suite.addTest(loader.loadTestsFromModule(m))
2518
 
    for m in MODULES_TO_DOCTEST:
 
2779
    if keep_only is None:
 
2780
        adapt_modules(test_transport_implementations, adapter, loader, suite)
 
2781
    else:
 
2782
        for mod in [m for m in test_transport_implementations
 
2783
                    if id_filter.is_module_name_used(m)]:
 
2784
            mod_suite = TestUtil.TestSuite()
 
2785
            adapt_modules([mod], adapter, loader, mod_suite)
 
2786
            mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
 
2787
            suite.addTest(mod_suite)
 
2788
 
 
2789
    # modules defining their own test_suite()
 
2790
    for package in [p for p in packages_to_test()
 
2791
                    if (keep_only is None
 
2792
                        or id_filter.is_module_name_used(p.__name__))]:
 
2793
        pack_suite = package.test_suite()
 
2794
        if keep_only is not None:
 
2795
            pack_suite = filter_suite_by_id_list(pack_suite, id_filter)
 
2796
        suite.addTest(pack_suite)
 
2797
 
 
2798
    # XXX: MODULES_TO_TEST should be obsoleted ?
 
2799
    for mod in [m for m in MODULES_TO_TEST
 
2800
                if keep_only is None or id_filter.is_module_name_used(m)]:
 
2801
        mod_suite = loader.loadTestsFromModule(mod)
 
2802
        if keep_only is not None:
 
2803
            mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
 
2804
        suite.addTest(mod_suite)
 
2805
 
 
2806
    for mod in MODULES_TO_DOCTEST:
2519
2807
        try:
2520
 
            suite.addTest(doctest.DocTestSuite(m))
 
2808
            doc_suite = doctest.DocTestSuite(mod)
2521
2809
        except ValueError, e:
2522
 
            print '**failed to get doctest for: %s\n%s' %(m,e)
 
2810
            print '**failed to get doctest for: %s\n%s' % (mod, e)
2523
2811
            raise
 
2812
        if keep_only is not None:
 
2813
            # DocTests may use ids which doesn't contain the module name
 
2814
            doc_suite = filter_suite_by_id_list(doc_suite, id_filter)
 
2815
        suite.addTest(doc_suite)
 
2816
 
2524
2817
    default_encoding = sys.getdefaultencoding()
2525
 
    for name, plugin in bzrlib.plugin.plugins().items():
 
2818
    for name, plugin in  [(n, p) for (n, p) in bzrlib.plugin.plugins().items()
 
2819
                          if (keep_only is None
 
2820
                              or id_filter.is_module_name_used(
 
2821
                p.module.__name__))]:
2526
2822
        try:
2527
2823
            plugin_suite = plugin.test_suite()
2528
2824
        except ImportError, e:
2530
2826
                'Unable to test plugin "%s": %s', name, e)
2531
2827
        else:
2532
2828
            if plugin_suite is not None:
 
2829
                if keep_only is not None:
 
2830
                    plugin_suite = filter_suite_by_id_list(plugin_suite,
 
2831
                                                           id_filter)
2533
2832
                suite.addTest(plugin_suite)
2534
2833
        if default_encoding != sys.getdefaultencoding():
2535
2834
            bzrlib.trace.warning(
2602
2901
        suite.addTests(adapter.adapt(test))
2603
2902
 
2604
2903
 
 
2904
def adapt_tests(tests_list, adapter, loader, suite):
 
2905
    """Adapt the tests in tests_list using adapter and add to suite."""
 
2906
    for test in tests_list:
 
2907
        suite.addTests(adapter.adapt(loader.loadTestsFromName(test)))
 
2908
 
 
2909
 
2605
2910
def _rmtree_temp_dir(dirname):
2606
2911
    # If LANG=C we probably have created some bogus paths
2607
2912
    # which rmtree(unicode) will fail to delete
2755
3060
        return 'FTPServer'
2756
3061
 
2757
3062
FTPServerFeature = _FTPServerFeature()
 
3063
 
 
3064
 
 
3065
class _CaseInsensitiveFilesystemFeature(Feature):
 
3066
    """Check if underlined filesystem is case-insensitive
 
3067
    (e.g. on Windows, Cygwin, MacOS)
 
3068
    """
 
3069
 
 
3070
    def _probe(self):
 
3071
        if TestCaseWithMemoryTransport.TEST_ROOT is None:
 
3072
            root = osutils.mkdtemp(prefix='testbzr-', suffix='.tmp')
 
3073
            TestCaseWithMemoryTransport.TEST_ROOT = root
 
3074
        else:
 
3075
            root = TestCaseWithMemoryTransport.TEST_ROOT
 
3076
        tdir = osutils.mkdtemp(prefix='case-sensitive-probe-', suffix='',
 
3077
            dir=root)
 
3078
        name_a = osutils.pathjoin(tdir, 'a')
 
3079
        name_A = osutils.pathjoin(tdir, 'A')
 
3080
        os.mkdir(name_a)
 
3081
        result = osutils.isdir(name_A)
 
3082
        _rmtree_temp_dir(tdir)
 
3083
        return result
 
3084
 
 
3085
    def feature_name(self):
 
3086
        return 'case-insensitive filesystem'
 
3087
 
 
3088
CaseInsensitiveFilesystemFeature = _CaseInsensitiveFilesystemFeature()