/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: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2018-03-25 11:54:30 UTC
  • mfrom: (6855.4.10 more-bees)
  • Revision ID: breezy.the.bot@gmail.com-20180325115430-75xnlbrmzjoomd83
Add more bees. In particular:

* for file ids
* for revision ids
* for file contents in build_tree_contents()

Merged from https://code.launchpad.net/~jelmer/brz/more-bees/+merge/337919

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2012, 2016 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
25
25
"""
26
26
 
27
27
import bz2
28
 
from cStringIO import StringIO
29
 
import tarfile
 
28
import zlib
30
29
 
31
 
from bzrlib import (
 
30
from breezy import (
32
31
    bencode,
33
32
    branch as _mod_branch,
34
 
    bzrdir,
 
33
    controldir,
35
34
    errors,
36
 
    pack,
 
35
    gpg,
37
36
    tests,
38
37
    transport,
39
38
    urlutils,
 
39
    )
 
40
from breezy.bzr import (
 
41
    branch as _mod_bzrbranch,
 
42
    inventory_delta,
40
43
    versionedfile,
41
44
    )
42
 
from bzrlib.smart import (
 
45
from breezy.bzr.smart import (
43
46
    branch as smart_branch,
44
47
    bzrdir as smart_dir,
45
48
    repository as smart_repo,
48
51
    server,
49
52
    vfs,
50
53
    )
51
 
from bzrlib.tests import test_server
52
 
from bzrlib.transport import (
 
54
from breezy.testament import Testament
 
55
from breezy.tests import test_server
 
56
from breezy.transport import (
53
57
    chroot,
54
58
    memory,
55
59
    )
56
60
 
57
61
 
58
 
def load_tests(standard_tests, module, loader):
 
62
def load_tests(loader, standard_tests, pattern):
59
63
    """Multiply tests version and protocol consistency."""
60
64
    # FindRepository tests.
61
65
    scenarios = [
81
85
 
82
86
    def setUp(self):
83
87
        self.vfs_transport_factory = memory.MemoryServer
84
 
        tests.TestCaseWithTransport.setUp(self)
 
88
        super(TestCaseWithChrootedTransport, self).setUp()
85
89
        self._chroot_server = None
86
90
 
87
91
    def get_transport(self, relpath=None):
89
93
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
90
94
            self._chroot_server = chroot.ChrootServer(backing_transport)
91
95
            self.start_server(self._chroot_server)
92
 
        t = transport.get_transport(self._chroot_server.get_url())
 
96
        t = transport.get_transport_from_url(self._chroot_server.get_url())
93
97
        if relpath is not None:
94
98
            t = t.clone(relpath)
95
99
        return t
103
107
        # the default or a parameterized class, but rather use the
104
108
        # TestCaseWithTransport infrastructure to set up a smart server and
105
109
        # transport.
106
 
        self.transport_server = self.make_transport_server
 
110
        self.overrideAttr(self, "transport_server", self.make_transport_server)
107
111
 
108
112
    def make_transport_server(self):
109
113
        return test_server.SmartTCPServer_for_testing('-' + self.id())
118
122
    def test_repeated_substreams_same_kind_are_one_stream(self):
119
123
        # Make a stream - an iterable of bytestrings.
120
124
        stream = [('text', [versionedfile.FulltextContentFactory(('k1',), None,
121
 
            None, 'foo')]),('text', [
 
125
            None, 'foo')]), ('text', [
122
126
            versionedfile.FulltextContentFactory(('k2',), None, None, 'bar')])]
123
 
        fmt = bzrdir.format_registry.get('pack-0.92')().repository_format
 
127
        fmt = controldir.format_registry.get('pack-0.92')().repository_format
124
128
        bytes = smart_repo._stream_to_byte_stream(stream, fmt)
125
129
        streams = []
126
130
        # Iterate the resulting iterable; checking that we get only one stream
163
167
        request = smart_req.SmartServerRequest(transport, 'foo/')
164
168
        self.assertEqual('./', request.translate_client_path('foo/'))
165
169
        self.assertRaises(
166
 
            errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
 
170
            urlutils.InvalidURLJoin, request.translate_client_path, 'foo/..')
167
171
        self.assertRaises(
168
172
            errors.PathNotChild, request.translate_client_path, '/')
169
173
        self.assertRaises(
197
201
    def test_cloning_metadir(self):
198
202
        """When there is a bzrdir present, the call succeeds."""
199
203
        backing = self.get_transport()
200
 
        dir = self.make_bzrdir('.')
 
204
        dir = self.make_controldir('.')
201
205
        local_result = dir.cloning_metadir()
202
206
        request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
203
207
        request = request_class(backing)
211
215
        """The request fails when bzrdir contains a branch reference."""
212
216
        backing = self.get_transport()
213
217
        referenced_branch = self.make_branch('referenced')
214
 
        dir = self.make_bzrdir('.')
 
218
        dir = self.make_controldir('.')
215
219
        local_result = dir.cloning_metadir()
216
 
        reference = _mod_branch.BranchReferenceFormat().initialize(
 
220
        reference = _mod_bzrbranch.BranchReferenceFormat().initialize(
217
221
            dir, target_branch=referenced_branch)
218
 
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(dir)
 
222
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(dir)
219
223
        # The server shouldn't try to follow the branch reference, so it's fine
220
224
        # if the referenced branch isn't reachable.
221
225
        backing.rename('referenced', 'moved')
225
229
        self.assertEqual(expected, request.execute('', 'False'))
226
230
 
227
231
 
 
232
class TestSmartServerBzrDirRequestCloningMetaDir(
 
233
    tests.TestCaseWithMemoryTransport):
 
234
    """Tests for BzrDir.checkout_metadir."""
 
235
 
 
236
    def test_checkout_metadir(self):
 
237
        backing = self.get_transport()
 
238
        request = smart_dir.SmartServerBzrDirRequestCheckoutMetaDir(
 
239
            backing)
 
240
        branch = self.make_branch('.', format='2a')
 
241
        response = request.execute('')
 
242
        self.assertEqual(
 
243
            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')),
 
247
            response)
 
248
 
 
249
 
 
250
class TestSmartServerBzrDirRequestDestroyBranch(
 
251
    tests.TestCaseWithMemoryTransport):
 
252
    """Tests for BzrDir.destroy_branch."""
 
253
 
 
254
    def test_destroy_branch_default(self):
 
255
        """The default branch can be removed."""
 
256
        backing = self.get_transport()
 
257
        dir = self.make_branch('.').controldir
 
258
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
259
        request = request_class(backing)
 
260
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
261
        self.assertEqual(expected, request.execute('', None))
 
262
 
 
263
    def test_destroy_branch_named(self):
 
264
        """A named branch can be removed."""
 
265
        backing = self.get_transport()
 
266
        dir = self.make_repository('.', format="development-colo").controldir
 
267
        dir.create_branch(name="branchname")
 
268
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
269
        request = request_class(backing)
 
270
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
271
        self.assertEqual(expected, request.execute('', "branchname"))
 
272
 
 
273
    def test_destroy_branch_missing(self):
 
274
        """An error is raised if the branch didn't exist."""
 
275
        backing = self.get_transport()
 
276
        dir = self.make_controldir('.', format="development-colo")
 
277
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
278
        request = request_class(backing)
 
279
        expected = smart_req.FailedSmartServerResponse(('nobranch',), None)
 
280
        self.assertEqual(expected, request.execute('', "branchname"))
 
281
 
 
282
 
 
283
class TestSmartServerBzrDirRequestHasWorkingTree(
 
284
    tests.TestCaseWithTransport):
 
285
    """Tests for BzrDir.has_workingtree."""
 
286
 
 
287
    def test_has_workingtree_yes(self):
 
288
        """A working tree is present."""
 
289
        backing = self.get_transport()
 
290
        dir = self.make_branch_and_tree('.').controldir
 
291
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
 
292
        request = request_class(backing)
 
293
        expected = smart_req.SuccessfulSmartServerResponse(('yes',))
 
294
        self.assertEqual(expected, request.execute(''))
 
295
 
 
296
    def test_has_workingtree_no(self):
 
297
        """A working tree is missing."""
 
298
        backing = self.get_transport()
 
299
        dir = self.make_controldir('.')
 
300
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
 
301
        request = request_class(backing)
 
302
        expected = smart_req.SuccessfulSmartServerResponse(('no',))
 
303
        self.assertEqual(expected, request.execute(''))
 
304
 
 
305
 
 
306
class TestSmartServerBzrDirRequestDestroyRepository(
 
307
    tests.TestCaseWithMemoryTransport):
 
308
    """Tests for BzrDir.destroy_repository."""
 
309
 
 
310
    def test_destroy_repository_default(self):
 
311
        """The repository can be removed."""
 
312
        backing = self.get_transport()
 
313
        dir = self.make_repository('.').controldir
 
314
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
 
315
        request = request_class(backing)
 
316
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
317
        self.assertEqual(expected, request.execute(''))
 
318
 
 
319
    def test_destroy_repository_missing(self):
 
320
        """An error is raised if the repository didn't exist."""
 
