~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: John Arbash Meinel
  • Date: 2006-06-18 02:21:57 UTC
  • mfrom: (1787 +trunk)
  • mto: This revision was merged to the branch mainline in revision 1794.
  • Revision ID: john@arbash-meinel.com-20060618022157-6e33aa9b67c25e4f
[merge] bzr.dev 1787

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
import logging
34
34
import os
35
35
import re
 
36
import shlex
36
37
import stat
 
38
from subprocess import Popen, PIPE
37
39
import sys
38
40
import tempfile
39
41
import unittest
43
45
import bzrlib.branch
44
46
import bzrlib.bzrdir as bzrdir
45
47
import bzrlib.commands
 
48
import bzrlib.bundle.serializer
46
49
import bzrlib.errors as errors
47
50
import bzrlib.inventory
48
51
import bzrlib.iterablefile
49
52
import bzrlib.lockdir
 
53
try:
 
54
    import bzrlib.lsprof
 
55
except ImportError:
 
56
    # lsprof not available
 
57
    pass
50
58
from bzrlib.merge import merge_inner
51
59
import bzrlib.merge3
52
60
import bzrlib.osutils
56
64
from bzrlib.revision import common_ancestor
57
65
import bzrlib.store
58
66
import bzrlib.trace
59
 
from bzrlib.transport import urlescape, get_transport
 
67
from bzrlib.transport import get_transport
60
68
import bzrlib.transport
61
69
from bzrlib.transport.local import LocalRelpathServer
62
70
from bzrlib.transport.readonly import ReadonlyServer
63
71
from bzrlib.trace import mutter
64
72
from bzrlib.tests.TestUtil import TestLoader, TestSuite
65
73
from bzrlib.tests.treeshape import build_tree_contents
 
74
import bzrlib.urlutils as urlutils
66
75
from bzrlib.workingtree import WorkingTree, WorkingTreeFormat2
67
76
 
68
77
default_transport = LocalRelpathServer
70
79
MODULES_TO_TEST = []
71
80
MODULES_TO_DOCTEST = [
72
81
                      bzrlib.branch,
 
82
                      bzrlib.bundle.serializer,
73
83
                      bzrlib.commands,
74
84
                      bzrlib.errors,
75
85
                      bzrlib.inventory,
80
90
                      bzrlib.osutils,
81
91
                      bzrlib.store
82
92
                      ]
 
93
 
 
94
 
83
95
def packages_to_test():
84
96
    """Return a list of packages to test.
85
97
 
223
235
        self.extractBenchmarkTime(test)
224
236
        if self.showAll:
225
237
            self.stream.writeln('   OK %s' % self._testTimeString())
 
238
            for bench_called, stats in getattr(test, '_benchcalls', []):
 
239
                self.stream.writeln('LSProf output for %s(%s, %s)' % bench_called)
 
240
                stats.pprint(file=self.stream)
226
241
        elif self.dots and self.pb is None:
227
242
            self.stream.write('~')
228
243
        elif self.dots:
316
331
        test_root = TestCaseInTempDir.TEST_ROOT
317
332
        if result.wasSuccessful() or not self.keep_output:
318
333
            if test_root is not None:
319
 
                    osutils.rmtree(test_root)
 
334
                # If LANG=C we probably have created some bogus paths
 
335
                # which rmtree(unicode) will fail to delete
 
336
                # so make sure we are using rmtree(str) to delete everything
 
337
                osutils.rmtree(test_root.encode(
 
338
                    sys.getfilesystemencoding()))
320
339
        else:
321
340
            if self.pb is not None:
322
341
                self.pb.note("Failed tests working directories are in '%s'\n",
352
371
class CommandFailed(Exception):
353
372
    pass
354
373
 
 
374
 
 
375
class StringIOWrapper(object):
 
376
    """A wrapper around cStringIO which just adds an encoding attribute.
 
377
    
 
378
    Internally we can check sys.stdout to see what the output encoding
 
379
    should be. However, cStringIO has no encoding attribute that we can
 
380
    set. So we wrap it instead.
 
381
    """
 
382
    encoding='ascii'
 
383
    _cstring = None
 
384
 
 
385
    def __init__(self, s=None):
 
386
        if s is not None:
 
387
            self.__dict__['_cstring'] = StringIO(s)
 
388
        else:
 
389
            self.__dict__['_cstring'] = StringIO()
 
390
 
 
391
    def __getattr__(self, name, getattr=getattr):
 
392
        return getattr(self.__dict__['_cstring'], name)
 
393
 
 
394
    def __setattr__(self, name, val):
 
395
        if name == 'encoding':
 
396
            self.__dict__['encoding'] = val
 
397
        else:
 
398
            return setattr(self._cstring, name, val)
 
399
 
 
400
 
355
401
class TestCase(unittest.TestCase):
356
402
    """Base class for bzr unit tests.
