~bzr-pqm/bzr/bzr.dev

2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
1
# Copyright (C) 2006 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 protococl."""
18
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
19
from bzrlib import bzrdir, errors, smart, tests
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
20
from bzrlib.smart.request import SmartServerResponse
21
import bzrlib.smart.bzrdir
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
22
import bzrlib.smart.branch
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
23
import bzrlib.smart.repository
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
24
25
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
26
class TestCaseWithSmartMedium(tests.TestCaseWithTransport):
27
28
    def setUp(self):
29
        super(TestCaseWithSmartMedium, self).setUp()
30
        # We're allowed to set  the transport class here, so that we don't use
31
        # the default or a parameterized class, but rather use the
32
        # TestCaseWithTransport infrastructure to set up a smart server and
33
        # transport.
34
        self.transport_server = smart.server.SmartTCPServer_for_testing
35
36
    def get_smart_medium(self):
37
        """Get a smart medium to use in tests."""
38
        return self.get_transport().get_smart_medium()
39
40
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
41
class TestSmartServerResponse(tests.TestCase):
42
43
    def test__eq__(self):
44
        self.assertEqual(SmartServerResponse(('ok', )),
45
            SmartServerResponse(('ok', )))
46
        self.assertEqual(SmartServerResponse(('ok', ), 'body'),
47
            SmartServerResponse(('ok', ), 'body'))
48
        self.assertNotEqual(SmartServerResponse(('ok', )),
49
            SmartServerResponse(('notok', )))
50
        self.assertNotEqual(SmartServerResponse(('ok', ), 'body'),
51
            SmartServerResponse(('ok', )))
2018.5.41 by Robert Collins
Fix SmartServerResponse.__eq__ to handle None.
52
        self.assertNotEqual(None,
53
            SmartServerResponse(('ok', )))
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
54
55
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
56
class TestSmartServerRequestFindRepository(tests.TestCaseWithTransport):
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
57
    """Tests for BzrDir.find_repository."""
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
58
59
    def test_no_repository(self):
60
        """When there is no repository to be found, ('norepository', ) is returned."""
61
        backing = self.get_transport()
62
        request = smart.bzrdir.SmartServerRequestFindRepository(backing)
63
        self.make_bzrdir('.')
64
        self.assertEqual(SmartServerResponse(('norepository', )),
65
            request.execute(backing.local_abspath('')))
66
67
    def test_nonshared_repository(self):
68
        # nonshared repositorys only allow 'find' to return a handle when the 
69
        # path the repository is being searched on is the same as that that 
70
        # the repository is at.
71
        backing = self.get_transport()
72
        request = smart.bzrdir.SmartServerRequestFindRepository(backing)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
73
        result = self._make_repository_and_result()
74
        self.assertEqual(result, request.execute(backing.local_abspath('')))
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
75
        self.make_bzrdir('subdir')
76
        self.assertEqual(SmartServerResponse(('norepository', )),
77
            request.execute(backing.local_abspath('subdir')))
78
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
79
    def _make_repository_and_result(self, shared=False, format=None):
80
        """Convenience function to setup a repository.
81
82
        :result: The SmartServerResponse to expect when opening it.
83
        """
84
        repo = self.make_repository('.', shared=shared, format=format)
85
        if repo.supports_rich_root():
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
86
            rich_root = 'yes'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
87
        else:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
88
            rich_root = 'no'
2018.5.138 by Robert Collins
Merge bzr.dev.
89
        if repo._format.supports_tree_reference:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
90
            subtrees = 'yes'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
91
        else:
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
92
            subtrees = 'no'
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
93
        return SmartServerResponse(('ok', '', rich_root, subtrees))
94
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
95
    def test_shared_repository(self):
96
        """When there is a shared repository, we get 'ok', 'relpath-to-repo'."""
97
        backing = self.get_transport()
98
        request = smart.bzrdir.SmartServerRequestFindRepository(backing)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
99
        result = self._make_repository_and_result(shared=True)
100
        self.assertEqual(result, request.execute(backing.local_abspath('')))
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
101
        self.make_bzrdir('subdir')
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
102
        result2 = SmartServerResponse(result.args[0:1] + ('..', ) + result.args[2:])
103
        self.assertEqual(result2,
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
104
            request.execute(backing.local_abspath('subdir')))
105
        self.make_bzrdir('subdir/deeper')
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
106
        result3 = SmartServerResponse(result.args[0:1] + ('../..', ) + result.args[2:])
