~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_errors.py

  • Committer: Martin Pool
  • Date: 2009-06-10 03:31:01 UTC
  • mfrom: (4070.12.3 249908-doc-generate)
  • mto: This revision was merged to the branch mainline in revision 4464.
  • Revision ID: mbp@sourcefrog.net-20090610033101-ce26xd79i9cbmpsd
Merge other outstanding work on 249908

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2011 Canonical Ltd
 
1
# Copyright (C) 2006, 2007, 2008 Canonical Ltd
 
2
#   Authors: Robert Collins <robert.collins@canonical.com>
 
3
#            and others
2
4
#
3
5
# This program is free software; you can redistribute it and/or modify
4
6
# it under the terms of the GNU General Public License as published by
16
18
 
17
19
"""Tests for the formatting and construction of errors."""
18
20
 
19
 
import inspect
20
 
import re
21
 
import socket
22
21
import sys
23
 
 
24
22
from bzrlib import (
25
23
    bzrdir,
26
24
    errors,
27
25
    osutils,
 
26
    symbol_versioning,
28
27
    urlutils,
29
28
    )
30
 
from bzrlib.tests import (
31
 
    TestCase,
32
 
    TestCaseWithTransport,
33
 
    TestSkipped,
34
 
    )
 
29
from bzrlib.tests import TestCase, TestCaseWithTransport
35
30
 
36
31
 
37
32
class TestErrors(TestCaseWithTransport):
38
33
 
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
 
 
64
34
    def test_bad_filename_encoding(self):
65
35
        error = errors.BadFilenameEncoding('bad/filen\xe5me', 'UTF-8')
66
36
        self.assertEqualDiff(
117
87
            "reason: reason for foo",
118
88
            str(error))
119
89
 
120
 
    def test_inconsistent_delta_delta(self):
121
 
        error = errors.InconsistentDeltaDelta([], 'reason')
122
 
        self.assertEqualDiff(
123
 
            "An inconsistent delta was supplied: []\nreason: reason",
124
 
            str(error))
125
 
 
126
90
    def test_in_process_transport(self):
127
91
        error = errors.InProcessTransport('fpp')
128
92
        self.assertEqualDiff(
162
126
            "cannot be broken.",
163
127
            str(error))
164
128
 
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
 
 
172
129
    def test_knit_data_stream_incompatible(self):
173
130
        error = errors.KnitDataStreamIncompatible(
174
131
            'stream format', 'target format')
285
242
            "You will need to upgrade the branch to permit branch stacking.",
286
243
            str(error))
287
244
 
288
 
    def test_unstackable_location(self):
289
 
        error = errors.UnstackableLocationError('foo', 'bar')
290
 
        self.assertEqualDiff("The branch 'foo' cannot be stacked on 'bar'.",
291
 
            str(error))
292
 
 
293
245
    def test_unstackable_repository_format(self):
294
246
        format = u'foo'
295
247
        url = "/foo"
300
252
            str(error))
301
253
 
302
254
    def test_up_to_date(self):
303
 
        error = errors.UpToDateFormat("someformat")
304
 
        self.assertEqualDiff(
305
 
            "The branch format someformat is already at the most "
306
 
            "recent format.", str(error))
 
255
        error = errors.UpToDateFormat(bzrdir.BzrDirFormat4())
 
256
        self.assertEqualDiff("The branch format All-in-one "
 
257
                             "format 4 is already at the most "
 
258
                             "recent format.",
 
259
                             str(error))
307
260
 
308
261
    def test_corrupt_repository(self):
309
262
        repo = self.make_repository('.')
577
530
        try:
578
531
            1/0
579
532
        except ZeroDivisionError:
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
 
533
            exc_info = sys.exc_info()
 
534
        err = errors.HookFailed('hook stage', 'hook name', exc_info)
 
535
        self.assertStartsWith(
 
536
            str(err), 'Hook \'hook name\' during hook stage failed:\n')
 
