~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

  • Committer: Mark Hammond
  • Date: 2009-01-12 01:55:34 UTC
  • mto: (3995.8.2 prepare-1.12)
  • mto: This revision was merged to the branch mainline in revision 4007.
  • Revision ID: mhammond@skippinet.com.au-20090112015534-yfxg50p7mpds9j4v
Include all .html files from the tortoise doc directory.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""Tests for the smart wire/domain protocol.
18
18
 
29
29
import tarfile
30
30
 
31
31
from bzrlib import (
32
 
    bencode,
33
32
    bzrdir,
34
33
    errors,
35
34
    pack,
36
35
    smart,
37
36
    tests,
38
37
    urlutils,
39
 
    versionedfile,
40
38
    )
41
39
from bzrlib.branch import Branch, BranchReferenceFormat
42
40
import bzrlib.smart.branch
43
 
import bzrlib.smart.bzrdir, bzrlib.smart.bzrdir as smart_dir
44
 
import bzrlib.smart.packrepository
 
41
import bzrlib.smart.bzrdir
45
42
import bzrlib.smart.repository
46
 
import bzrlib.smart.vfs
47
43
from bzrlib.smart.request import (
48
44
    FailedSmartServerResponse,
49
45
    SmartServerRequest,
51
47
    SuccessfulSmartServerResponse,
52
48
    )
53
49
from bzrlib.tests import (
 
50
    iter_suite_tests,
54
51
    split_suite_by_re,
 
52
    TestScenarioApplier,
55
53
    )
56
 
from bzrlib.transport import chroot, get_transport, local, memory
 
54
from bzrlib.transport import chroot, get_transport
 
55
from bzrlib.util import bencode
57
56
 
58
57
 
59
58
def load_tests(standard_tests, module, loader):
60
59
    """Multiply tests version and protocol consistency."""
61
60
    # FindRepository tests.
62
61
    bzrdir_mod = bzrlib.smart.bzrdir