321
        backing = self.get_transport()
 
322
        dir = self.make_controldir('.')
 
323
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
 
324
        request = request_class(backing)
 
325
        expected = smart_req.FailedSmartServerResponse(
 
326
            ('norepository',), None)
 
327
        self.assertEqual(expected, request.execute(''))
 
328
 
 
329
 
228
330
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
229
331
    """Tests for BzrDir.create_repository."""
230
332
 
231
333
    def test_makes_repository(self):
232
334
        """When there is a bzrdir present, the call succeeds."""
233
335
        backing = self.get_transport()
234
 
        self.make_bzrdir('.')
 
336
        self.make_controldir('.')
235
337
        request_class = smart_dir.SmartServerRequestCreateRepository
236
338
        request = request_class(backing)
237
 
        reference_bzrdir_format = bzrdir.format_registry.get('pack-0.92')()
 
339
        reference_bzrdir_format = controldir.format_registry.get('pack-0.92')()
238
340
        reference_format = reference_bzrdir_format.repository_format
239
341
        network_name = reference_format.network_name()
240
342
        expected = smart_req.SuccessfulSmartServerResponse(
249
351
        """When there is no repository to be found, ('norepository', ) is returned."""
250
352
        backing = self.get_transport()
251
353
        request = self._request_class(backing)
252
 
        self.make_bzrdir('.')
 
354
        self.make_controldir('.')
253
355
        self.assertEqual(smart_req.SmartServerResponse(('norepository', )),
254
356
            request.execute(''))
255
357
 
261
363
        request = self._request_class(backing)
262
364
        result = self._make_repository_and_result()
263
365
        self.assertEqual(result, request.execute(''))
264
 
        self.make_bzrdir('subdir')
 
366
        self.make_controldir('subdir')
265
367
        self.assertEqual(smart_req.SmartServerResponse(('norepository', )),
266
368
            request.execute('subdir'))
267
369
 
304
406
        request = self._request_class(backing)
305
407
        result = self._make_repository_and_result(shared=True)
306
408
        self.assertEqual(result, request.execute(''))
307
 
        self.make_bzrdir('subdir')
 
409
        self.make_controldir('subdir')
308
410
        result2 = smart_req.SmartServerResponse(
309
411
            result.args[0:1] + ('..', ) + result.args[2:])
310
412
        self.assertEqual(result2,
311
413
            request.execute('subdir'))
312
 
        self.make_bzrdir('subdir/deeper')
 
414
        self.make_controldir('subdir/deeper')
313
415
        result3 = smart_req.SmartServerResponse(
314
416
            result.args[0:1] + ('../..', ) + result.args[2:])
315
417
        self.assertEqual(result3,
320
422
        backing = self.get_transport()
321
423
        request = self._request_class(backing)
322
424
        result = self._make_repository_and_result(
323
 
            format='dirstate-with-subtree')
 
425
            format='development-subtree')
324
426
        # check the test will be valid
325
427
        self.assertEqual('yes', result.args[2])
326
428
        self.assertEqual('yes', result.args[3])
331
433
        backing = self.get_transport()
332
434
        request = self._request_class(backing)
333
435
        result = self._make_repository_and_result(
334
 
            format='dirstate-with-subtree')
 
436
            format='development-subtree')
335
437
        # check the test will be valid
336
 
        self.assertEqual('no', result.args[4])
 
438
        self.assertEqual('yes', result.args[4])
337
439
        self.assertEqual(result, request.execute(''))
338
440
 
339
441
 
343
445
 
344
446
    def test_present(self):
345
447
        backing = self.get_transport()
346
 
        dir = self.make_bzrdir('.')
 
448
        dir = self.make_controldir('.')
347
449
        dir.get_config().set_default_stack_on("/")
348
450
        local_result = dir._get_config()._get_config_file().read()
349
451
        request_class = smart_dir.SmartServerBzrDirRequestConfigFile
353
455
 
354
456
    def test_missing(self):
355
457
        backing = self.get_transport()
356
 
        dir = self.make_bzrdir('.')
 
458
        dir = self.make_controldir('.')
357
459
        request_class = smart_dir.SmartServerBzrDirRequestConfigFile
358
460
        request = request_class(backing)
359
461
        expected = smart_req.SuccessfulSmartServerResponse((), '')
360
462
        self.assertEqual(expected, request.execute(''))
361
463
 
362
464
 
 
465
class TestSmartServerBzrDirRequestGetBranches(
 
466
    tests.TestCaseWithMemoryTransport):
 
467
    """Tests for BzrDir.get_branches."""
 
468
 
 
469
    def test_simple(self):
 
470
        backing = self.get_transport()
 
471
        branch = self.make_branch('.')
 
472
        request_class = smart_dir.SmartServerBzrDirRequestGetBranches
 
473
        request = request_class(backing)
 
474
        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(''))
 
479
 
 
480
    def test_empty(self):
 
481
        backing = self.get_transport()
 
482
        dir = self.make_controldir('.')
 
483
        request_class = smart_dir.SmartServerBzrDirRequestGetBranches
 
484
        request = request_class(backing)
 
485
        local_result = bencode.bencode({})
 
486
        expected = smart_req.SuccessfulSmartServerResponse(
 
487
            ('success',), local_result)
 
488
        self.assertEqual(expected, request.execute(''))
 
489
 
 
490
 
363
491
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
364
492
 
365
493
    def test_empty_dir(self):
368
496
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
369
497
        self.assertEqual(smart_req.SmartServerResponse(('ok', )),
370
498
            request.execute(''))
371
 
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
 
499
        made_dir = controldir.ControlDir.open_from_transport(backing)
372
500
        # no branch, tree or repository is expected with the current
373
501
        # default formart.
374
502
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
386
514
        """Initializing an extant bzrdir should fail like the bzrdir api."""
387
515
        backing = self.get_transport()
388
516
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
389
 
        self.make_bzrdir('subdir')
390
 
        self.assertRaises(errors.FileExists,
 
517
        self.make_controldir('subdir')
 
518
        self.assertRaises(errors.AlreadyControlDirError,
391
519
            request.execute, 'subdir')
392
520
 
393
521
 
401
529
    def test_empty_dir(self):
402
530
        """Initializing an empty dir should succeed and do it."""
403
531
        backing = self.get_transport()
404
 
        name = self.make_bzrdir('reference')._format.network_name()
 
532
        name = self.make_controldir('reference')._format.network_name()
405
533
        request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
406
534
        self.assertEqual(
407
535
            smart_req.SmartServerResponse(('', '', '', '', '', '', name,
408
536
                                           'False', '', '', '')),
409
537
            request.execute(name, '', 'True', 'False', 'False', '', '', '', '',
410
538
                            'False'))
411
 
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
 
539
        made_dir = controldir.ControlDir.open_from_transport(backing)
412
540
        # no branch, tree or repository is expected with the current
413
541
        # default format.
414
542
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
418
546
    def test_missing_dir(self):
419
547
        """Initializing a missing directory should fail like the bzrdir api."""
420
548
        backing = self.get_transport()
421
 
        name = self.make_bzrdir('reference')._format.network_name()
 
549
        name = self.make_controldir('reference')._format.network_name()
422
550
        request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
423
551
        self.assertRaises(errors.NoSuchFile, request.execute, name,
424
552
            'subdir/dir', 'False', 'False', 'False', '', '', '', '', 'False')
426
554
    def test_initialized_dir(self):
427
555
        """Initializing an extant directory should fail like the bzrdir api."""
428
556
        backing = self.get_transport()
429
 
        name = self.make_bzrdir('reference')._format.network_name()
 
557
        name = self.make_controldir('reference')._format.network_name()
430
558
        request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
431
 
        self.make_bzrdir('subdir')
 
559
        self.make_controldir('subdir')
432
560
        self.assertRaises(errors.FileExists, request.execute, name, 'subdir',
433
561
            'False', 'False', 'False', '', '', '', '', 'False')
434
562
 
474
602
    def test_present_without_workingtree(self):
475
603
        backing = self.get_transport()
476
604
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
477
 
        self.make_bzrdir('.')
 
605
        self.make_controldir('.')
478
606
        self.assertEqual(smart_req.SmartServerResponse(('yes', 'no')),
479
607
            request.execute(''))
480
608
 
492
620
        self.vfs_transport_factory = test_server.LocalURLServer
493
621
        backing = self.get_transport()
494
622
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
495
 
        bd = self.make_bzrdir('.')
 
623
        bd = self.make_controldir('.')
496
624
        bd.create_repository()
497
625
        bd.create_branch()
498
626
        bd.create_workingtree()
506
634
        """When there is no branch, ('nobranch', ) is returned."""
507
635
        backing = self.get_transport()
508
636
        request = smart_dir.SmartServerRequestOpenBranch(backing)
509
 
        self.make_bzrdir('.')
 
637
        self.make_controldir('.')
510
638
        self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
511
639
            request.execute(''))
512
640
 
524
652
        backing = self.get_transport()
525
653
        request = smart_dir.SmartServerRequestOpenBranch(backing)
526
654
        branch = self.make_branch('branch')
