/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 breezy/tests/test_smart.py

  • Committer: Jelmer Vernooij
  • Date: 2020-05-06 02:13:25 UTC
  • mfrom: (7490.7.21 work)
  • mto: This revision was merged to the branch mainline in revision 7501.
  • Revision ID: jelmer@jelmer.uk-20200506021325-awbmmqu1zyorz7sj
Merge 3.1 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
"""
26
26
 
27
27
import bz2
 
28
from io import BytesIO
 
29
import tarfile
28
30
import zlib
29
31
 
30
32
from breezy import (
51
53
    server,
52
54
    vfs,
53
55
    )
54
 
from breezy.testament import Testament
 
56
from breezy.bzr.testament import Testament
55
57
from breezy.tests import test_server
56
58
from breezy.transport import (
57
59
    chroot,
70
72
        ("find_repositoryV3", {
71
73
            "_request_class": smart_dir.SmartServerRequestFindRepositoryV3}),
72
74
        ]
73
 
    to_adapt, result = tests.split_suite_by_re(standard_tests,
74
 
        "TestSmartServerRequestFindRepository")
75
 
    v2_only, v1_and_2 = tests.split_suite_by_re(to_adapt,
76
 
        "_v2")
 
75
    to_adapt, result = tests.split_suite_by_re(
 
76
        standard_tests, "TestSmartServerRequestFindRepository")
 
77
    v2_only, v1_and_2 = tests.split_suite_by_re(to_adapt, "_v2")
77
78
    tests.multiply_tests(v1_and_2, scenarios, result)
78
79
    # The first scenario is only applicable to v1 protocols, it is deleted
79
80
    # since.
121
122
 
122
123
    def test_repeated_substreams_same_kind_are_one_stream(self):
123
124
        # Make a stream - an iterable of bytestrings.
124
 
        stream = [('text', [versionedfile.FulltextContentFactory(('k1',), None,
125
 
            None, 'foo')]), ('text', [
126
 
            versionedfile.FulltextContentFactory(('k2',), None, None, 'bar')])]
 
125
        stream = [
 
126
            ('text', [versionedfile.FulltextContentFactory((b'k1',), None,
 
127
             None, b'foo')]),
 
128
            ('text', [versionedfile.FulltextContentFactory((b'k2',), None,
 
129
             None, b'bar')])]
127
130
        fmt = controldir.format_registry.get('pack-0.92')().repository_format
128
131
        bytes = smart_repo._stream_to_byte_stream(stream, fmt)
129
132
        streams = []
139
142
class TestSmartServerResponse(tests.TestCase):
140
143
 
141
144
    def test__eq__(self):
142
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', )),
143
 
            smart_req.SmartServerResponse(('ok', )))
144
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'body'),
145
 
            smart_req.SmartServerResponse(('ok', ), 'body'))
146
 
        self.assertNotEqual(smart_req.SmartServerResponse(('ok', )),
147
 
            smart_req.SmartServerResponse(('notok', )))
148
 
        self.assertNotEqual(smart_req.SmartServerResponse(('ok', ), 'body'),
149
 
            smart_req.SmartServerResponse(('ok', )))
 
145
        self.assertEqual(smart_req.SmartServerResponse((b'ok', )),
 
146
                         smart_req.SmartServerResponse((b'ok', )))
 
147
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), b'body'),
 
148
                         smart_req.SmartServerResponse((b'ok', ), b'body'))
 
149
        self.assertNotEqual(smart_req.SmartServerResponse((b'ok', )),
 
150
                            smart_req.SmartServerResponse((b'notok', )))
 
151
        self.assertNotEqual(smart_req.SmartServerResponse((b'ok', ), b'body'),
 
152
                            smart_req.SmartServerResponse((b'ok', )))
150
153
        self.assertNotEqual(None,
151
 
            smart_req.SmartServerResponse(('ok', )))
 
154
                            smart_req.SmartServerResponse((b'ok', )))
152
155
 
153
156
    def test__str__(self):
154
157
        """SmartServerResponses can be stringified."""
155
 
        self.assertEqual(
156
 
            "<SuccessfulSmartServerResponse args=('args',) body='body'>",
157
 
            str(smart_req.SuccessfulSmartServerResponse(('args',), 'body')))
158
 
        self.assertEqual(
159
 
            "<FailedSmartServerResponse args=('args',) body='body'>",
160
 
            str(smart_req.FailedSmartServerResponse(('args',), 'body')))
 
158
        self.assertIn(
 
159
            str(smart_req.SuccessfulSmartServerResponse((b'args',), b'body')),
 
160
            ("<SuccessfulSmartServerResponse args=(b'args',) body=b'body'>",
 
161
             "<SuccessfulSmartServerResponse args=('args',) body='body'>"))
 
162
        self.assertIn(
 
163
            str(smart_req.FailedSmartServerResponse((b'args',), b'body')),
 
164
            ("<FailedSmartServerResponse args=(b'args',) body=b'body'>",
 
165
             "<FailedSmartServerResponse args=('args',) body='body'>"))
161
166
 
162
167
 
163
168
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
165
170
    def test_translate_client_path(self):
166
171
        transport = self.get_transport()
167
172
        request = smart_req.SmartServerRequest(transport, 'foo/')
168
 
        self.assertEqual('./', request.translate_client_path('foo/'))
169
 
        self.assertRaises(
170
 
            urlutils.InvalidURLJoin, request.translate_client_path, 'foo/..')
171
 
        self.assertRaises(
172
 
            errors.PathNotChild, request.translate_client_path, '/')
173
 
        self.assertRaises(
174
 
            errors.PathNotChild, request.translate_client_path, 'bar/')
175
 
        self.assertEqual('./baz', request.translate_client_path('foo/baz'))
176
 
        e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'.encode('utf-8')
177
 
        self.assertEqual('./' + urlutils.escape(e_acute),
178
 
                         request.translate_client_path('foo/' + e_acute))
 
173
        self.assertEqual('./', request.translate_client_path(b'foo/'))
 
174
        self.assertRaises(
 
175
            urlutils.InvalidURLJoin, request.translate_client_path, b'foo/..')
 
176
        self.assertRaises(
 
177
            errors.PathNotChild, request.translate_client_path, b'/')
 
178
        self.assertRaises(
 
179
            errors.PathNotChild, request.translate_client_path, b'bar/')
 
180
        self.assertEqual('./baz', request.translate_client_path(b'foo/baz'))
 
181
        e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'
 
182
        self.assertEqual(
 
183
            u'./' + urlutils.escape(e_acute),
 
184
            request.translate_client_path(b'foo/' + e_acute.encode('utf-8')))
179
185
 
180
186
    def test_translate_client_path_vfs(self):
181
187
        """VfsRequests receive escaped paths rather than raw UTF-8."""
182
188
        transport = self.get_transport()
183
189
        request = vfs.VfsRequest(transport, 'foo/')
184
 
        e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'.encode('utf-8')
185
 
        escaped = urlutils.escape('foo/' + e_acute)
186
 
        self.assertEqual('./' + urlutils.escape(e_acute),
187
 
                         request.translate_client_path(escaped))
 
190
        e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'
 
191
        escaped = urlutils.escape(u'foo/' + e_acute)
 
192
        self.assertEqual(
 
193
            './' + urlutils.escape(e_acute),
 
194
            request.translate_client_path(escaped.encode('ascii')))
188
195
 
189
196
    def test_transport_from_client_path(self):
190
197
        transport = self.get_transport()
191
198
        request = smart_req.SmartServerRequest(transport, 'foo/')
192
199
        self.assertEqual(
193
200
            transport.base,
194
 
            request.transport_from_client_path('foo/').base)
 
201
            request.transport_from_client_path(b'foo/').base)
195
202
 
196
203
 
197
204
class TestSmartServerBzrDirRequestCloningMetaDir(
198
 
    tests.TestCaseWithMemoryTransport):
 
205
        tests.TestCaseWithMemoryTransport):
199
206
    """Tests for BzrDir.cloning_metadir."""
200
207
 
201
208
    def test_cloning_metadir(self):
207
214
        request = request_class(backing)
208
215
        expected = smart_req.SuccessfulSmartServerResponse(
209
216
            (local_result.network_name(),
210
 
            local_result.repository_format.network_name(),
211
 
            ('branch', local_result.get_branch_format().network_name())))
212
 
        self.assertEqual(expected, request.execute('', 'False'))
 
217
             local_result.repository_format.network_name(),
 
218
             (b'branch', local_result.get_branch_format().network_name())))
 
219
        self.assertEqual(expected, request.execute(b'', b'False'))
213
220
 
214
221
    def test_cloning_metadir_reference(self):
215
222
        """The request fails when bzrdir contains a branch reference."""
216
223
        backing = self.get_transport()
217
224
        referenced_branch = self.make_branch('referenced')
218
225
        dir = self.make_controldir('.')
219
 
        local_result = dir.cloning_metadir()
220
 
        reference = _mod_bzrbranch.BranchReferenceFormat().initialize(
 
226
        dir.cloning_metadir()
 
227
        _mod_bzrbranch.BranchReferenceFormat().initialize(
221
228
            dir, target_branch=referenced_branch)
222
 
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(dir)
 
229
        _mod_bzrbranch.BranchReferenceFormat().get_reference(dir)
223
230
        # The server shouldn't try to follow the branch reference, so it's fine
224
231
        # if the referenced branch isn't reachable.
225
232
        backing.rename('referenced', 'moved')
226
233
        request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
227
234
        request = request_class(backing)
228
 
        expected = smart_req.FailedSmartServerResponse(('BranchReference',))
229
 
        self.assertEqual(expected, request.execute('', 'False'))
230
 
 
231
 
 
232
 
class TestSmartServerBzrDirRequestCloningMetaDir(
233
 
    tests.TestCaseWithMemoryTransport):
 
235
        expected = smart_req.FailedSmartServerResponse((b'BranchReference',))
 
236
        self.assertEqual(expected, request.execute(b'', b'False'))
 
237
 
 
238
 
 
239
class TestSmartServerBzrDirRequestCheckoutMetaDir(
 
240
        tests.TestCaseWithMemoryTransport):
234
241
    """Tests for BzrDir.checkout_metadir."""
235
242
 
236
243
    def test_checkout_metadir(self):
237
244
        backing = self.get_transport()
238
245
        request = smart_dir.SmartServerBzrDirRequestCheckoutMetaDir(
239
246
            backing)
240
 
        branch = self.make_branch('.', format='2a')
241
 
        response = request.execute('')
 
247
        self.make_branch('.', format='2a')
 
248
        response = request.execute(b'')
242
249
        self.assertEqual(
243
250
            smart_req.SmartServerResponse(
244
 
                ('Bazaar-NG meta directory, format 1\n',
245
 
                 'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
246
 
                 'Bazaar Branch Format 7 (needs bzr 1.6)\n')),
 
251
                (b'Bazaar-NG meta directory, format 1\n',
 
252
                 b'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
 
253
                 b'Bazaar Branch Format 7 (needs bzr 1.6)\n')),
247
254
            response)
248
255
 
249
256
 
250
257
class TestSmartServerBzrDirRequestDestroyBranch(
251
 
    tests.TestCaseWithMemoryTransport):
 
258
        tests.TestCaseWithMemoryTransport):
252
259
    """Tests for BzrDir.destroy_branch."""
253
260
 
254
261
    def test_destroy_branch_default(self):
255
262
        """The default branch can be removed."""
256
263
        backing = self.get_transport()
257
 
        dir = self.make_branch('.').controldir
 
264
        self.make_branch('.')
258
265
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
259
266
        request = request_class(backing)
260
 
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
261
 
        self.assertEqual(expected, request.execute('', None))
 
267
        expected = smart_req.SuccessfulSmartServerResponse((b'ok',))
 
268
        self.assertEqual(expected, request.execute(b'', None))
262
269
 
263
270
    def test_destroy_branch_named(self):
264
271
        """A named branch can be removed."""
267
274
        dir.create_branch(name="branchname")
268
275
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
269
276
        request = request_class(backing)
270
 
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
271
 
        self.assertEqual(expected, request.execute('', "branchname"))
 
277
        expected = smart_req.SuccessfulSmartServerResponse((b'ok',))
 
278
        self.assertEqual(expected, request.execute(b'', b"branchname"))
272
279
 
273
280
    def test_destroy_branch_missing(self):
274
281
        """An error is raised if the branch didn't exist."""
275
282
        backing = self.get_transport()
276
 
        dir = self.make_controldir('.', format="development-colo")
 
283
        self.make_controldir('.', format="development-colo")
277
284
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
278
285
        request = request_class(backing)
279
 
        expected = smart_req.FailedSmartServerResponse(('nobranch',), None)
280
 
        self.assertEqual(expected, request.execute('', "branchname"))
 
286
        expected = smart_req.FailedSmartServerResponse((b'nobranch',), None)
 
287
        self.assertEqual(expected, request.execute(b'', b"branchname"))
281
288
 
282
289
 
283
290
class TestSmartServerBzrDirRequestHasWorkingTree(
284
 
    tests.TestCaseWithTransport):
 
291
        tests.TestCaseWithTransport):
285
292
    """Tests for BzrDir.has_workingtree."""
286
293
 
287
294
    def test_has_workingtree_yes(self):
288
295
        """A working tree is present."""
289
296
        backing = self.get_transport()
290
 
        dir = self.make_branch_and_tree('.').controldir
 
297
        self.make_branch_and_tree('.')
291
298
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
292
299
        request = request_class(backing)
293
 
        expected = smart_req.SuccessfulSmartServerResponse(('yes',))
294
 
        self.assertEqual(expected, request.execute(''))
 
300
        expected = smart_req.SuccessfulSmartServerResponse((b'yes',))
 
301
        self.assertEqual(expected, request.execute(b''))
295
302
 
296
303
    def test_has_workingtree_no(self):
297
304
        """A working tree is missing."""
298
305
        backing = self.get_transport()
299
 
        dir = self.make_controldir('.')
 
306
        self.make_controldir('.')
300
307
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
301
308
        request = request_class(backing)
302
 
        expected = smart_req.SuccessfulSmartServerResponse(('no',))
303
 
        self.assertEqual(expected, request.execute(''))
 
309
        expected = smart_req.SuccessfulSmartServerResponse((b'no',))
 
310
        self.assertEqual(expected, request.execute(b''))
304
311
 
305
312
 
306
313
class TestSmartServerBzrDirRequestDestroyRepository(
307
 
    tests.TestCaseWithMemoryTransport):
 
314
        tests.TestCaseWithMemoryTransport):
308
315
    """Tests for BzrDir.destroy_repository."""
309
316
 
310
317
    def test_destroy_repository_default(self):
311
318
        """The repository can be removed."""
312
319
        backing = self.get_transport()
313
 
        dir = self.make_repository('.').controldir
 
320
        self.make_repository('.')
314
321
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
315
322
        request = request_class(backing)
316
 
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
317
 
        self.assertEqual(expected, request.execute(''))
 
323
        expected = smart_req.SuccessfulSmartServerResponse((b'ok',))
 
324
        self.assertEqual(expected, request.execute(b''))
318
325
 
319
326
    def test_destroy_repository_missing(self):
320
327
        """An error is raised if the repository didn't exist."""
321
328
        backing = self.get_transport()
322
 
        dir = self.make_controldir('.')
 
329
        self.make_controldir('.')
323
330
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
324
331
        request = request_class(backing)
325
332
        expected = smart_req.FailedSmartServerResponse(
326
 
            ('norepository',), None)
327
 
        self.assertEqual(expected, request.execute(''))
328
 
 
329
 
 
330
 
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
 
333
            (b'norepository',), None)
 
334
        self.assertEqual(expected, request.execute(b''))
 
335
 
 
336
 
 
337
class TestSmartServerRequestCreateRepository(
 
338
        tests.TestCaseWithMemoryTransport):
331
339
    """Tests for BzrDir.create_repository."""
332
340
 
333
341
    def test_makes_repository(self):
340
348
        reference_format = reference_bzrdir_format.repository_format
341
349
        network_name = reference_format.network_name()
342
350
        expected = smart_req.SuccessfulSmartServerResponse(
343
 
            ('ok', 'no', 'no', 'no', network_name))
344
 
        self.assertEqual(expected, request.execute('', network_name, 'True'))
 
351
            (b'ok', b'no', b'no', b'no', network_name))
 
352
        self.assertEqual(expected, request.execute(b'', network_name, b'True'))
345
353
 
346
354
 
347
355
class TestSmartServerRequestFindRepository(tests.TestCaseWithMemoryTransport):
348
356
    """Tests for BzrDir.find_repository."""
349
357
 
350
358
    def test_no_repository(self):
351
 
        """When there is no repository to be found, ('norepository', ) is returned."""
 
359
        """If no repository is found, ('norepository', ) is returned."""
352
360
        backing = self.get_transport()
353
361
        request = self._request_class(backing)
354
362
        self.make_controldir('.')
355
 
        self.assertEqual(smart_req.SmartServerResponse(('norepository', )),
356
 
            request.execute(''))
 
363
        self.assertEqual(smart_req.SmartServerResponse((b'norepository', )),
 
364
                         request.execute(b''))
357
365
 
358
366
    def test_nonshared_repository(self):
359
367
        # nonshared repositorys only allow 'find' to return a handle when the
362
370
        backing = self.get_transport()
363
371
        request = self._request_class(backing)
364
372
        result = self._make_repository_and_result()
365
 
        self.assertEqual(result, request.execute(''))
 
373
        self.assertEqual(result, request.execute(b''))
366
374
        self.make_controldir('subdir')
367
 
        self.assertEqual(smart_req.SmartServerResponse(('norepository', )),
368
 
            request.execute('subdir'))
 
375
        self.assertEqual(smart_req.SmartServerResponse((b'norepository', )),
 
376
                         request.execute(b'subdir'))
369
377
 
370
378
    def _make_repository_and_result(self, shared=False, format=None):
371
379
        """Convenience function to setup a repository.
374
382
        """
375
383
        repo = self.make_repository('.', shared=shared, format=format)
376
384
        if repo.supports_rich_root():
377
 
            rich_root = 'yes'
 
385
            rich_root = b'yes'
378
386
        else:
379
 
            rich_root = 'no'
 
387
            rich_root = b'no'
380
388
        if repo._format.supports_tree_reference:
381
 
            subtrees = 'yes'
 
389
            subtrees = b'yes'
382
390
        else:
383
 
            subtrees = 'no'
 
391
            subtrees = b'no'
384
392
        if repo._format.supports_external_lookups:
385
 
            external = 'yes'
 
393
            external = b'yes'
386
394
        else:
387
 
            external = 'no'
 
395
            external = b'no'
388
396
        if (smart_dir.SmartServerRequestFindRepositoryV3 ==
389
 
            self._request_class):
 