107
        self.assertEqual(result3,
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
108
            request.execute(backing.local_abspath('subdir/deeper')))
109
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
110
    def test_rich_root_and_subtree_encoding(self):
111
        """Test for the format attributes for rich root and subtree support."""
112
        backing = self.get_transport()
113
        request = smart.bzrdir.SmartServerRequestFindRepository(backing)
114
        result = self._make_repository_and_result(format='dirstate-with-subtree')
115
        # check the test will be valid
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
116
        self.assertEqual('yes', result.args[2])
117
        self.assertEqual('yes', result.args[3])
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
118
        self.assertEqual(result, request.execute(backing.local_abspath('')))
119
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
120
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
121
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithTransport):
122
123
    def test_empty_dir(self):
124
        """Initializing an empty dir should succeed and do it."""
125
        backing = self.get_transport()
126
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
127
        self.assertEqual(SmartServerResponse(('ok', )),
128
            request.execute(backing.local_abspath('.')))
129
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
130
        # no branch, tree or repository is expected with the current 
131
        # default formart.
132
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
133
        self.assertRaises(errors.NotBranchError, made_dir.open_branch)
134
        self.assertRaises(errors.NoRepositoryPresent, made_dir.open_repository)
135
136
    def test_missing_dir(self):
137
        """Initializing a missing directory should fail like the bzrdir api."""
138
        backing = self.get_transport()
139
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
140
        self.assertRaises(errors.NoSuchFile,
141
            request.execute, backing.local_abspath('subdir'))
142
143
    def test_initialized_dir(self):
144
        """Initializing an extant bzrdir should fail like the bzrdir api."""
145
        backing = self.get_transport()
146
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
147
        self.make_bzrdir('subdir')
148
        self.assertRaises(errors.FileExists,
149
            request.execute, backing.local_abspath('subdir'))
150
151
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
152
class TestSmartServerRequestOpenBranch(tests.TestCaseWithTransport):
153
154
    def test_no_branch(self):
155
        """When there is no branch, ('nobranch', ) is returned."""
156
        backing = self.get_transport()
157
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
158
        self.make_bzrdir('.')
159
        self.assertEqual(SmartServerResponse(('nobranch', )),
160
            request.execute(backing.local_abspath('')))
161
162
    def test_branch(self):
163
        """When there is a branch, 'ok' is returned."""
164
        backing = self.get_transport()
165
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
166
        self.make_branch('.')
167
        self.assertEqual(SmartServerResponse(('ok', '')),
168
            request.execute(backing.local_abspath('')))
169
170
    def test_branch_reference(self):
171
        """When there is a branch reference, the reference URL is returned."""
172
        backing = self.get_transport()
173
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
174
        branch = self.make_branch('branch')
175
        checkout = branch.create_checkout('reference',lightweight=True)
176
        # TODO: once we have an API to probe for references of any sort, we
177
        # can use it here.
178
        reference_url = backing.abspath('branch') + '/'
179
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
180
        self.assertEqual(SmartServerResponse(('ok', reference_url)),
181
            request.execute(backing.local_abspath('reference')))
182
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
183
184
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithTransport):
185
186
    def test_empty(self):
187
        """For an empty branch, the body is empty."""
188
        backing = self.get_transport()
189
        request = smart.branch.SmartServerRequestRevisionHistory(backing)
190
        self.make_branch('.')
191
        self.assertEqual(SmartServerResponse(('ok', ), ''),
192
            request.execute(backing.local_abspath('')))
193
194
    def test_not_empty(self):
195
        """For a non-empty branch, the body is empty."""
196
        backing = self.get_transport()
197
        request = smart.branch.SmartServerRequestRevisionHistory(backing)
198
        tree = self.make_branch_and_memory_tree('.')
199
        tree.lock_write()
200
        tree.add('')
201
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
202
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
203
        tree.unlock()
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
204
        self.assertEqual(
205
            SmartServerResponse(('ok', ), ('\x00'.join([r1, r2]))),
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
206
            request.execute(backing.local_abspath('')))
207
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
208
209
class TestSmartServerBranchRequest(tests.TestCaseWithTransport):
210
211
    def test_no_branch(self):
212
        """When there is a bzrdir and no branch, NotBranchError is raised."""
213
        backing = self.get_transport()
214
        request = smart.branch.SmartServerBranchRequest(backing)
