~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

Merge from 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
41
49
from bzrlib.tests import (
42
50
    iter_suite_tests,
43
51
    split_suite_by_re,
44
52
    TestScenarioApplier,
45
53
    )
 
54
from bzrlib.transport import chroot, get_transport
46
55
from bzrlib.util import bencode
47
56
 
48
57
 
69
78
    return result
70
79
 
71
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
 
72
99
class TestCaseWithSmartMedium(tests.TestCaseWithTransport):
73
100
 
74
101
    def setUp(self):
98
125
        self.assertNotEqual(None,
99
126
            SmartServerResponse(('ok', )))
100
127
 
101
 
 
102
 
class TestSmartServerRequestFindRepository(tests.TestCaseWithTransport):
 
128
    def test__str__(self):
 
129
        """SmartServerResponses can be stringified."""
 
130
        self.assertEqual(
 
131
            "<SmartServerResponse status=OK args=('args',) body='body'>",
 
132
            str(SuccessfulSmartServerResponse(('args',), 'body')))
 
133
        self.assertEqual(
 
134
            "<SmartServerResponse status=ERR args=('args',) body='body'>",
 
135
            str(FailedSmartServerResponse(('args',), 'body')))
 
136
 
 
137
 
 
138
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
 
139
 
 
140
    def test_translate_client_path(self):
 
141
        transport = self.get_transport()
 
142
        request = SmartServerRequest(transport, 'foo/')
 
143
        self.assertEqual('./', request.translate_client_path('foo/'))
 
144
        self.assertRaises(
 
145
            errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
 
146
        self.assertRaises(
 
147
            errors.PathNotChild, request.translate_client_path, '/')
 
148
        self.assertRaises(
 
149
            errors.PathNotChild, request.translate_client_path, 'bar/')
 
150
        self.assertEqual('./baz', request.translate_client_path('foo/baz'))
 
151
 
 
152
    def test_transport_from_client_path(self):
 
153
        transport = self.get_transport()
 
154
        request = SmartServerRequest(transport, 'foo/')
 
155
        self.assertEqual(
 
156
            transport.base,
 
157
            request.transport_from_client_path('foo/').base)
 
158
 
 
159
 
 
160
class TestSmartServerRequestFindRepository(tests.TestCaseWithMemoryTransport):
103
161
    """Tests for BzrDir.find_repository."""
104
162
 
105
163
    def test_no_repository(self):
108
166
        request = self._request_class(backing)
109
167
        self.make_bzrdir('.')
110
168
        self.assertEqual(SmartServerResponse(('norepository', )),
111
 
            request.execute(backing.local_abspath('')))
 
169
            request.execute(''))
112
170
 
113
171
    def test_nonshared_repository(self):
114
172
        # nonshared repositorys only allow 'find' to return a handle when the 
117
175
        backing = self.get_transport()
118
176
        request = self._request_class(backing)
119
177
        result = self._make_repository_and_result()
120
 
        self.assertEqual(result, request.execute(backing.local_abspath('')))
 
178
        self.assertEqual(result, request.execute(''))
121
179
        self.make_bzrdir('subdir')
122
180
        self.assertEqual(SmartServerResponse(('norepository', )),
123
 
            request.execute(backing.local_abspath('subdir')))
 
181
            request.execute('subdir'))
124
182
 
125
183
    def _make_repository_and_result(self, shared=False, format=None):
