pycapnp/test/test_serialization.py

262 lines
6.9 KiB
Python
Raw Normal View History

2019-07-13 16:36:58 +01:00
import warnings
from contextlib import contextmanager
2013-09-03 22:12:28 -07:00
import pytest
import capnp
import os
import platform
2013-09-04 11:20:05 -07:00
import test_regression
2013-12-09 17:16:39 -08:00
import tempfile
2014-04-17 21:21:06 -07:00
import pickle
import mmap
import sys
2013-09-03 22:12:28 -07:00
this_dir = os.path.dirname(__file__)
2019-12-11 22:44:44 -08:00
2013-09-03 22:12:28 -07:00
@pytest.fixture
2013-09-04 11:20:05 -07:00
def all_types():
return capnp.load(os.path.join(this_dir, "all_types.capnp"))
2013-09-03 22:12:28 -07:00
2019-12-11 22:44:44 -08:00
2013-09-04 11:20:05 -07:00
def test_roundtrip_file(all_types):
2013-12-09 17:16:39 -08:00
f = tempfile.TemporaryFile()
2013-09-04 11:20:05 -07:00
msg = all_types.TestAllTypes.new_message()
test_regression.init_all_types(msg)
2013-09-03 22:12:28 -07:00
msg.write(f)
2013-12-09 17:16:39 -08:00
f.seek(0)
2013-09-04 11:20:05 -07:00
msg = all_types.TestAllTypes.read(f)
test_regression.check_all_types(msg)
2013-09-03 22:12:28 -07:00
2019-12-11 22:44:44 -08:00
2013-09-04 11:20:05 -07:00
def test_roundtrip_file_packed(all_types):
2013-12-09 17:16:39 -08:00
f = tempfile.TemporaryFile()
2013-09-04 11:20:05 -07:00
msg = all_types.TestAllTypes.new_message()
test_regression.init_all_types(msg)
2013-09-03 22:16:13 -07:00
msg.write_packed(f)
2013-12-09 17:16:39 -08:00
f.seek(0)
2013-09-04 11:20:05 -07:00
msg = all_types.TestAllTypes.read_packed(f)
test_regression.check_all_types(msg)
2013-09-03 22:16:13 -07:00
2019-12-11 22:44:44 -08:00
2013-09-04 11:20:05 -07:00
def test_roundtrip_bytes(all_types):
msg = all_types.TestAllTypes.new_message()
test_regression.init_all_types(msg)
2013-09-03 22:12:28 -07:00
message_bytes = msg.to_bytes()
with all_types.TestAllTypes.from_bytes(message_bytes) as msg:
test_regression.check_all_types(msg)
2013-09-03 22:12:28 -07:00
2019-12-11 22:44:44 -08:00
@pytest.mark.skipif(
platform.python_implementation() == "PyPy",
reason="TODO: Investigate why this works on CPython but fails on PyPy.",
)
def test_roundtrip_segments(all_types):
msg = all_types.TestAllTypes.new_message()
test_regression.init_all_types(msg)
segments = msg.to_segments()
msg = all_types.TestAllTypes.from_segments(segments)
test_regression.check_all_types(msg)
2019-12-11 22:44:44 -08:00
@pytest.mark.skipif(
sys.version_info[0] < 3,
reason="mmap doesn't implement the buffer interface under python 2.",
)
def test_roundtrip_bytes_mmap(all_types):
msg = all_types.TestAllTypes.new_message()
test_regression.init_all_types(msg)
with tempfile.TemporaryFile() as f:
msg.write(f)
length = f.tell()
f.seek(0)
memory = mmap.mmap(f.fileno(), length)
with all_types.TestAllTypes.from_bytes(memory) as msg:
test_regression.check_all_types(msg)
2019-12-11 22:44:44 -08:00
@pytest.mark.skipif(
sys.version_info[0] < 3, reason="memoryview is a builtin on Python 3"
)
2017-11-28 00:15:05 +00:00
def test_roundtrip_bytes_buffer(all_types):
msg = all_types.TestAllTypes.new_message()
test_regression.init_all_types(msg)
b = msg.to_bytes()
v = memoryview(b)
2022-01-18 12:04:01 +01:00
try:
with all_types.TestAllTypes.from_bytes(v) as msg:
test_regression.check_all_types(msg)
2022-01-18 12:04:01 +01:00
finally:
v.release()
2017-11-28 00:15:05 +00:00
2019-12-11 22:44:44 -08:00
2017-11-28 00:15:05 +00:00
def test_roundtrip_bytes_fail(all_types):
with pytest.raises(TypeError):
with all_types.TestAllTypes.from_bytes(42) as msg:
pass
2017-11-28 00:15:05 +00:00
2019-12-11 22:44:44 -08:00
@pytest.mark.skipif(
platform.python_implementation() == "PyPy",
reason="This works in PyPy 4.0.1 but travisci's version of PyPy has some bug that fails this test.",
)
def test_roundtrip_bytes_packed(all_types):
msg = all_types.TestAllTypes.new_message()
test_regression.init_all_types(msg)
message_bytes = msg.to_bytes_packed()
msg = all_types.TestAllTypes.from_bytes_packed(message_bytes)
test_regression.check_all_types(msg)
2019-07-13 16:36:58 +01:00
@contextmanager
def _warnings(
expected_count=2, expected_text="This message has already been written once."
):
2019-07-13 16:36:58 +01:00
with warnings.catch_warnings(record=True) as w:
yield
assert len(w) == expected_count
assert all(issubclass(x.category, UserWarning) for x in w), w
assert all(expected_text in str(x.message) for x in w), w
2019-12-11 22:44:44 -08:00
def test_roundtrip_file_multiple(all_types):
2013-12-09 17:16:39 -08:00
f = tempfile.TemporaryFile()
msg = all_types.TestAllTypes.new_message()
test_regression.init_all_types(msg)
msg.write(f)
2019-07-13 16:36:58 +01:00
with _warnings(2):
msg.write(f)
msg.write(f)
2013-12-09 17:16:39 -08:00
f.seek(0)
i = 0
for msg in all_types.TestAllTypes.read_multiple(f):
test_regression.check_all_types(msg)
i += 1
assert i == 3
2019-12-11 22:44:44 -08:00
def test_roundtrip_bytes_multiple(all_types):
msg = all_types.TestAllTypes.new_message()
test_regression.init_all_types(msg)
msgs = msg.to_bytes()
2019-07-13 16:36:58 +01:00
with _warnings(2):
msgs += msg.to_bytes()
msgs += msg.to_bytes()
i = 0
for msg in all_types.TestAllTypes.read_multiple_bytes(msgs):
test_regression.check_all_types(msg)
i += 1
assert i == 3
2019-12-11 22:44:44 -08:00
def test_roundtrip_file_multiple_packed(all_types):
2013-12-09 17:16:39 -08:00
f = tempfile.TemporaryFile()
msg = all_types.TestAllTypes.new_message()
test_regression.init_all_types(msg)
msg.write_packed(f)
2019-07-13 16:36:58 +01:00
with _warnings(2):
msg.write_packed(f)
msg.write_packed(f)
2013-12-09 17:16:39 -08:00
f.seek(0)
i = 0
for msg in all_types.TestAllTypes.read_multiple_packed(f):
test_regression.check_all_types(msg)
i += 1
assert i == 3
2019-12-11 22:44:44 -08:00
def test_roundtrip_bytes_multiple_packed(all_types):
msg = all_types.TestAllTypes.new_message()
test_regression.init_all_types(msg)
msgs = msg.to_bytes_packed()
2019-07-13 16:36:58 +01:00
with _warnings(2):
msgs += msg.to_bytes_packed()
msgs += msg.to_bytes_packed()
i = 0
for msg in all_types.TestAllTypes.read_multiple_bytes_packed(msgs):
test_regression.check_all_types(msg)
i += 1
assert i == 3
2019-12-11 22:44:44 -08:00
def test_file_and_bytes(all_types):
2013-12-09 17:16:39 -08:00
f = tempfile.TemporaryFile()
msg = all_types.TestAllTypes.new_message()
test_regression.init_all_types(msg)
msg.write(f)
2013-12-09 17:16:39 -08:00
f.seek(0)
2019-07-13 16:36:58 +01:00
with _warnings(1):
assert f.read() == msg.to_bytes()
2019-12-11 22:44:44 -08:00
def test_file_and_bytes_packed(all_types):
2013-12-09 17:16:39 -08:00
f = tempfile.TemporaryFile()
msg = all_types.TestAllTypes.new_message()
test_regression.init_all_types(msg)
msg.write_packed(f)
2013-12-09 17:16:39 -08:00
f.seek(0)
2019-07-13 16:36:58 +01:00
with _warnings(1):
assert f.read() == msg.to_bytes_packed()
2014-04-17 21:21:06 -07:00
2019-12-11 22:44:44 -08:00
2014-04-17 21:21:06 -07:00
def test_pickle(all_types):
msg = all_types.TestAllTypes.new_message()
test_regression.init_all_types(msg)
data = pickle.dumps(msg)
msg2 = pickle.loads(data)
test_regression.check_all_types(msg2)
2019-12-11 22:44:44 -08:00
def test_from_bytes_traversal_limit(all_types):
size = 1024
bld = all_types.TestAllTypes.new_message()
bld.init("structList", size)
data = bld.to_bytes()
with all_types.TestAllTypes.from_bytes(data) as msg:
with pytest.raises(capnp.KjException):
for i in range(0, size):
msg.structList[i].uInt8Field == 0
with all_types.TestAllTypes.from_bytes(data, traversal_limit_in_words=2 ** 62) as msg:
for i in range(0, size):
assert msg.structList[i].uInt8Field == 0
def test_from_bytes_packed_traversal_limit(all_types):
size = 1024
bld = all_types.TestAllTypes.new_message()
bld.init("structList", size)
data = bld.to_bytes_packed()
msg = all_types.TestAllTypes.from_bytes_packed(data)
with pytest.raises(capnp.KjException):
for i in range(0, size):
msg.structList[i].uInt8Field == 0
2019-12-11 22:44:44 -08:00
msg = all_types.TestAllTypes.from_bytes_packed(
data, traversal_limit_in_words=2**62
2019-12-11 22:44:44 -08:00
)
for i in range(0, size):
assert msg.structList[i].uInt8Field == 0