~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart_transport.py

  • Committer: Robert Collins
  • Date: 2006-09-17 23:05:02 UTC
  • mto: This revision was merged to the branch mainline in revision 2020.
  • Revision ID: robertc@robertcollins.net-20060917230502-20d52dba45fc2077
Rearrange the readv patch to put the serialise offsets method into the correct class, and document the structure of the classes somewhat better to hint to people writing patches where code should go. Also alter the test so that the client and server components are tested in one place preventing possible encoding skew from occuring.

Show diffs side-by-side

added added

removed removed

Lines of Context:
124
124
        returncode = child.wait()
125
125
        self.assertEquals(0, returncode)
126
126
 
127
 
    def test_serialize_offsets(self):
128
 
        def check(expected, offsets):
129
 
            value = smart.SmartTransport._serialise_offsets(offsets)
130
 
            self.assertEqual(expected, value)
131
 
 
132
 
        check('1,2', [(1,2)])
133
 
        check('1,2\n3,4', [(1,2), (3,4)])
134
 
        check('1,2\n3,4\n100,200', [(1,2), (3,4), (100, 200)])
135
 
 
136
 
    def test_deserialise_offsets(self):
137
 
        def check(expected, text):
138
 
            offsets = smart.SmartServer._deserialise_offsets(text)
139
 
            self.assertEqual(expected, offsets)
140
 
 
141
 
        check([(1,2)], '1,2')
142
 
        check([(1,2), (3,4)], '1,2\n3,4')
143
 
        check([(1,2), (3,4), (100, 200)], '1,2\n3,4\n100,200')
144
 
 
145
127
 
146
128
class SmartTCPTests(tests.TestCase):
147
129
    """Tests for connection to TCP server.
294
276
        self.assertEqual([('_call', ('get', '/foo'))], client._calls)
295
277
 
296
278
 
 
279
class InstrumentedClient(smart.SmartStreamClient):
 
280
    """A smart client whose writes are stored to a supplied list."""
 
281
 
 
282
    def __init__(self, write_output_list):
 
283
        smart.SmartStreamClient.__init__(self, None)
 
284
        self._write_output_list = write_output_list
 
285
 
 
286
    def _ensure_connection(self):
 
287
        """We are never strictly connected."""
 
288
 
 
289
    def _write_and_flush(self, bytes):
 
290
        self._write_output_list.append(bytes)
 
291
 
 
292
 
 
293
class InstrumentedServerProtocol(smart.SmartStreamServer):
 
294
    """A smart server which is backed by memory and saves its write requests."""
 
295
 
 
296
    def __init__(self, write_output_list):
 
297
        smart.SmartStreamServer.__init__(self, None, None,
 
298
            memory.MemoryTransport())
 
299
        self._write_output_list = write_output_list
 
300
 
 
301
    def _write_and_flush(self, bytes):
 
302
        self._write_output_list.append(bytes)
 
303
 
 
304
 
 
305
class TestSmartProtocol(tests.TestCase):
 
306
    """Tests for the smart protocol.
 
307
 
 
308
    Each test case gets a smart_server and smart_client created during setUp().
 
309
 
 
310
    It is planned that the client can be called with self.call_client() giving
 
311
    it an expected server response, which will be fed into it when it tries to
 
312
    read. Likewise, self.call_server will call a servers method with a canned
 
313
    serialised client request. Output done by the client or server for these
 
314
    calls will be captured to self.to_server and self.to_client. Each element
 
315
    in the list is a write call from the client or server respectively.
 
316
    """
 
317
 
 
318
    def setUp(self):
 
319
        super(TestSmartProtocol, self).setUp()
 
320
        self.to_server = []
 
321
        self.to_client = []
 
322
        self.smart_client = InstrumentedClient(self.to_server)
 
323
        self.smart_server = InstrumentedServerProtocol(self.to_client)
 
324
 
 
325
    def assertOffsetSerialisation(self, expected_offsets, expected_serialised,
 
326
        client, server_protocol):
 
327
        """Check that smart (de)serialises offsets as expected.
 
328
        
 
329
        We check both serialisation and deserialisation at the same time
 
330
        to ensure that the round tripping cannot skew: both directions should
 
331
        be as expected.
 
332
        
 
333
        :param expected_offsets: a readv offset list.
 
334
        :param expected_seralised: an expected serial form of the offsets.
 
335
        :param server: a SmartServer instance.
 
336
        """
 
337
        offsets = server_protocol.smart_server._deserialise_offsets(
 
338
            expected_serialised)
 
339
        self.assertEqual(expected_offsets, offsets)
 
340
        serialised = client._serialise_offsets(offsets)
 
341
        self.assertEqual(expected_serialised, serialised)
 
342
 
 
343
    def test_server_offset_serialisation(self):
 
344
        """The Smart protocol serialises offsets as a comma and \n string.
 
345
 
 
346
        We check a number of boundary cases are as expected: empty, one offset,
 
347
        one with the order of reads not increasing (an out of order read), and
 
348
        one that should coalesce.
 
349
        """
 
350
        self.assertOffsetSerialisation([], '',
 
351
            self.smart_client, self.smart_server)
 
352
        self.assertOffsetSerialisation([(1,2)], '1,2',
 
353
            self.smart_client, self.smart_server)
 
354
        self.assertOffsetSerialisation([(10,40), (0,5)], '10,40\n0,5',
 
355
            self.smart_client, self.smart_server)
 
356
        self.assertOffsetSerialisation([(1,2), (3,4), (100, 200)],
 
357
            '1,2\n3,4\n100,200', self.smart_client, self.smart_server)
 
358
 
 
359
 
297
360
# TODO: Client feature that does get_bundle and then installs that into a
298
361
# branch; this can be used in place of the regular pull/fetch operation when
299
362
# coming from a smart server.