397
                self._request_class):
390
398
            return smart_req.SuccessfulSmartServerResponse(
391
 
                ('ok', '', rich_root, subtrees, external,
 
399
                (b'ok', b'', rich_root, subtrees, external,
392
400
                 repo._format.network_name()))
393
401
        elif (smart_dir.SmartServerRequestFindRepositoryV2 ==
394
 
            self._request_class):
 
402
              self._request_class):
395
403
            # All tests so far are on formats, and for non-external
396
404
            # repositories.
397
405
            return smart_req.SuccessfulSmartServerResponse(
398
 
                ('ok', '', rich_root, subtrees, external))
 
406
                (b'ok', b'', rich_root, subtrees, external))
399
407
        else:
400
408
            return smart_req.SuccessfulSmartServerResponse(
401
 
                ('ok', '', rich_root, subtrees))
 
409
                (b'ok', b'', rich_root, subtrees))
402
410
 
403
411
    def test_shared_repository(self):
404
 
        """When there is a shared repository, we get 'ok', 'relpath-to-repo'."""
 
412
        """for a shared repository, we get 'ok', 'relpath-to-repo'."""
405
413
        backing = self.get_transport()
406
414
        request = self._request_class(backing)
407
415
        result = self._make_repository_and_result(shared=True)
408
 
        self.assertEqual(result, request.execute(''))
 
416
        self.assertEqual(result, request.execute(b''))
409
417
        self.make_controldir('subdir')
410
418
        result2 = smart_req.SmartServerResponse(
411
 
            result.args[0:1] + ('..', ) + result.args[2:])
 
419
            result.args[0:1] + (b'..', ) + result.args[2:])
412
420
        self.assertEqual(result2,
413
 
            request.execute('subdir'))
 
421
                         request.execute(b'subdir'))
414
422
        self.make_controldir('subdir/deeper')
415
423
        result3 = smart_req.SmartServerResponse(
416
 
            result.args[0:1] + ('../..', ) + result.args[2:])
 
424
            result.args[0:1] + (b'../..', ) + result.args[2:])
417
425
        self.assertEqual(result3,
418
 
            request.execute('subdir/deeper'))
 
426
                         request.execute(b'subdir/deeper'))
419
427
 
420
428
    def test_rich_root_and_subtree_encoding(self):
421
429
        """Test for the format attributes for rich root and subtree support."""
424
432
        result = self._make_repository_and_result(
425
433
            format='development-subtree')
426
434
        # check the test will be valid
427
 
        self.assertEqual('yes', result.args[2])
428
 
        self.assertEqual('yes', result.args[3])
429
 
        self.assertEqual(result, request.execute(''))
 
435
        self.assertEqual(b'yes', result.args[2])
 
436
        self.assertEqual(b'yes', result.args[3])
 
437
        self.assertEqual(result, request.execute(b''))
430
438
 
431
439
    def test_supports_external_lookups_no_v2(self):
432
440
        """Test for the supports_external_lookups attribute."""
435
443
        result = self._make_repository_and_result(
436
444
            format='development-subtree')
437
445
        # check the test will be valid
438
 
        self.assertEqual('yes', result.args[4])
439
 
        self.assertEqual(result, request.execute(''))
 
446
        self.assertEqual(b'yes', result.args[4])
 
447
        self.assertEqual(result, request.execute(b''))
440
448
 
441
449
 
442
450
class TestSmartServerBzrDirRequestGetConfigFile(
443
 
    tests.TestCaseWithMemoryTransport):
 
451
        tests.TestCaseWithMemoryTransport):
444
452
    """Tests for BzrDir.get_config_file."""
445
453
 
446
454
    def test_present(self):
451
459
        request_class = smart_dir.SmartServerBzrDirRequestConfigFile
452
460
        request = request_class(backing)
453
461
        expected = smart_req.SuccessfulSmartServerResponse((), local_result)
454
 
        self.assertEqual(expected, request.execute(''))
 
462
        self.assertEqual(expected, request.execute(b''))
455
463
 
456
464
    def test_missing(self):
457
465
        backing = self.get_transport()
458
 
        dir = self.make_controldir('.')
 
466
        self.make_controldir('.')
459
467
        request_class = smart_dir.SmartServerBzrDirRequestConfigFile
460
468
        request = request_class(backing)
461
 
        expected = smart_req.SuccessfulSmartServerResponse((), '')
462
 
        self.assertEqual(expected, request.execute(''))
 
469
        expected = smart_req.SuccessfulSmartServerResponse((), b'')
 
470
        self.assertEqual(expected, request.execute(b''))
463
471
 
464
472
 
465
473
class TestSmartServerBzrDirRequestGetBranches(
466
 
    tests.TestCaseWithMemoryTransport):
 
474
        tests.TestCaseWithMemoryTransport):
467
475
    """Tests for BzrDir.get_branches."""
468
476
 
469
477
    def test_simple(self):
472
480
        request_class = smart_dir.SmartServerBzrDirRequestGetBranches
473
481
        request = request_class(backing)
474
482
        local_result = bencode.bencode(
475
 
            {"": ("branch", branch._format.network_name())})
476
 
        expected = smart_req.SuccessfulSmartServerResponse(
477
 
            ("success", ), local_result)
478
 
        self.assertEqual(expected, request.execute(''))
 
483
            {b"": (b"branch", branch._format.network_name())})
 
484
        expected = smart_req.SuccessfulSmartServerResponse(
 
485
            (b"success", ), local_result)
 
486
        self.assertEqual(expected, request.execute(b''))
 
487
 
 
488
    def test_ref(self):
 
489
        backing = self.get_transport()
 
490
        dir = self.make_controldir('foo')
 
491
        b = self.make_branch('bar')
 
492
        dir.set_branch_reference(b)
 
493
        request_class = smart_dir.SmartServerBzrDirRequestGetBranches
 
494
        request = request_class(backing)
 
495
        local_result = bencode.bencode(
 
496
            {b"": (b"ref", b'../bar/')})
 
497
        expected = smart_req.SuccessfulSmartServerResponse(
 
498
            (b"success", ), local_result)
 
499
        self.assertEqual(expected, request.execute(b'foo'))
479
500
 
480
501
    def test_empty(self):
481
502
        backing = self.get_transport()
482
 
        dir = self.make_controldir('.')
 
503
        self.make_controldir('.')
483
504
        request_class = smart_dir.SmartServerBzrDirRequestGetBranches
484
505
        request = request_class(backing)
485
506
        local_result = bencode.bencode({})
486
507
        expected = smart_req.SuccessfulSmartServerResponse(
487
 
            ('success',), local_result)
488
 
        self.assertEqual(expected, request.execute(''))
489
 
 
490
 
 
491
 
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
 
508
            (b'success',), local_result)
 
509
        self.assertEqual(expected, request.execute(b''))
 
510
 
 
511
 
 
512
class TestSmartServerRequestInitializeBzrDir(
 
513
        tests.TestCaseWithMemoryTransport):
492
514
 
493
515
    def test_empty_dir(self):
494
516
        """Initializing an empty dir should succeed and do it."""
495
517
        backing = self.get_transport()
496
518
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
497
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', )),
498
 
            request.execute(''))
 
519
        self.assertEqual(smart_req.SmartServerResponse((b'ok', )),
 
520
                         request.execute(b''))
499
521
        made_dir = controldir.ControlDir.open_from_transport(backing)
500
522
        # no branch, tree or repository is expected with the current
501
523
        # default formart.
508
530
        backing = self.get_transport()
509
531
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
510
532
        self.assertRaises(errors.NoSuchFile,
511
 
            request.execute, 'subdir')
 
533
                          request.execute, b'subdir')
512
534
 
513
535
    def test_initialized_dir(self):
514
536
        """Initializing an extant bzrdir should fail like the bzrdir api."""
516
538
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
517
539
        self.make_controldir('subdir')
518
540
        self.assertRaises(errors.AlreadyControlDirError,
519
 
            request.execute, 'subdir')
 
541
                          request.execute, b'subdir')
520
542
 
521
543
 
522
544
class TestSmartServerRequestBzrDirInitializeEx(
523
 
    tests.TestCaseWithMemoryTransport):
 
545
        tests.TestCaseWithMemoryTransport):
524
546
    """Basic tests for BzrDir.initialize_ex_1.16 in the smart server.
525
547
 
526
548
    The main unit tests in test_bzrdir exercise the API comprehensively.
532
554
        name = self.make_controldir('reference')._format.network_name()
533
555
        request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
534
556
        self.assertEqual(
535
 
            smart_req.SmartServerResponse(('', '', '', '', '', '', name,
536
 
                                           'False', '', '', '')),
537
 
            request.execute(name, '', 'True', 'False', 'False', '', '', '', '',
538
 
                            'False'))
 
557
            smart_req.SmartServerResponse((b'', b'', b'', b'', b'', b'', name,
 
558
                                           b'False', b'', b'', b'')),
 
559
            request.execute(name, b'', b'True', b'False', b'False', b'', b'',
 
560
                            b'', b'', b'False'))
539
561
        made_dir = controldir.ControlDir.open_from_transport(backing)
540
562
        # no branch, tree or repository is expected with the current
541
563
        # default format.
549
571
        name = self.make_controldir('reference')._format.network_name()
550
572
        request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
551
573
        self.assertRaises(errors.NoSuchFile, request.execute, name,
552
 
            'subdir/dir', 'False', 'False', 'False', '', '', '', '', 'False')
 
574
                          b'subdir/dir', b'False', b'False', b'False', b'',
 
575
                          b'', b'', b'', b'False')
553
576
 
554
577
    def test_initialized_dir(self):
555
578
        """Initializing an extant directory should fail like the bzrdir api."""
557
580
        name = self.make_controldir('reference')._format.network_name()
558
581
        request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
559
582
        self.make_controldir('subdir')
560
 
        self.assertRaises(errors.FileExists, request.execute, name, 'subdir',
561
 
            'False', 'False', 'False', '', '', '', '', 'False')
 
583
        self.assertRaises(errors.FileExists, request.execute, name, b'subdir',
 
584
                          b'False', b'False', b'False', b'', b'', b'', b'',
 
585
                          b'False')
562
586
 
563
587
 
564
588
class TestSmartServerRequestOpenBzrDir(tests.TestCaseWithMemoryTransport):
566
590
    def test_no_directory(self):
567
591
        backing = self.get_transport()
568
592
        request = smart_dir.SmartServerRequestOpenBzrDir(backing)
569
 
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
570
 
            request.execute('does-not-exist'))
 
593
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
 
594
                         request.execute(b'does-not-exist'))
571
595
 
572
596
    def test_empty_directory(self):
573
597
        backing = self.get_transport()
574
598
        backing.mkdir('empty')
575
599
        request = smart_dir.SmartServerRequestOpenBzrDir(backing)
576
 
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
577
 
            request.execute('empty'))
 
600
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
 
601
                         request.execute(b'empty'))
578
602
 
579
603
    def test_outside_root_client_path(self):
580
604
        backing = self.get_transport()
581
 
        request = smart_dir.SmartServerRequestOpenBzrDir(backing,
582
 
            root_client_path='root')
583
 
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
584
 
            request.execute('not-root'))
 
605
        request = smart_dir.SmartServerRequestOpenBzrDir(
 
606
            backing, root_client_path='root')
 
607
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
 
608
                         request.execute(b'not-root'))
585
609
 
586
610
 
587
611
class TestSmartServerRequestOpenBzrDir_2_1(tests.TestCaseWithMemoryTransport):
589
613
    def test_no_directory(self):
590
614
        backing = self.get_transport()
591
615
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
592
 
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
593
 
            request.execute('does-not-exist'))
 
616
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
 
617
                         request.execute(b'does-not-exist'))
594
618
 
595
619
    def test_empty_directory(self):
596
620
        backing = self.get_transport()
597
621
        backing.mkdir('empty')
598
622
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
599
 
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
600
 
            request.execute('empty'))
 
623
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
 
624
                         request.execute(b'empty'))
601
625
 
602
626
    def test_present_without_workingtree(self):
603
627
        backing = self.get_transport()
604
628
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
605
629
        self.make_controldir('.')
606
 
        self.assertEqual(smart_req.SmartServerResponse(('yes', 'no')),
607
 
            request.execute(''))
 
630
        self.assertEqual(smart_req.SmartServerResponse((b'yes', b'no')),
 
631
                         request.execute(b''))
608
632
 
609
633
    def test_outside_root_client_path(self):
610
634
        backing = self.get_transport()
611
 
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing,
612
 
            root_client_path='root')
613
 
        self.assertEqual(smart_req.SmartServerResponse(('no',)),
614
 
            request.execute('not-root'))
 
635
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(
 
636
            backing, root_client_path='root')
 
637
        self.assertEqual(smart_req.SmartServerResponse((b'no',)),
 
638
                         request.execute(b'not-root'))
615
639
 
616
640
 
617
641
class TestSmartServerRequestOpenBzrDir_2_1_disk(TestCaseWithChrootedTransport):
624
648
        bd.create_repository()
625
649
        bd.create_branch()
626
650
        bd.create_workingtree()
627
 
        self.assertEqual(smart_req.SmartServerResponse(('yes', 'yes')),
628
 
            request.execute(''))
 
651
        self.assertEqual(smart_req.SmartServerResponse((b'yes', b'yes')),
 
652
                         request.execute(b''))
629
653
 
630
654
 
631
655
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
635
659
        backing = self.get_transport()
636
660
        request = smart_dir.SmartServerRequestOpenBranch(backing)
637
661
        self.make_controldir('.')
638
 
        self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
639
 
            request.execute(''))
 
662
        self.assertEqual(smart_req.SmartServerResponse((b'nobranch', )),
 
663
                         request.execute(b''))
640
664
 
641
665
    def test_branch(self):
642
666
        """When there is a branch, 'ok' is returned."""
643
667
        backing = self.get_transport()
644
668
        request = smart_dir.SmartServerRequestOpenBranch(backing)
645
669
        self.make_branch('.')
646
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', '')),
647
 
            request.execute(''))
 
670
        self.assertEqual(smart_req.SmartServerResponse((b'ok', b'')),
 
671
                         request.execute(b''))
648
672
 
649
673
    def test_branch_reference(self):
650
674
        """When there is a branch reference, the reference URL is returned."""
654
678
        branch = self.make_branch('branch')
655
679
        checkout = branch.create_checkout('reference', lightweight=True)
656
680
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(
657
 
            checkout.controldir)
 
681
            checkout.controldir).encode('utf-8')
658
682
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
659
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', reference_url)),
660
 
            request.execute('reference'))
 
683
        self.assertEqual(smart_req.SmartServerResponse((b'ok', reference_url)),
 
684
                         request.execute(b'reference'))
661
685
 
662
686
    def test_notification_on_branch_from_repository(self):
663
687
        """When there is a repository, the error should return details."""
664
688
        backing = self.get_transport()
665
689
        request = smart_dir.SmartServerRequestOpenBranch(backing)
666
 
        repo = self.make_repository('.')
667
 
        self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
668
 
            request.execute(''))
 
690
        self.make_repository('.')
 
691
        self.assertEqual(smart_req.SmartServerResponse((b'nobranch',)),
 
692
                         request.execute(b''))
669
693
 
670
694
 
671
695
class TestSmartServerRequestOpenBranchV2(TestCaseWithChrootedTransport):
675
699
        backing = self.get_transport()
676
700
        self.make_controldir('.')
677
701
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
678
 
        self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
679
 
            request.execute(''))
 
702
        self.assertEqual(smart_req.SmartServerResponse((b'nobranch', )),
 
703
                         request.execute(b''))
680
704
 
681
705
    def test_branch(self):
682
706
        """When there is a branch, 'ok' is returned."""
684
708
        expected = self.make_branch('.')._format.network_name()
685
709
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
686
710
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
687
 
                ('branch', expected)),
688
 
                         request.execute(''))
 
711
            (b'branch', expected)),
 
712
            request.execute(b''))
689
713
 
690
714
    def test_branch_reference(self):
691
715
        """When there is a branch reference, the reference URL is returned."""
695
719
        branch = self.make_branch('branch')
696
720
        checkout = branch.create_checkout('reference', lightweight=True)
697
721
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(
698
 
            checkout.controldir)
 
722
            checkout.controldir).encode('utf-8')
699
723
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
700
724
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
701
 
                ('ref', reference_url)),
702
 
                         request.execute('reference'))
 
725
            (b'ref', reference_url)),
 
726
            request.execute(b'reference'))
703
727
 
704
728
    def test_stacked_branch(self):
705
729
        """Opening a stacked branch does not open the stacked-on branch."""
713
737
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
714
738
        request.setup_jail()
715
739
        try:
716
 
            response = request.execute('feature')
 
740
            response = request.execute(b'feature')
717
741
        finally:
718
742
            request.teardown_jail()
719
743
        expected_format = feature._format.network_name()
720
744
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
721
 
                ('branch', expected_format)),
722
 
                         response)
 
745
            (b'branch', expected_format)),
 
746
            response)
723
747
        self.assertLength(1, opened_branches)
724
748
 
725
749
    def test_notification_on_branch_from_repository(self):
726
750
        """When there is a repository, the error should return details."""
727
751
        backing = self.get_transport()
728
752
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
729
 
        repo = self.make_repository('.')
730
 
        self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
731
 
            request.execute(''))
 
753
        self.make_repository('.')
 
754
        self.assertEqual(smart_req.SmartServerResponse((b'nobranch',)),
 
755
                         request.execute(b''))
732
756
 
733
757
 
734
758
class TestSmartServerRequestOpenBranchV3(TestCaseWithChrootedTransport):
738
762
        backing = self.get_transport()
739
763
        self.make_controldir('.')
740
764
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
741
 
        self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
742
 
            request.execute(''))
 
765
        self.assertEqual(smart_req.SmartServerResponse((b'nobranch',)),
 
766
                         request.execute(b''))
743
767
 
744
768
    def test_branch(self):
745
769
        """When there is a branch, 'ok' is returned."""
747
771
        expected = self.make_branch('.')._format.network_name()
748
772
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
749
773
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
750
 
                ('branch', expected)),
751
 
                         request.execute(''))
 
774
            (b'branch', expected)),
 
775
            request.execute(b''))
752
776
 
753
777
    def test_branch_reference(self):
754
778
        """When there is a branch reference, the reference URL is returned."""
758
782
        branch = self.make_branch('branch')
759
783
        checkout = branch.create_checkout('reference', lightweight=True)
760
784
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(
761
 
            checkout.controldir)
 
785
            checkout.controldir).encode('utf-8')
762
786
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
763
787
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
764
 
                ('ref', reference_url)),
765
 
                         request.execute('reference'))
 
788
            (b'ref', reference_url)),
 
789
            request.execute(b'reference'))
766
790
 
767
791
    def test_stacked_branch(self):
768
792
        """Opening a stacked branch does not open the stacked-on branch."""
776
800
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
777
801
        request.setup_jail()
778
802
        try:
779
 
            response = request.execute('feature')
 
803
            response = request.execute(b'feature')
780
804
        finally:
781
805
            request.teardown_jail()
782
806
        expected_format = feature._format.network_name()
783
807
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
784
 
                ('branch', expected_format)),
785
 
                         response)
 
808
            (b'branch', expected_format)),
 
809
            response)
786
810
        self.assertLength(1, opened_branches)
787
811
 
788
812
    def test_notification_on_branch_from_repository(self):
789
813
        """When there is a repository, the error should return details."""
790
814
        backing = self.get_transport()
791
815
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
792
 
        repo = self.make_repository('.')
 
816
        self.make_repository('.')
793
817
        self.assertEqual(smart_req.SmartServerResponse(
794
 
                ('nobranch', 'location is a repository')),
795
 
                         request.execute(''))
 
818
            (b'nobranch', b'location is a repository')),
 
819
            request.execute(b''))
796
820
 
797
821
 
798
822
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
802
826
        backing = self.get_transport()
803
827
        request = smart_branch.SmartServerRequestRevisionHistory(backing)
804
828
        self.make_branch('.')
805
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), ''),
806
 
            request.execute(''))
 
829
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), b''),
 
830
                         request.execute(b''))
807
831
 
808
832
    def test_not_empty(self):
809
833
        """For a non-empty branch, the body is empty."""
816
840
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
817
841
        tree.unlock()
818
842
        self.assertEqual(
819
 
            smart_req.SmartServerResponse(('ok', ), ('\x00'.join([r1, r2]))),
820
 
            request.execute(''))
 
843
            smart_req.SmartServerResponse((b'ok', ), (b'\x00'.join([r1, r2]))),
 
844
            request.execute(b''))
821
845
 
822
846
 
823
847
class TestSmartServerBranchRequest(tests.TestCaseWithMemoryTransport):
828
852
        request = smart_branch.SmartServerBranchRequest(backing)
829
853
        self.make_controldir('.')
830
854
        self.assertRaises(errors.NotBranchError,
831
 
            request.execute, '')
 
855
                          request.execute, b'')
832
856
 
833
857
    def test_branch_reference(self):
834
858
        """When there is a branch reference, NotBranchError is raised."""
835
859
        backing = self.get_transport()
836
860
        request = smart_branch.SmartServerBranchRequest(backing)
837
861
        branch = self.make_branch('branch')
838
 
        checkout = branch.create_checkout('reference', lightweight=True)
 
862
        branch.create_checkout('reference', lightweight=True)
839
863
        self.assertRaises(errors.NotBranchError,
840
 
            request.execute, 'checkout')
 
864
                          request.execute, b'checkout')
841
865
 
842
866
 
843
867
class TestSmartServerBranchRequestLastRevisionInfo(
844
 
    tests.TestCaseWithMemoryTransport):
 
868
        tests.TestCaseWithMemoryTransport):
845
869
 
846
870
    def test_empty(self):
847
 
        """For an empty branch, the result is ('ok', '0', 'null:')."""
 
871
        """For an empty branch, the result is ('ok', '0', b'null:')."""
848
872
        backing = self.get_transport()
849
 
        request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
 
873
        request = smart_branch.SmartServerBranchRequestLastRevisionInfo(
 
874
            backing)
850
875
        self.make_branch('.')
851
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', '0', 'null:')),
852
 
            request.execute(''))
 
876
        self.assertEqual(
 
877
            smart_req.SmartServerResponse((b'ok', b'0', b'null:')),
 
878
            request.execute(b''))
 
879
 
 
880
    def test_ghost(self):
 
881
        """For an empty branch, the result is ('ok', '0', b'null:')."""
 
882
        backing = self.get_transport()
 
883
        request = smart_branch.SmartServerBranchRequestLastRevisionInfo(
 
884
            backing)
 
885
        branch = self.make_branch('.')
 
886
 
 
887
        def last_revision_info():
 
888
            raise errors.GhostRevisionsHaveNoRevno(b'revid1', b'revid2')
 
889
        self.overrideAttr(branch, 'last_revision_info', last_revision_info)
 
890
        self.assertRaises(errors.GhostRevisionsHaveNoRevno,
 
891
                          request.do_with_branch, branch)
853
892
 
854
893
    def test_not_empty(self):
855
894
        """For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
