/brz/remove-bazaar

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

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

  • Committer: Andrew Bennetts
  • Date: 2008-04-08 06:38:34 UTC
  • mfrom: (2892.2.1 smart-set-last-revision)
  • mto: This revision was merged to the branch mainline in revision 3355.
  • Revision ID: andrew.bennetts@canonical.com-20080408063834-o4mid7woclibs6yj
Merge 'Add Branch.set_last_revision_info smart method'.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006, 2007 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""Tests for the smart wire/domain protocol.
 
18
 
 
19
This module contains tests for the domain-level smart requests and responses,
 
20
such as the 'Branch.lock_write' request. Many of these use specific disk
 
21
formats to exercise calls that only make sense for formats with specific
 
22
properties.
 
23
 
 
24
Tests for low-level protocol encoding are found in test_smart_transport.
 
25
"""
 
26
 
 
27
import bz2
 
28
from cStringIO import StringIO
 
29
import tarfile
 
30
 
 
31
from bzrlib import (
 
32
    bzrdir,
 
33
    errors,
 
34
    pack,
 
35
    smart,
 
36
    tests,
 
37
    urlutils,
 
38
    )
 
39
from bzrlib.branch import BranchReferenceFormat
 
40
import bzrlib.smart.branch
 
41
import bzrlib.smart.bzrdir
 
42
import bzrlib.smart.repository
 
43
from bzrlib.smart.request import (
 
44
    FailedSmartServerResponse,
 
45
    SmartServerRequest,
 
46
    SmartServerResponse,
 
47
    SuccessfulSmartServerResponse,
 
48
    )
 
49
from bzrlib.tests import (
 
50
    iter_suite_tests,
 
51
    split_suite_by_re,
 
52
    TestScenarioApplier,
 
53
    )
 
54
from bzrlib.transport import chroot, get_transport
 
55
from bzrlib.util import bencode
 
56
 
 
57
 
 
58
def load_tests(standard_tests, module, loader):
 
59
    """Multiply tests version and protocol consistency."""
 
60
    # FindRepository tests.
 
61
    bzrdir_mod = bzrlib.smart.bzrdir
 
62
    applier = TestScenarioApplier()
 
63
    applier.scenarios = [
 
64
        ("find_repository", {
 
65
            "_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV1}),
 
66
        ("find_repositoryV2", {
 
67
            "_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV2}),
 
68
        ]
 
69
    to_adapt, result = split_suite_by_re(standard_tests,
 
70
        "TestSmartServerRequestFindRepository")
 
71
    v2_only, v1_and_2 = split_suite_by_re(to_adapt,
 
72
        "_v2")
 
73
    for test in iter_suite_tests(v1_and_2):
 
74
        result.addTests(applier.adapt(test))
 
75
    del applier.scenarios[0]
 
76
    for test in iter_suite_tests(v2_only):
 
77
        result.addTests(applier.adapt(test))
 
78
    return result
 
79
 
 
80
 
 
81
class TestCaseWithChrootedTransport(tests.TestCaseWithTransport):
 
82
 
 
83
    def setUp(self):
 
84
        tests.TestCaseWithTransport.setUp(self)
 
85
        self._chroot_server = None
 
86
 
 
87
    def get_transport(self, relpath=None):
 
88
        if self._chroot_server is None:
 
89
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
 
90
            self._chroot_server = chroot.ChrootServer(backing_transport)
 
91
            self._chroot_server.setUp()
 
92
            self.addCleanup(self._chroot_server.tearDown)
 
93
        t = get_transport(self._chroot_server.get_url())
 
94
        if relpath is not None:
 
95
            t = t.clone(relpath)
 
96
        return t
 
97
 
 
98
 
 
99
class TestCaseWithSmartMedium(tests.TestCaseWithTransport):
 
100
 
 
101
    def setUp(self):
 
102
        super(TestCaseWithSmartMedium, self).setUp()
 
103
        # We're allowed to set  the transport class here, so that we don't use
 
104
        # the default or a parameterized class, but rather use the
 
105
        # TestCaseWithTransport infrastructure to set up a smart server and
 
106
        # transport.
 
107
        self.transport_server = smart.server.SmartTCPServer_for_testing
 
108
 
 
109
    def get_smart_medium(self):
 
110
        """Get a smart medium to use in tests."""
 
111
        return self.get_transport().get_smart_medium()
 
112
 
 
113
 
 
114
class TestSmartServerResponse(tests.TestCase):
 
115
 
 
116
    def test__eq__(self):
 
117
        self.assertEqual(SmartServerResponse(('ok', )),
 
118
            SmartServerResponse(('ok', )))
 
119
        self.assertEqual(SmartServerResponse(('ok', ), 'body'),
 
120
            SmartServerResponse(('ok', ), 'body'))
 
121
        self.assertNotEqual(SmartServerResponse(('ok', )),
 
122
            SmartServerResponse(('notok', )))
 
123
        self.assertNotEqual(SmartServerResponse(('ok', ), 'body'),
 
124
            SmartServerResponse(('ok', )))
 
125
        self.assertNotEqual(None,
 
126
            SmartServerResponse(('ok', )))
 
127
 
 
128
    def test__str__(self):
 
129
        """SmartServerResponses can be stringified."""
 
130
        self.assertEqual(
 
131
            "<SmartServerResponse status=OK args=('args',) body='body'>",
 
132
            str(SuccessfulSmartServerResponse(('args',), 'body')))
 
133
        self.assertEqual(
 
134
            "<SmartServerResponse status=ERR args=('args',) body='body'>",
 
135
            str(FailedSmartServerResponse(('args',), 'body')))
 
136
 
 
137
 
 
138
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
 
139
 
 
140
    def test_translate_client_path(self):
 
141
        transport = self.get_transport()
 
142
        request = SmartServerRequest(transport, 'foo/')
 
143
        self.assertEqual('./', request.translate_client_path('foo/'))
 
144
        self.assertRaises(
 
145
            errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
 
146
        self.assertRaises(
 
147
            errors.PathNotChild, request.translate_client_path, '/')
 
148
        self.assertRaises(
 
149
            errors.PathNotChild, request.translate_client_path, 'bar/')
 
150
        self.assertEqual('./baz', request.translate_client_path('foo/baz'))
 
151
 
 
152
    def test_transport_from_client_path(self):
 
153
        transport = self.get_transport()
 
154
        request = SmartServerRequest(transport, 'foo/')
 
155
        self.assertEqual(
 
156
            transport.base,
 
157
            request.transport_from_client_path('foo/').base)
 
158
 
 
159
 
 
160
class TestSmartServerRequestFindRepository(tests.TestCaseWithMemoryTransport):
 
161
    """Tests for BzrDir.find_repository."""
 
162
 
 
163
    def test_no_repository(self):
 
164
        """When there is no repository to be found, ('norepository', ) is returned."""
 
165
        backing = self.get_transport()
 
166
        request = self._request_class(backing)
 
167
        self.make_bzrdir('.')
 
168
        self.assertEqual(SmartServerResponse(('norepository', )),
 
169
            request.execute(''))
 
170
 
 
171
    def test_nonshared_repository(self):
 
172
        # nonshared repositorys only allow 'find' to return a handle when the 
 
173
        # path the repository is being searched on is the same as that that 
 
174
        # the repository is at.
 
175
        backing = self.get_transport()
 
176
        request = self._request_class(backing)
 
177
        result = self._make_repository_and_result()
 
178
        self.assertEqual(result, request.execute(''))
 
179
        self.make_bzrdir('subdir')
 
180
        self.assertEqual(SmartServerResponse(('norepository', )),
 
181
            request.execute('subdir'))
 
182
 
 
183
    def _make_repository_and_result(self, shared=False, format=None):
 
184
        """Convenience function to setup a repository.
 