63
 
    scenarios = [
 
62
    applier = TestScenarioApplier()
 
63
    applier.scenarios = [
64
64
        ("find_repository", {
65
65
            "_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV1}),
66
66
        ("find_repositoryV2", {
67
67
            "_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV2}),
68
 
        ("find_repositoryV3", {
69
 
            "_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV3}),
70
68
        ]
71
69
    to_adapt, result = split_suite_by_re(standard_tests,
72
70
        "TestSmartServerRequestFindRepository")
73
71
    v2_only, v1_and_2 = split_suite_by_re(to_adapt,
74
72
        "_v2")
75
 
    tests.multiply_tests(v1_and_2, scenarios, result)
76
 
    # The first scenario is only applicable to v1 protocols, it is deleted
77
 
    # since.
78
 
    tests.multiply_tests(v2_only, scenarios[1:], result)
 
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))
79
78
    return result
80
79
 
81
80
 
82
81
class TestCaseWithChrootedTransport(tests.TestCaseWithTransport):
83
82
 
84
83
    def setUp(self):
85
 
        self.vfs_transport_factory = memory.MemoryServer
86
84
        tests.TestCaseWithTransport.setUp(self)
87
85
        self._chroot_server = None
88
86
 
90
88
        if self._chroot_server is None:
91
89
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
92
90
            self._chroot_server = chroot.ChrootServer(backing_transport)
93
 
            self.start_server(self._chroot_server)
 
91
            self._chroot_server.setUp()
 
92
            self.addCleanup(self._chroot_server.tearDown)
94
93
        t = get_transport(self._chroot_server.get_url())
95
94
        if relpath is not None:
96
95
            t = t.clone(relpath)
97
96
        return t
98
97
 
99
98
 
100
 
class TestCaseWithSmartMedium(tests.TestCaseWithMemoryTransport):
 
99
class TestCaseWithSmartMedium(tests.TestCaseWithTransport):
101
100
 
102
101
    def setUp(self):
103
102
        super(TestCaseWithSmartMedium, self).setUp()
115
114
        return self.get_transport().get_smart_medium()
116
115
 
117
116
 
118
 
class TestByteStreamToStream(tests.TestCase):
119
 
 
120
 
    def test_repeated_substreams_same_kind_are_one_stream(self):
121
 
        # Make a stream - an iterable of bytestrings.
122
 
        stream = [('text', [versionedfile.FulltextContentFactory(('k1',), None,
123
 
            None, 'foo')]),('text', [
124
 
            versionedfile.FulltextContentFactory(('k2',), None, None, 'bar')])]
125
 
        fmt = bzrdir.format_registry.get('pack-0.92')().repository_format
126
 
        bytes = smart.repository._stream_to_byte_stream(stream, fmt)
127
 
        streams = []
128
 
        # Iterate the resulting iterable; checking that we get only one stream
129
 
        # out.
130
 
        fmt, stream = smart.repository._byte_stream_to_stream(bytes)
131
 
        for kind, substream in stream:
132
 
            streams.append((kind, list(substream)))
133
 
        self.assertLength(1, streams)
134
 
        self.assertLength(2, streams[0][1])
135
 
 
136
 
 
137
117
class TestSmartServerResponse(tests.TestCase):
138
118
 
139
119
    def test__eq__(self):
171
151
        self.assertRaises(
172
152
            errors.PathNotChild, request.translate_client_path, 'bar/')
173
153
        self.assertEqual('./baz', request.translate_client_path('foo/baz'))
174
 
        e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'.encode('utf-8')
175
 
        self.assertEqual('./' + urlutils.escape(e_acute),
176
 
                         request.translate_client_path('foo/' + e_acute))
177
 
 
178
 
    def test_translate_client_path_vfs(self):
179
 
        """VfsRequests receive escaped paths rather than raw UTF-8."""
180
 
        transport = self.get_transport()
181
 
        request = smart.vfs.VfsRequest(transport, 'foo/')
182
 
        e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'.encode('utf-8')
183
 
        escaped = urlutils.escape('foo/' + e_acute)
184
 
        self.assertEqual('./' + urlutils.escape(e_acute),
185
 
                         request.translate_client_path(escaped))
186
154
 
187
155
    def test_transport_from_client_path(self):
188
156
        transport = self.get_transport()
192
160
            request.transport_from_client_path('foo/').base)
193
161
 
194
162
 
195
 
class TestSmartServerBzrDirRequestCloningMetaDir(
196
 
    tests.TestCaseWithMemoryTransport):
197
 
    """Tests for BzrDir.cloning_metadir."""
198
 
 
199
 
    def test_cloning_metadir(self):
200
 
        """When there is a bzrdir present, the call succeeds."""
201
 
        backing = self.get_transport()
202
 
        dir = self.make_bzrdir('.')
203
 
        local_result = dir.cloning_metadir()
204
 
        request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
205
 
        request = request_class(backing)
206
 
        expected = SuccessfulSmartServerResponse(
207
 
            (local_result.network_name(),
208
 
            local_result.repository_format.network_name(),
209
 
            ('branch', local_result.get_branch_format().network_name())))
210
 
        self.assertEqual(expected, request.execute('', 'False'))
211
 
 
212
 
    def test_cloning_metadir_reference(self):
213
 
        """The request fails when bzrdir contains a branch reference."""
214
 
        backing = self.get_transport()
215
 
        referenced_branch = self.make_branch('referenced')
216
 
        dir = self.make_bzrdir('.')
217
 
        local_result = dir.cloning_metadir()
218
 
        reference = BranchReferenceFormat().initialize(dir, referenced_branch)
219
 
        reference_url = BranchReferenceFormat().get_reference(dir)
220
 
        # The server shouldn't try to follow the branch reference, so it's fine
221
 
        # if the referenced branch isn't reachable.
222
 
        backing.rename('referenced', 'moved')
223
 
        request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
224
 
        request = request_class(backing)
225
 
        expected = FailedSmartServerResponse(('BranchReference',))
226
 
        self.assertEqual(expected, request.execute('', 'False'))
227
 
 
228
 
 
229
 
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
230
 
    """Tests for BzrDir.create_repository."""
231
 
 
232
 
    def test_makes_repository(self):
233
 
        """When there is a bzrdir present, the call succeeds."""
234
 
        backing = self.get_transport()
235
 
        self.make_bzrdir('.')
236
 
        request_class = bzrlib.smart.bzrdir.SmartServerRequestCreateRepository
237
 
        request = request_class(backing)
238
 
        reference_bzrdir_format = bzrdir.format_registry.get('pack-0.92')()
239
 
        reference_format = reference_bzrdir_format.repository_format
240
 
        network_name = reference_format.network_name()
241
 
        expected = SuccessfulSmartServerResponse(
242
 
            ('ok', 'no', 'no', 'no', network_name))
243
 
        self.assertEqual(expected, request.execute('', network_name, 'True'))
244
 
 
245
 
 
246
163
class TestSmartServerRequestFindRepository(tests.TestCaseWithMemoryTransport):
247
164
    """Tests for BzrDir.find_repository."""
248
165
 
255
172
            request.execute(''))
256
173
 
257
174
    def test_nonshared_repository(self):
258
 
        # nonshared repositorys only allow 'find' to return a handle when the
259
 
        # path the repository is being searched on is the same as that that
 
175
        # nonshared repositorys only allow 'find' to return a handle when the 
 
176
        # path the repository is being searched on is the same as that that 
260
177
        # the repository is at.
261
178
        backing = self.get_transport()
262
179
        request = self._request_class(backing)
280
197
            subtrees = 'yes'
281
198
        else:
282
199
            subtrees = 'no'
283
 
        if repo._format.supports_external_lookups:
284
 
            external = 'yes'
285
 
        else:
286
 
            external = 'no'
287
 
        if (smart.bzrdir.SmartServerRequestFindRepositoryV3 ==
288
 
            self._request_class):
289
 
            return SuccessfulSmartServerResponse(
290
 
                ('ok', '', rich_root, subtrees, external,
291
 
                 repo._format.network_name()))
292
 
        elif (smart.bzrdir.SmartServerRequestFindRepositoryV2 ==
 
200
        if (smart.bzrdir.SmartServerRequestFindRepositoryV2 ==
293
201
            self._request_class):
294
202
            # All tests so far are on formats, and for non-external
295
203
            # repositories.
296
204
            return SuccessfulSmartServerResponse(
297
 
                ('ok', '', rich_root, subtrees, external))
 
205
                ('ok', '', rich_root, subtrees, 'no'))
298
206
        else:
299
207
            return SuccessfulSmartServerResponse(('ok', '', rich_root, subtrees))
300
208
 
333
241
        self.assertEqual(result, request.execute(''))
334
242
 
335
243
 
336
 
class TestSmartServerBzrDirRequestGetConfigFile(
337
 
    tests.TestCaseWithMemoryTransport):
338
 
    """Tests for BzrDir.get_config_file."""
339
 
 
340
 
    def test_present(self):
341
 
        backing = self.get_transport()
342
 
        dir = self.make_bzrdir('.')
343
 
        dir.get_config().set_default_stack_on("/")
344
 
        local_result = dir._get_config()._get_config_file().read()
345
 
        request_class = smart_dir.SmartServerBzrDirRequestConfigFile
346
 
        request = request_class(backing)
347
 
        expected = SuccessfulSmartServerResponse((), local_result)
348
 
        self.assertEqual(expected, request.execute(''))
349
 
 
350
 
    def test_missing(self):
351
 
        backing = self.get_transport()
352
 
        dir = self.make_bzrdir('.')
353
 
        request_class = smart_dir.SmartServerBzrDirRequestConfigFile
354
 
        request = request_class(backing)
355
 
        expected = SuccessfulSmartServerResponse((), '')
356
 
        self.assertEqual(expected, request.execute(''))
357
 
 
358
 
 
359
244
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
360
245
 
361
246
    def test_empty_dir(self):
365
250
        self.assertEqual(SmartServerResponse(('ok', )),
366
251
            request.execute(''))
367
252
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
368
 
        # no branch, tree or repository is expected with the current
 
253
        # no branch, tree or repository is expected with the current 
369
254
        # default formart.
370
255
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
371
256
        self.assertRaises(errors.NotBranchError, made_dir.open_branch)
387
272
            request.execute, 'subdir')
388
273
 
389
274
 
390
 
class TestSmartServerRequestBzrDirInitializeEx(tests.TestCaseWithMemoryTransport):
391
 
    """Basic tests for BzrDir.initialize_ex_1.16 in the smart server.
392
 
 
393
 
    The main unit tests in test_bzrdir exercise the API comprehensively.
394
 
    """
395
 
 
396
 
    def test_empty_dir(self):
397
 
        """Initializing an empty dir should succeed and do it."""
398
 
        backing = self.get_transport()
399
 
        name = self.make_bzrdir('reference')._format.network_name()
400
 
        request = smart.bzrdir.SmartServerRequestBzrDirInitializeEx(backing)
401
 
        self.assertEqual(SmartServerResponse(('', '', '', '', '', '', name,
402
 
            'False', '', '', '')),
403
 
            request.execute(name, '', 'True', 'False', 'False', '', '', '', '',
404
 
            'False'))
405
 
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
406
 
        # no branch, tree or repository is expected with the current
407
 
        # default format.
408
 
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
409
 
        self.assertRaises(errors.NotBranchError, made_dir.open_branch)
410
 
        self.assertRaises(errors.NoRepositoryPresent, made_dir.open_repository)
411
 
 
412
 
    def test_missing_dir(self):
413
 
        """Initializing a missing directory should fail like the bzrdir api."""
414
 
        backing = self.get_transport()
415
 
        name = self.make_bzrdir('reference')._format.network_name()
416
 
        request = smart.bzrdir.SmartServerRequestBzrDirInitializeEx(backing)
417
 
        self.assertRaises(errors.NoSuchFile, request.execute, name,
418
 
            'subdir/dir', 'False', 'False', 'False', '', '', '', '', 'False')
419
 
 
420
 
    def test_initialized_dir(self):
421
 
        """Initializing an extant directory should fail like the bzrdir api."""
422
 
        backing = self.get_transport()
423
 
        name = self.make_bzrdir('reference')._format.network_name()
424
 
        request = smart.bzrdir.SmartServerRequestBzrDirInitializeEx(backing)
425
 
        self.make_bzrdir('subdir')
426
 
        self.assertRaises(errors.FileExists, request.execute, name, 'subdir',
427
 
            'False', 'False', 'False', '', '', '', '', 'False')
428
 
 
429
 
 
430
 
class TestSmartServerRequestOpenBzrDir(tests.TestCaseWithMemoryTransport):
431
 
    
432
 
    def test_no_directory(self):
433
 
        backing = self.get_transport()
434
 
        request = smart.bzrdir.SmartServerRequestOpenBzrDir(backing)
435
 
        self.assertEqual(SmartServerResponse(('no', )),
436
 
            request.execute('does-not-exist'))
437
 
 
438
 
    def test_empty_directory(self):
439
 
        backing = self.get_transport()
440
 
        backing.mkdir('empty')
441
 
        request = smart.bzrdir.SmartServerRequestOpenBzrDir(backing)
442
 
        self.assertEqual(SmartServerResponse(('no', )),
443
 
            request.execute('empty'))
444
 
 
445
 
    def test_outside_root_client_path(self):
446
 
        backing = self.get_transport()
447
 
        request = smart.bzrdir.SmartServerRequestOpenBzrDir(backing,
448
 
            root_client_path='root')
449
 
        self.assertEqual(SmartServerResponse(('no', )),
450
 
            request.execute('not-root'))
451
 
 
452
 
    
453
 
class TestSmartServerRequestOpenBzrDir_2_1(tests.TestCaseWithMemoryTransport):
454
 
    
455
 
    def test_no_directory(self):
456
 
        backing = self.get_transport()
457
 
        request = smart.bzrdir.SmartServerRequestOpenBzrDir_2_1(backing)
458
 
        self.assertEqual(SmartServerResponse(('no', )),
459
 
            request.execute('does-not-exist'))
460
 
 
461
 
    def test_empty_directory(self):
462
 
        backing = self.get_transport()
463
 
        backing.mkdir('empty')
464
 
        request = smart.bzrdir.SmartServerRequestOpenBzrDir_2_1(backing)
465
 
        self.assertEqual(SmartServerResponse(('no', )),
466
 
            request.execute('empty'))
467
 
 
468
 
    def test_present_without_workingtree(self):
469
 
        backing = self.get_transport()
470
 
        request = smart.bzrdir.SmartServerRequestOpenBzrDir_2_1(backing)
471
 
        self.make_bzrdir('.')
472
 
        self.assertEqual(SmartServerResponse(('yes', 'no')),
473
 
            request.execute(''))
474
 
 
475
 
    def test_outside_root_client_path(self):
476
 
        backing = self.get_transport()
477
 
        request = smart.bzrdir.SmartServerRequestOpenBzrDir_2_1(backing,
478
 
            root_client_path='root')
479
 
        self.assertEqual(SmartServerResponse(('no',)),
480
 
            request.execute('not-root'))
481
 
 
482
 
    
483
 
class TestSmartServerRequestOpenBzrDir_2_1_disk(TestCaseWithChrootedTransport):
484
 
 
485
 
    def test_present_with_workingtree(self):
486
 
        self.vfs_transport_factory = local.LocalURLServer
487
 
        backing = self.get_transport()
488
 
        request = smart.bzrdir.SmartServerRequestOpenBzrDir_2_1(backing)
489
 
        bd = self.make_bzrdir('.')
490
 
        bd.create_repository()
491
 
        bd.create_branch()
492
 
        bd.create_workingtree()
493
 
        self.assertEqual(SmartServerResponse(('yes', 'yes')),
494
 
            request.execute(''))
495
 
 
496
 
 
497
275
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
498
276
 
499
277
    def test_no_branch(self):
514
292
 
515
293
    def test_branch_reference(self):
516
294
        """When there is a branch reference, the reference URL is returned."""
517
 
        self.vfs_transport_factory = local.LocalURLServer
518
295
        backing = self.get_transport()
519
296
        request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
520
297
        branch = self.make_branch('branch')
525
302
            request.execute('reference'))
526
303
 
527
304
 
528
 
class TestSmartServerRequestOpenBranchV2(TestCaseWithChrootedTransport):
529
 
 
530
 
    def test_no_branch(self):
531
 
        """When there is no branch, ('nobranch', ) is returned."""
532
 
        backing = self.get_transport()
533
 
        self.make_bzrdir('.')
534
 
        request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
535
 
        self.assertEqual(SmartServerResponse(('nobranch', )),
536
 
            request.execute(''))
537
 
 
538
 
    def test_branch(self):
539
 
        """When there is a branch, 'ok' is returned."""
540
 
        backing = self.get_transport()
541
 
        expected = self.make_branch('.')._format.network_name()
542
 
        request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
543
 
        self.assertEqual(SuccessfulSmartServerResponse(('branch', expected)),
544
 
            request.execute(''))
545
 
 
546
 
    def test_branch_reference(self):
547
 
        """When there is a branch reference, the reference URL is returned."""
548
 
        self.vfs_transport_factory = local.LocalURLServer
549
 
        backing = self.get_transport()
550
 
        request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
551
 
        branch = self.make_branch('branch')
552
 
        checkout = branch.create_checkout('reference',lightweight=True)
553
 
        reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
554
 
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
555
 
        self.assertEqual(SuccessfulSmartServerResponse(('ref', reference_url)),
556
 
            request.execute('reference'))
557
 
 
558
 
    def test_stacked_branch(self):
559
 
        """Opening a stacked branch does not open the stacked-on branch."""
560
 
        trunk = self.make_branch('trunk')
561
 
        feature = self.make_branch('feature')
562
 
        feature.set_stacked_on_url(trunk.base)
563
 
        opened_branches = []
564
 
        Branch.hooks.install_named_hook('open', opened_branches.append, None)
565
 
        backing = self.get_transport()
566
 
        request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
567
 
        request.setup_jail()
568
 
        try:
569
 
            response = request.execute('feature')
570
 
        finally:
571
 
            request.teardown_jail()
572
 
        expected_format = feature._format.network_name()
573
 
        self.assertEqual(
574
 
            SuccessfulSmartServerResponse(('branch', expected_format)),
575
 
            response)
576
 
        self.assertLength(1, opened_branches)
577
 
 
578
 
 
579
305
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
580
306
 
581
307
    def test_empty(self):
662
388
    def test_with_content(self):
663
389
        # SmartServerBranchGetConfigFile should return the content from
664
390
        # branch.control_files.get('branch.conf') for now - in the future it may
665
 
        # perform more complex processing.
 
391
        # perform more complex processing. 
666
392
        backing = self.get_transport()
667
393
        request = smart.branch.SmartServerBranchGetConfigFile(backing)
668
394
        branch = self.make_branch('.')
671
397
            request.execute(''))
