~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_http_response.py

Merge and cleanup pre-external-reference-repository tests

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
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 from HTTP response parsing.
18
18
 
96
96
        # Override the thresold to force the warning emission
97
97
        conn._range_warning_thresold = 6 # There are 7 bytes pending
98
98
        conn.cleanup_pipe()
99
 
        self.assertContainsRe(self.get_log(), 'Got a 200 response when asking')
 
99
        self.assertContainsRe(self._get_log(keep_log_file=True),
 
100
                              'Got a 200 response when asking')
100
101
 
101
102
 
102
103
class TestRangeFileMixin(object):
224
225
        self.assertEquals('', f.read(0))
225
226
        self.assertEquals('', f.read(1))
226
227
 
227
 
 
228
228
class TestRangeFileSizeKnown(tests.TestCase, TestRangeFileMixin):
229
229
    """Test a RangeFile for a whole file whose size is known."""
230
230
 
253
253
        f._pos = 0 # Force an invalid pos
254
254
        self.assertRaises(errors.InvalidRange, f.read, 2)
255
255
 
256
 
 
257
256
class TestRangeFileMultipleRanges(tests.TestCase, TestRangeFileMixin):
258
257
    """Test a RangeFile for multiple ranges.
259
258
 
267
266
    fact) in real uses but may lead to hard to track bugs.
268
267
    """
269
268
 
270
 
    # The following is used to represent the boundary paramter defined
271
 
    # in HTTP response headers and the boundary lines that separate
272
 
    # multipart content.
273
 
 
274
 
    boundary = "separation"
275
 
 
276
269
    def setUp(self):
277
270
        super(TestRangeFileMultipleRanges, self).setUp()
278
271
 
279
 
        boundary = self.boundary
 
272
        boundary = 'separation'
280
273
 
281
274
        content = ''
282
275
        self.first_range_start = 25
288
281
            content += self._multipart_byterange(part, start, boundary,
289
282
                                                 file_size)
290
283
        # Final boundary
291
 
        content += self._boundary_line()
 
284
        content += self._boundary_line(boundary)
292
285
 
293
286
        self._file = response.RangeFile('Multiple_ranges_file',
294
287
                                        StringIO(content))
295
 
        self.set_file_boundary()
296
 
 
297
 
    def _boundary_line(self):
298
 
        """Helper to build the formatted boundary line."""
299
 
        return '--' + self.boundary + '\r\n'
300
 
 
301
 
    def set_file_boundary(self):
302
288
        # Ranges are set by decoding the range headers, the RangeFile user is
303
289
        # supposed to call the following before using seek or read since it
304
290
        # requires knowing the *response* headers (in that case the boundary
305
291
        # which is part of the Content-Type header).
306
 
        self._file.set_boundary(self.boundary)
 
292
        self._file.set_boundary(boundary)
 
293
 
 
294
    def _boundary_line(self, boundary):
 
295
        """Helper to build the formatted boundary line."""
 
296
        return '--' + boundary + '\r\n'
307
297
 
308
298
    def _multipart_byterange(self, data, offset, boundary, file_size='*'):
309
299
        """Encode a part of a file as a multipart/byterange MIME type.
321
311
        :return: a string containing the data encoded as it will appear in the
322
312
            HTTP response body.
323
313
        """
324
 
        bline = self._boundary_line()
 
314
        bline = self._boundary_line(boundary)
325
315
        # Each range begins with a boundary line
326
316
        range = bline
327
317
        # A range is described by a set of headers, but only 'Content-Range' is
405
395
        self.assertRaises(errors.InvalidHttpResponse, f.read, 1)
406
396
 
407
397
 
408
 
class TestRangeFileMultipleRangesQuotedBoundaries(TestRangeFileMultipleRanges):
409
 
    """Perform the same tests as TestRangeFileMultipleRanges, but uses
410
 
    an angle-bracket quoted boundary string like IIS 6.0 and 7.0
411
 
    (but not IIS 5, which breaks the RFC in a different way
412
 
    by using square brackets, not angle brackets)
413
 
 
414
 
    This reveals a bug caused by
415
 
 
416
 
    - The bad implementation of RFC 822 unquoting in Python (angles are not
417
 
      quotes), coupled with
418
 
 
419
 
    - The bad implementation of RFC 2046 in IIS (angles are not permitted chars
420
 
      in boundary lines).
421
 
 
422
 
    """
423
 
    # The boundary as it appears in boundary lines
424
 
    # IIS 6 and 7 use this value
425
 
    _boundary_trimmed = "q1w2e3r4t5y6u7i8o9p0zaxscdvfbgnhmjklkl"
426
 
    boundary = '<' + _boundary_trimmed + '>'
427
 
 
428
 
    def set_file_boundary(self):
429
 
        # Emulate broken rfc822.unquote() here by removing angles
430
 
        self._file.set_boundary(self._boundary_trimmed)
431
 
 
432
 
 
433
398
class TestRangeFileVarious(tests.TestCase):
434
399
    """Tests RangeFile aspects not covered elsewhere."""
435
400
 
800
765
    """
801
766
 
802
767
    def setUp(self):
803
 
        tests.TestCase.setUp(self)
804
768
        # create a test datablock larger than _max_read_size.
805
769
        chunk_size = response.RangeFile._max_read_size
806
770
        test_pattern = '0123456789ABCDEF'