/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: John Arbash Meinel
  • Date: 2006-04-25 15:05:42 UTC
  • mfrom: (1185.85.85 bzr-encoding)
  • mto: This revision was merged to the branch mainline in revision 1752.
  • Revision ID: john@arbash-meinel.com-20060425150542-c7b518dca9928691
[merge] the old bzr-encoding changes, reparenting them on bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2012, 2016 Canonical Ltd
 
1
# Copyright (C) 2006 by Canonical Ltd
 
2
#   Authors: Robert Collins <robert.collins@canonical.com>
2
3
#
3
4
# This program is free software; you can redistribute it and/or modify
4
5
# it under the terms of the GNU General Public License as published by
12
13
#
13
14
# You should have received a copy of the GNU General Public License
14
15
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
 
17
18
"""Tests for the formatting and construction of errors."""
18
19
 
19
 
import inspect
20
 
import re
21
 
import socket
22
 
import sys
23
 
 
24
 
from .. import (
25
 
    controldir,
26
 
    errors,
27
 
    osutils,
28
 
    tests,
29
 
    urlutils,
30
 
    )
31
 
from ..sixish import (
32
 
    PY3,
33
 
    text_type,
34
 
    )
35
 
 
36
 
 
37
 
class TestErrors(tests.TestCase):
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
 
        for c in errors.BzrError.__subclasses__():
49
 
            init = getattr(c, '__init__', None)
50
 
            fmt = getattr(c, '_fmt', None)
51
 
            if init:
52
 
                if PY3:
53
 
                    args = inspect.getfullargspec(init)[0]
54
 
                else:
55
 
                    args = inspect.getargspec(init)[0]
56
 
                self.assertFalse('message' in args,
57
 
                                 ('Argument name "message" not allowed for '
58
 
                                  '"errors.%s.__init__"' % c.__name__))
59
 
            if fmt and fmt_pattern.search(fmt):
60
 
                self.assertFalse(True, ('"message" not allowed in '
61
 
                                        '"errors.%s._fmt"' % c.__name__))
62
 
 
63
 
    def test_bad_filename_encoding(self):
64
 
        error = errors.BadFilenameEncoding(b'bad/filen\xe5me', 'UTF-8')
65
 
        self.assertContainsRe(
66
 
            str(error),
67
 
            "^Filename b?'bad/filen\\\\xe5me' is not valid in your current"
68
 
            " filesystem encoding UTF-8$")
69
 
 
70
 
    def test_duplicate_file_id(self):
71
 
        error = errors.DuplicateFileId('a_file_id', 'foo')
72
 
        self.assertEqualDiff('File id {a_file_id} already exists in inventory'
73
 
                             ' as foo', str(error))
74
 
 
75
 
    def test_duplicate_help_prefix(self):
76
 
        error = errors.DuplicateHelpPrefix('foo')
77
 
        self.assertEqualDiff('The prefix foo is in the help search path twice.',
78
 
                             str(error))
79
 
 
80
 
    def test_ghost_revisions_have_no_revno(self):
81
 
        error = errors.GhostRevisionsHaveNoRevno('target', 'ghost_rev')
82
 
        self.assertEqualDiff("Could not determine revno for {target} because"
83
 
                             " its ancestry shows a ghost at {ghost_rev}",
84
 
                             str(error))
85
 
 
86
 
    def test_incompatibleVersion(self):
87
 
        error = errors.IncompatibleVersion("module", [(4, 5, 6), (7, 8, 9)],
88
 
                                           (1, 2, 3))
89
 
        self.assertEqualDiff(
90
 
            'API module is not compatible; one of versions '
91
 
            '[(4, 5, 6), (7, 8, 9)] is required, but current version is '
92
 
            '(1, 2, 3).',
93
 
            str(error))
94
 
 
95
 
    def test_inconsistent_delta(self):
96
 
        error = errors.InconsistentDelta('path', 'file-id', 'reason for foo')
97
 
        self.assertEqualDiff(
98
 
            "An inconsistent delta was supplied involving 'path', 'file-id'\n"
99
 
            "reason: reason for foo",
100
 
            str(error))
101
 
 
102
 
    def test_inconsistent_delta_delta(self):