856
895
        backing = self.get_transport()
857
 
        request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
 
896
        request = smart_branch.SmartServerBranchRequestLastRevisionInfo(
 
897
            backing)
858
898
        tree = self.make_branch_and_memory_tree('.')
859
899
        tree.lock_write()
860
900
        tree.add('')
861
901
        rev_id_utf8 = u'\xc8'.encode('utf-8')
862
 
        r1 = tree.commit('1st commit')
863
 
        r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
 
902
        tree.commit('1st commit')
 
903
        tree.commit('2nd commit', rev_id=rev_id_utf8)
864
904
        tree.unlock()
865
905
        self.assertEqual(
866
 
            smart_req.SmartServerResponse(('ok', '2', rev_id_utf8)),
867
 
            request.execute(''))
 
906
            smart_req.SmartServerResponse((b'ok', b'2', rev_id_utf8)),
 
907
            request.execute(b''))
868
908
 
869
909
 
870
910
class TestSmartServerBranchRequestRevisionIdToRevno(
871
 
    tests.TestCaseWithMemoryTransport):
 
911
        tests.TestCaseWithMemoryTransport):
872
912
 
873
913
    def test_null(self):
874
914
        backing = self.get_transport()
875
915
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
876
916
            backing)
877
917
        self.make_branch('.')
878
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', '0')),
879
 
            request.execute('', 'null:'))
 
918
        self.assertEqual(smart_req.SmartServerResponse((b'ok', b'0')),
 
919
                         request.execute(b'', b'null:'))
 
920
 
 
921
    def test_ghost_revision(self):
 
922
        backing = self.get_transport()
 
923
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
924
            backing)
 
925
        branch = self.make_branch('.')
 
926
        def revision_id_to_dotted_revno(revid):
 
927
            raise errors.GhostRevisionsHaveNoRevno(revid, b'ghost-revid')
 
928
        self.overrideAttr(branch, 'revision_id_to_dotted_revno', revision_id_to_dotted_revno)
 
929
        self.assertEqual(
 
930
            smart_req.FailedSmartServerResponse(
 
931
                (b'GhostRevisionsHaveNoRevno', b'revid', b'ghost-revid')),
 
932
            request.do_with_branch(branch, b'revid'))
880
933
 
881
934
    def test_simple(self):
882
935
        backing = self.get_transport()
888
941
        r1 = tree.commit('1st commit')
889
942
        tree.unlock()
890
943
        self.assertEqual(
891
 
            smart_req.SmartServerResponse(('ok', '1')),
892
 
            request.execute('', r1))
 
944
            smart_req.SmartServerResponse((b'ok', b'1')),
 
945
            request.execute(b'', r1))
893
946
 
894
947
    def test_not_found(self):
895
948
        backing = self.get_transport()
896
949
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
897
950
            backing)
898
 
        branch = self.make_branch('.')
 
951
        self.make_branch('.')
899
952
        self.assertEqual(
900
953
            smart_req.FailedSmartServerResponse(
901
 
                ('NoSuchRevision', 'idontexist')),
902
 
            request.execute('', 'idontexist'))
 
954
                (b'NoSuchRevision', b'idontexist')),
 
955
            request.execute(b'', b'idontexist'))
903
956
 
904
957
 
905
958
class TestSmartServerBranchRequestGetConfigFile(
906
 
    tests.TestCaseWithMemoryTransport):
 
959
        tests.TestCaseWithMemoryTransport):
907
960
 
908
961
    def test_default(self):
909
962
        """With no file, we get empty content."""
910
963
        backing = self.get_transport()
911
964
        request = smart_branch.SmartServerBranchGetConfigFile(backing)
912
 
        branch = self.make_branch('.')
 
965
        self.make_branch('.')
913
966
        # there should be no file by default
914
 
        content = ''
915
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), content),
916
 
            request.execute(''))
 
967
        content = b''
 
968
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), content),
 
969
                         request.execute(b''))
917
970
 
918
971
    def test_with_content(self):
919
972
        # SmartServerBranchGetConfigFile should return the content from
920
 
        # branch.control_files.get('branch.conf') for now - in the future it may
921
 
        # perform more complex processing.
 
973
        # branch.control_files.get('branch.conf') for now - in the future it
 
974
        # may perform more complex processing.
922
975
        backing = self.get_transport()
923
976
        request = smart_branch.SmartServerBranchGetConfigFile(backing)
924
977
        branch = self.make_branch('.')
925
 
        branch._transport.put_bytes('branch.conf', 'foo bar baz')
926
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'foo bar baz'),
927
 
            request.execute(''))
 
978
        branch._transport.put_bytes('branch.conf', b'foo bar baz')
 
979
        self.assertEqual(
 
980
            smart_req.SmartServerResponse((b'ok', ), b'foo bar baz'),
 
981
            request.execute(b''))
928
982
 
929
983
 
930
984
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
943
997
        request = smart_branch.SmartServerBranchPutConfigFile(backing)
944
998
        branch = self.make_branch('.')
945
999
        branch_token, repo_token = self.get_lock_tokens(branch)
946
 
        self.assertIs(None, request.execute('', branch_token, repo_token))
 
1000
        self.assertIs(None, request.execute(b'', branch_token, repo_token))
947
1001
        self.assertEqual(
948
 
            smart_req.SmartServerResponse(('ok', )),
949
 
            request.do_body('foo bar baz'))
 
1002
            smart_req.SmartServerResponse((b'ok', )),
 
1003
            request.do_body(b'foo bar baz'))
950
1004
        self.assertEqual(
951
1005
            branch.control_transport.get_bytes('branch.conf'),
952
 
            'foo bar baz')
 
1006
            b'foo bar baz')
953
1007
        branch.unlock()
954
1008
 
955
1009
 
961
1015
            branch.controldir.root_transport)
962
1016
        branch_token, repo_token = self.get_lock_tokens(branch)
963
1017
        config = branch._get_config()
964
 
        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
965
 
            '')
 
1018
        result = request.execute(b'', branch_token, repo_token, b'bar', b'foo',
 
1019
                                 b'')
966
1020
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
967
1021
        self.assertEqual('bar', config.get_option('foo'))
968
1022
        # Cleanup
974
1028
            branch.controldir.root_transport)
975
1029
        branch_token, repo_token = self.get_lock_tokens(branch)
976
1030
        config = branch._get_config()
977
 
        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
978
 
            'gam')
 
1031
        result = request.execute(b'', branch_token, repo_token, b'bar', b'foo',
 
1032
                                 b'gam')
979
1033
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
980
1034
        self.assertEqual('bar', config.get_option('foo', 'gam'))
981
1035
        # Cleanup
989
1043
        # A dict with non-ascii keys and values to exercise unicode
990
1044
        # roundtripping.
991
1045
        self.encoded_value_dict = (
992
 
            'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde')
 
1046
            b'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde')
993
1047
        self.value_dict = {
994
1048
            'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
995
1049
 
999
1053
            branch.controldir.root_transport)
1000
1054
        branch_token, repo_token = self.get_lock_tokens(branch)
1001
1055
        config = branch._get_config()
1002
 
        result = request.execute('', branch_token, repo_token,
1003
 
            self.encoded_value_dict, 'foo', '')
 
1056
        result = request.execute(b'', branch_token, repo_token,
 
1057
                                 self.encoded_value_dict, b'foo', b'')
1004
1058
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
1005
1059
        self.assertEqual(self.value_dict, config.get_option('foo'))
1006
1060
        # Cleanup
1012
1066
            branch.controldir.root_transport)
1013
1067
        branch_token, repo_token = self.get_lock_tokens(branch)
1014
1068
        config = branch._get_config()
1015
 
        result = request.execute('', branch_token, repo_token,
1016
 
            self.encoded_value_dict, 'foo', 'gam')
 
1069
        result = request.execute(b'', branch_token, repo_token,
 
1070
                                 self.encoded_value_dict, b'foo', b'gam')
1017
1071
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
1018
1072
        self.assertEqual(self.value_dict, config.get_option('foo', 'gam'))
1019
1073
        # Cleanup
1031
1085
        branch_token, repo_token = self.get_lock_tokens(base_branch)
1032
1086
        request = smart_branch.SmartServerBranchSetTagsBytes(
1033
1087
            self.get_transport())
1034
 
        response = request.execute('base', branch_token, repo_token)
 
1088
        response = request.execute(b'base', branch_token, repo_token)
1035
1089
        self.assertEqual(None, response)
1036
1090
        response = request.do_chunk(tag_bytes)
1037
1091
        self.assertEqual(None, response)
1047
1101
        request = smart_branch.SmartServerBranchSetTagsBytes(
1048
1102
            self.get_transport())
1049
1103
        self.assertRaises(errors.TokenMismatch, request.execute,
1050
 
            'base', 'wrong token', 'wrong token')
 
1104
                          b'base', b'wrong token', b'wrong token')
1051
1105
        # The request handler will keep processing the message parts, so even
1052
1106
        # if the request fails immediately do_chunk and do_end are still
1053
1107
        # called.
1056
1110
        base_branch.unlock()
1057
1111
 
1058
1112
 
1059
 
 
1060
1113
class SetLastRevisionTestBase(TestLockedBranch):
1061
1114
    """Base test case for verbs that implement set_last_revision."""
1062
1115
 
1081
1134
 
1082
1135
    def assertRequestSucceeds(self, revision_id, revno):
1083
1136
        response = self.set_last_revision(revision_id, revno)
1084
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
1137
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
1085
1138
                         response)
1086
1139
 
1087
1140
 
1089
1142
    """Mixin test case for verbs that implement set_last_revision."""
1090
1143
 
1091
1144
    def test_set_null_to_null(self):
1092
 
        """An empty branch can have its last revision set to 'null:'."""
1093
 
        self.assertRequestSucceeds('null:', 0)
 
1145
        """An empty branch can have its last revision set to b'null:'."""
 
1146
        self.assertRequestSucceeds(b'null:', 0)
1094
1147
 
1095
1148
    def test_NoSuchRevision(self):
1096
1149
        """If the revision_id is not present, the verb returns NoSuchRevision.
1097
1150
        """
1098
 
        revision_id = 'non-existent revision'
1099
 
        self.assertEqual(smart_req.FailedSmartServerResponse(('NoSuchRevision',
1100
 
                                                              revision_id)),
1101
 
                         self.set_last_revision(revision_id, 1))
 
1151
        revision_id = b'non-existent revision'
 
1152
        self.assertEqual(
 
1153
            smart_req.FailedSmartServerResponse(
 
1154
                (b'NoSuchRevision', revision_id)),
 
1155
            self.set_last_revision(revision_id, 1))
1102
1156
 
1103
1157
    def make_tree_with_two_commits(self):
1104
1158
        self.tree.lock_write()
1105
1159
        self.tree.add('')
1106
1160
        rev_id_utf8 = u'\xc8'.encode('utf-8')
1107
 
        r1 = self.tree.commit('1st commit', rev_id=rev_id_utf8)
1108
 
        r2 = self.tree.commit('2nd commit', rev_id='rev-2')
 
1161
        self.tree.commit('1st commit', rev_id=rev_id_utf8)
 
1162
        self.tree.commit('2nd commit', rev_id=b'rev-2')
1109
1163
        self.tree.unlock()
1110
1164
 
1111
1165
    def test_branch_last_revision_info_is_updated(self):
1116
1170
        # its repository.
1117
1171
        self.make_tree_with_two_commits()
1118
1172
        rev_id_utf8 = u'\xc8'.encode('utf-8')
1119
 
        self.tree.branch.set_last_revision_info(0, 'null:')
 
1173
        self.tree.branch.set_last_revision_info(0, b'null:')
1120
1174
        self.assertEqual(
1121
 
            (0, 'null:'), self.tree.branch.last_revision_info())
 
1175
            (0, b'null:'), self.tree.branch.last_revision_info())
1122
1176
        # We can update the branch to a revision that is present in the
1123
1177
        # repository.
1124
1178
        self.assertRequestSucceeds(rev_id_utf8, 1)
1132
1186
        self.make_tree_with_two_commits()
1133
1187
        rev_id_utf8 = u'\xc8'.encode('utf-8')
1134
1188
        self.assertEqual(
1135
 
            (2, 'rev-2'), self.tree.branch.last_revision_info())
 
1189
            (2, b'rev-2'), self.tree.branch.last_revision_info())
1136
1190
        self.assertRequestSucceeds(rev_id_utf8, 1)
1137
1191
        self.assertEqual(
1138
1192
            (1, rev_id_utf8), self.tree.branch.last_revision_info())
1142
1196
        returns TipChangeRejected.
1143
1197
        """
1144
1198
        rejection_message = u'rejection message\N{INTERROBANG}'
 
1199
 
1145
1200
        def hook_that_rejects(params):
1146
1201
            raise errors.TipChangeRejected(rejection_message)
1147
1202
        _mod_branch.Branch.hooks.install_named_hook(
1148
1203
            'pre_change_branch_tip', hook_that_rejects, None)
1149
1204
        self.assertEqual(
1150
1205
            smart_req.FailedSmartServerResponse(
1151
 
                ('TipChangeRejected', rejection_message.encode('utf-8'))),
1152
 
            self.set_last_revision('null:', 0))
 
1206
                (b'TipChangeRejected', rejection_message.encode('utf-8'))),
 
1207
            self.set_last_revision(b'null:', 0))
1153
1208
 
1154
1209
 
1155
1210
class TestSmartServerBranchRequestSetLastRevision(
1160
1215
 
1161
1216
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
1162
1217
        return self.request.execute(
1163
 
            '', branch_token, repo_token, revision_id)
 
1218
            b'', branch_token, repo_token, revision_id)
1164
1219
 
1165
1220
 
1166
1221
class TestSmartServerBranchRequestSetLastRevisionInfo(
1171
1226
 
1172
1227
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
1173
1228
        return self.request.execute(
1174
 
            '', branch_token, repo_token, revno, revision_id)
 
1229
            b'', branch_token, repo_token, revno, revision_id)
1175
1230
 
1176
1231
    def test_NoSuchRevision(self):
1177
1232
        """Branch.set_last_revision_info does not have to return
1188
1243
 
1189
1244
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
1190
1245
        return self.request.execute(
1191
 
            '', branch_token, repo_token, revision_id, 0, 0)
 
1246
            b'', branch_token, repo_token, revision_id, 0, 0)
1192
1247
 