126
184
        """Convenience function to setup a repository.
150
208
        backing = self.get_transport()
151
209
        request = self._request_class(backing)
152
210
        result = self._make_repository_and_result(shared=True)
153
 
        self.assertEqual(result, request.execute(backing.local_abspath('')))
 
211
        self.assertEqual(result, request.execute(''))
154
212
        self.make_bzrdir('subdir')
155
213
        result2 = SmartServerResponse(result.args[0:1] + ('..', ) + result.args[2:])
156
214
        self.assertEqual(result2,
157
 
            request.execute(backing.local_abspath('subdir')))
 
215
            request.execute('subdir'))
158
216
        self.make_bzrdir('subdir/deeper')
159
217
        result3 = SmartServerResponse(result.args[0:1] + ('../..', ) + result.args[2:])
160
218
        self.assertEqual(result3,
161
 
            request.execute(backing.local_abspath('subdir/deeper')))
 
219
            request.execute('subdir/deeper'))
162
220
 
163
221
    def test_rich_root_and_subtree_encoding(self):
164
222
        """Test for the format attributes for rich root and subtree support."""
168
226
        # check the test will be valid
169
227
        self.assertEqual('yes', result.args[2])
170
228
        self.assertEqual('yes', result.args[3])
171
 
        self.assertEqual(result, request.execute(backing.local_abspath('')))
 
229
        self.assertEqual(result, request.execute(''))
172
230
 
173
231
    def test_supports_external_lookups_no_v2(self):
174
232
        """Test for the supports_external_lookups attribute."""
177
235
        result = self._make_repository_and_result(format='dirstate-with-subtree')
178
236
        # check the test will be valid
179
237
        self.assertEqual('no', result.args[4])
180
 
        self.assertEqual(result, request.execute(backing.local_abspath('')))
181
 
 
182
 
 
183
 
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithTransport):
 
238
        self.assertEqual(result, request.execute(''))
 
239
 
 
240
 
 
241
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
184
242
 
185
243
    def test_empty_dir(self):
186
244
        """Initializing an empty dir should succeed and do it."""
187
245
        backing = self.get_transport()
188
246
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
189
247
        self.assertEqual(SmartServerResponse(('ok', )),
190
 
            request.execute(backing.local_abspath('.')))
 
248
            request.execute(''))
191
249
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
192
250
        # no branch, tree or repository is expected with the current 
193
251
        # default formart.
200
258
        backing = self.get_transport()
201
259
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
202
260
        self.assertRaises(errors.NoSuchFile,
203
 
            request.execute, backing.local_abspath('subdir'))
 
261
            request.execute, 'subdir')
204
262
 
205
263
    def test_initialized_dir(self):
206
264
        """Initializing an extant bzrdir should fail like the bzrdir api."""
208
266
        request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
209
267
        self.make_bzrdir('subdir')
210
268
        self.assertRaises(errors.FileExists,
211
 
            request.execute, backing.local_abspath('subdir'))
212
 
 
213
 
 
214
 
class TestSmartServerRequestOpenBranch(tests.TestCaseWithTransport):
 
269
            request.execute, 'subdir')
 
270
 
 
271
 
 
272
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
215
273
 
216
274
    def test_no_branch(self):
217
275
        """When there is no branch, ('nobranch', ) is returned."""
219
277
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
220
278
        self.make_bzrdir('.')
221
279
        self.assertEqual(SmartServerResponse(('nobranch', )),
222
 
            request.execute(backing.local_abspath('')))
 
280
            request.execute(''))
223
281
 
224
282
    def test_branch(self):
225
283
        """When there is a branch, 'ok' is returned."""
227
285
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
228
286
        self.make_branch('.')
229
287
        self.assertEqual(SmartServerResponse(('ok', '')),
230
 
            request.execute(backing.local_abspath('')))
 
288
            request.execute(''))
231
289
 
232
290
    def test_branch_reference(self):
233
291
        """When there is a branch reference, the reference URL is returned."""
235
293
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
236
294
        branch = self.make_branch('branch')
237
295
        checkout = branch.create_checkout('reference',lightweight=True)
238
 
        # TODO: once we have an API to probe for references of any sort, we
239
 
        # can use it here.
240
 
        reference_url = backing.abspath('branch') + '/'
 
296
        reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
241
297
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
242
298
        self.assertEqual(SmartServerResponse(('ok', reference_url)),
243
 
            request.execute(backing.local_abspath('reference')))
244
 
 
245
 
 
246
 
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithTransport):
 
299
            request.execute('reference'))
 
300
 
 
301
 
 
302
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
247
303
 
248
304
    def test_empty(self):
249
305
        """For an empty branch, the body is empty."""
251
307
        request = smart.branch.SmartServerRequestRevisionHistory(backing)
252
308
        self.make_branch('.')
253
309
        self.assertEqual(SmartServerResponse(('ok', ), ''),
254
 
            request.execute(backing.local_abspath('')))
 
310
            request.execute(''))
255
311
 
256
312
    def test_not_empty(self):
257
313
        """For a non-empty branch, the body is empty."""
265
321
        tree.unlock()
266
322
        self.assertEqual(
267
323
            SmartServerResponse(('ok', ), ('\x00'.join([r1, r2]))),
268
 
            request.execute(backing.local_abspath('')))
269
 
 
270
 
 
271
 
class TestSmartServerBranchRequest(tests.TestCaseWithTransport):
 
324
            request.execute(''))
 
325
 
 
326
 
 
327
class TestSmartServerBranchRequest(tests.TestCaseWithMemoryTransport):
272
328
 
273
329
    def test_no_branch(self):
274
330
        """When there is a bzrdir and no branch, NotBranchError is raised."""
276
332
        request = smart.branch.SmartServerBranchRequest(backing)
277
333
        self.make_bzrdir('.')
278
334
        self.assertRaises(errors.NotBranchError,
279
 
            request.execute, backing.local_abspath(''))
 
335
            request.execute, '')
280
336
 
281
337
    def test_branch_reference(self):
282
338
        """When there is a branch reference, NotBranchError is raised."""
285
341
        branch = self.make_branch('branch')
286
342
        checkout = branch.create_checkout('reference',lightweight=True)
287
343
        self.assertRaises(errors.NotBranchError,
288
 
            request.execute, backing.local_abspath('checkout'))
289
 
 
290
 
 
291
 
class TestSmartServerBranchRequestLastRevisionInfo(tests.TestCaseWithTransport):
 
344
            request.execute, 'checkout')
 
345
 
 
346
 
 
347
class TestSmartServerBranchRequestLastRevisionInfo(tests.TestCaseWithMemoryTransport):
292
348
 
293
349
    def test_empty(self):
294
350
        """For an empty branch, the result is ('ok', '0', 'null:')."""
296
352
        request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
297
353
        self.make_branch('.')
298
354
        self.assertEqual(SmartServerResponse(('ok', '0', 'null:')),
299
 
            request.execute(backing.local_abspath('')))
 
355
            request.execute(''))
300
356
 
301
357
    def test_not_empty(self):
302
358
        """For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
