~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_errors.py

  • Committer: Jelmer Vernooij
  • Date: 2011-09-26 15:21:01 UTC
  • mfrom: (6165.2.3 avoid-revision-history)
  • mto: This revision was merged to the branch mainline in revision 6216.
  • Revision ID: jelmer@samba.org-20110926152101-afcxw1hikybyivfd
merge avoid-revision-history.

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-2011 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
 
23
25
    bzrdir,
24
26
    errors,
25
27
    osutils,
26
 
    symbol_versioning,
27
28
    urlutils,
28
29
    )
29
 
from bzrlib.tests import TestCase, TestCaseWithTransport
 
30
from bzrlib.tests import (
 
31
    TestCase,
 
32
    TestCaseWithTransport,
 
33
    TestSkipped,
 
34
    )
30
35
 
31
36
 
32
37
class TestErrors(TestCaseWithTransport):
33
38
 
 
39
    def test_no_arg_named_message(self):
 
40
        """Ensure the __init__ and _fmt in errors do not have "message" arg.
 
41
 
 
42
        This test fails if __init__ or _fmt in errors has an argument
 
43
        named "message" as this can cause errors in some Python versions.
 
44
        Python 2.5 uses a slot for StandardError.message.
 
45
        See bug #603461
 
46
        """
 
47
        fmt_pattern = re.compile("%\(message\)[sir]")
 
48
        subclasses_present = getattr(errors.BzrError, '__subclasses__', None)
 
49
        if not subclasses_present:
 
50
            raise TestSkipped('__subclasses__ attribute required for classes. '
 
51
                'Requires Python 2.5 or later.')
 
52
        for c in errors.BzrError.__subclasses__():
 
53
            init = getattr(c, '__init__', None)
 
54
            fmt = getattr(c, '_fmt', None)
 
55
            if init:
 
56
                args = inspect.getargspec(init)[0]
 
57
                self.assertFalse('message' in args,
 
58
                    ('Argument name "message" not allowed for '
 
59
                    '"errors.%s.__init__"' % c.__name__))
 
60
            if fmt and fmt_pattern.search(fmt):
 
61
                self.assertFalse(True, ('"message" not allowed in '
 
62
                    '"errors.%s._fmt"' % c.__name__))
 
63
 
34
64
    def test_bad_filename_encoding(self):
35
65
        error = errors.BadFilenameEncoding('bad/filen\xe5me', 'UTF-8')
36
66
        self.assertEqualDiff(
132
162
            "cannot be broken.",
133
163
            str(error))
134
164
 
 
165
    def test_lock_corrupt(self):
 
166
        error = errors.LockCorrupt("corruption info")
 
167
        self.assertEqualDiff("Lock is apparently held, but corrupted: "
 
168
            "corruption info\n"
 
169
            "Use 'bzr break-lock' to clear it",
 
170
            str(error))
 
171
 
135
172
    def test_knit_data_stream_incompatible(self):
136
173
        error = errors.KnitDataStreamIncompatible(
137
174
            'stream format', 'target format')
263
300
            str(error))
264
301
 
265
302
    def test_up_to_date(self):
266
 
        error = errors.UpToDateFormat(bzrdir.BzrDirFormat4())
267
 
        self.assertEqualDiff("The branch format All-in-one "
268
 
                             "format 4 is already at the most "
269
 
                             "recent format.",
270
 
                             str(error))
 
303
        error = errors.UpToDateFormat("someformat")
 
304
        self.assertEqualDiff(
 
305
            "The branch format someformat is already at the most "
 
306
            "recent format.", str(error))
271
307
 
272
308
    def test_corrupt_repository(self):
273
309
        repo = self.make_repository('.')
541
577
        try:
542
578
            1/0
543
579
        except ZeroDivisionError:
544
 
            exc_info = sys.exc_info()
545
 
        err = errors.HookFailed('hook stage', 'hook name', exc_info, warn=False)
546
 
        self.assertStartsWith(
547
 
            str(err), 'Hook \'hook name\' during hook stage failed:\n')
548
 
        self.assertEndsWith(
549
 
            str(err), 'integer division or modulo by zero')
 
580
            err = errors.HookFailed('hook stage', 'hook name', sys.exc_info(),
 
581
                warn=False)
 
582
        # GZ 2010-11-08: Should not store exc_info in exception instances, but
 