103
 
        error = errors.InconsistentDeltaDelta([], 'reason')
104
 
        self.assertEqualDiff(
105
 
            "An inconsistent delta was supplied: []\nreason: reason",
106
 
            str(error))
107
 
 
108
 
    def test_in_process_transport(self):
109
 
        error = errors.InProcessTransport('fpp')
110
 
        self.assertEqualDiff(
111
 
            "The transport 'fpp' is only accessible within this process.",
112
 
            str(error))
113
 
 
114
 
    def test_invalid_http_range(self):
115
 
        error = errors.InvalidHttpRange('path',
116
 
                                        'Content-Range: potatoes 0-00/o0oo0',
117
 
                                        'bad range')
118
 
        self.assertEqual("Invalid http range"
119
 
                         " 'Content-Range: potatoes 0-00/o0oo0'"
120
 
                         " for path: bad range",
121
 
                         str(error))
122
 
 
123
 
    def test_invalid_range(self):
124
 
        error = errors.InvalidRange('path', 12, 'bad range')
125
 
        self.assertEqual("Invalid range access in path at 12: bad range",
126
 
                         str(error))
127
 
 
128
 
    def test_inventory_modified(self):
129
 
        error = errors.InventoryModified("a tree to be repred")
130
 
        self.assertEqualDiff("The current inventory for the tree 'a tree to "
131
 
                             "be repred' has been modified, so a clean inventory cannot be "
132
 
                             "read without data loss.",
133
 
                             str(error))
134
 
 
135
 
    def test_jail_break(self):
136
 
        error = errors.JailBreak("some url")
137
 
        self.assertEqualDiff("An attempt to access a url outside the server"
138
 
                             " jail was made: 'some url'.",
139
 
                             str(error))
140
 
 
141
 
    def test_lock_active(self):
142
 
        error = errors.LockActive("lock description")
143
 
        self.assertEqualDiff("The lock for 'lock description' is in use and "
144
 
                             "cannot be broken.",
145
 
                             str(error))
146
 
 
147
 
    def test_lock_corrupt(self):
148
 
        error = errors.LockCorrupt("corruption info")
149
 
        self.assertEqualDiff("Lock is apparently held, but corrupted: "
150
 
                             "corruption info\n"
151
 
                             "Use 'brz break-lock' to clear it",
152
 
                             str(error))
153
 
 
154
 
    def test_medium_not_connected(self):
155
 
        error = errors.MediumNotConnected("a medium")
156
 
        self.assertEqualDiff(
157
 
            "The medium 'a medium' is not connected.", str(error))
158
 
 
159
 
    def test_no_smart_medium(self):
160
 
        error = errors.NoSmartMedium("a transport")
161
 
        self.assertEqualDiff("The transport 'a transport' cannot tunnel the "
162
 
                             "smart protocol.",
163
 
                             str(error))
164
 
 
165
 
    def test_no_such_id(self):
166
 
        error = errors.NoSuchId("atree", "anid")
167
 
        self.assertEqualDiff("The file id \"anid\" is not present in the tree "
168
 
                             "atree.",
169
 
                             str(error))
170
 
 
171
 
    def test_no_such_revision_in_tree(self):
172
 
        error = errors.NoSuchRevisionInTree("atree", "anid")
173
 
        self.assertEqualDiff("The revision id {anid} is not present in the"
174
 
                             " tree atree.", str(error))
175
 
        self.assertIsInstance(error, errors.NoSuchRevision)
176
 
 
177
 
    def test_not_stacked(self):
178
 
        error = errors.NotStacked('a branch')
179
 
        self.assertEqualDiff("The branch 'a branch' is not stacked.",
180
 
                             str(error))
181
 
 
182
 
    def test_not_write_locked(self):
183
 
        error = errors.NotWriteLocked('a thing to repr')
184
 
        self.assertEqualDiff("'a thing to repr' is not write locked but needs "
185
 
                             "to be.",
186
 
                             str(error))
187
 
 
188
 
    def test_lock_failed(self):
189
 
        error = errors.LockFailed(
190
 
            'http://canonical.com/', 'readonly transport')
