2020-10-12 09:26:43 -05:00
|
|
|
import errno
|
|
|
|
|
import os
|
|
|
|
|
import unittest
|
|
|
|
|
from unittest.mock import ANY, call, NonCallableMagicMock, patch
|
|
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
from test_utils import MockSock, MockFile, MockException, ZEN, SuperMock
|
2020-10-12 09:26:43 -05:00
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
from paasio import MeteredFile, MeteredSocket
|
2020-10-12 09:26:43 -05:00
|
|
|
|
2021-02-08 17:51:59 -05:00
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
class PaasioTest(unittest.TestCase):
|
|
|
|
|
def test_meteredsocket_context_manager(self):
|
2020-10-12 09:26:43 -05:00
|
|
|
wrapped = MockSock()
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
mock.__exit__.side_effect = wrapped.__exit__
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
self.assertFalse(mock.__enter__.called)
|
|
|
|
|
socket.recv(30)
|
|
|
|
|
self.assertFalse(mock.__enter__.called)
|
|
|
|
|
mock.__exit__.assert_called_once_with(None, None, None)
|
|
|
|
|
self.assertEqual(2, len(mock.mock_calls))
|
|
|
|
|
with self.assertRaisesRegex(OSError, os.strerror(errno.EBADF)):
|
|
|
|
|
socket.recv(30)
|
|
|
|
|
with self.assertRaisesRegex(OSError, os.strerror(errno.EBADF)):
|
|
|
|
|
socket.send(b"")
|
|
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
def test_meteredsocket_context_manager_exception_raise(self):
|
2020-10-12 09:26:43 -05:00
|
|
|
exception = MockException("Should raise")
|
|
|
|
|
wrapped = MockSock(exception=exception)
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
mock.__exit__.side_effect = wrapped.__exit__
|
|
|
|
|
with self.assertRaisesRegex(MockException, "Should raise") as err:
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
self.assertFalse(mock.__enter__.called)
|
|
|
|
|
socket.recv(4096)
|
|
|
|
|
self.assertFalse(mock.__enter__.called)
|
|
|
|
|
mock.__exit__.assert_called_once_with(
|
2021-02-08 17:51:59 -05:00
|
|
|
MockException,
|
|
|
|
|
err.exception,
|
|
|
|
|
ANY,
|
2020-10-12 09:26:43 -05:00
|
|
|
)
|
|
|
|
|
self.assertEqual(exception, err.exception)
|
|
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
def test_meteredsocket_context_manager_exception_suppress(self):
|
2020-10-12 09:26:43 -05:00
|
|
|
exception = MockException("Should suppress")
|
|
|
|
|
wrapped = MockSock(exception=exception)
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
mock.__exit__.side_effect = wrapped.__exit__
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
self.assertFalse(mock.__enter__.called)
|
|
|
|
|
socket.recv(4096)
|
|
|
|
|
self.assertFalse(mock.__enter__.called)
|
|
|
|
|
mock.__exit__.assert_called_once_with(
|
2021-02-08 17:51:59 -05:00
|
|
|
MockException,
|
|
|
|
|
exception,
|
|
|
|
|
ANY,
|
2020-10-12 09:26:43 -05:00
|
|
|
)
|
|
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
def test_meteredsocket_recv_once(self):
|
2020-10-12 09:26:43 -05:00
|
|
|
mock = NonCallableMagicMock(wraps=MockSock(), autospec=True)
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
actual_recv = socket.recv(4096)
|
|
|
|
|
self.assertEqual(ZEN, actual_recv)
|
|
|
|
|
self.assertEqual(1, socket.recv_ops)
|
|
|
|
|
self.assertEqual(len(ZEN), socket.recv_bytes)
|
|
|
|
|
self.assertEqual(1, mock.recv.call_count)
|
|
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
def test_meteredsocket_recv_multiple(self):
|
2020-10-12 09:26:43 -05:00
|
|
|
wrapped = MockSock()
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
actual_recv = b""
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
for _ in range(5):
|
|
|
|
|
actual_recv += socket.recv(30)
|
|
|
|
|
self.assertEqual(ZEN[:150], actual_recv)
|
|
|
|
|
self.assertEqual(5, socket.recv_ops)
|
|
|
|
|
self.assertEqual(150, socket.recv_bytes)
|
|
|
|
|
self.assertEqual(5, mock.recv.call_count)
|
|
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
def test_meteredsocket_recv_multiple_chunk(self):
|
2020-10-12 09:26:43 -05:00
|
|
|
wrapped = MockSock(chunk=20)
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
actual_recv = b""
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
for _ in range(5):
|
|
|
|
|
actual_recv += socket.recv(4096)
|
|
|
|
|
actual_recv += socket.recv(10)
|
|
|
|
|
self.assertEqual(ZEN[:110], actual_recv)
|
|
|
|
|
self.assertEqual(6, socket.recv_ops)
|
|
|
|
|
self.assertEqual(110, socket.recv_bytes)
|
|
|
|
|
self.assertEqual(6, mock.recv.call_count)
|
|
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
def test_meteredsocket_recv_under_size(self):
|
2020-10-12 09:26:43 -05:00
|
|
|
wrapped = MockSock(chunk=257) # largish odd number
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
actual_recv = socket.recv(4096)
|
|
|
|
|
self.assertEqual(ZEN[:257], actual_recv)
|
|
|
|
|
self.assertEqual(1, socket.recv_ops)
|
|
|
|
|
self.assertEqual(257, socket.recv_bytes)
|
|
|
|
|
self.assertEqual(1, mock.recv.call_count)
|
|
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
def test_meteredsocket_send_once(self):
|
2020-10-12 09:26:43 -05:00
|
|
|
wrapped = MockSock(chunk=257) # largish odd number
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
send_len = socket.send(ZEN)
|
|
|
|
|
self.assertEqual(ZEN[:257], wrapped._sender.getbuffer())
|
|
|
|
|
self.assertEqual(257, send_len)
|
|
|
|
|
self.assertEqual(1, socket.send_ops)
|
|
|
|
|
self.assertEqual(257, socket.send_bytes)
|
|
|
|
|
self.assertEqual(1, mock.send.call_count)
|
|
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
def test_meteredsocket_send_multiple(self):
|
2020-10-12 09:26:43 -05:00
|
|
|
wrapped = MockSock()
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
send_len = 0
|
|
|
|
|
expected = b"Tomorrow's victory is today's practice."
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
send_len += socket.send(b"Tomorro")
|
|
|
|
|
send_len += socket.send(b"w's victo")
|
|
|
|
|
send_len += socket.send(b"ry is today")
|
|
|
|
|
send_len += socket.send(b"'s practice.")
|
|
|
|
|
self.assertEqual(expected, wrapped._sender.getbuffer())
|
|
|
|
|
self.assertEqual(39, send_len)
|
|
|
|
|
self.assertEqual(4, socket.send_ops)
|
|
|
|
|
self.assertEqual(39, socket.send_bytes)
|
|
|
|
|
self.assertEqual(4, mock.send.call_count)
|
|
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
def test_meteredsocket_send_under_size(self):
|
2020-10-12 09:26:43 -05:00
|
|
|
wrapped = MockSock(chunk=257) # largish odd number
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
send_len = socket.send(ZEN[:123])
|
|
|
|
|
self.assertEqual(ZEN[:123], wrapped._sender.getbuffer())
|
|
|
|
|
self.assertEqual(123, send_len)
|
|
|
|
|
self.assertEqual(1, socket.send_ops)
|
|
|
|
|
self.assertEqual(123, socket.send_bytes)
|
|
|
|
|
self.assertEqual(1, mock.send.call_count)
|
|
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
def test_meteredsocket_bufsize_required(self):
|
2020-10-12 09:26:43 -05:00
|
|
|
mock = NonCallableMagicMock(wraps=MockSock(), autospec=True)
|
|
|
|
|
with self.assertRaisesRegex(TypeError, "argument"):
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
socket.recv()
|
|
|
|
|
self.assertFalse(mock.recv.called)
|
|
|
|
|
|
|
|
|
|
mock = NonCallableMagicMock(wraps=MockSock(), autospec=True)
|
|
|
|
|
with self.assertRaisesRegex(TypeError, "^'NoneType'.+integer$"):
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
socket.recv(None)
|
|
|
|
|
self.assertTrue(
|
|
|
|
|
call(None) in mock.recv.mock_calls
|
|
|
|
|
or call(None, ANY) in mock.recv.mock_calls
|
|
|
|
|
)
|
|
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
def test_meteredsocket_flags_support(self):
|
2020-10-12 09:26:43 -05:00
|
|
|
mock = NonCallableMagicMock(wraps=MockSock(), autospec=True)
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
self.assertEqual(len(ZEN), socket.send(ZEN, 42))
|
|
|
|
|
self.assertEqual(ZEN, socket.recv(4096, 24))
|
|
|
|
|
mock.send.assert_called_once_with(ZEN, 42)
|
|
|
|
|
mock.recv.assert_called_once_with(4096, 24)
|
|
|
|
|
|
|
|
|
|
wrapped = MockSock()
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
socket.recv(50)
|
|
|
|
|
self.assertEqual(0, wrapped.flags)
|
|
|
|
|
socket.send(b"no flags")
|
|
|
|
|
self.assertEqual(0, wrapped.flags)
|
|
|
|
|
socket.recv(30, 30)
|
|
|
|
|
self.assertEqual(30, wrapped.flags)
|
|
|
|
|
socket.send(b"flags", 1024)
|
|
|
|
|
self.assertEqual(1024, wrapped.flags)
|
|
|
|
|
with self.assertRaisesRegex(TypeError, "integer is required"):
|
|
|
|
|
socket.send(b"data", None)
|
|
|
|
|
with self.assertRaisesRegex(TypeError, "integer is required"):
|
|
|
|
|
socket.send(b"data", b"flags")
|
|
|
|
|
with self.assertRaisesRegex(TypeError, "integer is required"):
|
|
|
|
|
socket.recv(b"data", None)
|
|
|
|
|
with self.assertRaisesRegex(TypeError, "integer is required"):
|
|
|
|
|
socket.recv(b"data", b"flags")
|
|
|
|
|
|
2021-02-06 17:12:26 -05:00
|
|
|
def test_meteredsocket_stats_read_only(self):
|
2020-10-12 09:26:43 -05:00
|
|
|
mock = NonCallableMagicMock(wraps=MockSock(), autospec=True)
|
|
|
|
|
with MeteredSocket(mock) as socket:
|
|
|
|
|
self.assertEqual(0, socket.send_ops)
|
|
|
|
|
self.assertEqual(0, socket.send_bytes)
|
|
|
|
|
self.assertEqual(0, socket.recv_ops)
|
|
|
|
|
self.assertEqual(0, socket.recv_bytes)
|
|
|
|
|
for _ in range(277):
|
|
|
|
|
socket.send(b"b")
|
|
|
|
|
socket.send(b"bytes")
|
|
|
|
|
for _ in range(257):
|
|
|
|
|
socket.recv(1)
|
|
|
|
|
socket.recv(2)
|
|
|
|
|
self.assertEqual(278, socket.send_ops)
|
|
|
|
|
self.assertEqual(282, socket.send_bytes)
|
|
|
|
|
self.assertEqual(258, socket.recv_ops)
|
|
|
|
|
self.assertEqual(259, socket.recv_bytes)
|
|
|
|
|
with self.assertRaisesRegex(AttributeError, "can't set"):
|
|
|
|
|
socket.send_ops = 0
|
|
|
|
|
with self.assertRaisesRegex(AttributeError, "can't set"):
|
|
|
|
|
socket.send_bytes = 0
|
|
|
|
|
with self.assertRaisesRegex(AttributeError, "can't set"):
|
|
|
|
|
socket.recv_ops = 0
|
|
|
|
|
with self.assertRaisesRegex(AttributeError, "can't set"):
|
|
|
|
|
socket.recv_bytes = 0
|
|
|
|
|
self.assertEqual(278, socket.send_ops)
|
|
|
|
|
self.assertEqual(282, socket.send_bytes)
|
|
|
|
|
self.assertEqual(258, socket.recv_ops)
|
|
|
|
|
self.assertEqual(259, socket.recv_bytes)
|
|
|
|
|
|
2021-02-08 17:42:00 -05:00
|
|
|
@patch("paasio.super", create=True, new_callable=SuperMock)
|
|
|
|
|
def test_meteredfile_context_manager(self, super_mock):
|
|
|
|
|
wrapped = MockFile(ZEN)
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
mock.__exit__.side_effect = wrapped.__exit__
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
with MeteredFile() as file:
|
|
|
|
|
self.assertEqual(1, super_mock.init_called)
|
|
|
|
|
self.assertFalse(mock.__enter__.called)
|
|
|
|
|
file.read()
|
|
|
|
|
self.assertFalse(mock.__enter__.called)
|
|
|
|
|
mock.__exit__.assert_called_once_with(None, None, None)
|
|
|
|
|
self.assertEqual(2, len(mock.mock_calls))
|
2021-02-08 17:51:59 -05:00
|
|
|
with self.assertRaisesRegex(ValueError, "I/O operation on closed file."):
|
2021-02-08 17:42:00 -05:00
|
|
|
file.read()
|
2021-02-08 17:51:59 -05:00
|
|
|
with self.assertRaisesRegex(ValueError, "I/O operation on closed file."):
|
2021-02-08 17:42:00 -05:00
|
|
|
file.write(b"data")
|
2021-02-08 17:51:59 -05:00
|
|
|
|
2021-02-08 17:42:00 -05:00
|
|
|
@patch("paasio.super", create=True, new_callable=SuperMock)
|
|
|
|
|
def test_meteredfile_context_manager_exception_raise(self, super_mock):
|
|
|
|
|
exception = MockException("Should raise")
|
|
|
|
|
wrapped = MockFile(ZEN, exception=exception)
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
mock.__exit__.side_effect = wrapped.__exit__
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
with self.assertRaisesRegex(MockException, "Should raise") as err:
|
|
|
|
|
with MeteredFile() as file:
|
|
|
|
|
self.assertFalse(mock.__enter__.called)
|
|
|
|
|
file.read()
|
|
|
|
|
self.assertFalse(mock.__enter__.called)
|
|
|
|
|
mock.__exit__.assert_called_once_with(
|
2021-02-08 17:51:59 -05:00
|
|
|
MockException,
|
|
|
|
|
err.exception,
|
|
|
|
|
ANY,
|
2021-02-08 17:42:00 -05:00
|
|
|
)
|
|
|
|
|
self.assertEqual(exception, err.exception)
|
2021-02-08 17:51:59 -05:00
|
|
|
|
2021-02-08 17:42:00 -05:00
|
|
|
@patch("paasio.super", create=True, new_callable=SuperMock)
|
|
|
|
|
def test_meteredfile_context_manager_exception_suppress(self, super_mock):
|
|
|
|
|
exception = MockException("Should suppress")
|
|
|
|
|
wrapped = MockFile(ZEN, exception=exception)
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
mock.__exit__.side_effect = wrapped.__exit__
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
with MeteredFile() as file:
|
|
|
|
|
self.assertFalse(mock.__enter__.called)
|
|
|
|
|
file.read()
|
|
|
|
|
self.assertFalse(mock.__enter__.called)
|
|
|
|
|
mock.__exit__.assert_called_once_with(
|
2021-02-08 17:51:59 -05:00
|
|
|
MockException,
|
|
|
|
|
exception,
|
|
|
|
|
ANY,
|
2021-02-08 17:42:00 -05:00
|
|
|
)
|
2021-02-08 17:51:59 -05:00
|
|
|
|
2021-02-08 17:42:00 -05:00
|
|
|
@patch("paasio.super", create=True, new_callable=SuperMock)
|
|
|
|
|
def test_meteredfile_iteration(self, super_mock):
|
|
|
|
|
mock = NonCallableMagicMock(wraps=MockFile(ZEN), autospec=True)
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
actual_reads = b""
|
|
|
|
|
file = MeteredFile()
|
|
|
|
|
for line in file:
|
|
|
|
|
actual_reads += line
|
2021-02-08 17:51:59 -05:00
|
|
|
self.assertLess(0, mock.readline.call_count, "File's readline not called")
|
2021-02-08 17:42:00 -05:00
|
|
|
self.assertGreater(
|
|
|
|
|
50, mock.readline.call_count, "Possible infinte loop detected"
|
|
|
|
|
)
|
|
|
|
|
self.assertEqual(file.read_ops, mock.readline.call_count)
|
|
|
|
|
self.assertFalse(mock.__iter__.called)
|
|
|
|
|
self.assertEqual(len(ZEN), file.read_bytes)
|
|
|
|
|
self.assertEqual(ZEN, actual_reads)
|
2021-02-08 17:51:59 -05:00
|
|
|
|
2021-02-08 17:42:00 -05:00
|
|
|
@patch("paasio.super", create=True, new_callable=SuperMock)
|
|
|
|
|
def test_meteredfile_read_once(self, super_mock):
|
|
|
|
|
mock = NonCallableMagicMock(wraps=MockFile(ZEN), autospec=True)
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
with MeteredFile() as file:
|
|
|
|
|
actual_read = file.read()
|
|
|
|
|
self.assertEqual(ZEN, actual_read)
|
|
|
|
|
self.assertEqual((len(ZEN)), file.read_bytes)
|
|
|
|
|
self.assertEqual(1, file.read_ops)
|
|
|
|
|
self.assertEqual(mock.read.call_count, file.read_ops)
|
|
|
|
|
mock = NonCallableMagicMock(wraps=MockFile(ZEN), autospec=True)
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
with MeteredFile() as file:
|
|
|
|
|
actual_read = file.read(None)
|
|
|
|
|
self.assertEqual(ZEN, actual_read)
|
|
|
|
|
self.assertEqual((len(ZEN)), file.read_bytes)
|
|
|
|
|
self.assertEqual(1, file.read_ops)
|
|
|
|
|
self.assertEqual(mock.read.call_count, file.read_ops)
|
|
|
|
|
mock = NonCallableMagicMock(wraps=MockFile(ZEN), autospec=True)
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
with MeteredFile() as file:
|
|
|
|
|
actual_read = file.read(-1)
|
|
|
|
|
self.assertEqual(ZEN, actual_read)
|
|
|
|
|
self.assertEqual((len(ZEN)), file.read_bytes)
|
|
|
|
|
self.assertEqual(1, file.read_ops)
|
|
|
|
|
self.assertEqual(mock.read.call_count, file.read_ops)
|
2021-02-08 17:51:59 -05:00
|
|
|
|
2021-02-08 17:42:00 -05:00
|
|
|
@patch("paasio.super", create=True, new_callable=SuperMock)
|
|
|
|
|
def test_meteredfile_read_multiple(self, super_mock):
|
|
|
|
|
wrapped = MockFile(ZEN)
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
actual_read = b""
|
|
|
|
|
with MeteredFile() as file:
|
|
|
|
|
for _ in range(5):
|
|
|
|
|
actual_read += file.read(30)
|
|
|
|
|
self.assertEqual(ZEN[:150], actual_read)
|
|
|
|
|
self.assertEqual(5, file.read_ops)
|
|
|
|
|
self.assertEqual(150, file.read_bytes)
|
|
|
|
|
self.assertEqual(5, mock.read.call_count)
|
2021-02-08 17:51:59 -05:00
|
|
|
|
2021-02-08 17:42:00 -05:00
|
|
|
@patch("paasio.super", create=True, new_callable=SuperMock)
|
|
|
|
|
def test_meteredfile_read_multiple_chunk(self, super_mock):
|
|
|
|
|
wrapped = MockFile(ZEN, chunk=20)
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
actual_read = b""
|
|
|
|
|
with MeteredFile() as file:
|
|
|
|
|
for _ in range(5):
|
|
|
|
|
actual_read += file.read()
|
|
|
|
|
actual_read += file.read(10)
|
|
|
|
|
self.assertEqual(ZEN[:110], actual_read)
|
|
|
|
|
self.assertEqual(6, file.read_ops)
|
|
|
|
|
self.assertEqual(110, file.read_bytes)
|
|
|
|
|
self.assertEqual(6, mock.read.call_count)
|
|
|
|
|
wrapped = MockFile(ZEN, chunk=20)
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
actual_read = b""
|
|
|
|
|
with MeteredFile() as file:
|
|
|
|
|
for size in [None, -2, -1, 0, 1, 2]:
|
|
|
|
|
actual_read += file.read(size)
|
|
|
|
|
actual_read += file.read(10)
|
|
|
|
|
self.assertEqual(ZEN[:73], actual_read)
|
|
|
|
|
self.assertEqual(7, file.read_ops)
|
|
|
|
|
self.assertEqual(73, file.read_bytes)
|
|
|
|
|
self.assertEqual(7, mock.read.call_count)
|
2021-02-08 17:51:59 -05:00
|
|
|
|
2021-02-08 17:42:00 -05:00
|
|
|
@patch("paasio.super", create=True, new_callable=SuperMock)
|
|
|
|
|
def test_meteredfile_read_under_size(self, super_mock):
|
|
|
|
|
wrapped = MockFile(ZEN, chunk=257) # largish odd number
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
with MeteredFile() as file:
|
|
|
|
|
actual_read = file.read()
|
|
|
|
|
self.assertEqual(ZEN[:257], actual_read)
|
|
|
|
|
self.assertEqual(1, file.read_ops)
|
|
|
|
|
self.assertEqual(257, file.read_bytes)
|
|
|
|
|
self.assertEqual(1, mock.read.call_count)
|
2021-02-08 17:51:59 -05:00
|
|
|
|
2021-02-08 17:42:00 -05:00
|
|
|
@patch("paasio.super", create=True, new_callable=SuperMock)
|
|
|
|
|
def test_meteredfile_write_once(self, super_mock):
|
|
|
|
|
wrapped = MockFile(chunk=257) # largish odd number
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
with MeteredFile() as file:
|
|
|
|
|
write_len = file.write(ZEN)
|
|
|
|
|
self.assertEqual(ZEN[:257], wrapped.getbuffer())
|
|
|
|
|
self.assertEqual(257, write_len)
|
|
|
|
|
self.assertEqual(1, file.write_ops)
|
|
|
|
|
self.assertEqual(257, file.write_bytes)
|
|
|
|
|
self.assertEqual(1, mock.write.call_count)
|
2021-02-08 17:51:59 -05:00
|
|
|
|
2021-02-08 17:42:00 -05:00
|
|
|
@patch("paasio.super", create=True, new_callable=SuperMock)
|
|
|
|
|
def test_meteredfile_write_multiple(self, super_mock):
|
|
|
|
|
wrapped = MockFile()
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
write_len = 0
|
|
|
|
|
expected = b"Tomorrow's victory is today's practice."
|
|
|
|
|
with MeteredFile() as file:
|
|
|
|
|
write_len += file.write(b"Tomorro")
|
|
|
|
|
write_len += file.write(b"w's victo")
|
|
|
|
|
write_len += file.write(b"ry is today")
|
|
|
|
|
write_len += file.write(b"'s practice.")
|
|
|
|
|
self.assertEqual(expected, wrapped.getbuffer())
|
|
|
|
|
self.assertEqual(39, write_len)
|
|
|
|
|
self.assertEqual(4, file.write_ops)
|
|
|
|
|
self.assertEqual(39, file.write_bytes)
|
|
|
|
|
self.assertEqual(4, mock.write.call_count)
|
2021-02-08 17:51:59 -05:00
|
|
|
|
2021-02-08 17:42:00 -05:00
|
|
|
@patch("paasio.super", create=True, new_callable=SuperMock)
|
|
|
|
|
def test_meteredfile_write_under_size(self, super_mock):
|
|
|
|
|
wrapped = MockFile(chunk=257) # largish odd number
|
|
|
|
|
mock = NonCallableMagicMock(wraps=wrapped, autospec=True)
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
with MeteredFile() as file:
|
|
|
|
|
write_len = file.write(ZEN[:123])
|
|
|
|
|
self.assertEqual(ZEN[:123], wrapped.getbuffer())
|
|
|
|
|
self.assertEqual(123, write_len)
|
|
|
|
|
self.assertEqual(1, file.write_ops)
|
|
|
|
|
self.assertEqual(123, file.write_bytes)
|
|
|
|
|
self.assertEqual(1, mock.write.call_count)
|
2021-02-08 17:51:59 -05:00
|
|
|
|
2021-02-08 17:42:00 -05:00
|
|
|
@patch("paasio.super", create=True, new_callable=SuperMock)
|
|
|
|
|
def test_meteredfile_stats_read_only(self, super_mock):
|
|
|
|
|
mock = NonCallableMagicMock(wraps=MockFile(ZEN), autospec=True)
|
|
|
|
|
super_mock.mock_object = mock
|
|
|
|
|
with MeteredFile() as file:
|
|
|
|
|
self.assertEqual(0, file.read_ops)
|
|
|
|
|
self.assertEqual(0, file.read_bytes)
|
|
|
|
|
for _ in range(57):
|
|
|
|
|
file.read(1)
|
|
|
|
|
file.read(2)
|
|
|
|
|
self.assertEqual(58, file.read_ops)
|
|
|
|
|
self.assertEqual(59, file.read_bytes)
|
|
|
|
|
self.assertEqual(0, file.write_ops)
|
|
|
|
|
self.assertEqual(0, file.write_bytes)
|
|
|
|
|
for _ in range(77):
|
|
|
|
|
file.write(b"b")
|
|
|
|
|
file.write(b"bytes")
|
|
|
|
|
self.assertEqual(78, file.write_ops)
|
|
|
|
|
self.assertEqual(82, file.write_bytes)
|
|
|
|
|
with self.assertRaisesRegex(AttributeError, "can't set"):
|
|
|
|
|
file.write_ops = 0
|
|
|
|
|
with self.assertRaisesRegex(AttributeError, "can't set"):
|
|
|
|
|
file.write_bytes = 0
|
|
|
|
|
with self.assertRaisesRegex(AttributeError, "can't set"):
|
|
|
|
|
file.read_ops = 0
|
|
|
|
|
with self.assertRaisesRegex(AttributeError, "can't set"):
|
|
|
|
|
file.read_bytes = 0
|
|
|
|
|
self.assertEqual(78, file.write_ops)
|
|
|
|
|
self.assertEqual(82, file.write_bytes)
|
|
|
|
|
self.assertEqual(58, file.read_ops)
|
|
|
|
|
self.assertEqual(59, file.read_bytes)
|
|
|
|
|
|
|
|
|
|
|
2020-10-12 09:26:43 -05:00
|
|
|
if __name__ == "__main__":
|
|
|
|
|
unittest.main()
|