1193
1248
    def assertRequestSucceeds(self, revision_id, revno):
1194
1249
        response = self.set_last_revision(revision_id, revno)
1195
1250
        self.assertEqual(
1196
 
            smart_req.SuccessfulSmartServerResponse(('ok', revno, revision_id)),
 
1251
            smart_req.SuccessfulSmartServerResponse(
 
1252
                (b'ok', revno, revision_id)),
1197
1253
            response)
1198
1254
 
1199
1255
    def test_branch_last_revision_info_rewind(self):
1203
1259
        self.make_tree_with_two_commits()
1204
1260
        rev_id_utf8 = u'\xc8'.encode('utf-8')
1205
1261
        self.assertEqual(
1206
 
            (2, 'rev-2'), self.tree.branch.last_revision_info())
 
1262
            (2, b'rev-2'), self.tree.branch.last_revision_info())
1207
1263
        # If allow_overwrite_descendant flag is 0, then trying to set the tip
1208
1264
        # to an older revision ID has no effect.
1209
1265
        branch_token, repo_token = self.lock_branch()
1210
1266
        response = self.request.execute(
1211
 
            '', branch_token, repo_token, rev_id_utf8, 0, 0)
 
1267
            b'', branch_token, repo_token, rev_id_utf8, 0, 0)
1212
1268
        self.assertEqual(
1213
 
            smart_req.SuccessfulSmartServerResponse(('ok', 2, 'rev-2')),
 
1269
            smart_req.SuccessfulSmartServerResponse((b'ok', 2, b'rev-2')),
1214
1270
            response)
1215
1271
        self.assertEqual(
1216
 
            (2, 'rev-2'), self.tree.branch.last_revision_info())
 
1272
            (2, b'rev-2'), self.tree.branch.last_revision_info())
1217
1273
 
1218
1274
        # If allow_overwrite_descendant flag is 1, then setting the tip to an
1219
1275
        # ancestor works.
1220
1276
        response = self.request.execute(
1221
 
            '', branch_token, repo_token, rev_id_utf8, 0, 1)
 
1277
            b'', branch_token, repo_token, rev_id_utf8, 0, 1)
1222
1278
        self.assertEqual(
1223
 
            smart_req.SuccessfulSmartServerResponse(('ok', 1, rev_id_utf8)),
 
1279
            smart_req.SuccessfulSmartServerResponse((b'ok', 1, rev_id_utf8)),
1224
1280
            response)
1225
1281
        self.unlock_branch()
1226
1282
        self.assertEqual(
1234
1290
        """
1235
1291
        self.tree.lock_write()
1236
1292
        self.tree.add('')
1237
 
        r1 = self.tree.commit('1st commit')
 
1293
        self.tree.commit('1st commit')
1238
1294
        revno_1, revid_1 = self.tree.branch.last_revision_info()
1239
 
        r2 = self.tree.commit('2nd commit', rev_id='child-1')
 
1295
        self.tree.commit('2nd commit', rev_id=b'child-1')
1240
1296
        # Undo the second commit
1241
1297
        self.tree.branch.set_last_revision_info(revno_1, revid_1)
1242
1298
        self.tree.set_parent_ids([revid_1])
1243
1299
        # Make a new second commit, child-2.  child-2 has diverged from
1244
1300
        # child-1.
1245
 
        new_r2 = self.tree.commit('2nd commit', rev_id='child-2')
 
1301
        self.tree.commit('2nd commit', rev_id=b'child-2')
1246
1302
        self.tree.unlock()
1247
1303
 
1248
1304
    def test_not_allow_diverged(self):
1251
1307
        """
1252
1308
        self.make_branch_with_divergent_history()
1253
1309
        self.assertEqual(
1254
 
            smart_req.FailedSmartServerResponse(('Diverged',)),
1255
 
            self.set_last_revision('child-1', 2))
 
1310
            smart_req.FailedSmartServerResponse((b'Diverged',)),
 
1311
            self.set_last_revision(b'child-1', 2))
1256
1312
        # The branch tip was not changed.
1257
 
        self.assertEqual('child-2', self.tree.branch.last_revision())
 
1313
        self.assertEqual(b'child-2', self.tree.branch.last_revision())
1258
1314
 
1259
1315
    def test_allow_diverged(self):
