~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_errors.py

  • Committer: Jelmer Vernooij
  • Date: 2010-12-20 11:57:14 UTC
  • mto: This revision was merged to the branch mainline in revision 5577.
  • Revision ID: jelmer@samba.org-20101220115714-2ru3hfappjweeg7q
Don't use no-plugins.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006, 2007, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
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')
542
576
            1/0
543
577
        except ZeroDivisionError:
544
578
            exc_info = sys.exc_info()
545
 
        err = errors.HookFailed('hook stage', 'hook name', exc_info)
 
579
        err = errors.HookFailed('hook stage', 'hook name', exc_info, warn=False)
546
580
        self.assertStartsWith(
547
581
            str(err), 'Hook \'hook name\' during hook stage failed:\n')
548
582
        self.assertEndsWith(
623
657
        self.assertEqual(
624
658
            'Repository dummy repo cannot suspend a write group.', str(err))
625
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
 
626
712
 
627
713
class PassThroughError(errors.BzrError):
628
714
 
638
724
 
639
725
 
640
726
class ErrorWithNoFormat(errors.BzrError):
641
 
    """This class has a docstring but no format string."""
 
727
    __doc__ = """This class has a docstring but no format string."""
642
728
 
643
729
 
644
730
class TestErrorFormatting(TestCase):
671
757
            str(e), 'Unprintable exception ErrorWithBadFormat')
672
758
 
673
759
    def test_cannot_bind_address(self):
674
 
        # see <https://bugs.edge.launchpad.net/bzr/+bug/286871>
 
760
        # see <https://bugs.launchpad.net/bzr/+bug/286871>
675
761
        e = errors.CannotBindAddress('example.com', 22,
676
762
            socket.error(13, 'Permission denied'))
677
763
        self.assertContainsRe(str(e),
678
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))