/brz/remove-bazaar

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

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_remote.py

  • Committer: Robert Collins
  • Date: 2008-02-13 03:30:01 UTC
  • mfrom: (3221 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3224.
  • Revision ID: robertc@robertcollins.net-20080213033001-rw70ul0zb02ph856
Merge to fix conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
These tests correspond to tests.test_smart, which exercises the server side.
24
24
"""
25
25
 
 
26
import bz2
26
27
from cStringIO import StringIO
27
28
 
28
29
from bzrlib import (
29
 
    bzrdir,
30
30
    errors,
 
31
    graph,
31
32
    pack,
32
33
    remote,
33
34
    repository,
108
109
    """Lookalike SmartClientRequestProtocolOne allowing body reading tests."""
109
110
 
110
111
    def __init__(self, body, fake_client):
111
 
        self._body_buffer = StringIO(body)
 
112
        self.body = body
 
113
        self._body_buffer = None
112
114
        self._fake_client = fake_client
113
115
 
114
116
    def read_body_bytes(self, count=-1):
 
117
        if self._body_buffer is None:
 
118
            self._body_buffer = StringIO(self.body)
115
119
        bytes = self._body_buffer.read(count)
116
120
        if self._body_buffer.tell() == len(self._body_buffer.getvalue()):
117
121
            self._fake_client.expecting_body = False
120
124
    def cancel_read_body(self):
121
125
        self._fake_client.expecting_body = False
122
126
 
 
127
    def read_streamed_body(self):
 
128
        return self.body
 
129
 
123
130
 
124
131
class FakeClient(_SmartClient):
125
132
    """Lookalike for _SmartClient allowing testing."""
126
133
    
127
 
    def __init__(self, responses):
128
 
        # We don't call the super init because there is no medium.
 
134
    def __init__(self, responses, fake_medium_base='fake base'):
129
135
        """Create a FakeClient.
130
136
 
131
 
        :param respones: A list of response-tuple, body-data pairs to be sent
 
137
        :param responses: A list of response-tuple, body-data pairs to be sent
132
138
            back to callers.
133
139
        """
134
140
        self.responses = responses
135
141
        self._calls = []
136
142
        self.expecting_body = False
 
143
        _SmartClient.__init__(self, FakeMedium(fake_medium_base, self._calls))
137
144
 
138
145
    def call(self, method, *args):
139
146
        self._calls.append(('call', method, args))
145
152
        self.expecting_body = True
146
153
        return result[0], FakeProtocol(result[1], self)
147
154
 
 
155
    def call_with_body_bytes_expecting_body(self, method, args, body):
 
156
        self._calls.append(('call_with_body_bytes_expecting_body', method,
 
157
            args, body))
 
158
        result = self.responses.pop(0)
 
159
        self.expecting_body = True
 
160
        return result[0], FakeProtocol(result[1], self)
 
161
 
 
162
 
 
163
class FakeMedium(object):
 
164
 
 
165
    def __init__(self, base, client_calls):
 
166
        self.base = base
 
167
        self.connection = FakeConnection(client_calls)
 
168
        self._client_calls = client_calls
 
169
 
 
170
 
 
171
class FakeConnection(object):
 
172
 
 
173
    def __init__(self, client_calls):
 
174
        self._remote_is_at_least_1_2 = True
 
175
        self._client_calls = client_calls
 
176
 
 
177
    def disconnect(self):
 
178
        self._client_calls.append(('disconnect medium',))
 
179
 
 
180
 
 
181
class TestVfsHas(tests.TestCase):
 
182
 
 
183
    def test_unicode_path(self):
 
184
        client = FakeClient([(('yes',), )], '/')
 
185
        transport = RemoteTransport('bzr://localhost/', _client=client)
 
186
        filename = u'/hell\u00d8'.encode('utf8')
 
187
        result = transport.has(filename)
 
188
        self.assertEqual(
 
189
            [('call', 'has', (filename,))],
 
190
            client._calls)
 
191
        self.assertTrue(result)
 
192
 
148
193
 
149
194
class TestBzrDirOpenBranch(tests.TestCase):
150
195
 
151
196
    def test_branch_present(self):
152
 
        client = FakeClient([(('ok', ''), ), (('ok', '', 'no', 'no'), )])
153
197
        transport = MemoryTransport()
154
198
        transport.mkdir('quack')
155
199
        transport = transport.clone('quack')
 
200
        client = FakeClient([(('ok', ''), ), (('ok', '', 'no', 'no'), )],
 
201
                            transport.base)
156
202
        bzrdir = RemoteBzrDir(transport, _client=client)
157
203
        result = bzrdir.open_branch()
158
204
        self.assertEqual(
159
 
            [('call', 'BzrDir.open_branch', ('///quack/',)),
160
 
             ('call', 'BzrDir.find_repository', ('///quack/',))],
 
205
            [('call', 'BzrDir.open_branch', ('quack/',)),
 
206
             ('call', 'BzrDir.find_repository', ('quack/',))],
161
207
            client._calls)
162
208
        self.assertIsInstance(result, RemoteBranch)
163
209
        self.assertEqual(bzrdir, result.bzrdir)
164
210
 
165
211
    def test_branch_missing(self):
166
 
        client = FakeClient([(('nobranch',), )])
167
212
        transport = MemoryTransport()
168
213
        transport.mkdir('quack')
169
214
        transport = transport.clone('quack')
 
215
        client = FakeClient([(('nobranch',), )], transport.base)
170
216
        bzrdir = RemoteBzrDir(transport, _client=client)
171
217
        self.assertRaises(errors.NotBranchError, bzrdir.open_branch)
172
218
        self.assertEqual(
173
 
            [('call', 'BzrDir.open_branch', ('///quack/',))],
 
219
            [('call', 'BzrDir.open_branch', ('quack/',))],
 
220
            client._calls)
 
221
 
 
222
    def test__get_tree_branch(self):
 
223
        # _get_tree_branch is a form of open_branch, but it should only ask for
 
224
        # branch opening, not any other network requests.
 
225
        calls = []
 
226
        def open_branch():
 
227
            calls.append("Called")
 
228
            return "a-branch"
 
229
        transport = MemoryTransport()
 
230
        # no requests on the network - catches other api calls being made.
 
231
        client = FakeClient([], transport.base)
 
232
        bzrdir = RemoteBzrDir(transport, _client=client)
 
233
        # patch the open_branch call to record that it was called.
 
234
        bzrdir.open_branch = open_branch
 
235
        self.assertEqual((None, "a-branch"), bzrdir._get_tree_branch())
 
236
        self.assertEqual(["Called"], calls)
 
237
        self.assertEqual([], client._calls)
 
238
 
 
239
    def test_url_quoting_of_path(self):
 
240
        # Relpaths on the wire should not be URL-escaped.  So "~" should be
 
241
        # transmitted as "~", not "%7E".
 
242
        transport = RemoteTransport('bzr://localhost/~hello/')
 
243
        client = FakeClient([(('ok', ''), ), (('ok', '', 'no', 'no'), )],
 
244
                            transport.base)
 
245
        bzrdir = RemoteBzrDir(transport, _client=client)
 
246
        result = bzrdir.open_branch()
 
247
        self.assertEqual(
 
248
            [('call', 'BzrDir.open_branch', ('~hello/',)),
 
249
             ('call', 'BzrDir.find_repository', ('~hello/',))],
174
250
            client._calls)
175
251
 
176
252
    def check_open_repository(self, rich_root, subtrees):
 
253
        transport = MemoryTransport()
 
254
        transport.mkdir('quack')
 
255
        transport = transport.clone('quack')
177
256
        if rich_root:
178
257
            rich_response = 'yes'
179
258
        else:
182
261
            subtree_response = 'yes'
183
262
        else:
184
263
            subtree_response = 'no'
185
 
        client = FakeClient([(('ok', '', rich_response, subtree_response), ),])
186
 
        transport = MemoryTransport()
187
 
        transport.mkdir('quack')
188
 
        transport = transport.clone('quack')
 
264
        client = FakeClient([(('ok', '', rich_response, subtree_response), ),],
 
265
                            transport.base)
189
266
        bzrdir = RemoteBzrDir(transport, _client=client)
190
267
        result = bzrdir.open_repository()
191
268
        self.assertEqual(
192
 
            [('call', 'BzrDir.find_repository', ('///quack/',))],
 
269
            [('call', 'BzrDir.find_repository', ('quack/',))],
193
270
            client._calls)
194
271
        self.assertIsInstance(result, RemoteRepository)
195
272
        self.assertEqual(bzrdir, result.bzrdir)
239
316
 
240
317
    def test_empty_branch(self):
241
318
        # in an empty branch we decode the response properly
242
 
        client = FakeClient([(('ok', '0', 'null:'), )])
243
319
        transport = MemoryTransport()
 
320
        client = FakeClient([(('ok', '0', 'null:'), )], transport.base)
244
321
        transport.mkdir('quack')
245
322
        transport = transport.clone('quack')
246
323
        # we do not want bzrdir to make any remote calls
249
326
        result = branch.last_revision_info()
250
327
 
251
328
        self.assertEqual(
252
 
            [('call', 'Branch.last_revision_info', ('///quack/',))],
 
329
            [('call', 'Branch.last_revision_info', ('quack/',))],
253
330
            client._calls)
254
331
        self.assertEqual((0, NULL_REVISION), result)
255
332
 
256
333
    def test_non_empty_branch(self):
257
334
        # in a non-empty branch we also decode the response properly
258
335
        revid = u'\xc8'.encode('utf8')
259
 
        client = FakeClient([(('ok', '2', revid), )])
260
336
        transport = MemoryTransport()
 
337
        client = FakeClient([(('ok', '2', revid), )], transport.base)
261
338
        transport.mkdir('kwaak')
262
339
        transport = transport.clone('kwaak')
263
340
        # we do not want bzrdir to make any remote calls
266
343
        result = branch.last_revision_info()
267
344
 
268
345
        self.assertEqual(
269
 
            [('call', 'Branch.last_revision_info', ('///kwaak/',))],
 
346
            [('call', 'Branch.last_revision_info', ('kwaak/',))],
270
347
            client._calls)
271
348
        self.assertEqual((2, revid), result)
272
349
 
276
353
    def test_set_empty(self):
277
354
        # set_revision_history([]) is translated to calling
278
355
        # Branch.set_last_revision(path, '') on the wire.
 
356
        transport = MemoryTransport()
 
357
        transport.mkdir('branch')
 
358
        transport = transport.clone('branch')
 
359
 
279
360
        client = FakeClient([
280
361
            # lock_write
281
362
            (('ok', 'branch token', 'repo token'), ),
282
363
            # set_last_revision
283
364
            (('ok',), ),
284
365
            # unlock
285
 
            (('ok',), )])
286
 
        transport = MemoryTransport()
287
 
        transport.mkdir('branch')
288
 
        transport = transport.clone('branch')
289
 
 
 
366
            (('ok',), )],
 
367
            transport.base)
290
368
        bzrdir = RemoteBzrDir(transport, _client=False)
291
369
        branch = RemoteBranch(bzrdir, None, _client=client)
292
370
        # This is a hack to work around the problem that RemoteBranch currently
297
375
        result = branch.set_revision_history([])
298
376
        self.assertEqual(
299
377
            [('call', 'Branch.set_last_revision',
300
 
                ('///branch/', 'branch token', 'repo token', 'null:'))],
 
378
                ('branch/', 'branch token', 'repo token', 'null:'))],
301
379
            client._calls)
302
380
        branch.unlock()
303
381
        self.assertEqual(None, result)
305
383
    def test_set_nonempty(self):
306
384
        # set_revision_history([rev-id1, ..., rev-idN]) is translated to calling
307
385
        # Branch.set_last_revision(path, rev-idN) on the wire.
 
386
        transport = MemoryTransport()
 
387
        transport.mkdir('branch')
 
388
        transport = transport.clone('branch')
 
389
 
308
390
        client = FakeClient([
309
391
            # lock_write
310
392
            (('ok', 'branch token', 'repo token'), ),
311
393
            # set_last_revision
312
394
            (('ok',), ),
313
395
            # unlock
314
 
            (('ok',), )])
315
 
        transport = MemoryTransport()
316
 
        transport.mkdir('branch')
317
 
        transport = transport.clone('branch')
318
 
 
 
396
            (('ok',), )],
 
397
            transport.base)
319
398
        bzrdir = RemoteBzrDir(transport, _client=False)
320
399
        branch = RemoteBranch(bzrdir, None, _client=client)
321
400
        # This is a hack to work around the problem that RemoteBranch currently
328
407
        result = branch.set_revision_history(['rev-id1', 'rev-id2'])
329
408
        self.assertEqual(
330
409
            [('call', 'Branch.set_last_revision',
331
 
                ('///branch/', 'branch token', 'repo token', 'rev-id2'))],
 
410
                ('branch/', 'branch token', 'repo token', 'rev-id2'))],
332
411
            client._calls)
333
412
        branch.unlock()
334
413
        self.assertEqual(None, result)
368
447
 
369
448
    def test_get_branch_conf(self):
370
449
        # in an empty branch we decode the response properly
371
 
        client = FakeClient([(('ok', ), 'config file body')])
 
450
        client = FakeClient([(('ok', ), 'config file body')], self.get_url())
372
451
        # we need to make a real branch because the remote_branch.control_files
373
452
        # will trigger _ensure_real.
374
453
        branch = self.make_branch('quack')
378
457
        branch = RemoteBranch(bzrdir, None, _client=client)
379
458
        result = branch.control_files.get('branch.conf')
380
459
        self.assertEqual(
381
 
            [('call_expecting_body', 'Branch.get_config_file', ('///quack/',))],
 
460
            [('call_expecting_body', 'Branch.get_config_file', ('quack/',))],
382
461
            client._calls)
383
462
        self.assertEqual('config file body', result.read())
384
463
 
386
465
class TestBranchLockWrite(tests.TestCase):
387
466
 
388
467
    def test_lock_write_unlockable(self):
389
 
        client = FakeClient([(('UnlockableTransport', ), '')])
390
468
        transport = MemoryTransport()
 
469
        client = FakeClient([(('UnlockableTransport', ), '')], transport.base)
391
470
        transport.mkdir('quack')
392
471
        transport = transport.clone('quack')
393
472
        # we do not want bzrdir to make any remote calls
395
474
        branch = RemoteBranch(bzrdir, None, _client=client)
396
475
        self.assertRaises(errors.UnlockableTransport, branch.lock_write)
397
476
        self.assertEqual(
398
 
            [('call', 'Branch.lock_write', ('///quack/', '', ''))],
 
477
            [('call', 'Branch.lock_write', ('quack/', '', ''))],
399
478
            client._calls)
400
479
 
401
480
 
468
547
        :param transport_path: Path below the root of the MemoryTransport
469
548
            where the repository will be created.
470
549
        """
471
 
        client = FakeClient(responses)
472
550
        transport = MemoryTransport()
473
551
        transport.mkdir(transport_path)
 
552
        client = FakeClient(responses, transport.base)
474
553
        transport = transport.clone(transport_path)
475
554
        # we do not want bzrdir to make any remote calls
476
555
        bzrdir = RemoteBzrDir(transport, _client=False)
489
568
        result = repo.gather_stats(None)
490
569
        self.assertEqual(
491
570
            [('call_expecting_body', 'Repository.gather_stats',
492
 
             ('///quack/','','no'))],
 
571
             ('quack/','','no'))],