1260
1316
        """If allow_diverged is passed, then setting a divergent history
1263
1319
        self.make_branch_with_divergent_history()
1264
1320
        branch_token, repo_token = self.lock_branch()
1265
1321
        response = self.request.execute(
1266
 
            '', branch_token, repo_token, 'child-1', 1, 0)
 
1322
            b'', branch_token, repo_token, b'child-1', 1, 0)
1267
1323
        self.assertEqual(
1268
 
            smart_req.SuccessfulSmartServerResponse(('ok', 2, 'child-1')),
 
1324
            smart_req.SuccessfulSmartServerResponse((b'ok', 2, b'child-1')),
1269
1325
            response)
1270
1326
        self.unlock_branch()
1271
1327
        # The branch tip was changed.
1272
 
        self.assertEqual('child-1', self.tree.branch.last_revision())
 
1328
        self.assertEqual(b'child-1', self.tree.branch.last_revision())
1273
1329
 
1274
1330
 
1275
1331
class TestSmartServerBranchBreakLock(tests.TestCaseWithMemoryTransport):
1280
1336
            self.get_transport())
1281
1337
        base_branch.lock_write()
1282
1338
        self.assertEqual(
1283
 
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
1284
 
            request.execute('base'))
 
1339
            smart_req.SuccessfulSmartServerResponse((b'ok', ), None),
 
1340
            request.execute(b'base'))
1285
1341
 
1286
1342
    def test_nothing_to_break(self):
1287
 
        base_branch = self.make_branch('base')
 
1343
        self.make_branch('base')
1288
1344
        request = smart_branch.SmartServerBranchBreakLock(
1289
1345
            self.get_transport())
1290
1346
        self.assertEqual(
1291
 
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
1292
 
            request.execute('base'))
 
1347
            smart_req.SuccessfulSmartServerResponse((b'ok', ), None),
 
1348
            request.execute(b'base'))
1293
1349
 
1294
1350
 
1295
1351
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
1296
1352
 
1297
1353
    def test_get_parent_none(self):
1298
 
        base_branch = self.make_branch('base')
 
1354
        self.make_branch('base')
1299
1355
        request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1300
 
        response = request.execute('base')
 
1356
        response = request.execute(b'base')
1301
1357
        self.assertEqual(
1302
 
            smart_req.SuccessfulSmartServerResponse(('',)), response)
 
1358
            smart_req.SuccessfulSmartServerResponse((b'',)), response)
1303
1359
 
1304
1360
    def test_get_parent_something(self):
1305
1361
        base_branch = self.make_branch('base')
1306
1362
        base_branch.set_parent(self.get_url('foo'))
1307
1363
        request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1308
 
        response = request.execute('base')
 
1364
        response = request.execute(b'base')
1309
1365
        self.assertEqual(
1310
 
            smart_req.SuccessfulSmartServerResponse(("../foo",)),
 
1366
            smart_req.SuccessfulSmartServerResponse((b"../foo",)),
1311
1367
            response)
1312
1368
 
1313
1369
 
1322
1378
            self.get_transport())
1323
1379
        branch_token, repo_token = self.get_lock_tokens(branch)
1324
1380
        try:
1325
 
            response = request.execute('base', branch_token, repo_token, '')
 
1381
            response = request.execute(b'base', branch_token, repo_token, b'')
1326
1382
        finally:
1327
1383
            branch.unlock()
1328
1384
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1336
1392
            self.get_transport())
1337
1393
        branch_token, repo_token = self.get_lock_tokens(branch)
1338
1394
        try:
1339
 
            response = request.execute('base', branch_token, repo_token,
1340
 
                                       'http://bar/')
 
1395
            response = request.execute(b'base', branch_token, repo_token,
 
1396
                                       b'http://bar/')
1341
1397
        finally:
1342
1398
            branch.unlock()
1343
1399
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1346
1402
 
1347
1403
 
1348
1404
class TestSmartServerBranchRequestGetTagsBytes(
1349
 
    tests.TestCaseWithMemoryTransport):
 
1405
        tests.TestCaseWithMemoryTransport):
1350
1406
    # Only called when the branch format and tags match [yay factory
1351
1407
    # methods] so only need to test straight forward cases.
1352
1408
 
1353
1409
    def test_get_bytes(self):
1354
 
        base_branch = self.make_branch('base')
 
1410
        self.make_branch('base')
1355
1411
        request = smart_branch.SmartServerBranchGetTagsBytes(
1356
1412
            self.get_transport())
1357
 
        response = request.execute('base')
 
1413
        response = request.execute(b'base')
1358
1414
        self.assertEqual(
1359
 
            smart_req.SuccessfulSmartServerResponse(('',)), response)
1360
 
 
1361
 
 
1362
 
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
 
1415
            smart_req.SuccessfulSmartServerResponse((b'',)), response)
 
1416
 
 
1417
 
 
1418
class TestSmartServerBranchRequestGetStackedOnURL(
 
1419
        tests.TestCaseWithMemoryTransport):
1363
1420
 
1364
1421
    def test_get_stacked_on_url(self):
1365
 
        base_branch = self.make_branch('base', format='1.6')
 
1422
        self.make_branch('base', format='1.6')
1366
1423
        stacked_branch = self.make_branch('stacked', format='1.6')
1367
1424
        # typically should be relative
1368
1425
        stacked_branch.set_stacked_on_url('../base')
1369
1426
        request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
1370
1427
            self.get_transport())
1371
 
        response = request.execute('stacked')
 
1428
        response = request.execute(b'stacked')
1372
1429
        self.assertEqual(
1373
 
            smart_req.SmartServerResponse(('ok', '../base')),
 
1430
            smart_req.SmartServerResponse((b'ok', b'../base')),
1374
1431
            response)
1375
1432
 
1376
1433
 
1381
1438
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1382
1439
        branch = self.make_branch('.', format='knit')
1383
1440
        repository = branch.repository
1384
 
        response = request.execute('')
 
1441
        response = request.execute(b'')
1385
1442
        branch_nonce = branch.control_files._lock.peek().get('nonce')
1386
1443
        repository_nonce = repository.control_files._lock.peek().get('nonce')
1387
1444
        self.assertEqual(smart_req.SmartServerResponse(
1388
 
                ('ok', branch_nonce, repository_nonce)),
1389
 
                         response)
 
1445
            (b'ok', branch_nonce, repository_nonce)),
 
1446
            response)
1390
1447
        # The branch (and associated repository) is now locked.  Verify that
1391
1448
        # with a new branch object.
1392
1449
        new_branch = repository.controldir.open_branch()
1393
1450
        self.assertRaises(errors.LockContention, new_branch.lock_write)
1394
1451
        # Cleanup
1395
1452
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1396
 
        response = request.execute('', branch_nonce, repository_nonce)
 
1453
        response = request.execute(b'', branch_nonce, repository_nonce)
1397
1454
 
1398
1455
    def test_lock_write_on_locked_branch(self):
1399
1456
        backing = self.get_transport()
1402
1459
        branch_token = branch.lock_write().token
1403
1460
        branch.leave_lock_in_place()
1404
1461
        branch.unlock()
1405
 
        response = request.execute('')
 
1462
        response = request.execute(b'')
1406
1463
        self.assertEqual(
1407
 
            smart_req.SmartServerResponse(('LockContention',)), response)
 
1464
            smart_req.SmartServerResponse((b'LockContention',)), response)
1408
1465
        # Cleanup
1409
1466
        branch.lock_write(branch_token)
1410
1467
        branch.dont_leave_lock_in_place()
1418
1475
        branch.leave_lock_in_place()
1419
1476
        branch.repository.leave_lock_in_place()
1420
1477
        branch.unlock()
1421
 
        response = request.execute('',
 
1478
        response = request.execute(b'',
1422
1479
                                   branch_token, repo_token)
1423
1480
        self.assertEqual(
1424
 
            smart_req.SmartServerResponse(('ok', branch_token, repo_token)),
 
1481
            smart_req.SmartServerResponse((b'ok', branch_token, repo_token)),
1425
1482
            response)
1426
1483
        # Cleanup
1427
1484
        branch.repository.lock_write(repo_token)
1439
1496
        branch.leave_lock_in_place()
1440
1497
        branch.repository.leave_lock_in_place()
1441
1498
        branch.unlock()
1442
 
        response = request.execute('',
1443
 
                                   branch_token+'xxx', repo_token)
 
1499
        response = request.execute(b'',
 
1500
                                   branch_token + b'xxx', repo_token)
1444
1501
        self.assertEqual(
1445
 
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
 
1502
            smart_req.SmartServerResponse((b'TokenMismatch',)), response)
1446
1503
        # Cleanup
1447
1504
        branch.repository.lock_write(repo_token)
1448
1505
        branch.repository.dont_leave_lock_in_place()
1459
1516
        repo_token = repo.lock_write().repository_token
1460
1517
        repo.leave_lock_in_place()
1461
1518
        repo.unlock()
1462
 
        response = request.execute('')
 
1519
        response = request.execute(b'')
1463
1520
        self.assertEqual(
1464
 
            smart_req.SmartServerResponse(('LockContention',)), response)
 
1521
            smart_req.SmartServerResponse((b'LockContention',)), response)
1465
1522
        # Cleanup
1466
1523
        repo.lock_write(repo_token)
1467
1524
        repo.dont_leave_lock_in_place()
1470
1527
    def test_lock_write_on_readonly_transport(self):
1471
1528
        backing = self.get_readonly_transport()
1472
1529
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1473
 
        branch = self.make_branch('.')
 
1530
        self.make_branch('.')
1474
1531
        root = self.get_transport().clone('/')
1475
1532
        path = urlutils.relative_url(root.base, self.get_transport().base)
1476
 
        response = request.execute(path)
 
1533
        response = request.execute(path.encode('utf-8'))
1477
1534
        error_name, lock_str, why_str = response.args
1478
1535
        self.assertFalse(response.is_successful())
1479
 
        self.assertEqual('LockFailed', error_name)
 
1536
        self.assertEqual(b'LockFailed', error_name)
1480
1537
 
1481
1538
 
1482
1539
class TestSmartServerBranchRequestGetPhysicalLockStatus(TestLockedBranch):
1488
1545
        branch = self.make_branch('.')
1489
1546
        branch_token, repo_token = self.get_lock_tokens(branch)
1490
1547
        self.assertEqual(True, branch.get_physical_lock_status())
1491
 
        response = request.execute('')
 
1548
        response = request.execute(b'')
1492
1549
        self.assertEqual(
1493
 
            smart_req.SmartServerResponse(('yes',)), response)
 
1550
            smart_req.SmartServerResponse((b'yes',)), response)
1494
1551
        branch.unlock()
1495
1552
 
1496
1553
    def test_false(self):
1499
1556
            backing)
1500
1557
        branch = self.make_branch('.')
1501
1558
        self.assertEqual(False, branch.get_physical_lock_status())
1502
 
        response = request.execute('')
 
1559
        response = request.execute(b'')
1503
1560
        self.assertEqual(
1504
 
            smart_req.SmartServerResponse(('no',)), response)
 
1561
            smart_req.SmartServerResponse((b'no',)), response)
1505
1562
 
1506
1563
 
1507
1564
class TestSmartServerBranchRequestUnlock(TestLockedBranch):
1517
1574
        branch.leave_lock_in_place()
1518
1575
        branch.repository.leave_lock_in_place()
1519
1576
        branch.unlock()
1520
 
        response = request.execute('',
 
1577
        response = request.execute(b'',
1521
1578
                                   branch_token, repo_token)
1522
1579
        self.assertEqual(
1523
 
            smart_req.SmartServerResponse(('ok',)), response)
 
1580
            smart_req.SmartServerResponse((b'ok',)), response)
1524
1581
        # The branch is now unlocked.  Verify that with a new branch
1525
1582
        # object.
1526
1583
        new_branch = branch.controldir.open_branch()
1530
1587
    def test_unlock_on_unlocked_branch_unlocked_repo(self):
1531
1588
        backing = self.get_transport()
1532
1589
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1533
 
        branch = self.make_branch('.', format='knit')
 
1590
        self.make_branch('.', format='knit')
1534
1591
        response = request.execute(
1535
 
            '', 'branch token', 'repo token')
 
1592
            b'', b'branch token', b'repo token')
1536
1593
        self.assertEqual(
1537
 
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
 
1594
            smart_req.SmartServerResponse((b'TokenMismatch',)), response)
1538
1595
 
1539
1596
    def test_unlock_on_unlocked_branch_locked_repo(self):
1540
1597
        backing = self.get_transport()
1546
1603
        branch.repository.unlock()
1547
1604
        # Issue branch lock_write request on the unlocked branch (with locked
1548
1605
        # repo).
1549
 
        response = request.execute('', 'branch token', repo_token)
 
1606
        response = request.execute(b'', b'branch token', repo_token)
1550
1607
        self.assertEqual(
1551
 
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
 
1608
            smart_req.SmartServerResponse((b'TokenMismatch',)), response)
1552
1609
        # Cleanup
1553
1610
        branch.repository.lock_write(repo_token)
1554
1611
        branch.repository.dont_leave_lock_in_place()
1568
1625
        self.make_repository('.', shared=True)
1569
1626
        self.make_controldir('subdir')
1570
1627
        self.assertRaises(errors.NoRepositoryPresent,
1571
 
            request.execute, 'subdir')
1572
 
 
1573
 
 
1574
 
class TestSmartServerRepositoryAddSignatureText(tests.TestCaseWithMemoryTransport):
 
1628
                          request.execute, b'subdir')
 
1629
 
 
1630
 
 
1631
class TestSmartServerRepositoryAddSignatureText(
 
1632
        tests.TestCaseWithMemoryTransport):
1575
1633
 
1576
1634
    def test_add_text(self):
1577
1635
        backing = self.get_transport()
1580
1638
        write_token = tree.lock_write()
1581
1639
        self.addCleanup(tree.unlock)
1582
1640
        tree.add('')
1583
 
        tree.commit("Message", rev_id='rev1')
 
1641
        tree.commit("Message", rev_id=b'rev1')
1584
1642
        tree.branch.repository.start_write_group()
1585
1643
        write_group_tokens = tree.branch.repository.suspend_write_group()
1586
 
        self.assertEqual(None, request.execute('', write_token,
1587
 
            'rev1', *write_group_tokens))
1588
 
        response = request.do_body('somesignature')
 
1644
        self.assertEqual(
 
1645
            None, request.execute(
 
1646
                b'', write_token, b'rev1',
 
1647
                *[token.encode('utf-8') for token in write_group_tokens]))
 
1648
        response = request.do_body(b'somesignature')
1589
1649
        self.assertTrue(response.is_successful())
1590
 
        self.assertEqual(response.args[0], 'ok')
1591
 
        write_group_tokens = response.args[1:]
 
1650
        self.assertEqual(response.args[0], b'ok')
 
1651
        write_group_tokens = [token.decode('utf-8')
 
1652
                              for token in response.args[1:]]
1592
1653
        tree.branch.repository.resume_write_group(write_group_tokens)
1593
1654
        tree.branch.repository.commit_write_group()
1594
1655
        tree.unlock()
1595
 
        self.assertEqual("somesignature",
1596
 
            tree.branch.repository.get_signature_text("rev1"))
 
1656
        self.assertEqual(b"somesignature",
 
1657
                         tree.branch.repository.get_signature_text(b"rev1"))
1597
1658
 
1598
1659
 
1599
1660
class TestSmartServerRepositoryAllRevisionIds(
1600
 
    tests.TestCaseWithMemoryTransport):
 
1661
        tests.TestCaseWithMemoryTransport):
1601
1662
 
1602
1663
    def test_empty(self):
1603
1664
        """An empty body should be returned for an empty repository."""
1605
1666
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
1606
1667
        self.make_repository('.')
1607
1668
        self.assertEqual(
1608
 
            smart_req.SuccessfulSmartServerResponse(("ok", ), ""),
1609
 
            request.execute(''))
 
1669
            smart_req.SuccessfulSmartServerResponse((b"ok", ), b""),
 
1670
            request.execute(b''))
1610
1671
 
1611
1672
    def test_some_revisions(self):
1612
1673
        """An empty body should be returned for an empty repository."""
1615
1676
        tree = self.make_branch_and_memory_tree('.')
1616
1677
        tree.lock_write()
1617
1678
        tree.add('')
1618
 
        tree.commit(rev_id='origineel', message="message")
1619
 
        tree.commit(rev_id='nog-een-revisie', message="message")
 
1679
        tree.commit(rev_id=b'origineel', message="message")
 
1680
        tree.commit(rev_id=b'nog-een-revisie', message="message")
1620
1681
        tree.unlock()
1621
 
        self.assertEqual(
1622
 
            smart_req.SuccessfulSmartServerResponse(("ok", ),
1623
 
                "origineel\nnog-een-revisie"),
1624
 
            request.execute(''))
 
1682
        self.assertIn(
 
1683
            request.execute(b''),
 
1684
            [smart_req.SuccessfulSmartServerResponse(
 
1685
                (b"ok", ), b"origineel\nnog-een-revisie"),
 
1686
             smart_req.SuccessfulSmartServerResponse(
 
1687
                 (b"ok", ), b"nog-een-revisie\norigineel")])
1625
1688
 
1626
1689
 
1627
1690
class TestSmartServerRepositoryBreakLock(tests.TestCaseWithMemoryTransport):
1632
1695
        tree = self.make_branch_and_memory_tree('.')
1633
1696
        tree.branch.repository.lock_write()
1634
1697
        self.assertEqual(
1635
 
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
1636
 
            request.execute(''))
 
1698
            smart_req.SuccessfulSmartServerResponse((b'ok', ), None),
 
1699
            request.execute(b''))
1637
1700
 
1638
1701
    def test_nothing_to_break(self):
1639
1702
        backing = self.get_transport()
1640
1703
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
1641
 
        tree = self.make_branch_and_memory_tree('.')
 
1704
        self.make_branch_and_memory_tree('.')
1642
1705
        self.assertEqual(
1643
 
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
1644
 
            request.execute(''))
 
1706
            smart_req.SuccessfulSmartServerResponse((b'ok', ), None),
 
1707
            request.execute(b''))
1645
1708
 
1646
1709
 
1647
1710
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithMemoryTransport):
1650
1713
        # This tests that the wire encoding is actually bzipped
1651
1714
        backing = self.get_transport()
1652
1715
        request = smart_repo.SmartServerRepositoryGetParentMap(backing)
1653
 
        tree = self.make_branch_and_memory_tree('.')
 
1716
        self.make_branch_and_memory_tree('.')
1654
1717
 
1655
1718
        self.assertEqual(None,
1656
 
            request.execute('', 'missing-id'))
 
1719
                         request.execute(b'', b'missing-id'))
1657
1720
        # Note that it returns a body that is bzipped.
1658
1721
        self.assertEqual(
1659
 
            smart_req.SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
1660
 
            request.do_body('\n\n0\n'))
 
1722
            smart_req.SuccessfulSmartServerResponse(
 
1723
                (b'ok', ), bz2.compress(b'')),
 
1724
            request.do_body(b'\n\n0\n'))
1661
1725
 
1662
1726
    def test_trivial_include_missing(self):
1663
1727
        backing = self.get_transport()
1664
1728
        request = smart_repo.SmartServerRepositoryGetParentMap(backing)
1665
 
        tree = self.make_branch_and_memory_tree('.')
 
1729
        self.make_branch_and_memory_tree('.')
1666
1730
 
1667
 
        self.assertEqual(None,
1668
 
            request.execute('', 'missing-id', 'include-missing:'))
1669
 
        self.assertEqual(
1670
 
            smart_req.SuccessfulSmartServerResponse(('ok', ),
1671
 
                bz2.compress('missing:missing-id')),
1672
 
            request.do_body('\n\n0\n'))
 
1731
        self.assertEqual(
 
1732
            None, request.execute(b'', b'missing-id', b'include-missing:'))
 
1733
        self.assertEqual(
 
1734
            smart_req.SuccessfulSmartServerResponse(
 
1735
                (b'ok', ), bz2.compress(b'missing:missing-id')),
 
1736
            request.do_body(b'\n\n0\n'))
1673
1737
 
1674
1738
 
1675
1739
class TestSmartServerRepositoryGetRevisionGraph(
1676
 
    tests.TestCaseWithMemoryTransport):
 
1740
        tests.TestCaseWithMemoryTransport):
1677
1741
 
1678
1742
    def test_none_argument(self):
1679
1743
        backing = self.get_transport()
1687
1751
 
1688
1752
        # the lines of revision_id->revision_parent_list has no guaranteed
1689
1753
        # order coming out of a dict, so sort both our test and response
1690
 
        lines = sorted([' '.join([r2, r1]), r1])
1691
 
        response = request.execute('', '')
1692
 
        response.body = '\n'.join(sorted(response.body.split('\n')))
 
1754
        lines = sorted([b' '.join([r2, r1]), r1])
 
1755
        response = request.execute(b'', b'')
 
1756
        response.body = b'\n'.join(sorted(response.body.split(b'\n')))
1693
1757
 
1694
1758
        self.assertEqual(
1695
 
            smart_req.SmartServerResponse(('ok', ), '\n'.join(lines)), response)
 
1759
            smart_req.SmartServerResponse((b'ok', ), b'\n'.join(lines)),
 
1760
            response)
1696
1761
 
1697
1762
    def test_specific_revision_argument(self):
1698
1763
        backing = self.get_transport()
1701
1766
        tree.lock_write()
1702
1767
        tree.add('')
1703
1768
        rev_id_utf8 = u'\xc9'.encode('utf-8')
1704
 
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
1705
 
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
 
1769
        tree.commit('1st commit', rev_id=rev_id_utf8)
 
1770
        tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
1706
1771
        tree.unlock()
1707
1772
 
1708
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), rev_id_utf8),
1709
 
            request.execute('', rev_id_utf8))
 
1773
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), rev_id_utf8),
 
1774
                         request.execute(b'', rev_id_utf8))
1710
1775
 
1711
1776
    def test_no_such_revision(self):
1712
1777
        backing = self.get_transport()
1714
1779
        tree = self.make_branch_and_memory_tree('.')
1715
1780
        tree.lock_write()
1716
1781
        tree.add('')
1717
 
        r1 = tree.commit('1st commit')
 
1782
        tree.commit('1st commit')
1718
1783
        tree.unlock()
1719
1784
 
1720
1785
        # Note that it still returns body (of zero bytes).
1721
1786
        self.assertEqual(smart_req.SmartServerResponse(
1722
 
                ('nosuchrevision', 'missingrevision', ), ''),
1723
 
                         request.execute('', 'missingrevision'))
 
1787
            (b'nosuchrevision', b'missingrevision', ), b''),
 
1788
            request.execute(b'', b'missingrevision'))
1724
1789
 
1725
1790
 
1726
1791
class TestSmartServerRepositoryGetRevIdForRevno(
1727
 
    tests.TestCaseWithMemoryTransport):
 
1792
        tests.TestCaseWithMemoryTransport):
1728
1793
 
1729
1794
    def test_revno_found(self):
1730
1795
        backing = self.get_transport()
1738
1803
        tree.commit('2nd commit', rev_id=rev2_id_utf8)
1739
1804
        tree.unlock()
1740
1805
 
1741
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', rev1_id_utf8)),
1742
 
            request.execute('', 1, (2, rev2_id_utf8)))
 
1806
        self.assertEqual(smart_req.SmartServerResponse((b'ok', rev1_id_utf8)),
 
1807
                         request.execute(b'', 1, (2, rev2_id_utf8)))
1743
1808
 
1744
1809
    def test_known_revid_missing(self):
1745
1810
        backing = self.get_transport()
1746
1811
        request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1747
 
        repo = self.make_repository('.')
 
1812
        self.make_repository('.')
1748
1813
        self.assertEqual(
1749
 
            smart_req.FailedSmartServerResponse(('nosuchrevision', 'ghost')),
1750
 
            request.execute('', 1, (2, 'ghost')))
 
1814
            smart_req.FailedSmartServerResponse((b'nosuchrevision', b'ghost')),
 
1815
            request.execute(b'', 1, (2, b'ghost')))
1751
1816
 
1752
1817
    def test_history_incomplete(self):
1753
1818
        backing = self.get_transport()
1754
1819
        request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1755
1820
        parent = self.make_branch_and_memory_tree('parent', format='1.9')
1756
1821
        parent.lock_write()
1757
 
        parent.add([''], ['TREE_ROOT'])
1758
 
        r1 = parent.commit(message='first commit')
 
1822
        parent.add([''], [b'TREE_ROOT'])
 
1823
        parent.commit(message='first commit')
1759
1824
        r2 = parent.commit(message='second commit')
1760
1825
        parent.unlock()
1761
1826
        local = self.make_branch_and_memory_tree('local', format='1.9')
1765
1830
        local.branch.create_clone_on_transport(
1766
1831
            self.get_transport('stacked'), stacked_on=self.get_url('parent'))
1767
1832
        self.assertEqual(
1768
 
            smart_req.SmartServerResponse(('history-incomplete', 2, r2)),
1769
 
            request.execute('stacked', 1, (3, r3)))
 
1833
            smart_req.SmartServerResponse((b'history-incomplete', 2, r2)),
 
1834
            request.execute(b'stacked', 1, (3, r3)))
1770
1835
 
1771
1836
 
1772
1837
class TestSmartServerRepositoryIterRevisions(
1773
 
    tests.TestCaseWithMemoryTransport):
 
1838
        tests.TestCaseWithMemoryTransport):
1774
1839
 
1775
1840
    def test_basic(self):
1776
1841
        backing = self.get_transport()
1778
1843
        tree = self.make_branch_and_memory_tree('.', format='2a')
1779
1844
        tree.lock_write()
1780
1845
        tree.add('')
1781
 
        tree.commit('1st commit', rev_id="rev1")
1782
 
        tree.commit('2nd commit', rev_id="rev2")
 
1846
        tree.commit('1st commit', rev_id=b"rev1")
 
1847
        tree.commit('2nd commit', rev_id=b"rev2")
1783
1848
        tree.unlock()
1784
1849
 
1785
 
        self.assertIs(None, request.execute(''))
1786
 
        response = request.do_body("rev1\nrev2")
 
1850
        self.assertIs(None, request.execute(b''))
 
1851
        response = request.do_body(b"rev1\nrev2")
1787
1852
        self.assertTrue(response.is_successful())
1788
1853
        # Format 2a uses serializer format 10
1789
 
        self.assertEqual(response.args, ("ok", "10"))
 
1854
        self.assertEqual(response.args, (b"ok", b"10"))
1790
1855
 
1791
1856
        self.addCleanup(tree.branch.lock_read().unlock)
1792
1857
        entries = [zlib.compress(record.get_bytes_as("fulltext")) for record in
1793
 
            tree.branch.repository.revisions.get_record_stream(
1794
 
            [("rev1", ), ("rev2", )], "unordered", True)]
 
1858
                   tree.branch.repository.revisions.get_record_stream(
 
1859
            [(b"rev1", ), (b"rev2", )], "unordered", True)]
1795
1860
 
1796
 
        contents = "".join(response.body_stream)
 
1861
        contents = b"".join(response.body_stream)
1797
1862
        self.assertTrue(contents in (
1798
 
            "".join([entries[0], entries[1]]),
1799
 
            "".join([entries[1], entries[0]])))
 
1863
            b"".join([entries[0], entries[1]]),
 
1864
            b"".join([entries[1], entries[0]])))
1800
1865
 
1801
1866
    def test_missing(self):
1802
1867
        backing = self.get_transport()
1803
1868
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
1804
 
        tree = self.make_branch_and_memory_tree('.', format='2a')
 
1869
        self.make_branch_and_memory_tree('.', format='2a')
1805
1870
 
1806
 
        self.assertIs(None, request.execute(''))
1807
 
        response = request.do_body("rev1\nrev2")
 
1871
        self.assertIs(None, request.execute(b''))
 
1872
        response = request.do_body(b"rev1\nrev2")
1808
1873
        self.assertTrue(response.is_successful())
1809
1874
        # Format 2a uses serializer format 10
1810
 
        self.assertEqual(response.args, ("ok", "10"))
 
1875
        self.assertEqual(response.args, (b"ok", b"10"))
1811
1876
 
1812
 
        contents = "".join(response.body_stream)
1813
 
        self.assertEqual(contents, "")
 
1877
        contents = b"".join(response.body_stream)
 
1878
        self.assertEqual(contents, b"")
1814
1879
 
1815
1880
 
1816
1881
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
1833
1898
        backing = self.get_transport()
1834
1899
        request = smart_repo.SmartServerRepositoryGetStream(backing)
1835
1900
        repo, r1, r2 = self.make_two_commit_repo()
1836
 
        fetch_spec = ['ancestry-of', r2]
1837
 
        lines = '\n'.join(fetch_spec)
1838
 
        request.execute('', repo._format.network_name())
 
1901
        fetch_spec = [b'ancestry-of', r2]
 
1902
        lines = b'\n'.join(fetch_spec)
 
1903
        request.execute(b'', repo._format.network_name())
1839
1904
        response = request.do_body(lines)
1840
 
        self.assertEqual(('ok',), response.args)
1841
 
        stream_bytes = ''.join(response.body_stream)
1842
 
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
 
1905
        self.assertEqual((b'ok',), response.args)
 
1906
        stream_bytes = b''.join(response.body_stream)
 
1907
        self.assertStartsWith(stream_bytes, b'Bazaar pack format 1')
1843
1908
 
1844
1909
    def test_search(self):
1845
1910
        """The search argument may be a 'search' of some explicit keys."""
1846
1911
        backing = self.get_transport()
1847
1912
        request = smart_repo.SmartServerRepositoryGetStream(backing)
1848
1913
        repo, r1, r2 = self.make_two_commit_repo()
1849
 
        fetch_spec = ['search', '%s %s' % (r1, r2), 'null:', '2']
1850
 
        lines = '\n'.join(fetch_spec)
1851
 
        request.execute('', repo._format.network_name())
 
1914
        fetch_spec = [b'search', r1 + b' ' + r2, b'null:', b'2']
 
1915
        lines = b'\n'.join(fetch_spec)
 
1916
        request.execute(b'', repo._format.network_name())
1852
1917
        response = request.do_body(lines)
1853
 
        self.assertEqual(('ok',), response.args)
1854
 
        stream_bytes = ''.join(response.body_stream)
1855
 
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
 
1918
        self.assertEqual((b'ok',), response.args)
 
1919
        stream_bytes = b''.join(response.body_stream)
 
1920
        self.assertStartsWith(stream_bytes, b'Bazaar pack format 1')
1856
1921
 
1857
1922
    def test_search_everything(self):
1858
1923
        """A search of 'everything' returns a stream."""
1859
1924
        backing = self.get_transport()
1860
1925
        request = smart_repo.SmartServerRepositoryGetStream_1_19(backing)
1861
1926
        repo, r1, r2 = self.make_two_commit_repo()
1862
 
        serialised_fetch_spec = 'everything'
1863
 
        request.execute('', repo._format.network_name())
 
1927
        serialised_fetch_spec = b'everything'
 
1928
        request.execute(b'', repo._format.network_name())
1864
1929
        response = request.do_body(serialised_fetch_spec)
1865
 
        self.assertEqual(('ok',), response.args)
1866
 
        stream_bytes = ''.join(response.body_stream)
1867
 
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
 
1930
        self.assertEqual((b'ok',), response.args)
 
1931
        stream_bytes = b''.join(response.body_stream)
 
1932
        self.assertStartsWith(stream_bytes, b'Bazaar pack format 1')
1868
1933
 
1869
1934
 
1870
1935
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1874
1939
        backing = self.get_transport()
1875
1940
        request = smart_repo.SmartServerRequestHasRevision(backing)
1876
1941
        self.make_repository('.')
1877
 
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
1878
 
            request.execute('', 'revid'))
 
1942
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
 
1943
                         request.execute(b'', b'revid'))
1879
1944
 
1880
1945
    def test_present_revision(self):
1881
1946
        """For a present revision, ('yes', ) is returned."""
1885
1950
        tree.lock_write()
1886
1951
        tree.add('')
1887
1952
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
1888
 
        r1 = tree.commit('a commit', rev_id=rev_id_utf8)
 
1953
        tree.commit('a commit', rev_id=rev_id_utf8)
1889
1954
        tree.unlock()
1890
1955
        self.assertTrue(tree.branch.repository.has_revision(rev_id_utf8))
1891
 
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
1892
 
            request.execute('', rev_id_utf8))
 
1956
        self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
 
1957
                         request.execute(b'', rev_id_utf8))
1893
1958
 
1894
1959
 
1895
1960
class TestSmartServerRepositoryIterFilesBytes(tests.TestCaseWithTransport):
1899
1964
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
1900
1965
        t = self.make_branch_and_tree('.')
1901
1966
        self.addCleanup(t.lock_write().unlock)
1902
 
        self.build_tree_contents([("file", "somecontents")])
1903
 
        t.add(["file"], ["thefileid"])
1904
 
        t.commit(rev_id='somerev', message="add file")
1905
 
        self.assertIs(None, request.execute(''))
1906
 
        response = request.do_body("thefileid\0somerev\n")
 
1967
        self.build_tree_contents([("file", b"somecontents")])
 
1968
        t.add(["file"], [b"thefileid"])
 
1969
        t.commit(rev_id=b'somerev', message="add file")
 
1970
        self.assertIs(None, request.execute(b''))
 
1971
        response = request.do_body(b"thefileid\0somerev\n")
1907
1972
        self.assertTrue(response.is_successful())
1908
 
        self.assertEqual(response.args, ("ok", ))
1909
 
        self.assertEqual("".join(response.body_stream),
1910
 
            "ok\x000\n" + zlib.compress("somecontents"))
 
1973
        self.assertEqual(response.args, (b"ok", ))
 
1974
        self.assertEqual(b"".join(response.body_stream),
 
1975
                         b"ok\x000\n" + zlib.compress(b"somecontents"))
1911
1976
 
1912
1977
    def test_missing(self):
1913
1978
        backing = self.get_transport()
1914
1979
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
1915
1980
        t = self.make_branch_and_tree('.')
1916
1981
        self.addCleanup(t.lock_write().unlock)
1917
 
        self.assertIs(None, request.execute(''))
1918
 
        response = request.do_body("thefileid\0revision\n")
 
1982
        self.assertIs(None, request.execute(b''))
 
1983
        response = request.do_body(b"thefileid\0revision\n")
1919
1984
        self.assertTrue(response.is_successful())
1920
 
        self.assertEqual(response.args, ("ok", ))
1921
 
        self.assertEqual("".join(response.body_stream),
1922
 
            "absent\x00thefileid\x00revision\x000\n")
 
1985
        self.assertEqual(response.args, (b"ok", ))
 
1986
        self.assertEqual(b"".join(response.body_stream),
 
1987
                         b"absent\x00thefileid\x00revision\x000\n")
1923
1988
 
1924
1989
 
1925
1990
class TestSmartServerRequestHasSignatureForRevisionId(
1933
1998
        self.make_repository('.')
1934
1999
        self.assertEqual(
1935
2000
            smart_req.FailedSmartServerResponse(
1936
 
                ('nosuchrevision', 'revid'), None),
1937
 
            request.execute('', 'revid'))
 
2001
                (b'nosuchrevision', b'revid'), None),
 
2002
            request.execute(b'', b'revid'))
1938
2003
 
1939
2004
    def test_missing_signature(self):
1940
2005
        """For a missing signature, ('no', ) is returned."""
1944
2009
        tree = self.make_branch_and_memory_tree('.')
1945
2010
        tree.lock_write()
1946
2011
        tree.add('')
1947
 
        r1 = tree.commit('a commit', rev_id='A')
 
2012
        tree.commit('a commit', rev_id=b'A')
1948
2013
        tree.unlock()
1949
 
        self.assertTrue(tree.branch.repository.has_revision('A'))
1950
 
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
1951
 
            request.execute('', 'A'))
 
2014
        self.assertTrue(tree.branch.repository.has_revision(b'A'))
 
2015
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
 
2016
                         request.execute(b'', b'A'))
1952
2017
 
1953
2018
    def test_present_signature(self):
1954
2019
        """For a present signature, ('yes', ) is returned."""
1959
2024
        tree = self.make_branch_and_memory_tree('.')
1960
2025
        tree.lock_write()
1961
2026
        tree.add('')
1962
 
        r1 = tree.commit('a commit', rev_id='A')
 
2027
        tree.commit('a commit', rev_id=b'A')
1963
2028
        tree.branch.repository.start_write_group()
1964
 
        tree.branch.repository.sign_revision('A', strategy)
 
2029
        tree.branch.repository.sign_revision(b'A', strategy)
1965
2030
        tree.branch.repository.commit_write_group()
1966
2031
        tree.unlock()
1967
 
        self.assertTrue(tree.branch.repository.has_revision('A'))
1968
 
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
1969
 
            request.execute('', 'A'))
 
2032
        self.assertTrue(tree.branch.repository.has_revision(b'A'))
 
2033
        self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
 
2034
                         request.execute(b'', b'A'))
1970
2035
 
1971
2036
 
1972
2037
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
1976
2041
        backing = self.get_transport()
1977
2042
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
1978
2043
        repository = self.make_repository('.')
1979
 
        stats = repository.gather_stats()
1980
 
        expected_body = 'revisions: 0\n'
1981
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), expected_body),
1982
 
                         request.execute('', '', 'no'))
 
2044
        repository.gather_stats()
 
2045
        expected_body = b'revisions: 0\n'
 
2046
        self.assertEqual(
 
2047
            smart_req.SmartServerResponse((b'ok', ), expected_body),
 
2048
            request.execute(b'', b'', b'no'))
1983
2049
 
1984
2050
    def test_revid_with_committers(self):
1985
2051
        """For a revid we get more infos."""
1995
2061
                    rev_id=rev_id_utf8)
1996
2062
        tree.unlock()
1997
2063
 
1998
 
        stats = tree.branch.repository.gather_stats()
1999
 
        expected_body = ('firstrev: 123456.200 3600\n'
2000
 
                         'latestrev: 654321.400 0\n'
2001
 
                         'revisions: 2\n')
2002
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), expected_body),
2003
 
                         request.execute('',
2004
 
                                         rev_id_utf8, 'no'))
 
2064
        tree.branch.repository.gather_stats()
 
2065
        expected_body = (b'firstrev: 123456.200 3600\n'
 
2066
                         b'latestrev: 654321.400 0\n'
 
2067
                         b'revisions: 2\n')
 
2068
        self.assertEqual(
 
2069
            smart_req.SmartServerResponse((b'ok', ), expected_body),
 
2070
            request.execute(b'', rev_id_utf8, b'no'))
2005
2071
 
2006
2072
    def test_not_empty_repository_with_committers(self):
2007
2073
        """For a revid and requesting committers we get the whole thing."""
2017
2083
        tree.commit('a commit', timestamp=654321.4, timezone=0,
2018
2084
                    committer='bar', rev_id=rev_id_utf8)
2019
2085
        tree.unlock()
2020
 
        stats = tree.branch.repository.gather_stats()
 
2086
        tree.branch.repository.gather_stats()
2021
2087
 
2022
 
        expected_body = ('committers: 2\n'
2023
 
                         'firstrev: 123456.200 3600\n'
2024
 
                         'latestrev: 654321.400 0\n'
2025
 
                         'revisions: 2\n')
2026
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), expected_body),
2027
 
                         request.execute('',
2028
 
                                         rev_id_utf8, 'yes'))
 
2088
        expected_body = (b'committers: 2\n'
 
2089
                         b'firstrev: 123456.200 3600\n'
 
2090
                         b'latestrev: 654321.400 0\n'
 
2091
                         b'revisions: 2\n')
 
2092
        self.assertEqual(
 
2093
            smart_req.SmartServerResponse((b'ok', ), expected_body),
 
2094
            request.execute(b'', rev_id_utf8, b'yes'))
2029
2095
 
2030
2096
    def test_unknown_revid(self):
2031
2097
        """An unknown revision id causes a 'nosuchrevision' error."""
2032
2098
        backing = self.get_transport()
2033
2099
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
2034
 
        repository = self.make_repository('.')
2035
 
        expected_body = 'revisions: 0\n'
 
2100
        self.make_repository('.')
2036
2101
        self.assertEqual(
2037
2102
            smart_req.FailedSmartServerResponse(
2038
 
                ('nosuchrevision', 'mia'), None),
2039
 
            request.execute('', 'mia', 'yes'))
 
2103
                (b'nosuchrevision', b'mia'), None),
 
2104
            request.execute(b'', b'mia', b'yes'))
2040
2105
 
2041
2106
 
2042
2107
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
2046
2111
        backing = self.get_transport()
2047
2112
        request = smart_repo.SmartServerRepositoryIsShared(backing)
2048
2113
        self.make_repository('.', shared=True)
2049
 
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
2050
 
            request.execute('', ))
 
2114
        self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
 
2115
                         request.execute(b'', ))
2051
2116
 
2052
2117
    def test_is_not_shared(self):
2053
2118
        """For a shared repository, ('no', ) is returned."""
2054
2119
        backing = self.get_transport()
2055
2120
        request = smart_repo.SmartServerRepositoryIsShared(backing)
2056
2121
        self.make_repository('.', shared=False)
2057
 
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
2058
 
            request.execute('', ))
 
2122
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
 
2123
                         request.execute(b'', ))
2059
2124
 
2060
2125
 
2061
2126
class TestSmartServerRepositoryGetRevisionSignatureText(
2066
2131
        request = smart_repo.SmartServerRepositoryGetRevisionSignatureText(
2067
2132
            backing)
2068
2133
        bb = self.make_branch_builder('.')
2069
 
        bb.build_commit(rev_id='A')
 
2134
        bb.build_commit(rev_id=b'A')
2070
2135
        repo = bb.get_branch().repository
2071
2136
        strategy = gpg.LoopbackGPGStrategy(None)
2072
2137
        self.addCleanup(repo.lock_write().unlock)
2073
2138
        repo.start_write_group()
2074
 
        repo.sign_revision('A', strategy)
 
2139
        repo.sign_revision(b'A', strategy)
2075
2140
        repo.commit_write_group()
2076
2141
        expected_body = (
2077
 
            '-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
2078
 
            Testament.from_revision(repo, 'A').as_short_text() +
2079
 
            '-----END PSEUDO-SIGNED CONTENT-----\n')
 
2142
            b'-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
 
2143
            Testament.from_revision(repo, b'A').as_short_text() +
 
2144
            b'-----END PSEUDO-SIGNED CONTENT-----\n')
2080
2145
        self.assertEqual(
2081
 
            smart_req.SmartServerResponse(('ok', ), expected_body),
2082
 
            request.execute('', 'A'))
 
2146
            smart_req.SmartServerResponse((b'ok', ), expected_body),
 
2147
            request.execute(b'', b'A'))
2083
2148
 
2084
2149
 
2085
2150
class TestSmartServerRepositoryMakeWorkingTrees(
2091
2156
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
2092
2157
        r = self.make_repository('.')
2093
2158
        r.set_make_working_trees(True)
2094
 
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
2095
 
            request.execute('', ))
 
2159
        self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
 
2160
                         request.execute(b'', ))
2096
2161
 
2097
2162
    def test_is_not_shared(self):
2098
2163
        """For a repository with working trees, ('no', ) is returned."""
2100
2165
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
2101
2166
        r = self.make_repository('.')
2102
2167
        r.set_make_working_trees(False)
2103
 
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
2104
 
            request.execute('', ))
 
2168
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
 
2169
                         request.execute(b'', ))
2105
2170
 
2106
2171
 
2107
2172
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
2110
2175
        backing = self.get_transport()
2111
2176
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
2112
2177
        repository = self.make_repository('.', format='knit')
2113
 
        response = request.execute('')
 
2178
        response = request.execute(b'')
2114
2179
        nonce = repository.control_files._lock.peek().get('nonce')
2115
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', nonce)), response)
 
2180
        self.assertEqual(smart_req.SmartServerResponse(
 
2181
            (b'ok', nonce)), response)
2116
2182
        # The repository is now locked.  Verify that with a new repository
2117
2183
        # object.
2118
2184
        new_repo = repository.controldir.open_repository()
2119
2185
        self.assertRaises(errors.LockContention, new_repo.lock_write)
2120
2186
        # Cleanup
2121
2187
        request = smart_repo.SmartServerRepositoryUnlock(backing)
2122
 
        response = request.execute('', nonce)
 
2188
        response = request.execute(b'', nonce)
2123
2189
 
2124
2190
    def test_lock_write_on_locked_repo(self):
2125
2191
        backing = self.get_transport()
2128
2194
        repo_token = repository.lock_write().repository_token
2129
2195
        repository.leave_lock_in_place()
2130
2196
        repository.unlock()
2131
 
        response = request.execute('')
 
2197
        response = request.execute(b'')
2132
2198
        self.assertEqual(
2133
 
            smart_req.SmartServerResponse(('LockContention',)), response)
 
2199
            smart_req.SmartServerResponse((b'LockContention',)), response)
2134
2200
        # Cleanup
2135
2201
        repository.lock_write(repo_token)
2136
2202
        repository.dont_leave_lock_in_place()
2139
2205
    def test_lock_write_on_readonly_transport(self):
2140
2206
        backing = self.get_readonly_transport()
2141
2207
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
2142
 
        repository = self.make_repository('.', format='knit')
2143
 
        response = request.execute('')
 
2208
        self.make_repository('.', format='knit')
 
2209
        response = request.execute(b'')
2144
2210
        self.assertFalse(response.is_successful())
2145
 
        self.assertEqual('LockFailed', response.args[0])
 
2211
        self.assertEqual(b'LockFailed', response.args[0])
2146
2212
 
2147
2213
 
2148
2214
class TestInsertStreamBase(tests.TestCaseWithMemoryTransport):
2149
2215
 
2150
2216
    def make_empty_byte_stream(self, repo):
2151
2217
        byte_stream = smart_repo._stream_to_byte_stream([], repo._format)
2152
 
        return ''.join(byte_stream)
 
2218
        return b''.join(byte_stream)
2153
2219
 
2154
2220
 
2155
2221
class TestSmartServerRepositoryInsertStream(TestInsertStreamBase):
2158
2224
        backing = self.get_transport()
2159
2225
        request = smart_repo.SmartServerRepositoryInsertStream(backing)
2160
2226
        repository = self.make_repository('.')
2161
 
        response = request.execute('', '')
 
2227
        response = request.execute(b'', b'')
2162
2228
        self.assertEqual(None, response)
2163
2229
        response = request.do_chunk(self.make_empty_byte_stream(repository))
2164
2230
        self.assertEqual(None, response)
2165
2231
        response = request.do_end()
2166
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
 
2232
        self.assertEqual(smart_req.SmartServerResponse((b'ok', )), response)
2167
2233
 
2168
2234
 
2169
2235
class TestSmartServerRepositoryInsertStreamLocked(TestInsertStreamBase):
2174
2240
            backing)
2175
2241
        repository = self.make_repository('.', format='knit')
2176
2242
        lock_token = repository.lock_write().repository_token
2177
 
        response = request.execute('', '', lock_token)
 
2243
        response = request.execute(b'', b'', lock_token)
2178
2244
        self.assertEqual(None, response)
2179
2245
        response = request.do_chunk(self.make_empty_byte_stream(repository))
2180
2246
        self.assertEqual(None, response)
2181
2247
        response = request.do_end()
2182
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
 
2248
        self.assertEqual(smart_req.SmartServerResponse((b'ok', )), response)
2183
2249
        repository.unlock()
2184
2250
 
2185
2251
    def test_insert_stream_with_wrong_lock_token(self):
2187
2253
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
2188
2254
            backing)
2189
2255
        repository = self.make_repository('.', format='knit')
2190
 
        lock_token = repository.lock_write().repository_token
2191
 
        self.assertRaises(
2192
 
            errors.TokenMismatch, request.execute, '', '', 'wrong-token')
2193
 
        repository.unlock()
 
2256
        with repository.lock_write():
 
2257
            self.assertRaises(
 
2258
                errors.TokenMismatch, request.execute, b'', b'',
 
2259
                b'wrong-token')
2194
2260
 
2195
2261
 
2196
2262
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
2202
2268
        token = repository.lock_write().repository_token
2203
2269
        repository.leave_lock_in_place()
2204
2270
        repository.unlock()
2205
 
        response = request.execute('', token)
 
2271
        response = request.execute(b'', token)
2206
2272
        self.assertEqual(
2207
 
            smart_req.SmartServerResponse(('ok',)), response)
 
2273
            smart_req.SmartServerResponse((b'ok',)), response)
2208
2274
        # The repository is now unlocked.  Verify that with a new repository
2209
2275
        # object.
2210
2276
        new_repo = repository.controldir.open_repository()
2214
2280
    def test_unlock_on_unlocked_repo(self):
2215
2281
        backing = self.get_transport()
2216
2282
        request = smart_repo.SmartServerRepositoryUnlock(backing)
2217
 
        repository = self.make_repository('.', format='knit')
2218
 
        response = request.execute('', 'some token')
 
2283
        self.make_repository('.', format='knit')
 
2284
        response = request.execute(b'', b'some token')
2219
2285
        self.assertEqual(
2220
 
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
 
2286
            smart_req.SmartServerResponse((b'TokenMismatch',)), response)
2221
2287
 
2222
2288
 
2223
2289
class TestSmartServerRepositoryGetPhysicalLockStatus(
2224
 
    tests.TestCaseWithTransport):
 
2290
        tests.TestCaseWithTransport):
2225
2291
 
2226
2292
    def test_with_write_lock(self):
2227
2293
        backing = self.get_transport()
2230
2296
        # lock_write() doesn't necessarily actually take a physical
2231
2297
        # lock out.
2232
2298
        if repo.get_physical_lock_status():
2233
 
            expected = 'yes'
 
2299
            expected = b'yes'
2234
2300
        else:
2235
 
            expected = 'no'
 
2301
            expected = b'no'
2236
2302
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
2237
2303
        request = request_class(backing)
2238
2304
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((expected,)),
2239
 
            request.execute('', ))
 
2305
                         request.execute(b'', ))
2240
2306
 
2241
2307
    def test_without_write_lock(self):
2242
2308
        backing = self.get_transport()
2244
2310
        self.assertEqual(False, repo.get_physical_lock_status())
2245
2311
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
2246
2312
        request = request_class(backing)
2247
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('no',)),
2248
 
            request.execute('', ))
 
2313
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'no',)),
 
2314
                         request.execute(b'', ))
2249
2315
 
2250
2316
 
2251
2317
class TestSmartServerRepositoryReconcile(tests.TestCaseWithTransport):
2258
2324
        request_class = smart_repo.SmartServerRepositoryReconcile
2259
2325
        request = request_class(backing)
2260
2326
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
2261
 
            ('ok', ),
2262
 
             'garbage_inventories: 0\n'
2263
 
             'inconsistent_parents: 0\n'),
2264
 
            request.execute('', token))
 
2327
            (b'ok', ),
 
2328
            b'garbage_inventories: 0\n'
 
2329
            b'inconsistent_parents: 0\n'),
 
2330
            request.execute(b'', token))
2265
2331
 
2266
2332
 
2267
2333
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
2271
2337
        request = smart_req.SmartServerIsReadonly(backing)
2272
2338
        response = request.execute()
2273
2339
        self.assertEqual(
2274
 
            smart_req.SmartServerResponse(('no',)), response)
 
2340
            smart_req.SmartServerResponse((b'no',)), response)
2275
2341
 
2276
2342
    def test_is_readonly_yes(self):
2277
2343
        backing = self.get_readonly_transport()
2278
2344
        request = smart_req.SmartServerIsReadonly(backing)
2279
2345
        response = request.execute()
2280
2346
        self.assertEqual(
2281
 
            smart_req.SmartServerResponse(('yes',)), response)
 
2347
            smart_req.SmartServerResponse((b'yes',)), response)
2282
2348
 
2283
2349
 
2284
2350
class TestSmartServerRepositorySetMakeWorkingTrees(
2285
 
    tests.TestCaseWithMemoryTransport):
 
2351
        tests.TestCaseWithMemoryTransport):
2286
2352
 
2287
2353
    def test_set_false(self):
2288
2354
        backing = self.get_transport()
2290
2356
        repo.set_make_working_trees(True)
2291
2357
        request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
2292
2358
        request = request_class(backing)
2293
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
2294
 
            request.execute('', 'False'))
 
2359
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
 
2360
                         request.execute(b'', b'False'))
2295
2361
        repo = repo.controldir.open_repository()
2296
2362
        self.assertFalse(repo.make_working_trees())
2297
2363
 
2301
2367
        repo.set_make_working_trees(False)
2302
2368
        request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
2303
2369
        request = request_class(backing)
2304
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
2305
 
            request.execute('', 'True'))
 
2370
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
 
2371
                         request.execute(b'', b'True'))
2306
2372
        repo = repo.controldir.open_repository()
2307
2373
        self.assertTrue(repo.make_working_trees())
2308
2374
 
2309
2375
 
2310
2376
class TestSmartServerRepositoryGetSerializerFormat(
2311
 
    tests.TestCaseWithMemoryTransport):
 
2377
        tests.TestCaseWithMemoryTransport):
2312
2378
 
2313
2379
    def test_get_serializer_format(self):
2314
2380
        backing = self.get_transport()
2316
2382
        request_class = smart_repo.SmartServerRepositoryGetSerializerFormat
2317
2383
        request = request_class(backing)
2318
2384
        self.assertEqual(
2319
 
            smart_req.SuccessfulSmartServerResponse(('ok', '10')),
2320
 
            request.execute(''))
 
2385
            smart_req.SuccessfulSmartServerResponse((b'ok', b'10')),
 
2386
            request.execute(b''))
2321
2387
 
2322
2388
 
2323
2389
class TestSmartServerRepositoryWriteGroup(
2324
 
    tests.TestCaseWithMemoryTransport):
 
2390
        tests.TestCaseWithMemoryTransport):
2325
2391
 
2326
2392
    def test_start_write_group(self):
2327
2393
        backing = self.get_transport()
2330
2396
        self.addCleanup(repo.unlock)
2331
2397
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2332
2398
        request = request_class(backing)
2333
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok', [])),
2334
 
            request.execute('', lock_token))
 
2399
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok', [])),
 
2400
                         request.execute(b'', lock_token))
2335
2401
 
2336
2402
    def test_start_write_group_unsuspendable(self):
2337
2403
        backing = self.get_transport()
2341
2407
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2342
2408
        request = request_class(backing)
2343
2409
        self.assertEqual(
2344
 
            smart_req.FailedSmartServerResponse(('UnsuspendableWriteGroup',)),
2345
 
            request.execute('', lock_token))
 
2410
            smart_req.FailedSmartServerResponse((b'UnsuspendableWriteGroup',)),
 
2411
            request.execute(b'', lock_token))
2346
2412
 
2347
2413
    def test_commit_write_group(self):
2348
2414
        backing = self.get_transport()
2353
2419
        tokens = repo.suspend_write_group()
2354
2420
        request_class = smart_repo.SmartServerRepositoryCommitWriteGroup
2355
2421
        request = request_class(backing)
2356
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
2357
 
            request.execute('', lock_token, tokens))
 
2422
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
 
2423
                         request.execute(b'', lock_token, tokens))
2358
2424
 
2359
2425
    def test_abort_write_group(self):
2360
2426
        backing = self.get_transport()
2365
2431
        self.addCleanup(repo.unlock)
2366
2432
        request_class = smart_repo.SmartServerRepositoryAbortWriteGroup
2367
2433
        request = request_class(backing)
2368
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
2369
 
            request.execute('', lock_token, tokens))
 
2434
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
 
2435
                         request.execute(b'', lock_token, tokens))
2370
2436
 
2371
2437
    def test_check_write_group(self):
2372
2438
        backing = self.get_transport()
2377
2443
        self.addCleanup(repo.unlock)
2378
2444
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2379
2445
        request = request_class(backing)
2380
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
2381
 
            request.execute('', lock_token, tokens))
 
2446
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
 
2447
                         request.execute(b'', lock_token, tokens))
2382
2448
 
2383
2449
    def test_check_write_group_invalid(self):
2384
2450
        backing = self.get_transport()
2388
2454
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2389
2455
        request = request_class(backing)
2390
2456
        self.assertEqual(smart_req.FailedSmartServerResponse(
2391
 
            ('UnresumableWriteGroup', ['random'],
2392
 
                'Malformed write group token')),
2393
 
            request.execute('', lock_token, ["random"]))
 
2457
            (b'UnresumableWriteGroup', [b'random'],
 
2458
                b'Malformed write group token')),
 
2459
            request.execute(b'', lock_token, [b"random"]))
2394
2460
 
2395
2461
 
2396
2462
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
2414
2480
        backing = self.get_transport()
2415
2481
        request = smart_packrepo.SmartServerPackRepositoryAutopack(
2416
2482
            backing)
2417
 
        response = request.execute('')
2418
 
        self.assertEqual(smart_req.SmartServerResponse(('ok',)), response)
 
2483
        response = request.execute(b'')
 
2484
        self.assertEqual(smart_req.SmartServerResponse((b'ok',)), response)
2419
2485
        repo._pack_collection.reload_pack_names()
2420
2486
        self.assertEqual(1, len(repo._pack_collection.names()))
2421
2487
 
2429
2495
        backing = self.get_transport()
2430
2496
        request = smart_packrepo.SmartServerPackRepositoryAutopack(
2431
2497
            backing)
2432
 
        response = request.execute('')
2433
 
        self.assertEqual(smart_req.SmartServerResponse(('ok',)), response)
 
2498
        response = request.execute(b'')
 
2499
        self.assertEqual(smart_req.SmartServerResponse((b'ok',)), response)
2434
2500
        repo._pack_collection.reload_pack_names()
2435
2501
        self.assertEqual(9, len(repo._pack_collection.names()))
2436
2502
 
2440
2506
        backing = self.get_transport()
2441
2507
        request = smart_packrepo.SmartServerPackRepositoryAutopack(
2442
2508
            backing)
2443
 
        response = request.execute('')
2444
 
        self.assertEqual(smart_req.SmartServerResponse(('ok',)), response)
 
2509
        response = request.execute(b'')
 
2510
        self.assertEqual(smart_req.SmartServerResponse((b'ok',)), response)
2445
2511
 
2446
2512
 
2447
2513
class TestSmartServerVfsGet(tests.TestCaseWithMemoryTransport):
2452
2518
        filename_escaped = urlutils.escape(filename)
2453
2519
        backing = self.get_transport()
2454
2520
        request = vfs.GetRequest(backing)
2455
 
        backing.put_bytes_non_atomic(filename_escaped, 'contents')
2456
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'contents'),
2457
 
            request.execute(filename_escaped))
 
2521
        backing.put_bytes_non_atomic(filename_escaped, b'contents')
 
2522
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), b'contents'),
 
2523
                         request.execute(filename_escaped.encode('ascii')))
2458
2524
 
2459
2525
 
2460
2526
class TestHandlers(tests.TestCase):
2475
2541
 
2476
2542
    def test_registered_methods(self):
2477
2543
        """Test that known methods are registered to the correct object."""
2478
 
        self.assertHandlerEqual('Branch.break_lock',
2479
 
            smart_branch.SmartServerBranchBreakLock)
2480
 
        self.assertHandlerEqual('Branch.get_config_file',
2481
 
            smart_branch.SmartServerBranchGetConfigFile)
2482
 
        self.assertHandlerEqual('Branch.put_config_file',
2483
 
            smart_branch.SmartServerBranchPutConfigFile)
2484
 
        self.assertHandlerEqual('Branch.get_parent',
2485
 
            smart_branch.SmartServerBranchGetParent)
2486
 
        self.assertHandlerEqual('Branch.get_physical_lock_status',
2487
 
            smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
2488
 
        self.assertHandlerEqual('Branch.get_tags_bytes',
2489
 
            smart_branch.SmartServerBranchGetTagsBytes)
2490
 
        self.assertHandlerEqual('Branch.lock_write',
2491
 
            smart_branch.SmartServerBranchRequestLockWrite)
2492
 
        self.assertHandlerEqual('Branch.last_revision_info',
2493
 
            smart_branch.SmartServerBranchRequestLastRevisionInfo)
2494
 
        self.assertHandlerEqual('Branch.revision_history',
2495
 
            smart_branch.SmartServerRequestRevisionHistory)
2496
 
        self.assertHandlerEqual('Branch.revision_id_to_revno',
2497
 
            smart_branch.SmartServerBranchRequestRevisionIdToRevno)
2498
 
        self.assertHandlerEqual('Branch.set_config_option',
2499
 
            smart_branch.SmartServerBranchRequestSetConfigOption)
2500
 
        self.assertHandlerEqual('Branch.set_last_revision',
2501
 
            smart_branch.SmartServerBranchRequestSetLastRevision)
2502
 
        self.assertHandlerEqual('Branch.set_last_revision_info',
2503
 
            smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
2504
 
        self.assertHandlerEqual('Branch.set_last_revision_ex',
2505
 
            smart_branch.SmartServerBranchRequestSetLastRevisionEx)
2506
 
        self.assertHandlerEqual('Branch.set_parent_location',
2507
 
            smart_branch.SmartServerBranchRequestSetParentLocation)
2508
 
        self.assertHandlerEqual('Branch.unlock',
2509
 
            smart_branch.SmartServerBranchRequestUnlock)
2510
 
        self.assertHandlerEqual('BzrDir.destroy_branch',
2511
 
            smart_dir.SmartServerBzrDirRequestDestroyBranch)
2512
 
        self.assertHandlerEqual('BzrDir.find_repository',
2513
 
            smart_dir.SmartServerRequestFindRepositoryV1)
2514
 
        self.assertHandlerEqual('BzrDir.find_repositoryV2',
2515
 
            smart_dir.SmartServerRequestFindRepositoryV2)
2516
 
        self.assertHandlerEqual('BzrDirFormat.initialize',
2517
 
            smart_dir.SmartServerRequestInitializeBzrDir)
2518
 
        self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
2519
 
            smart_dir.SmartServerRequestBzrDirInitializeEx)
2520
 
        self.assertHandlerEqual('BzrDir.checkout_metadir',
2521
 
            smart_dir.SmartServerBzrDirRequestCheckoutMetaDir)
2522
 
        self.assertHandlerEqual('BzrDir.cloning_metadir',
2523
 
            smart_dir.SmartServerBzrDirRequestCloningMetaDir)
2524
 
        self.assertHandlerEqual('BzrDir.get_branches',
2525
 
            smart_dir.SmartServerBzrDirRequestGetBranches)
2526
 
        self.assertHandlerEqual('BzrDir.get_config_file',
2527
 
            smart_dir.SmartServerBzrDirRequestConfigFile)
2528
 
        self.assertHandlerEqual('BzrDir.open_branch',
2529
 
            smart_dir.SmartServerRequestOpenBranch)
2530
 
        self.assertHandlerEqual('BzrDir.open_branchV2',
2531
 
            smart_dir.SmartServerRequestOpenBranchV2)
2532
 
        self.assertHandlerEqual('BzrDir.open_branchV3',
2533
 
            smart_dir.SmartServerRequestOpenBranchV3)
2534
 
        self.assertHandlerEqual('PackRepository.autopack',
2535
 
            smart_packrepo.SmartServerPackRepositoryAutopack)
2536
 
        self.assertHandlerEqual('Repository.add_signature_text',
2537
 
            smart_repo.SmartServerRepositoryAddSignatureText)
2538
 
        self.assertHandlerEqual('Repository.all_revision_ids',
2539
 
            smart_repo.SmartServerRepositoryAllRevisionIds)
2540
 
        self.assertHandlerEqual('Repository.break_lock',
2541
 
            smart_repo.SmartServerRepositoryBreakLock)
2542
 
        self.assertHandlerEqual('Repository.gather_stats',
2543
 
            smart_repo.SmartServerRepositoryGatherStats)
2544
 
        self.assertHandlerEqual('Repository.get_parent_map',
2545
 
            smart_repo.SmartServerRepositoryGetParentMap)
2546
 
        self.assertHandlerEqual('Repository.get_physical_lock_status',
2547
 
            smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
2548
 
        self.assertHandlerEqual('Repository.get_rev_id_for_revno',
2549
 
            smart_repo.SmartServerRepositoryGetRevIdForRevno)
2550
 
        self.assertHandlerEqual('Repository.get_revision_graph',
2551
 
            smart_repo.SmartServerRepositoryGetRevisionGraph)
2552
 
        self.assertHandlerEqual('Repository.get_revision_signature_text',
2553
 
            smart_repo.SmartServerRepositoryGetRevisionSignatureText)
2554
 
        self.assertHandlerEqual('Repository.get_stream',
2555
 
            smart_repo.SmartServerRepositoryGetStream)
2556
 
        self.assertHandlerEqual('Repository.get_stream_1.19',
2557
 
            smart_repo.SmartServerRepositoryGetStream_1_19)
2558
 
        self.assertHandlerEqual('Repository.iter_revisions',
2559
 
            smart_repo.SmartServerRepositoryIterRevisions)
2560
 
        self.assertHandlerEqual('Repository.has_revision',
2561
 
            smart_repo.SmartServerRequestHasRevision)
2562
 
        self.assertHandlerEqual('Repository.insert_stream',
2563
 
            smart_repo.SmartServerRepositoryInsertStream)
2564
 
        self.assertHandlerEqual('Repository.insert_stream_locked',
2565
 
            smart_repo.SmartServerRepositoryInsertStreamLocked)
2566
 
        self.assertHandlerEqual('Repository.is_shared',
2567
 
            smart_repo.SmartServerRepositoryIsShared)
2568
 
        self.assertHandlerEqual('Repository.iter_files_bytes',
2569
 
            smart_repo.SmartServerRepositoryIterFilesBytes)
2570
 
        self.assertHandlerEqual('Repository.lock_write',
2571
 
            smart_repo.SmartServerRepositoryLockWrite)
2572
 
        self.assertHandlerEqual('Repository.make_working_trees',
2573
 
            smart_repo.SmartServerRepositoryMakeWorkingTrees)
2574
 
        self.assertHandlerEqual('Repository.pack',
2575
 
            smart_repo.SmartServerRepositoryPack)
2576
 
        self.assertHandlerEqual('Repository.reconcile',
2577
 
            smart_repo.SmartServerRepositoryReconcile)
2578
 
        self.assertHandlerEqual('Repository.tarball',
2579
 
            smart_repo.SmartServerRepositoryTarball)
2580
 
        self.assertHandlerEqual('Repository.unlock',
2581
 
            smart_repo.SmartServerRepositoryUnlock)
2582
 
        self.assertHandlerEqual('Repository.start_write_group',
2583
 
            smart_repo.SmartServerRepositoryStartWriteGroup)
2584
 
        self.assertHandlerEqual('Repository.check_write_group',
2585
 
            smart_repo.SmartServerRepositoryCheckWriteGroup)
2586
 
        self.assertHandlerEqual('Repository.commit_write_group',
2587
 
            smart_repo.SmartServerRepositoryCommitWriteGroup)
2588
 
        self.assertHandlerEqual('Repository.abort_write_group',
2589
 
            smart_repo.SmartServerRepositoryAbortWriteGroup)
2590
 
        self.assertHandlerEqual('VersionedFileRepository.get_serializer_format',
2591
 
            smart_repo.SmartServerRepositoryGetSerializerFormat)
2592
 
        self.assertHandlerEqual('VersionedFileRepository.get_inventories',
2593
 
            smart_repo.SmartServerRepositoryGetInventories)
2594
 
        self.assertHandlerEqual('Transport.is_readonly',
2595
 
            smart_req.SmartServerIsReadonly)
 
2544
        self.assertHandlerEqual(b'Branch.break_lock',
 
2545
                                smart_branch.SmartServerBranchBreakLock)
 
2546
        self.assertHandlerEqual(b'Branch.get_config_file',
 
2547
                                smart_branch.SmartServerBranchGetConfigFile)
 
2548
        self.assertHandlerEqual(b'Branch.put_config_file',
 
2549
                                smart_branch.SmartServerBranchPutConfigFile)
 
2550
        self.assertHandlerEqual(b'Branch.get_parent',
 
2551
                                smart_branch.SmartServerBranchGetParent)
 
2552
        self.assertHandlerEqual(b'Branch.get_physical_lock_status',
 
2553
                                smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
 
2554
        self.assertHandlerEqual(b'Branch.get_tags_bytes',
 
2555
                                smart_branch.SmartServerBranchGetTagsBytes)
 
2556
        self.assertHandlerEqual(b'Branch.lock_write',
 
2557
                                smart_branch.SmartServerBranchRequestLockWrite)
 
2558
        self.assertHandlerEqual(b'Branch.last_revision_info',
 
2559
                                smart_branch.SmartServerBranchRequestLastRevisionInfo)
 
2560
        self.assertHandlerEqual(b'Branch.revision_history',
 
2561
                                smart_branch.SmartServerRequestRevisionHistory)
 
2562
        self.assertHandlerEqual(b'Branch.revision_id_to_revno',
 
2563
                                smart_branch.SmartServerBranchRequestRevisionIdToRevno)
 
2564
        self.assertHandlerEqual(b'Branch.set_config_option',
 
2565
                                smart_branch.SmartServerBranchRequestSetConfigOption)
 
2566
        self.assertHandlerEqual(b'Branch.set_last_revision',
 
2567
                                smart_branch.SmartServerBranchRequestSetLastRevision)
 
2568
        self.assertHandlerEqual(b'Branch.set_last_revision_info',
 
2569
                                smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
 
2570
        self.assertHandlerEqual(b'Branch.set_last_revision_ex',
 
2571
                                smart_branch.SmartServerBranchRequestSetLastRevisionEx)
 
2572
        self.assertHandlerEqual(b'Branch.set_parent_location',
 
2573
                                smart_branch.SmartServerBranchRequestSetParentLocation)
 
2574
        self.assertHandlerEqual(b'Branch.unlock',
 
2575
                                smart_branch.SmartServerBranchRequestUnlock)
 
2576
        self.assertHandlerEqual(b'BzrDir.destroy_branch',
 
2577
                                smart_dir.SmartServerBzrDirRequestDestroyBranch)
 
2578
        self.assertHandlerEqual(b'BzrDir.find_repository',
 
2579
                                smart_dir.SmartServerRequestFindRepositoryV1)
 
2580
        self.assertHandlerEqual(b'BzrDir.find_repositoryV2',
 
2581
                                smart_dir.SmartServerRequestFindRepositoryV2)
 
2582
        self.assertHandlerEqual(b'BzrDirFormat.initialize',
 
2583
                                smart_dir.SmartServerRequestInitializeBzrDir)
 
2584
        self.assertHandlerEqual(b'BzrDirFormat.initialize_ex_1.16',
 
2585
                                smart_dir.SmartServerRequestBzrDirInitializeEx)
 
2586
        self.assertHandlerEqual(b'BzrDir.checkout_metadir',
 
2587
                                smart_dir.SmartServerBzrDirRequestCheckoutMetaDir)
 
2588
        self.assertHandlerEqual(b'BzrDir.cloning_metadir',
 
2589
                                smart_dir.SmartServerBzrDirRequestCloningMetaDir)
 
2590
        self.assertHandlerEqual(b'BzrDir.get_branches',
 
2591
                                smart_dir.SmartServerBzrDirRequestGetBranches)
 
2592
        self.assertHandlerEqual(b'BzrDir.get_config_file',
 
2593
                                smart_dir.SmartServerBzrDirRequestConfigFile)
 
2594
        self.assertHandlerEqual(b'BzrDir.open_branch',
 
2595
                                smart_dir.SmartServerRequestOpenBranch)
 
2596
        self.assertHandlerEqual(b'BzrDir.open_branchV2',
 
2597
                                smart_dir.SmartServerRequestOpenBranchV2)
 
2598
        self.assertHandlerEqual(b'BzrDir.open_branchV3',
 
2599
                                smart_dir.SmartServerRequestOpenBranchV3)
 
2600
        self.assertHandlerEqual(b'PackRepository.autopack',
 
2601
                                smart_packrepo.SmartServerPackRepositoryAutopack)
 
2602
        self.assertHandlerEqual(b'Repository.add_signature_text',
 
2603
                                smart_repo.SmartServerRepositoryAddSignatureText)
 
2604
        self.assertHandlerEqual(b'Repository.all_revision_ids',
 
2605
                                smart_repo.SmartServerRepositoryAllRevisionIds)
 
2606
        self.assertHandlerEqual(b'Repository.break_lock',
 
2607
                                smart_repo.SmartServerRepositoryBreakLock)
 
2608
        self.assertHandlerEqual(b'Repository.gather_stats',
 
2609
                                smart_repo.SmartServerRepositoryGatherStats)
 
2610
        self.assertHandlerEqual(b'Repository.get_parent_map',
 
2611
                                smart_repo.SmartServerRepositoryGetParentMap)
 
2612
        self.assertHandlerEqual(b'Repository.get_physical_lock_status',
 
2613
                                smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
 
2614
        self.assertHandlerEqual(b'Repository.get_rev_id_for_revno',
 
2615
                                smart_repo.SmartServerRepositoryGetRevIdForRevno)
 
2616
        self.assertHandlerEqual(b'Repository.get_revision_graph',
 
2617
                                smart_repo.SmartServerRepositoryGetRevisionGraph)
 
2618
        self.assertHandlerEqual(b'Repository.get_revision_signature_text',
 
2619
                                smart_repo.SmartServerRepositoryGetRevisionSignatureText)
 
2620
        self.assertHandlerEqual(b'Repository.get_stream',
 
2621
                                smart_repo.SmartServerRepositoryGetStream)
 
2622
        self.assertHandlerEqual(b'Repository.get_stream_1.19',
 
2623
                                smart_repo.SmartServerRepositoryGetStream_1_19)
 
2624
        self.assertHandlerEqual(b'Repository.iter_revisions',
 
2625
                                smart_repo.SmartServerRepositoryIterRevisions)
 
2626
        self.assertHandlerEqual(b'Repository.has_revision',
 
2627
                                smart_repo.SmartServerRequestHasRevision)
 
2628
        self.assertHandlerEqual(b'Repository.insert_stream',
 
2629
                                smart_repo.SmartServerRepositoryInsertStream)
 
2630
        self.assertHandlerEqual(b'Repository.insert_stream_locked',
 
2631
                                smart_repo.SmartServerRepositoryInsertStreamLocked)
 
2632
        self.assertHandlerEqual(b'Repository.is_shared',
 
2633
                                smart_repo.SmartServerRepositoryIsShared)
 
2634
        self.assertHandlerEqual(b'Repository.iter_files_bytes',
 
2635
                                smart_repo.SmartServerRepositoryIterFilesBytes)
 
2636
        self.assertHandlerEqual(b'Repository.lock_write',
 
2637
                                smart_repo.SmartServerRepositoryLockWrite)
 
2638
        self.assertHandlerEqual(b'Repository.make_working_trees',
 
2639
                                smart_repo.SmartServerRepositoryMakeWorkingTrees)
 
2640
        self.assertHandlerEqual(b'Repository.pack',
 
2641
                                smart_repo.SmartServerRepositoryPack)
 
2642
        self.assertHandlerEqual(b'Repository.reconcile',
 
2643
                                smart_repo.SmartServerRepositoryReconcile)
 
2644
        self.assertHandlerEqual(b'Repository.tarball',
 
2645
                                smart_repo.SmartServerRepositoryTarball)
 
2646
        self.assertHandlerEqual(b'Repository.unlock',
 
2647
                                smart_repo.SmartServerRepositoryUnlock)
 
2648
        self.assertHandlerEqual(b'Repository.start_write_group',
 
2649
                                smart_repo.SmartServerRepositoryStartWriteGroup)
 
2650
        self.assertHandlerEqual(b'Repository.check_write_group',
 
2651
                                smart_repo.SmartServerRepositoryCheckWriteGroup)
 
2652
        self.assertHandlerEqual(b'Repository.commit_write_group',
 
2653
                                smart_repo.SmartServerRepositoryCommitWriteGroup)
 
2654
        self.assertHandlerEqual(b'Repository.abort_write_group',
 
2655
                                smart_repo.SmartServerRepositoryAbortWriteGroup)
 
2656
        self.assertHandlerEqual(b'VersionedFileRepository.get_serializer_format',
 
2657
                                smart_repo.SmartServerRepositoryGetSerializerFormat)
 
2658
        self.assertHandlerEqual(b'VersionedFileRepository.get_inventories',
 
2659
                                smart_repo.SmartServerRepositoryGetInventories)
 
2660
        self.assertHandlerEqual(b'Transport.is_readonly',
 
2661
                                smart_req.SmartServerIsReadonly)
2596
2662
 
2597
2663
 
2598
2664
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
2606
2672
        """Test the server started hooks get fired properly."""
2607
2673
        started_calls = []
2608
2674
        server.SmartTCPServer.hooks.install_named_hook('server_started',
2609
 
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
2610
 
            None)
 
2675
                                                       lambda backing_urls, url: started_calls.append(
 
2676
                                                           (backing_urls, url)),
 
2677
                                                       None)
2611
2678
        started_ex_calls = []
2612
2679
        server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
2613
 
            lambda backing_urls, url: started_ex_calls.append((backing_urls, url)),
2614
 
            None)
 
2680
                                                       lambda backing_urls, url: started_ex_calls.append(
 
2681
                                                           (backing_urls, url)),
 
2682
                                                       None)
2615
2683
        self.server._sockname = ('example.com', 42)
2616
2684
        self.server.run_server_started_hooks()
2617
2685
        self.assertEqual(started_calls,
2618
 
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2686
                         [([self.get_transport().base], 'bzr://example.com:42/')])
2619
2687
        self.assertEqual(started_ex_calls,
2620
 
            [([self.get_transport().base], self.server)])
 
2688
                         [([self.get_transport().base], self.server)])
2621
2689
 
2622
2690
    def test_run_server_started_hooks_ipv6(self):
2623
2691
        """Test that socknames can contain 4-tuples."""
2624
2692
        self.server._sockname = ('::', 42, 0, 0)
2625
2693
        started_calls = []
2626
2694
        server.SmartTCPServer.hooks.install_named_hook('server_started',
2627
 
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
2628
 
            None)
 
2695
                                                       lambda backing_urls, url: started_calls.append(
 
2696
                                                           (backing_urls, url)),
 
2697
                                                       None)
2629
2698
        self.server.run_server_started_hooks()
2630
2699
        self.assertEqual(started_calls,
2631
 
                [([self.get_transport().base], 'bzr://:::42/')])
 
2700
                         [([self.get_transport().base], 'bzr://:::42/')])
2632
2701
 
2633
2702
    def test_run_server_stopped_hooks(self):
2634
2703
        """Test the server stopped hooks."""
2635
2704
        self.server._sockname = ('example.com', 42)
2636
2705
        stopped_calls = []
2637
2706
        server.SmartTCPServer.hooks.install_named_hook('server_stopped',
2638
 
            lambda backing_urls, url: stopped_calls.append((backing_urls, url)),
2639
 
            None)
 
2707
                                                       lambda backing_urls, url: stopped_calls.append(
 
2708
                                                           (backing_urls, url)),
 
2709
                                                       None)
2640
2710
        self.server.run_server_stopped_hooks()
2641
2711
        self.assertEqual(stopped_calls,
2642
 
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2712
                         [([self.get_transport().base], 'bzr://example.com:42/')])
2643
2713
 
2644
2714
 
2645
2715
class TestSmartServerRepositoryPack(tests.TestCaseWithMemoryTransport):
2650
2720
        tree = self.make_branch_and_memory_tree('.')
2651
2721
        repo_token = tree.branch.repository.lock_write().repository_token
2652
2722
 
2653
 
        self.assertIs(None, request.execute('', repo_token, False))
 
2723
        self.assertIs(None, request.execute(b'', repo_token, False))
2654
2724
 
2655
2725
        self.assertEqual(
2656
 
            smart_req.SuccessfulSmartServerResponse(('ok', ), ),
2657
 
            request.do_body(''))
 
2726
            smart_req.SuccessfulSmartServerResponse((b'ok', ), ),
 
2727
            request.do_body(b''))
2658
2728
 
2659
2729
 
2660
2730
class TestSmartServerRepositoryGetInventories(tests.TestCaseWithTransport):
2663
2733
        base_inv = repository.revision_tree(base_revid).root_inventory
2664
2734
        inv = repository.revision_tree(revid).root_inventory
2665
2735
        inv_delta = inv._make_delta(base_inv)
2666
 
        serializer = inventory_delta.InventoryDeltaSerializer(True, False)
2667
 
        return "".join(serializer.delta_to_lines(base_revid, revid, inv_delta))
 
2736
        serializer = inventory_delta.InventoryDeltaSerializer(True, True)
 
2737
        return b"".join(serializer.delta_to_lines(base_revid, revid, inv_delta))
2668
2738
 
2669
2739
    def test_single(self):
2670
2740
        backing = self.get_transport()
2671
2741
        request = smart_repo.SmartServerRepositoryGetInventories(backing)
2672
2742
        t = self.make_branch_and_tree('.', format='2a')
2673
2743
        self.addCleanup(t.lock_write().unlock)
2674
 
        self.build_tree_contents([("file", "somecontents")])
2675
 
        t.add(["file"], ["thefileid"])
2676
 
        t.commit(rev_id='somerev', message="add file")
2677
 
        self.assertIs(None, request.execute('', 'unordered'))
2678
 
        response = request.do_body("somerev\n")
 
2744
        self.build_tree_contents([("file", b"somecontents")])
 
2745
        t.add(["file"], [b"thefileid"])
 
2746
        t.commit(rev_id=b'somerev', message="add file")
 
2747
        self.assertIs(None, request.execute(b'', b'unordered'))
 
2748
        response = request.do_body(b"somerev\n")
2679
2749
        self.assertTrue(response.is_successful())
2680
 
        self.assertEqual(response.args, ("ok", ))
 
2750
        self.assertEqual(response.args, (b"ok", ))
2681
2751
        stream = [('inventory-deltas', [
2682
 
            versionedfile.FulltextContentFactory('somerev', None, None,
2683
 
                self._get_serialized_inventory_delta(
2684
 
                    t.branch.repository, 'null:', 'somerev'))])]
 
2752
            versionedfile.FulltextContentFactory(b'somerev', None, None,
 
2753
                                                 self._get_serialized_inventory_delta(
 
2754
                                                     t.branch.repository, b'null:', b'somerev'))])]
2685
2755
        fmt = controldir.format_registry.get('2a')().repository_format
2686
2756
        self.assertEqual(
2687
 
            "".join(response.body_stream),
2688
 
            "".join(smart_repo._stream_to_byte_stream(stream, fmt)))
 
2757
            b"".join(response.body_stream),
 
2758
            b"".join(smart_repo._stream_to_byte_stream(stream, fmt)))
2689
2759
 
2690
2760
    def test_empty(self):
2691
2761
        backing = self.get_transport()
2692
2762
        request = smart_repo.SmartServerRepositoryGetInventories(backing)
2693
2763
        t = self.make_branch_and_tree('.', format='2a')
2694
2764
        self.addCleanup(t.lock_write().unlock)
2695
 
        self.build_tree_contents([("file", "somecontents")])
2696
 
        t.add(["file"], ["thefileid"])
2697
 
        t.commit(rev_id='somerev', message="add file")
2698
 
        self.assertIs(None, request.execute('', 'unordered'))
2699
 
        response = request.do_body("")
2700
 
        self.assertTrue(response.is_successful())
2701
 
        self.assertEqual(response.args, ("ok", ))
2702
 
        self.assertEqual("".join(response.body_stream),
2703
 
            "Bazaar pack format 1 (introduced in 0.18)\nB54\n\nBazaar repository format 2a (needs bzr 1.16 or later)\nE")
 
2765
        self.build_tree_contents([("file", b"somecontents")])
 
2766
        t.add(["file"], [b"thefileid"])
 
2767
        t.commit(rev_id=b'somerev', message="add file")
 
2768
        self.assertIs(None, request.execute(b'', b'unordered'))
 
2769
        response = request.do_body(b"")
 
2770
        self.assertTrue(response.is_successful())
 
2771
        self.assertEqual(response.args, (b"ok", ))
 
2772
        self.assertEqual(b"".join(response.body_stream),
 
2773
                         b"Bazaar pack format 1 (introduced in 0.18)\nB54\n\nBazaar repository format 2a (needs bzr 1.16 or later)\nE")
 
2774
 
 
2775
 
 
2776
class TestSmartServerRepositoryGetStreamForMissingKeys(GetStreamTestBase):
 
2777
 
 
2778
    def test_missing(self):
 
2779
        """The search argument may be a 'ancestry-of' some heads'."""
 