311
367
        tree.unlock()
312
368
        self.assertEqual(
313
369
            SmartServerResponse(('ok', '2', rev_id_utf8)),
314
 
            request.execute(backing.local_abspath('')))
315
 
 
316
 
 
317
 
class TestSmartServerBranchRequestGetConfigFile(tests.TestCaseWithTransport):
 
370
            request.execute(''))
 
371
 
 
372
 
 
373
class TestSmartServerBranchRequestGetConfigFile(tests.TestCaseWithMemoryTransport):
318
374
 
319
375
    def test_default(self):
320
376
        """With no file, we get empty content."""
324
380
        # there should be no file by default
325
381
        content = ''
326
382
        self.assertEqual(SmartServerResponse(('ok', ), content),
327
 
            request.execute(backing.local_abspath('')))
 
383
            request.execute(''))
328
384
 
329
385
    def test_with_content(self):
330
386
        # SmartServerBranchGetConfigFile should return the content from
335
391
        branch = self.make_branch('.')
336
392
        branch.control_files.put_utf8('branch.conf', 'foo bar baz')
337
393
        self.assertEqual(SmartServerResponse(('ok', ), 'foo bar baz'),
338
 
            request.execute(backing.local_abspath('')))
339
 
 
340
 
 
341
 
class TestSmartServerBranchRequestSetLastRevision(tests.TestCaseWithTransport):
 
394
            request.execute(''))
 
395
 
 
396
 
 
397
class TestSmartServerBranchRequestSetLastRevision(tests.TestCaseWithMemoryTransport):
342
398
 
343
399
    def test_empty(self):
344
400
        backing = self.get_transport()
350
406
        try:
351
407
            self.assertEqual(SmartServerResponse(('ok',)),
352
408
                request.execute(
353
 
                    backing.local_abspath(''), branch_token, repo_token,
 
409
                    '', branch_token, repo_token,
354
410
                    'null:'))
355
411
        finally:
356
412
            b.unlock()
