~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

  • Committer: Ian Clatworthy
  • Date: 2009-12-03 23:21:16 UTC
  • mfrom: (4852.4.1 RCStoVCS)
  • mto: This revision was merged to the branch mainline in revision 4860.
  • Revision ID: ian.clatworthy@canonical.com-20091203232116-f8igfvc6muqrn4yx
Revision Control -> Version Control in docs

Show diffs side-by-side

added added

removed removed

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