1188
1188
src_repo.copy_content_into(dest_repo)
1191
class TestErrorTranslation(tests.TestCaseWithMemoryTransport):
1191
class TestErrorTranslationBase(tests.TestCaseWithMemoryTransport):
1192
"""Base class for unit tests for bzrlib.remote._translate_error."""
1194
def translateTuple(self, error_tuple, **context):
1195
"""Call _translate_error with an ErrorFromSmartServer built from the
1198
:param error_tuple: A tuple of a smart server response, as would be
1199
passed to an ErrorFromSmartServer.
1200
:kwargs context: context items to call _translate_error with.
1202
:returns: The error raised by _translate_error.
1204
# Raise the ErrorFromSmartServer before passing it as an argument,
1205
# because _translate_error may need to re-raise it with a bare 'raise'
1207
server_error = errors.ErrorFromSmartServer(error_tuple)
1208
translated_error = self.translateErrorFromSmartServer(
1209
server_error, **context)
1210
return translated_error
1212
def translateErrorFromSmartServer(self, error_object, **context):
1213
"""Like translateTuple, but takes an already constructed
1214
ErrorFromSmartServer rather than a tuple.
1218
except errors.ErrorFromSmartServer, server_error:
1219
translated_error = self.assertRaises(
1220
errors.BzrError, remote._translate_error, server_error,
1222
return translated_error
1225
class TestErrorTranslationSuccess(TestErrorTranslationBase):
1192
1226
"""Unit tests for bzrlib.remote._translate_error.
1194
1228
Given an ErrorFromSmartServer (which has an error tuple from a smart
1195
1229
server) and some context, _translate_error raises more specific errors from
1232
This test case covers the cases where _translate_error succeeds in
1233
translating an ErrorFromSmartServer to something better. See
1234
TestErrorTranslationRobustness for other cases.
1199
def translateError(self, error_tuple, **context):
1200
server_error = errors.ErrorFromSmartServer(error_tuple)
1201
exc = self.assertRaises(
1202
errors.BzrError, remote._translate_error, server_error, **context)
1205
1237
def test_NoSuchRevision(self):
1206
1238
branch = self.make_branch('')
1207
1239
revid = 'revid'
1208
translated_error = self.translateError(
1240
translated_error = self.translateTuple(
1209
1241
('NoSuchRevision', revid), branch=branch)
1210
1242
expected_error = errors.NoSuchRevision(branch, revid)
1211
1243
self.assertEqual(expected_error, translated_error)
1213
1245
def test_nosuchrevision(self):
1214
1246
repository = self.make_repository('')
1215
1247
revid = 'revid'
1216
translated_error = self.translateError(
1248
translated_error = self.translateTuple(
1217
1249
('nosuchrevision', revid), repository=repository)
1218
1250
expected_error = errors.NoSuchRevision(repository, revid)
1219
1251
self.assertEqual(expected_error, translated_error)
1221
1253
def test_nobranch(self):
1222
1254
bzrdir = self.make_bzrdir('')
1223
translated_error = self.translateError(('nobranch',), bzrdir=bzrdir)
1255
translated_error = self.translateTuple(('nobranch',), bzrdir=bzrdir)
1224
1256
expected_error = errors.NotBranchError(path=bzrdir.root_transport.base)
1225
1257
self.assertEqual(expected_error, translated_error)
1227
1259
def test_LockContention(self):
1228
translated_error = self.translateError(('LockContention',))
1260
translated_error = self.translateTuple(('LockContention',))
1229
1261
expected_error = errors.LockContention('(remote lock)')
1230
1262
self.assertEqual(expected_error, translated_error)
1232
1264
def test_UnlockableTransport(self):
1233
1265
bzrdir = self.make_bzrdir('')
1234
translated_error = self.translateError(
1266
translated_error = self.translateTuple(
1235
1267
('UnlockableTransport',), bzrdir=bzrdir)
1236
1268
expected_error = errors.UnlockableTransport(bzrdir.root_transport)
1237
1269
self.assertEqual(expected_error, translated_error)
1239
1271
def test_LockFailed(self):
1240
1272
lock = 'str() of a server lock'
1241
1273
why = 'str() of why'
1242
translated_error = self.translateError(('LockFailed', lock, why))
1274
translated_error = self.translateTuple(('LockFailed', lock, why))
1243
1275
expected_error = errors.LockFailed(lock, why)
1244
1276
self.assertEqual(expected_error, translated_error)
1246
1278
def test_TokenMismatch(self):
1247
1279
token = 'a lock token'
1248
translated_error = self.translateError(('TokenMismatch',), token=token)
1280
translated_error = self.translateTuple(('TokenMismatch',), token=token)
1249
1281
expected_error = errors.TokenMismatch(token, '(remote token)')
1250
1282
self.assertEqual(expected_error, translated_error)
1252
1284
def test_Diverged(self):
1253
1285
branch = self.make_branch('a')
1254
1286
other_branch = self.make_branch('b')
1255
translated_error = self.translateError(
1287
translated_error = self.translateTuple(
1256
1288
('Diverged',), branch=branch, other_branch=other_branch)
1257
1289
expected_error = errors.DivergedBranches(branch, other_branch)
1258
1290
self.assertEqual(expected_error, translated_error)
1293
class TestErrorTranslationRobustness(TestErrorTranslationBase):
1294
"""Unit tests for bzrlib.remote._translate_error's robustness.
1296
TestErrorTranslationSuccess is for cases where _translate_error can
1297
translate successfully. This class about how _translate_err behaves when
1298
it fails to translate: it re-raises the original error.
1301
def test_unrecognised_server_error(self):
1302
"""If the error code from the server is not recognised, the original
1303
ErrorFromSmartServer is propagated unmodified.
1305
error_tuple = ('An unknown error tuple',)
1306
server_error = errors.ErrorFromSmartServer(error_tuple)
1307
translated_error = self.translateErrorFromSmartServer(server_error)
1308
self.assertEqual(server_error, translated_error)
1310
def test_context_missing_a_key(self):
1311
"""In case of a bug in the client, or perhaps an unexpected response
1312
from a server, _translate_error returns the original error tuple from
1313
the server and mutters a warning.
1315
# To translate a NoSuchRevision error _translate_error needs a 'branch'
1316
# in the context dict. So let's give it an empty context dict instead
1317
# to exercise its error recovery.
1319
error_tuple = ('NoSuchRevision', 'revid')
1320
server_error = errors.ErrorFromSmartServer(error_tuple)
1321
translated_error = self.translateErrorFromSmartServer(server_error)
1322
self.assertEqual(server_error, translated_error)
1323
# In addition to re-raising ErrorFromSmartServer, some debug info has
1324
# been muttered to the log file for developer to look at.
1325
self.assertContainsRe(
1326
self._get_log(keep_log_file=True),
1327
"Missing key 'branch' in context")