672
398
 
673
399
 
674
 
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
675
 
 
676
 
    def get_lock_tokens(self, branch):
677
 
        branch_token = branch.lock_write()
678
 
        repo_token = branch.repository.lock_write()
679
 
        branch.repository.unlock()
680
 
        return branch_token, repo_token
681
 
 
682
 
 
683
 
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
684
 
 
685
 
    def test_value_name(self):
686
 
        branch = self.make_branch('.')
687
 
        request = smart.branch.SmartServerBranchRequestSetConfigOption(
688
 
            branch.bzrdir.root_transport)
689
 
        branch_token, repo_token = self.get_lock_tokens(branch)
690
 
        config = branch._get_config()
691
 
        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
692
 
            '')
693
 
        self.assertEqual(SuccessfulSmartServerResponse(()), result)
694
 
        self.assertEqual('bar', config.get_option('foo'))
695
 
        # Cleanup
696
 
        branch.unlock()
697
 
 
698
 
    def test_value_name_section(self):
699
 
        branch = self.make_branch('.')
700
 
        request = smart.branch.SmartServerBranchRequestSetConfigOption(
701
 
            branch.bzrdir.root_transport)
702
 
        branch_token, repo_token = self.get_lock_tokens(branch)
703
 
        config = branch._get_config()
