~lifeless/bzr/index.range_map

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

  • Committer: Robert Collins
  • Date: 2008-06-19 01:17:19 UTC
  • mfrom: (3218.1.277 +trunk)
  • Revision ID: robertc@robertcollins.net-20080619011719-1c4g4uxzzhdls2wf
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
"""
26
26
 
27
27
import bz2
28
 
from StringIO import StringIO
29
 
import tempfile
 
28
from cStringIO import StringIO
30
29
import tarfile
31
30
 
32
 
from bzrlib import bzrdir, errors, pack, smart, tests
 
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
33
43
from bzrlib.smart.request import (
34
44
    FailedSmartServerResponse,
 
45
    SmartServerRequest,
35
46
    SmartServerResponse,
36
47
    SuccessfulSmartServerResponse,
37
48
    )
38
 
import bzrlib.smart.bzrdir
39
 
import bzrlib.smart.branch
40
 
import bzrlib.smart.repository
 
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
41
55
from bzrlib.util import bencode
42
56
 
43
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
 
44
99
class TestCaseWithSmartMedium(tests.TestCaseWithTransport):
45
100
 
46
101
    def setUp(self):
49
104
        # the default or a parameterized class, but rather use the
50
105
        # TestCaseWithTransport infrastructure to set up a smart server and
51
106
        # transport.
52
 
        self.transport_server = smart.server.SmartTCPServer_for_testing
 
107
        self.transport_server = self.make_transport_server
 
108
 
 
109
    def make_transport_server(self):
 
110
        return smart.server.SmartTCPServer_for_testing('-' + self.id())
53
111
 
54
112
    def get_smart_medium(self):
55
113
        """Get a smart medium to use in tests."""
70
128
        self.assertNotEqual(None,
71
129
            SmartServerResponse(('ok', )))
72
130
 
73
 
 
74
 
class TestSmartServerRequestFindRepository(tests.TestCaseWithTransport):
 
131
    def test__str__(self):
 
132
        """SmartServerResponses can be stringified."""
 
133
        self.assertEqual(
 
134
            "<SmartServerResponse status=OK args=('args',) body='body'>",
 
135
            str(SuccessfulSmartServerResponse(('args',), 'body')))
 
136
        self.assertEqual(
 
137
            "<SmartServerResponse status=ERR args=('args',) body='body'>",
 
138
            str(FailedSmartServerResponse(('args',), 'body')))
 
139
 
 
140
 
 
141
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
 
142
 
 
143
    def test_translate_client_path(self):
 
144
        transport = self.get_transport()
 
145
        request = SmartServerRequest(transport, 'foo/')
 
146
        self.assertEqual('./', request.translate_client_path('foo/'))
 
147
        self.assertRaises(
 
148
            errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
 
149
        self.assertRaises(
 
150
            errors.PathNotChild, request.translate_client_path, '/')
 
151
        self.assertRaises(
 
152
            errors.PathNotChild, request.translate_client_path, 'bar/')
 
153
        self.assertEqual('./baz', request.translate_client_path('foo/baz'))
 
154
 
 
155
    def test_transport_from_client_path(self):
 
156
        transport = self.get_transport()
 
157
        request = SmartServerRequest(transport, 'foo/')
 
158
        self.assertEqual(
 
159
            transport.base,
 
160
            request.transport_from_client_path('foo/').base)
 
161
 
 
162
 
 
163
class TestSmartServerRequestFindRepository(tests.TestCaseWithMemoryTransport):
75
164
    """Tests for BzrDir.find_repository."""
76
165
 
77
166
    def test_no_repository(self):
78
167
        """When there is no repository to be found, ('norepository', ) is returned."""
79
168
        backing = self.get_transport()
80
 
        request = smart.bzrdir.SmartServerRequestFindRepository(backing)
 
169
        request = self._request_class(backing)
81
170
        self.make_bzrdir('.')
82
171
        self.assertEqual(SmartServerResponse(('norepository', )),
83
 
            request.execute(backing.local_abspath('')))
 
172
            request.execute(''))
84
173
 
85
174
    def test_nonshared_repository(self):
86
175
        # nonshared repositorys only allow 'find' to return a handle when the 
87
176
        # path the repository is being searched on is the same as that that 
88
177
        # the repository is at.
89
178
        backing = self.get_transport()
90
 
        request = smart.bzrdir.SmartServerRequestFindRepository(backing)
 
179
        request = self._request_class(backing)
91
180
        result = self._make_repository_and_result()
92
 
        self.assertEqual(result, request.execute(backing.local_abspath('')))
 
181
        self.assertEqual(result, request.execute(''))
93
182
        self.make_bzrdir('subdir')
94
183
        self.assertEqual(SmartServerResponse(('norepository', )),
95
 
            request.execute(backing.local_abspath('subdir')))
 
184
            request.execute('subdir'))
96
185
 
97
186
    def _make_repository_and_result(self, shared=False, format=None):
98
187
        """Convenience function to setup a repository.
