/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

  • Committer: Jan Hudec
  • Date: 2006-11-25 20:38:39 UTC
  • mto: (2199.1.1 jam-integration)
  • mto: This revision was merged to the branch mainline in revision 2200.
  • Revision ID: bulb@ucw.cz-20061125203839-9nuhv32z63hb8811
Option --pull for merge command.

Option --pull was added to merge command, that, if the merge would be
trivial, ie. if the common ancestor is equal to the local tip, causes pull of
the remote instead of creating the merger.

Simple test for this option is included.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006 Canonical Ltd
 
2
#   Authors: Robert Collins <robert.collins@canonical.com>
 
3
#
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; either version 2 of the License, or
 
7
# (at your option) any later version.
 
8
#
 
9
# This program is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
# GNU General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU General Public License
 
15
# along with this program; if not, write to the Free Software
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
 
18
"""Tests for the formatting and construction of errors."""
 
19
 
 
20
from bzrlib import (
 
21
    bzrdir,
 
22
    errors,
 
23
    )
 
24
from bzrlib.tests import TestCase, TestCaseWithTransport
 
25
 
 
26
 
 
27
# TODO: Make sure builtin exception class formats are consistent - e.g. should
 
28
# or shouldn't end with a full stop, etc.
 
29
 
 
30
 
 
31
class TestErrors(TestCaseWithTransport):
 
32
 
 
33
    def test_inventory_modified(self):
 
34
        error = errors.InventoryModified("a tree to be repred")
 
35
        self.assertEqualDiff("The current inventory for the tree 'a tree to "
 
36
            "be repred' has been modified, so a clean inventory cannot be "
 
37
            "read without data loss.",
 
38
            str(error))
 
39
 
 
40
    def test_install_failed(self):
 
41
        error = errors.InstallFailed(['rev-one'])
 
42
        self.assertEqual("Could not install revisions:\nrev-one", str(error))
 
43
        error = errors.InstallFailed(['rev-one', 'rev-two'])
 
44
        self.assertEqual("Could not install revisions:\nrev-one, rev-two",
 
45
                         str(error))
 
46
        error = errors.InstallFailed([None])
 
47
        self.assertEqual("Could not install revisions:\nNone", str(error))
 
48
 
 
49
    def test_medium_not_connected(self):
 
50
        error = errors.MediumNotConnected("a medium")
 
51
        self.assertEqualDiff(
 
52
            "The medium 'a medium' is not connected.", str(error))
 
53
        
 
54
    def test_no_repo(self):
 
55
        dir = bzrdir.BzrDir.create(self.get_url())
 
56
        error = errors.NoRepositoryPresent(dir)
 
57
        self.assertNotEqual(-1, str(error).find((dir.transport.clone('..').base)))
 
58
        self.assertEqual(-1, str(error).find((dir.transport.base)))
 
59
        
 
60
    def test_no_smart_medium(self):
 
61
        error = errors.NoSmartMedium("a transport")
 
62
        self.assertEqualDiff("The transport 'a transport' cannot tunnel the "
 
63
            "smart protocol.",
 
64
            str(error))
 
65
 
 
66
    def test_no_such_id(self):
 
67
        error = errors.NoSuchId("atree", "anid")
 
68
        self.assertEqualDiff("The file id anid is not present in the tree "
 
69
            "atree.",
 
70
            str(error))
 
71
 
 
72
    def test_not_write_locked(self):
 
73
        error = errors.NotWriteLocked('a thing to repr')
 
74
        self.assertEqualDiff("'a thing to repr' is not write locked but needs "
 
75
            "to be.",
 
76
            str(error))
 
77
 
 
78
    def test_too_many_concurrent_requests(self):
 
79
        error = errors.TooManyConcurrentRequests("a medium")
 
80
        self.assertEqualDiff("The medium 'a medium' has reached its concurrent "
 
81
            "request limit. Be sure to finish_writing and finish_reading on "
 
82
            "the current request that is open.",
 
83
            str(error))
 
84
 
 
85
    def test_up_to_date(self):
 
86
        error = errors.UpToDateFormat(bzrdir.BzrDirFormat4())
 
87
        self.assertEqualDiff("The branch format Bazaar-NG branch, "
 
88
                             "format 0.0.4 is already at the most "
 
89
                             "recent format.",
 
90
                             str(error))
 
91
 
 
92
    def test_corrupt_repository(self):
 
93
        repo = self.make_repository('.')
 
94
        error = errors.CorruptRepository(repo)
 
95
        self.assertEqualDiff("An error has been detected in the repository %s.\n"
 
96
                             "Please run bzr reconcile on this repository." %
 
97
                             repo.bzrdir.root_transport.base,
 
98
                             str(error))
 
99
 
 
100
    def test_bzrnewerror_is_deprecated(self):
 
101
        class DeprecatedError(errors.BzrNewError):
 
102
            pass
 
103
        self.callDeprecated(['BzrNewError was deprecated in bzr 0.13; '
 
104
             'please convert DeprecatedError to use BzrError instead'],
 
105
            DeprecatedError)
 
106
 
 
107
    def test_bzrerror_from_literal_string(self):
 
108
        # Some code constructs BzrError from a literal string, in which case
 
109
        # no further formatting is done.  (I'm not sure raising the base class
 
110
        # is a great idea, but if the exception is not intended to be caught
 
111
        # perhaps no more is needed.)
 
112
        try:
 
113
            raise errors.BzrError('this is my errors; %d is not expanded')
 