191
 
        self.assertEqualDiff("Cannot lock http://canonical.com/: readonly transport",
192
 
                             str(error))
193
 
        self.assertFalse(error.internal_error)
194
 
 
195
 
    def test_too_many_concurrent_requests(self):
196
 
        error = errors.TooManyConcurrentRequests("a medium")
197
 
        self.assertEqualDiff("The medium 'a medium' has reached its concurrent "
198
 
                             "request limit. Be sure to finish_writing and finish_reading on "
199
 
                             "the currently open request.",
200
 
                             str(error))
201
 
 
202
 
    def test_unavailable_representation(self):
203
 
        error = errors.UnavailableRepresentation(
204
 
            ('key',), "mpdiff", "fulltext")
205
 
        self.assertEqualDiff("The encoding 'mpdiff' is not available for key "
206
 
                             "('key',) which is encoded as 'fulltext'.",
207
 
                             str(error))
208
 
 
209
 
    def test_unstackable_location(self):
210
 
        error = errors.UnstackableLocationError('foo', 'bar')
211
 
        self.assertEqualDiff("The branch 'foo' cannot be stacked on 'bar'.",
212
 
                             str(error))
213
 
 
214
 
    def test_unstackable_repository_format(self):
215
 
        format = u'foo'
216
 
        url = "/foo"
217
 
        error = errors.UnstackableRepositoryFormat(format, url)
218
 
        self.assertEqualDiff(
219
 
            "The repository '/foo'(foo) is not a stackable format. "
220
 
            "You will need to upgrade the repository to permit branch stacking.",
221
 
            str(error))
222
 
 
223
 
    def test_up_to_date(self):
224
 
        error = errors.UpToDateFormat("someformat")
225
 
        self.assertEqualDiff(
226
 
            "The branch format someformat is already at the most "
227
 
            "recent format.", str(error))
228
 
 
229
 
    def test_read_error(self):
230
 
        # a unicode path to check that %r is being used.
231
 
        path = u'a path'
232
 
        error = errors.ReadError(path)
233
 
        self.assertContainsRe(str(error), "^Error reading from u?'a path'.$")
234
 
 
235
 
    def test_bzrerror_from_literal_string(self):
236
 
        # Some code constructs BzrError from a literal string, in which case
237
 
        # no further formatting is done.  (I'm not sure raising the base class
238
 
        # is a great idea, but if the exception is not intended to be caught
239
 
        # perhaps no more is needed.)
240
 
        try:
241
 
            raise errors.BzrError('this is my errors; %d is not expanded')
242
 
        except errors.BzrError as e:
243
 
            self.assertEqual('this is my errors; %d is not expanded', str(e))
244
 
 
245
 
    def test_reading_completed(self):
246
 
        error = errors.ReadingCompleted("a request")
247
 
        self.assertEqualDiff("The MediumRequest 'a request' has already had "
248
 
                             "finish_reading called upon it - the request has been completed and"
249
 
                             " no more data may be read.",
250
 
                             str(error))
251
 
 
252
 
    def test_writing_completed(self):
253
 
        error = errors.WritingCompleted("a request")
254
 
        self.assertEqualDiff("The MediumRequest 'a request' has already had "
255
 
                             "finish_writing called upon it - accept bytes may not be called "
256
 
                             "anymore.",
257
 
                             str(error))
258
 
 
259
 
    def test_writing_not_completed(self):
260
 
        error = errors.WritingNotComplete("a request")
261
 
        self.assertEqualDiff("The MediumRequest 'a request' has not has "
262
 
                             "finish_writing called upon it - until the write phase is complete"
263
 
                             " no data may be read.",
264
 
                             str(error))
265
 
 
266
 
    def test_transport_not_possible(self):
267
 
        error = errors.TransportNotPossible('readonly', 'original error')
268
 
        self.assertEqualDiff('Transport operation not possible:'
269
 
                             ' readonly original error', str(error))
270
 
 
271
 
    def assertSocketConnectionError(self, expected, *args, **kwargs):
272
 
        """Check the formatting of a SocketConnectionError exception"""
273
 
        e = errors.SocketConnectionError(*args, **kwargs)
274
 
        self.assertEqual(expected, str(e))
