~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

(jelmer) Use the absolute_import feature everywhere in bzrlib,
 and add a source test to make sure it's used everywhere. (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

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