357
403
    
375
421
 
376
422
    _log_file_name = None
377
423
    _log_contents = ''
 
424
    # record lsprof data when performing benchmark calls.
 
425
    _gather_lsprof_in_benchmarks = False
378
426
 
379
427
    def __init__(self, methodName='testMethod'):
380
428
        super(TestCase, self).__init__(methodName)
385
433
        self._cleanEnvironment()
386
434
        bzrlib.trace.disable_default_logging()
387
435
        self._startLogFile()
 
436
        self._benchcalls = []
388
437
        self._benchtime = None
389
438
 
390
439
    def _ndiff_strings(self, a, b):
435
484
            raise AssertionError('pattern "%s" not found in "%s"'
436
485
                    % (needle_re, haystack))
437
486
 
 
487
    def assertNotContainsRe(self, haystack, needle_re):
 
488
        """Assert that a does not match a regular expression"""
 
489
        if re.search(needle_re, haystack):
 
490
            raise AssertionError('pattern "%s" found in "%s"'
 
491
                    % (needle_re, haystack))
 
492
 
438
493
    def assertSubset(self, sublist, superlist):
439
494
        """Assert that every entry in sublist is present in superlist."""
440
495
        missing = []
541
596
        unittest.TestCase.tearDown(self)
542
597
 
543
598
    def time(self, callable, *args, **kwargs):
544
 
        """Run callable and accrue the time it takes to the benchmark time."""
 
599
        """Run callable and accrue the time it takes to the benchmark time.
 
600
        
 
601
        If lsprofiling is enabled (i.e. by --lsprof-time to bzr selftest) then
 
602
        this will cause lsprofile statistics to be gathered and stored in
 
603
        self._benchcalls.
 
604
        """
545
605
        if self._benchtime is None:
546
606
            self._benchtime = 0
547
607
        start = time.time()
548
608
        try:
549
 
            callable(*args, **kwargs)
 
609
            if not self._gather_lsprof_in_benchmarks:
 
610
                return callable(*args, **kwargs)
 
611
            else:
 
612
                # record this benchmark
 
613
                ret, stats = bzrlib.lsprof.profile(callable, *args, **kwargs)
 
614
                stats.sort()
 
615
                self._benchcalls.append(((callable, args, kwargs), stats))
 
616
                return ret
550
617
        finally:
551
618
            self._benchtime += time.time() - start
552
619
 
575
642
        """Shortcut that splits cmd into words, runs, and returns stdout"""
576
643
        return self.run_bzr_captured(cmd.split(), retcode=retcode)[0]
577
644
 
578
 
    def run_bzr_captured(self, argv, retcode=0, stdin=None):
 
645
    def run_bzr_captured(self, argv, retcode=0, encoding=None, stdin=None):
579
646
        """Invoke bzr and return (stdout, stderr).
580
647
 
581
648
        Useful for code that wants to check the contents of the
592
659
        errors, and with logging set to something approximating the
593
660
        default, so that error reporting can be checked.
594
661
 
595
 
        argv -- arguments to invoke bzr
596
 
        retcode -- expected return code, or None for don't-care.
 
662
        :param argv: arguments to invoke bzr
 
663
        :param retcode: expected return code, or None for don't-care.
 
664
        :param encoding: encoding for sys.stdout and sys.stderr
597
665
        :param stdin: A string to be used as stdin for the command.
598
666
        """
 
667
        if encoding is None:
 
668
            encoding = bzrlib.user_encoding
599
669
        if stdin is not None:
600
670
            stdin = StringIO(stdin)
601
 
        stdout = StringIO()
602
 
        stderr = StringIO()
603
 
        self.log('run bzr: %s', ' '.join(argv))
 
671
        stdout = StringIOWrapper()
 
672
        stderr = StringIOWrapper()
 
673
        stdout.encoding = encoding
 
674
        stderr.encoding = encoding
 
675
 
 
676
        self.log('run bzr: %r', argv)
604
677
        # FIXME: don't call into logging here
605
678
        handler = logging.StreamHandler(stderr)
606
679
        handler.setFormatter(bzrlib.trace.QuietFormatter())