704
 
        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
705
 
            'gam')
706
 
        self.assertEqual(SuccessfulSmartServerResponse(()), result)
707
 
        self.assertEqual('bar', config.get_option('foo', 'gam'))
708
 
        # Cleanup
709
 
        branch.unlock()
710
 
 
711
 
 
712
 
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
713
 
    # Only called when the branch format and tags match [yay factory
714
 
    # methods] so only need to test straight forward cases.
715
 
 
716
 
    def test_set_bytes(self):
717
 
        base_branch = self.make_branch('base')
718
 
        tag_bytes = base_branch._get_tags_bytes()
719
 
        # get_lock_tokens takes out a lock.
720
 
        branch_token, repo_token = self.get_lock_tokens(base_branch)
721
 
        request = smart.branch.SmartServerBranchSetTagsBytes(
722
 
            self.get_transport())
723
 
        response = request.execute('base', branch_token, repo_token)
724
 
        self.assertEqual(None, response)
725
 
        response = request.do_chunk(tag_bytes)
726
 
        self.assertEqual(None, response)
727
 
        response = request.do_end()
728
 
        self.assertEquals(
729
 
            SuccessfulSmartServerResponse(()), response)
730
 
        base_branch.unlock()
731
 
 
732
 
    def test_lock_failed(self):
733
 
        base_branch = self.make_branch('base')
734
 
        base_branch.lock_write()
735
 
        tag_bytes = base_branch._get_tags_bytes()
736
 
        request = smart.branch.SmartServerBranchSetTagsBytes(
737
 
            self.get_transport())
738
 
        self.assertRaises(errors.TokenMismatch, request.execute,
739
 
            'base', 'wrong token', 'wrong token')
740
 
        # The request handler will keep processing the message parts, so even
741
 
        # if the request fails immediately do_chunk and do_end are still
742
 
        # called.
743
 
        request.do_chunk(tag_bytes)
744
 
        request.do_end()
745
 
        base_branch.unlock()
746
 
 
747
 
 
748
 
 
749
 
class SetLastRevisionTestBase(TestLockedBranch):
 
400
class SetLastRevisionTestBase(tests.TestCaseWithMemoryTransport):
750
401
    """Base test case for verbs that implement set_last_revision."""
751
402
 
752
403
    def setUp(self):
756
407
        self.tree = self.make_branch_and_memory_tree('.')
757
408
 
758
409
    def lock_branch(self):
759
 
        return self.get_lock_tokens(self.tree.branch)
 
410
        b = self.tree.branch
 
411
        branch_token = b.lock_write()
 
412
        repo_token = b.repository.lock_write()
 
413
        b.repository.unlock()
 
414
        return branch_token, repo_token
760
415
 
761
416
    def unlock_branch(self):
762
417
        self.tree.branch.unlock()
763
 
 
 
418
        
764
419
    def set_last_revision(self, revision_id, revno):
765
420
        branch_token, repo_token = self.lock_branch()
