~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

  • Committer: Vincent Ladeuil
  • Date: 2016-01-21 11:42:23 UTC
  • mto: This revision was merged to the branch mainline in revision 6610.
  • Revision ID: v.ladeuil+lp@free.fr-20160121114223-ngcvndi02ydiqs5z
Allow hyphens in option names to unbreak compatibility.

Show diffs side-by-side

added added

removed removed

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