~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_errors.py

Merge checkout-tags-propagation-603395-2.2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007, 2008 Canonical Ltd
2
 
#   Authors: Robert Collins <robert.collins@canonical.com>
3
 
#            and others
 
1
# Copyright (C) 2006-2010 Canonical Ltd
4
2
#
5
3
# This program is free software; you can redistribute it and/or modify
6
4
# it under the terms of the GNU General Public License as published by
18
16
 
19
17
"""Tests for the formatting and construction of errors."""
20
18
 
 
19
import inspect
 
20
import re
 
21
import socket
21
22
import sys
 
23
 
22
24
from bzrlib import (
23
25
    bzrdir,
24
26
    errors,
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(
87
114
            "reason: reason for foo",
88
115
            str(error))
89
116
 
 
117
    def test_inconsistent_delta_delta(self):
 
118
        error = errors.InconsistentDeltaDelta([], 'reason')
 
119
        self.assertEqualDiff(
 
120
            "An inconsistent delta was supplied: []\nreason: reason",
 
121
            str(error))
 
122
 
90
123
    def test_in_process_transport(self):
91
124
        error = errors.InProcessTransport('fpp')
92
125
        self.assertEqualDiff(
114
147
            "read without data loss.",
115
148
            str(error))
116
149
 
117
 
    def test_install_failed(self):
118
 
        error = errors.InstallFailed(['rev-one'])
119
 
        self.assertEqual("Could not install revisions:\nrev-one", str(error))
120
 
        error = errors.InstallFailed(['rev-one', 'rev-two'])
121
 
        self.assertEqual("Could not install revisions:\nrev-one, rev-two",
122
 
                         str(error))
123
 
        error = errors.InstallFailed([None])
124
 
        self.assertEqual("Could not install revisions:\nNone", str(error))
 
150
    def test_jail_break(self):
 
151
        error = errors.JailBreak("some url")
 
152
        self.assertEqualDiff("An attempt to access a url outside the server"
 
153
            " jail was made: 'some url'.",
 
154
            str(error))
125
155
 
126
156
    def test_lock_active(self):
127
157
        error = errors.LockActive("lock description")
129
159
            "cannot be broken.",
130
160
            str(error))
131
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
 
132
169
    def test_knit_data_stream_incompatible(self):
133
170
        error = errors.KnitDataStreamIncompatible(
134
171
            'stream format', 'target format')
245
282
            "You will need to upgrade the branch to permit branch stacking.",
246
283
            str(error))
247
284
 
 
285
    def test_unstackable_location(self):
 
286
        error = errors.UnstackableLocationError('foo', 'bar')
 
287
        self.assertEqualDiff("The branch 'foo' cannot be stacked on 'bar'.",
 
288
            str(error))
 
289
 
248
290
    def test_unstackable_repository_format(self):
249
291
        format = u'foo'
250
292
        url = "/foo"
534
576
            1/0
535
577
        except ZeroDivisionError:
536
578
            exc_info = sys.exc_info()
537
 
        err = errors.HookFailed('hook stage', 'hook name', exc_info)
 
579
        err = errors.HookFailed('hook stage', 'hook name', exc_info, warn=False)
538
580
        self.assertStartsWith(
539
581
            str(err), 'Hook \'hook name\' during hook stage failed:\n')