493
572
            client._calls)
494
573
        self.assertEqual({'revisions': 2, 'size': 18}, result)
495
574
 
507
586
        result = repo.gather_stats(revid)
508
587
        self.assertEqual(
509
588
            [('call_expecting_body', 'Repository.gather_stats',
510
 
              ('///quick/', revid, 'no'))],
 
589
              ('quick/', revid, 'no'))],
511
590
            client._calls)
512
591
        self.assertEqual({'revisions': 2, 'size': 18,
513
592
                          'firstrev': (123456.300, 3600),
529
608
        result = repo.gather_stats(revid, True)
530
609
        self.assertEqual(
531
610
            [('call_expecting_body', 'Repository.gather_stats',
532
 
              ('///buick/', revid, 'yes'))],
 
611
              ('buick/', revid, 'yes'))],
533
612
            client._calls)
534
613
        self.assertEqual({'revisions': 2, 'size': 18,
535
614
                          'committers': 128,
538
617
                         result)
539
618
 
540
619
 
 
620
class TestRepositoryGetGraph(TestRemoteRepository):
 
621
 
 
622
    def test_get_graph(self):
 
623
        # get_graph returns a graph with the repository as the
 
624
        # parents_provider.
 
625
        responses = []
 
626
        transport_path = 'quack'
 
627
        repo, client = self.setup_fake_client_and_repository(
 
628
            responses, transport_path)
 
629
        graph = repo.get_graph()
 
630
        self.assertEqual(graph._parents_provider, repo)
 
631
 
 
632
 
 
633
class TestRepositoryGetParentMap(TestRemoteRepository):
 
634
 
 
635
    def test_get_parent_map_caching(self):
 
636
        # get_parent_map returns from cache until unlock()
 
637
        # setup a reponse with two revisions
 
638
        r1 = u'\u0e33'.encode('utf8')
 
639
        r2 = u'\u0dab'.encode('utf8')
 
640
        lines = [' '.join([r2, r1]), r1]
 
641
        encoded_body = bz2.compress('\n'.join(lines))
 
642
        responses = [(('ok', ), encoded_body), (('ok', ), encoded_body)]
 
643
 
 
644
        transport_path = 'quack'
 
645
        repo, client = self.setup_fake_client_and_repository(
 
646
            responses, transport_path)
 
647
        repo.lock_read()
 
648
        graph = repo.get_graph()
 
649
        parents = graph.get_parent_map([r2])
 
650
        self.assertEqual({r2: (r1,)}, parents)
 
651
        # locking and unlocking deeper should not reset
 
652
        repo.lock_read()
 
653
        repo.unlock()
 
654
        parents = graph.get_parent_map([r1])
 
655
        self.assertEqual({r1: (NULL_REVISION,)}, parents)
 
656
        self.assertEqual(
 
657
            [('call_with_body_bytes_expecting_body',
 
658
              'Repository.get_parent_map', ('quack/', r2), '\n\n0')],
 
659
            client._calls)
 
660
        repo.unlock()
 
661
        # now we call again, and it should use the second response.
 
662
        repo.lock_read()
 
663
        graph = repo.get_graph()
 
664
        parents = graph.get_parent_map([r1])
 
665
        self.assertEqual({r1: (NULL_REVISION,)}, parents)
 
666
        self.assertEqual(
 
667
            [('call_with_body_bytes_expecting_body',
 
668
              'Repository.get_parent_map', ('quack/', r2), '\n\n0'),
 
669
             ('call_with_body_bytes_expecting_body',
 
670
              'Repository.get_parent_map', ('quack/', r1), '\n\n0'),
 
671
            ],
 
672
            client._calls)
 
673
        repo.unlock()
 
674
 
 
675
    def test_get_parent_map_reconnects_if_unknown_method(self):
 
676
        error_msg = (
 
677
            "Generic bzr smart protocol error: "
 
678
            "bad request 'Repository.get_parent_map'")
 
679
        responses = [
 
680
            (('error', error_msg), ''),
 
681
            (('ok',), '')]
 
682
        transport_path = 'quack'
 
683
        repo, client = self.setup_fake_client_and_repository(
 
684
            responses, transport_path)
 
685
        rev_id = 'revision-id'
 
686
        parents = repo.get_parent_map([rev_id])
 
687
        self.assertEqual(
 
688
            [('call_with_body_bytes_expecting_body',
 
689
              'Repository.get_parent_map', ('quack/', rev_id), '\n\n0'),
 
690
             ('disconnect medium',),
 
691
             ('call_expecting_body', 'Repository.get_revision_graph',
 
692
              ('quack/', ''))],
 
693
            client._calls)
 
694
 
 
695
 
 
696
 
541
697
class TestRepositoryGetRevisionGraph(TestRemoteRepository):
542
698
    
543
699
    def test_null_revision(self):
565
721
        result = repo.get_revision_graph()
566
722
        self.assertEqual(
567
723
            [('call_expecting_body', 'Repository.get_revision_graph',
568
 
             ('///sinhala/', ''))],
 
724
             ('sinhala/', ''))],