108
197
            subtrees = 'yes'
109
198
        else:
110
199
            subtrees = 'no'
111
 
        return SmartServerResponse(('ok', '', rich_root, subtrees))
 
200
        if (smart.bzrdir.SmartServerRequestFindRepositoryV2 ==
 
201
            self._request_class):
 
202
            # All tests so far are on formats, and for non-external
 
203
            # repositories.
 
204
            return SuccessfulSmartServerResponse(
 
205
                ('ok', '', rich_root, subtrees, 'no'))
 
206
        else:
 
207
            return SuccessfulSmartServerResponse(('ok', '', rich_root, subtrees))
112
208
 
113
209
    def test_shared_repository(self):
114
210
        """When there is a shared repository, we get 'ok', 'relpath-to-repo'."""
115
211
        backing = self.get_transport()
116
 
        request = smart.bzrdir.SmartServerRequestFindRepository(backing)
 
212
        request = self._request_class(backing)
117
213
        result = self._make_repository_and_result(shared=True)
118
 
        self.assertEqual(result, request.execute(backing.local_abspath('')))
 
214
        self.assertEqual(result, request.execute(''))
119
215
        self.make_bzrdir('subdir')
120
216
        result2 = SmartServerResponse(result.args[0:1] + ('..', ) + result.args[2:])
121
217
        self.assertEqual(result2,
122
 
            request.execute(backing.local_abspath('subdir')))
 
218
            request.execute('subdir'))
123
219
        self.make_bzrdir('subdir/deeper')
124
220
        result3 = SmartServerResponse(result.args[0:1] + ('../..', ) + result.args[2:])
125
221
        self.assertEqual(result3,
126
 
            request.execute(backing.local_abspath('subdir/deeper')))
 
222
            request.execute('subdir/deeper'))
127
223
 
128
224
    def test_rich_root_and_subtree_encoding(self):
129
225
        """Test for the format attributes for rich root and subtree support."""
130
226
        backing = self.get_transport()
131
 
        request = smart.bzrdir.SmartServerRequestFindRepository(backing)
 
227
        request = self._request_class(backing)
132
228
        result = self._make_repository_and_result(format='dirstate-with-subtree')
133
229
        # check the test will be valid
134
230
        self.assertEqual('yes', result.args[2])
135
231
        self.assertEqual('yes', result.args[3])
136
 
        self.assertEqual(result, request.execute(backing.local_abspath('')))
137
 
 
138
 
 
139
 
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithTransport):
 
232
        self.assertEqual(result, request.execute(''))
 
233
 
 
234
    def test_supports_external_lookups_no_v2(self):
 
235
        """Test for the supports_external_lookups attribute."""
 
236
        backing = self.get_transport()
 
237
        request = self._request_class(backing)
 
238
        result = self._make_repository_and_result(format='dirstate-with-subtree')
 
239
        # check the test will be valid
 
240
        self.assertEqual('no', result.args[4])
 
241
        self.assertEqual(result, request.execute(''))
 
242
 
 
243
 
 
244
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
140
245
 
141
246
    def test_empty_dir(self):
142
247
        """Initializing an empty dir should succeed and do it."""
143
248
        backing = self.get_transport()
144
249
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
145
250
        self.assertEqual(SmartServerResponse(('ok', )),
146
 
            request.execute(backing.local_abspath('.')))
 
251
            request.execute(''))
147
252
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
148
253
        # no branch, tree or repository is expected with the current 
149
254
        # default formart.
156
261
        backing = self.get_transport()
157
262
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
158
263
        self.assertRaises(errors.NoSuchFile,
159
 
            request.execute, backing.local_abspath('subdir'))
 
264
            request.execute, 'subdir')
160
265
 
161
266
    def test_initialized_dir(self):
162
267
        """Initializing an extant bzrdir should fail like the bzrdir api."""
164
269
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
165
270
        self.make_bzrdir('subdir')
166
271
        self.assertRaises(errors.FileExists,
167
 
            request.execute, backing.local_abspath('subdir'))
168
 
 
169
 
 
170
 
class TestSmartServerRequestOpenBranch(tests.TestCaseWithTransport):
 
272
            request.execute, 'subdir')
 
273
 
 
274
 
 
275
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
171
276
 
172
277
    def test_no_branch(self):
