~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: John Arbash Meinel
  • Date: 2007-04-28 15:04:17 UTC
  • mfrom: (2466 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2566.
  • Revision ID: john@arbash-meinel.com-20070428150417-trp3pi0pzd411pu4
[merge] bzr.dev 2466

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
import logging
35
35
import os
36
36
from pprint import pformat
 
37
import random
37
38
import re
38
 
import shlex
39
39
import stat
40
40
from subprocess import Popen, PIPE
41
41
import sys
53
53
    progress,
54
54
    ui,
55
55
    urlutils,
 
56
    workingtree,
56
57
    )
57
58
import bzrlib.branch
58
59
import bzrlib.commands
89
90
from bzrlib.tests.treeshape import build_tree_contents
90
91
from bzrlib.workingtree import WorkingTree, WorkingTreeFormat2
91
92
 
 
93
# Mark this python module as being part of the implementation
 
94
# of unittest: this gives us better tracebacks where the last
 
95
# shown frame is the test code, not our assertXYZ.
 
96
__unittest = 1
 
97
 
92
98
default_transport = LocalURLServer
93
99
 
94
100
MODULES_TO_TEST = []
496
502
                 keep_output=False,
497
503
                 bench_history=None,
498
504
                 use_numbered_dirs=False,
 
505
                 list_only=False
499
506
                 ):
500
507
        self.stream = unittest._WritelnDecorator(stream)
501
508
        self.descriptions = descriptions
503
510
        self.keep_output = keep_output
504
511
        self._bench_history = bench_history
505
512
        self.use_numbered_dirs = use_numbered_dirs
 
513
        self.list_only = list_only
506
514
 
507
515
    def run(self, test):
508
516
        "Run the given test case or test suite."
520
528
                              )
521
529
        result.stop_early = self.stop_on_failure
522
530
        result.report_starting()
523
 
        test.run(result)
 
531
        if self.list_only:
 
532
            if self.verbosity >= 2:
 
533
                self.stream.writeln("Listing tests only ...\n")
 
534
            run = 0
 
535
            for t in iter_suite_tests(test):
 
536
                self.stream.writeln("%s" % (t.id()))
 
537
                run += 1
 
538
            actionTaken = "Listed"
 
539
        else: 
 
540
            test.run(result)
 
541
            run = result.testsRun
 
542
            actionTaken = "Ran"
524
543
        stopTime = time.time()
525
544
        timeTaken = stopTime - startTime
526
545
        result.printErrors()
527
546
        self.stream.writeln(result.separator2)
528
 
        run = result.testsRun
529
 
        self.stream.writeln("Ran %d test%s in %.3fs" %
530
 
                            (run, run != 1 and "s" or "", timeTaken))
 
547
        self.stream.writeln("%s %d test%s in %.3fs" % (actionTaken,
 
548
                            run, run != 1 and "s" or "", timeTaken))
531
549
        self.stream.writeln()
532
550
        if not result.wasSuccessful():
533
551
            self.stream.write("FAILED (")
751
769
        self._startLogFile()
752
770
        self._benchcalls = []
753
771
        self._benchtime = None
 
772
        self._clear_hooks()
 
773
 
 
774
    def _clear_hooks(self):
754
775
        # prevent hooks affecting tests
 
776
        import bzrlib.branch
 
777
        import bzrlib.smart.server
755
778
        self._preserved_hooks = {
756
 
            bzrlib.branch.Branch:bzrlib.branch.Branch.hooks,
757
 
            bzrlib.smart.server.SmartTCPServer:bzrlib.smart.server.SmartTCPServer.hooks,
 
779
            bzrlib.branch.Branch: bzrlib.branch.Branch.hooks,
 
780
            bzrlib.smart.server.SmartTCPServer: bzrlib.smart.server.SmartTCPServer.hooks,
758
781
            }
759
782
        self.addCleanup(self._restoreHooks)
760
 
        # this list of hooks must be kept in sync with the defaults
761
 
        # in branch.py
 
783
        # reset all hooks to an empty instance of the appropriate type
762
784
        bzrlib.branch.Branch.hooks = bzrlib.branch.BranchHooks()
 
785
        bzrlib.smart.server.SmartTCPServer.hooks = bzrlib.smart.server.SmartServerHooks()
 
786
        # FIXME: Rather than constructing new objects like this, how about
 
787
        # having save() and clear() methods on the base Hook class? mbp
 
788
        # 20070416
763
789
 
764
790
    def _silenceUI(self):
765
791
        """Turn off UI for duration of test"""
1272
1298
        if err:
1273
1299
            self.log('errors:\n%r', err)
1274
1300
        if retcode is not None:
1275
 
            self.assertEquals(retcode, result)
 
1301
            self.assertEquals(retcode, result,
 
1302
                              message='Unexpected return code')
