~michael-ellerman/bzr/mpe

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

[merge] bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
import logging
35
35
import os
36
36
import re
37
 
import shutil
 
37
import shlex
38
38
import stat
 
39
from subprocess import Popen, PIPE
39
40
import sys
40
41
import tempfile
41
42
import unittest
64
65
from bzrlib.revision import common_ancestor
65
66
import bzrlib.store
66
67
import bzrlib.trace
67
 
from bzrlib.transport import urlescape, get_transport
 
68
from bzrlib.transport import get_transport
68
69
import bzrlib.transport
69
70
from bzrlib.transport.local import LocalRelpathServer
70
71
from bzrlib.transport.readonly import ReadonlyServer
71
72
from bzrlib.trace import mutter
72
 
from bzrlib.tests.TestUtil import TestLoader, TestSuite
 
73
from bzrlib.tests import TestUtil
 
74
from bzrlib.tests.TestUtil import (
 
75
                          TestSuite,
 
76
                          TestLoader,
 
77
                          )
73
78
from bzrlib.tests.treeshape import build_tree_contents
 
79
import bzrlib.urlutils as urlutils
74
80
from bzrlib.workingtree import WorkingTree, WorkingTreeFormat2
75
81
 
76
82
default_transport = LocalRelpathServer
330
336
        test_root = TestCaseInTempDir.TEST_ROOT
331
337
        if result.wasSuccessful() or not self.keep_output:
332
338
            if test_root is not None:
333
 
                    osutils.rmtree(test_root)
 
339
                # If LANG=C we probably have created some bogus paths
 
340
                # which rmtree(unicode) will fail to delete
 
341
                # so make sure we are using rmtree(str) to delete everything
 
342
                # except on win32, where rmtree(str) will fail
 
343
                # since it doesn't have the property of byte-stream paths
 
344
                # (they are either ascii or mbcs)
 
345
                if sys.platform == 'win32':
 
346
                    # make sure we are using the unicode win32 api
 
347
                    test_root = unicode(test_root)
 
348
                else:
 
349
                    test_root = test_root.encode(
 
350
                        sys.getfilesystemencoding())
 
351
                osutils.rmtree(test_root)
334
352
        else:
335
353
            if self.pb is not None:
336
354
                self.pb.note("Failed tests working directories are in '%s'\n",
366
384
class CommandFailed(Exception):
367
385
    pass
368
386
 
 
387
 
 
388
class StringIOWrapper(object):
 
389
    """A wrapper around cStringIO which just adds an encoding attribute.
 
390
    
 
391
    Internally we can check sys.stdout to see what the output encoding
 
392
    should be. However, cStringIO has no encoding attribute that we can
 
393
    set. So we wrap it instead.
 
394
    """
 
395
    encoding='ascii'
 
396
    _cstring = None
 
397
 
 
398
    def __init__(self, s=None):
 
399
        if s is not None:
 
400
            self.__dict__['_cstring'] = StringIO(s)
 
401
        else:
 
402
            self.__dict__['_cstring'] = StringIO()
 
403
 
 
404
    def __getattr__(self, name, getattr=getattr):
 
405
        return getattr(self.__dict__['_cstring'], name)
 
406
 
 
407
    def __setattr__(self, name, val):
 
408
        if name == 'encoding':
 
409
            self.__dict__['encoding'] = val
 
410
        else:
 
411
            return setattr(self._cstring, name, val)
 
412
 
 
413
 
369
414
class TestCase(unittest.TestCase):
370
415
    """Base class for bzr unit tests.
371
416
    
452
497
            raise AssertionError('pattern "%s" not found in "%s"'
453
498
                    % (needle_re, haystack))
454
499
 
 
500
    def assertNotContainsRe(self, haystack, needle_re):
 
501
        """Assert that a does not match a regular expression"""
 
502
        if re.search(needle_re, haystack):
 
503
            raise AssertionError('pattern "%s" found in "%s"'
 
504
                    % (needle_re, haystack))
 
505
 
455
506
    def assertSubset(self, sublist, superlist):
456
507
        """Assert that every entry in sublist is present in superlist."""
457
508
        missing = []
604
655
        """Shortcut that splits cmd into words, runs, and returns stdout"""
605
656
        return self.run_bzr_captured(cmd.split(), retcode=retcode)[0]
606
657
 
607
 
    def run_bzr_captured(self, argv, retcode=0, stdin=None):
 
658
    def run_bzr_captured(self, argv, retcode=0, encoding=None, stdin=None):
608
659
        """Invoke bzr and return (stdout, stderr).
609
660
 
610
661
        Useful for code that wants to check the contents of the
621
672
        errors, and with logging set to something approximating the
622
673
        default, so that error reporting can be checked.
623
674
 
624
 
        argv -- arguments to invoke bzr
625
 
        retcode -- expected return code, or None for don't-care.
 
675
        :param argv: arguments to invoke bzr
 
676
        :param retcode: expected return code, or None for don't-care.
 
677
        :param encoding: encoding for sys.stdout and sys.stderr
626
678
        :param stdin: A string to be used as stdin for the command.
627
679
        """
 
680
        if encoding is None:
 
681
            encoding = bzrlib.user_encoding
628
682
        if stdin is not None:
629
683
            stdin = StringIO(stdin)
630
 
        stdout = StringIO()
631
 
        stderr = StringIO()
632
 
        self.log('run bzr: %s', ' '.join(argv))
 
684
        stdout = StringIOWrapper()
 
685
        stderr = StringIOWrapper()
 
686
        stdout.encoding = encoding
 
687
        stderr.encoding = encoding
 
688
 
 
689
        self.log('run bzr: %r', argv)
633
690
        # FIXME: don't call into logging here
634
691
        handler = logging.StreamHandler(stderr)
635
 
        handler.setFormatter(bzrlib.trace.QuietFormatter())
636
692
        handler.setLevel(logging.INFO)
637
693
        logger = logging.getLogger('')
638
694
        logger.addHandler(handler)
648
704
        finally:
649
705
            logger.removeHandler(handler)
650
706
            bzrlib.ui.ui_factory = old_ui_factory
 
707
 
651
708
        out = stdout.getvalue()
652
709
        err = stderr.getvalue()
653
710
        if out:
654
 
            self.log('output:\n%s', out)
 
711
            self.log('output:\n%r', out)
655
712
        if err:
656
 
            self.log('errors:\n%s', err)
 
713
            self.log('errors:\n%r', err)
657
714
        if retcode is not None:
658
 
            self.assertEquals(result, retcode)
 
715
            self.assertEquals(retcode, result)
659
716
        return out, err
660
717
 
661
718
    def run_bzr(self, *args, **kwargs):
671
728
        :param stdin: A string to be used as stdin for the command.
672
729
        """
673
730
        retcode = kwargs.pop('retcode', 0)
 
731
        encoding = kwargs.pop('encoding', None)
674
732
        stdin = kwargs.pop('stdin', None)
675
 
        return self.run_bzr_captured(args, retcode, stdin)
 
733
        return self.run_bzr_captured(args, retcode=retcode, encoding=encoding, stdin=stdin)
 
734
 
 
735
    def run_bzr_decode(self, *args, **kwargs):
 
736
        if kwargs.has_key('encoding'):
 
737
            encoding = kwargs['encoding']
 
738
        else:
 
739
            encoding = bzrlib.user_encoding
 
740
        return self.run_bzr(*args, **kwargs)[0].decode(encoding)
 
741
 
 
742
    def run_bzr_subprocess(self, *args, **kwargs):
 
743
        """Run bzr in a subprocess for testing.
 
744
 
 
745
        This starts a new Python interpreter and runs bzr in there. 
 
746
        This should only be used for tests that have a justifiable need for
 
747
        this isolation: e.g. they are testing startup time, or signal
 
748
        handling, or early startup code, etc.  Subprocess code can't be 
 
749
        profiled or debugged so easily.
 
750
 
 
751
        :param retcode: The status code that is expected.  Defaults to 0.  If
 
752
        None is supplied, the status code is not checked.
 
753
        """
 
754
        bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
 
755
        args = list(args)
 
756
        process = Popen([sys.executable, bzr_path]+args, stdout=PIPE, 
 
757
                         stderr=PIPE)
 
758
        out = process.stdout.read()
 
759
        err = process.stderr.read()
 
760
        retcode = process.wait()
 
761
        supplied_retcode = kwargs.get('retcode', 0)
 
762
        if supplied_retcode is not None:
 
763
            assert supplied_retcode == retcode
 
764
        return [out, err]
676
765
 
677
766
    def check_inventory_shape(self, inv, shape):
678
767
        """Compare an inventory to a list of expected names.
843
932
        for name in shape:
844
933
            self.assert_(isinstance(name, basestring))
845
934
            if name[-1] == '/':
846
 
                transport.mkdir(urlescape(name[:-1]))
 
935
                transport.mkdir(urlutils.escape(name[:-1]))
847
936
            else:
848
937
                if line_endings == 'binary':
849
938
                    end = '\n'
851
940
                    end = os.linesep
852
941
                else:
853
942
                    raise errors.BzrError('Invalid line ending request %r' % (line_endings,))
854
 
                content = "contents of %s%s" % (name, end)
855
 
                transport.put(urlescape(name), StringIO(content))
 
943
                content = "contents of %s%s" % (name.encode('utf-8'), end)
 
944
                transport.put(urlutils.escape(name), StringIO(content))
856
945
 
857
946
    def build_tree_contents(self, shape):
858
947
        build_tree_contents(shape)
868
957
    def assertFileEqual(self, content, path):
869
958
        """Fail if path does not contain 'content'."""
870
959
        self.failUnless(osutils.lexists(path))
 
960
        # TODO: jam 20060427 Shouldn't this be 'rb'?
871
961
        self.assertEqualDiff(content, open(path, 'r').read())
872
962
 
873
963
 
949
1039
        if relpath is not None and relpath != '.':
950
1040
            if not base.endswith('/'):
951
1041
                base = base + '/'
952
 
            base = base + relpath
 
1042
            base = base + urlutils.escape(relpath)
953
1043
        return base
954
1044
 
955
1045
    def get_transport(self):
976
1066
    def make_bzrdir(self, relpath, format=None):
977
1067
        try:
978
1068
            url = self.get_url(relpath)
979
 
            segments = relpath.split('/')
 
1069
            mutter('relpath %r => url %r', relpath, url)
 
1070
            segments = url.split('/')
980
1071
            if segments and segments[-1] not in ('', '.'):
981
 
                parent = self.get_url('/'.join(segments[:-1]))
 
1072
                parent = '/'.join(segments[:-1])
982
1073
                t = get_transport(parent)
983
1074
                try:
984
1075
                    t.mkdir(segments[-1])
1050
1141
 
1051
1142
 
1052
1143
def filter_suite_by_re(suite, pattern):
1053
 
    result = TestSuite()
 
1144
    result = TestUtil.TestSuite()
1054
1145
    filter_re = re.compile(pattern)
1055
1146
    for test in iter_suite_tests(suite):
1056
1147
        if filter_re.search(test.id()):
1126
1217
                   'bzrlib.tests.test_decorators',
1127
1218
                   'bzrlib.tests.test_diff',
1128
1219
                   'bzrlib.tests.test_doc_generate',
 
1220
                   'bzrlib.tests.test_emptytree',
1129
1221
                   'bzrlib.tests.test_errors',
1130
1222
                   'bzrlib.tests.test_escaped_store',
1131
1223
                   'bzrlib.tests.test_fetch',
1157
1249
                   'bzrlib.tests.test_revision',
1158
1250
                   'bzrlib.tests.test_revisionnamespaces',
1159
1251
                   'bzrlib.tests.test_revprops',
 
1252
                   'bzrlib.tests.test_revisiontree',
1160
1253
                   'bzrlib.tests.test_rio',
1161
1254
                   'bzrlib.tests.test_sampler',
1162
1255
                   'bzrlib.tests.test_selftest',
1178
1271
                   'bzrlib.tests.test_tuned_gzip',
1179
1272
                   'bzrlib.tests.test_ui',
1180
1273
                   'bzrlib.tests.test_upgrade',
 
1274
                   'bzrlib.tests.test_urlutils',
1181
1275
                   'bzrlib.tests.test_versionedfile',
1182
1276
                   'bzrlib.tests.test_weave',
1183
1277
                   'bzrlib.tests.test_whitebox',
1185
1279
                   'bzrlib.tests.test_xml',
1186
1280
                   ]
1187
1281
    test_transport_implementations = [
1188
 
        'bzrlib.tests.test_transport_implementations']
1189
 
 
1190
 
    suite = TestSuite()
 
1282
        'bzrlib.tests.test_transport_implementations',
 
1283
        'bzrlib.tests.test_read_bundle',
 
1284
        ]
 
1285
    suite = TestUtil.TestSuite()
1191
1286
    loader = TestUtil.TestLoader()
1192
1287
    from bzrlib.transport import TransportTestProviderAdapter
1193
1288
    adapter = TransportTestProviderAdapter()