275
 
 
276
 
    def test_socket_connection_error(self):
277
 
        """Test the formatting of SocketConnectionError"""
278
 
 
279
 
        # There should be a default msg about failing to connect
280
 
        # we only require a host name.
281
 
        self.assertSocketConnectionError(
282
 
            'Failed to connect to ahost',
283
 
            'ahost')
284
 
 
285
 
        # If port is None, we don't put :None
286
 
        self.assertSocketConnectionError(
287
 
            'Failed to connect to ahost',
288
 
            'ahost', port=None)
289
 
        # But if port is supplied we include it
290
 
        self.assertSocketConnectionError(
291
 
            'Failed to connect to ahost:22',
292
 
            'ahost', port=22)
293
 
 
294
 
        # We can also supply extra information about the error
295
 
        # with or without a port
296
 
        self.assertSocketConnectionError(
297
 
            'Failed to connect to ahost:22; bogus error',
298
 
            'ahost', port=22, orig_error='bogus error')
299
 
        self.assertSocketConnectionError(
300
 
            'Failed to connect to ahost; bogus error',
301
 
            'ahost', orig_error='bogus error')
302
 
        # An exception object can be passed rather than a string
303
 
        orig_error = ValueError('bad value')
304
 
        self.assertSocketConnectionError(
305
 
            'Failed to connect to ahost; %s' % (str(orig_error),),
306
 
            host='ahost', orig_error=orig_error)
307
 
 
308
 
        # And we can supply a custom failure message
309
 
        self.assertSocketConnectionError(
310
 
            'Unable to connect to ssh host ahost:444; my_error',
311
 
            host='ahost', port=444, msg='Unable to connect to ssh host',
312
 
            orig_error='my_error')
313
 
 
314
 
    def test_target_not_branch(self):
315
 
        """Test the formatting of TargetNotBranch."""
316
 
        error = errors.TargetNotBranch('foo')
317
 
        self.assertEqual(
318
 
            "Your branch does not have all of the revisions required in "
319
 
            "order to merge this merge directive and the target "
320
 
            "location specified in the merge directive is not a branch: "
321
 
            "foo.", str(error))
322
 
 
323
 
    def test_unexpected_smart_server_response(self):
324
 
        e = errors.UnexpectedSmartServerResponse(('not yes',))
325
 
        self.assertEqual(
326
 
            "Could not understand response from smart server: ('not yes',)",
327
 
            str(e))
328
 
 
329
 
    def test_unknown_container_format(self):
330
 
        """Test the formatting of UnknownContainerFormatError."""
331
 
        e = errors.UnknownContainerFormatError('bad format string')
332
 
        self.assertEqual(
333
 
            "Unrecognised container format: 'bad format string'",
334
 
            str(e))
335
 
 
336
 
    def test_unexpected_end_of_container(self):
337
 
        """Test the formatting of UnexpectedEndOfContainerError."""
338
 
        e = errors.UnexpectedEndOfContainerError()
339
 
        self.assertEqual(
340
 
            "Unexpected end of container stream", str(e))
341
 
 
342
 
    def test_unknown_record_type(self):
343
 
        """Test the formatting of UnknownRecordTypeError."""
344
 
        e = errors.UnknownRecordTypeError("X")
345
 
        self.assertEqual(
346
 
            "Unknown record type: 'X'",
347
 
            str(e))
348
 
 
349
 
    def test_invalid_record(self):
350
 
        """Test the formatting of InvalidRecordError."""
351
 
        e = errors.InvalidRecordError("xxx")
352
 
        self.assertEqual(
353
 
            "Invalid record: xxx",
354
 
            str(e))
355
 
 
356
 
    def test_container_has_excess_data(self):
357
 
        """Test the formatting of ContainerHasExcessDataError."""
358
 
        e = errors.ContainerHasExcessDataError("excess bytes")
359
 
        self.assertEqual(
360
 
            "Container has data after end marker: 'excess bytes'",
361
 
            str(e))
362
 
 
363
 
    def test_duplicate_record_name_error(self):
364
 
        """Test the formatting of DuplicateRecordNameError."""
365
 
        e = errors.DuplicateRecordNameError(b"n\xc3\xa5me")