185
 
 
186
        :result: The SmartServerResponse to expect when opening it.
 
187
        """
 
188
        repo = self.make_repository('.', shared=shared, format=format)
 
189
        if repo.supports_rich_root():
 
190
            rich_root = 'yes'
 
191
        else:
 
192
            rich_root = 'no'
 
193
        if repo._format.supports_tree_reference:
 
194
            subtrees = 'yes'
 
195
        else:
 
196
            subtrees = 'no'
 
197
        if (smart.bzrdir.SmartServerRequestFindRepositoryV2 ==
 
198
            self._request_class):
 
199
            # All tests so far are on formats, and for non-external
 
200
            # repositories.
 
201
            return SuccessfulSmartServerResponse(
 
202
                ('ok', '', rich_root, subtrees, 'no'))
 
203
        else:
 
204
            return SuccessfulSmartServerResponse(('ok', '', rich_root, subtrees))
 
205
 
 
206
    def test_shared_repository(self):
 
207
        """When there is a shared repository, we get 'ok', 'relpath-to-repo'."""
 
208
        backing = self.get_transport()
 
209
        request = self._request_class(backing)
 
210
        result = self._make_repository_and_result(shared=True)
 
211
        self.assertEqual(result, request.execute(''))
 
212
        self.make_bzrdir('subdir')
 
213
        result2 = SmartServerResponse(result.args[0:1] + ('..', ) + result.args[2:])
 
214
        self.assertEqual(result2,
 
215
            request.execute('subdir'))
 
216
        self.make_bzrdir('subdir/deeper')
 
217
        result3 = SmartServerResponse(result.args[0:1] + ('../..', ) + result.args[2:])
 
218
        self.assertEqual(result3,
 
219
            request.execute('subdir/deeper'))
 
220
 
 
221
    def test_rich_root_and_subtree_encoding(self):
 
222
        """Test for the format attributes for rich root and subtree support."""
 
223
        backing = self.get_transport()
 
224
        request = self._request_class(backing)
 
225
        result = self._make_repository_and_result(format='dirstate-with-subtree')
 
226
        # check the test will be valid
 
227
        self.assertEqual('yes', result.args[2])
 
228
        self.assertEqual('yes', result.args[3])
 
229
        self.assertEqual(result, request.execute(''))
 
230
 
 
231
    def test_supports_external_lookups_no_v2(self):
 
232
        """Test for the supports_external_lookups attribute."""
 
233
        backing = self.get_transport()
 
234
        request = self._request_class(backing)
 
235
        result = self._make_repository_and_result(format='dirstate-with-subtree')
 
236
        # check the test will be valid
 
237
        self.assertEqual('no', result.args[4])
 
238
        self.assertEqual(result, request.execute(''))
 
239
 
 
240
 
 
241
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
 
242
 
 
243
    def test_empty_dir(self):
 
244
        """Initializing an empty dir should succeed and do it."""
 
245
        backing = self.get_transport()
 
246
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
 
247
        self.assertEqual(SmartServerResponse(('ok', )),
 
248
            request.execute(''))
 
249
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
 
250
        # no branch, tree or repository is expected with the current 
 
251
        # default formart.
 
252
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
 
253
        self.assertRaises(errors.NotBranchError, made_dir.open_branch)
 
254
        self.assertRaises(errors.NoRepositoryPresent, made_dir.open_repository)
 
255
 
 
256
    def test_missing_dir(self):
 
257
        """Initializing a missing directory should fail like the bzrdir api."""
 
258
        backing = self.get_transport()
 
259
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
 
260
        self.assertRaises(errors.NoSuchFile,
 
261
            request.execute, 'subdir')
 
262
 
 
263
    def test_initialized_dir(self):
 
264
        """Initializing an extant bzrdir should fail like the bzrdir api."""
 
265
        backing = self.get_transport()
 
266
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
 
267
        self.make_bzrdir('subdir')
 
268
        self.assertRaises(errors.FileExists,
 
269
            request.execute, 'subdir')
 
270
 
 
271
 
 
272
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
 
273
 
 
274
    def test_no_branch(self):
 
275
        """When there is no branch, ('nobranch', ) is returned."""
 
276
        backing = self.get_transport()
 
277
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
 
278
        self.make_bzrdir('.')
 
279
        self.assertEqual(SmartServerResponse(('nobranch', )),
 
280
            request.execute(''))
 
281
 
 
282
    def test_branch(self):
 
283
        """When there is a branch, 'ok' is returned."""
 
284
        backing = self.get_transport()
 
285
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
 
286
        self.make_branch('.')
 
287
        self.assertEqual(SmartServerResponse(('ok', '')),
 
288
            request.execute(''))
 
289
 
 
290
    def test_branch_reference(self):
 
291
        """When there is a branch reference, the reference URL is returned."""
 
292
        backing = self.get_transport()
 
293
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
 
294
        branch = self.make_branch('branch')
 
295
        checkout = branch.create_checkout('reference',lightweight=True)
 
296
        reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
 
297
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
 
298
        self.assertEqual(SmartServerResponse(('ok', reference_url)),
 
299
            request.execute('reference'))
 
300
 
 
301
 
 
302
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
 
303
 
 
304
    def test_empty(self):
 
305
        """For an empty branch, the body is empty."""
 
306
        backing = self.get_transport()
 
307
        request = smart.branch.SmartServerRequestRevisionHistory(backing)
 
308
        self.make_branch('.')
 
309
        self.assertEqual(SmartServerResponse(('ok', ), ''),
 
310
            request.execute(''))
 
311
 
 
312
    def test_not_empty(self):
 
313
        """For a non-empty branch, the body is empty."""
 
314
        backing = self.get_transport()
 
315
        request = smart.branch.SmartServerRequestRevisionHistory(backing)
 
316
        tree = self.make_branch_and_memory_tree('.')
 
317
        tree.lock_write()
 
318
        tree.add('')
 
319
        r1 = tree.commit('1st commit')
 
320
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
 
321
        tree.unlock()
 
322
        self.assertEqual(
 
323
            SmartServerResponse(('ok', ), ('\x00'.join([r1, r2]))),
 
324
            request.execute(''))
 
325
 
 
326
 
 
327
class TestSmartServerBranchRequest(tests.TestCaseWithMemoryTransport):
 
328
 
 
329
    def test_no_branch(self):
 
330
        """When there is a bzrdir and no branch, NotBranchError is raised."""
 
331
        backing = self.get_transport()
 
332
        request = smart.branch.SmartServerBranchRequest(backing)
 
333
        self.make_bzrdir('.')
 
334
        self.assertRaises(errors.NotBranchError,
 
335
            request.execute, '')
 
336
 
 
337
    def test_branch_reference(self):
 
338
        """When there is a branch reference, NotBranchError is raised."""
 
339
        backing = self.get_transport()
 
340
        request = smart.branch.SmartServerBranchRequest(backing)
 
341
        branch = self.make_branch('branch')
 
342
        checkout = branch.create_checkout('reference',lightweight=True)
 
343
        self.assertRaises(errors.NotBranchError,
 
344
            request.execute, 'checkout')
 
345
 
 
346
 
 
347
class TestSmartServerBranchRequestLastRevisionInfo(tests.TestCaseWithMemoryTransport):
 
348
 
 
349
    def test_empty(self):
 
350
        """For an empty branch, the result is ('ok', '0', 'null:')."""
 
351
        backing = self.get_transport()
 
352
        request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
 
353
        self.make_branch('.')
 
354
        self.assertEqual(SmartServerResponse(('ok', '0', 'null:')),
 
355
            request.execute(''))
 
356
 
 
357
    def test_not_empty(self):
 
358
        """For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
 
