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

Add bzrlib.pyutils, which has get_named_object, a wrapper around __import__.

This is used to replace various ad hoc implementations of the same logic,
notably the version used in registry's _LazyObjectGetter which had a bug when
getting a module without also getting a member.  And of course, this new
function has unit tests, unlike the replaced code.

This also adds a KnownHooksRegistry subclass to provide a more natural home for
some other logic.

I'm not thrilled about the name of the new module or the new functions, but it's
hard to think of good names for such generic functionality.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Tests for the formatting and construction of errors."""
18
18
 
 
19
import inspect
 
20
import re
19
21
import socket
20
22
import sys
21
23
 
26
28
    symbol_versioning,
27
29
    urlutils,
28
30
    )
29
 
from bzrlib.tests import TestCase, TestCaseWithTransport
 
31
from bzrlib.tests import TestCase, TestCaseWithTransport, TestSkipped
30
32
 
31
33
 
32
34
class TestErrors(TestCaseWithTransport):
33
35
 
 
36
    def test_no_arg_named_message(self):
 
37
        """Ensure the __init__ and _fmt in errors do not have "message" arg.
 
38
 
 
39
        This test fails if __init__ or _fmt in errors has an argument
 
40
        named "message" as this can cause errors in some Python versions.
 
41
        Python 2.5 uses a slot for StandardError.message.
 
42
        See bug #603461
 
43
        """
 
44
        fmt_pattern = re.compile("%\(message\)[sir]")
 
45
        subclasses_present = getattr(errors.BzrError, '__subclasses__', None)
 
46
        if not subclasses_present:
 
47
            raise TestSkipped('__subclasses__ attribute required for classes. '
 
48
                'Requires Python 2.5 or later.')
 
49
        for c in errors.BzrError.__subclasses__():
 
50
            init = getattr(c, '__init__', None)
 
51
            fmt = getattr(c, '_fmt', None)
 
52
            if init:
 
53
                args = inspect.getargspec(init)[0]
 
54
                self.assertFalse('message' in args,
 
55
                    ('Argument name "message" not allowed for '
 
56
                    '"errors.%s.__init__"' % c.__name__))
 
57
            if fmt and fmt_pattern.search(fmt):
 
58
                self.assertFalse(True, ('"message" not allowed in '
 
59
                    '"errors.%s._fmt"' % c.__name__))
 
60
 
34
61
    def test_bad_filename_encoding(self):
35
62
        error = errors.BadFilenameEncoding('bad/filen\xe5me', 'UTF-8')
36
63
        self.assertEqualDiff(
132
159
            "cannot be broken.",
133
160
            str(error))
134
161
 
 
162
    def test_lock_corrupt(self):
 
163
        error = errors.LockCorrupt("corruption info")
 
164
        self.assertEqualDiff("Lock is apparently held, but corrupted: "
 
165
            "corruption info\n"
 
166
            "Use 'bzr break-lock' to clear it",
 
167
            str(error))
 
168
 
135
169
    def test_knit_data_stream_incompatible(self):
136
170
        error = errors.KnitDataStreamIncompatible(
137
171
            'stream format', 'target format')
655
689
        str(err)
656
690
        self.assertEqual(['open_repository'], fake_bzrdir.calls)
657
691
 
 
692
    def test_invalid_pattern(self):
 
693
        error = errors.InvalidPattern('Bad pattern msg.')
 
694
        self.assertEqualDiff("Invalid pattern(s) found. Bad pattern msg.",
 
695
            str(error))
 
696
 
 
697
    def test_recursive_bind(self):
 
698
        error = errors.RecursiveBind('foo_bar_branch')
 
699
        msg = ('Branch "foo_bar_branch" appears to be bound to itself. '
 
700
            'Please use `bzr unbind` to fix.')
 
701
        self.assertEqualDiff(msg, str(error))
 
702
 
658
703
 
659
704
class PassThroughError(errors.BzrError):
660
705
 
703
748
            str(e), 'Unprintable exception ErrorWithBadFormat')
704
749
 
705
750
    def test_cannot_bind_address(self):
706
 
        # see <https://bugs.edge.launchpad.net/bzr/+bug/286871>
 
751
        # see <https://bugs.launchpad.net/bzr/+bug/286871>
707
752
        e = errors.CannotBindAddress('example.com', 22,
708
753
            socket.error(13, 'Permission denied'))
709
754
        self.assertContainsRe(str(e),
713
758
        e = errors.FileTimestampUnavailable("/path/foo")
714
759
        self.assertEquals("The filestamp for /path/foo is not available.",
715
760
            str(e))
 
761
            
 
762
    def test_transform_rename_failed(self):
 
763
        e = errors.TransformRenameFailed(u"from", u"to", "readonly file", 2)
 
764
        self.assertEquals(
 
765
            u"Failed to rename from to to: readonly file",
 
766
            str(e))