766
421
        response = self._set_last_revision(
772
427
        response = self.set_last_revision(revision_id, revno)
773
428
        self.assertEqual(SuccessfulSmartServerResponse(('ok',)), response)
774
429
 
775
 
 
 
430
        
776
431
class TestSetLastRevisionVerbMixin(object):
777
432
    """Mixin test case for verbs that implement set_last_revision."""
778
433
 
883
538
        self.assertEqual(
884
539
            SuccessfulSmartServerResponse(('ok', revno, revision_id)),
885
540
            response)
886
 
 
 
541
        
887
542
    def test_branch_last_revision_info_rewind(self):
888
543
        """A branch's tip can be set to a revision that is an ancestor of the
889
544
        current tip, but only if allow_overwrite_descendant is passed.
932
587
        # child-1.
933
588
        new_r2 = self.tree.commit('2nd commit', rev_id='child-2')
934
589
        self.tree.unlock()
935
 
 
 
590
        
936
591
    def test_not_allow_diverged(self):
937
592
        """If allow_diverged is not passed, then setting a divergent history
938
593
        returns a Diverged error.
960
615
        self.assertEqual('child-1', self.tree.branch.last_revision())
961
616
 
962
617
 
963
 
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
964
 
 
965
 
    def test_get_parent_none(self):
966
 
        base_branch = self.make_branch('base')
967
 
        request = smart.branch.SmartServerBranchGetParent(self.get_transport())
968
 
        response = request.execute('base')
969
 
        self.assertEquals(
970
 
            SuccessfulSmartServerResponse(('',)), response)
971
 
 
972
 
    def test_get_parent_something(self):
973
 
        base_branch = self.make_branch('base')
974
 
        base_branch.set_parent(self.get_url('foo'))
975
 
        request = smart.branch.SmartServerBranchGetParent(self.get_transport())
976
 
        response = request.execute('base')
977
 
        self.assertEquals(
978
 
            SuccessfulSmartServerResponse(("../foo",)),
979
 
            response)
980
 
 
981
 
 
982
 
class TestSmartServerBranchRequestSetParent(tests.TestCaseWithMemoryTransport):
983
 
 
984
 
    def test_set_parent_none(self):
985
 
        branch = self.make_branch('base', format="1.9")
986
 
        branch.lock_write()
987
 
        branch._set_parent_location('foo')
988
 
        branch.unlock()
989
 
        request = smart.branch.SmartServerBranchRequestSetParentLocation(
990
 
            self.get_transport())
991
 
        branch_token = branch.lock_write()
992
 
        repo_token = branch.repository.lock_write()
993
 
        try:
994
 
            response = request.execute('base', branch_token, repo_token, '')
995
 
        finally:
996
 
            branch.repository.unlock()
997
 
            branch.unlock()
998
 
        self.assertEqual(SuccessfulSmartServerResponse(()), response)
999
 
        self.assertEqual(None, branch.get_parent())
1000
 
 
1001
 
    def test_set_parent_something(self):
1002
 
        branch = self.make_branch('base', format="1.9")
1003
 
        request = smart.branch.SmartServerBranchRequestSetParentLocation(
1004
 
            self.get_transport())
1005
 
        branch_token = branch.lock_write()
1006
 
        repo_token = branch.repository.lock_write()
1007
 
        try:
1008
 
            response = request.execute('base', branch_token, repo_token,
1009
 
            'http://bar/')
1010
 
        finally:
1011
 
            branch.repository.unlock()
1012
 
            branch.unlock()
1013
 
        self.assertEqual(SuccessfulSmartServerResponse(()), response)
1014
 
        self.assertEqual('http://bar/', branch.get_parent())
1015
 
 
1016
 
 
1017
 
class TestSmartServerBranchRequestGetTagsBytes(tests.TestCaseWithMemoryTransport):
1018
 
    # Only called when the branch format and tags match [yay factory
1019
 
    # methods] so only need to test straight forward cases.
1020
 
 
1021
 
    def test_get_bytes(self):
1022
 
        base_branch = self.make_branch('base')
1023
 
        request = smart.branch.SmartServerBranchGetTagsBytes(
1024
 
            self.get_transport())
1025
 
        response = request.execute('base')
1026
 
        self.assertEquals(
1027
 
            SuccessfulSmartServerResponse(('',)), response)
1028
 
 
1029
 
 
1030
618
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
1031
619
 
1032
620
    def test_get_stacked_on_url(self):
1062
650
        # with a new branch object.
1063
651
        new_branch = repository.bzrdir.open_branch()
1064
652
        self.assertRaises(errors.LockContention, new_branch.lock_write)
1065
 
        # Cleanup
1066
 
        request = smart.branch.SmartServerBranchRequestUnlock(backing)
1067
 
        response = request.execute('', branch_nonce, repository_nonce)
1068
653
 
1069
654
    def test_lock_write_on_locked_branch(self):
1070
655
        backing = self.get_transport()
1071
656
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1072
657
        branch = self.make_branch('.')
1073
 
        branch_token = branch.lock_write()
 
658
        branch.lock_write()
1074
659
        branch.leave_lock_in_place()
1075
660
        branch.unlock()
1076
661
        response = request.execute('')
1077
662
        self.assertEqual(
1078
663
            SmartServerResponse(('LockContention',)), response)
1079
 
        # Cleanup
1080
 
        branch.lock_write(branch_token)
1081
 
        branch.dont_leave_lock_in_place()
1082
 
        branch.unlock()
1083
664
 
1084
665
    def test_lock_write_with_tokens_on_locked_branch(self):
1085
666
        backing = self.get_transport()
1095
676
                                   branch_token, repo_token)
1096
677
        self.assertEqual(
1097
678
            SmartServerResponse(('ok', branch_token, repo_token)), response)
1098
 
        # Cleanup
1099
 
        branch.repository.lock_write(repo_token)
1100
 
        branch.repository.dont_leave_lock_in_place()
1101
 
        branch.repository.unlock()
1102
 
        branch.lock_write(branch_token)
1103
 
        branch.dont_leave_lock_in_place()
1104
 
        branch.unlock()
1105
679
 
1106
680
    def test_lock_write_with_mismatched_tokens_on_locked_branch(self):
1107
681
        backing = self.get_transport()
1117
691
                                   branch_token+'xxx', repo_token)
1118
692
        self.assertEqual(
1119
693
            SmartServerResponse(('TokenMismatch',)), response)
1120
 
        # Cleanup
1121
 
        branch.repository.lock_write(repo_token)
1122
 
        branch.repository.dont_leave_lock_in_place()
1123
 
        branch.repository.unlock()
1124
 
        branch.lock_write(branch_token)
1125
 
        branch.dont_leave_lock_in_place()
1126
 
        branch.unlock()
1127
694
 
1128
695
    def test_lock_write_on_locked_repo(self):
1129
696
        backing = self.get_transport()
1130
697
        request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1131
698
        branch = self.make_branch('.', format='knit')
1132
 
        repo = branch.repository
1133
 
        repo_token = repo.lock_write()
1134
 
        repo.leave_lock_in_place()
1135
 
        repo.unlock()
 
699
        branch.repository.lock_write()
 
700
        branch.repository.leave_lock_in_place()
 
701
        branch.repository.unlock()
1136
702
        response = request.execute('')
1137
703
        self.assertEqual(
1138
704
            SmartServerResponse(('LockContention',)), response)
1139
 
        # Cleanup
1140
 
        repo.lock_write(repo_token)
1141
 
        repo.dont_leave_lock_in_place()
1142
 
        repo.unlock()
1143
705
 
1144
706
    def test_lock_write_on_readonly_transport(self):
1145
707
        backing = self.get_readonly_transport()
1204
766
            '', 'branch token', repo_token)
1205
767
        self.assertEqual(
1206
768
            SmartServerResponse(('TokenMismatch',)), response)
1207
 
        # Cleanup
1208
 
        branch.repository.lock_write(repo_token)
1209
 
        branch.repository.dont_leave_lock_in_place()
1210
 
        branch.repository.unlock()
1211
769
 
1212
770
 
1213
771
class TestSmartServerRepositoryRequest(tests.TestCaseWithMemoryTransport):
1236
794
 
1237
795
        self.assertEqual(None,
1238
796
            request.execute('', 'missing-id'))
1239
 
        # Note that it returns a body that is bzipped.
 
797
        # Note that it returns a body (of '' bzipped).
1240
798
        self.assertEqual(
1241
799
            SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
1242
800
            request.do_body('\n\n0\n'))
1243
801
 
1244
 
    def test_trivial_include_missing(self):
1245
 
        backing = self.get_transport()
1246
 
        request = smart.repository.SmartServerRepositoryGetParentMap(backing)
1247
 
        tree = self.make_branch_and_memory_tree('.')
1248
 
 
1249
 
        self.assertEqual(None,
1250
 
            request.execute('', 'missing-id', 'include-missing:'))
1251
 
        self.assertEqual(
1252
 
            SuccessfulSmartServerResponse(('ok', ),
1253
 
                bz2.compress('missing:missing-id')),
1254
 
            request.do_body('\n\n0\n'))
1255
 
 
1256
802
 
1257
803
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithMemoryTransport):
1258
804
 
1288
834
 