569
725
            client._calls)
570
726
        self.assertEqual({r1: (), r2: (r1, )}, result)
571
727
 
585
741
        result = repo.get_revision_graph(r2)
586
742
        self.assertEqual(
587
743
            [('call_expecting_body', 'Repository.get_revision_graph',
588
 
             ('///sinhala/', r2))],
 
744
             ('sinhala/', r2))],
589
745
            client._calls)
590
746
        self.assertEqual({r11: (), r12: (), r2: (r11, r12), }, result)
591
747
 
600
756
            repo.get_revision_graph, revid)
601
757
        self.assertEqual(
602
758
            [('call_expecting_body', 'Repository.get_revision_graph',
603
 
             ('///sinhala/', revid))],
 
759
             ('sinhala/', revid))],
604
760
            client._calls)
605
761
 
606
762
        
614
770
            responses, transport_path)
615
771
        result = repo.is_shared()
616
772
        self.assertEqual(
617
 
            [('call', 'Repository.is_shared', ('///quack/',))],
 
773
            [('call', 'Repository.is_shared', ('quack/',))],
618
774
            client._calls)
619
775
        self.assertEqual(True, result)
620
776
 
626
782
            responses, transport_path)
627
783
        result = repo.is_shared()
628
784
        self.assertEqual(
629
 
            [('call', 'Repository.is_shared', ('///qwack/',))],
 
785
            [('call', 'Repository.is_shared', ('qwack/',))],
630
786
            client._calls)