367
423
            self.assertEqual(
368
424
                SmartServerResponse(('NoSuchRevision', revision_id)),
369
425
                request.execute(
370
 
                    backing.local_abspath(''), branch_token, repo_token,
 
426
                    '', branch_token, repo_token,
371
427
                    revision_id))
372
428
        finally:
373
429
            b.unlock()
389
445
            self.assertEqual(
390
446
                SmartServerResponse(('ok',)),
391
447
                request.execute(
392
 
                    backing.local_abspath(''), branch_token, repo_token,
 
448
                    '', branch_token, repo_token,
393
449
                    rev_id_utf8))
394
450
            self.assertEqual([rev_id_utf8], tree.branch.revision_history())
395
451
        finally:
413
469
            self.assertEqual(
414
470
                SmartServerResponse(('ok',)),
415
471
                request.execute(
416
 
                    backing.local_abspath(''), branch_token, repo_token,
 
472
                    '', branch_token, repo_token,
417
473
                    rev_id_utf8))
418
474
            self.assertEqual([rev_id_utf8], tree.branch.revision_history())
419
475
        finally:
420
476
            tree.branch.unlock()
421
477
 
422
478
 
423
 
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithTransport):
 
479
class TestSmartServerBranchRequestSetLastRevisionInfo(tests.TestCaseWithTransport):
 
480
 
 
481
    def lock_branch(self, branch):
 
482
        branch_token = branch.lock_write()
 
483
        repo_token = branch.repository.lock_write()
 
484
        branch.repository.unlock()
 
485
        self.addCleanup(branch.unlock)
 
486
        return branch_token, repo_token
 
487
 
 
488
    def make_locked_branch(self, format=None):
 
489
        branch = self.make_branch('.', format=format)
 
490
        branch_token, repo_token = self.lock_branch(branch)
 
491
        return branch, branch_token, repo_token
 
492
 
 
493
    def test_empty(self):
 
494
        """An empty branch can have its last revision set to 'null:'."""
 
495
        b, branch_token, repo_token = self.make_locked_branch()
 
496
        backing = self.get_transport()
 
497
        request = smart.branch.SmartServerBranchRequestSetLastRevisionInfo(
 
498
            backing)
 
499
        response = request.execute('', branch_token, repo_token, '0', 'null:')
 
500
        self.assertEqual(SmartServerResponse(('ok',)), response)
 
501
 
 
502
    def assertBranchLastRevisionInfo(self, expected_info, branch_relpath):
 
503
        branch = bzrdir.BzrDir.open(branch_relpath).open_branch()
 
504
        self.assertEqual(expected_info, branch.last_revision_info())
 
505
 
 
506
    def test_branch_revision_info_is_updated(self):
 
507
        """This method really does update the branch last revision info."""
 
508
        tree = self.make_branch_and_memory_tree('.')
 
509
        tree.lock_write()
 
510
        tree.add('')
 
511
        tree.commit('First commit', rev_id='revision-1')
 
512
        tree.commit('Second commit', rev_id='revision-2')
 
513
        tree.unlock()
 
514
        branch = tree.branch
 
515
 
 
516
        branch_token, repo_token = self.lock_branch(branch)
 
517
        backing = self.get_transport()
 
518
        request = smart.branch.SmartServerBranchRequestSetLastRevisionInfo(
 
519
            backing)
 
520
        self.assertBranchLastRevisionInfo((2, 'revision-2'), '.')
 
521
        response = request.execute(
 
522
            '', branch_token, repo_token, '1', 'revision-1')
 
523
        self.assertEqual(SmartServerResponse(('ok',)), response)
 
524
        self.assertBranchLastRevisionInfo((1, 'revision-1'), '.')
 
525
 
 
526
    def test_not_present_revid(self):
 
527
        """Some branch formats will check that the revision is present in the
 
528
        repository.  When that check fails, a NoSuchRevision error is returned
 
529
        to the client.
 
530
        """
 
531
        # Make a knit format branch, because that format checks the values
 
532
        # given to set_last_revision_info.
 
533
        b, branch_token, repo_token = self.make_locked_branch(format='knit')
 
534
        backing = self.get_transport()
 
535
        request = smart.branch.SmartServerBranchRequestSetLastRevisionInfo(
 
536
            backing)
 