1289
835
        self.assertEqual(SmartServerResponse(('ok', ), rev_id_utf8),
1290
836
            request.execute('', rev_id_utf8))
1291
 
 
 
837
    
1292
838
    def test_no_such_revision(self):
1293
839
        backing = self.get_transport()
1294
840
        request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
1304
850
            request.execute('', 'missingrevision'))
1305
851
 
1306
852
 
1307
 
class TestSmartServerRepositoryGetRevIdForRevno(tests.TestCaseWithMemoryTransport):
1308
 
 
1309
 
    def test_revno_found(self):
1310
 
        backing = self.get_transport()
1311
 
        request = smart.repository.SmartServerRepositoryGetRevIdForRevno(backing)
1312
 
        tree = self.make_branch_and_memory_tree('.')
1313
 
        tree.lock_write()
1314
 
        tree.add('')
1315
 
        rev1_id_utf8 = u'\xc8'.encode('utf-8')
1316
 
        rev2_id_utf8 = u'\xc9'.encode('utf-8')
1317
 
        tree.commit('1st commit', rev_id=rev1_id_utf8)
1318
 
        tree.commit('2nd commit', rev_id=rev2_id_utf8)
1319
 
        tree.unlock()
1320
 
 
1321
 
        self.assertEqual(SmartServerResponse(('ok', rev1_id_utf8)),
1322
 
            request.execute('', 1, (2, rev2_id_utf8)))
1323
 
 
1324
 
    def test_known_revid_missing(self):
1325
 
        backing = self.get_transport()
1326
 
        request = smart.repository.SmartServerRepositoryGetRevIdForRevno(backing)
1327
 
        repo = self.make_repository('.')
1328
 
        self.assertEqual(
1329
 
            FailedSmartServerResponse(('nosuchrevision', 'ghost')),
1330
 
            request.execute('', 1, (2, 'ghost')))
1331
 
 
1332
 
    def test_history_incomplete(self):
1333
 
        backing = self.get_transport()
1334
 
        request = smart.repository.SmartServerRepositoryGetRevIdForRevno(backing)
1335
 
        parent = self.make_branch_and_memory_tree('parent', format='1.9')
1336
 
        parent.lock_write()
1337
 
        parent.add([''], ['TREE_ROOT'])
1338
 
        r1 = parent.commit(message='first commit')
1339
 
        r2 = parent.commit(message='second commit')
1340
 
        parent.unlock()
1341
 
        local = self.make_branch_and_memory_tree('local', format='1.9')
1342
 
        local.branch.pull(parent.branch)
1343
 
        local.set_parent_ids([r2])
1344
 
        r3 = local.commit(message='local commit')
1345
 
        local.branch.create_clone_on_transport(
1346
 
            self.get_transport('stacked'), stacked_on=self.get_url('parent'))
1347
 
        self.assertEqual(
1348
 
            SmartServerResponse(('history-incomplete', 2, r2)),
1349
 
            request.execute('stacked', 1, (3, r3)))
1350
 
 
1351
 
 
1352
 
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
1353
 
 
1354
 
    def make_two_commit_repo(self):
1355
 
        tree = self.make_branch_and_memory_tree('.')
1356
 
        tree.lock_write()
1357
 
        tree.add('')
1358
 
        r1 = tree.commit('1st commit')
1359
 
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
1360
 
        tree.unlock()
1361
 
        repo = tree.branch.repository
1362
 
        return repo, r1, r2
1363
 
 
1364
 
    def test_ancestry_of(self):
1365
 
        """The search argument may be a 'ancestry-of' some heads'."""
1366
 
        backing = self.get_transport()
1367
 
        request = smart.repository.SmartServerRepositoryGetStream(backing)
1368
 
        repo, r1, r2 = self.make_two_commit_repo()
1369
 
        fetch_spec = ['ancestry-of', r2]
1370
 
        lines = '\n'.join(fetch_spec)
1371
 
        request.execute('', repo._format.network_name())
1372
 
        response = request.do_body(lines)
1373
 
        self.assertEqual(('ok',), response.args)
1374
 
        stream_bytes = ''.join(response.body_stream)
1375
 
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1376
 
 
1377
 
    def test_search(self):
1378
 
        """The search argument may be a 'search' of some explicit keys."""
1379
 
        backing = self.get_transport()
1380
 
        request = smart.repository.SmartServerRepositoryGetStream(backing)
1381
 
        repo, r1, r2 = self.make_two_commit_repo()
1382
 
        fetch_spec = ['search', '%s %s' % (r1, r2), 'null:', '2']
1383
 
        lines = '\n'.join(fetch_spec)
1384
 
        request.execute('', repo._format.network_name())
1385
 
        response = request.do_body(lines)
1386
 
        self.assertEqual(('ok',), response.args)
1387
 
        stream_bytes = ''.join(response.body_stream)
1388
 
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1389
 
 
1390
 
 
1391
853
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1392
854
 
1393
855
    def test_missing_revision(self):
1493
955
 
1494
956
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
1495
957
 
 
958
    def setUp(self):
 
959
        tests.TestCaseWithMemoryTransport.setUp(self)
 
960
 
1496
961
    def test_lock_write_on_unlocked_repo(self):
1497
962
        backing = self.get_transport()
1498
963
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
1504
969
        # object.
1505
970
        new_repo = repository.bzrdir.open_repository()
1506
971
        self.assertRaises(errors.LockContention, new_repo.lock_write)
1507
 
        # Cleanup
1508
 
        request = smart.repository.SmartServerRepositoryUnlock(backing)
1509
 
        response = request.execute('', nonce)
1510
972
 
1511
973
    def test_lock_write_on_locked_repo(self):
1512
974
        backing = self.get_transport()
1513
975
        request = smart.repository.SmartServerRepositoryLockWrite(backing)
1514
976
        repository = self.make_repository('.', format='knit')
1515
 
        repo_token = repository.lock_write()
 
977
        repository.lock_write()
1516
978
        repository.leave_lock_in_place()
1517
979
        repository.unlock()
1518
980
        response = request.execute('')
1519
981
        self.assertEqual(
1520
982
            SmartServerResponse(('LockContention',)), response)
1521
 
        # Cleanup
1522
 
        repository.lock_write(repo_token)
1523
 
        repository.dont_leave_lock_in_place()
1524
 
        repository.unlock()
1525
983
 
1526
984
    def test_lock_write_on_readonly_transport(self):
1527
985
        backing = self.get_readonly_transport()
1532
990
        self.assertEqual('LockFailed', response.args[0])
1533
991
 
1534
992
 
1535
 
class TestInsertStreamBase(tests.TestCaseWithMemoryTransport):
1536
 
 
1537
 
    def make_empty_byte_stream(self, repo):
1538
 
        byte_stream = smart.repository._stream_to_byte_stream([], repo._format)
1539
 
        return ''.join(byte_stream)
1540
 
 
1541
 
 
1542
 