359
        backing = self.get_transport()
 
360
        request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
 
361
        tree = self.make_branch_and_memory_tree('.')
 
362
        tree.lock_write()
 
363
        tree.add('')
 
364
        rev_id_utf8 = u'\xc8'.encode('utf-8')
 
365
        r1 = tree.commit('1st commit')
 
366
        r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
 
367
        tree.unlock()
 
368
        self.assertEqual(
 
369
            SmartServerResponse(('ok', '2', rev_id_utf8)),
 
370
            request.execute(''))
 
371
 
 
372
 
 
373
class TestSmartServerBranchRequestGetConfigFile(tests.TestCaseWithMemoryTransport):
 
374
 
 
375
    def test_default(self):
 
376
        """With no file, we get empty content."""
 
377
        backing = self.get_transport()
 
378
        request = smart.branch.SmartServerBranchGetConfigFile(backing)
 
379
        branch = self.make_branch('.')
 
380
        # there should be no file by default
 
381
        content = ''
 
382
        self.assertEqual(SmartServerResponse(('ok', ), content),
 
383
            request.execute(''))
 
384
 
 
385
    def test_with_content(self):
 
386
        # SmartServerBranchGetConfigFile should return the content from
 
387
        # branch.control_files.get('branch.conf') for now - in the future it may
 
388
        # perform more complex processing. 
 
389
        backing = self.get_transport()
 
390
        request = smart.branch.SmartServerBranchGetConfigFile(backing)
 
391
        branch = self.make_branch('.')
 
392
        branch.control_files.put_utf8('branch.conf', 'foo bar baz')
 
393
        self.assertEqual(SmartServerResponse(('ok', ), 'foo bar baz'),
 
394
            request.execute(''))
 
395
 
 
396
 
 
397
class TestSmartServerBranchRequestSetLastRevision(tests.TestCaseWithMemoryTransport):
 
398
 
 
399
    def test_empty(self):
 
400
        backing = self.get_transport()
 
401
        request = smart.branch.SmartServerBranchRequestSetLastRevision(backing)
 
402
        b = self.make_branch('.')
 
403
        branch_token = b.lock_write()
 
404
        repo_token = b.repository.lock_write()
 
405
        b.repository.unlock()
 
406
        try:
 
407
            self.assertEqual(SmartServerResponse(('ok',)),
 
408
                request.execute(
 
409
                    '', branch_token, repo_token,
 
410
                    'null:'))
 
411
        finally:
 
412
            b.unlock()
 
413
 
 
414
    def test_not_present_revision_id(self):
 
415
        backing = self.get_transport()
 
416
        request = smart.branch.SmartServerBranchRequestSetLastRevision(backing)
 
417
        b = self.make_branch('.')
 
418
        branch_token = b.lock_write()
 
419
        repo_token = b.repository.lock_write()
 
420
        b.repository.unlock()
 
421
        try:
 