173
278
        """When there is no branch, ('nobranch', ) is returned."""
175
280
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
176
281
        self.make_bzrdir('.')
177
282
        self.assertEqual(SmartServerResponse(('nobranch', )),
178
 
            request.execute(backing.local_abspath('')))
 
283
            request.execute(''))
179
284
 
180
285
    def test_branch(self):
181
286
        """When there is a branch, 'ok' is returned."""
183
288
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
184
289
        self.make_branch('.')
185
290
        self.assertEqual(SmartServerResponse(('ok', '')),
186
 
            request.execute(backing.local_abspath('')))
 
291
            request.execute(''))
187
292
 
188
293
    def test_branch_reference(self):
189
294
        """When there is a branch reference, the reference URL is returned."""
191
296
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
192
297
        branch = self.make_branch('branch')
193
298
        checkout = branch.create_checkout('reference',lightweight=True)
194
 
        # TODO: once we have an API to probe for references of any sort, we
195
 
        # can use it here.
196
 
        reference_url = backing.abspath('branch') + '/'
 
299
        reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
197
300
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
198
301
        self.assertEqual(SmartServerResponse(('ok', reference_url)),
199
 
            request.execute(backing.local_abspath('reference')))
200
 
 
201
 
 
202
 
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithTransport):
 
302
            request.execute('reference'))
 
303
 
 
304
 
 
305
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
203
306
 
204
307
    def test_empty(self):
205
308
        """For an empty branch, the body is empty."""
207
310
        request = smart.branch.SmartServerRequestRevisionHistory(backing)
208
311
        self.make_branch('.')
209
312
        self.assertEqual(SmartServerResponse(('ok', ), ''),
210
 
            request.execute(backing.local_abspath('')))
 
313
            request.execute(''))
211
314
 
212
315
    def test_not_empty(self):
213
316
        """For a non-empty branch, the body is empty."""
221
324
        tree.unlock()
222
325
        self.assertEqual(
223
326
            SmartServerResponse(('ok', ), ('\x00'.join([r1, r2]))),
224
 
            request.execute(backing.local_abspath('')))
225
 
 
226
 
 
227
 
class TestSmartServerBranchRequest(tests.TestCaseWithTransport):
 
327
            request.execute(''))
 
328
 
 
329
 
 
330
class TestSmartServerBranchRequest(tests.TestCaseWithMemoryTransport):
228
331
 
229
332
    def test_no_branch(self):
230
333
        """When there is a bzrdir and no branch, NotBranchError is raised."""
232
335
        request = smart.branch.SmartServerBranchRequest(backing)
233
336
        self.make_bzrdir('.')
234
337
        self.assertRaises(errors.NotBranchError,
235
 
            request.execute, backing.local_abspath(''))
 
338
            request.execute, '')
236
339
 
237
340
    def test_branch_reference(self):
238
341
        """When there is a branch reference, NotBranchError is raised."""
241
344
        branch = self.make_branch('branch')
242
345
        checkout = branch.create_checkout('reference',lightweight=True)
243
346
        self.assertRaises(errors.NotBranchError,
244
 
            request.execute, backing.local_abspath('checkout'))
245
 
 
246
 
 
247
 
class TestSmartServerBranchRequestLastRevisionInfo(tests.TestCaseWithTransport):
 
347
            request.execute, 'checkout')
 
348
 
 
349
 
 
350
class TestSmartServerBranchRequestLastRevisionInfo(tests.TestCaseWithMemoryTransport):
248
351
 
249
352
    def test_empty(self):
250
353
        """For an empty branch, the result is ('ok', '0', 'null:')."""
252
355
        request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
253
356
        self.make_branch('.')
254
357
        self.assertEqual(SmartServerResponse(('ok', '0', 'null:')),
255
 
            request.execute(backing.local_abspath('')))
 
358
            request.execute(''))
256
359
 
257
360
    def test_not_empty(self):