619
692
        finally:
620
693
            logger.removeHandler(handler)
621
694
            bzrlib.ui.ui_factory = old_ui_factory
 
695
 
622
696
        out = stdout.getvalue()
623
697
        err = stderr.getvalue()
624
698
        if out:
625
 
            self.log('output:\n%s', out)
 
699
            self.log('output:\n%r', out)
626
700
        if err:
627
 
            self.log('errors:\n%s', err)
 
701
            self.log('errors:\n%r', err)
628
702
        if retcode is not None:
629
 
            self.assertEquals(result, retcode)
 
703
            self.assertEquals(retcode, result)
630
704
        return out, err
631
705
 
632
706
    def run_bzr(self, *args, **kwargs):
642
716
        :param stdin: A string to be used as stdin for the command.
643
717
        """
644
718
        retcode = kwargs.pop('retcode', 0)
 
719
        encoding = kwargs.pop('encoding', None)
645
720
        stdin = kwargs.pop('stdin', None)
646
 
        return self.run_bzr_captured(args, retcode, stdin)
 
721
        return self.run_bzr_captured(args, retcode=retcode, encoding=encoding, stdin=stdin)
 
722
 
 
723
    def run_bzr_decode(self, *args, **kwargs):
 
724
        if kwargs.has_key('encoding'):
 
725
            encoding = kwargs['encoding']
 
726
        else:
 
727
            encoding = bzrlib.user_encoding
 
728
        return self.run_bzr(*args, **kwargs)[0].decode(encoding)
 
729
 
 
730
    def run_bzr_subprocess(self, *args, **kwargs):
 
731
        """Run bzr in a subprocess for testing.
 
732
 
 
733
        This starts a new Python interpreter and runs bzr in there. 
 
734
        This should only be used for tests that have a justifiable need for
 
735
        this isolation: e.g. they are testing startup time, or signal
 
736
        handling, or early startup code, etc.  Subprocess code can't be 
 
737
        profiled or debugged so easily.
 
738
 
 
739
        :param retcode: The status code that is expected.  Defaults to 0.  If
 
740
        None is supplied, the status code is not checked.
 
741
        """
 
742
        bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
 
743
        args = list(args)
 
744
        process = Popen([sys.executable, bzr_path]+args, stdout=PIPE, 
 
745
                         stderr=PIPE)
 
746
        out = process.stdout.read()
 
747
        err = process.stderr.read()
 
748
        retcode = process.wait()
 
749
        supplied_retcode = kwargs.get('retcode', 0)
 
750
        if supplied_retcode is not None:
 
751
            assert supplied_retcode == retcode
 
752
        return [out, err]
647
753
 
648
754
    def check_inventory_shape(self, inv, shape):
649
755
        """Compare an inventory to a list of expected names.
814
920
        for name in shape:
815
921
            self.assert_(isinstance(name, basestring))
816
922
            if name[-1] == '/':
817
 
                transport.mkdir(urlescape(name[:-1]))
 
923
                transport.mkdir(urlutils.escape(name[:-1]))
818
924
            else:
819
925
                if line_endings == 'binary':
820
926
                    end = '\n'
822
928
                    end = os.linesep
823
929
                else:
824
930
                    raise errors.BzrError('Invalid line ending request %r' % (line_endings,))
825
 
                content = "contents of %s%s" % (name, end)
826
 
                transport.put(urlescape(name), StringIO(content))
 
931
                content = "contents of %s%s" % (name.encode('utf-8'), end)
 
932
                transport.put(urlutils.escape(name), StringIO(content))
827
933
 
828
934
    def build_tree_contents(self, shape):
829
935
        build_tree_contents(shape)
839
945
    def assertFileEqual(self, content, path):
840
946
        """Fail if path does not contain 'content'."""
841
947
        self.failUnless(osutils.lexists(path))
 
948
        # TODO: jam 20060427 Shouldn't this be 'rb'?
842
949
        self.assertEqualDiff(content, open(path, 'r').read())
843
950
 
844
951
 
920
1027
        if relpath is not None and relpath != '.':
921
1028
            if not base.endswith('/'):
922
1029
                base = base + '/'
923
 
            base = base + relpath
 
1030
            base = base + urlutils.escape(relpath)
924
1031
        return base
925
1032
 
926
1033
    def get_transport(self):
947
1054
    def make_bzrdir(self, relpath, format=None):
948
1055
        try:
949
1056
            url = self.get_url(relpath)