2780
        backing = self.get_transport()
 
2781
        request = smart_repo.SmartServerRepositoryGetStreamForMissingKeys(
 
2782
            backing)
 
2783
        repo, r1, r2 = self.make_two_commit_repo()
 
2784
        request.execute(b'', repo._format.network_name())
 
2785
        lines = b'inventories\t' + r1
 
2786
        response = request.do_body(lines)
 
2787
        self.assertEqual((b'ok',), response.args)
 
2788
        stream_bytes = b''.join(response.body_stream)
 
2789
        self.assertStartsWith(stream_bytes, b'Bazaar pack format 1')
 
2790
 
 
2791
    def test_unknown_format(self):
 
2792
        """The format may not be known by the remote server."""
 
2793
        backing = self.get_transport()
 
2794
        request = smart_repo.SmartServerRepositoryGetStreamForMissingKeys(
 
2795
            backing)
 
2796
        repo, r1, r2 = self.make_two_commit_repo()
 
2797
        request.execute(b'', b'yada yada yada')
 
2798
        expected = smart_req.FailedSmartServerResponse(
 
2799
            (b'UnknownFormat', b'repository', b'yada yada yada'))
 
2800
 
 
2801
 
 
2802
class TestSmartServerRepositoryRevisionArchive(tests.TestCaseWithTransport):
 