527
 
        checkout = branch.create_checkout('reference',lightweight=True)
528
 
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(
529
 
            checkout.bzrdir)
 
655
        checkout = branch.create_checkout('reference', lightweight=True)
 
656
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(
 
657
            checkout.controldir)
530
658
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
531
659
        self.assertEqual(smart_req.SmartServerResponse(('ok', reference_url)),
532
660
            request.execute('reference'))
545
673
    def test_no_branch(self):
546
674
        """When there is no branch, ('nobranch', ) is returned."""
547
675
        backing = self.get_transport()
548
 
        self.make_bzrdir('.')
 
676
        self.make_controldir('.')
549
677
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
550
678
        self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
551
679
            request.execute(''))
565
693
        backing = self.get_transport()
566
694
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
567
695
        branch = self.make_branch('branch')
568
 
        checkout = branch.create_checkout('reference',lightweight=True)
569
 
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(
570
 
            checkout.bzrdir)
 
696
        checkout = branch.create_checkout('reference', lightweight=True)
 
697
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(
 
698
            checkout.controldir)
571
699
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
572
700
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
573
701
                ('ref', reference_url)),
608
736
    def test_no_branch(self):
609
737
        """When there is no branch, ('nobranch', ) is returned."""
610
738
        backing = self.get_transport()
611
 
        self.make_bzrdir('.')
 
739
        self.make_controldir('.')
612
740
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
613
741
        self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
614
742
            request.execute(''))
628
756
        backing = self.get_transport()
629
757
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
630
758
        branch = self.make_branch('branch')
631
 
        checkout = branch.create_checkout('reference',lightweight=True)
632
 
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(
633
 
            checkout.bzrdir)
 
759
        checkout = branch.create_checkout('reference', lightweight=True)
 
760
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(
 
761
            checkout.controldir)
634
762
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
635
763
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
636
764
                ('ref', reference_url)),
698
826
        """When there is a bzrdir and no branch, NotBranchError is raised."""
699
827
        backing = self.get_transport()
700
828
        request = smart_branch.SmartServerBranchRequest(backing)
701
 
        self.make_bzrdir('.')
 
829
        self.make_controldir('.')
702
830
        self.assertRaises(errors.NotBranchError,
703
831
            request.execute, '')
704
832
 
707
835
        backing = self.get_transport()
708
836
        request = smart_branch.SmartServerBranchRequest(backing)
709
837
        branch = self.make_branch('branch')
710
 
        checkout = branch.create_checkout('reference',lightweight=True)
 
838
        checkout = branch.create_checkout('reference', lightweight=True)
711
839
        self.assertRaises(errors.NotBranchError,
712
840
            request.execute, 'checkout')
713
841
 
739
867
            request.execute(''))
740
868
 
741
869
 
 
870
class TestSmartServerBranchRequestRevisionIdToRevno(
 
871
    tests.TestCaseWithMemoryTransport):
 
872
 
 
873
    def test_null(self):
 
874
        backing = self.get_transport()
 
875
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
876
            backing)
 
877
        self.make_branch('.')
 
878
        self.assertEqual(smart_req.SmartServerResponse(('ok', '0')),
 
879
            request.execute('', 'null:'))
 
880
 
 
881
    def test_simple(self):
 
882
        backing = self.get_transport()
 
883
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
884
            backing)
 
885
        tree = self.make_branch_and_memory_tree('.')
 
886
        tree.lock_write()
 
887
        tree.add('')
 
888
        r1 = tree.commit('1st commit')
 
889
        tree.unlock()
 
890
        self.assertEqual(
 
891
            smart_req.SmartServerResponse(('ok', '1')),
 
892
            request.execute('', r1))
 
893
 
 
894
    def test_not_found(self):
 
895
        backing = self.get_transport()
 
896
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
897
            backing)
 
898
        branch = self.make_branch('.')
 
899
        self.assertEqual(
 
900
            smart_req.FailedSmartServerResponse(
 
901
                ('NoSuchRevision', 'idontexist')),
 
902
            request.execute('', 'idontexist'))
 
903
 
 
904
 
742
905
class TestSmartServerBranchRequestGetConfigFile(
743
906
    tests.TestCaseWithMemoryTransport):
744
907
 
767
930
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
768
931
 
769
932
    def get_lock_tokens(self, branch):
770
 
        branch_token = branch.lock_write()
771
 
        repo_token = branch.repository.lock_write()
 
933
        branch_token = branch.lock_write().token
 
934
        repo_token = branch.repository.lock_write().repository_token
772
935
        branch.repository.unlock()
773
936
        return branch_token, repo_token
774
937
 
775
938
 
 
939
class TestSmartServerBranchRequestPutConfigFile(TestLockedBranch):
 
940
 
 
941
    def test_with_content(self):
 
942
        backing = self.get_transport()
 
943
        request = smart_branch.SmartServerBranchPutConfigFile(backing)
 
944
        branch = self.make_branch('.')
 
945
        branch_token, repo_token = self.get_lock_tokens(branch)
 
946
        self.assertIs(None, request.execute('', branch_token, repo_token))
 
947
        self.assertEqual(
 
948
            smart_req.SmartServerResponse(('ok', )),
 
949
            request.do_body('foo bar baz'))
 
950
        self.assertEqual(
 
951
            branch.control_transport.get_bytes('branch.conf'),
 
952
            'foo bar baz')
 
953
        branch.unlock()
 
954
 
 
955
 
776
956
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
777
957
 
778
958
    def test_value_name(self):
779
959
        branch = self.make_branch('.')
780
960
        request = smart_branch.SmartServerBranchRequestSetConfigOption(
781
 
            branch.bzrdir.root_transport)
 
961
            branch.controldir.root_transport)
782
962
        branch_token, repo_token = self.get_lock_tokens(branch)
783
963
        config = branch._get_config()
784
964
        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
791
971
    def test_value_name_section(self):
792
972
        branch = self.make_branch('.')
793
973
        request = smart_branch.SmartServerBranchRequestSetConfigOption(
794
 
            branch.bzrdir.root_transport)
 
974
            branch.controldir.root_transport)
795
975
        branch_token, repo_token = self.get_lock_tokens(branch)
796
976
        config = branch._get_config()
797
977
        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
802
982
        branch.unlock()
803
983
 
804
984
 
 
985
class TestSmartServerBranchRequestSetConfigOptionDict(TestLockedBranch):
 
986
 
 
987
    def setUp(self):
 
988
        TestLockedBranch.setUp(self)
 
989
        # A dict with non-ascii keys and values to exercise unicode
 
990
        # roundtripping.
 
991
        self.encoded_value_dict = (
 
992
            'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde')
 
993
        self.value_dict = {
 
994
            'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
 
995
 
 
996
    def test_value_name(self):
 
997
        branch = self.make_branch('.')
 
998
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
 
999
            branch.controldir.root_transport)
 
1000
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1001
        config = branch._get_config()
 
1002
        result = request.execute('', branch_token, repo_token,
 
1003
            self.encoded_value_dict, 'foo', '')
 
1004
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
 
1005
        self.assertEqual(self.value_dict, config.get_option('foo'))
 
1006
        # Cleanup
 
1007
        branch.unlock()
 
1008
 
 
1009
    def test_value_name_section(self):
 
1010
        branch = self.make_branch('.')
 
1011
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
 
1012
            branch.controldir.root_transport)
 
1013
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1014
        config = branch._get_config()
 
1015
        result = request.execute('', branch_token, repo_token,
 
1016
            self.encoded_value_dict, 'foo', 'gam')
 
1017
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
 
1018
        self.assertEqual(self.value_dict, config.get_option('foo', 'gam'))
 
1019
        # Cleanup
 
1020
        branch.unlock()
 
1021
 
 
1022
 
805
1023
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
806
1024
    # Only called when the branch format and tags match [yay factory
807
1025
    # methods] so only need to test straight forward cases.
818
1036
        response = request.do_chunk(tag_bytes)
819
1037
        self.assertEqual(None, response)
820
1038
        response = request.do_end()