class TestSmartServerRepositoryInsertStream(TestInsertStreamBase):
1543
 
 
1544
 
    def test_insert_stream_empty(self):
1545
 
        backing = self.get_transport()
1546
 
        request = smart.repository.SmartServerRepositoryInsertStream(backing)
1547
 
        repository = self.make_repository('.')
1548
 
        response = request.execute('', '')
1549
 
        self.assertEqual(None, response)
1550
 
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1551
 
        self.assertEqual(None, response)
1552
 
        response = request.do_end()
1553
 
        self.assertEqual(SmartServerResponse(('ok', )), response)
1554
 
        
1555
 
 
1556
 
class TestSmartServerRepositoryInsertStreamLocked(TestInsertStreamBase):
1557
 
 
1558
 
    def test_insert_stream_empty(self):
1559
 
        backing = self.get_transport()
1560
 
        request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1561
 
            backing)
1562
 
        repository = self.make_repository('.', format='knit')
1563
 
        lock_token = repository.lock_write()
1564
 
        response = request.execute('', '', lock_token)
1565
 
        self.assertEqual(None, response)
1566
 
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1567
 
        self.assertEqual(None, response)
1568
 
        response = request.do_end()
1569
 
        self.assertEqual(SmartServerResponse(('ok', )), response)
1570
 
        repository.unlock()
1571
 
 
1572
 
    def test_insert_stream_with_wrong_lock_token(self):
1573
 
        backing = self.get_transport()
1574
 
        request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1575
 
            backing)
1576
 
        repository = self.make_repository('.', format='knit')
1577
 
        lock_token = repository.lock_write()
1578
 
        self.assertRaises(
1579
 
            errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1580
 
        repository.unlock()
1581
 
 
1582
 
 
1583
993
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
1584
994
 
1585
995
    def setUp(self):
1627
1037
            SmartServerResponse(('yes',)), response)
1628
1038
 
1629
1039
 
1630
 
class TestSmartServerRepositorySetMakeWorkingTrees(tests.TestCaseWithMemoryTransport):
1631
 
 
1632
 
    def test_set_false(self):
1633
 
        backing = self.get_transport()
1634
 
        repo = self.make_repository('.', shared=True)
1635
 
        repo.set_make_working_trees(True)
1636
 
        request_class = smart.repository.SmartServerRepositorySetMakeWorkingTrees
1637
 
        request = request_class(backing)
1638
 
        self.assertEqual(SuccessfulSmartServerResponse(('ok',)),
1639
 
            request.execute('', 'False'))
1640
 
        repo = repo.bzrdir.open_repository()
1641
 
        self.assertFalse(repo.make_working_trees())
1642
 
 
1643
 
    def test_set_true(self):
1644
 
        backing = self.get_transport()
1645
 
        repo = self.make_repository('.', shared=True)
1646
 
        repo.set_make_working_trees(False)
1647
 
        request_class = smart.repository.SmartServerRepositorySetMakeWorkingTrees
1648
 
        request = request_class(backing)
1649
 
        self.assertEqual(SuccessfulSmartServerResponse(('ok',)),
1650
 
            request.execute('', 'True'))
1651
 
        repo = repo.bzrdir.open_repository()
1652
 
        self.assertTrue(repo.make_working_trees())
1653
 
 
1654
 
 
1655
1040
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1656
1041
 
1657
1042
    def make_repo_needing_autopacking(self, path='.'):
1668
1053
 
1669
1054
    def test_autopack_needed(self):
1670
1055
        repo = self.make_repo_needing_autopacking()
1671
 
        repo.lock_write()
1672
 
        self.addCleanup(repo.unlock)
1673
1056
        backing = self.get_transport()
1674
1057
        request = smart.packrepository.SmartServerPackRepositoryAutopack(
1675
1058
            backing)
1677
1060
        self.assertEqual(SmartServerResponse(('ok',)), response)
1678
1061
        repo._pack_collection.reload_pack_names()
1679
1062
        self.assertEqual(1, len(repo._pack_collection.names()))
1680
 
 
 
1063
    
1681
1064
    def test_autopack_not_needed(self):
1682
1065
        tree = self.make_branch_and_tree('.', format='pack-0.92')
1683
1066
        repo = tree.branch.repository
1684
 
        repo.lock_write()
1685
 
        self.addCleanup(repo.unlock)
1686
1067
        for x in range(9):
1687
1068
            tree.commit('commit %s' % x)
1688
1069
        backing = self.get_transport()
1692
1073
        self.assertEqual(SmartServerResponse(('ok',)), response)
1693
1074
        repo._pack_collection.reload_pack_names()
1694
1075
        self.assertEqual(9, len(repo._pack_collection.names()))
1695
 
 
 
1076
    
1696
1077
    def test_autopack_on_nonpack_format(self):
1697
1078
        """A request to autopack a non-pack repo is a no-op."""
1698
1079
        repo = self.make_repository('.', format='knit')
1701
1082
            backing)
1702
1083
        response = request.execute('')
1703
1084
        self.assertEqual(SmartServerResponse(('ok',)), response)
1704
 
 
1705
 
 
1706
 
class TestSmartServerVfsGet(tests.TestCaseWithMemoryTransport):
1707
 
 
1708
 
    def test_unicode_path(self):
1709
 
        """VFS requests expect unicode paths to be escaped."""
1710
 
        filename = u'foo\N{INTERROBANG}'
1711
 
        filename_escaped = urlutils.escape(filename)
1712
 
        backing = self.get_transport()
1713
 
        request = smart.vfs.GetRequest(backing)
1714
 
        backing.put_bytes_non_atomic(filename_escaped, 'contents')
1715
 
        self.assertEqual(SmartServerResponse(('ok', ), 'contents'),
1716
 
            request.execute(filename_escaped))
1717
 
 
 
1085
        
1718
1086
 
1719
1087
class TestHandlers(tests.TestCase):
1720
1088
    """Tests for the request.request_handlers object."""
1726
1094
        for key, item in smart.request.request_handlers.iteritems():
1727
1095
            pass
1728
1096
 
1729
 
    def assertHandlerEqual(self, verb, handler):
1730
 
        self.assertEqual(smart.request.request_handlers.get(verb), handler)
1731
 
 
1732
1097
    def test_registered_methods(self):
1733
1098
        """Test that known methods are registered to the correct object."""