2803
    def test_get(self):
 
2804
        backing = self.get_transport()
 
2805
        request = smart_repo.SmartServerRepositoryRevisionArchive(backing)
 
2806
        t = self.make_branch_and_tree('.')
 
2807
        self.addCleanup(t.lock_write().unlock)
 
2808
        self.build_tree_contents([("file", b"somecontents")])
 
2809
        t.add(["file"], [b"thefileid"])
 
2810
        t.commit(rev_id=b'somerev', message="add file")
 
2811
        response = request.execute(b'', b"somerev", b"tar", b"foo.tar", b"foo")
 
2812
        self.assertTrue(response.is_successful())
 
2813
        self.assertEqual(response.args, (b"ok", ))
 
2814
        b = BytesIO(b"".join(response.body_stream))
 
2815
        with tarfile.open(mode='r', fileobj=b) as tf:
 
2816
            self.assertEqual(['foo/file'], tf.getnames())
 
2817
 
 
2818
 
 
2819
class TestSmartServerRepositoryAnnotateFileRevision(tests.TestCaseWithTransport):
 
2820
 
 
2821
    def test_get(self):
 
2822
        backing = self.get_transport()
 
2823
        request = smart_repo.SmartServerRepositoryAnnotateFileRevision(backing)
 
2824
        t = self.make_branch_and_tree('.')
 