821
 
        self.assertEquals(
 
1039
        self.assertEqual(
822
1040
            smart_req.SuccessfulSmartServerResponse(()), response)
823
1041
        base_branch.unlock()
824
1042
 
843
1061
    """Base test case for verbs that implement set_last_revision."""
844
1062
 
845
1063
    def setUp(self):
846
 
        tests.TestCaseWithMemoryTransport.setUp(self)
 
1064
        super(SetLastRevisionTestBase, self).setUp()
847
1065
        backing_transport = self.get_transport()
848
1066
        self.request = self.request_class(backing_transport)
849
1067
        self.tree = self.make_branch_and_memory_tree('.')
887
1105
        self.tree.add('')
888
1106
        rev_id_utf8 = u'\xc8'.encode('utf-8')
889
1107
        r1 = self.tree.commit('1st commit', rev_id=rev_id_utf8)
890
 
        r2 = self.tree.commit('2nd commit', rev_id='rev-2')
 
1108
        r2 = self.tree.commit('2nd commit', rev_id=b'rev-2')
891
1109
        self.tree.unlock()
892
1110
 
893
1111
    def test_branch_last_revision_info_is_updated(self):
898
1116
        # its repository.
899
1117
        self.make_tree_with_two_commits()
900
1118
        rev_id_utf8 = u'\xc8'.encode('utf-8')
901
 
        self.tree.branch.set_revision_history([])
 
1119
        self.tree.branch.set_last_revision_info(0, 'null:')
902
1120
        self.assertEqual(
903
1121
            (0, 'null:'), self.tree.branch.last_revision_info())
904
1122
        # We can update the branch to a revision that is present in the
1018
1236
        self.tree.add('')
1019
1237
        r1 = self.tree.commit('1st commit')
1020
1238
        revno_1, revid_1 = self.tree.branch.last_revision_info()
1021
 
        r2 = self.tree.commit('2nd commit', rev_id='child-1')
 
1239
        r2 = self.tree.commit('2nd commit', rev_id=b'child-1')
1022
1240
        # Undo the second commit
1023
1241
        self.tree.branch.set_last_revision_info(revno_1, revid_1)
1024
1242
        self.tree.set_parent_ids([revid_1])
1025
1243
        # Make a new second commit, child-2.  child-2 has diverged from
1026
1244
        # child-1.
1027
 
        new_r2 = self.tree.commit('2nd commit', rev_id='child-2')
 
1245
        new_r2 = self.tree.commit('2nd commit', rev_id=b'child-2')
1028
1246
        self.tree.unlock()
1029
1247
 
1030
1248
    def test_not_allow_diverged(self):
1054
1272
        self.assertEqual('child-1', self.tree.branch.last_revision())
1055
1273
 
1056
1274
 
 
1275
class TestSmartServerBranchBreakLock(tests.TestCaseWithMemoryTransport):
 
1276
 
 
1277
    def test_lock_to_break(self):
 
1278
        base_branch = self.make_branch('base')
 
1279
        request = smart_branch.SmartServerBranchBreakLock(
 
1280
            self.get_transport())
 
1281
        base_branch.lock_write()
 
1282
        self.assertEqual(
 
1283
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1284
            request.execute('base'))
 
1285
 
 
1286
    def test_nothing_to_break(self):
 
1287
        base_branch = self.make_branch('base')
 
1288
        request = smart_branch.SmartServerBranchBreakLock(
 
1289
            self.get_transport())
 
1290
        self.assertEqual(
 
1291
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1292
            request.execute('base'))
 
1293
 
 
1294
 
1057
1295
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
1058
1296
 
1059
1297
    def test_get_parent_none(self):
1060
1298
        base_branch = self.make_branch('base')
1061
1299
        request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1062
1300
        response = request.execute('base')
1063
 
        self.assertEquals(
 
1301
        self.assertEqual(
1064
1302
            smart_req.SuccessfulSmartServerResponse(('',)), response)
1065
1303
 
1066
1304
    def test_get_parent_something(self):
1068
1306
        base_branch.set_parent(self.get_url('foo'))
1069
1307
        request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1070
1308
        response = request.execute('base')
1071
 
        self.assertEquals(
 
1309
        self.assertEqual(
1072
1310
            smart_req.SuccessfulSmartServerResponse(("../foo",)),
1073
1311
            response)
1074
1312
 
1075
1313
 
1076
 
class TestSmartServerBranchRequestSetParent(tests.TestCaseWithMemoryTransport):
 
1314
class TestSmartServerBranchRequestSetParent(TestLockedBranch):
1077
1315
 
1078
1316
    def test_set_parent_none(self):
1079
1317
        branch = self.make_branch('base', format="1.9")
1082
1320
        branch.unlock()
1083
1321
        request = smart_branch.SmartServerBranchRequestSetParentLocation(
1084
1322
            self.get_transport())
1085
 
        branch_token = branch.lock_write()
1086
 
        repo_token = branch.repository.lock_write()
 
1323
        branch_token, repo_token = self.get_lock_tokens(branch)
1087
1324
        try:
1088
1325
            response = request.execute('base', branch_token, repo_token, '')
1089
1326
        finally:
1090
 
            branch.repository.unlock()
1091
1327
            branch.unlock()
1092
1328
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
 
1329
        # Refresh branch as SetParentLocation modified it
 
1330
        branch = branch.controldir.open_branch()
1093
1331
        self.assertEqual(None, branch.get_parent())
1094
1332
 
1095
1333
    def test_set_parent_something(self):
1096
1334
        branch = self.make_branch('base', format="1.9")
1097
1335
        request = smart_branch.SmartServerBranchRequestSetParentLocation(
1098
1336
            self.get_transport())
1099
 
        branch_token = branch.lock_write()
1100
 
        repo_token = branch.repository.lock_write()
 
1337
        branch_token, repo_token = self.get_lock_tokens(branch)
1101
1338
        try:
1102
1339
            response = request.execute('base', branch_token, repo_token,
1103
 
            'http://bar/')
 
1340
                                       'http://bar/')
1104
1341
        finally:
1105
 
            branch.repository.unlock()
1106
1342
            branch.unlock()
1107
1343
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1108
 
        self.assertEqual('http://bar/', branch.get_parent())
 
1344
        refreshed = _mod_branch.Branch.open(branch.base)
 
1345
        self.assertEqual('http://bar/', refreshed.get_parent())
1109
1346
 
1110
1347
 
1111
1348
class TestSmartServerBranchRequestGetTagsBytes(
1118
1355
        request = smart_branch.SmartServerBranchGetTagsBytes(
1119
1356
            self.get_transport())
1120
1357
        response = request.execute('base')
1121
 
        self.assertEquals(
 
1358
        self.assertEqual(
1122
1359
            smart_req.SuccessfulSmartServerResponse(('',)), response)
1123
1360
 
1124
1361
 
1132
1369
        request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
1133
1370
            self.get_transport())
1134
1371
        response = request.execute('stacked')
1135
 
        self.assertEquals(
 
1372
        self.assertEqual(
1136
1373
            smart_req.SmartServerResponse(('ok', '../base')),
1137
1374
            response)
1138
1375
 
1139
1376
 
1140
 
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
1141
 
 
1142
 
    def setUp(self):
1143
 
        tests.TestCaseWithMemoryTransport.setUp(self)
 
1377
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
1144
1378
 
1145
1379
    def test_lock_write_on_unlocked_branch(self):
1146
1380
        backing = self.get_transport()
1155
1389
                         response)
1156
1390
        # The branch (and associated repository) is now locked.  Verify that
1157
1391
        # with a new branch object.
1158
 
        new_branch = repository.bzrdir.open_branch()
 
1392
        new_branch = repository.controldir.open_branch()
1159
1393
        self.assertRaises(errors.LockContention, new_branch.lock_write)
1160
1394
        # Cleanup
1161
1395
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1165
1399
        backing = self.get_transport()
1166
1400
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1167
1401
        branch = self.make_branch('.')
1168
 
        branch_token = branch.lock_write()
 
1402
        branch_token = branch.lock_write().token
1169
1403
        branch.leave_lock_in_place()
1170
1404
        branch.unlock()
1171
1405
        response = request.execute('')
1180
1414
        backing = self.get_transport()
1181
1415
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1182
1416
        branch = self.make_branch('.', format='knit')
1183
 
        branch_token = branch.lock_write()
1184
 
        repo_token = branch.repository.lock_write()
1185
 
        branch.repository.unlock()
 
1417
        branch_token, repo_token = self.get_lock_tokens(branch)
1186
1418
        branch.leave_lock_in_place()
1187
1419
        branch.repository.leave_lock_in_place()
1188
1420
        branch.unlock()
1203
1435
        backing = self.get_transport()
1204
1436
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1205
1437
        branch = self.make_branch('.', format='knit')
1206
 
        branch_token = branch.lock_write()
1207
 
        repo_token = branch.repository.lock_write()
1208
 
        branch.repository.unlock()
 
1438
        branch_token, repo_token = self.get_lock_tokens(branch)
1209
1439
        branch.leave_lock_in_place()
1210
1440
        branch.repository.leave_lock_in_place()
1211
1441
        branch.unlock()
1226
1456
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1227
1457
        branch = self.make_branch('.', format='knit')
1228
1458
        repo = branch.repository
1229
 
        repo_token = repo.lock_write()
 
1459
        repo_token = repo.lock_write().repository_token
1230
1460
        repo.leave_lock_in_place()
1231
1461
        repo.unlock()
1232
1462
        response = request.execute('')
1249
1479
        self.assertEqual('LockFailed', error_name)
1250
1480
 
1251
1481
 
1252
 
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
1253
 
 
1254
 
    def setUp(self):
1255
 
        tests.TestCaseWithMemoryTransport.setUp(self)
 
1482
class TestSmartServerBranchRequestGetPhysicalLockStatus(TestLockedBranch):
 
1483
 
 
1484
    def test_true(self):
 
1485
        backing = self.get_transport()
 
1486
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
 
1487
            backing)
 
1488
        branch = self.make_branch('.')
 
1489
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1490
        self.assertEqual(True, branch.get_physical_lock_status())
 
1491
        response = request.execute('')
 
1492
        self.assertEqual(
 
1493
            smart_req.SmartServerResponse(('yes',)), response)
 
1494
        branch.unlock()
 
1495
 
 
1496
    def test_false(self):
 
1497
        backing = self.get_transport()
 
1498
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
 
1499
            backing)
 
1500
        branch = self.make_branch('.')
 
1501
        self.assertEqual(False, branch.get_physical_lock_status())
 
1502
        response = request.execute('')
 
1503
        self.assertEqual(
 
1504
            smart_req.SmartServerResponse(('no',)), response)
 
1505
 
 
1506
 
 
1507
class TestSmartServerBranchRequestUnlock(TestLockedBranch):
1256
1508
 
1257
1509
    def test_unlock_on_locked_branch_and_repo(self):
1258
1510
        backing = self.get_transport()
1259
1511
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1260
1512
        branch = self.make_branch('.', format='knit')
1261
1513
        # Lock the branch
1262
 
        branch_token = branch.lock_write()
1263
 
        repo_token = branch.repository.lock_write()
1264
 
        branch.repository.unlock()
 
1514
        branch_token, repo_token = self.get_lock_tokens(branch)
1265
1515
        # Unlock the branch (and repo) object, leaving the physical locks
1266
1516
        # in place.
1267
1517
        branch.leave_lock_in_place()
1273
1523
            smart_req.SmartServerResponse(('ok',)), response)