583
        #                HookFailed is deprecated anyway and could maybe go.
 
584
        try:
 
585
            self.assertStartsWith(
 
586
                str(err), 'Hook \'hook name\' during hook stage failed:\n')
 
587
            self.assertEndsWith(
 
588
                str(err), 'integer division or modulo by zero')
 
589
        finally:
 
590
            del err
550
591
 
551
592
    def test_tip_change_rejected(self):
552
593
        err = errors.TipChangeRejected(u'Unicode message\N{INTERROBANG}')
575
616
        try:
576
617
            raise Exception("example error")
577
618
        except Exception:
578
 
            exc_info = sys.exc_info()
579
 
        err = errors.SmartMessageHandlerError(exc_info)
580
 
        self.assertStartsWith(
581
 
            str(err), "The message handler raised an exception:\n")
582
 
        self.assertEndsWith(str(err), "Exception: example error\n")
 
619
            err = errors.SmartMessageHandlerError(sys.exc_info())
 
620
        # GZ 2010-11-08: Should not store exc_info in exception instances.
 
621
        try:
 
622
            self.assertStartsWith(
 
623
                str(err), "The message handler raised an exception:\n")
 
624
            self.assertEndsWith(str(err), "Exception: example error\n")
 
625
        finally:
 
626
            del err
583
627
 
584
628
    def test_must_have_working_tree(self):
585
629
        err = errors.MustHaveWorkingTree('foo', 'bar')
638
682
        err = errors.NotBranchError('path', bzrdir=bzrdir)
639
683
        self.assertEqual('Not a branch: "path".', str(err))
640
684
 
 
685
    def test_not_branch_bzrdir_with_recursive_not_branch_error(self):
 
686
        class FakeBzrDir(object):
 
687
            def open_repository(self):
 
688
                # str() on the NotBranchError will trigger a call to this,
 
689
                # which in turn will another, identical NotBranchError.
 
690
                raise errors.NotBranchError('path', bzrdir=FakeBzrDir())
 
691
        err = errors.NotBranchError('path', bzrdir=FakeBzrDir())
 
692
        self.assertEqual('Not a branch: "path".', str(err))
 
693
 
641
694
    def test_not_branch_laziness(self):
642
695
        real_bzrdir = self.make_bzrdir('path')
643
696
        class FakeBzrDir(object):
655
708
        str(err)
656
709
        self.assertEqual(['open_repository'], fake_bzrdir.calls)
657
710
 
 
711
    def test_invalid_pattern(self):
 
712
        error = errors.InvalidPattern('Bad pattern msg.')
 
713
        self.assertEqualDiff("Invalid pattern(s) found. Bad pattern msg.",
 
714
            str(error))
 
715
 
 
716
    def test_recursive_bind(self):
 
717
        error = errors.RecursiveBind('foo_bar_branch')
 
718
        msg = ('Branch "foo_bar_branch" appears to be bound to itself. '
 
719
            'Please use `bzr unbind` to fix.')
 
720
        self.assertEqualDiff(msg, str(error))
 
721
 
658
722
 
659
723
class PassThroughError(errors.BzrError):
660
724
 
670
734
 
671
735
 
672
736
class ErrorWithNoFormat(errors.BzrError):
673
 
    """This class has a docstring but no format string."""
 
737
    __doc__ = """This class has a docstring but no format string."""
674
738
 
675
739
 
676
740
class TestErrorFormatting(TestCase):
703
767
            str(e), 'Unprintable exception ErrorWithBadFormat')
704
768
 
705
769
    def test_cannot_bind_address(self):
706
 
        # see <https://bugs.edge.launchpad.net/bzr/+bug/286871>
 
770
        # see <https://bugs.launchpad.net/bzr/+bug/286871>
707
771
        e = errors.CannotBindAddress('example.com', 22,
708
772
            socket.error(13, 'Permission denied'))
709
773
        self.assertContainsRe(str(e),
713
777
        e = errors.FileTimestampUnavailable("/path/foo")
714
778
        self.assertEquals("The filestamp for /path/foo is not available.",
715
779
            str(e))
 
780
            
 
781
    def test_transform_rename_failed(self):
 
782
        e = errors.TransformRenameFailed(u"from", u"to", "readonly file", 2)
 
783
        self.assertEquals(
 
784
            u"Failed to rename from to to: readonly file",
 
785
            str(e))