258
361
        """For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
267
370
        tree.unlock()
268
371
        self.assertEqual(
269
372
            SmartServerResponse(('ok', '2', rev_id_utf8)),
270
 
            request.execute(backing.local_abspath('')))
271
 
 
272
 
 
273
 
class TestSmartServerBranchRequestGetConfigFile(tests.TestCaseWithTransport):
 
373
            request.execute(''))
 
374
 
 
375
 
 
376
class TestSmartServerBranchRequestGetConfigFile(tests.TestCaseWithMemoryTransport):
274
377
 
275
378
    def test_default(self):
276
379
        """With no file, we get empty content."""
280
383
        # there should be no file by default
281
384
        content = ''
282
385
        self.assertEqual(SmartServerResponse(('ok', ), content),
283
 
            request.execute(backing.local_abspath('')))
 
386
            request.execute(''))
284
387
 
285
388
    def test_with_content(self):
286
389
        # SmartServerBranchGetConfigFile should return the content from
289
392
        backing = self.get_transport()
290
393
        request = smart.branch.SmartServerBranchGetConfigFile(backing)
291
394
        branch = self.make_branch('.')
292
 
        branch.control_files.put_utf8('branch.conf', 'foo bar baz')
 
395
        branch._transport.put_bytes('branch.conf', 'foo bar baz')
293
396
        self.assertEqual(SmartServerResponse(('ok', ), 'foo bar baz'),
294
 
            request.execute(backing.local_abspath('')))
295
 
 
296
 
 
297
 
class TestSmartServerBranchRequestSetLastRevision(tests.TestCaseWithTransport):
 
397
            request.execute(''))
 
398
 
 
399
 
 
400
class TestSmartServerBranchRequestSetLastRevision(tests.TestCaseWithMemoryTransport):
298
401
 
299
402
    def test_empty(self):
300
403
        backing = self.get_transport()
306
409
        try:
307
410
            self.assertEqual(SmartServerResponse(('ok',)),
308
411
                request.execute(
309
 
                    backing.local_abspath(''), branch_token, repo_token,
 
412
                    '', branch_token, repo_token,
310
413
                    'null:'))
311
414
        finally:
312
415
            b.unlock()
323
426
            self.assertEqual(
324
427
                SmartServerResponse(('NoSuchRevision', revision_id)),
325
428
                request.execute(
326
 
                    backing.local_abspath(''), branch_token, repo_token,
 
429
                    '', branch_token, repo_token,
327
430
                    revision_id))
328
431
        finally:
329
432
            b.unlock()
345
448
            self.assertEqual(
346
449
                SmartServerResponse(('ok',)),
347
450
                request.execute(
348
 
                    backing.local_abspath(''), branch_token, repo_token,
 
451
                    '', branch_token, repo_token,
349
452
                    rev_id_utf8))
350
453
            self.assertEqual([rev_id_utf8], tree.branch.revision_history())
351
454
        finally:
369
472
            self.assertEqual(
370
473
                SmartServerResponse(('ok',)),
371
474
                request.execute(
372
 
                    backing.local_abspath(''), branch_token, repo_token,
 
475
                    '', branch_token, repo_token,
373
476
                    rev_id_utf8))
374
477
            self.assertEqual([rev_id_utf8], tree.branch.revision_history())
375
478
        finally:
376
479
            tree.branch.unlock()
377
480
 
378
481
 
379
 
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithTransport):
 
482
class TestSmartServerBranchRequestSetLastRevisionInfo(tests.TestCaseWithTransport):
 
483
 
 
484
    def lock_branch(self, branch):
 
485
        branch_token = branch.lock_write()
 
486
        repo_token = branch.repository.lock_write()
 
487
        branch.repository.unlock()
 
488
        self.addCleanup(branch.unlock)
 
489
        return branch_token, repo_token
 
490
 
 
491
    def make_locked_branch(self, format=None):
 
492
        branch = self.make_branch('.', format=format)
 
493
        branch_token, repo_token = self.lock_branch(branch)
 
494
        return branch, branch_token, repo_token
 
495
 
 
496
    def test_empty(self):
 
497
        """An empty branch can have its last revision set to 'null:'."""
 
498
        b, branch_token, repo_token = self.make_locked_branch()
 
499
        backing = self.get_transport()
 
500
        request = smart.branch.SmartServerBranchRequestSetLastRevisionInfo(
 
501
            backing)
 
502
        response = request.execute('', branch_token, repo_token, '0', 'null:')
 
503
        self.assertEqual(SmartServerResponse(('ok',)), response)
 
504
 
 
505
    def assertBranchLastRevisionInfo(self, expected_info, branch_relpath):
 
506
        branch = bzrdir.BzrDir.open(branch_relpath).open_branch()
 
507
        self.assertEqual(expected_info, branch.last_revision_info())
 
508
 
 
509
    def test_branch_revision_info_is_updated(self):
 
510
        """This method really does update the branch last revision info."""
 
511
        tree = self.make_branch_and_memory_tree('.')
 
512
        tree.lock_write()
 
513
        tree.add('')
 
514
        tree.commit('First commit', rev_id='revision-1')
 
515
        tree.commit('Second commit', rev_id='revision-2')
 
516
        tree.unlock()
 
517
        branch = tree.branch
 
518
 
 
519
        branch_token, repo_token = self.lock_branch(branch)
 
520
        backing = self.get_transport()
 
521
        request = smart.branch.SmartServerBranchRequestSetLastRevisionInfo(
 
522
            backing)
 
523
        self.assertBranchLastRevisionInfo((2, 'revision-2'), '.')
 
524
        response = request.execute(
 
525
            '', branch_token, repo_token, '1', 'revision-1')
 
526
        self.assertEqual(SmartServerResponse(('ok',)), response)
 
527
        self.assertBranchLastRevisionInfo((1, 'revision-1'), '.')
 
528
 
 
529
    def test_not_present_revid(self):
 
530
        """Some branch formats will check that the revision is present in the
 