422
            revision_id = 'non-existent revision'
 
423
            self.assertEqual(
 
424
                SmartServerResponse(('NoSuchRevision', revision_id)),
 
425
                request.execute(
 
426
                    '', branch_token, repo_token,
 
427
                    revision_id))
 
428
        finally:
 
429
            b.unlock()
 
430
 
 
431
    def test_revision_id_present(self):
 
432
        backing = self.get_transport()
 
433
        request = smart.branch.SmartServerBranchRequestSetLastRevision(backing)
 
434
        tree = self.make_branch_and_memory_tree('.')
 
435
        tree.lock_write()
 
436
        tree.add('')
 
437
        rev_id_utf8 = u'\xc8'.encode('utf-8')
 
438
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
 
439
        r2 = tree.commit('2nd commit')
 
440
        tree.unlock()
 
441
        branch_token = tree.branch.lock_write()
 
442
        repo_token = tree.branch.repository.lock_write()
 
443
        tree.branch.repository.unlock()
 
444
        try:
 
445
            self.assertEqual(
 
446
                SmartServerResponse(('ok',)),
 
447
                request.execute(
 
448
                    '', branch_token, repo_token,
 
449
                    rev_id_utf8))
 
450
            self.assertEqual([rev_id_utf8], tree.branch.revision_history())
 
451
        finally:
 
452
            tree.branch.unlock()
 
453
 
 
454
    def test_revision_id_present2(self):
 
455
        backing = self.get_transport()
 
456
        request = smart.branch.SmartServerBranchRequestSetLastRevision(backing)
 
457
        tree = self.make_branch_and_memory_tree('.')
 
458
        tree.lock_write()
 
459
        tree.add('')
 
460
        rev_id_utf8 = u'\xc8'.encode('utf-8')
 
461
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
 
462
        r2 = tree.commit('2nd commit')
 
463
        tree.unlock()
 
464
        tree.branch.set_revision_history([])
 
465
        branch_token = tree.branch.lock_write()
 
466
        repo_token = tree.branch.repository.lock_write()
 
467
        tree.branch.repository.unlock()
 
468
        try:
 
469
            self.assertEqual(
 
470
                SmartServerResponse(('ok',)),
 
471
                request.execute(
 
472
                    '', branch_token, repo_token,
 
473
                    rev_id_utf8))
 
474
            self.assertEqual([rev_id_utf8], tree.branch.revision_history())
 
475
        finally:
 
476
            tree.branch.unlock()
 
477
 
 
478
 
 
479
class TestSmartServerBranchRequestSetLastRevisionInfo(tests.TestCaseWithTransport):
 
480
 
 
481
    def test_revision_id_present(self):
 
482
        backing = self.get_transport()
 
483
        request = smart.branch.SmartServerBranchRequestSetLastRevision(backing)
 
484
        tree = self.make_branch_and_memory_tree('.')
 
485
        tree.lock_write()
 
486
        tree.add('')
 
487
        rev_id_utf8 = u'\xc8'.encode('utf-8')
 
488
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
 
489
        r2 = tree.commit('2nd commit')
 
490
        tree.unlock()
 
491
        branch_token = tree.branch.lock_write()
 
492
        repo_token = tree.branch.repository.lock_write()
 
493
        tree.branch.repository.unlock()
 
494
        try:
 
495
            self.assertEqual(
 
496
                SmartServerResponse(('ok',)),
 
497
                request.execute(
 
498
                    '', branch_token, repo_token,
 
499
                    rev_id_utf8))
 
500
            self.assertEqual([rev_id_utf8], tree.branch.revision_history())
 
501
        finally:
 
502
            tree.branch.unlock()
 
503
 
 
504
 
 
505
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
 
506
 
 
507
    def setUp(self):
 
508
        tests.TestCaseWithMemoryTransport.setUp(self)
 
509
 
 
510
    def test_lock_write_on_unlocked_branch(self):
 
511
        backing = self.get_transport()
 
512
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
 
513
        branch = self.make_branch('.', format='knit')
 
514
        repository = branch.repository
 
515
        response = request.execute('')
 
516
        branch_nonce = branch.control_files._lock.peek().get('nonce')
 
517
        repository_nonce = repository.control_files._lock.peek().get('nonce')
 
518
        self.assertEqual(
 
519
            SmartServerResponse(('ok', branch_nonce, repository_nonce)),
 
520
            response)
 
521
        # The branch (and associated repository) is now locked.  Verify that
 
522
        # with a new branch object.
 
523
        new_branch = repository.bzrdir.open_branch()
 
524
        self.assertRaises(errors.LockContention, new_branch.lock_write)
 
525
 
 
526
    def test_lock_write_on_locked_branch(self):
 
527
        backing = self.get_transport()
 
528
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
 
529
        branch = self.make_branch('.')
 
530
        branch.lock_write()
 
531
        branch.leave_lock_in_place()
 
532
        branch.unlock()
 
533
        response = request.execute('')
 
534
        self.assertEqual(
 
535
            SmartServerResponse(('LockContention',)), response)
 
536
 
 
537
    def test_lock_write_with_tokens_on_locked_branch(self):
 
538
        backing = self.get_transport()
 
539
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
 
540
        branch = self.make_branch('.', format='knit')
 
541
        branch_token = branch.lock_write()
 
542
        repo_token = branch.repository.lock_write()
 
543
        branch.repository.unlock()
 
544
        branch.leave_lock_in_place()
 
545
        branch.repository.leave_lock_in_place()
 
546
        branch.unlock()
 
547
        response = request.execute('',
 
548
                                   branch_token, repo_token)
 
549
        self.assertEqual(
 
550
            SmartServerResponse(('ok', branch_token, repo_token)), response)
 
551
 
 
552
    def test_lock_write_with_mismatched_tokens_on_locked_branch(self):
 
553
        backing = self.get_transport()
 
554
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
 
555
        branch = self.make_branch('.', format='knit')
 
556
        branch_token = branch.lock_write()
 
557
        repo_token = branch.repository.lock_write()
 
558
        branch.repository.unlock()
 
559
        branch.leave_lock_in_place()
 
