/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

  • Committer: Marius Kruger
  • Date: 2010-07-10 21:28:56 UTC
  • mto: (5384.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 5385.
  • Revision ID: marius.kruger@enerweb.co.za-20100710212856-uq4ji3go0u5se7hx
* Update documentation
* add NEWS

Show diffs side-by-side

added added

removed removed

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