631
787
        self.assertEqual(False, result)
632
788
 
640
796
            responses, transport_path)
641
797
        result = repo.lock_write()
642
798
        self.assertEqual(
643
 
            [('call', 'Repository.lock_write', ('///quack/', ''))],
 
799
            [('call', 'Repository.lock_write', ('quack/', ''))],
644
800
            client._calls)
645
801
        self.assertEqual('a token', result)
646
802
 
651
807
            responses, transport_path)
652
808
        self.assertRaises(errors.LockContention, repo.lock_write)
653
809
        self.assertEqual(
654
 
            [('call', 'Repository.lock_write', ('///quack/', ''))],
 
810
            [('call', 'Repository.lock_write', ('quack/', ''))],
655
811
            client._calls)
656
812
 
657
813
    def test_lock_write_unlockable(self):
661
817
            responses, transport_path)
662
818
        self.assertRaises(errors.UnlockableTransport, repo.lock_write)
663
819
        self.assertEqual(
664
 
            [('call', 'Repository.lock_write', ('///quack/', ''))],
 
820
            [('call', 'Repository.lock_write', ('quack/', ''))],
665
821
            client._calls)
666
822
 
667
823
 
676
832
        repo.lock_write()
677
833
        repo.unlock()
678
834
        self.assertEqual(
679
 
            [('call', 'Repository.lock_write', ('///quack/', '')),
680
 
             ('call', 'Repository.unlock', ('///quack/', 'a token'))],
 
835
            [('call', 'Repository.lock_write', ('quack/', '')),
 
836
             ('call', 'Repository.unlock', ('quack/', 'a token'))],
681
837
            client._calls)