366
 
        self.assertEqual(
367
 
            u"Container has multiple records with the same name: n\xe5me",
368
 
            text_type(e))
369
 
 
370
 
    def test_check_error(self):
371
 
        e = errors.BzrCheckError('example check failure')
372
 
        self.assertEqual(
373
 
            "Internal check failed: example check failure",
374
 
            str(e))
375
 
        self.assertTrue(e.internal_error)
376
 
 
377
 
    def test_repository_data_stream_error(self):
378
 
        """Test the formatting of RepositoryDataStreamError."""
379
 
        e = errors.RepositoryDataStreamError(u"my reason")
380
 
        self.assertEqual(
381
 
            "Corrupt or incompatible data stream: my reason", str(e))
382
 
 
383
 
    def test_immortal_pending_deletion_message(self):
384
 
        err = errors.ImmortalPendingDeletion('foo')
385
 
        self.assertEqual(
386
 
            "Unable to delete transform temporary directory foo.  "
387
 
            "Please examine foo to see if it contains any files "
388
 
            "you wish to keep, and delete it when you are done.",
389
 
            str(err))
390
 
 
391
 
    def test_invalid_url_join(self):
392
 
        """Test the formatting of InvalidURLJoin."""
393
 
        e = urlutils.InvalidURLJoin('Reason', 'base path', ('args',))
394
 
        self.assertEqual(
395
 
            "Invalid URL join request: Reason: 'base path' + ('args',)",
396
 
            str(e))
397
 
 
398
 
    def test_unable_encode_path(self):
399
 
        err = errors.UnableEncodePath('foo', 'executable')
400
 
        self.assertEqual("Unable to encode executable path 'foo' in "
401
 
                         "user encoding " + osutils.get_user_encoding(),
402
 
                         str(err))
403
 
 
404
 
    def test_unknown_format(self):
405
 
        err = errors.UnknownFormatError('bar', kind='foo')
406
 
        self.assertEqual("Unknown foo format: 'bar'", str(err))
407
 
 
408
 
    def test_tip_change_rejected(self):
409
 
        err = errors.TipChangeRejected(u'Unicode message\N{INTERROBANG}')
410
 
        self.assertEqual(
411
 
            u'Tip change rejected: Unicode message\N{INTERROBANG}',
412
 
            text_type(err))
413
 
 
414
 
    def test_error_from_smart_server(self):
415
 
        error_tuple = ('error', 'tuple')
416
 
        err = errors.ErrorFromSmartServer(error_tuple)
417
 
        self.assertEqual(
418
 
            "Error received from smart server: ('error', 'tuple')", str(err))
419
 
 
420
 
    def test_untranslateable_error_from_smart_server(self):
421
 
        error_tuple = ('error', 'tuple')
422
 
        orig_err = errors.ErrorFromSmartServer(error_tuple)
423
 
        err = errors.UnknownErrorFromSmartServer(orig_err)
424
 
        self.assertEqual(
425
 
            "Server sent an unexpected error: ('error', 'tuple')", str(err))
426
 
 
427
 
    def test_smart_message_handler_error(self):
428
 
        # Make an exc_info tuple.
429
 
        try:
430
 
            raise Exception("example error")
431
 
        except Exception:
432
 
            err = errors.SmartMessageHandlerError(sys.exc_info())
433
 
        # GZ 2010-11-08: Should not store exc_info in exception instances.
434
 
        try:
435
 
            self.assertStartsWith(
436
 
                str(err), "The message handler raised an exception:\n")
437
 
            self.assertEndsWith(str(err), "Exception: example error\n")
438
 
        finally:
439
 
            del err
440
 
 
441
 
    def test_unresumable_write_group(self):
442
 
        repo = "dummy repo"
443
 
        wg_tokens = ['token']
444
 
        reason = "a reason"
445
 
        err = errors.UnresumableWriteGroup(repo, wg_tokens, reason)
446
 
        self.assertEqual(
447
 
            "Repository dummy repo cannot resume write group "
448
 
            "['token']: a reason", str(err))
449
 
 
450
 
    def test_unsuspendable_write_group(self):
451
 
        repo = "dummy repo"