114
        except errors.BzrError, e:
 
115
            self.assertEqual('this is my errors; %d is not expanded', str(e))
 
116
 
 
117
    def test_reading_completed(self):
 
118
        error = errors.ReadingCompleted("a request")
 
119
        self.assertEqualDiff("The MediumRequest 'a request' has already had "
 
120
            "finish_reading called upon it - the request has been completed and"
 
121
            " no more data may be read.",
 
122
            str(error))
 
123
 
 
124
    def test_writing_completed(self):
 
125
        error = errors.WritingCompleted("a request")
 
126
        self.assertEqualDiff("The MediumRequest 'a request' has already had "
 
127
            "finish_writing called upon it - accept bytes may not be called "
 
128
            "anymore.",
 
129
            str(error))
 
130
 
 
131
    def test_writing_not_completed(self):
 
132
        error = errors.WritingNotComplete("a request")
 
133
        self.assertEqualDiff("The MediumRequest 'a request' has not has "
 
134
            "finish_writing called upon it - until the write phase is complete"
 
135
            " no data may be read.",
 
136
            str(error))
 
137
 
 
138
    def test_transport_not_possible(self):
 
139
        e = errors.TransportNotPossible('readonly', 'original error')
 
140
        self.assertEqual('Transport operation not possible:'
 
141
                         ' readonly original error', str(e))
 
142
 
 
143
    def assertSocketConnectionError(self, expected, *args, **kwargs):
 
144
        """Check the formatting of a SocketConnectionError exception"""
 
145
        e = errors.SocketConnectionError(*args, **kwargs)
 
146
        self.assertEqual(expected, str(e))
 
147
 
 
148
    def test_socket_connection_error(self):
 
149
        """Test the formatting of SocketConnectionError"""
 
150
 
 
151
        # There should be a default msg about failing to connect
 
152
        # we only require a host name.
 
153
        self.assertSocketConnectionError(
 
154
            'Failed to connect to ahost',
 
155
            'ahost')
 
156
 
 
157
        # If port is None, we don't put :None
 
158
        self.assertSocketConnectionError(
 
159
            'Failed to connect to ahost',
 
160
            'ahost', port=None)
 
161
        # But if port is supplied we include it
 
162
        self.assertSocketConnectionError(
 
163
            'Failed to connect to ahost:22',
 
164
            'ahost', port=22)
 
165
 
 
166
        # We can also supply extra information about the error
 
167
        # with or without a port
 
168
        self.assertSocketConnectionError(
 
169
            'Failed to connect to ahost:22; bogus error',
 
170
            'ahost', port=22, orig_error='bogus error')
 
171
        self.assertSocketConnectionError(
 
172
            'Failed to connect to ahost; bogus error',
 
173
            'ahost', orig_error='bogus error')
 
174
        # An exception object can be passed rather than a string
 
175
        orig_error = ValueError('bad value')
 
176
        self.assertSocketConnectionError(
 
177
            'Failed to connect to ahost; %s' % (str(orig_error),),
 
178
            host='ahost', orig_error=orig_error)
 
179
 
 
180
        # And we can supply a custom failure message
 
181
        self.assertSocketConnectionError(
 
182
            'Unable to connect to ssh host ahost:444; my_error',
 
183
            host='ahost', port=444, msg='Unable to connect to ssh host',
 
184
            orig_error='my_error')
 
185
 
 
186
 
 
187
 
 
188
class PassThroughError(errors.BzrError):
 
189
    
 
190
    _fmt = """Pass through %(foo)s and %(bar)s"""
 
191
 
 
192
    def __init__(self, foo, bar):
 
193
        errors.BzrError.__init__(self, foo=foo, bar=bar)
 
194
 
 
195
 
 
196
class ErrorWithBadFormat(errors.BzrError):
 
197
 
 
198
    _fmt = """One format specifier: %(thing)s"""
 
199
 
 
200
 
 
201
class ErrorWithNoFormat(errors.BzrError):
 
202
    """This class has a docstring but no format string."""
 
203
 
 
204
 
 
205
class TestErrorFormatting(TestCase):
 
206
    
 
207
    def test_always_str(self):
 
208
        e = PassThroughError(u'\xb5', 'bar')
 
209
        self.assertIsInstance(e.__str__(), str)
 
210
        # In Python str(foo) *must* return a real byte string
 
211
        # not a Unicode string. The following line would raise a
 
212
        # Unicode error, because it tries to call str() on the string
 
213
        # returned from e.__str__(), and it has non ascii characters
 
214
        s = str(e)
 
215
        self.assertEqual('Pass through \xc2\xb5 and bar', s)
 
216
 
 
217
    def test_missing_format_string(self):
 
218
        e = ErrorWithNoFormat(param='randomvalue')
 
219
        s = self.callDeprecated(
 
220
                ['ErrorWithNoFormat uses its docstring as a format, it should use _fmt instead'],
 
221
                lambda x: str(x), e)
 
222
        ## s = str(e)
 
223
        self.assertEqual(s, 
 
224
                "This class has a docstring but no format string.")
 
225
 
 
226
    def test_mismatched_format_args(self):
 
227
        # Even though ErrorWithBadFormat's format string does not match the
 
228
        # arguments we constructing it with, we can still stringify an instance
 
229
        # of this exception. The resulting string will say its unprintable.
 
230
        e = ErrorWithBadFormat(not_thing='x')
 
231
        self.assertStartsWith(
 
232
            str(e), 'Unprintable exception ErrorWithBadFormat')
 
233