537
        response = request.execute(
 
538
            '', branch_token, repo_token, '1', 'not-present')
 
539
        self.assertEqual(
 
540
            SmartServerResponse(('NoSuchRevision', 'not-present')), response)
 
541
 
 
542
 
 
543
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
424
544
 
425
545
    def setUp(self):
426
 
        tests.TestCaseWithTransport.setUp(self)
 
546
        tests.TestCaseWithMemoryTransport.setUp(self)
427
547
 
428
548
    def test_lock_write_on_unlocked_branch(self):
429
549
        backing = self.get_transport()
430
550
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
431
551
        branch = self.make_branch('.', format='knit')
432
552
        repository = branch.repository
433
 
        response = request.execute(backing.local_abspath(''))
 
553
        response = request.execute('')
434
554
        branch_nonce = branch.control_files._lock.peek().get('nonce')
435
555
        repository_nonce = repository.control_files._lock.peek().get('nonce')
436
556
        self.assertEqual(
448
568
        branch.lock_write()
449
569
        branch.leave_lock_in_place()
450
570
        branch.unlock()
451
 
        response = request.execute(backing.local_abspath(''))
 
571
        response = request.execute('')
452
572
        self.assertEqual(
453
573
            SmartServerResponse(('LockContention',)), response)
454
574
 
462
582
        branch.leave_lock_in_place()
463
583
        branch.repository.leave_lock_in_place()
464
584
        branch.unlock()
465
 
        response = request.execute(backing.local_abspath(''),
 
585
        response = request.execute('',
466
586
                                   branch_token, repo_token)
467
587
        self.assertEqual(
468
588
            SmartServerResponse(('ok', branch_token, repo_token)), response)
477
597
        branch.leave_lock_in_place()
478
598
        branch.repository.leave_lock_in_place()
479
599
        branch.unlock()
480
 
        response = request.execute(backing.local_abspath(''),
 
600
        response = request.execute('',
481
601
                                   branch_token+'xxx', repo_token)
482
602
        self.assertEqual(
483
603
            SmartServerResponse(('TokenMismatch',)), response)
489
609
        branch.repository.lock_write()
490
610
        branch.repository.leave_lock_in_place()
491
611
        branch.repository.unlock()
492
 
        response = request.execute(backing.local_abspath(''))
 
612
        response = request.execute('')
493
613
        self.assertEqual(
494
614
            SmartServerResponse(('LockContention',)), response)
495
615
 
497
617
        backing = self.get_readonly_transport()
498
618
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
499
619
        branch = self.make_branch('.')
500
 
        response = request.execute('')
 
620
        root = self.get_transport().clone('/')
 
621
        path = urlutils.relative_url(root.base, self.get_transport().base)
 
622
        response = request.execute(path)
501
623
        error_name, lock_str, why_str = response.args
502
624
        self.assertFalse(response.is_successful())
503
625
        self.assertEqual('LockFailed', error_name)
504
626
 
505
627
 
506
 
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithTransport):
 
628
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
507
629
 
508
630
    def setUp(self):
509
 
        tests.TestCaseWithTransport.setUp(self)
 
631
        tests.TestCaseWithMemoryTransport.setUp(self)
510
632
 
511
633
    def test_unlock_on_locked_branch_and_repo(self):
512
634
        backing = self.get_transport()
521
643
        branch.leave_lock_in_place()
522
644
        branch.repository.leave_lock_in_place()
523
645
        branch.unlock()
524
 
        response = request.execute(backing.local_abspath(''),
 
646
        response = request.execute('',
525
647
                                   branch_token, repo_token)
526
648
        self.assertEqual(
527
649
            SmartServerResponse(('ok',)), response)
536
658
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
537
659
        branch = self.make_branch('.', format='knit')
538
660
        response = request.execute(
539
 
            backing.local_abspath(''), 'branch token', 'repo token')
 
661
            '', 'branch token', 'repo token')
540
662
        self.assertEqual(
541
663
            SmartServerResponse(('TokenMismatch',)), response)
542
664
 
551
673
        # Issue branch lock_write request on the unlocked branch (with locked
552
674
        # repo).
553
675
        response = request.execute(
554
 
            backing.local_abspath(''), 'branch token', repo_token)
 
676
            '', 'branch token', repo_token)
555
677
        self.assertEqual(
556
678
            SmartServerResponse(('TokenMismatch',)), response)
557
679
 
558
680
 
559
 
class TestSmartServerRepositoryRequest(tests.TestCaseWithTransport):
 
681
class TestSmartServerRepositoryRequest(tests.TestCaseWithMemoryTransport):
560
682
 
561
683
    def test_no_repository(self):
562
684
        """Raise NoRepositoryPresent when there is a bzrdir and no repo."""
569
691
        self.make_repository('.', shared=True)
570
692
        self.make_bzrdir('subdir')
571
693
        self.assertRaises(errors.NoRepositoryPresent,
572
 
            request.execute, backing.local_abspath('subdir'))
 
694
            request.execute, 'subdir')