682
838
 
683
839
    def test_unlock_wrong_token(self):
701
857
            responses, transport_path)
702
858
 
703
859
        # The null revision is always there, so has_revision(None) == True.
704
 
        self.assertEqual(True, repo.has_revision(None))
 
860
        self.assertEqual(True, repo.has_revision(NULL_REVISION))
705
861
 
706
862
        # The remote repo shouldn't be accessed.
707
863
        self.assertEqual([], client._calls)
731
887
        expected_responses = [(('ok',), self.tarball_content),
732
888
            ]
733
889
        expected_calls = [('call_expecting_body', 'Repository.tarball',
734
 
                           ('///repo/', 'bz2',),),
 
890
                           ('repo/', 'bz2',),),
735
891
            ]
736
892
        remote_repo, client = self.setup_fake_client_and_repository(
737
893
            expected_responses, transport_path)
775
931
        pack_file.seek(0)
776
932
        return pack_file
777
933
 
 
934
    def make_pack_stream(self, records):
 
935
        pack_serialiser = pack.ContainerSerialiser()
 
936
        yield pack_serialiser.begin()
 
937
        for bytes, names in records:
 
938
            yield pack_serialiser.bytes_record(bytes, names)
 
939
        yield pack_serialiser.end()
 
940
 
778
941
    def test_bad_pack_from_server(self):