1274
1524
        # The branch is now unlocked.  Verify that with a new branch
1275
1525
        # object.
1276
 
        new_branch = branch.bzrdir.open_branch()
 
1526
        new_branch = branch.controldir.open_branch()
1277
1527
        new_branch.lock_write()
1278
1528
        new_branch.unlock()
1279
1529
 
1291
1541
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1292
1542
        branch = self.make_branch('.', format='knit')
1293
1543
        # Lock the repository.
1294
 
        repo_token = branch.repository.lock_write()
 
1544
        repo_token = branch.repository.lock_write().repository_token
1295
1545
        branch.repository.leave_lock_in_place()
1296
1546
        branch.repository.unlock()
1297
1547
        # Issue branch lock_write request on the unlocked branch (with locked
1298
1548
        # repo).
1299
 
        response = request.execute(
1300
 
            '', 'branch token', repo_token)
 
1549
        response = request.execute('', 'branch token', repo_token)
1301
1550
        self.assertEqual(
1302
1551
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1303
1552
        # Cleanup
1317
1566
        backing = self.get_transport()
1318
1567
        request = smart_repo.SmartServerRepositoryRequest(backing)
1319
1568
        self.make_repository('.', shared=True)
1320
 
        self.make_bzrdir('subdir')
 
1569
        self.make_controldir('subdir')
1321
1570
        self.assertRaises(errors.NoRepositoryPresent,
1322
1571
            request.execute, 'subdir')
1323
1572
 
1324
1573
 
 
1574
class TestSmartServerRepositoryAddSignatureText(tests.TestCaseWithMemoryTransport):
 
1575
 
 
1576
    def test_add_text(self):
 
1577
        backing = self.get_transport()
 
1578
        request = smart_repo.SmartServerRepositoryAddSignatureText(backing)
 
1579
        tree = self.make_branch_and_memory_tree('.')
 
1580
        write_token = tree.lock_write()
 
1581
        self.addCleanup(tree.unlock)
 
1582
        tree.add('')
 
1583
        tree.commit("Message", rev_id=b'rev1')
 
1584
        tree.branch.repository.start_write_group()
 
1585
        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')
 
1589
        self.assertTrue(response.is_successful())
 
1590
        self.assertEqual(response.args[0], 'ok')
 
1591
        write_group_tokens = response.args[1:]
 
1592
        tree.branch.repository.resume_write_group(write_group_tokens)
 
1593
        tree.branch.repository.commit_write_group()
 
1594
        tree.unlock()
 
1595
        self.assertEqual("somesignature",
 
1596
            tree.branch.repository.get_signature_text("rev1"))
 
1597
 
 
1598
 
 
1599
class TestSmartServerRepositoryAllRevisionIds(
 
1600
    tests.TestCaseWithMemoryTransport):
 
1601
 
 
1602
    def test_empty(self):
 
1603
        """An empty body should be returned for an empty repository."""
 
1604
        backing = self.get_transport()
 
1605
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
 
1606
        self.make_repository('.')
 
1607
        self.assertEqual(
 
1608
            smart_req.SuccessfulSmartServerResponse(("ok", ), ""),
 
1609
            request.execute(''))
 
1610
 
 
1611
    def test_some_revisions(self):
 
1612
        """An empty body should be returned for an empty repository."""
 
1613
        backing = self.get_transport()
 
1614
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
 
1615
        tree = self.make_branch_and_memory_tree('.')
 
1616
        tree.lock_write()
 
1617
        tree.add('')
 
1618
        tree.commit(rev_id=b'origineel', message="message")
 
1619
        tree.commit(rev_id=b'nog-een-revisie', message="message")
 
1620
        tree.unlock()
 
1621
        self.assertEqual(
 
1622
            smart_req.SuccessfulSmartServerResponse(("ok", ),
 
1623
                "origineel\nnog-een-revisie"),
 
1624
            request.execute(''))
 
1625
 
 
1626
 
 
1627
class TestSmartServerRepositoryBreakLock(tests.TestCaseWithMemoryTransport):
 
1628
 
 
1629
    def test_lock_to_break(self):
 
1630
        backing = self.get_transport()
 
1631
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
 
1632
        tree = self.make_branch_and_memory_tree('.')
 
1633
        tree.branch.repository.lock_write()
 
1634
        self.assertEqual(
 
1635
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1636
            request.execute(''))
 
1637
 
 
1638
    def test_nothing_to_break(self):
 
1639
        backing = self.get_transport()
 
1640
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
 
1641
        tree = self.make_branch_and_memory_tree('.')
 
1642
        self.assertEqual(
 
1643
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1644
            request.execute(''))
 
1645
 
 
1646
 
1325
1647
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithMemoryTransport):
1326
1648
 
1327
1649
    def test_trivial_bzipped(self):
1447
1769
            request.execute('stacked', 1, (3, r3)))
1448
1770
 
1449
1771
 
1450
 
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
 
1772
class TestSmartServerRepositoryIterRevisions(
 
1773
    tests.TestCaseWithMemoryTransport):
 
1774
 
 
1775
    def test_basic(self):
 
1776
        backing = self.get_transport()
 
1777
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
 
1778
        tree = self.make_branch_and_memory_tree('.', format='2a')
 
1779
        tree.lock_write()
 
1780
        tree.add('')
 
1781
        tree.commit('1st commit', rev_id="rev1")
 
1782
        tree.commit('2nd commit', rev_id="rev2")
 
1783
        tree.unlock()
 
1784
 
 
1785
        self.assertIs(None, request.execute(''))
 
1786
        response = request.do_body("rev1\nrev2")
 
1787
        self.assertTrue(response.is_successful())
 
1788
        # Format 2a uses serializer format 10
 
1789
        self.assertEqual(response.args, ("ok", "10"))
 
1790
 
 
1791
        self.addCleanup(tree.branch.lock_read().unlock)
 
1792
        entries = [zlib.compress(record.get_bytes_as("fulltext")) for record in
 
1793
            tree.branch.repository.revisions.get_record_stream(
 
1794
            [("rev1", ), ("rev2", )], "unordered", True)]
 
1795
 
 
1796
        contents = "".join(response.body_stream)
 
1797
        self.assertTrue(contents in (
 
1798
            "".join([entries[0], entries[1]]),
 
1799
            "".join([entries[1], entries[0]])))
 
1800
 
 
1801
    def test_missing(self):
 
1802
        backing = self.get_transport()
 
1803
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
 
1804
        tree = self.make_branch_and_memory_tree('.', format='2a')
 
1805
 
 
1806
        self.assertIs(None, request.execute(''))
 
1807
        response = request.do_body("rev1\nrev2")
 
1808
        self.assertTrue(response.is_successful())
 
1809
        # Format 2a uses serializer format 10
 
1810
        self.assertEqual(response.args, ("ok", "10"))
 
1811
 
 
1812
        contents = "".join(response.body_stream)
 
1813
        self.assertEqual(contents, "")
 
1814
 
 
1815
 
 
1816
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
1451
1817
 
1452
1818
    def make_two_commit_repo(self):
1453
1819
        tree = self.make_branch_and_memory_tree('.')
1459
1825
        repo = tree.branch.repository
1460
1826
        return repo, r1, r2
1461
1827
 
 
1828
 
 
1829
class TestSmartServerRepositoryGetStream(GetStreamTestBase):
 
1830
 
1462
1831
    def test_ancestry_of(self):
1463
1832
        """The search argument may be a 'ancestry-of' some heads'."""
1464
1833
        backing = self.get_transport()
1485
1854
        stream_bytes = ''.join(response.body_stream)
1486
1855
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1487
1856
 
 
1857
    def test_search_everything(self):
 
1858
        """A search of 'everything' returns a stream."""
 
