diff --git a/gcloud/_apitools/stream_slice.py b/gcloud/_apitools/stream_slice.py index 3f202f6628b9..9cbde994d77f 100644 --- a/gcloud/_apitools/stream_slice.py +++ b/gcloud/_apitools/stream_slice.py @@ -9,26 +9,26 @@ class StreamSlice(object): """Provides a slice-like object for streams.""" def __init__(self, stream, max_bytes): - self.__stream = stream - self.__remaining_bytes = max_bytes - self.__max_bytes = max_bytes + self._stream = stream + self._remaining_bytes = max_bytes + self._max_bytes = max_bytes - def __str__(self): + def __repr__(self): return 'Slice of stream %s with %s/%s bytes not yet read' % ( - self.__stream, self.__remaining_bytes, self.__max_bytes) + self._stream, self._remaining_bytes, self._max_bytes) def __len__(self): - return self.__max_bytes + return self._max_bytes def __nonzero__(self): # For 32-bit python2.x, len() cannot exceed a 32-bit number; avoid # accidental len() calls from httplib in the form of "if this_object:". - return bool(self.__max_bytes) + return bool(self._max_bytes) @property def length(self): # For 32-bit python2.x, len() cannot exceed a 32-bit number. - return self.__max_bytes + return self._max_bytes def read(self, size=None): # pylint: disable=missing-docstring """Read at most size bytes from this slice. @@ -50,15 +50,15 @@ def read(self, size=None): # pylint: disable=missing-docstring """ if size is not None: - read_size = min(size, self.__remaining_bytes) + read_size = min(size, self._remaining_bytes) else: - read_size = self.__remaining_bytes - data = self.__stream.read(read_size) + read_size = self._remaining_bytes + data = self._stream.read(read_size) if read_size > 0 and not data: raise exceptions.StreamExhausted( 'Not enough bytes in stream; expected %d, exhausted ' 'after %d' % ( - self.__max_bytes, - self.__max_bytes - self.__remaining_bytes)) - self.__remaining_bytes -= len(data) + self._max_bytes, + self._max_bytes - self._remaining_bytes)) + self._remaining_bytes -= len(data) return data diff --git a/gcloud/_apitools/test_stream_slice.py b/gcloud/_apitools/test_stream_slice.py new file mode 100644 index 000000000000..7deee2d89f78 --- /dev/null +++ b/gcloud/_apitools/test_stream_slice.py @@ -0,0 +1,69 @@ +# pylint: skip-file +import unittest2 + + +class Test_StreamSlice(unittest2.TestCase): + + def _getTargetClass(self): + from gcloud._apitools.stream_slice import StreamSlice + return StreamSlice + + def _makeOne(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def test_ctor(self): + from io import BytesIO + CONTENT = b'CONTENT GOES HERE' + MAXSIZE = 4 + stream = BytesIO(CONTENT) + stream_slice = self._makeOne(stream, MAXSIZE) + self.assertTrue(stream_slice._stream is stream) + self.assertEqual(stream_slice._remaining_bytes, MAXSIZE) + self.assertEqual(stream_slice._max_bytes, MAXSIZE) + self.assertEqual(len(stream_slice), MAXSIZE) + self.assertEqual(stream_slice.length, MAXSIZE) + + def test___nonzero___empty(self): + from io import BytesIO + CONTENT = b'' + MAXSIZE = 0 + stream = BytesIO(CONTENT) + stream_slice = self._makeOne(stream, MAXSIZE) + self.assertFalse(stream_slice) + + def test___nonzero___nonempty(self): + from io import BytesIO + CONTENT = b'CONTENT GOES HERE' + MAXSIZE = 4 + stream = BytesIO(CONTENT) + stream_slice = self._makeOne(stream, MAXSIZE) + self.assertTrue(stream_slice) + + def test_read_exhausted(self): + from io import BytesIO + from gcloud._apitools.exceptions import StreamExhausted + CONTENT = b'' + MAXSIZE = 4 + stream = BytesIO(CONTENT) + stream_slice = self._makeOne(stream, MAXSIZE) + with self.assertRaises(StreamExhausted): + stream_slice.read() + + def test_read_implicit_size(self): + from io import BytesIO + CONTENT = b'CONTENT GOES HERE' + MAXSIZE = 4 + stream = BytesIO(CONTENT) + stream_slice = self._makeOne(stream, MAXSIZE) + self.assertEqual(stream_slice.read(), CONTENT[:MAXSIZE]) + self.assertEqual(stream_slice._remaining_bytes, 0) + + def test_read_explicit_size(self): + from io import BytesIO + CONTENT = b'CONTENT GOES HERE' + MAXSIZE = 4 + SIZE = 3 + stream = BytesIO(CONTENT) + stream_slice = self._makeOne(stream, MAXSIZE) + self.assertEqual(stream_slice.read(SIZE), CONTENT[:SIZE]) + self.assertEqual(stream_slice._remaining_bytes, MAXSIZE - SIZE)