From a088cdcd7336979d31c6ce5ee8ecf15f055159f5 Mon Sep 17 00:00:00 2001 From: "Brian S. Stephan" Date: Tue, 20 Jun 2023 20:01:22 -0500 Subject: [PATCH] unit tests for config parsing out of storage closes #1 --- pyproject.toml | 6 +-- requirements/requirements-dev.txt | 2 + tests/conftest.py | 16 +++++++ tests/test-files/test-storage-area.bin | Bin 0 -> 8192 bytes tests/test_storage.py | 64 +++++++++++++++++++++++++ 5 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 tests/conftest.py create mode 100644 tests/test-files/test-storage-area.bin create mode 100644 tests/test_storage.py diff --git a/pyproject.toml b/pyproject.toml index 3437b0f..4878d10 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,9 +14,9 @@ dependencies = ["grpcio-tools"] dynamic = ["version"] [project.optional-dependencies] -dev = ["flake8", "flake8-blind-except", "flake8-builtins", "flake8-docstrings", "flake8-executable", "flake8-fixme", - "flake8-isort", "flake8-logging-format", "flake8-mutable", "flake8-pyproject", "mypy", "pip-tools", "pytest", - "setuptools-scm"] +dev = ["decorator", "flake8", "flake8-blind-except", "flake8-builtins", "flake8-docstrings", "flake8-executable", + "flake8-fixme", "flake8-isort", "flake8-logging-format", "flake8-mutable", "flake8-pyproject", "mypy", + "pip-tools", "pytest", "setuptools-scm"] [project.scripts] visualize-storage = "gp2040ce_bintools.storage:visualize" diff --git a/requirements/requirements-dev.txt b/requirements/requirements-dev.txt index 7131e94..73574c6 100644 --- a/requirements/requirements-dev.txt +++ b/requirements/requirements-dev.txt @@ -8,6 +8,8 @@ build==0.10.0 # via pip-tools click==8.1.3 # via pip-tools +decorator==5.1.1 + # via gp2040ce-binary-tools (pyproject.toml) exceptiongroup==1.1.1 # via pytest flake8==6.0.0 diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..107eb84 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,16 @@ +"""Create the test fixtures and other data.""" +import os + +import pytest + +HERE = os.path.dirname(os.path.abspath(__file__)) + + +@pytest.fixture +def storage_dump(): + """Read in a test storage dump file (101FE000-10200000) of a GP2040-CE board.""" + filename = os.path.join(HERE, 'test-files', 'test-storage-area.bin') + with open(filename, 'rb') as file: + content = file.read() + + yield content diff --git a/tests/test-files/test-storage-area.bin b/tests/test-files/test-storage-area.bin new file mode 100644 index 0000000000000000000000000000000000000000..829754a4c698a07042dc5498dee9874d48fa1e83 GIT binary patch literal 8192 zcmeH|PiP}m9LK-EH%VqTjhPr-i8Ur6f)1gUAqX2|X+tlTUW^5??8UGs#63uM7o|$s zjCx2wFgf-hySZ8LQV&9Jj;xR##8wa5({5Z3S-fnP6)fzU=bNVKyexDN9?N@|`F?-D z_viOMA-@Nxp$I4fihv@Z2q*%IfFhs>C<2OrBA^H;0*Zhlpa>`eihv@Z2q*%lkw7@~ zkv)5EHXn}}EQSQjz=DkeN|?680fSKb7;MVzmNP(A>4N~_Z`Rc8U0iK>Wwb_?kpUpd+9#^xZAk?we!K8 z2z1h&(|atB)LVf{w8J~Xek8n?v$Cg)eW4Sq9P*3;=dApJJ)w{)JI7n!

-M^as5zij+q*BRk-@vZL_vNk{&a|3hlp8XQ8CQ2dreqZ+l5yd5lPC0at6ts0dx z)j%z{raKgB(o~zm8^p(hI+EU$^p>QzCGARjN78$e-j{Sw(sv|1@U*`8q3Ezd(UZw~ z%eK6pEJ}vxZK$G#@y*(V4MK;oN!TK66I{X$VUMs+=n?J^2808G!_Z`CGi)$)7&aNU z7`7Q)h8>1IhJA(}!}4#M==_L5bbir!r;|dDiEv8zQoI$x?E5EXP0OD;dQuL{_k$H* zR()CX<>VD}AyE!XX!*>EN0LQ06{zUVfLy7+r&aPEk;PX|+(Vk`%TfKy=H#k(R~`xA zya$dhB*f!{X=IT@9z`r-87nxC3%HniOl6|3%U<3;R=xsRu-PXsoS64leMV;|XJPcJ UuP_4x9r)$vOSj+q^WLxj0i@eDR{#J2 literal 0 HcmV?d00001 diff --git a/tests/test_storage.py b/tests/test_storage.py new file mode 100644 index 0000000..1588325 --- /dev/null +++ b/tests/test_storage.py @@ -0,0 +1,64 @@ +"""Unit tests for the storage module.""" +import os +import sys + +import pytest +from decorator import decorator + +from gp2040ce_bintools.storage import get_config, get_config_footer + +HERE = os.path.dirname(os.path.abspath(__file__)) + + +@decorator +def with_pb2s(test, *args, **kwargs): + """Wrap a test with precompiled pb2 files on the path.""" + proto_path = os.path.join(HERE, 'test-files', 'pb2-files') + sys.path.append(proto_path) + + test(*args, **kwargs) + + sys.path.pop() + del sys.modules['config_pb2'] + + +def test_config_footer(storage_dump): + """Test that a config footer is identified as expected.""" + size, crc, magic = get_config_footer(storage_dump) + assert size == 2032 + assert crc == 3799109329 + assert magic == '0x65e3f1d2' + + +def test_config_footer_way_too_small(storage_dump): + """Test that a config footer isn't detected if the size is way too small.""" + with pytest.raises(ValueError): + size, crc, magic = get_config_footer(storage_dump[-11:]) + + +def test_config_footer_too_small(storage_dump): + """Test that a config footer isn't detected if the size is smaller than that found in the header.""" + with pytest.raises(ValueError): + size, crc, magic = get_config_footer(storage_dump[-1000:]) + + +def test_config_footer_bad_magic(storage_dump): + """Test that a config footer isn't detected if the magic is incorrect.""" + unmagical = bytearray(storage_dump) + unmagical[-1] = 0 + with pytest.raises(ValueError): + size, crc, magic = get_config_footer(unmagical) + + +def test_config_fails_without_pb2s(storage_dump): + """Test that we need the config_pb2 to exist/be compiled for reading the config to work.""" + with pytest.raises(ModuleNotFoundError): + _ = get_config(storage_dump) + + +@with_pb2s +def test_config_parses(storage_dump): + """Test that we need the config_pb2 to exist/be compiled for reading the config to work.""" + config = get_config(storage_dump) + assert config.boardVersion == 'v0.7.2' + assert config.hotkeyOptions.hotkeyF1Up.dpadMask == 1