573
695
 
574
696
 
575
697
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithTransport):
581
703
        tree = self.make_branch_and_memory_tree('.')
582
704
 
583
705
        self.assertEqual(None,
584
 
            request.execute(backing.local_abspath(''), 'missing-id'))
 
706
            request.execute('', 'missing-id'))
585
707
        # Note that it returns a body (of '' bzipped).
586
708
        self.assertEqual(
587
709
            SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
588
710
            request.do_body('\n\n0\n'))
589
711
 
590
712
 
591
 
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithTransport):
 
713
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithMemoryTransport):
592
714
 
593
715
    def test_none_argument(self):
594
716
        backing = self.get_transport()
603
725
        # the lines of revision_id->revision_parent_list has no guaranteed
604
726
        # order coming out of a dict, so sort both our test and response
605
727
        lines = sorted([' '.join([r2, r1]), r1])
606
 
        response = request.execute(backing.local_abspath(''), '')
 
728
        response = request.execute('', '')
607
729
        response.body = '\n'.join(sorted(response.body.split('\n')))
608
730
 
609
731
        self.assertEqual(
621
743
        tree.unlock()
622
744
 
623
745
        self.assertEqual(SmartServerResponse(('ok', ), rev_id_utf8),
624
 
            request.execute(backing.local_abspath(''), rev_id_utf8))
 
746
            request.execute('', rev_id_utf8))
625
747
    
626
748
    def test_no_such_revision(self):
627
749
        backing = self.get_transport()
635
757
        # Note that it still returns body (of zero bytes).
636
758
        self.assertEqual(
637
759
            SmartServerResponse(('nosuchrevision', 'missingrevision', ), ''),
638
 
            request.execute(backing.local_abspath(''), 'missingrevision'))
639
 
 
640
 
 
641
 
class TestSmartServerRequestHasRevision(tests.TestCaseWithTransport):
 
760
            request.execute('', 'missingrevision'))
 
761
 
 
762
 
 
763
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
642
764
 
643
765
    def test_missing_revision(self):
644
766
        """For a missing revision, ('no', ) is returned."""
646
768
        request = smart.repository.SmartServerRequestHasRevision(backing)
647
769
        self.make_repository('.')
648
770
        self.assertEqual(SmartServerResponse(('no', )),
649
 
            request.execute(backing.local_abspath(''), 'revid'))
 
771
            request.execute('', 'revid'))
650
772
 
651
773
    def test_present_revision(self):
652
774
        """For a present revision, ('yes', ) is returned."""
660
782
        tree.unlock()
661
783
        self.assertTrue(tree.branch.repository.has_revision(rev_id_utf8))
662
784
        self.assertEqual(SmartServerResponse(('yes', )),
663
 
            request.execute(backing.local_abspath(''), rev_id_utf8))
664
 
 
665
 
 
666
 
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithTransport):
 
785
            request.execute('', rev_id_utf8))
 
786
 
 
787
 
 
788
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
667
789
 
668
790
    def test_empty_revid(self):
669
791
        """With an empty revid, we get only size an number and revisions"""
674
796
        size = stats['size']
675
797
        expected_body = 'revisions: 0\nsize: %d\n' % size
676
798
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
677
 
                         request.execute(backing.local_abspath(''), '', 'no'))
 