950
 
            segments = relpath.split('/')
 
1057
            mutter('relpath %r => url %r', relpath, url)
 
1058
            segments = url.split('/')
951
1059
            if segments and segments[-1] not in ('', '.'):
952
 
                parent = self.get_url('/'.join(segments[:-1]))
 
1060
                parent = '/'.join(segments[:-1])
953
1061
                t = get_transport(parent)
954
1062
                try:
955
1063
                    t.mkdir(segments[-1])
1031
1139
 
1032
1140
def run_suite(suite, name='test', verbose=False, pattern=".*",
1033
1141
              stop_on_failure=False, keep_output=False,
1034
 
              transport=None):
 
1142
              transport=None, lsprof_timed=None):
1035
1143
    TestCaseInTempDir._TEST_NAME = name
 
1144
    TestCase._gather_lsprof_in_benchmarks = lsprof_timed
1036
1145
    if verbose:
1037
1146
        verbosity = 2
1038
1147
        pb = None
1054
1163
def selftest(verbose=False, pattern=".*", stop_on_failure=True,
1055
1164
             keep_output=False,
1056
1165
             transport=None,
1057
 
             test_suite_factory=None):
 
1166
             test_suite_factory=None,
 
1167
             lsprof_timed=None):
1058
1168
    """Run the whole test suite under the enhanced runner"""
1059
1169
    global default_transport
1060
1170
    if transport is None:
1068
1178
            suite = test_suite_factory()
1069
1179
        return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
1070
1180
                     stop_on_failure=stop_on_failure, keep_output=keep_output,
1071
 
                     transport=transport)
 
1181
                     transport=transport,
 
1182
                     lsprof_timed=lsprof_timed)
1072
1183
    finally:
1073
1184
        default_transport = old_transport
1074
1185
 
1088
1199
                   'bzrlib.tests.test_api',
1089
1200
                   'bzrlib.tests.test_bad_files',
1090
1201
                   'bzrlib.tests.test_branch',
 
1202
                   'bzrlib.tests.test_bundle',
1091
1203
                   'bzrlib.tests.test_bzrdir',
1092
1204
                   'bzrlib.tests.test_command',
1093
1205
                   'bzrlib.tests.test_commit',
1097
1209
                   'bzrlib.tests.test_decorators',
1098
1210
                   'bzrlib.tests.test_diff',
1099
1211
                   'bzrlib.tests.test_doc_generate',
 
1212
                   'bzrlib.tests.test_emptytree',
1100
1213
                   'bzrlib.tests.test_errors',
1101
1214
                   'bzrlib.tests.test_escaped_store',
1102
1215
                   'bzrlib.tests.test_fetch',
1119
1232
                   'bzrlib.tests.test_options',
1120
1233
                   'bzrlib.tests.test_osutils',
1121
1234
                   'bzrlib.tests.test_patch',
 
1235
                   'bzrlib.tests.test_patches',
1122
1236
                   'bzrlib.tests.test_permissions',
1123
1237
                   'bzrlib.tests.test_plugins',
1124
1238
                   'bzrlib.tests.test_progress',
1127
1241
                   'bzrlib.tests.test_revision',
1128
1242
                   'bzrlib.tests.test_revisionnamespaces',
1129
1243
                   'bzrlib.tests.test_revprops',
 
1244
                   'bzrlib.tests.test_revisiontree',
1130
1245
                   'bzrlib.tests.test_rio',
1131
1246
                   'bzrlib.tests.test_sampler',
1132
1247
                   'bzrlib.tests.test_selftest',
1148
1263
                   'bzrlib.tests.test_tuned_gzip',
1149
1264
                   'bzrlib.tests.test_ui',
1150
1265
                   'bzrlib.tests.test_upgrade',
 
1266
                   'bzrlib.tests.test_urlutils',
1151
1267
                   'bzrlib.tests.test_versionedfile',
1152
1268
                   'bzrlib.tests.test_weave',
1153
1269
                   'bzrlib.tests.test_whitebox',
1155
1271
                   'bzrlib.tests.test_xml',
1156
1272
                   ]
1157
1273
    test_transport_implementations = [
1158
 
        'bzrlib.tests.test_transport_implementations']
 
1274
        'bzrlib.tests.test_transport_implementations',
 
1275
        'bzrlib.tests.test_read_bundle',
 
1276
        ]
1159
1277
 
1160
1278
    suite = TestSuite()
1161
1279
    loader = TestUtil.TestLoader()