540
582
        self.assertEndsWith(
615
657
        self.assertEqual(
616
658
            'Repository dummy repo cannot suspend a write group.', str(err))
617
659
 
 
660
    def test_not_branch_no_args(self):
 
661
        err = errors.NotBranchError('path')
 
662
        self.assertEqual('Not a branch: "path".', str(err))
 
663
 
 
664
    def test_not_branch_bzrdir_with_repo(self):
 
665
        bzrdir = self.make_repository('repo').bzrdir
 
666
        err = errors.NotBranchError('path', bzrdir=bzrdir)
 
667
        self.assertEqual(
 
668
            'Not a branch: "path": location is a repository.', str(err))
 
669
 
 
670
    def test_not_branch_bzrdir_without_repo(self):
 
671
        bzrdir = self.make_bzrdir('bzrdir')
 
672
        err = errors.NotBranchError('path', bzrdir=bzrdir)
 
673
        self.assertEqual('Not a branch: "path".', str(err))
 
674
 
 
675
    def test_not_branch_bzrdir_with_recursive_not_branch_error(self):
 
676
        class FakeBzrDir(object):
 
677
            def open_repository(self):
 
678
                # str() on the NotBranchError will trigger a call to this,
 
679
                # which in turn will another, identical NotBranchError.
 
680
                raise errors.NotBranchError('path', bzrdir=FakeBzrDir())
 
681
        err = errors.NotBranchError('path', bzrdir=FakeBzrDir())
 
682
        self.assertEqual('Not a branch: "path".', str(err))
 
683
 
 
684
    def test_not_branch_laziness(self):
 
685
        real_bzrdir = self.make_bzrdir('path')
 
686
        class FakeBzrDir(object):
 
687
            def __init__(self):
 
688
                self.calls = []
 
689
            def open_repository(self):
 
690
                self.calls.append('open_repository')
 
691
                raise errors.NoRepositoryPresent(real_bzrdir)
 
692
        fake_bzrdir = FakeBzrDir()
 
693
        err = errors.NotBranchError('path', bzrdir=fake_bzrdir)
 
694
        self.assertEqual([], fake_bzrdir.calls)
 
695
        str(err)
 
696
        self.assertEqual(['open_repository'], fake_bzrdir.calls)
 
697
        # Stringifying twice doesn't try to open a repository twice.
 
698
        str(err)
 
699
        self.assertEqual(['open_repository'], fake_bzrdir.calls)
 
700
 
 
701
    def test_invalid_pattern(self):
 
702
        error = errors.InvalidPattern('Bad pattern msg.')
 
703
        self.assertEqualDiff("Invalid pattern(s) found. Bad pattern msg.",
 
704
            str(error))
 
705
 
 
706
    def test_recursive_bind(self):
 
707
        error = errors.RecursiveBind('foo_bar_branch')
 
708
        msg = ('Branch "foo_bar_branch" appears to be bound to itself. '
 
709
            'Please use `bzr unbind` to fix.')
 
710
        self.assertEqualDiff(msg, str(error))
 
711
 
618
712
 
619
713
class PassThroughError(errors.BzrError):
620
714
 
630
724
 
631
725
 
632
726
class ErrorWithNoFormat(errors.BzrError):
633
 
    """This class has a docstring but no format string."""
 
727
    __doc__ = """This class has a docstring but no format string."""
634
728
 
635
729
 
636
730
class TestErrorFormatting(TestCase):
661
755
        e = ErrorWithBadFormat(not_thing='x')
662
756
        self.assertStartsWith(
663
757
            str(e), 'Unprintable exception ErrorWithBadFormat')
 
758
 
 
759
    def test_cannot_bind_address(self):
 
760
        # see <https://bugs.launchpad.net/bzr/+bug/286871>
 
761
        e = errors.CannotBindAddress('example.com', 22,
 
762
            socket.error(13, 'Permission denied'))
 
763
        self.assertContainsRe(str(e),
 
764
            r'Cannot bind address "example\.com:22":.*Permission denied')
 
765
 
 
766
    def test_file_timestamp_unavailable(self):            
 
767
        e = errors.FileTimestampUnavailable("/path/foo")
 
768
        self.assertEquals("The filestamp for /path/foo is not available.",
 
769
            str(e))
 
770
            
 
771
    def test_transform_rename_failed(self):
 
772
        e = errors.TransformRenameFailed(u"from", u"to", "readonly file", 2)
 
773
        self.assertEquals(
 
774
            u"Failed to rename from to to: readonly file",
 
775
            str(e))