799
                         request.execute('', '', 'no'))
678
800
 
679
801
    def test_revid_with_committers(self):
680
802
        """For a revid we get more infos."""
697
819
                         'revisions: 2\n'
698
820
                         'size: %d\n' % size)
699
821
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
700
 
                         request.execute(backing.local_abspath(''),
 
822
                         request.execute('',
701
823
                                         rev_id_utf8, 'no'))
702
824
 
703
825
    def test_not_empty_repository_with_committers(self):
723
845
                         'revisions: 2\n'
724
846
                         'size: %d\n' % size)
725
847
        self.assertEqual(SmartServerResponse(('ok', ), expected_body),
726
 
                         request.execute(backing.local_abspath(''),
 
848
                         request.execute('',
727
849
                                         rev_id_utf8, 'yes'))
728
850
 
729
851
 
730
 
class TestSmartServerRepositoryIsShared(tests.TestCaseWithTransport):
 
852
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
731
853
 
732
854
    def test_is_shared(self):
733
855
        """For a shared repository, ('yes', ) is returned."""
735
857
        request = smart.repository.SmartServerRepositoryIsShared(backing)
736
858
        self.make_repository('.', shared=True)
737
859
        self.assertEqual(SmartServerResponse(('yes', )),
738
 
            request.execute(backing.local_abspath(''), ))
 
860
            request.execute('', ))
739
861
 
740
862
    def test_is_not_shared(self):
741
863
        """For a shared repository, ('no', ) is returned."""
743
865
        request = smart.repository.SmartServerRepositoryIsShared(backing)
744
866
        self.make_repository('.', shared=False)
745
867
        self.assertEqual(SmartServerResponse(('no', )),
746
 
            request.execute(backing.local_abspath(''), ))
747
 
 
748
 
 
749
 
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithTransport):
 
868
            request.execute('', ))
 
869
 
 
870
 
 
871
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
750
872
 
751
873
    def setUp(self):
752
 
        tests.TestCaseWithTransport.setUp(self)
 
874
        tests.TestCaseWithMemoryTransport.setUp(self)
753
875
 
754
876
    def test_lock_write_on_unlocked_repo(self):
755
877
        backing = self.get_transport()
756
878
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
757
879
        repository = self.make_repository('.', format='knit')
758
 
        response = request.execute(backing.local_abspath(''))
 
880
        response = request.execute('')
759
881
        nonce = repository.control_files._lock.peek().get('nonce')
760
882
        self.assertEqual(SmartServerResponse(('ok', nonce)), response)
761
883
        # The repository is now locked.  Verify that with a new repository
770
892
        repository.lock_write()
771
893
        repository.leave_lock_in_place()
772
894
        repository.unlock()
773
 
        response = request.execute(backing.local_abspath(''))
 
895
        response = request.execute('')
774
896
        self.assertEqual(
775
897
            SmartServerResponse(('LockContention',)), response)
776
898
 
783
905
        self.assertEqual('LockFailed', response.args[0])
784
906
 
785
907
 
786
 
class TestSmartServerRepositoryUnlock(tests.TestCaseWithTransport):
 
908
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
787
909
 
788
910
    def setUp(self):
789
 
        tests.TestCaseWithTransport.setUp(self)
 
911
        tests.TestCaseWithMemoryTransport.setUp(self)
790
912
 
791
913
    def test_unlock_on_locked_repo(self):
792
914
        backing = self.get_transport()
795
917
        token = repository.lock_write()
796
918
        repository.leave_lock_in_place()
797
919
        repository.unlock()
798
 
        response = request.execute(backing.local_abspath(''), token)
 
920
        response = request.execute('', token)
799
921
        self.assertEqual(
800
922
            SmartServerResponse(('ok',)), response)
801
923
        # The repository is now unlocked.  Verify that with a new repository
808
930
        backing = self.get_transport()
809
931
        request = smart.repository.SmartServerRepositoryUnlock(backing)
810
932
        repository = self.make_repository('.', format='knit')
811
 
        response = request.execute(backing.local_abspath(''), 'some token')
 
933
        response = request.execute('', 'some token')
812
934
        self.assertEqual(
813
935
            SmartServerResponse(('TokenMismatch',)), response)