779
942
        """A response with invalid data (e.g. it has a record with multiple
780
943
        names) triggers an exception.
783
946
        malformed data should be.
784
947
        """
785
948
        record = ('bytes', [('name1',), ('name2',)])
786
 
        pack_file = self.make_pack_file([record])
787
 
        responses = [(('ok',), pack_file.getvalue()), ]
 
949
        pack_stream = self.make_pack_stream([record])
 
950
        responses = [(('ok',), pack_stream), ]
788
951
        transport_path = 'quack'
789
952
        repo, client = self.setup_fake_client_and_repository(
790
953
            responses, transport_path)
791
 
        stream = repo.get_data_stream(['revid'])
 
954
        search = graph.SearchResult(set(['revid']), set(), 1, set(['revid']))
 
955
        stream = repo.get_data_stream_for_search(search)
792
956
        self.assertRaises(errors.SmartProtocolError, list, stream)
793
957
    
794
958
    def test_backwards_compatibility(self):
795
959
        """If the server doesn't recognise this request, fallback to VFS."""
796
960
        error_msg = (
797
961
            "Generic bzr smart protocol error: "
798
 
            "bad request 'Repository.stream_knit_data_for_revisions'")
 
962
            "bad request 'Repository.stream_revisions_chunked'")
799
963
        responses = [
800
964
            (('error', error_msg), '')]
801
965
        repo, client = self.setup_fake_client_and_repository(
802
966
            responses, 'path')
803
967
        self.mock_called = False
804
968
        repo._real_repository = MockRealRepository(self)
805
 
        repo.get_data_stream(['revid'])
 
969
        search = graph.SearchResult(set(['revid']), set(), 1, set(['revid']))
 
970
        repo.get_data_stream_for_search(search)
806
971
        self.assertTrue(self.mock_called)
807
972
        self.failIf(client.expecting_body,
808
973
            "The protocol has been left in an unclean state that will cause "
815
980
    def __init__(self, test):
816
981
        self.test = test
817
982
 
818
 
    def get_data_stream(self, revision_ids):
819
 
        self.test.assertEqual(['revid'], revision_ids)
 
983
    def get_data_stream_for_search(self, search):
 
984
        self.test.assertEqual(set(['revid']), search.get_keys())
820
985
        self.test.mock_called = True
821
986
 
822
987