1276
1303
        return out, err
1277
1304
 
1278
1305
    def run_bzr(self, *args, **kwargs):
1293
1320
        encoding = kwargs.pop('encoding', None)
1294
1321
        stdin = kwargs.pop('stdin', None)
1295
1322
        working_dir = kwargs.pop('working_dir', None)
1296
 
        return self.run_bzr_captured(args, retcode=retcode, encoding=encoding,
1297
 
                                     stdin=stdin, working_dir=working_dir)
 
1323
        error_regexes = kwargs.pop('error_regexes', [])
 
1324
 
 
1325
        out, err = self.run_bzr_captured(args, retcode=retcode,
 
1326
            encoding=encoding, stdin=stdin, working_dir=working_dir)
 
1327
 
 
1328
        for regex in error_regexes:
 
1329
            self.assertContainsRe(err, regex)
 
1330
        return out, err
 
1331
 
1298
1332
 
1299
1333
    def run_bzr_decode(self, *args, **kwargs):
1300
1334
        if 'encoding' in kwargs:
1328
1362
                               'commit', '--strict', '-m', 'my commit comment')
1329
1363
        """
1330
1364
        kwargs.setdefault('retcode', 3)
1331
 
        out, err = self.run_bzr(*args, **kwargs)
1332
 
        for regex in error_regexes:
1333
 
            self.assertContainsRe(err, regex)
 
1365
        out, err = self.run_bzr(error_regexes=error_regexes, *args, **kwargs)
1334
1366
        return out, err
1335
1367
 
1336
1368
    def run_bzr_subprocess(self, *args, **kwargs):
1718
1750
    def get_vfs_only_url(self, relpath=None):
1719
1751
        """Get a URL (or maybe a path for the plain old vfs transport.
1720
1752
 
1721
 
        This will never be a smart protocol.
 
1753
        This will never be a smart protocol.  It always has all the
 
1754
        capabilities of the local filesystem, but it might actually be a
 
1755
        MemoryTransport or some other similar virtual filesystem.
 
1756
 
 
1757
        This is the backing transport (if any) of the server returned by
 
1758
        get_url and get_readonly_url.
1722
1759
 
1723
1760
        :param relpath: provides for clients to get a path relative to the base
1724
1761
            url.  These should only be downwards relative, not upwards.
1786
1823
            raise TestSkipped("Format %s is not initializable." % format)
1787
1824
 
1788
1825
    def make_repository(self, relpath, shared=False, format=None):
1789
 
        """Create a repository on our default transport at relpath."""
 
1826
        """Create a repository on our default transport at relpath.
 
1827
        
 
1828
        Note that relpath must be a relative path, not a full url.
 
1829
        """
 
1830
        # FIXME: If you create a remoterepository this returns the underlying
 
1831
        # real format, which is incorrect.  Actually we should make sure that 
 
1832
        # RemoteBzrDir returns a RemoteRepository.
 
1833
        # maybe  mbp 20070410
1790
1834
        made_control = self.make_bzrdir(relpath, format=format)
1791
1835
        return made_control.create_repository(shared=shared)
1792
1836
 
1933
1977
        self.assertEqualDiff(content, s)
1934
1978
 
1935
1979
    def failUnlessExists(self, path):
1936
 
        """Fail unless path, which may be abs or relative, exists."""
1937
 
        self.failUnless(osutils.lexists(path),path+" does not exist")
 
1980
        """Fail unless path or paths, which may be abs or relative, exist."""
 
1981
        if not isinstance(path, basestring):
 
1982
            for p in path:
 
1983
                self.failUnlessExists(p)
 
1984
        else:
 
1985
            self.failUnless(osutils.lexists(path),path+" does not exist")
1938
1986
 
1939
1987
    def failIfExists(self, path):
1940
 
        """Fail if path, which may be abs or relative, exists."""
1941
 
        self.failIf(osutils.lexists(path),path+" exists")
 
1988
        """Fail if path or paths, which may be abs or relative, exist."""
 
1989
        if not isinstance(path, basestring):
 
1990
            for p in path:
 
1991
                self.failIfExists(p)
 
1992
        else:
 
1993
            self.failIf(osutils.lexists(path),path+" exists")
 
1994
 
 
1995
    def assertInWorkingTree(self,path,root_path='.',tree=None):
 
1996
        """Assert whether path or paths are in the WorkingTree"""
 
1997
        if tree is None:
 
1998
            tree = workingtree.WorkingTree.open(root_path)
 
1999
        if not isinstance(path, basestring):
 
2000
            for p in path:
 
2001
                self.assertInWorkingTree(p,tree=tree)
 
2002
        else:
 
2003
            self.assertIsNot(tree.path2id(path), None,
 
2004
                path+' not in working tree.')
 
2005
 
 
2006
    def assertNotInWorkingTree(self,path,root_path='.',tree=None):
 
2007
        """Assert whether path or paths are not in the WorkingTree"""
 
2008
        if tree is None:
 
2009
            tree = workingtree.WorkingTree.open(root_path)
 
2010
        if not isinstance(path, basestring):
 
2011
            for p in path:
 
2012
                self.assertNotInWorkingTree(p,tree=tree)
 
2013
        else:
 
2014
            self.assertIs(tree.path2id(path), None, path+' in working tree.')
1942
2015
 
1943
2016
 
1944
2017
class TestCaseWithTransport(TestCaseInTempDir):
2046
2119
            self.transport_readonly_server = HttpServer
2047
2120
 
2048
2121
 
2049
 
def filter_suite_by_re(suite, pattern):
2050
 
    result = TestUtil.TestSuite()
2051
 
    filter_re = re.compile(pattern)
2052
 
    for test in iter_suite_tests(suite):
2053
 
        if filter_re.search(test.id()):
2054
 
            result.addTest(test)
2055
 
    return result
2056
 
 
2057
 
 
2058
 
def sort_suite_by_re(suite, pattern):
 
2122
def filter_suite_by_re(suite, pattern, exclude_pattern=None,
 
2123
                       random_order=False):
 
2124
    """Create a test suite by filtering another one.
 
2125
    
 
2126
    :param suite:           the source suite
 
2127
    :param pattern:         pattern that names must match
 
2128
    :param exclude_pattern: pattern that names must not match, if any
 
2129
    :param random_order:    if True, tests in the new suite will be put in
 
2130
                            random order
 
2131
    :returns: the newly created suite
 
2132
    """ 
 
2133
    return sort_suite_by_re(suite, pattern, exclude_pattern,
 
2134
        random_order, False)
 
2135
 
 
2136
 
 
2137
def sort_suite_by_re(suite, pattern, exclude_pattern=None,
 
2138
                     random_order=False, append_rest=True):
 
2139
    """Create a test suite by sorting another one.
 
2140
    
 
2141
    :param suite:           the source suite
 
2142
    :param pattern:         pattern that names must match in order to go
 
2143
                            first in the new suite
 
2144
    :param exclude_pattern: pattern that names must not match, if any
 
2145
    :param random_order:    if True, tests in the new suite will be put in
 
2146
                            random order
 
2147
    :param append_rest:     if False, pattern is a strict filter and not
 
2148
                            just an ordering directive
 
2149
    :returns: the newly created suite
 
2150
    """ 
2059
2151
    first = []
2060
2152
    second = []
2061
2153
    filter_re = re.compile(pattern)
 
2154
    if exclude_pattern is not None:
 
2155
        exclude_re = re.compile(exclude_pattern)
2062
2156
    for test in iter_suite_tests(suite):
2063
 
        if filter_re.search(test.id()):
2064
 
            first.append(test)
2065
 
        else:
2066
 
            second.append(test)
 
2157
        test_id = test.id()
 
2158
        if exclude_pattern is None or not exclude_re.search(test_id):
 
2159
            if filter_re.search(test_id):
 
2160
                first.append(test)
 
2161
            elif append_rest:
 
2162
                second.append(test)
 
2163
    if random_order:
 
2164
        random.shuffle(first)
 
2165
        random.shuffle(second)
2067
2166
    return TestUtil.TestSuite(first + second)
2068
2167
 
2069
2168
 
2071
2170
              stop_on_failure=False, keep_output=False,
2072
2171
              transport=None, lsprof_timed=None, bench_history=None,
2073
2172
              matching_tests_first=None,
2074
 
              numbered_dirs=None):
 