814
936
 
822
944
        # make some extraneous junk in the repository directory which should
823
945
        # not be copied
824
946
        self.build_tree(['.bzr/repository/extra-junk'])
825
 
        response = request.execute(backing.local_abspath(''), 'bz2')
 
947
        response = request.execute('', 'bz2')
826
948
        self.assertEqual(('ok',), response.args)
827
949
        # body should be a tbz2
828
950
        body_file = StringIO(response.body)
837
959
            "extraneous file present in tar file")
838
960
 
839
961
 
840
 
class TestSmartServerRepositoryStreamKnitData(tests.TestCaseWithTransport):
 
962
class TestSmartServerRepositoryStreamKnitData(tests.TestCaseWithMemoryTransport):
841
963
 
842
964
    def test_fetch_revisions(self):
843
965
        backing = self.get_transport()
851
973
        r1 = tree.commit('2nd commit', rev_id=rev_id2_utf8)
852
974
        tree.unlock()
853
975
 
854
 
        response = request.execute(backing.local_abspath(''), rev_id2_utf8)
 
976
        response = request.execute('', rev_id2_utf8)
855
977
        self.assertEqual(('ok',), response.args)
856
 
        from cStringIO import StringIO
857
978
        unpacker = pack.ContainerReader(StringIO(response.body))
858
979
        names = []
859
980
        for [name], read_bytes in unpacker.iter_records():
869
990
        request = smart.repository.SmartServerRepositoryStreamKnitDataForRevisions(backing)
870
991
        repo = self.make_repository('.')
871
992
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
872
 
        response = request.execute(backing.local_abspath(''), rev_id1_utf8)
 
993
        response = request.execute('', rev_id1_utf8)
873
994
        self.assertEqual(
874
995
            SmartServerResponse(('NoSuchRevision', rev_id1_utf8)),
875
996
            response)
876
997
 
877
998
 
878
 
class TestSmartServerRepositoryStreamRevisionsChunked(tests.TestCaseWithTransport):
 
999
class TestSmartServerRepositoryStreamRevisionsChunked(tests.TestCaseWithMemoryTransport):
879
1000
 
880
1001
    def test_fetch_revisions(self):
881
1002
        backing = self.get_transport()
890
1011
        tree.commit('2nd commit', rev_id=rev_id2_utf8)
891
1012
        tree.unlock()
892
1013
 
893
 
        response = request.execute(backing.local_abspath(''))
 
1014
        response = request.execute('')
894
1015
        self.assertEqual(None, response)
895
1016
        response = request.do_body("%s\n%s\n1" % (rev_id2_utf8, rev_id1_utf8))
896
1017
        self.assertEqual(('ok',), response.args)
897
 
        from cStringIO import StringIO
898
1018
        parser = pack.ContainerPushParser()
899
1019
        names = []
900
1020
        for stream_bytes in response.body_stream:
912
1032
            backing)
913
1033
        repo = self.make_repository('.')
914
1034
        rev_id1_utf8 = u'\xc8'.encode('utf-8')
915
 
        response = request.execute(backing.local_abspath(''))
 
1035
        response = request.execute('')
916
1036
        self.assertEqual(None, response)
917
1037
        response = request.do_body("%s\n\n1" % (rev_id1_utf8,))
918
1038
        self.assertEqual(
920
1040
            response)
921
1041
 
922
1042
 
923
 
class TestSmartServerIsReadonly(tests.TestCaseWithTransport):
 
1043
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
924
1044
 
925
1045
    def test_is_readonly_no(self):
926
1046
        backing = self.get_transport()
958
1078
            smart.request.request_handlers.get('Branch.set_last_revision'),
959
1079
            smart.branch.SmartServerBranchRequestSetLastRevision)
960
1080
        self.assertEqual(
 
1081
            smart.request.request_handlers.get('Branch.set_last_revision_info'),
 
1082
            smart.branch.SmartServerBranchRequestSetLastRevisionInfo)
 
1083
        self.assertEqual(
961
1084
            smart.request.request_handlers.get('Branch.unlock'),
962
1085
            smart.branch.SmartServerBranchRequestUnlock)
963
1086
        self.assertEqual(