560
        branch.repository.leave_lock_in_place()
 
561
        branch.unlock()
 
562
        response = request.execute('',
 
563
                                   branch_token+'xxx', repo_token)
 
564
        self.assertEqual(
 
565
            SmartServerResponse(('TokenMismatch',)), response)
 
566
 
 
567
    def test_lock_write_on_locked_repo(self):
 
568
        backing = self.get_transport()
 
569
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
 
570
        branch = self.make_branch('.', format='knit')
 
571
        branch.repository.lock_write()
 
572
        branch.repository.leave_lock_in_place()
 
573
        branch.repository.unlock()
 
574
        response = request.execute('')
 
575
        self.assertEqual(
 
576
            SmartServerResponse(('LockContention',)), response)
 
577
 
 
578
    def test_lock_write_on_readonly_transport(self):
 
579
        backing = self.get_readonly_transport()
 
580
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
 
581
        branch = self.make_branch('.')
 
582
        root = self.get_transport().clone('/')
 
583
        path = urlutils.relative_url(root.base, self.get_transport().base)
 
584
        response = request.execute(path)
 
585
        error_name, lock_str, why_str = response.args
 
586
        self.assertFalse(response.is_successful())
 
587
        self.assertEqual('LockFailed', error_name)
 
588
 
 
589
 
 
590
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
 
591
 
 
592
    def setUp(self):
 
593
        tests.TestCaseWithMemoryTransport.setUp(self)
 
594
 
 
595
    def test_unlock_on_locked_branch_and_repo(self):
 
596
        backing = self.get_transport()
 
597
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
 
598
        branch = self.make_branch('.', format='knit')
 
599
        # Lock the branch
 
600
        branch_token = branch.lock_write()
 
601
        repo_token = branch.repository.lock_write()
 
602
        branch.repository.unlock()
 
603
        # Unlock the branch (and repo) object, leaving the physical locks
 
604
        # in place.
 
605
        branch.leave_lock_in_place()
 
606
        branch.repository.leave_lock_in_place()
 
607
        branch.unlock()
 
608
        response = request.execute('',
 
609
                                   branch_token, repo_token)
 
610
        self.assertEqual(
 
611
            SmartServerResponse(('ok',)), response)
 
612
        # The branch is now unlocked.  Verify that with a new branch
 
613
        # object.
 
614
        new_branch = branch.bzrdir.open_branch()
 
615
        new_branch.lock_write()
 
616
        new_branch.unlock()
 
617
 
 
618
    def test_unlock_on_unlocked_branch_unlocked_repo(self):
 
619
        backing = self.get_transport()
 
620
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
 
621
        branch = self.make_branch('.', format='knit')
 
622
        response = request.execute(
 
623
            '', 'branch token', 'repo token')
 
624
        self.assertEqual(
 
625
            SmartServerResponse(('TokenMismatch',)), response)
 
626
 
 
627
    def test_unlock_on_unlocked_branch_locked_repo(self):
 
628
        backing = self.get_transport()
 
629
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
 
630
        branch = self.make_branch('.', format='knit')
 
631
        # Lock the repository.
 
632
        repo_token = branch.repository.lock_write()
 
633
        branch.repository.leave_lock_in_place()
 
634
        branch.repository.unlock()
 
635
        # Issue branch lock_write request on the unlocked branch (with locked
 
636
        # repo).
 
637
        response = request.execute(
 
638
            '', 'branch token', repo_token)
 
639
        self.assertEqual(
 
640
            SmartServerResponse(('TokenMismatch',)), response)
 
641
 
 
642
 
 
643
class TestSmartServerRepositoryRequest(tests.TestCaseWithMemoryTransport):
 
644
 
 
645
    def test_no_repository(self):
 
646
        """Raise NoRepositoryPresent when there is a bzrdir and no repo."""
 
647
        # we test this using a shared repository above the named path,
 
648
        # thus checking the right search logic is used - that is, that
 
649
        # its the exact path being looked at and the server is not
 
650
        # searching.
 
651
        backing = self.get_transport()
 
652
        request = smart.repository.SmartServerRepositoryRequest(backing)
 
653
        self.make_repository('.', shared=True)
 
654
        self.make_bzrdir('subdir')
 
655
        self.assertRaises(errors.NoRepositoryPresent,
 
656
            request.execute, 'subdir')
 
657
 
 
658
 
 
659
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithTransport):
 
660
 
 
661
    def test_trivial_bzipped(self):
 
662
        # This tests that the wire encoding is actually bzipped
 
663
        backing = self.get_transport()
 
664
        request = smart.repository.SmartServerRepositoryGetParentMap(backing)
 
665
        tree = self.make_branch_and_memory_tree('.')
 
666
 
 
667
        self.assertEqual(None,
 
668
            request.execute('', 'missing-id'))
 
669
        # Note that it returns a body (of '' bzipped).
 
670
        self.assertEqual(
 
671
            SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
 
672
            request.do_body('\n\n0\n'))
 
673
 
 
674
 
 
675
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithMemoryTransport):
 
676
 
 
677
    def test_none_argument(self):
 
678
        backing = self.get_transport()
 
679
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
 
680
        tree = self.make_branch_and_memory_tree('.')
 
681
        tree.lock_write()
 
682
        tree.add('')
 
683
        r1 = tree.commit('1st commit')
 
684
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
 
685
        tree.unlock()
 
686
 
 
687
        # the lines of revision_id->revision_parent_list has no guaranteed
 
688
        # order coming out of a dict, so sort both our test and response
 
689
        lines = sorted([' '.join([r2, r1]), r1])
 
690
        response = request.execute('', '')
 
691
        response.body = '\n'.join(sorted(response.body.split('\n')))
 
692
 
 
693
        self.assertEqual(
 
694
            SmartServerResponse(('ok', ), '\n'.join(lines)), response)
 
695
 
 
696
    def test_specific_revision_argument(self):
 
697
        backing = self.get_transport()
 
698
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
 
699
        tree = self.make_branch_and_memory_tree('.')
 
700
        tree.lock_write()
 
701
        tree.add('')
 
702
        rev_id_utf8 = u'\xc9'.encode('utf-8')
 