2173
              numbered_dirs=None,
 
2174
              list_only=False,
 
2175
              random_seed=None,
 
2176
              exclude_pattern=None,
 
2177
              ):
2075
2178
    use_numbered_dirs = bool(numbered_dirs)
2076
2179
 
2077
2180
    TestCase._gather_lsprof_in_benchmarks = lsprof_timed
2087
2190
                            keep_output=keep_output,
2088
2191
                            bench_history=bench_history,
2089
2192
                            use_numbered_dirs=use_numbered_dirs,
 
2193
                            list_only=list_only,
2090
2194
                            )
2091
2195
    runner.stop_on_failure=stop_on_failure
2092
 
    if pattern != '.*':
 
2196
    # Initialise the random number generator and display the seed used.
 
2197
    # We convert the seed to a long to make it reuseable across invocations.
 
2198
    random_order = False
 
2199
    if random_seed is not None:
 
2200
        random_order = True
 
2201
        if random_seed == "now":
 
2202
            random_seed = long(time.time())
 
2203
        else:
 
2204
            # Convert the seed to a long if we can
 
2205
            try:
 
2206
                random_seed = long(random_seed)
 
2207
            except:
 
2208
                pass
 
2209
        runner.stream.writeln("Randomizing test order using seed %s\n" %
 
2210
            (random_seed))
 
