Add option to repeatly execute betterproto operations in test, to evaluate performance
This commit is contained in:
parent
5e2d9febea
commit
de61ddab21
@ -5,6 +5,7 @@ import sys
|
|||||||
import pytest
|
import pytest
|
||||||
import betterproto
|
import betterproto
|
||||||
from betterproto.tests.util import get_directories, inputs_path
|
from betterproto.tests.util import get_directories, inputs_path
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
# Force pure-python implementation instead of C++, otherwise imports
|
# Force pure-python implementation instead of C++, otherwise imports
|
||||||
# break things because we can't properly reset the symbol database.
|
# break things because we can't properly reset the symbol database.
|
||||||
@ -22,47 +23,13 @@ plugin_output_package = "betterproto.tests.output_betterproto"
|
|||||||
reference_output_package = "betterproto.tests.output_reference"
|
reference_output_package = "betterproto.tests.output_reference"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("test_case_name", test_case_names)
|
TestData = namedtuple("TestData", "plugin_module, reference_module, json_data")
|
||||||
def test_message_can_be_imported(test_case_name: str) -> None:
|
|
||||||
importlib.import_module(
|
|
||||||
f"{plugin_output_package}.{test_case_name}.{test_case_name}"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("test_case_name", test_case_names)
|
@pytest.fixture(scope="module", params=test_case_names)
|
||||||
def test_message_can_instantiated(test_case_name: str) -> None:
|
def test_data(request):
|
||||||
plugin_module = importlib.import_module(
|
test_case_name = request.param
|
||||||
f"{plugin_output_package}.{test_case_name}.{test_case_name}"
|
|
||||||
)
|
|
||||||
plugin_module.Test()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("test_case_name", test_case_names)
|
|
||||||
def test_message_equality(test_case_name: str) -> None:
|
|
||||||
plugin_module = importlib.import_module(
|
|
||||||
f"{plugin_output_package}.{test_case_name}.{test_case_name}"
|
|
||||||
)
|
|
||||||
message1 = plugin_module.Test()
|
|
||||||
message2 = plugin_module.Test()
|
|
||||||
assert message1 == message2
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("test_case_name", test_case_names)
|
|
||||||
def test_message_json(test_case_name: str) -> None:
|
|
||||||
plugin_module = importlib.import_module(
|
|
||||||
f"{plugin_output_package}.{test_case_name}.{test_case_name}"
|
|
||||||
)
|
|
||||||
message: betterproto.Message = plugin_module.Test()
|
|
||||||
reference_json_data = get_test_case_json_data(test_case_name)
|
|
||||||
|
|
||||||
message.from_json(reference_json_data)
|
|
||||||
message_json = message.to_json(0)
|
|
||||||
|
|
||||||
assert json.loads(reference_json_data) == json.loads(message_json)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("test_case_name", test_case_names)
|
|
||||||
def test_binary_compatibility(test_case_name: str) -> None:
|
|
||||||
# Reset the internal symbol database so we can import the `Test` message
|
# Reset the internal symbol database so we can import the `Test` message
|
||||||
# multiple times. Ugh.
|
# multiple times. Ugh.
|
||||||
sym = symbol_database.Default()
|
sym = symbol_database.Default()
|
||||||
@ -74,33 +41,66 @@ def test_binary_compatibility(test_case_name: str) -> None:
|
|||||||
|
|
||||||
sys.path.append(reference_module_root)
|
sys.path.append(reference_module_root)
|
||||||
|
|
||||||
# import reference message
|
yield TestData(
|
||||||
reference_module = importlib.import_module(
|
plugin_module=importlib.import_module(
|
||||||
f"{reference_output_package}.{test_case_name}.{test_case_name}_pb2"
|
f"{plugin_output_package}.{test_case_name}.{test_case_name}"
|
||||||
|
),
|
||||||
|
reference_module=importlib.import_module(
|
||||||
|
f"{reference_output_package}.{test_case_name}.{test_case_name}_pb2"
|
||||||
|
),
|
||||||
|
json_data=get_test_case_json_data(test_case_name),
|
||||||
)
|
)
|
||||||
plugin_module = importlib.import_module(
|
|
||||||
f"{plugin_output_package}.{test_case_name}.{test_case_name}"
|
|
||||||
)
|
|
||||||
|
|
||||||
test_data = get_test_case_json_data(test_case_name)
|
|
||||||
|
|
||||||
reference_instance = Parse(test_data, reference_module.Test())
|
|
||||||
reference_binary_output = reference_instance.SerializeToString()
|
|
||||||
|
|
||||||
plugin_instance_from_json: betterproto.Message = plugin_module.Test().from_json(
|
|
||||||
test_data
|
|
||||||
)
|
|
||||||
plugin_instance_from_binary = plugin_module.Test.FromString(reference_binary_output)
|
|
||||||
|
|
||||||
# # Generally this can't be relied on, but here we are aiming to match the
|
|
||||||
# # existing Python implementation and aren't doing anything tricky.
|
|
||||||
# # https://developers.google.com/protocol-buffers/docs/encoding#implications
|
|
||||||
assert plugin_instance_from_json == plugin_instance_from_binary
|
|
||||||
assert plugin_instance_from_json.to_dict() == plugin_instance_from_binary.to_dict()
|
|
||||||
|
|
||||||
sys.path.remove(reference_module_root)
|
sys.path.remove(reference_module_root)
|
||||||
|
|
||||||
|
|
||||||
|
def test_message_can_instantiated(test_data: TestData) -> None:
|
||||||
|
plugin_module, *_ = test_data
|
||||||
|
plugin_module.Test()
|
||||||
|
|
||||||
|
|
||||||
|
def test_message_equality(test_data: TestData) -> None:
|
||||||
|
plugin_module, *_ = test_data
|
||||||
|
message1 = plugin_module.Test()
|
||||||
|
message2 = plugin_module.Test()
|
||||||
|
assert message1 == message2
|
||||||
|
|
||||||
|
|
||||||
|
def test_message_json(repeat, test_data: TestData) -> None:
|
||||||
|
plugin_module, _, json_data = test_data
|
||||||
|
|
||||||
|
for _ in range(repeat):
|
||||||
|
message: betterproto.Message = plugin_module.Test()
|
||||||
|
|
||||||
|
message.from_json(json_data)
|
||||||
|
message_json = message.to_json(0)
|
||||||
|
|
||||||
|
assert json.loads(json_data) == json.loads(message_json)
|
||||||
|
|
||||||
|
|
||||||
|
def test_binary_compatibility(repeat, test_data: TestData) -> None:
|
||||||
|
plugin_module, reference_module, json_data = test_data
|
||||||
|
|
||||||
|
reference_instance = Parse(json_data, reference_module.Test())
|
||||||
|
reference_binary_output = reference_instance.SerializeToString()
|
||||||
|
|
||||||
|
for _ in range(repeat):
|
||||||
|
plugin_instance_from_json: betterproto.Message = plugin_module.Test().from_json(
|
||||||
|
json_data
|
||||||
|
)
|
||||||
|
plugin_instance_from_binary = plugin_module.Test.FromString(
|
||||||
|
reference_binary_output
|
||||||
|
)
|
||||||
|
|
||||||
|
# # Generally this can't be relied on, but here we are aiming to match the
|
||||||
|
# # existing Python implementation and aren't doing anything tricky.
|
||||||
|
# # https://developers.google.com/protocol-buffers/docs/encoding#implications
|
||||||
|
assert plugin_instance_from_json == plugin_instance_from_binary
|
||||||
|
assert (
|
||||||
|
plugin_instance_from_json.to_dict() == plugin_instance_from_binary.to_dict()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
helper methods
|
helper methods
|
||||||
"""
|
"""
|
||||||
|
10
conftest.py
Normal file
10
conftest.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
def pytest_addoption(parser):
|
||||||
|
parser.addoption("--repeat", type=int, default=1, help="repeat the operation multiple times")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def repeat(request):
|
||||||
|
return request.config.getoption("repeat")
|
Loading…
x
Reference in New Issue
Block a user