2825
        self.addCleanup(t.lock_write().unlock)
 
2826
        self.build_tree_contents([("file", b"somecontents\nmorecontents\n")])
 
2827
        t.add(["file"], [b"thefileid"])
 
2828
        t.commit(rev_id=b'somerev', message="add file")
 
2829
        response = request.execute(b'', b"somerev", b"file")
 
2830
        self.assertTrue(response.is_successful())
 
2831
        self.assertEqual(response.args, (b"ok", ))
 
2832
        self.assertEqual(
 
2833
            [[b'somerev', b'somecontents\n'], [b'somerev', b'morecontents\n']],
 
2834
            bencode.bdecode(response.body))
 
2835
 
 
2836
 
 
2837
class TestSmartServerBranchRequestGetAllReferenceInfo(TestLockedBranch):
 
2838
 
 
2839
    def test_get_some(self):
 
2840
        backing = self.get_transport()
 
2841
        request = smart_branch.SmartServerBranchRequestGetAllReferenceInfo(backing)
 
2842
        branch = self.make_branch('.')
 
2843
        branch.set_reference_info('some/path', 'http://www.example.com/')
 
2844
        response = request.execute(b'')
 
2845
        self.assertTrue(response.is_successful())
 
2846
        self.assertEqual(response.args, (b"ok", ))
 
2847
        self.assertEqual(
 
2848
            [[b'some/path', b'http://www.example.com/', b'']],
 
2849
            bencode.bdecode(response.body))