703
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
 
704
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
 
705
        tree.unlock()
 
706
 
 
707
        self.assertEqual(SmartServerResponse(('ok', ), rev_id_utf8),
 
708
            request.execute('', rev_id_utf8))
 
709
    
 
710
    def test_no_such_revision(self):
 
711
        backing = self.get_transport()
 
712
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
 
713
        tree = self.make_branch_and_memory_tree('.')
 
714
        tree.lock_write()
 
715
        tree.add('')
 
716
        r1 = tree.commit('1st commit')
 
717
        tree.unlock()
 
718
 
 
719
        # Note that it still returns body (of zero bytes).
 
720
        self.assertEqual(
 
721
            SmartServerResponse(('nosuchrevision', 'missingrevision', ), ''),
 
722
            request.execute('', 'missingrevision'))
 
723
 
 
724
 
 
725
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
 
726
 
 
727
    def test_missing_revision(self):
 
728
        """For a missing revision, ('no', ) is returned."""
 
729
        backing = self.get_transport()
 
730
        request = smart.repository.SmartServerRequestHasRevision(backing)
 
731
        self.make_repository('.')
 
732
        self.assertEqual(SmartServerResponse(('no', )),
 
733
            request.execute('', 'revid'))
 
734
 
 
735
    def test_present_revision(self):
 
736
        """For a present revision, ('yes', ) is returned."""
 
737
        backing = self.get_transport()
 
738
        request = smart.repository.SmartServerRequestHasRevision(backing)
 
739
        tree = self.make_branch_and_memory_tree('.')
 
740
        tree.lock_write()
 
741
        tree.add('')
 
742
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
 
743
        r1 = tree.commit('a commit', rev_id=rev_id_utf8)
 
744
        tree.unlock()
 
745
        self.assertTrue(tree.branch.repository.has_revision(rev_id_utf8))
 
746
        self.assertEqual(SmartServerResponse(('yes', )),
 
747
            request.execute('', rev_id_utf8))
 
748
 
 
749
 
 
750
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
 
751
 
 
752
    def test_empty_revid(self):
 
753
        """With an empty revid, we get only size an number and revisions"""
 
754
        backing = self.get_transport()
 
755
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
 
756
        repository = self.make_repository('.')
 
757
        stats = repository.gather_stats()
 
758
        size = stats['size']
 
759
        expected_body = 'revisions: 0\nsize: %d\n' % size
 
760
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
 
761
                         request.execute('', '', 'no'))
 
762
 
 
763
    def test_revid_with_committers(self):
 
764
        """For a revid we get more infos."""
 
765
        backing = self.get_transport()
 
766
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
 
767
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
 
768
        tree = self.make_branch_and_memory_tree('.')
 
769
        tree.lock_write()
 
770
        tree.add('')
 
771
        # Let's build a predictable result
 
772
        tree.commit('a commit', timestamp=123456.2, timezone=3600)
 
773
        tree.commit('a commit', timestamp=654321.4, timezone=0,
 
774
                    rev_id=rev_id_utf8)
 
775
        tree.unlock()
 
776
 
 
777
        stats = tree.branch.repository.gather_stats()
 
778
        size = stats['size']
 
779
        expected_body = ('firstrev: 123456.200 3600\n'
 
780
                         'latestrev: 654321.400 0\n'
 
781
                         'revisions: 2\n'
 
782
                         'size: %d\n' % size)
 
783
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
 
784
                         request.execute('',
 
785
                                         rev_id_utf8, 'no'))
 
786
 
 
787
    def test_not_empty_repository_with_committers(self):
 
788
        """For a revid and requesting committers we get the whole thing."""
 
789
        backing = self.get_transport()
 
790
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
 
791
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
 
792
        tree = self.make_branch_and_memory_tree('.')
 
793
        tree.lock_write()
 
794
        tree.add('')
 
795
        # Let's build a predictable result
 
796
        tree.commit('a commit', timestamp=123456.2, timezone=3600,
 
797
                    committer='foo')
 
798
        tree.commit('a commit', timestamp=654321.4, timezone=0,
 
799
                    committer='bar', rev_id=rev_id_utf8)
 
800
        tree.unlock()
 
801
        stats = tree.branch.repository.gather_stats()
 
802
 
 
803
        size = stats['size']
 
804
        expected_body = ('committers: 2\n'
 
805
                         'firstrev: 123456.200 3600\n'
 
806
                         'latestrev: 654321.400 0\n'
 
807
                         'revisions: 2\n'
 
808
                         'size: %d\n' % size)
 
809
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
 
810
                         request.execute('',
 
811
                                         rev_id_utf8, 'yes'))
 
812
 
 
813
 
 
814
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
 
815
 
 
816
    def test_is_shared(self):
 
817
        """For a shared repository, ('yes', ) is returned."""
 
818
        backing = self.get_transport()
 
819
        request = smart.repository.SmartServerRepositoryIsShared(backing)
 
820
        self.make_repository('.', shared=True)
 
821
        self.assertEqual(SmartServerResponse(('yes', )),
 
822
            request.execute('', ))
 
823
 
 
824
    def test_is_not_shared(self):
 
825
        """For a shared repository, ('no', ) is returned."""
 
826
        backing = self.get_transport()
 
827
        request = smart.repository.SmartServerRepositoryIsShared(backing)
 
828
        self.make_repository('.', shared=False)
 
829
        self.assertEqual(SmartServerResponse(('no', )),
 
830
            request.execute('', ))
 
831
 
 
832
 
 
833
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
 
834
 
 
835
    def setUp(self):
 
836
        tests.TestCaseWithMemoryTransport.setUp(self)
 
837
 
 
838
    def test_lock_write_on_unlocked_repo(self):
 
839
        backing = self.get_transport()
 
840
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
 
841
        repository = self.make_repository('.', format='knit')
 
842
        response = request.execute('')
 
843
        nonce = repository.control_files._lock.peek().get('nonce')
 
844
        self.assertEqual(SmartServerResponse(('ok', nonce)), response)
 
845
        # The repository is now locked.  Verify that with a new repository
 
846
        # object.
 