531
        repository.  When that check fails, a NoSuchRevision error is returned
 
532
        to the client.
 
533
        """
 
534
        # Make a knit format branch, because that format checks the values
 
535
        # given to set_last_revision_info.
 
536
        b, branch_token, repo_token = self.make_locked_branch(format='knit')
 
537
        backing = self.get_transport()
 
538
        request = smart.branch.SmartServerBranchRequestSetLastRevisionInfo(
 
539
            backing)
 
540
        response = request.execute(
 
541
            '', branch_token, repo_token, '1', 'not-present')
 
542
        self.assertEqual(
 
543
            SmartServerResponse(('NoSuchRevision', 'not-present')), response)
 
544
 
 
545
 
 
546
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
380
547
 
381
548
    def setUp(self):
382
 
        tests.TestCaseWithTransport.setUp(self)
383
 
        self.reduceLockdirTimeout()
 
549
        tests.TestCaseWithMemoryTransport.setUp(self)
384
550
 
385
551
    def test_lock_write_on_unlocked_branch(self):
386
552
        backing = self.get_transport()
387
553
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
388
554
        branch = self.make_branch('.', format='knit')
389
555
        repository = branch.repository
390
 
        response = request.execute(backing.local_abspath(''))
 
556
        response = request.execute('')
391
557
        branch_nonce = branch.control_files._lock.peek().get('nonce')
392
558
        repository_nonce = repository.control_files._lock.peek().get('nonce')
393
559
        self.assertEqual(
405
571
        branch.lock_write()
406
572
        branch.leave_lock_in_place()
407
573
        branch.unlock()
408
 
        response = request.execute(backing.local_abspath(''))
 
574
        response = request.execute('')
409
575
        self.assertEqual(
410
576
            SmartServerResponse(('LockContention',)), response)
411
577
 
419
585
        branch.leave_lock_in_place()
420
586
        branch.repository.leave_lock_in_place()
421
587
        branch.unlock()
422
 
        response = request.execute(backing.local_abspath(''),
 
588
        response = request.execute('',
423
589
                                   branch_token, repo_token)
424
590
        self.assertEqual(
425
591
            SmartServerResponse(('ok', branch_token, repo_token)), response)
434
600
        branch.leave_lock_in_place()
435
601
        branch.repository.leave_lock_in_place()
436
602
        branch.unlock()
437
 
        response = request.execute(backing.local_abspath(''),
 
603
        response = request.execute('',
438
604
                                   branch_token+'xxx', repo_token)
439
605
        self.assertEqual(
440
606
            SmartServerResponse(('TokenMismatch',)), response)
446
612
        branch.repository.lock_write()
447
613
        branch.repository.leave_lock_in_place()
448
614
        branch.repository.unlock()
449
 
        response = request.execute(backing.local_abspath(''))
 
615
        response = request.execute('')
450
616
        self.assertEqual(
451
617
            SmartServerResponse(('LockContention',)), response)
452
618
 
454
620
        backing = self.get_readonly_transport()
455
621
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
456
622
        branch = self.make_branch('.')
457
 
        response = request.execute('')
 
623
        root = self.get_transport().clone('/')
 
624
        path = urlutils.relative_url(root.base, self.get_transport().base)
 
625
        response = request.execute(path)
458
626
        error_name, lock_str, why_str = response.args
459
627
        self.assertFalse(response.is_successful())
460
628
        self.assertEqual('LockFailed', error_name)
461
629
 
462
630
 
463
 
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithTransport):
 
631
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
464
632
 
465
633
    def setUp(self):
466
 
        tests.TestCaseWithTransport.setUp(self)
467
 
        self.reduceLockdirTimeout()
 
634
        tests.TestCaseWithMemoryTransport.setUp(self)
468
635
 
469
636
    def test_unlock_on_locked_branch_and_repo(self):
470
637
        backing = self.get_transport()
479
646
        branch.leave_lock_in_place()
480
647
        branch.repository.leave_lock_in_place()
481
648
        branch.unlock()
482
 
        response = request.execute(backing.local_abspath(''),
 
649
        response = request.execute('',
483
650
                                   branch_token, repo_token)
484
651
        self.assertEqual(
485
652
            SmartServerResponse(('ok',)), response)
494
661
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
495
662
        branch = self.make_branch('.', format='knit')
496
663
        response = request.execute(
497
 
            backing.local_abspath(''), 'branch token', 'repo token')
 
664
            '', 'branch token', 'repo token')
498
665
        self.assertEqual(
499
666
            SmartServerResponse(('TokenMismatch',)), response)
500
667
 
509
676
        # Issue branch lock_write request on the unlocked branch (with locked
510
677
        # repo).
511
678
        response = request.execute(
512
 
            backing.local_abspath(''), 'branch token', repo_token)
 
679
            '', 'branch token', repo_token)
513
680
        self.assertEqual(
514
681
            SmartServerResponse(('TokenMismatch',)), response)
515
682
 
516
683
 
517
 
class TestSmartServerRepositoryRequest(tests.TestCaseWithTransport):
 
684
class TestSmartServerRepositoryRequest(tests.TestCaseWithMemoryTransport):
518
685
 
519
686
    def test_no_repository(self):
520
687
        """Raise NoRepositoryPresent when there is a bzrdir and no repo."""
527
694
        self.make_repository('.', shared=True)
528
695
        self.make_bzrdir('subdir')
529
696
        self.assertRaises(errors.NoRepositoryPresent,
530
 
            request.execute, backing.local_abspath('subdir'))
 
697
            request.execute, 'subdir')
531
698
 
532
699
 
533
700
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithTransport):
539
706
        tree = self.make_branch_and_memory_tree('.')
540
707
 
541
708
        self.assertEqual(None,
542
 
            request.execute(backing.local_abspath(''), 'missing-id'))
 
709
            request.execute('', 'missing-id'))
543
710
        # Note that it returns a body (of '' bzipped).
544
711
        self.assertEqual(
545
712
            SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
546
713
            request.do_body('\n\n0\n'))
547
714
 
548
715
 
549
 
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithTransport):
 
716
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithMemoryTransport):
550
717
 
551
718
    def test_none_argument(self):
552
719
        backing = self.get_transport()
561
728
        # the lines of revision_id->revision_parent_list has no guaranteed
562
729
        # order coming out of a dict, so sort both our test and response
563
730
        lines = sorted([' '.join([r2, r1]), r1])
564
 
        response = request.execute(backing.local_abspath(''), '')
 
731
        response = request.execute('', '')
565
732
        response.body = '\n'.join(sorted(response.body.split('\n')))
566
733
 
567
734
        self.assertEqual(
579
746
        tree.unlock()
580
747
 
581
748
        self.assertEqual(SmartServerResponse(('ok', ), rev_id_utf8),
582
 
            request.execute(backing.local_abspath(''), rev_id_utf8))
 
749
            request.execute('', rev_id_utf8))
583
750
    
584
751
    def test_no_such_revision(self):
585
752
        backing = self.get_transport()
593
760
        # Note that it still returns body (of zero bytes).
594
761
        self.assertEqual(
595
762
            SmartServerResponse(('nosuchrevision', 'missingrevision', ), ''),
596
 
            request.execute(backing.local_abspath(''), 'missingrevision'))
597
 
 
598
 
 
599
 
class TestSmartServerRequestHasRevision(tests.TestCaseWithTransport):
 
763
            request.execute('', 'missingrevision'))
 
764
 
 
765
 
 
766
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
600
767
 
601
768
    def test_missing_revision(self):
602
769
        """For a missing revision, ('no', ) is returned."""
604
771
        request = smart.repository.SmartServerRequestHasRevision(backing)
605
772
        self.make_repository('.')
606
773
        self.assertEqual(SmartServerResponse(('no', )),
607
 
            request.execute(backing.local_abspath(''), 'revid'))
 
774
            request.execute('', 'revid'))
608
775
 
609
776
    def test_present_revision(self):
610
777
        """For a present revision, ('yes', ) is returned."""
618
785
        tree.unlock()
619
786
        self.assertTrue(tree.branch.repository.has_revision(rev_id_utf8))
620
787
        self.assertEqual(SmartServerResponse(('yes', )),
621
 
            request.execute(backing.local_abspath(''), rev_id_utf8))
622
 
 
623
 
 
624
 
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithTransport):
 
788
            request.execute('', rev_id_utf8))
 
789
 
 
790
 
 
791
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
625
792
 
626
793
    def test_empty_revid(self):
627
794
        """With an empty revid, we get only size an number and revisions"""
632
799
        size = stats['size']
633
800
        expected_body = 'revisions: 0\nsize: %d\n' % size
634
801
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
635
 
                         request.execute(backing.local_abspath(''), '', 'no'))
 
802
                         request.execute('', '', 'no'))
636
803
 
637
804
    def test_revid_with_committers(self):
638
805
        """For a revid we get more infos."""
655
822
                         'revisions: 2\n'
656
823
                         'size: %d\n' % size)
657
824
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
658
 
                         request.execute(backing.local_abspath(''),
 
825
                         request.execute('',
659
826
                                         rev_id_utf8, 'no'))
660
827
 
661
828
    def test_not_empty_repository_with_committers(self):
681
848
                         'revisions: 2\n'
682
849
                         'size: %d\n' % size)
683
850
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
684
 
                         request.execute(backing.local_abspath(''),
 
851
                         request.execute('',
685
852
                                         rev_id_utf8, 'yes'))
686
853
 
687
854
 
688
 
class TestSmartServerRepositoryIsShared(tests.TestCaseWithTransport):
 
855
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
689
856
 
690
857
    def test_is_shared(self):
691
858
        """For a shared repository, ('yes', ) is returned."""
693
860
        request = smart.repository.SmartServerRepositoryIsShared(backing)
694
861
        self.make_repository('.', shared=True)
695
862
        self.assertEqual(SmartServerResponse(('yes', )),
696
 
            request.execute(backing.local_abspath(''), ))
 
863
            request.execute('', ))
697
864
 
698
865
    def test_is_not_shared(self):
699
866
        """For a shared repository, ('no', ) is returned."""
701
868
        request = smart.repository.SmartServerRepositoryIsShared(backing)
702
869
        self.make_repository('.', shared=False)
703
870
        self.assertEqual(SmartServerResponse(('no', )),
704
 
            request.execute(backing.local_abspath(''), ))
705
 
 
706
 
 
707
 
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithTransport):
 
871
            request.execute('', ))
 
872
 
 
873
 
 
874
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
708
875
 
709
876
    def setUp(self):
710
 
        tests.TestCaseWithTransport.setUp(self)
711
 
        self.reduceLockdirTimeout()
 
877
        tests.TestCaseWithMemoryTransport.setUp(self)
712
878
 
713
879
    def test_lock_write_on_unlocked_repo(self):
714
880
        backing = self.get_transport()
715
881
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
716
882
        repository = self.make_repository('.', format='knit')
717
 
        response = request.execute(backing.local_abspath(''))
 
883
        response = request.execute('')
718
884
        nonce = repository.control_files._lock.peek().get('nonce')
719
885
        self.assertEqual(SmartServerResponse(('ok', nonce)), response)
720
886
        # The repository is now locked.  Verify that with a new repository
729
895
        repository.lock_write()
730
896
        repository.leave_lock_in_place()
731
897
        repository.unlock()
732
 
        response = request.execute(backing.local_abspath(''))
 
898
        response = request.execute('')
733
899
        self.assertEqual(
734
900
            SmartServerResponse(('LockContention',)), response)
735
901
 
742
908
        self.assertEqual('LockFailed', response.args[0])
743
909
 
744
910
 
745
 
class TestSmartServerRepositoryUnlock(tests.TestCaseWithTransport):
 
911
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
746
912
 
747
913
    def setUp(self):
748
 
        tests.TestCaseWithTransport.setUp(self)
749
 
        self.reduceLockdirTimeout()
 
914
        tests.TestCaseWithMemoryTransport.setUp(self)
750
915
 
751
916
    def test_unlock_on_locked_repo(self):
752
917
        backing = self.get_transport()
755
920
        token = repository.lock_write()
756
921
        repository.leave_lock_in_place()
757
922
        repository.unlock()
758
 
        response = request.execute(backing.local_abspath(''), token)
 
923
        response = request.execute('', token)
759
924
        self.assertEqual(
760
925
            SmartServerResponse(('ok',)), response)
761
926
        # The repository is now unlocked.  Verify that with a new repository
768
933
        backing = self.get_transport()
769
934
        request = smart.repository.SmartServerRepositoryUnlock(backing)
770
935
        repository = self.make_repository('.', format='knit')
771
 
        response = request.execute(backing.local_abspath(''), 'some token')
 
936
        response = request.execute('', 'some token')
772
937
        self.assertEqual(
773
938
            SmartServerResponse(('TokenMismatch',)), response)
774
939
 
782
947
        # make some extraneous junk in the repository directory which should
783
948
        # not be copied
784
949
        self.build_tree(['.bzr/repository/extra-junk'])
785
 
        response = request.execute(backing.local_abspath(''), 'bz2')
 
950
        response = request.execute('', 'bz2')
786
951
        self.assertEqual(('ok',), response.args)
787
952
        # body should be a tbz2
788
953
        body_file = StringIO(response.body)
797
962
            "extraneous file present in tar file")
798
963
 
799
964
 
800
 
class TestSmartServerRepositoryStreamKnitData(tests.TestCaseWithTransport):
 
965
class TestSmartServerRepositoryStreamKnitData(tests.TestCaseWithMemoryTransport):
801
966
 
802
967
    def test_fetch_revisions(self):
803
968
        backing = self.get_transport()
811
976
        r1 = tree.commit('2nd commit', rev_id=rev_id2_utf8)
812
977
        tree.unlock()
813
978
 
814
 
        response = request.execute(backing.local_abspath(''), rev_id2_utf8)
 
979
        response = request.execute('', rev_id2_utf8)
815
980
        self.assertEqual(('ok',), response.args)
816
 
        from cStringIO import StringIO
817
981
        unpacker = pack.ContainerReader(StringIO(response.body))
818
982
        names = []
819
983
        for [name], read_bytes in unpacker.iter_records():
829
993
        request = smart.repository.SmartServerRepositoryStreamKnitDataForRevisions(backing)
830
994
        repo = self.make_repository('.')
831
995
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
832
 
        response = request.execute(backing.local_abspath(''), rev_id1_utf8)
 
996
        response = request.execute('', rev_id1_utf8)
833
997
        self.assertEqual(
834
998
            SmartServerResponse(('NoSuchRevision', rev_id1_utf8)),
835
999
            response)
836
1000
 
837
1001
 
838
 
class TestSmartServerRepositoryStreamRevisionsChunked(tests.TestCaseWithTransport):
 
1002
class TestSmartServerRepositoryStreamRevisionsChunked(tests.TestCaseWithMemoryTransport):
839
1003
 
840
1004
    def test_fetch_revisions(self):
841
1005
        backing = self.get_transport()
850
1014
        tree.commit('2nd commit', rev_id=rev_id2_utf8)
851
1015
        tree.unlock()
852
1016
 
853
 
        response = request.execute(backing.local_abspath(''))
 
1017
        response = request.execute('')
854
1018
        self.assertEqual(None, response)
855
1019
        response = request.do_body("%s\n%s\n1" % (rev_id2_utf8, rev_id1_utf8))
856
1020
        self.assertEqual(('ok',), response.args)
857
 
        from cStringIO import StringIO
858
1021
        parser = pack.ContainerPushParser()
859
1022
        names = []
860
1023
        for stream_bytes in response.body_stream:
872
1035
            backing)
873
1036
        repo = self.make_repository('.')
874
1037
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
875
 
        response = request.execute(backing.local_abspath(''))
 
1038
        response = request.execute('')
876
1039
        self.assertEqual(None, response)
877
1040
        response = request.do_body("%s\n\n1" % (rev_id1_utf8,))
878
1041
        self.assertEqual(
880
1043
            response)
881
1044
 
882
1045
 
883
 
class TestSmartServerIsReadonly(tests.TestCaseWithTransport):
 
1046
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
884
1047
 
885
1048
    def test_is_readonly_no(self):
886
1049
        backing = self.get_transport()
918
1081
            smart.request.request_handlers.get('Branch.set_last_revision'),
919
1082
            smart.branch.SmartServerBranchRequestSetLastRevision)
920
1083
        self.assertEqual(
 
1084
            smart.request.request_handlers.get('Branch.set_last_revision_info'),
 
1085
            smart.branch.SmartServerBranchRequestSetLastRevisionInfo)
 
1086
        self.assertEqual(
921
1087
            smart.request.request_handlers.get('Branch.unlock'),
922
1088
            smart.branch.SmartServerBranchRequestUnlock)
923
1089
        self.assertEqual(
924
1090
            smart.request.request_handlers.get('BzrDir.find_repository'),
925
 
            smart.bzrdir.SmartServerRequestFindRepository)
 
1091
            smart.bzrdir.SmartServerRequestFindRepositoryV1)
 
1092
        self.assertEqual(
 
1093
            smart.request.request_handlers.get('BzrDir.find_repositoryV2'),
 
1094
            smart.bzrdir.SmartServerRequestFindRepositoryV2)
926
1095
        self.assertEqual(
927
1096
            smart.request.request_handlers.get('BzrDirFormat.initialize'),
928
1097
            smart.bzrdir.SmartServerRequestInitializeBzrDir)