1734
 
        self.assertHandlerEqual('Branch.get_config_file',
 
1099
        self.assertEqual(
 
1100
            smart.request.request_handlers.get('Branch.get_config_file'),
1735
1101
            smart.branch.SmartServerBranchGetConfigFile)
1736
 
        self.assertHandlerEqual('Branch.get_parent',
1737
 
            smart.branch.SmartServerBranchGetParent)
1738
 
        self.assertHandlerEqual('Branch.get_tags_bytes',
1739
 
            smart.branch.SmartServerBranchGetTagsBytes)
1740
 
        self.assertHandlerEqual('Branch.lock_write',
 
1102
        self.assertEqual(
 
1103
            smart.request.request_handlers.get('Branch.lock_write'),
1741
1104
            smart.branch.SmartServerBranchRequestLockWrite)
1742
 
        self.assertHandlerEqual('Branch.last_revision_info',
 
1105
        self.assertEqual(
 
1106
            smart.request.request_handlers.get('Branch.last_revision_info'),
1743
1107
            smart.branch.SmartServerBranchRequestLastRevisionInfo)
1744
 
        self.assertHandlerEqual('Branch.revision_history',
 
1108
        self.assertEqual(
 
1109
            smart.request.request_handlers.get('Branch.revision_history'),
1745
1110
            smart.branch.SmartServerRequestRevisionHistory)
1746
 
        self.assertHandlerEqual('Branch.set_config_option',
1747
 
            smart.branch.SmartServerBranchRequestSetConfigOption)
1748
 
        self.assertHandlerEqual('Branch.set_last_revision',
 
1111
        self.assertEqual(
 
1112
            smart.request.request_handlers.get('Branch.set_last_revision'),
1749
1113
            smart.branch.SmartServerBranchRequestSetLastRevision)
1750
 
        self.assertHandlerEqual('Branch.set_last_revision_info',
 
1114
        self.assertEqual(
 
1115
            smart.request.request_handlers.get('Branch.set_last_revision_info'),
1751
1116
            smart.branch.SmartServerBranchRequestSetLastRevisionInfo)
1752
 
        self.assertHandlerEqual('Branch.set_last_revision_ex',
1753
 
            smart.branch.SmartServerBranchRequestSetLastRevisionEx)
1754
 
        self.assertHandlerEqual('Branch.set_parent_location',
1755
 
            smart.branch.SmartServerBranchRequestSetParentLocation)
1756
 
        self.assertHandlerEqual('Branch.unlock',
 
1117
        self.assertEqual(
 
1118
            smart.request.request_handlers.get('Branch.unlock'),
1757
1119
            smart.branch.SmartServerBranchRequestUnlock)
1758
 
        self.assertHandlerEqual('BzrDir.find_repository',
 
1120
        self.assertEqual(
 
1121
            smart.request.request_handlers.get('BzrDir.find_repository'),
1759
1122
            smart.bzrdir.SmartServerRequestFindRepositoryV1)
1760
 
        self.assertHandlerEqual('BzrDir.find_repositoryV2',
 
1123
        self.assertEqual(
 
1124
            smart.request.request_handlers.get('BzrDir.find_repositoryV2'),
1761
1125
            smart.bzrdir.SmartServerRequestFindRepositoryV2)
1762
 
        self.assertHandlerEqual('BzrDirFormat.initialize',
 
1126
        self.assertEqual(
 
1127
            smart.request.request_handlers.get('BzrDirFormat.initialize'),
1763
1128
            smart.bzrdir.SmartServerRequestInitializeBzrDir)
1764
 
        self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
1765
 
            smart.bzrdir.SmartServerRequestBzrDirInitializeEx)
1766
 
        self.assertHandlerEqual('BzrDir.cloning_metadir',
1767
 
            smart.bzrdir.SmartServerBzrDirRequestCloningMetaDir)
1768
 
        self.assertHandlerEqual('BzrDir.get_config_file',
1769
 
            smart.bzrdir.SmartServerBzrDirRequestConfigFile)
1770
 
        self.assertHandlerEqual('BzrDir.open_branch',
 
1129
        self.assertEqual(
 
1130
            smart.request.request_handlers.get('BzrDir.open_branch'),
1771
1131
            smart.bzrdir.SmartServerRequestOpenBranch)
1772
 
        self.assertHandlerEqual('BzrDir.open_branchV2',
1773
 
            smart.bzrdir.SmartServerRequestOpenBranchV2)
1774
 
        self.assertHandlerEqual('PackRepository.autopack',
 
1132
        self.assertEqual(
 
1133
            smart.request.request_handlers.get('PackRepository.autopack'),
1775
1134
            smart.packrepository.SmartServerPackRepositoryAutopack)
1776
 
        self.assertHandlerEqual('Repository.gather_stats',
 
1135
        self.assertEqual(
 
1136
            smart.request.request_handlers.get('Repository.gather_stats'),
1777
1137
            smart.repository.SmartServerRepositoryGatherStats)
1778
 
        self.assertHandlerEqual('Repository.get_parent_map',
 
1138
        self.assertEqual(
 
1139
            smart.request.request_handlers.get('Repository.get_parent_map'),
1779
1140
            smart.repository.SmartServerRepositoryGetParentMap)
1780
 
        self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1781
 
            smart.repository.SmartServerRepositoryGetRevIdForRevno)
1782
 
        self.assertHandlerEqual('Repository.get_revision_graph',
 
1141
        self.assertEqual(
 
1142
            smart.request.request_handlers.get(
 
1143
                'Repository.get_revision_graph'),
1783
1144
            smart.repository.SmartServerRepositoryGetRevisionGraph)
1784
 
        self.assertHandlerEqual('Repository.get_stream',
1785
 
            smart.repository.SmartServerRepositoryGetStream)
1786
 
        self.assertHandlerEqual('Repository.has_revision',
 
1145
        self.assertEqual(
 
1146
            smart.request.request_handlers.get('Repository.has_revision'),
1787
1147
            smart.repository.SmartServerRequestHasRevision)
1788
 
        self.assertHandlerEqual('Repository.insert_stream',
1789
 
            smart.repository.SmartServerRepositoryInsertStream)
1790
 
        self.assertHandlerEqual('Repository.insert_stream_locked',
1791
 
            smart.repository.SmartServerRepositoryInsertStreamLocked)
1792
 
        self.assertHandlerEqual('Repository.is_shared',
 
1148
        self.assertEqual(
 
1149
            smart.request.request_handlers.get('Repository.is_shared'),
1793
1150
            smart.repository.SmartServerRepositoryIsShared)
1794
 
        self.assertHandlerEqual('Repository.lock_write',
 
1151
        self.assertEqual(
 
1152
            smart.request.request_handlers.get('Repository.lock_write'),
1795
1153
            smart.repository.SmartServerRepositoryLockWrite)
1796
 
        self.assertHandlerEqual('Repository.tarball',
 
1154
        self.assertEqual(
 
1155
            smart.request.request_handlers.get('Repository.tarball'),
1797
1156
            smart.repository.SmartServerRepositoryTarball)
1798
 
        self.assertHandlerEqual('Repository.unlock',
 
1157
        self.assertEqual(
 
1158
            smart.request.request_handlers.get('Repository.unlock'),
1799
1159
            smart.repository.SmartServerRepositoryUnlock)
1800
 
        self.assertHandlerEqual('Transport.is_readonly',
 
1160
        self.assertEqual(
 
1161
            smart.request.request_handlers.get('Transport.is_readonly'),
1801
1162
            smart.request.SmartServerIsReadonly)