215
        self.make_bzrdir('.')
216
        self.assertRaises(errors.NotBranchError,
217
            request.execute, backing.local_abspath(''))
218
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
219
    def test_branch_reference(self):
220
        """When there is a branch reference, NotBranchError is raised."""
221
        backing = self.get_transport()
2018.5.49 by Wouter van Heyst
Refactor SmartServerBranchRequest out from SmartServerRequestRevisionHistory to
222
        request = smart.branch.SmartServerBranchRequest(backing)
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
223
        branch = self.make_branch('branch')
224
        checkout = branch.create_checkout('reference',lightweight=True)
225
        self.assertRaises(errors.NotBranchError,
226
            request.execute, backing.local_abspath('checkout'))
227
228
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
229
class TestSmartServerBranchRequestLastRevisionInfo(tests.TestCaseWithTransport):
230
231
    def test_empty(self):
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
232
        """For an empty branch, the result is ('ok', '0', 'null:')."""
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
233
        backing = self.get_transport()
234
        request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
235
        self.make_branch('.')
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
236
        self.assertEqual(SmartServerResponse(('ok', '0', 'null:')),
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
237
            request.execute(backing.local_abspath('')))
238
239
    def test_not_empty(self):
240
        """For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
241
        backing = self.get_transport()
242
        request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
243
        tree = self.make_branch_and_memory_tree('.')
244
        tree.lock_write()
245
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
246
        rev_id_utf8 = u'\xc8'.encode('utf-8')
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
247
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
248
        r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
249
        tree.unlock()
250
        self.assertEqual(
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
251
            SmartServerResponse(('ok', '2', rev_id_utf8)),
2018.5.50 by Wouter van Heyst
Add SmartServerBranchRequestLastRevisionInfo method.
252
            request.execute(backing.local_abspath('')))
253
254
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
255
class TestSmartServerBranchRequestGetConfigFile(tests.TestCaseWithTransport):
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
256
257
    def test_default(self):
258
        """With no file, we get empty content."""
259
        backing = self.get_transport()
260
        request = smart.branch.SmartServerBranchGetConfigFile(backing)
261
        branch = self.make_branch('.')
262
        # there should be no file by default
263
        content = ''
264
        self.assertEqual(SmartServerResponse(('ok', ), content),
265
            request.execute(backing.local_abspath('')))
266
267
    def test_with_content(self):
268
        # SmartServerBranchGetConfigFile should return the content from
269
        # branch.control_files.get('branch.conf') for now - in the future it may
270
        # perform more complex processing. 
271
        backing = self.get_transport()
272
        request = smart.branch.SmartServerBranchGetConfigFile(backing)
273
        branch = self.make_branch('.')
274
        branch.control_files.put_utf8('branch.conf', 'foo bar baz')
275
        self.assertEqual(SmartServerResponse(('ok', ), 'foo bar baz'),
276
            request.execute(backing.local_abspath('')))
277
278
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
279
class TestSmartServerBranchRequestSetLastRevision(tests.TestCaseWithTransport):
280
281
    def test_empty(self):
282
        backing = self.get_transport()
283
        request = smart.branch.SmartServerBranchRequestSetLastRevision(backing)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
284
        b = self.make_branch('.')
2018.5.144 by Andrew Bennetts
Fix four tests I broke with the Branch.lock_write changes.
285
        branch_token = b.lock_write()
286
        repo_token = b.repository.lock_write()
287
        b.repository.unlock()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
288
        try:
289
            self.assertEqual(SmartServerResponse(('ok',)),
290
                request.execute(
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
291
                    backing.local_abspath(''), branch_token, repo_token,
292
                    'null:'))
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
293
        finally:
294
            b.unlock()
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
295
296
    def test_not_present_revision_id(self):
297
        backing = self.get_transport()
298
        request = smart.branch.SmartServerBranchRequestSetLastRevision(backing)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
299
        b = self.make_branch('.')
2018.5.144 by Andrew Bennetts
Fix four tests I broke with the Branch.lock_write changes.
300
        branch_token = b.lock_write()
301
        repo_token = b.repository.lock_write()
302
        b.repository.unlock()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
303
        try:
304
            revision_id = 'non-existent revision'
305
            self.assertEqual(
306
                SmartServerResponse(('NoSuchRevision', revision_id)),
307
                request.execute(
308
                    backing.local_abspath(''), branch_token, repo_token,
309
                    revision_id))
310
        finally:
311
            b.unlock()
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
312
313
    def test_revision_id_present(self):
314
        backing = self.get_transport()
315
        request = smart.branch.SmartServerBranchRequestSetLastRevision(backing)
316
        tree = self.make_branch_and_memory_tree('.')
317
        tree.lock_write()
318
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
319
        rev_id_utf8 = u'\xc8'.encode('utf-8')
320
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
321
        r2 = tree.commit('2nd commit')
322
        tree.unlock()
2018.5.144 by Andrew Bennetts
Fix four tests I broke with the Branch.lock_write changes.
323
        branch_token = tree.branch.lock_write()
324
        repo_token = tree.branch.repository.lock_write()
325
        tree.branch.repository.unlock()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
326
        try:
327
            self.assertEqual(
328
                SmartServerResponse(('ok',)),
329
                request.execute(
330
                    backing.local_abspath(''), branch_token, repo_token,
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
331
                    rev_id_utf8))
332
            self.assertEqual([rev_id_utf8], tree.branch.revision_history())
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
333
        finally:
334
            tree.branch.unlock()
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
335
336
    def test_revision_id_present2(self):
337
        backing = self.get_transport()
338
        request = smart.branch.SmartServerBranchRequestSetLastRevision(backing)
339
        tree = self.make_branch_and_memory_tree('.')
340
        tree.lock_write()
341
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
342
        rev_id_utf8 = u'\xc8'.encode('utf-8')
343
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
344
        r2 = tree.commit('2nd commit')
345
        tree.unlock()
346
        tree.branch.set_revision_history([])
2018.5.144 by Andrew Bennetts
Fix four tests I broke with the Branch.lock_write changes.
347
        branch_token = tree.branch.lock_write()
348
        repo_token = tree.branch.repository.lock_write()
349
        tree.branch.repository.unlock()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
350
        try:
351
            self.assertEqual(
352
                SmartServerResponse(('ok',)),
353
                request.execute(
354
                    backing.local_abspath(''), branch_token, repo_token,
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
355
                    rev_id_utf8))
356
            self.assertEqual([rev_id_utf8], tree.branch.revision_history())
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
357
        finally:
358
            tree.branch.unlock()
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
359
360
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
361
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithTransport):
362
363
    def setUp(self):
364
        tests.TestCaseWithTransport.setUp(self)
365
        self.reduceLockdirTimeout()
366
367
    def test_lock_write_on_unlocked_branch(self):
368
        backing = self.get_transport()
369
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
370
        branch = self.make_branch('.')
371
        repository = branch.repository
372
        response = request.execute(backing.local_abspath(''))
373
        branch_nonce = branch.control_files._lock.peek().get('nonce')
374
        repository_nonce = repository.control_files._lock.peek().get('nonce')
375
        self.assertEqual(
376
            SmartServerResponse(('ok', branch_nonce, repository_nonce)),
377
            response)
378
        # The branch (and associated repository) is now locked.  Verify that
379
        # with a new branch object.
380
        new_branch = repository.bzrdir.open_branch()
381
        self.assertRaises(errors.LockContention, new_branch.lock_write)
382
383
    def test_lock_write_on_locked_branch(self):
384
        backing = self.get_transport()
385
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
386
        branch = self.make_branch('.')
387
        branch.lock_write()
388
        branch.leave_lock_in_place()
389
        branch.unlock()
390
        response = request.execute(backing.local_abspath(''))
391
        self.assertEqual(
392
            SmartServerResponse(('LockContention',)), response)
393
394
    def test_lock_write_with_tokens_on_locked_branch(self):
395
        backing = self.get_transport()
396
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
397
        branch = self.make_branch('.')
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
398
        branch_token = branch.lock_write()
399
        repo_token = branch.repository.lock_write()
400
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
401
        branch.leave_lock_in_place()
402
        branch.repository.leave_lock_in_place()
403
        branch.unlock()
404
        response = request.execute(backing.local_abspath(''),
405
                                   branch_token, repo_token)
406
        self.assertEqual(
407
            SmartServerResponse(('ok', branch_token, repo_token)), response)
408
409
    def test_lock_write_with_mismatched_tokens_on_locked_branch(self):
410
        backing = self.get_transport()
411
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
412
        branch = self.make_branch('.')
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
413
        branch_token = branch.lock_write()
414
        repo_token = branch.repository.lock_write()
415
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
416
        branch.leave_lock_in_place()
417
        branch.repository.leave_lock_in_place()
418
        branch.unlock()
419
        response = request.execute(backing.local_abspath(''),
420
                                   branch_token+'xxx', repo_token)
421
        self.assertEqual(
422
            SmartServerResponse(('TokenMismatch',)), response)
423
424
    def test_lock_write_on_locked_repo(self):
425
        backing = self.get_transport()
426
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
427
        branch = self.make_branch('.')
428
        branch.repository.lock_write()
429
        branch.repository.leave_lock_in_place()
430
        branch.repository.unlock()
431
        response = request.execute(backing.local_abspath(''))
432
        self.assertEqual(
433
            SmartServerResponse(('LockContention',)), response)
434
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
435
    def test_lock_write_on_readonly_transport(self):
436
        backing = self.get_readonly_transport()
437
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
438
        branch = self.make_branch('.')
439
        response = request.execute('')
440
        self.assertEqual(
441
            SmartServerResponse(('UnlockableTransport',)), response)
442
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
443
444
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithTransport):
445
446
    def setUp(self):
447
        tests.TestCaseWithTransport.setUp(self)
448
        self.reduceLockdirTimeout()
449
450
    def test_unlock_on_locked_branch_and_repo(self):
451
        backing = self.get_transport()
452
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
453
        branch = self.make_branch('.')
454
        # Lock the branch
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
455
        branch_token = branch.lock_write()
456
        repo_token = branch.repository.lock_write()
457
        branch.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
458
        # Unlock the branch (and repo) object, leaving the physical locks
459
        # in place.
460
        branch.leave_lock_in_place()
461
        branch.repository.leave_lock_in_place()
462
        branch.unlock()
463
        response = request.execute(backing.local_abspath(''),
464
                                   branch_token, repo_token)
465
        self.assertEqual(
466
            SmartServerResponse(('ok',)), response)
467
        # The branch is now unlocked.  Verify that with a new branch
468
        # object.
469
        new_branch = branch.bzrdir.open_branch()
470
        new_branch.lock_write()
471
        new_branch.unlock()
472
473
    def test_unlock_on_unlocked_branch_unlocked_repo(self):
474
        backing = self.get_transport()
475
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
476
        branch = self.make_branch('.')
477
        response = request.execute(
478
            backing.local_abspath(''), 'branch token', 'repo token')
479
        self.assertEqual(
480
            SmartServerResponse(('TokenMismatch',)), response)
481
482
    def test_unlock_on_unlocked_branch_locked_repo(self):
483
        backing = self.get_transport()
484
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
485
        branch = self.make_branch('.')
486
        # Lock the repository.
487
        repo_token = branch.repository.lock_write()
488
        branch.repository.leave_lock_in_place()
489
        branch.repository.unlock()
490
        # Issue branch lock_write request on the unlocked branch (with locked
491
        # repo).
492
        response = request.execute(
493
            backing.local_abspath(''), 'branch token', repo_token)
494
        self.assertEqual(
495
            SmartServerResponse(('TokenMismatch',)), response)
496
497
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
498
class TestSmartServerRepositoryRequest(tests.TestCaseWithTransport):
499
500
    def test_no_repository(self):
501
        """Raise NoRepositoryPresent when there is a bzrdir and no repo."""
502
        # we test this using a shared repository above the named path,
503
        # thus checking the right search logic is used - that is, that
504
        # its the exact path being looked at and the server is not
505
        # searching.
506
        backing = self.get_transport()
2018.5.58 by Wouter van Heyst
Small test fixes to reflect naming and documentation
507
        request = smart.repository.SmartServerRepositoryRequest(backing)
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
508
        self.make_repository('.', shared=True)
509
        self.make_bzrdir('subdir')
510
        self.assertRaises(errors.NoRepositoryPresent,
2018.5.58 by Wouter van Heyst
Small test fixes to reflect naming and documentation
511
            request.execute, backing.local_abspath('subdir'))
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
512
513
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
514
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithTransport):
515
516
    def test_none_argument(self):
517
        backing = self.get_transport()
518
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
519
        tree = self.make_branch_and_memory_tree('.')
520
        tree.lock_write()
521
        tree.add('')
522
        r1 = tree.commit('1st commit')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
523
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
524
        tree.unlock()
525
526
        # the lines of revision_id->revision_parent_list has no guaranteed
527
        # order coming out of a dict, so sort both our test and response
528
        lines = sorted([' '.join([r2, r1]), r1])
529
        response = request.execute(backing.local_abspath(''), '')
530
        response.body = '\n'.join(sorted(response.body.split('\n')))
531
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
532
        self.assertEqual(
533
            SmartServerResponse(('ok', ), '\n'.join(lines)), response)
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
534
535
    def test_specific_revision_argument(self):
536
        backing = self.get_transport()
537
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
538
        tree = self.make_branch_and_memory_tree('.')
539
        tree.lock_write()
540
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
541
        rev_id_utf8 = u'\xc9'.encode('utf-8')
542
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
543
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
544
        tree.unlock()
545
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
546
        self.assertEqual(SmartServerResponse(('ok', ), rev_id_utf8),
547
            request.execute(backing.local_abspath(''), rev_id_utf8))
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
548
    
549
    def test_no_such_revision(self):
550
        backing = self.get_transport()
551
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
552
        tree = self.make_branch_and_memory_tree('.')
553
        tree.lock_write()
554
        tree.add('')
555
        r1 = tree.commit('1st commit')
556
        tree.unlock()
557
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
558
        # Note that it still returns body (of zero bytes).
559
        self.assertEqual(
560
            SmartServerResponse(('nosuchrevision', 'missingrevision', ), ''),
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
561
            request.execute(backing.local_abspath(''), 'missingrevision'))
562
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
563
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
564
class TestSmartServerRequestHasRevision(tests.TestCaseWithTransport):
565
566
    def test_missing_revision(self):
567
        """For a missing revision, ('no', ) is returned."""
568
        backing = self.get_transport()
569
        request = smart.repository.SmartServerRequestHasRevision(backing)
570
        self.make_repository('.')
571
        self.assertEqual(SmartServerResponse(('no', )),
572
            request.execute(backing.local_abspath(''), 'revid'))
573
574
    def test_present_revision(self):
2018.5.158 by Andrew Bennetts
Return 'yes'/'no' rather than 'ok'/'no' from the Repository.has_revision smart command.
575
        """For a present revision, ('yes', ) is returned."""
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
576
        backing = self.get_transport()
577
        request = smart.repository.SmartServerRequestHasRevision(backing)
578
        tree = self.make_branch_and_memory_tree('.')
579
        tree.lock_write()
580
        tree.add('')
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
581
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
582
        r1 = tree.commit('a commit', rev_id=rev_id_utf8)
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
583
        tree.unlock()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
584
        self.assertTrue(tree.branch.repository.has_revision(rev_id_utf8))
2018.5.158 by Andrew Bennetts
Return 'yes'/'no' rather than 'ok'/'no' from the Repository.has_revision smart command.
585
        self.assertEqual(SmartServerResponse(('yes', )),
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
586
            request.execute(backing.local_abspath(''), rev_id_utf8))
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
587
588
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
589
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithTransport):
590
591
    def test_empty_revid(self):
592
        """With an empty revid, we get only size an number and revisions"""
593
        backing = self.get_transport()
594
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
595
        repository = self.make_repository('.')
596
        stats = repository.gather_stats()
597
        size = stats['size']
598
        expected_body = 'revisions: 0\nsize: %d\n' % size
599
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
600
                         request.execute(backing.local_abspath(''), '', 'no'))
601
602
    def test_revid_with_committers(self):
603
        """For a revid we get more infos."""
604
        backing = self.get_transport()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
605
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
606
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
607
        tree = self.make_branch_and_memory_tree('.')
608
        tree.lock_write()
609
        tree.add('')
610
        # Let's build a predictable result
611
        tree.commit('a commit', timestamp=123456.2, timezone=3600)
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
612
        tree.commit('a commit', timestamp=654321.4, timezone=0,
613
                    rev_id=rev_id_utf8)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
614
        tree.unlock()
615
616
        stats = tree.branch.repository.gather_stats()
617
        size = stats['size']
618
        expected_body = ('firstrev: 123456.200 3600\n'
619
                         'latestrev: 654321.400 0\n'
620
                         'revisions: 2\n'
621
                         'size: %d\n' % size)
622
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
623
                         request.execute(backing.local_abspath(''),
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
624
                                         rev_id_utf8, 'no'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
625
626
    def test_not_empty_repository_with_committers(self):
627
        """For a revid and requesting committers we get the whole thing."""
628
        backing = self.get_transport()
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
629
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
630
        request = smart.repository.SmartServerRepositoryGatherStats(backing)
631
        tree = self.make_branch_and_memory_tree('.')
632
        tree.lock_write()
633
        tree.add('')
634
        # Let's build a predictable result
635
        tree.commit('a commit', timestamp=123456.2, timezone=3600,
636
                    committer='foo')
637
        tree.commit('a commit', timestamp=654321.4, timezone=0,
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
638
                    committer='bar', rev_id=rev_id_utf8)
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
639
        tree.unlock()
640
        stats = tree.branch.repository.gather_stats()
641
642
        size = stats['size']
643
        expected_body = ('committers: 2\n'
644
                         'firstrev: 123456.200 3600\n'
645
                         'latestrev: 654321.400 0\n'
646
                         'revisions: 2\n'
647
                         'size: %d\n' % size)
648
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
649
                         request.execute(backing.local_abspath(''),
2018.5.148 by Andrew Bennetts
Fix all the DeprecationWarnings in test_smart caused by unicode revision IDs.
650
                                         rev_id_utf8, 'yes'))
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
651
652
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
653
class TestSmartServerRepositoryIsShared(tests.TestCaseWithTransport):
654
655
    def test_is_shared(self):
656
        """For a shared repository, ('yes', ) is returned."""
657
        backing = self.get_transport()
658
        request = smart.repository.SmartServerRepositoryIsShared(backing)
659
        self.make_repository('.', shared=True)
660
        self.assertEqual(SmartServerResponse(('yes', )),
661
            request.execute(backing.local_abspath(''), ))
662
663
    def test_is_not_shared(self):
2018.5.58 by Wouter van Heyst
Small test fixes to reflect naming and documentation
664
        """For a shared repository, ('no', ) is returned."""
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
665
        backing = self.get_transport()
666
        request = smart.repository.SmartServerRepositoryIsShared(backing)
667
        self.make_repository('.', shared=False)
668
        self.assertEqual(SmartServerResponse(('no', )),
669
            request.execute(backing.local_abspath(''), ))
670
2018.5.56 by Robert Collins
Factor out code we expect to be common in SmartServerRequestHasRevision to SmartServerRepositoryRequest (Robert Collins, Vincent Ladeuil).
671
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
672
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithTransport):
673
674
    def setUp(self):
675
        tests.TestCaseWithTransport.setUp(self)
676
        self.reduceLockdirTimeout()
677
678
    def test_lock_write_on_unlocked_repo(self):
679
        backing = self.get_transport()
680
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
681
        repository = self.make_repository('.')
682
        response = request.execute(backing.local_abspath(''))
683
        nonce = repository.control_files._lock.peek().get('nonce')
684
        self.assertEqual(SmartServerResponse(('ok', nonce)), response)
685
        # The repository is now locked.  Verify that with a new repository
686
        # object.
687
        new_repo = repository.bzrdir.open_repository()
688
        self.assertRaises(errors.LockContention, new_repo.lock_write)
689
690
    def test_lock_write_on_locked_repo(self):
691
        backing = self.get_transport()
692
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
693
        repository = self.make_repository('.')
694
        repository.lock_write()
695
        repository.leave_lock_in_place()
696
        repository.unlock()
697
        response = request.execute(backing.local_abspath(''))
698
        self.assertEqual(
699
            SmartServerResponse(('LockContention',)), response)
700
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
701
    def test_lock_write_on_readonly_transport(self):
702
        backing = self.get_readonly_transport()
703
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
704
        repository = self.make_repository('.')
705
        response = request.execute('')
706
        self.assertEqual(
707
            SmartServerResponse(('UnlockableTransport',)), response)
708
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
709
710
class TestSmartServerRepositoryUnlock(tests.TestCaseWithTransport):
711
712
    def setUp(self):
713
        tests.TestCaseWithTransport.setUp(self)
714
        self.reduceLockdirTimeout()
715
716
    def test_unlock_on_locked_repo(self):
717
        backing = self.get_transport()
718
        request = smart.repository.SmartServerRepositoryUnlock(backing)
719
        repository = self.make_repository('.')
720
        token = repository.lock_write()
721
        repository.leave_lock_in_place()
722
        repository.unlock()
723
        response = request.execute(backing.local_abspath(''), token)
724
        self.assertEqual(
725
            SmartServerResponse(('ok',)), response)
726
        # The repository is now unlocked.  Verify that with a new repository
727
        # object.
728
        new_repo = repository.bzrdir.open_repository()
729
        new_repo.lock_write()
730
        new_repo.unlock()
731
732
    def test_unlock_on_unlocked_repo(self):
733
        backing = self.get_transport()
734
        request = smart.repository.SmartServerRepositoryUnlock(backing)
735
        repository = self.make_repository('.')
736
        response = request.execute(backing.local_abspath(''), 'some token')
737
        self.assertEqual(
738
            SmartServerResponse(('TokenMismatch',)), response)
739
740
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
741
class TestSmartServerIsReadonly(tests.TestCaseWithTransport):
742
743
    def test_is_readonly_no(self):
744
        backing = self.get_transport()
745
        request = smart.request.SmartServerIsReadonly(backing)
746
        response = request.execute()
747
        self.assertEqual(
748
            SmartServerResponse(('no',)), response)
749
750
    def test_is_readonly_yes(self):
751
        backing = self.get_readonly_transport()
752
        request = smart.request.SmartServerIsReadonly(backing)
753
        response = request.execute()
754
        self.assertEqual(
755
            SmartServerResponse(('yes',)), response)
756
757
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
758
class TestHandlers(tests.TestCase):
759
    """Tests for the request.request_handlers object."""
760
761
    def test_registered_methods(self):
762
        """Test that known methods are registered to the correct object."""
763
        self.assertEqual(
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
764
            smart.request.request_handlers.get('Branch.get_config_file'),
765
            smart.branch.SmartServerBranchGetConfigFile)
766
        self.assertEqual(
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
767
            smart.request.request_handlers.get('Branch.lock_write'),
768
            smart.branch.SmartServerBranchRequestLockWrite)
769
        self.assertEqual(
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
770
            smart.request.request_handlers.get('Branch.last_revision_info'),
771
            smart.branch.SmartServerBranchRequestLastRevisionInfo)
772
        self.assertEqual(
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
773
            smart.request.request_handlers.get('Branch.revision_history'),
774
            smart.branch.SmartServerRequestRevisionHistory)
775
        self.assertEqual(
2018.5.77 by Wouter van Heyst
Fix typo in request_handlers registration of Branch.set_last_revision, and test that registration
776
            smart.request.request_handlers.get('Branch.set_last_revision'),
777
            smart.branch.SmartServerBranchRequestSetLastRevision)
778
        self.assertEqual(
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
779
            smart.request.request_handlers.get('Branch.unlock'),
780
            smart.branch.SmartServerBranchRequestUnlock)
781
        self.assertEqual(
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
782
            smart.request.request_handlers.get('BzrDir.find_repository'),
783
            smart.bzrdir.SmartServerRequestFindRepository)
784
        self.assertEqual(
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
785
            smart.request.request_handlers.get('BzrDirFormat.initialize'),
786
            smart.bzrdir.SmartServerRequestInitializeBzrDir)
787
        self.assertEqual(
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
788
            smart.request.request_handlers.get('BzrDir.open_branch'),
789
            smart.bzrdir.SmartServerRequestOpenBranch)
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
790
        self.assertEqual(
2018.10.2 by v.ladeuil+lp at free
gather_stats server side and request registration
791
            smart.request.request_handlers.get('Repository.gather_stats'),
792
            smart.repository.SmartServerRepositoryGatherStats)
793
        self.assertEqual(
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
794
            smart.request.request_handlers.get('Repository.get_revision_graph'),
795
            smart.repository.SmartServerRepositoryGetRevisionGraph)
796
        self.assertEqual(
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
797
            smart.request.request_handlers.get('Repository.has_revision'),
798
            smart.repository.SmartServerRequestHasRevision)
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
799
        self.assertEqual(
800
            smart.request.request_handlers.get('Repository.is_shared'),
801
            smart.repository.SmartServerRepositoryIsShared)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
802
        self.assertEqual(
803
            smart.request.request_handlers.get('Repository.lock_write'),
804
            smart.repository.SmartServerRepositoryLockWrite)
805
        self.assertEqual(
806
            smart.request.request_handlers.get('Repository.unlock'),
807
            smart.repository.SmartServerRepositoryUnlock)
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
808
        self.assertEqual(
809
            smart.request.request_handlers.get('Transport.is_readonly'),
810
            smart.request.SmartServerIsReadonly)