1859
        backing = self.get_transport()
 
1860
        request = smart_repo.SmartServerRepositoryGetStream_1_19(backing)
 
1861
        repo, r1, r2 = self.make_two_commit_repo()
 
1862
        serialised_fetch_spec = 'everything'
 
1863
        request.execute('', repo._format.network_name())
 
1864
        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')
 
1868
 
1488
1869
 
1489
1870
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1490
1871
 
1511
1892
            request.execute('', rev_id_utf8))
1512
1893
 
1513
1894
 
 
1895
class TestSmartServerRepositoryIterFilesBytes(tests.TestCaseWithTransport):
 
1896
 
 
1897
    def test_single(self):
 
1898
        backing = self.get_transport()
 
1899
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
 
1900
        t = self.make_branch_and_tree('.')
 
1901
        self.addCleanup(t.lock_write().unlock)
 
1902
        self.build_tree_contents([("file", b"somecontents")])
 
1903
        t.add(["file"], [b"thefileid"])
 
1904
        t.commit(rev_id=b'somerev', message="add file")
 
1905
        self.assertIs(None, request.execute(''))
 
1906
        response = request.do_body("thefileid\0somerev\n")
 
1907
        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"))
 
1911
 
 
1912
    def test_missing(self):
 
1913
        backing = self.get_transport()
 
1914
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
 
1915
        t = self.make_branch_and_tree('.')
 
1916
        self.addCleanup(t.lock_write().unlock)
 
1917
        self.assertIs(None, request.execute(''))
 
1918
        response = request.do_body("thefileid\0revision\n")
 
1919
        self.assertTrue(response.is_successful())
 
1920
        self.assertEqual(response.args, ("ok", ))
 
1921
        self.assertEqual("".join(response.body_stream),
 
1922
            "absent\x00thefileid\x00revision\x000\n")
 
1923
 
 
1924
 
 
1925
class TestSmartServerRequestHasSignatureForRevisionId(
 
1926
        tests.TestCaseWithMemoryTransport):
 
1927
 
 
1928
    def test_missing_revision(self):
 
1929
        """For a missing revision, NoSuchRevision is returned."""
 
1930
        backing = self.get_transport()
 
1931
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1932
            backing)
 
1933
        self.make_repository('.')
 
1934
        self.assertEqual(
 
1935
            smart_req.FailedSmartServerResponse(
 
1936
                ('nosuchrevision', 'revid'), None),
 
1937
            request.execute('', 'revid'))
 
1938
 
 
1939
    def test_missing_signature(self):
 
1940
        """For a missing signature, ('no', ) is returned."""
 
1941
        backing = self.get_transport()
 
1942
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1943
            backing)
 
1944
        tree = self.make_branch_and_memory_tree('.')
 
1945
        tree.lock_write()
 
1946
        tree.add('')
 
1947
        r1 = tree.commit('a commit', rev_id=b'A')
 
1948
        tree.unlock()
 
1949
        self.assertTrue(tree.branch.repository.has_revision('A'))
 
1950
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
1951
            request.execute('', 'A'))
 
1952
 
 
1953
    def test_present_signature(self):
 
1954
        """For a present signature, ('yes', ) is returned."""
 
1955
        backing = self.get_transport()
 
1956
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1957
            backing)
 
1958
        strategy = gpg.LoopbackGPGStrategy(None)
 
1959
        tree = self.make_branch_and_memory_tree('.')
 
1960
        tree.lock_write()
 
1961
        tree.add('')
 
1962
        r1 = tree.commit('a commit', rev_id=b'A')
 
1963
        tree.branch.repository.start_write_group()
 
1964
        tree.branch.repository.sign_revision('A', strategy)
 
1965
        tree.branch.repository.commit_write_group()
 
1966
        tree.unlock()
 
1967
        self.assertTrue(tree.branch.repository.has_revision('A'))
 
1968
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
 
1969
            request.execute('', 'A'))
 
1970
 
 
1971
 
1514
1972
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
1515
1973
 
1516
1974
    def test_empty_revid(self):
1569
2027
                         request.execute('',
1570
2028
                                         rev_id_utf8, 'yes'))
1571
2029
 
 
2030
    def test_unknown_revid(self):
 
2031
        """An unknown revision id causes a 'nosuchrevision' error."""
 
2032
        backing = self.get_transport()
 
2033
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
 
2034
        repository = self.make_repository('.')
 
2035
        expected_body = 'revisions: 0\n'
 
2036
        self.assertEqual(
 
2037
            smart_req.FailedSmartServerResponse(
 
2038
                ('nosuchrevision', 'mia'), None),
 
2039
            request.execute('', 'mia', 'yes'))
 
2040
 
1572
2041
 
1573
2042
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
1574
2043
 
1589
2058
            request.execute('', ))
1590
2059
 
1591
2060
 
 
2061
class TestSmartServerRepositoryGetRevisionSignatureText(
 
2062
        tests.TestCaseWithMemoryTransport):
 
2063
 
 
2064
    def test_get_signature(self):
 
2065
        backing = self.get_transport()
 
2066
        request = smart_repo.SmartServerRepositoryGetRevisionSignatureText(
 
2067
            backing)
 
2068
        bb = self.make_branch_builder('.')
 
2069
        bb.build_commit(rev_id=b'A')
 
2070
        repo = bb.get_branch().repository
 
2071
        strategy = gpg.LoopbackGPGStrategy(None)
 
2072
        self.addCleanup(repo.lock_write().unlock)
 
2073
        repo.start_write_group()
 
2074
        repo.sign_revision('A', strategy)
 
2075
        repo.commit_write_group()
 
2076
        expected_body = (
 
2077
            '-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
 
2078
            Testament.from_revision(repo, 'A').as_short_text() +
 
2079
            '-----END PSEUDO-SIGNED CONTENT-----\n')
 
2080
        self.assertEqual(
 
2081
            smart_req.SmartServerResponse(('ok', ), expected_body),
 
2082
            request.execute('', 'A'))
 
2083
 
 
2084
 
 
2085
class TestSmartServerRepositoryMakeWorkingTrees(
 
2086
        tests.TestCaseWithMemoryTransport):
 
2087
 
 
2088
    def test_make_working_trees(self):
 
2089
        """For a repository with working trees, ('yes', ) is returned."""
 
2090
        backing = self.get_transport()
 
2091
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
 
2092
        r = self.make_repository('.')
 
2093
        r.set_make_working_trees(True)
 
2094
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
 
2095
            request.execute('', ))
 
2096
 
 
2097
    def test_is_not_shared(self):
 
2098
        """For a repository with working trees, ('no', ) is returned."""
 
2099
        backing = self.get_transport()
 
2100
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
 
2101
        r = self.make_repository('.')
 
2102
        r.set_make_working_trees(False)
 
2103
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
2104
            request.execute('', ))
 
2105
 
 
2106
 
1592
2107
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
1593
2108
 
1594
2109
    def test_lock_write_on_unlocked_repo(self):
1600
2115
        self.assertEqual(smart_req.SmartServerResponse(('ok', nonce)), response)
1601
2116
        # The repository is now locked.  Verify that with a new repository
1602
2117
        # object.
1603
 
        new_repo = repository.bzrdir.open_repository()
 
2118
        new_repo = repository.controldir.open_repository()
1604
2119
        self.assertRaises(errors.LockContention, new_repo.lock_write)
1605
2120
        # Cleanup
1606
2121
        request = smart_repo.SmartServerRepositoryUnlock(backing)
1610
2125
        backing = self.get_transport()
1611
2126
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
1612
2127
        repository = self.make_repository('.', format='knit')
1613
 
        repo_token = repository.lock_write()
 
2128
        repo_token = repository.lock_write().repository_token
1614
2129
        repository.leave_lock_in_place()
1615
2130
        repository.unlock()
1616
2131
        response = request.execute('')
1658
2173
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1659
2174
            backing)
1660
2175
        repository = self.make_repository('.', format='knit')
1661
 
        lock_token = repository.lock_write()
 
2176
        lock_token = repository.lock_write().repository_token
1662
2177
        response = request.execute('', '', lock_token)
1663
2178
        self.assertEqual(None, response)
1664
2179
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1672
2187
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1673
2188
            backing)
1674
2189
        repository = self.make_repository('.', format='knit')
1675
 
        lock_token = repository.lock_write()
 
2190
        lock_token = repository.lock_write().repository_token
1676
2191
        self.assertRaises(
1677
2192
            errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1678
2193
        repository.unlock()
1680
2195
 
1681
2196
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
1682
2197
 
1683
 
    def setUp(self):
1684
 
        tests.TestCaseWithMemoryTransport.setUp(self)
1685
 
 
1686
2198
    def test_unlock_on_locked_repo(self):
1687
2199
        backing = self.get_transport()
1688
2200
        request = smart_repo.SmartServerRepositoryUnlock(backing)
1689
2201
        repository = self.make_repository('.', format='knit')
1690
 
        token = repository.lock_write()
 
2202
        token = repository.lock_write().repository_token
1691
2203
        repository.leave_lock_in_place()
1692
2204
        repository.unlock()
1693
2205
        response = request.execute('', token)
1695
2207
            smart_req.SmartServerResponse(('ok',)), response)