537
        self.assertEndsWith(
 
538
            str(err), 'integer division or modulo by zero')
591
539
 
592
540
    def test_tip_change_rejected(self):
593
541
        err = errors.TipChangeRejected(u'Unicode message\N{INTERROBANG}')
616
564
        try:
617
565
            raise Exception("example error")
618
566
        except Exception:
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
 
567
            exc_info = sys.exc_info()
 
568
        err = errors.SmartMessageHandlerError(exc_info)
 
569
        self.assertStartsWith(
 
570
            str(err), "The message handler raised an exception:\n")
 
571
        self.assertEndsWith(str(err), "Exception: example error\n")
627
572
 
628
573
    def test_must_have_working_tree(self):
629
574
        err = errors.MustHaveWorkingTree('foo', 'bar')
667
612
        self.assertEqual(
668
613
            'Repository dummy repo cannot suspend a write group.', str(err))
669
614
 
670
 
    def test_not_branch_no_args(self):
671
 
        err = errors.NotBranchError('path')
672
 
        self.assertEqual('Not a branch: "path".', str(err))
673
 
 
674
 
    def test_not_branch_bzrdir_with_repo(self):
675
 
        bzrdir = self.make_repository('repo').bzrdir
676
 
        err = errors.NotBranchError('path', bzrdir=bzrdir)
677
 
        self.assertEqual(
678
 
            'Not a branch: "path": location is a repository.', str(err))
679
 
 
680
 
    def test_not_branch_bzrdir_without_repo(self):
681
 
        bzrdir = self.make_bzrdir('bzrdir')
682
 
        err = errors.NotBranchError('path', bzrdir=bzrdir)
683
 
        self.assertEqual('Not a branch: "path".', str(err))
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
 
 
694
 
    def test_not_branch_laziness(self):
695
 
        real_bzrdir = self.make_bzrdir('path')
696
 
        class FakeBzrDir(object):
697
 
            def __init__(self):
698
 
                self.calls = []
699
 
            def open_repository(self):
700
 
                self.calls.append('open_repository')
701
 
                raise errors.NoRepositoryPresent(real_bzrdir)
702
 
        fake_bzrdir = FakeBzrDir()
703
 
        err = errors.NotBranchError('path', bzrdir=fake_bzrdir)
704
 
        self.assertEqual([], fake_bzrdir.calls)
705
 
        str(err)
706
 
        self.assertEqual(['open_repository'], fake_bzrdir.calls)
707
 
        # Stringifying twice doesn't try to open a repository twice.
708
 
        str(err)
709
 
        self.assertEqual(['open_repository'], fake_bzrdir.calls)
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
 
 
722
615
 
723
616
class PassThroughError(errors.BzrError):
724
617
 
734
627
 
735
628
 
736
629
class ErrorWithNoFormat(errors.BzrError):
737
 
    __doc__ = """This class has a docstring but no format string."""
 
630
    """This class has a docstring but no format string."""
738
631
 
739
632
 
740
633
class TestErrorFormatting(TestCase):
765
658
        e = ErrorWithBadFormat(not_thing='x')
766
659
        self.assertStartsWith(
767
660
            str(e), 'Unprintable exception ErrorWithBadFormat')
768
 
 
769
 
    def test_cannot_bind_address(self):
770
 
        # see <https://bugs.launchpad.net/bzr/+bug/286871>
771
 
        e = errors.CannotBindAddress('example.com', 22,
772
 
            socket.error(13, 'Permission denied'))
773
 
        self.assertContainsRe(str(e),
774
 
            r'Cannot bind address "example\.com:22":.*Permission denied')
775
 
 
776
 
    def test_file_timestamp_unavailable(self):            
777
 
        e = errors.FileTimestampUnavailable("/path/foo")
778
 
        self.assertEquals("The filestamp for /path/foo is not available.",
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))