452
 
        err = errors.UnsuspendableWriteGroup(repo)
453
 
        self.assertEqual(
454
 
            'Repository dummy repo cannot suspend a write group.', str(err))
455
 
 
456
 
    def test_not_branch_no_args(self):
457
 
        err = errors.NotBranchError('path')
458
 
        self.assertEqual('Not a branch: "path".', str(err))
459
 
 
460
 
    def test_not_branch_bzrdir_with_recursive_not_branch_error(self):
461
 
        class FakeBzrDir(object):
462
 
            def open_repository(self):
463
 
                # str() on the NotBranchError will trigger a call to this,
464
 
                # which in turn will another, identical NotBranchError.
465
 
                raise errors.NotBranchError('path', controldir=FakeBzrDir())
466
 
        err = errors.NotBranchError('path', controldir=FakeBzrDir())
467
 
        self.assertEqual('Not a branch: "path": NotBranchError.', str(err))
468
 
 
469
 
    def test_recursive_bind(self):
470
 
        error = errors.RecursiveBind('foo_bar_branch')
471
 
        msg = ('Branch "foo_bar_branch" appears to be bound to itself. '
472
 
               'Please use `brz unbind` to fix.')
473
 
        self.assertEqualDiff(msg, str(error))
474
 
 
475
 
    def test_retry_with_new_packs(self):
476
 
        fake_exc_info = ('{exc type}', '{exc value}', '{exc traceback}')
477
 
        error = errors.RetryWithNewPacks(
478
 
            '{context}', reload_occurred=False, exc_info=fake_exc_info)
479
 
        self.assertEqual(
480
 
            'Pack files have changed, reload and retry. context: '
481
 
            '{context} {exc value}', str(error))
482
 
 
483
 
 
484
 
class PassThroughError(errors.BzrError):
485
 
 
486
 
    _fmt = """Pass through %(foo)s and %(bar)s"""
487
 
 
488
 
    def __init__(self, foo, bar):
489
 
        errors.BzrError.__init__(self, foo=foo, bar=bar)
490
 
 
491
 
 
492
 
class ErrorWithBadFormat(errors.BzrError):
493
 
 
494
 
    _fmt = """One format specifier: %(thing)s"""
495
 
 
496
 
 
497
 
class ErrorWithNoFormat(errors.BzrError):
498
 
    __doc__ = """This class has a docstring but no format string."""
499
 
 
500
 
 
501
 
class TestErrorFormatting(tests.TestCase):
502
 
 
503
 
    def test_always_str(self):
504
 
        e = PassThroughError(u'\xb5', 'bar')
505
 
        self.assertIsInstance(e.__str__(), str)
506
 
        # In Python 2 str(foo) *must* return a real byte string
507
 
        # not a Unicode string. The following line would raise a
508
 
        # Unicode error, because it tries to call str() on the string
509
 
        # returned from e.__str__(), and it has non ascii characters
510
 
        s = str(e)
511
 
        if PY3:
512
 
            self.assertEqual('Pass through \xb5 and bar', s)
513
 
        else:
514
 
            self.assertEqual('Pass through \xc2\xb5 and bar', s)
515
 
 
516
 
    def test_missing_format_string(self):
517
 
        e = ErrorWithNoFormat(param='randomvalue')
518
 
        self.assertStartsWith(str(e),
519
 
                              "Unprintable exception ErrorWithNoFormat")
520
 
 
521
 
    def test_mismatched_format_args(self):
522
 
        # Even though ErrorWithBadFormat's format string does not match the
523
 
        # arguments we constructing it with, we can still stringify an instance
524
 
        # of this exception. The resulting string will say its unprintable.
525
 
        e = ErrorWithBadFormat(not_thing='x')
526
 
        self.assertStartsWith(
527
 
            str(e), 'Unprintable exception ErrorWithBadFormat')
528
 
 
529
 
    def test_cannot_bind_address(self):
530
 
        # see <https://bugs.launchpad.net/bzr/+bug/286871>
531
 
        e = errors.CannotBindAddress('example.com', 22,
532
 
                                     socket.error(13, 'Permission denied'))