1696
2208
        # The repository is now unlocked.  Verify that with a new repository
1697
2209
        # object.
1698
 
        new_repo = repository.bzrdir.open_repository()
 
2210
        new_repo = repository.controldir.open_repository()
1699
2211
        new_repo.lock_write()
1700
2212
        new_repo.unlock()
1701
2213
 
1708
2220
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1709
2221
 
1710
2222
 
 
2223
class TestSmartServerRepositoryGetPhysicalLockStatus(
 
2224
    tests.TestCaseWithTransport):
 
2225
 
 
2226
    def test_with_write_lock(self):
 
2227
        backing = self.get_transport()
 
2228
        repo = self.make_repository('.')
 
2229
        self.addCleanup(repo.lock_write().unlock)
 
2230
        # lock_write() doesn't necessarily actually take a physical
 
2231
        # lock out.
 
2232
        if repo.get_physical_lock_status():
 
2233
            expected = 'yes'
 
2234
        else:
 
2235
            expected = 'no'
 
2236
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
 
2237
        request = request_class(backing)
 
2238
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((expected,)),
 
2239
            request.execute('', ))
 
2240
 
 
2241
    def test_without_write_lock(self):
 
2242
        backing = self.get_transport()
 
2243
        repo = self.make_repository('.')
 
2244
        self.assertEqual(False, repo.get_physical_lock_status())
 
2245
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
 
2246
        request = request_class(backing)
 
2247
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('no',)),
 
2248
            request.execute('', ))
 
2249
 
 
2250
 
 
2251
class TestSmartServerRepositoryReconcile(tests.TestCaseWithTransport):
 
2252
 
 
2253
    def test_reconcile(self):
 
2254
        backing = self.get_transport()
 
2255
        repo = self.make_repository('.')
 
2256
        token = repo.lock_write().repository_token
 
2257
        self.addCleanup(repo.unlock)
 
2258
        request_class = smart_repo.SmartServerRepositoryReconcile
 
2259
        request = request_class(backing)
 
2260
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
 
2261
            ('ok', ),
 
2262
             'garbage_inventories: 0\n'
 
2263
             'inconsistent_parents: 0\n'),
 
2264
            request.execute('', token))
 
2265
 
 
2266
 
1711
2267
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
1712
2268
 
1713
2269
    def test_is_readonly_no(self):
1736
2292
        request = request_class(backing)
1737
2293
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1738
2294
            request.execute('', 'False'))
1739
 
        repo = repo.bzrdir.open_repository()
 
2295
        repo = repo.controldir.open_repository()
1740
2296
        self.assertFalse(repo.make_working_trees())
1741
2297
 
1742
2298
    def test_set_true(self):
1747
2303
        request = request_class(backing)
1748
2304
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1749
2305
            request.execute('', 'True'))
1750
 
        repo = repo.bzrdir.open_repository()
 
2306
        repo = repo.controldir.open_repository()
1751
2307
        self.assertTrue(repo.make_working_trees())
1752
2308
 
1753
2309
 
 
2310
class TestSmartServerRepositoryGetSerializerFormat(
 
2311
    tests.TestCaseWithMemoryTransport):
 
2312
 
 
2313
    def test_get_serializer_format(self):
 
2314
        backing = self.get_transport()
 
2315
        repo = self.make_repository('.', format='2a')
 
2316
        request_class = smart_repo.SmartServerRepositoryGetSerializerFormat
 
2317
        request = request_class(backing)
 
2318
        self.assertEqual(
 
2319
            smart_req.SuccessfulSmartServerResponse(('ok', '10')),
 
2320
            request.execute(''))
 
2321
 
 
2322
 
 
2323
class TestSmartServerRepositoryWriteGroup(
 
2324
    tests.TestCaseWithMemoryTransport):
 
2325
 
 
2326
    def test_start_write_group(self):
 
2327
        backing = self.get_transport()
 
2328
        repo = self.make_repository('.')
 
2329
        lock_token = repo.lock_write().repository_token
 
2330
        self.addCleanup(repo.unlock)
 
2331
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
 
2332
        request = request_class(backing)
 
2333
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok', [])),
 
2334
            request.execute('', lock_token))
 
2335
 
 
2336
    def test_start_write_group_unsuspendable(self):
 
2337
        backing = self.get_transport()
 
2338
        repo = self.make_repository('.', format='knit')
 
2339
        lock_token = repo.lock_write().repository_token
 
2340
        self.addCleanup(repo.unlock)
 
2341
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
 
2342
        request = request_class(backing)
 
2343
        self.assertEqual(
 
2344
            smart_req.FailedSmartServerResponse(('UnsuspendableWriteGroup',)),
 
2345
            request.execute('', lock_token))
 
2346
 
 
2347
    def test_commit_write_group(self):
 
2348
        backing = self.get_transport()
 
2349
        repo = self.make_repository('.')
 
2350
        lock_token = repo.lock_write().repository_token
 
2351
        self.addCleanup(repo.unlock)
 
2352
        repo.start_write_group()
 
2353
        tokens = repo.suspend_write_group()
 
2354
        request_class = smart_repo.SmartServerRepositoryCommitWriteGroup
 
2355
        request = request_class(backing)
 
2356
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2357
            request.execute('', lock_token, tokens))
 
2358
 
 
2359
    def test_abort_write_group(self):
 
2360
        backing = self.get_transport()
 
2361
        repo = self.make_repository('.')
 
2362
        lock_token = repo.lock_write().repository_token
 
2363
        repo.start_write_group()
 
2364
        tokens = repo.suspend_write_group()
 
2365
        self.addCleanup(repo.unlock)
 
2366
        request_class = smart_repo.SmartServerRepositoryAbortWriteGroup
 
2367
        request = request_class(backing)
 
2368
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2369
            request.execute('', lock_token, tokens))
 
2370
 
 
2371
    def test_check_write_group(self):
 
2372
        backing = self.get_transport()
 
2373
        repo = self.make_repository('.')
 
2374
        lock_token = repo.lock_write().repository_token
 
2375
        repo.start_write_group()
 
2376
        tokens = repo.suspend_write_group()
 
2377
        self.addCleanup(repo.unlock)
 
2378
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
 
2379
        request = request_class(backing)
 
2380
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2381
            request.execute('', lock_token, tokens))
 
2382
 
 
2383
    def test_check_write_group_invalid(self):
 
2384
        backing = self.get_transport()
 
2385
        repo = self.make_repository('.')
 
2386
        lock_token = repo.lock_write().repository_token
 
2387
        self.addCleanup(repo.unlock)
 
2388
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
 
2389
        request = request_class(backing)
 
2390
        self.assertEqual(smart_req.FailedSmartServerResponse(
 
2391
            ('UnresumableWriteGroup', ['random'],
 
2392
                'Malformed write group token')),
 
2393
            request.execute('', lock_token, ["random"]))
 
2394
 
 
2395
 
1754
2396
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1755
2397
 
1756
2398
    def make_repo_needing_autopacking(self, path='.'):
1822
2464
        """All registered request_handlers can be found."""
1823
2465
        # If there's a typo in a register_lazy call, this loop will fail with
1824
2466
        # an AttributeError.
1825
 
        for key, item in smart_req.request_handlers.iteritems():
1826
 
            pass
 
2467
        for key in smart_req.request_handlers.keys():
 
2468
            try:
 
2469
                item = smart_req.request_handlers.get(key)
 
2470
            except AttributeError as e:
 
2471
                raise AttributeError('failed to get %s: %s' % (key, e))
1827
2472
 
1828
2473
    def assertHandlerEqual(self, verb, handler):
1829
2474
        self.assertEqual(smart_req.request_handlers.get(verb), handler)
1830
2475
 
1831
2476
    def test_registered_methods(self):
1832
2477
        """Test that known methods are registered to the correct object."""
 
2478
        self.assertHandlerEqual('Branch.break_lock',
 
2479
            smart_branch.SmartServerBranchBreakLock)
1833
2480
        self.assertHandlerEqual('Branch.get_config_file',
1834
2481
            smart_branch.SmartServerBranchGetConfigFile)
 
2482
        self.assertHandlerEqual('Branch.put_config_file',
 
2483
            smart_branch.SmartServerBranchPutConfigFile)
1835
2484
        self.assertHandlerEqual('Branch.get_parent',
1836
2485
            smart_branch.SmartServerBranchGetParent)
 
