13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
"""Tests for the smart wire/domain protocol.
70
73
"TestSmartServerRequestFindRepository")
71
74
v2_only, v1_and_2 = split_suite_by_re(to_adapt,
73
tests.multiply_tests(v1_and_2, scenarios, result)
74
# The first scenario is only applicable to v1 protocols, it is deleted
76
tests.multiply_tests(v2_only, scenarios[1:], result)
76
for test in iter_suite_tests(v1_and_2):
77
result.addTests(applier.adapt(test))
78
del applier.scenarios[0]
79
for test in iter_suite_tests(v2_only):
80
result.addTests(applier.adapt(test))
173
177
expected = SuccessfulSmartServerResponse(
174
178
(local_result.network_name(),
175
179
local_result.repository_format.network_name(),
176
('branch', local_result.get_branch_format().network_name())))
180
('direct', local_result.get_branch_format().network_name())))
177
181
self.assertEqual(expected, request.execute('', 'False'))
179
183
def test_cloning_metadir_reference(self):
180
"""The request fails when bzrdir contains a branch reference."""
184
"""The request works when bzrdir contains a branch reference."""
181
185
backing = self.get_transport()
182
186
referenced_branch = self.make_branch('referenced')
183
187
dir = self.make_bzrdir('.')
189
193
backing.rename('referenced', 'moved')
190
194
request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
191
195
request = request_class(backing)
192
expected = FailedSmartServerResponse(('BranchReference',))
196
expected = SuccessfulSmartServerResponse(
197
(local_result.network_name(),
198
local_result.repository_format.network_name(),
199
('reference', reference_url)))
193
200
self.assertEqual(expected, request.execute('', 'False'))
357
364
request.execute('reference'))
360
class TestSmartServerRequestOpenBranchV2(TestCaseWithChrootedTransport):
362
def test_no_branch(self):
363
"""When there is no branch, ('nobranch', ) is returned."""
364
backing = self.get_transport()
365
self.make_bzrdir('.')
366
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
367
self.assertEqual(SmartServerResponse(('nobranch', )),
370
def test_branch(self):
371
"""When there is a branch, 'ok' is returned."""
372
backing = self.get_transport()
373
expected = self.make_branch('.')._format.network_name()
374
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
375
self.assertEqual(SuccessfulSmartServerResponse(('branch', expected)),
378
def test_branch_reference(self):
379
"""When there is a branch reference, the reference URL is returned."""
380
backing = self.get_transport()
381
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
382
branch = self.make_branch('branch')
383
checkout = branch.create_checkout('reference',lightweight=True)
384
reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
385
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
386
self.assertEqual(SuccessfulSmartServerResponse(('ref', reference_url)),
387
request.execute('reference'))
389
def test_stacked_branch(self):
390
"""Opening a stacked branch does not open the stacked-on branch."""
391
trunk = self.make_branch('trunk')
392
feature = self.make_branch('feature', format='1.9')
393
feature.set_stacked_on_url(trunk.base)
395
Branch.hooks.install_named_hook('open', opened_branches.append, None)
396
backing = self.get_transport()
397
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
400
response = request.execute('feature')
402
request.teardown_jail()
403
expected_format = feature._format.network_name()
405
SuccessfulSmartServerResponse(('branch', expected_format)),
407
self.assertLength(1, opened_branches)
410
367
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
412
369
def test_empty(self):
502
459
request.execute(''))
505
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
507
def get_lock_tokens(self, branch):
508
branch_token = branch.lock_write()
509
repo_token = branch.repository.lock_write()
510
branch.repository.unlock()
511
return branch_token, repo_token
514
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
516
def test_value_name(self):
517
branch = self.make_branch('.')
518
request = smart.branch.SmartServerBranchRequestSetConfigOption(
519
branch.bzrdir.root_transport)
520
branch_token, repo_token = self.get_lock_tokens(branch)
521
config = branch._get_config()
522
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
524
self.assertEqual(SuccessfulSmartServerResponse(()), result)
525
self.assertEqual('bar', config.get_option('foo'))
527
def test_value_name_section(self):
528
branch = self.make_branch('.')
529
request = smart.branch.SmartServerBranchRequestSetConfigOption(
530
branch.bzrdir.root_transport)
531
branch_token, repo_token = self.get_lock_tokens(branch)
532
config = branch._get_config()
533
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
535
self.assertEqual(SuccessfulSmartServerResponse(()), result)
536
self.assertEqual('bar', config.get_option('foo', 'gam'))
539
class SetLastRevisionTestBase(TestLockedBranch):
462
class SetLastRevisionTestBase(tests.TestCaseWithMemoryTransport):
540
463
"""Base test case for verbs that implement set_last_revision."""
546
469
self.tree = self.make_branch_and_memory_tree('.')
548
471
def lock_branch(self):
549
return self.get_lock_tokens(self.tree.branch)
473
branch_token = b.lock_write()
474
repo_token = b.repository.lock_write()
475
b.repository.unlock()
476
return branch_token, repo_token
551
478
def unlock_branch(self):
552
479
self.tree.branch.unlock()
772
class TestSmartServerBranchRequestGetTagsBytes(tests.TestCaseWithMemoryTransport):
773
# Only called when the branch format and tags match [yay factory
774
# methods] so only need to test straight forward cases.
776
def test_get_bytes(self):
777
base_branch = self.make_branch('base')
778
request = smart.branch.SmartServerBranchGetTagsBytes(
779
self.get_transport())
780
response = request.execute('base')
782
SuccessfulSmartServerResponse(('',)), response)
785
699
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
787
701
def test_get_stacked_on_url(self):
962
876
self.assertEqual(None,
963
877
request.execute('', 'missing-id'))
964
# Note that it returns a body that is bzipped.
878
# Note that it returns a body (of '' bzipped).
965
879
self.assertEqual(
966
880
SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
967
881
request.do_body('\n\n0\n'))
969
def test_trivial_include_missing(self):
970
backing = self.get_transport()
971
request = smart.repository.SmartServerRepositoryGetParentMap(backing)
972
tree = self.make_branch_and_memory_tree('.')
974
self.assertEqual(None,
975
request.execute('', 'missing-id', 'include-missing:'))
977
SuccessfulSmartServerResponse(('ok', ),
978
bz2.compress('missing:missing-id')),
979
request.do_body('\n\n0\n'))
982
884
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithMemoryTransport):
1029
931
request.execute('', 'missingrevision'))
1032
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
1034
def make_two_commit_repo(self):
1035
tree = self.make_branch_and_memory_tree('.')
1038
r1 = tree.commit('1st commit')
1039
r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
1041
repo = tree.branch.repository
1044
def test_ancestry_of(self):
1045
"""The search argument may be a 'ancestry-of' some heads'."""
1046
backing = self.get_transport()
1047
request = smart.repository.SmartServerRepositoryGetStream(backing)
1048
repo, r1, r2 = self.make_two_commit_repo()
1049
fetch_spec = ['ancestry-of', r2]
1050
lines = '\n'.join(fetch_spec)
1051
request.execute('', repo._format.network_name())
1052
response = request.do_body(lines)
1053
self.assertEqual(('ok',), response.args)
1054
stream_bytes = ''.join(response.body_stream)
1055
self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1057
def test_search(self):
1058
"""The search argument may be a 'search' of some explicit keys."""
1059
backing = self.get_transport()
1060
request = smart.repository.SmartServerRepositoryGetStream(backing)
1061
repo, r1, r2 = self.make_two_commit_repo()
1062
fetch_spec = ['search', '%s %s' % (r1, r2), 'null:', '2']
1063
lines = '\n'.join(fetch_spec)
1064
request.execute('', repo._format.network_name())
1065
response = request.do_body(lines)
1066
self.assertEqual(('ok',), response.args)
1067
stream_bytes = ''.join(response.body_stream)
1068
self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1071
934
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1073
936
def test_missing_revision(self):
1205
1071
self.assertEqual('LockFailed', response.args[0])
1208
class TestInsertStreamBase(tests.TestCaseWithMemoryTransport):
1210
def make_empty_byte_stream(self, repo):
1211
byte_stream = smart.repository._stream_to_byte_stream([], repo._format)
1212
return ''.join(byte_stream)
1215
class TestSmartServerRepositoryInsertStream(TestInsertStreamBase):
1217
def test_insert_stream_empty(self):
1218
backing = self.get_transport()
1219
request = smart.repository.SmartServerRepositoryInsertStream(backing)
1220
repository = self.make_repository('.')
1221
response = request.execute('', '')
1222
self.assertEqual(None, response)
1223
response = request.do_chunk(self.make_empty_byte_stream(repository))
1224
self.assertEqual(None, response)
1225
response = request.do_end()
1226
self.assertEqual(SmartServerResponse(('ok', )), response)
1229
class TestSmartServerRepositoryInsertStreamLocked(TestInsertStreamBase):
1231
def test_insert_stream_empty(self):
1232
backing = self.get_transport()
1233
request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1235
repository = self.make_repository('.', format='knit')
1236
lock_token = repository.lock_write()
1237
response = request.execute('', '', lock_token)
1238
self.assertEqual(None, response)
1239
response = request.do_chunk(self.make_empty_byte_stream(repository))
1240
self.assertEqual(None, response)
1241
response = request.do_end()
1242
self.assertEqual(SmartServerResponse(('ok', )), response)
1245
def test_insert_stream_with_wrong_lock_token(self):
1246
backing = self.get_transport()
1247
request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1249
repository = self.make_repository('.', format='knit')
1250
lock_token = repository.lock_write()
1252
errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1256
1074
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
1258
1076
def setUp(self):
1354
1170
def test_autopack_not_needed(self):
1355
1171
tree = self.make_branch_and_tree('.', format='pack-0.92')
1356
1172
repo = tree.branch.repository
1358
self.addCleanup(repo.unlock)
1359
1173
for x in range(9):
1360
1174
tree.commit('commit %s' % x)
1361
1175
backing = self.get_transport()
1395
1209
smart.request.request_handlers.get('Branch.get_parent'),
1396
1210
smart.branch.SmartServerBranchGetParent)
1397
1211
self.assertEqual(
1398
smart.request.request_handlers.get('Branch.get_tags_bytes'),
1399
smart.branch.SmartServerBranchGetTagsBytes)
1401
1212
smart.request.request_handlers.get('Branch.lock_write'),
1402
1213
smart.branch.SmartServerBranchRequestLockWrite)
1403
1214
self.assertEqual(
1407
1218
smart.request.request_handlers.get('Branch.revision_history'),
1408
1219
smart.branch.SmartServerRequestRevisionHistory)
1409
1220
self.assertEqual(
1410
smart.request.request_handlers.get('Branch.set_config_option'),
1411
smart.branch.SmartServerBranchRequestSetConfigOption)
1413
1221
smart.request.request_handlers.get('Branch.set_last_revision'),
1414
1222
smart.branch.SmartServerBranchRequestSetLastRevision)
1415
1223
self.assertEqual(
1434
1242
smart.request.request_handlers.get('BzrDir.open_branch'),
1435
1243
smart.bzrdir.SmartServerRequestOpenBranch)
1436
1244
self.assertEqual(
1437
smart.request.request_handlers.get('BzrDir.open_branchV2'),
1438
smart.bzrdir.SmartServerRequestOpenBranchV2)
1440
1245
smart.request.request_handlers.get('PackRepository.autopack'),
1441
1246
smart.packrepository.SmartServerPackRepositoryAutopack)
1442
1247
self.assertEqual(
1450
1255
'Repository.get_revision_graph'),
1451
1256
smart.repository.SmartServerRepositoryGetRevisionGraph)
1452
1257
self.assertEqual(
1453
smart.request.request_handlers.get('Repository.get_stream'),
1454
smart.repository.SmartServerRepositoryGetStream)
1456
1258
smart.request.request_handlers.get('Repository.has_revision'),
1457
1259
smart.repository.SmartServerRequestHasRevision)
1458
1260
self.assertEqual(
1459
smart.request.request_handlers.get('Repository.insert_stream'),
1460
smart.repository.SmartServerRepositoryInsertStream)
1462
smart.request.request_handlers.get('Repository.insert_stream_locked'),
1463
smart.repository.SmartServerRepositoryInsertStreamLocked)
1465
1261
smart.request.request_handlers.get('Repository.is_shared'),
1466
1262
smart.repository.SmartServerRepositoryIsShared)
1467
1263
self.assertEqual(
1468
1264
smart.request.request_handlers.get('Repository.lock_write'),
1469
1265
smart.repository.SmartServerRepositoryLockWrite)
1470
1266
self.assertEqual(
1267
smart.request.request_handlers.get('Repository.get_stream'),
1268
smart.repository.SmartServerRepositoryGetStream)
1471
1270
smart.request.request_handlers.get('Repository.tarball'),
1472
1271
smart.repository.SmartServerRepositoryTarball)
1473
1272
self.assertEqual(