847
        new_repo = repository.bzrdir.open_repository()
 
848
        self.assertRaises(errors.LockContention, new_repo.lock_write)
 
849
 
 
850
    def test_lock_write_on_locked_repo(self):
 
851
        backing = self.get_transport()
 
852
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
 
853
        repository = self.make_repository('.', format='knit')
 
854
        repository.lock_write()
 
855
        repository.leave_lock_in_place()
 
856
        repository.unlock()
 
857
        response = request.execute('')
 
858
        self.assertEqual(
 
859
            SmartServerResponse(('LockContention',)), response)
 
860
 
 
861
    def test_lock_write_on_readonly_transport(self):
 
862
        backing = self.get_readonly_transport()
 
863
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
 
864
        repository = self.make_repository('.', format='knit')
 
865
        response = request.execute('')
 
866
        self.assertFalse(response.is_successful())
 
867
        self.assertEqual('LockFailed', response.args[0])
 
868
 
 
869
 
 
870
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
 
871
 
 
872
    def setUp(self):
 
873
        tests.TestCaseWithMemoryTransport.setUp(self)
 
874
 
 
875
    def test_unlock_on_locked_repo(self):
 
876
        backing = self.get_transport()
 
877
        request = smart.repository.SmartServerRepositoryUnlock(backing)
 
878
        repository = self.make_repository('.', format='knit')
 
879
        token = repository.lock_write()
 
880
        repository.leave_lock_in_place()
 
881
        repository.unlock()
 
882
        response = request.execute('', token)
 
883
        self.assertEqual(
 
884
            SmartServerResponse(('ok',)), response)
 
885
        # The repository is now unlocked.  Verify that with a new repository
 
886
        # object.
 
887
        new_repo = repository.bzrdir.open_repository()
 
888
        new_repo.lock_write()
 
889
        new_repo.unlock()
 
890
 
 
891
    def test_unlock_on_unlocked_repo(self):
 
892
        backing = self.get_transport()
 
893
        request = smart.repository.SmartServerRepositoryUnlock(backing)
 
894
        repository = self.make_repository('.', format='knit')
 
895
        response = request.execute('', 'some token')
 
896
        self.assertEqual(
 
897
            SmartServerResponse(('TokenMismatch',)), response)
 
898
 
 
899
 
 
900
class TestSmartServerRepositoryTarball(tests.TestCaseWithTransport):
 
901
 
 
902
    def test_repository_tarball(self):
 
903
        backing = self.get_transport()
 
904
        request = smart.repository.SmartServerRepositoryTarball(backing)
 
905
        repository = self.make_repository('.')
 
906
        # make some extraneous junk in the repository directory which should
 
907
        # not be copied
 
908
        self.build_tree(['.bzr/repository/extra-junk'])
 
909
        response = request.execute('', 'bz2')
 
910
        self.assertEqual(('ok',), response.args)
 
911
        # body should be a tbz2
 
912
        body_file = StringIO(response.body)
 
913
        body_tar = tarfile.open('body_tar.tbz2', fileobj=body_file,
 
914
            mode='r|bz2')
 
915
        # let's make sure there are some key repository components inside it.
 
916
        # the tarfile returns directories with trailing slashes...
 
917
        names = set([n.rstrip('/') for n in body_tar.getnames()])
 
918
        self.assertTrue('.bzr/repository/lock' in names)
 
919
        self.assertTrue('.bzr/repository/format' in names)
 
920
        self.assertTrue('.bzr/repository/extra-junk' not in names,
 
921
            "extraneous file present in tar file")
 
922
 
 
923
 
 
924
class TestSmartServerRepositoryStreamKnitData(tests.TestCaseWithMemoryTransport):
 
925
 
 
926
    def test_fetch_revisions(self):
 
927
        backing = self.get_transport()
 
928
        request = smart.repository.SmartServerRepositoryStreamKnitDataForRevisions(backing)
 
929
        tree = self.make_branch_and_memory_tree('.')
 
930
        tree.lock_write()
 
931
        tree.add('')
 
932
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
 
933
        rev_id2_utf8 = u'\xc9'.encode('utf-8')
 
934
        r1 = tree.commit('1st commit', rev_id=rev_id1_utf8)
 
935
        r1 = tree.commit('2nd commit', rev_id=rev_id2_utf8)
 
936
        tree.unlock()
 
937
 
 
938
        response = request.execute('', rev_id2_utf8)
 
939
        self.assertEqual(('ok',), response.args)
 
940
        unpacker = pack.ContainerReader(StringIO(response.body))
 
941
        names = []
 
942
        for [name], read_bytes in unpacker.iter_records():
 
943
            names.append(name)
 
944
            bytes = read_bytes(None)
 
945
            # The bytes should be a valid bencoded string.
 
946
            bencode.bdecode(bytes)
 
947
            # XXX: assert that the bencoded knit records have the right
 
948
            # contents?
 
949
        
 
950
    def test_no_such_revision_error(self):
 
951
        backing = self.get_transport()
 
952
        request = smart.repository.SmartServerRepositoryStreamKnitDataForRevisions(backing)
 
953
        repo = self.make_repository('.')
 
954
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
 
955
        response = request.execute('', rev_id1_utf8)
 
956
        self.assertEqual(
 
957
            SmartServerResponse(('NoSuchRevision', rev_id1_utf8)),
 
958
            response)
 
959
 
 
960
 
 
961
class TestSmartServerRepositoryStreamRevisionsChunked(tests.TestCaseWithMemoryTransport):
 
962
 
 
963
    def test_fetch_revisions(self):
 
964
        backing = self.get_transport()
 
965
        request = smart.repository.SmartServerRepositoryStreamRevisionsChunked(
 
966
            backing)
 
967
        tree = self.make_branch_and_memory_tree('.')
 
968
        tree.lock_write()
 
969
        tree.add('')
 
970
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
 
971
        rev_id2_utf8 = u'\xc9'.encode('utf-8')
 
972
        tree.commit('1st commit', rev_id=rev_id1_utf8)
 
973
        tree.commit('2nd commit', rev_id=rev_id2_utf8)
 
974
        tree.unlock()
 