533
 
        self.assertContainsRe(
534
 
            str(e),
535
 
            r'Cannot bind address "example\.com:22":.*Permission denied')
536
 
 
537
 
    def test_transform_rename_failed(self):
538
 
        e = errors.TransformRenameFailed(u"from", u"to", "readonly file", 2)
539
 
        self.assertEqual(
540
 
            u"Failed to rename from to to: readonly file",
541
 
            str(e))
542
 
 
543
 
 
544
 
class TestErrorsUsingTransport(tests.TestCaseWithMemoryTransport):
545
 
    """Tests for errors that need to use a branch or repo."""
546
 
 
547
 
    def test_no_public_branch(self):
548
 
        b = self.make_branch('.')
549
 
        error = errors.NoPublicBranch(b)
550
 
        url = urlutils.unescape_for_display(b.base, 'ascii')
551
 
        self.assertEqualDiff(
552
 
            'There is no public branch set for "%s".' % url, str(error))
 
20
import bzrlib.bzrdir as bzrdir
 
21
import bzrlib.errors as errors
 
22
from bzrlib.tests import TestCaseWithTransport
 
23
 
 
24
 
 
25
class TestErrors(TestCaseWithTransport):
553
26
 
554
27
    def test_no_repo(self):
555
 
        dir = controldir.ControlDir.create(self.get_url())
 
28
        dir = bzrdir.BzrDir.create(self.get_url())
556
29
        error = errors.NoRepositoryPresent(dir)
557
 
        self.assertNotEqual(-1,
558
 
                            str(error).find((dir.transport.clone('..').base)))
559
 
        self.assertEqual(-1, str(error).find((dir.transport.base)))
 
30
        self.assertNotEqual(-1, str(error).find(repr(dir.transport.clone('..').base)))
 
31
        self.assertEqual(-1, str(error).find(repr(dir.transport.base)))
 
32
 
 
33
    def test_up_to_date(self):
 
34
        error = errors.UpToDateFormat(bzrdir.BzrDirFormat4())
 
35
        self.assertEqualDiff("The branch format Bazaar-NG branch, "
 
36
                             "format 0.0.4 is already at the most "
 
37
                             "recent format.",
 
38
                             str(error))
560
39
 
561
40
    def test_corrupt_repository(self):
562
41
        repo = self.make_repository('.')
563
42
        error = errors.CorruptRepository(repo)
564
43
        self.assertEqualDiff("An error has been detected in the repository %s.\n"
565
 
                             "Please run brz reconcile on this repository." %
566
 
                             repo.controldir.root_transport.base,
 
44
                             "Please run bzr reconcile on this repository." %
 
45
                             repo.bzrdir.root_transport.base,
567
46
                             str(error))
568
 
 
569
 
    def test_not_branch_bzrdir_with_repo(self):
570
 
        controldir = self.make_repository('repo').controldir
571
 
        err = errors.NotBranchError('path', controldir=controldir)
572
 
        self.assertEqual(
573
 
            'Not a branch: "path": location is a repository.', str(err))
574
 
 
575
 
    def test_not_branch_bzrdir_without_repo(self):
576
 
        controldir = self.make_controldir('bzrdir')
577
 
        err = errors.NotBranchError('path', controldir=controldir)
578
 
        self.assertEqual('Not a branch: "path".', str(err))
579
 
 
580
 
    def test_not_branch_laziness(self):
581
 
        real_bzrdir = self.make_controldir('path')
582
 
 
583
 
        class FakeBzrDir(object):
584
 
            def __init__(self):
585
 
                self.calls = []
586
 
 
587
 
            def open_repository(self):
588
 
                self.calls.append('open_repository')
589
 
                raise errors.NoRepositoryPresent(real_bzrdir)
590
 
        fake_bzrdir = FakeBzrDir()
591
 
        err = errors.NotBranchError('path', controldir=fake_bzrdir)
592
 
        self.assertEqual([], fake_bzrdir.calls)
593
 
        str(err)
594
 
        self.assertEqual(['open_repository'], fake_bzrdir.calls)
595
 
        # Stringifying twice doesn't try to open a repository twice.
596
 
        str(err)
597
 
        self.assertEqual(['open_repository'], fake_bzrdir.calls)