2211
        random.seed(random_seed)
 
2212
    # Customise the list of tests if requested
 
2213
    if pattern != '.*' or exclude_pattern is not None or random_order:
2093
2214
        if matching_tests_first:
2094
 
            suite = sort_suite_by_re(suite, pattern)
 
2215
            suite = sort_suite_by_re(suite, pattern, exclude_pattern,
 
2216
                random_order)
2095
2217
        else:
2096
 
            suite = filter_suite_by_re(suite, pattern)
 
2218
            suite = filter_suite_by_re(suite, pattern, exclude_pattern,
 
2219
                random_order)
2097
2220
    result = runner.run(suite)
2098
2221
    return result.wasSuccessful()
2099
2222
 
2105
2228
             lsprof_timed=None,
2106
2229
             bench_history=None,
2107
2230
             matching_tests_first=None,
2108
 
             numbered_dirs=None):
 
2231
             numbered_dirs=None,
 
2232
             list_only=False,
 
2233
             random_seed=None,
 
2234
             exclude_pattern=None):
2109
2235
    """Run the whole test suite under the enhanced runner"""
2110
2236
    # XXX: Very ugly way to do this...
2111
2237
    # Disable warning about old formats because we don't want it to disturb
2129
2255
                     lsprof_timed=lsprof_timed,
2130
2256
                     bench_history=bench_history,
2131
2257
                     matching_tests_first=matching_tests_first,
2132
 
                     numbered_dirs=numbered_dirs)
 
2258
                     numbered_dirs=numbered_dirs,
 
2259
                     list_only=list_only,
 
2260
                     random_seed=random_seed,
 
2261
                     exclude_pattern=exclude_pattern)
2133
2262
    finally:
2134
2263
        default_transport = old_transport
2135
2264
 
2147
2276
                   'bzrlib.tests.test_atomicfile',
2148
2277
                   'bzrlib.tests.test_bad_files',
2149
2278
                   'bzrlib.tests.test_branch',
 
2279
                   'bzrlib.tests.test_bugtracker',
2150
2280
                   'bzrlib.tests.test_bundle',
2151
2281
                   'bzrlib.tests.test_bzrdir',
2152
2282
                   'bzrlib.tests.test_cache_utf8',
2159
2289
                   'bzrlib.tests.test_delta',
2160
2290
                   'bzrlib.tests.test_diff',
2161
2291
                   'bzrlib.tests.test_dirstate',
2162
 
                   'bzrlib.tests.test_doc_generate',
2163
2292
                   'bzrlib.tests.test_errors',
2164
2293
                   'bzrlib.tests.test_escaped_store',
2165
2294
                   'bzrlib.tests.test_extract',
2171
2300
                   'bzrlib.tests.test_gpg',
2172
2301
                   'bzrlib.tests.test_graph',
2173
2302
                   'bzrlib.tests.test_hashcache',
 
2303
                   'bzrlib.tests.test_help',
2174
2304
                   'bzrlib.tests.test_http',
2175
2305
                   'bzrlib.tests.test_http_response',
2176
2306
                   'bzrlib.tests.test_https_ca_bundle',
2201
2331
                   'bzrlib.tests.test_progress',
2202
2332
                   'bzrlib.tests.test_reconcile',
2203
2333
                   'bzrlib.tests.test_registry',
 
2334
                   'bzrlib.tests.test_remote',
2204
2335
                   'bzrlib.tests.test_repository',
2205
2336
                   'bzrlib.tests.test_revert',
2206
2337
                   'bzrlib.tests.test_revision',
2211
2342
                   'bzrlib.tests.test_selftest',
2212
2343
                   'bzrlib.tests.test_setup',
2213
2344
                   'bzrlib.tests.test_sftp_transport',
 
2345
                   'bzrlib.tests.test_smart',
2214
2346
                   'bzrlib.tests.test_smart_add',
2215
2347
                   'bzrlib.tests.test_smart_transport',
2216
2348
                   'bzrlib.tests.test_source',
2298
2430
        if sys.platform == 'win32' and e.errno == errno.EACCES:
2299
2431
            print >>sys.stderr, ('Permission denied: '
2300
2432
                                 'unable to remove testing dir '
2301
 
                                 '%s' % os.path.basename(test_root))
 
2433
                                 '%s' % os.path.basename(dirname))
2302
2434
        else:
2303
2435
            raise
2304
2436
 
2311
2443
    :param  quiet:  suppress report about deleting directories
2312
2444
    """
2313
2445
    import re
2314
 
    import shutil
2315
 
 
2316
2446
    re_dir = re.compile(r'''test\d\d\d\d\.tmp''')
2317
2447
    if root is None:
2318
2448
        root = u'.'