975
 
 
976
        response = request.execute('')
 
977
        self.assertEqual(None, response)
 
978
        response = request.do_body("%s\n%s\n1" % (rev_id2_utf8, rev_id1_utf8))
 
979
        self.assertEqual(('ok',), response.args)
 
980
        parser = pack.ContainerPushParser()
 
981
        names = []
 
982
        for stream_bytes in response.body_stream:
 
983
            parser.accept_bytes(stream_bytes)
 
984
            for [name], record_bytes in parser.read_pending_records():
 
985
                names.append(name)
 
986
                # The bytes should be a valid bencoded string.
 
987
                bencode.bdecode(record_bytes)
 
988
                # XXX: assert that the bencoded knit records have the right
 
989
                # contents?
 
990
        
 
991
    def test_no_such_revision_error(self):
 
992
        backing = self.get_transport()
 
993
        request = smart.repository.SmartServerRepositoryStreamRevisionsChunked(
 
994
            backing)
 
995
        repo = self.make_repository('.')
 
996
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
 
997
        response = request.execute('')
 
998
        self.assertEqual(None, response)
 
999
        response = request.do_body("%s\n\n1" % (rev_id1_utf8,))
 
1000
        self.assertEqual(
 
1001
            FailedSmartServerResponse(('NoSuchRevision', )),
 
1002
            response)
 
1003
 
 
1004
 
 
1005
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
 
1006
 
 
1007
    def test_is_readonly_no(self):
 
1008
        backing = self.get_transport()
 
1009
        request = smart.request.SmartServerIsReadonly(backing)
 
1010
        response = request.execute()
 
1011
        self.assertEqual(
 
1012
            SmartServerResponse(('no',)), response)
 
1013
 
 
1014
    def test_is_readonly_yes(self):
 
1015
        backing = self.get_readonly_transport()
 
1016
        request = smart.request.SmartServerIsReadonly(backing)
 
1017
        response = request.execute()
 
1018
        self.assertEqual(
 
1019
            SmartServerResponse(('yes',)), response)
 
1020
 
 
1021
 
 
1022
class TestHandlers(tests.TestCase):
 
1023
    """Tests for the request.request_handlers object."""
 
1024
 
 
1025
    def test_registered_methods(self):
 
1026
        """Test that known methods are registered to the correct object."""
 
1027
        self.assertEqual(
 
1028
            smart.request.request_handlers.get('Branch.get_config_file'),
 
1029
            smart.branch.SmartServerBranchGetConfigFile)
 
1030
        self.assertEqual(
 
1031
            smart.request.request_handlers.get('Branch.lock_write'),
 
1032
            smart.branch.SmartServerBranchRequestLockWrite)
 
1033
        self.assertEqual(
 
1034
            smart.request.request_handlers.get('Branch.last_revision_info'),
 
1035
            smart.branch.SmartServerBranchRequestLastRevisionInfo)
 
1036
        self.assertEqual(
 
1037
            smart.request.request_handlers.get('Branch.revision_history'),
 
1038
            smart.branch.SmartServerRequestRevisionHistory)
 
1039
        self.assertEqual(
 
1040
            smart.request.request_handlers.get('Branch.set_last_revision'),
 
1041
            smart.branch.SmartServerBranchRequestSetLastRevision)
 
1042
        self.assertEqual(
 
1043
            smart.request.request_handlers.get('Branch.set_last_revision_info'),
 
1044
            smart.branch.SmartServerBranchRequestSetLastRevisionInfo)
 
1045
        self.assertEqual(
 
1046
            smart.request.request_handlers.get('Branch.unlock'),
 
1047
            smart.branch.SmartServerBranchRequestUnlock)
 
1048
        self.assertEqual(
 
1049
            smart.request.request_handlers.get('BzrDir.find_repository'),
 
1050
            smart.bzrdir.SmartServerRequestFindRepositoryV1)
 
1051
        self.assertEqual(
 
1052
            smart.request.request_handlers.get('BzrDir.find_repositoryV2'),
 
1053
            smart.bzrdir.SmartServerRequestFindRepositoryV2)
 
1054
        self.assertEqual(
 
1055
            smart.request.request_handlers.get('BzrDirFormat.initialize'),
 
1056
            smart.bzrdir.SmartServerRequestInitializeBzrDir)
 
1057
        self.assertEqual(
 
1058
            smart.request.request_handlers.get('BzrDir.open_branch'),
 
1059
            smart.bzrdir.SmartServerRequestOpenBranch)
 
1060
        self.assertEqual(
 
1061
            smart.request.request_handlers.get('Repository.gather_stats'),
 
1062
            smart.repository.SmartServerRepositoryGatherStats)
 
1063
        self.assertEqual(
 
1064
            smart.request.request_handlers.get('Repository.get_parent_map'),
 
1065
            smart.repository.SmartServerRepositoryGetParentMap)
 
1066
        self.assertEqual(
 
1067
            smart.request.request_handlers.get(
 
1068
                'Repository.get_revision_graph'),
 
1069
            smart.repository.SmartServerRepositoryGetRevisionGraph)
 
1070
        self.assertEqual(
 
1071
            smart.request.request_handlers.get('Repository.has_revision'),
 
1072
            smart.repository.SmartServerRequestHasRevision)
 
1073
        self.assertEqual(
 
1074
            smart.request.request_handlers.get('Repository.is_shared'),
 
1075
            smart.repository.SmartServerRepositoryIsShared)
 
1076
        self.assertEqual(
 
1077
            smart.request.request_handlers.get('Repository.lock_write'),
 
1078
            smart.repository.SmartServerRepositoryLockWrite)
 
1079
        self.assertEqual(
 
1080
            smart.request.request_handlers.get('Repository.tarball'),
 
1081
            smart.repository.SmartServerRepositoryTarball)
 
1082
        self.assertEqual(
 
1083
            smart.request.request_handlers.get('Repository.unlock'),
 
1084
            smart.repository.SmartServerRepositoryUnlock)
 
1085
        self.assertEqual(
 
1086
            smart.request.request_handlers.get('Transport.is_readonly'),
 
1087
            smart.request.SmartServerIsReadonly)