2486
        self.assertHandlerEqual('Branch.get_physical_lock_status',
 
2487
            smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
1837
2488
        self.assertHandlerEqual('Branch.get_tags_bytes',
1838
2489
            smart_branch.SmartServerBranchGetTagsBytes)
1839
2490
        self.assertHandlerEqual('Branch.lock_write',
1842
2493
            smart_branch.SmartServerBranchRequestLastRevisionInfo)
1843
2494
        self.assertHandlerEqual('Branch.revision_history',
1844
2495
            smart_branch.SmartServerRequestRevisionHistory)
 
2496
        self.assertHandlerEqual('Branch.revision_id_to_revno',
 
2497
            smart_branch.SmartServerBranchRequestRevisionIdToRevno)
1845
2498
        self.assertHandlerEqual('Branch.set_config_option',
1846
2499
            smart_branch.SmartServerBranchRequestSetConfigOption)
1847
2500
        self.assertHandlerEqual('Branch.set_last_revision',
1854
2507
            smart_branch.SmartServerBranchRequestSetParentLocation)
1855
2508
        self.assertHandlerEqual('Branch.unlock',
1856
2509
            smart_branch.SmartServerBranchRequestUnlock)
 
2510
        self.assertHandlerEqual('BzrDir.destroy_branch',
 
2511
            smart_dir.SmartServerBzrDirRequestDestroyBranch)
1857
2512
        self.assertHandlerEqual('BzrDir.find_repository',
1858
2513
            smart_dir.SmartServerRequestFindRepositoryV1)
1859
2514
        self.assertHandlerEqual('BzrDir.find_repositoryV2',
1862
2517
            smart_dir.SmartServerRequestInitializeBzrDir)
1863
2518
        self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
1864
2519
            smart_dir.SmartServerRequestBzrDirInitializeEx)
 
2520
        self.assertHandlerEqual('BzrDir.checkout_metadir',
 
2521
            smart_dir.SmartServerBzrDirRequestCheckoutMetaDir)
1865
2522
        self.assertHandlerEqual('BzrDir.cloning_metadir',
1866
2523
            smart_dir.SmartServerBzrDirRequestCloningMetaDir)
 
2524
        self.assertHandlerEqual('BzrDir.get_branches',
 
2525
            smart_dir.SmartServerBzrDirRequestGetBranches)
1867
2526
        self.assertHandlerEqual('BzrDir.get_config_file',
1868
2527
            smart_dir.SmartServerBzrDirRequestConfigFile)
1869
2528
        self.assertHandlerEqual('BzrDir.open_branch',
1874
2533
            smart_dir.SmartServerRequestOpenBranchV3)
1875
2534
        self.assertHandlerEqual('PackRepository.autopack',
1876
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)
1877
2542
        self.assertHandlerEqual('Repository.gather_stats',
1878
2543
            smart_repo.SmartServerRepositoryGatherStats)
1879
2544
        self.assertHandlerEqual('Repository.get_parent_map',
1880
2545
            smart_repo.SmartServerRepositoryGetParentMap)
 
2546
        self.assertHandlerEqual('Repository.get_physical_lock_status',
 
2547
            smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
1881
2548
        self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1882
2549
            smart_repo.SmartServerRepositoryGetRevIdForRevno)
1883
2550
        self.assertHandlerEqual('Repository.get_revision_graph',
1884
2551
            smart_repo.SmartServerRepositoryGetRevisionGraph)
 
2552
        self.assertHandlerEqual('Repository.get_revision_signature_text',
 
2553
            smart_repo.SmartServerRepositoryGetRevisionSignatureText)
1885
2554
        self.assertHandlerEqual('Repository.get_stream',
1886
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)
1887
2560
        self.assertHandlerEqual('Repository.has_revision',
1888
2561
            smart_repo.SmartServerRequestHasRevision)
1889
2562
        self.assertHandlerEqual('Repository.insert_stream',
1892
2565
            smart_repo.SmartServerRepositoryInsertStreamLocked)
1893
2566
        self.assertHandlerEqual('Repository.is_shared',
1894
2567
            smart_repo.SmartServerRepositoryIsShared)
 
2568
        self.assertHandlerEqual('Repository.iter_files_bytes',
 
2569
            smart_repo.SmartServerRepositoryIterFilesBytes)
1895
2570
        self.assertHandlerEqual('Repository.lock_write',
1896
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)
1897
2578
        self.assertHandlerEqual('Repository.tarball',
1898
2579
            smart_repo.SmartServerRepositoryTarball)
1899
2580
        self.assertHandlerEqual('Repository.unlock',
1900
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)
1901
2594
        self.assertHandlerEqual('Transport.is_readonly',
1902
2595
            smart_req.SmartServerIsReadonly)
 
2596
 
 
2597
 
 
2598
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
 
2599
    """Tests for SmartTCPServer hooks."""
 
2600
 
 
2601
    def setUp(self):
 
2602
        super(SmartTCPServerHookTests, self).setUp()
 
2603
        self.server = server.SmartTCPServer(self.get_transport())
 
2604
 
 
2605
    def test_run_server_started_hooks(self):
 
2606
        """Test the server started hooks get fired properly."""
 
2607
        started_calls = []
 
2608
        server.SmartTCPServer.hooks.install_named_hook('server_started',
 
2609
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
 
2610
            None)
 
2611
        started_ex_calls = []
 
2612
        server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
 
2613
            lambda backing_urls, url: started_ex_calls.append((backing_urls, url)),
 
2614
            None)
 
2615
        self.server._sockname = ('example.com', 42)
 
2616
        self.server.run_server_started_hooks()
 
2617
        self.assertEqual(started_calls,
 
2618
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2619
        self.assertEqual(started_ex_calls,
 
2620
            [([self.get_transport().base], self.server)])
 
2621
 
 
2622
    def test_run_server_started_hooks_ipv6(self):
 
2623
        """Test that socknames can contain 4-tuples."""
 
2624
        self.server._sockname = ('::', 42, 0, 0)
 
2625
        started_calls = []
 
2626
        server.SmartTCPServer.hooks.install_named_hook('server_started',
 
2627
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
 
2628
            None)
 
2629
        self.server.run_server_started_hooks()
 
2630
        self.assertEqual(started_calls,
 
2631
                [([self.get_transport().base], 'bzr://:::42/')])
 
2632
 
 
2633
    def test_run_server_stopped_hooks(self):
 
2634
        """Test the server stopped hooks."""
 
2635
        self.server._sockname = ('example.com', 42)
 
2636
        stopped_calls = []
 
2637
        server.SmartTCPServer.hooks.install_named_hook('server_stopped',
 
2638
            lambda backing_urls, url: stopped_calls.append((backing_urls, url)),
 
2639
            None)
 
2640
        self.server.run_server_stopped_hooks()
 
2641
        self.assertEqual(stopped_calls,
 
2642
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2643
 
 
2644
 
 
2645
class TestSmartServerRepositoryPack(tests.TestCaseWithMemoryTransport):
 
2646
 
 
2647
    def test_pack(self):
 
2648
        backing = self.get_transport()
 
2649
        request = smart_repo.SmartServerRepositoryPack(backing)
 
2650
        tree = self.make_branch_and_memory_tree('.')
 
2651
        repo_token = tree.branch.repository.lock_write().repository_token
 
2652
 
 
2653
        self.assertIs(None, request.execute('', repo_token, False))
 
2654
 
 
2655
        self.assertEqual(
 
2656
            smart_req.SuccessfulSmartServerResponse(('ok', ), ),
 
2657
            request.do_body(''))
 
2658
 
 
2659
 
 
2660
class TestSmartServerRepositoryGetInventories(tests.TestCaseWithTransport):
 
2661
 
 
2662
    def _get_serialized_inventory_delta(self, repository, base_revid, revid):
 
2663
        base_inv = repository.revision_tree(base_revid).root_inventory
 
2664
        inv = repository.revision_tree(revid).root_inventory
 
2665
        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))
 
2668
 
 
2669
    def test_single(self):
 
2670
        backing = self.get_transport()
 
2671
        request = smart_repo.SmartServerRepositoryGetInventories(backing)
 
2672
        t = self.make_branch_and_tree('.', format='2a')
 
2673
        self.addCleanup(t.lock_write().unlock)
 
2674
        self.build_tree_contents([("file", b"somecontents")])
 
2675
        t.add(["file"], [b"thefileid"])
 
2676
        t.commit(rev_id=b'somerev', message="add file")
 
2677
        self.assertIs(None, request.execute('', 'unordered'))
 
2678
        response = request.do_body("somerev\n")
 
2679
        self.assertTrue(response.is_successful())
 
2680
        self.assertEqual(response.args, ("ok", ))
 
2681
        stream = [('inventory-deltas', [
 
2682
            versionedfile.FulltextContentFactory('somerev', None, None,
 
2683
                self._get_serialized_inventory_delta(
 
2684
                    t.branch.repository, 'null:', 'somerev'))])]
 
2685
        fmt = controldir.format_registry.get('2a')().repository_format
 
2686
        self.assertEqual(
 
2687
            "".join(response.body_stream),
 
2688
            "".join(smart_repo._stream_to_byte_stream(stream, fmt)))
 
2689
 
 
2690
    def test_empty(self):
 
2691
        backing = self.get_transport()
 
2692
        request = smart_repo.SmartServerRepositoryGetInventories(backing)
 
2693
        t = self.make_branch_and_tree('.', format='2a')
 
2694
        self.addCleanup(t.lock_write().unlock)
 
2695
        self.build_tree_contents([("file", b"somecontents")])
 
2696
        t.add(["file"], [b"thefileid"])
 
2697
        t.commit(rev_id=b'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")