add pytest, test creation/import of config_pb2 module

This commit is contained in:
Brian S. Stephan 2023-06-20 19:35:04 -05:00
parent 0c7ed1fcea
commit 54035de00a
Signed by: bss
GPG Key ID: 3DE06D3180895FCB
10 changed files with 1067 additions and 7 deletions

View File

@ -50,9 +50,6 @@ def get_config_pb2():
try:
return importlib.import_module('config_pb2')
except ModuleNotFoundError:
if args.proto_files_path:
# compile the proto files in realtime, leave them in this package
logger.info("Invoking gRPC tool to compile config.proto...")
return grpc.protos('config.proto')
raise
# compile the proto files in realtime, leave them in this package
logger.info("Invoking gRPC tool to compile config.proto...")
return grpc.protos('config.proto')

View File

@ -15,7 +15,7 @@ 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",
"flake8-isort", "flake8-logging-format", "flake8-mutable", "flake8-pyproject", "mypy", "pip-tools", "pytest",
"setuptools-scm"]
[project.scripts]

View File

@ -8,6 +8,8 @@ build==0.10.0
# via pip-tools
click==8.1.3
# via pip-tools
exceptiongroup==1.1.1
# via pytest
flake8==6.0.0
# via
# flake8-builtins
@ -39,6 +41,8 @@ grpcio==1.54.2
# via grpcio-tools
grpcio-tools==1.54.2
# via gp2040ce-binary-tools (pyproject.toml)
iniconfig==2.0.0
# via pytest
isort==5.12.0
# via flake8-isort
mccabe==0.7.0
@ -50,9 +54,12 @@ mypy-extensions==1.0.0
packaging==23.1
# via
# build
# pytest
# setuptools-scm
pip-tools==6.13.0
# via gp2040ce-binary-tools (pyproject.toml)
pluggy==1.0.0
# via pytest
protobuf==4.23.3
# via grpcio-tools
pycodestyle==2.10.0
@ -63,6 +70,8 @@ pyflakes==3.0.1
# via flake8
pyproject-hooks==1.0.0
# via build
pytest==7.3.2
# via gp2040ce-binary-tools (pyproject.toml)
setuptools-scm==7.1.0
# via gp2040ce-binary-tools (pyproject.toml)
snowballstemmer==2.2.0
@ -72,6 +81,7 @@ tomli==2.0.1
# build
# flake8-pyproject
# mypy
# pytest
# setuptools-scm
typing-extensions==4.6.3
# via

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: enums.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
import nanopb_pb2 as nanopb__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0b\x65nums.proto\x1a\x0cnanopb.proto*\xa1\x03\n\x0c\x42uttonLayout\x12\x17\n\x13\x42UTTON_LAYOUT_STICK\x10\x00\x12\x1b\n\x17\x42UTTON_LAYOUT_STICKLESS\x10\x01\x12 \n\x1c\x42UTTON_LAYOUT_BUTTONS_ANGLED\x10\x02\x12\x1f\n\x1b\x42UTTON_LAYOUT_BUTTONS_BASIC\x10\x03\x12!\n\x1d\x42UTTON_LAYOUT_KEYBOARD_ANGLED\x10\x04\x12\x1b\n\x17\x42UTTON_LAYOUT_KEYBOARDA\x10\x05\x12\x1b\n\x17\x42UTTON_LAYOUT_DANCEPADA\x10\x06\x12\x1c\n\x18\x42UTTON_LAYOUT_TWINSTICKA\x10\x07\x12\x18\n\x14\x42UTTON_LAYOUT_BLANKA\x10\x08\x12\x16\n\x12\x42UTTON_LAYOUT_VLXA\x10\t\x12\"\n\x1e\x42UTTON_LAYOUT_FIGHTBOARD_STICK\x10\n\x12%\n!BUTTON_LAYOUT_FIGHTBOARD_MIRRORED\x10\x0b\x12\x19\n\x15\x42UTTON_LAYOUT_CUSTOMA\x10\x0c\x1a\x05\x92?\x02 \x00*\x82\x04\n\x11\x42uttonLayoutRight\x12\x18\n\x14\x42UTTON_LAYOUT_ARCADE\x10\x00\x12\x1c\n\x18\x42UTTON_LAYOUT_STICKLESSB\x10\x01\x12!\n\x1d\x42UTTON_LAYOUT_BUTTONS_ANGLEDB\x10\x02\x12\x18\n\x14\x42UTTON_LAYOUT_VEWLIX\x10\x03\x12\x19\n\x15\x42UTTON_LAYOUT_VEWLIX7\x10\x04\x12\x18\n\x14\x42UTTON_LAYOUT_CAPCOM\x10\x05\x12\x19\n\x15\x42UTTON_LAYOUT_CAPCOM6\x10\x06\x12\x18\n\x14\x42UTTON_LAYOUT_SEGA2P\x10\x07\x12\x17\n\x13\x42UTTON_LAYOUT_NOIR8\x10\x08\x12\x1b\n\x17\x42UTTON_LAYOUT_KEYBOARDB\x10\t\x12\x1b\n\x17\x42UTTON_LAYOUT_DANCEPADB\x10\n\x12\x1c\n\x18\x42UTTON_LAYOUT_TWINSTICKB\x10\x0b\x12\x18\n\x14\x42UTTON_LAYOUT_BLANKB\x10\x0c\x12\x16\n\x12\x42UTTON_LAYOUT_VLXB\x10\r\x12\x1c\n\x18\x42UTTON_LAYOUT_FIGHTBOARD\x10\x0e\x12+\n\'BUTTON_LAYOUT_FIGHTBOARD_STICK_MIRRORED\x10\x0f\x12\x19\n\x15\x42UTTON_LAYOUT_CUSTOMB\x10\x10\x1a\x05\x92?\x02 \x00*y\n\nSplashMode\x12\x16\n\x12SPLASH_MODE_STATIC\x10\x00\x12\x17\n\x13SPLASH_MODE_CLOSEIN\x10\x01\x12\x1d\n\x19SPLASH_MODE_CLOSEINCUSTOM\x10\x02\x12\x14\n\x10SPLASH_MODE_NONE\x10\x03\x1a\x05\x92?\x02 \x00*\xa0\x01\n\x0cSplashChoice\x12\x16\n\x12SPLASH_CHOICE_MAIN\x10\x00\x12\x13\n\x0fSPLASH_CHOICE_X\x10\x01\x12\x13\n\x0fSPLASH_CHOICE_Y\x10\x02\x12\x13\n\x0fSPLASH_CHOICE_Z\x10\x03\x12\x18\n\x14SPLASH_CHOICE_CUSTOM\x10\x04\x12\x18\n\x14SPLASH_CHOICE_LEGACY\x10\x05\x1a\x05\x92?\x02 \x00*z\n\x0eOnBoardLedMode\x12\x19\n\x15ON_BOARD_LED_MODE_OFF\x10\x00\x12$\n ON_BOARD_LED_MODE_MODE_INDICATOR\x10\x01\x12 \n\x1cON_BOARD_LED_MODE_INPUT_TEST\x10\x02\x1a\x05\x92?\x02 \x00*\x99\x01\n\tInputMode\x12\x15\n\x11INPUT_MODE_XINPUT\x10\x00\x12\x15\n\x11INPUT_MODE_SWITCH\x10\x01\x12\x12\n\x0eINPUT_MODE_HID\x10\x02\x12\x17\n\x13INPUT_MODE_KEYBOARD\x10\x03\x12\x12\n\x0eINPUT_MODE_PS4\x10\x04\x12\x16\n\x11INPUT_MODE_CONFIG\x10\xff\x01\x1a\x05\x92?\x02 \x00*_\n\x08\x44padMode\x12\x15\n\x11\x44PAD_MODE_DIGITAL\x10\x00\x12\x19\n\x15\x44PAD_MODE_LEFT_ANALOG\x10\x01\x12\x1a\n\x16\x44PAD_MODE_RIGHT_ANALOG\x10\x02\x1a\x05\x92?\x02 \x00*\xa2\x01\n\x08SOCDMode\x12\x19\n\x15SOCD_MODE_UP_PRIORITY\x10\x00\x12\x15\n\x11SOCD_MODE_NEUTRAL\x10\x01\x12#\n\x1fSOCD_MODE_SECOND_INPUT_PRIORITY\x10\x02\x12\"\n\x1eSOCD_MODE_FIRST_INPUT_PRIORITY\x10\x03\x12\x14\n\x10SOCD_MODE_BYPASS\x10\x04\x1a\x05\x92?\x02 \x00*\xa9\x03\n\rGamepadHotkey\x12\x0f\n\x0bHOTKEY_NONE\x10\x00\x12\x17\n\x13HOTKEY_DPAD_DIGITAL\x10\x01\x12\x1b\n\x17HOTKEY_DPAD_LEFT_ANALOG\x10\x02\x12\x1c\n\x18HOTKEY_DPAD_RIGHT_ANALOG\x10\x03\x12\x16\n\x12HOTKEY_HOME_BUTTON\x10\x04\x12\x19\n\x15HOTKEY_CAPTURE_BUTTON\x10\x05\x12\x1b\n\x17HOTKEY_SOCD_UP_PRIORITY\x10\x06\x12\x17\n\x13HOTKEY_SOCD_NEUTRAL\x10\x07\x12\x1a\n\x16HOTKEY_SOCD_LAST_INPUT\x10\x08\x12\x18\n\x14HOTKEY_INVERT_X_AXIS\x10\t\x12\x18\n\x14HOTKEY_INVERT_Y_AXIS\x10\n\x12\x1b\n\x17HOTKEY_SOCD_FIRST_INPUT\x10\x0b\x12\x16\n\x12HOTKEY_SOCD_BYPASS\x10\x0c\x12\x1c\n\x18HOTKEY_TOGGLE_4_WAY_MODE\x10\r\x12 \n\x1cHOTKEY_TOGGLE_DDI_4_WAY_MODE\x10\x0e\x1a\x05\x92?\x02 \x00*c\n\x0fLEDFormat_Proto\x12\x12\n\x0eLED_FORMAT_GRB\x10\x00\x12\x12\n\x0eLED_FORMAT_RGB\x10\x01\x12\x13\n\x0fLED_FORMAT_GRBW\x10\x02\x12\x13\n\x0fLED_FORMAT_RGBW\x10\x03*\\\n\x0cShmupMixMode\x12!\n\x1dSHMUP_MIX_MODE_TURBO_PRIORITY\x10\x00\x12\"\n\x1eSHMUP_MIX_MODE_CHARGE_PRIORITY\x10\x01\x1a\x05\x92?\x02 \x00*T\n\x08PLEDType\x12\x1b\n\x0ePLED_TYPE_NONE\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x12\x11\n\rPLED_TYPE_PWM\x10\x00\x12\x11\n\rPLED_TYPE_RGB\x10\x01\x1a\x05\x92?\x02 \x00*\xa3\x01\n\x0f\x46orcedSetupMode\x12\x19\n\x15\x46ORCED_SETUP_MODE_OFF\x10\x00\x12&\n\"FORCED_SETUP_MODE_LOCK_MODE_SWITCH\x10\x01\x12%\n!FORCED_SETUP_MODE_LOCK_WEB_CONFIG\x10\x02\x12\x1f\n\x1b\x46ORCED_SETUP_MODE_LOCK_BOTH\x10\x03\x1a\x05\x92?\x02 \x00')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'enums_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
_BUTTONLAYOUT._options = None
_BUTTONLAYOUT._serialized_options = b'\222?\002 \000'
_BUTTONLAYOUTRIGHT._options = None
_BUTTONLAYOUTRIGHT._serialized_options = b'\222?\002 \000'
_SPLASHMODE._options = None
_SPLASHMODE._serialized_options = b'\222?\002 \000'
_SPLASHCHOICE._options = None
_SPLASHCHOICE._serialized_options = b'\222?\002 \000'
_ONBOARDLEDMODE._options = None
_ONBOARDLEDMODE._serialized_options = b'\222?\002 \000'
_INPUTMODE._options = None
_INPUTMODE._serialized_options = b'\222?\002 \000'
_DPADMODE._options = None
_DPADMODE._serialized_options = b'\222?\002 \000'
_SOCDMODE._options = None
_SOCDMODE._serialized_options = b'\222?\002 \000'
_GAMEPADHOTKEY._options = None
_GAMEPADHOTKEY._serialized_options = b'\222?\002 \000'
_SHMUPMIXMODE._options = None
_SHMUPMIXMODE._serialized_options = b'\222?\002 \000'
_PLEDTYPE._options = None
_PLEDTYPE._serialized_options = b'\222?\002 \000'
_FORCEDSETUPMODE._options = None
_FORCEDSETUPMODE._serialized_options = b'\222?\002 \000'
_BUTTONLAYOUT._serialized_start=30
_BUTTONLAYOUT._serialized_end=447
_BUTTONLAYOUTRIGHT._serialized_start=450
_BUTTONLAYOUTRIGHT._serialized_end=964
_SPLASHMODE._serialized_start=966
_SPLASHMODE._serialized_end=1087
_SPLASHCHOICE._serialized_start=1090
_SPLASHCHOICE._serialized_end=1250
_ONBOARDLEDMODE._serialized_start=1252
_ONBOARDLEDMODE._serialized_end=1374
_INPUTMODE._serialized_start=1377
_INPUTMODE._serialized_end=1530
_DPADMODE._serialized_start=1532
_DPADMODE._serialized_end=1627
_SOCDMODE._serialized_start=1630
_SOCDMODE._serialized_end=1792
_GAMEPADHOTKEY._serialized_start=1795
_GAMEPADHOTKEY._serialized_end=2220
_LEDFORMAT_PROTO._serialized_start=2222
_LEDFORMAT_PROTO._serialized_end=2321
_SHMUPMIXMODE._serialized_start=2323
_SHMUPMIXMODE._serialized_end=2415
_PLEDTYPE._serialized_start=2417
_PLEDTYPE._serialized_end=2501
_FORCEDSETUPMODE._serialized_start=2504
_FORCEDSETUPMODE._serialized_end=2667
# @@protoc_insertion_point(module_scope)

View File

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: nanopb.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cnanopb.proto\x1a google/protobuf/descriptor.proto\"\xc4\x07\n\rNanoPBOptions\x12\x10\n\x08max_size\x18\x01 \x01(\x05\x12\x12\n\nmax_length\x18\x0e \x01(\x05\x12\x11\n\tmax_count\x18\x02 \x01(\x05\x12&\n\x08int_size\x18\x07 \x01(\x0e\x32\x08.IntSize:\nIS_DEFAULT\x12$\n\x04type\x18\x03 \x01(\x0e\x32\n.FieldType:\nFT_DEFAULT\x12\x18\n\nlong_names\x18\x04 \x01(\x08:\x04true\x12\x1c\n\rpacked_struct\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0bpacked_enum\x18\n \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0cskip_message\x18\x06 \x01(\x08:\x05\x66\x61lse\x12\x18\n\tno_unions\x18\x08 \x01(\x08:\x05\x66\x61lse\x12\r\n\x05msgid\x18\t \x01(\r\x12\x1e\n\x0f\x61nonymous_oneof\x18\x0b \x01(\x08:\x05\x66\x61lse\x12\x15\n\x06proto3\x18\x0c \x01(\x08:\x05\x66\x61lse\x12#\n\x14proto3_singular_msgs\x18\x15 \x01(\x08:\x05\x66\x61lse\x12\x1d\n\x0e\x65num_to_string\x18\r \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0c\x66ixed_length\x18\x0f \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0b\x66ixed_count\x18\x10 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x0fsubmsg_callback\x18\x16 \x01(\x08:\x05\x66\x61lse\x12/\n\x0cmangle_names\x18\x11 \x01(\x0e\x32\x11.TypenameMangling:\x06M_NONE\x12(\n\x11\x63\x61llback_datatype\x18\x12 \x01(\t:\rpb_callback_t\x12\x34\n\x11\x63\x61llback_function\x18\x13 \x01(\t:\x19pb_default_field_callback\x12\x30\n\x0e\x64\x65scriptorsize\x18\x14 \x01(\x0e\x32\x0f.DescriptorSize:\x07\x44S_AUTO\x12\x1a\n\x0b\x64\x65\x66\x61ult_has\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x0f\n\x07include\x18\x18 \x03(\t\x12\x0f\n\x07\x65xclude\x18\x1a \x03(\t\x12\x0f\n\x07package\x18\x19 \x01(\t\x12\x41\n\rtype_override\x18\x1b \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x19\n\x0bsort_by_tag\x18\x1c \x01(\x08:\x04true\x12.\n\rfallback_type\x18\x1d \x01(\x0e\x32\n.FieldType:\x0b\x46T_CALLBACK\x12\x1e\n\x0f\x64isallow_export\x18\x1e \x01(\x08:\x05\x66\x61lse*i\n\tFieldType\x12\x0e\n\nFT_DEFAULT\x10\x00\x12\x0f\n\x0b\x46T_CALLBACK\x10\x01\x12\x0e\n\nFT_POINTER\x10\x04\x12\r\n\tFT_STATIC\x10\x02\x12\r\n\tFT_IGNORE\x10\x03\x12\r\n\tFT_INLINE\x10\x05*D\n\x07IntSize\x12\x0e\n\nIS_DEFAULT\x10\x00\x12\x08\n\x04IS_8\x10\x08\x12\t\n\x05IS_16\x10\x10\x12\t\n\x05IS_32\x10 \x12\t\n\x05IS_64\x10@*Z\n\x10TypenameMangling\x12\n\n\x06M_NONE\x10\x00\x12\x13\n\x0fM_STRIP_PACKAGE\x10\x01\x12\r\n\tM_FLATTEN\x10\x02\x12\x16\n\x12M_PACKAGE_INITIALS\x10\x03*E\n\x0e\x44\x65scriptorSize\x12\x0b\n\x07\x44S_AUTO\x10\x00\x12\x08\n\x04\x44S_1\x10\x01\x12\x08\n\x04\x44S_2\x10\x02\x12\x08\n\x04\x44S_4\x10\x04\x12\x08\n\x04\x44S_8\x10\x08:E\n\x0enanopb_fileopt\x12\x1c.google.protobuf.FileOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:G\n\rnanopb_msgopt\x12\x1f.google.protobuf.MessageOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:E\n\x0enanopb_enumopt\x12\x1c.google.protobuf.EnumOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:>\n\x06nanopb\x12\x1d.google.protobuf.FieldOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptionsB\x1a\n\x18\x66i.kapsi.koti.jpa.nanopb')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'nanopb_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(nanopb_fileopt)
google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(nanopb_msgopt)
google_dot_protobuf_dot_descriptor__pb2.EnumOptions.RegisterExtension(nanopb_enumopt)
google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(nanopb)
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\030fi.kapsi.koti.jpa.nanopb'
_FIELDTYPE._serialized_start=1017
_FIELDTYPE._serialized_end=1122
_INTSIZE._serialized_start=1124
_INTSIZE._serialized_end=1192
_TYPENAMEMANGLING._serialized_start=1194
_TYPENAMEMANGLING._serialized_end=1284
_DESCRIPTORSIZE._serialized_start=1286
_DESCRIPTORSIZE._serialized_end=1355
_NANOPBOPTIONS._serialized_start=51
_NANOPBOPTIONS._serialized_end=1015
# @@protoc_insertion_point(module_scope)

View File

@ -0,0 +1,426 @@
syntax = "proto2";
import "nanopb.proto";
import "enums.proto";
message GamepadOptions
{
optional InputMode inputMode = 1;
optional DpadMode dpadMode = 2;
optional SOCDMode socdMode = 3;
optional bool invertXAxis = 4;
optional bool invertYAxis = 5;
optional bool switchTpShareForDs4 = 6;
optional bool lockHotkeys = 7;
optional bool fourWayMode = 8;
}
message KeyboardMapping
{
optional uint32 keyDpadUp = 1;
optional uint32 keyDpadDown = 2;
optional uint32 keyDpadLeft = 3;
optional uint32 keyDpadRight = 4;
optional uint32 keyButtonB1 = 5;
optional uint32 keyButtonB2 = 6;
optional uint32 keyButtonB3 = 7;
optional uint32 keyButtonB4 = 8;
optional uint32 keyButtonL1 = 9;
optional uint32 keyButtonR1 = 10;
optional uint32 keyButtonL2 = 11;
optional uint32 keyButtonR2 = 12;
optional uint32 keyButtonS1 = 13;
optional uint32 keyButtonS2 = 14;
optional uint32 keyButtonL3 = 15;
optional uint32 keyButtonR3 = 16;
optional uint32 keyButtonA1 = 17;
optional uint32 keyButtonA2 = 18;
}
message HotkeyEntry
{
optional uint32 dpadMask = 1;
optional GamepadHotkey action = 2;
}
message HotkeyOptions
{
optional HotkeyEntry hotkeyF1Up = 1;
optional HotkeyEntry hotkeyF1Down = 2;
optional HotkeyEntry hotkeyF1Left = 3;
optional HotkeyEntry hotkeyF1Right = 4;
optional HotkeyEntry hotkeyF2Up = 5;
optional HotkeyEntry hotkeyF2Down = 6;
optional HotkeyEntry hotkeyF2Left = 7;
optional HotkeyEntry hotkeyF2Right = 8;
}
message ForcedSetupOptions
{
optional ForcedSetupMode mode = 1;
};
message ButtonLayoutParamsCommon
{
optional int32 startX = 1;
optional int32 startY = 2;
optional int32 buttonRadius = 3;
optional int32 buttonPadding = 4;
}
message ButtonLayoutParamsLeft
{
optional ButtonLayout layout = 1;
optional ButtonLayoutParamsCommon common = 2;
}
message ButtonLayoutParamsRight
{
optional ButtonLayoutRight layout = 1;
optional ButtonLayoutParamsCommon common = 2;
}
message ButtonLayoutCustomOptions
{
optional ButtonLayoutParamsLeft paramsLeft = 1;
optional ButtonLayoutParamsRight paramsRight = 2;
}
message PinMappings
{
optional int32 pinDpadUp = 1;
optional int32 pinDpadDown = 2;
optional int32 pinDpadLeft = 3;
optional int32 pinDpadRight = 4;
optional int32 pinButtonB1 = 5;
optional int32 pinButtonB2 = 6;
optional int32 pinButtonB3 = 7;
optional int32 pinButtonB4 = 8;
optional int32 pinButtonL1 = 9;
optional int32 pinButtonR1 = 10;
optional int32 pinButtonL2 = 11;
optional int32 pinButtonR2 = 12;
optional int32 pinButtonS1 = 13;
optional int32 pinButtonS2 = 14;
optional int32 pinButtonL3 = 15;
optional int32 pinButtonR3 = 16;
optional int32 pinButtonA1 = 17;
optional int32 pinButtonA2 = 18;
}
message DisplayOptions
{
optional bool enabled = 1;
optional int32 i2cBlock = 2;
optional int32 i2cSDAPin = 3;
optional int32 i2cSCLPin = 4;
optional int32 i2cAddress = 5;
optional int32 i2cSpeed = 6;
optional ButtonLayout buttonLayout = 7;
optional ButtonLayoutRight buttonLayoutRight = 8;
optional ButtonLayoutCustomOptions buttonLayoutCustomOptions = 9;
optional SplashMode splashMode = 10;
optional SplashChoice splashChoice = 11;
optional int32 splashDuration = 12;
optional bytes splashImage = 13 [(nanopb).max_size = 1024];
optional int32 size = 14;
optional int32 flip = 15;
optional bool invert = 16;
optional int32 displaySaverTimeout = 17;
}
message LEDOptions
{
optional int32 dataPin = 1;
optional LEDFormat_Proto ledFormat = 2;
optional ButtonLayout ledLayout = 3;
optional uint32 ledsPerButton = 4;
optional uint32 brightnessMaximum = 5;
optional uint32 brightnessSteps = 6;
optional int32 indexUp = 7;
optional int32 indexDown = 8;
optional int32 indexLeft = 9;
optional int32 indexRight = 10;
optional int32 indexB1 = 11;
optional int32 indexB2 = 12;
optional int32 indexB3 = 13;
optional int32 indexB4 = 14;
optional int32 indexL1 = 15;
optional int32 indexR1 = 16;
optional int32 indexL2 = 17;
optional int32 indexR2 = 18;
optional int32 indexS1 = 19;
optional int32 indexS2 = 20;
optional int32 indexL3 = 21;
optional int32 indexR3 = 22;
optional int32 indexA1 = 23;
optional int32 indexA2 = 24;
optional PLEDType pledType = 25;
optional int32 pledPin1 = 26;
optional int32 pledPin2 = 27;
optional int32 pledPin3 = 28;
optional int32 pledPin4 = 29;
optional uint32 pledColor = 30;
};
// This has to be kept in sync with AnimationOptions in AnimationStation.hpp
message AnimationOptions_Proto
{
optional uint32 baseAnimationIndex = 1;
optional uint32 brightness = 2;
optional uint32 staticColorIndex = 3;
optional uint32 buttonColorIndex = 4;
optional int32 chaseCycleTime = 5;
optional int32 rainbowCycleTime = 6;
optional uint32 themeIndex = 7;
optional bool hasCustomTheme = 8;
optional uint32 customThemeUp = 9;
optional uint32 customThemeDown = 10;
optional uint32 customThemeLeft = 11;
optional uint32 customThemeRight = 12;
optional uint32 customThemeB1 = 13;
optional uint32 customThemeB2 = 14;
optional uint32 customThemeB3 = 15;
optional uint32 customThemeB4 = 16;
optional uint32 customThemeL1 = 17;
optional uint32 customThemeR1 = 18;
optional uint32 customThemeL2 = 19;
optional uint32 customThemeR2 = 20;
optional uint32 customThemeS1 = 21;
optional uint32 customThemeS2 = 22;
optional uint32 customThemeL3 = 23;
optional uint32 customThemeR3 = 24;
optional uint32 customThemeA1 = 25;
optional uint32 customThemeA2 = 26;
optional uint32 customThemeUpPressed = 27;
optional uint32 customThemeDownPressed = 28;
optional uint32 customThemeLeftPressed = 29;
optional uint32 customThemeRightPressed = 30;
optional uint32 customThemeB1Pressed = 31;
optional uint32 customThemeB2Pressed = 32;
optional uint32 customThemeB3Pressed = 33;
optional uint32 customThemeB4Pressed = 34;
optional uint32 customThemeL1Pressed = 35;
optional uint32 customThemeR1Pressed = 36;
optional uint32 customThemeL2Pressed = 37;
optional uint32 customThemeR2Pressed = 38;
optional uint32 customThemeS1Pressed = 39;
optional uint32 customThemeS2Pressed = 40;
optional uint32 customThemeL3Pressed = 41;
optional uint32 customThemeR3Pressed = 42;
optional uint32 customThemeA1Pressed = 43;
optional uint32 customThemeA2Pressed = 44;
}
message BootselButtonOptions
{
optional bool enabled = 1;
optional uint32 buttonMap = 2;
}
message OnBoardLedOptions
{
optional OnBoardLedMode mode = 1;
optional bool enabled = 2;
}
message AnalogOptions
{
optional bool enabled = 1;
optional int32 analogAdcPinX = 2;
optional int32 analogAdcPinY = 3;
optional bool forced_circularity = 4;
optional uint32 analog_deadzone = 5;
}
message TurboOptions
{
optional bool enabled = 1;
optional int32 buttonPin = 2;
optional int32 ledPin = 3;
optional uint32 shotCount = 4;
optional int32 shmupDialPin = 5;
optional bool shmupModeEnabled = 6;
optional uint32 shmupAlwaysOn1 = 7;
optional uint32 shmupAlwaysOn2 = 8;
optional uint32 shmupAlwaysOn3 = 9;
optional uint32 shmupAlwaysOn4 = 10;
optional int32 shmupBtn1Pin = 11;
optional int32 shmupBtn2Pin = 12;
optional int32 shmupBtn3Pin = 13;
optional int32 shmupBtn4Pin = 14;
optional uint32 shmupBtnMask1 = 15;
optional uint32 shmupBtnMask2 = 16;
optional uint32 shmupBtnMask3 = 17;
optional uint32 shmupBtnMask4 = 18;
optional ShmupMixMode shmupMixMode = 19;
}
message SliderOptions
{
optional bool enabled = 1;
optional int32 pinLS = 2;
optional int32 pinRS = 3;
}
message SOCDSliderOptions
{
optional bool enabled = 1;
optional int32 pinOne = 2;
optional int32 pinTwo = 3;
optional SOCDMode modeDefault = 4;
optional SOCDMode modeOne = 5;
optional SOCDMode modeTwo = 6;
}
message ReverseOptions
{
optional bool enabled = 1;
optional int32 buttonPin = 2;
optional int32 ledPin = 3;
optional uint32 actionUp = 4;
optional uint32 actionDown = 5;
optional uint32 actionLeft = 6;
optional uint32 actionRight = 7;
}
message AnalogADS1219Options
{
optional bool enabled = 1;
optional int32 i2cBlock = 2;
optional int32 i2cSDAPin = 3;
optional int32 i2cSCLPin = 4;
optional int32 i2cAddress = 5;
optional int32 i2cSpeed = 6;
}
message DualDirectionalOptions
{
optional bool enabled = 1;
optional int32 upPin = 2;
optional int32 downPin = 3;
optional int32 leftPin = 4;
optional int32 rightPin = 5;
optional DpadMode dpadMode = 6;
optional uint32 combineMode = 7;
optional bool fourWayMode = 8;
}
message BuzzerOptions
{
optional bool enabled = 1;
optional int32 pin = 2;
optional uint32 volume = 3;
}
message ExtraButtonOptions
{
optional bool enabled = 1;
optional int32 pin = 2;
optional uint32 buttonMap = 3;
}
message PlayerNumberOptions
{
optional bool enabled = 1;
optional uint32 number = 2;
}
message PS4Options
{
optional bool enabled = 1;
optional bytes serial = 2 [(nanopb).max_size = 16];
optional bytes signature = 3 [(nanopb).max_size = 256];
optional bytes rsaN = 4 [(nanopb).max_size = 256];
optional bytes rsaE = 5 [(nanopb).max_size = 4];
optional bytes rsaD = 6 [(nanopb).max_size = 256];
optional bytes rsaP = 7 [(nanopb).max_size = 128];
optional bytes rsaQ = 8 [(nanopb).max_size = 128];
optional bytes rsaDP = 9 [(nanopb).max_size = 128];
optional bytes rsaDQ = 10 [(nanopb).max_size = 128];
optional bytes rsaQP = 11 [(nanopb).max_size = 128];
optional bytes rsaRN = 12 [(nanopb).max_size = 256];
}
message WiiOptions
{
optional bool enabled = 1;
optional int32 i2cBlock = 2;
optional int32 i2cSDAPin = 3;
optional int32 i2cSCLPin = 4;
optional int32 i2cSpeed = 5;
}
message SNESOptions
{
optional bool enabled = 1;
optional int32 clockPin = 2;
optional int32 latchPin = 3;
optional int32 dataPin = 4;
}
message FocusModeOptions
{
optional bool enabled = 1;
optional int32 pin = 2;
optional int32 buttonLockMask = 3;
optional bool oledLockEnabled = 4;
optional bool rgbLockEnabled = 5;
optional bool buttonLockEnabled = 6;
}
message AddonOptions
{
optional BootselButtonOptions bootselButtonOptions = 1;
optional OnBoardLedOptions onBoardLedOptions = 2;
optional AnalogOptions analogOptions = 3;
optional TurboOptions turboOptions = 4;
optional SliderOptions sliderOptions = 5;
optional ReverseOptions reverseOptions = 6;
optional AnalogADS1219Options analogADS1219Options = 7;
optional DualDirectionalOptions dualDirectionalOptions = 8;
optional BuzzerOptions buzzerOptions = 9;
optional ExtraButtonOptions extraButtonOptions = 10;
optional PlayerNumberOptions playerNumberOptions = 11;
optional PS4Options ps4Options = 12 [(nanopb).disallow_export = true];
optional WiiOptions wiiOptions = 13;
optional SOCDSliderOptions socdSliderOptions = 14;
optional SNESOptions snesOptions = 15;
optional FocusModeOptions focusModeOptions = 16;
}
message Config
{
optional string boardVersion = 1 [(nanopb).max_length = 31];
optional GamepadOptions gamepadOptions = 2;
optional HotkeyOptions hotkeyOptions = 3;
optional PinMappings pinMappings = 4;
optional KeyboardMapping keyboardMapping = 5;
optional DisplayOptions displayOptions = 6;
optional LEDOptions ledOptions = 7;
optional AnimationOptions_Proto animationOptions = 8;
optional AddonOptions addonOptions = 9;
optional ForcedSetupOptions forcedSetupOptions = 10;
}

View File

@ -0,0 +1,165 @@
syntax = "proto2";
import "nanopb.proto";
enum ButtonLayout
{
option (nanopb_enumopt).long_names = false;
BUTTON_LAYOUT_STICK = 0;
BUTTON_LAYOUT_STICKLESS = 1;
BUTTON_LAYOUT_BUTTONS_ANGLED = 2;
BUTTON_LAYOUT_BUTTONS_BASIC = 3;
BUTTON_LAYOUT_KEYBOARD_ANGLED = 4;
BUTTON_LAYOUT_KEYBOARDA = 5;
BUTTON_LAYOUT_DANCEPADA = 6;
BUTTON_LAYOUT_TWINSTICKA = 7;
BUTTON_LAYOUT_BLANKA = 8;
BUTTON_LAYOUT_VLXA = 9;
BUTTON_LAYOUT_FIGHTBOARD_STICK = 10;
BUTTON_LAYOUT_FIGHTBOARD_MIRRORED = 11;
BUTTON_LAYOUT_CUSTOMA = 12;
}
enum ButtonLayoutRight
{
option (nanopb_enumopt).long_names = false;
BUTTON_LAYOUT_ARCADE = 0;
BUTTON_LAYOUT_STICKLESSB = 1;
BUTTON_LAYOUT_BUTTONS_ANGLEDB = 2;
BUTTON_LAYOUT_VEWLIX = 3;
BUTTON_LAYOUT_VEWLIX7 = 4;
BUTTON_LAYOUT_CAPCOM = 5;
BUTTON_LAYOUT_CAPCOM6 = 6;
BUTTON_LAYOUT_SEGA2P = 7;
BUTTON_LAYOUT_NOIR8 = 8;
BUTTON_LAYOUT_KEYBOARDB = 9;
BUTTON_LAYOUT_DANCEPADB = 10;
BUTTON_LAYOUT_TWINSTICKB = 11;
BUTTON_LAYOUT_BLANKB = 12;
BUTTON_LAYOUT_VLXB = 13;
BUTTON_LAYOUT_FIGHTBOARD = 14;
BUTTON_LAYOUT_FIGHTBOARD_STICK_MIRRORED = 15;
BUTTON_LAYOUT_CUSTOMB = 16;
}
enum SplashMode
{
option (nanopb_enumopt).long_names = false;
SPLASH_MODE_STATIC = 0;
SPLASH_MODE_CLOSEIN = 1;
SPLASH_MODE_CLOSEINCUSTOM = 2;
SPLASH_MODE_NONE = 3;
}
enum SplashChoice
{
option (nanopb_enumopt).long_names = false;
SPLASH_CHOICE_MAIN = 0;
SPLASH_CHOICE_X = 1;
SPLASH_CHOICE_Y = 2;
SPLASH_CHOICE_Z = 3;
SPLASH_CHOICE_CUSTOM = 4;
SPLASH_CHOICE_LEGACY = 5;
}
enum OnBoardLedMode
{
option (nanopb_enumopt).long_names = false;
ON_BOARD_LED_MODE_OFF = 0;
ON_BOARD_LED_MODE_MODE_INDICATOR = 1;
ON_BOARD_LED_MODE_INPUT_TEST = 2;
}
enum InputMode
{
option (nanopb_enumopt).long_names = false;
INPUT_MODE_XINPUT = 0;
INPUT_MODE_SWITCH = 1;
INPUT_MODE_HID = 2;
INPUT_MODE_KEYBOARD = 3;
INPUT_MODE_PS4 = 4;
INPUT_MODE_CONFIG = 255;
}
enum DpadMode
{
option (nanopb_enumopt).long_names = false;
DPAD_MODE_DIGITAL = 0;
DPAD_MODE_LEFT_ANALOG = 1;
DPAD_MODE_RIGHT_ANALOG = 2;
}
enum SOCDMode
{
option (nanopb_enumopt).long_names = false;
SOCD_MODE_UP_PRIORITY = 0; // U+D=U, L+R=N
SOCD_MODE_NEUTRAL = 1; // U+D=N, L+R=N
SOCD_MODE_SECOND_INPUT_PRIORITY = 2; // U>D=D, L>R=R (Last Input Priority, aka Last Win)
SOCD_MODE_FIRST_INPUT_PRIORITY = 3; // U>D=U, L>R=L (First Input Priority, aka First Win)
SOCD_MODE_BYPASS = 4; // U+D=UD, L+R=LR (No cleaning applied)
}
enum GamepadHotkey
{
option (nanopb_enumopt).long_names = false;
HOTKEY_NONE = 0;
HOTKEY_DPAD_DIGITAL = 1;
HOTKEY_DPAD_LEFT_ANALOG = 2;
HOTKEY_DPAD_RIGHT_ANALOG = 3;
HOTKEY_HOME_BUTTON = 4;
HOTKEY_CAPTURE_BUTTON = 5;
HOTKEY_SOCD_UP_PRIORITY = 6;
HOTKEY_SOCD_NEUTRAL = 7;
HOTKEY_SOCD_LAST_INPUT = 8;
HOTKEY_INVERT_X_AXIS = 9;
HOTKEY_INVERT_Y_AXIS = 10;
HOTKEY_SOCD_FIRST_INPUT = 11;
HOTKEY_SOCD_BYPASS = 12;
HOTKEY_TOGGLE_4_WAY_MODE = 13;
HOTKEY_TOGGLE_DDI_4_WAY_MODE = 14;
}
// This has to be kept in sync with LEDFormat in NeoPico.hpp
enum LEDFormat_Proto
{
LED_FORMAT_GRB = 0;
LED_FORMAT_RGB = 1;
LED_FORMAT_GRBW = 2;
LED_FORMAT_RGBW = 3;
}
enum ShmupMixMode
{
option (nanopb_enumopt).long_names = false;
SHMUP_MIX_MODE_TURBO_PRIORITY = 0;
SHMUP_MIX_MODE_CHARGE_PRIORITY = 1;
}
enum PLEDType
{
option (nanopb_enumopt).long_names = false;
PLED_TYPE_NONE = -1;
PLED_TYPE_PWM = 0;
PLED_TYPE_RGB = 1;
};
enum ForcedSetupMode
{
option (nanopb_enumopt).long_names = false;
FORCED_SETUP_MODE_OFF = 0;
FORCED_SETUP_MODE_LOCK_MODE_SWITCH = 1;
FORCED_SETUP_MODE_LOCK_WEB_CONFIG = 2;
FORCED_SETUP_MODE_LOCK_BOTH = 3;
};

View File

@ -0,0 +1,189 @@
// Custom options for defining:
// - Maximum size of string/bytes
// - Maximum number of elements in array
//
// These are used by nanopb to generate statically allocable structures
// for memory-limited environments.
syntax = "proto2";
import "google/protobuf/descriptor.proto";
option java_package = "fi.kapsi.koti.jpa.nanopb";
enum FieldType {
FT_DEFAULT = 0; // Automatically decide field type, generate static field if possible.
FT_CALLBACK = 1; // Always generate a callback field.
FT_POINTER = 4; // Always generate a dynamically allocated field.
FT_STATIC = 2; // Generate a static field or raise an exception if not possible.
FT_IGNORE = 3; // Ignore the field completely.
FT_INLINE = 5; // Legacy option, use the separate 'fixed_length' option instead
}
enum IntSize {
IS_DEFAULT = 0; // Default, 32/64bit based on type in .proto
IS_8 = 8;
IS_16 = 16;
IS_32 = 32;
IS_64 = 64;
}
enum TypenameMangling {
M_NONE = 0; // Default, no typename mangling
M_STRIP_PACKAGE = 1; // Strip current package name
M_FLATTEN = 2; // Only use last path component
M_PACKAGE_INITIALS = 3; // Replace the package name by the initials
}
enum DescriptorSize {
DS_AUTO = 0; // Select minimal size based on field type
DS_1 = 1; // 1 word; up to 15 byte fields, no arrays
DS_2 = 2; // 2 words; up to 4095 byte fields, 4095 entry arrays
DS_4 = 4; // 4 words; up to 2^32-1 byte fields, 2^16-1 entry arrays
DS_8 = 8; // 8 words; up to 2^32-1 entry arrays
}
// This is the inner options message, which basically defines options for
// a field. When it is used in message or file scope, it applies to all
// fields.
message NanoPBOptions {
// Allocated size for 'bytes' and 'string' fields.
// For string fields, this should include the space for null terminator.
optional int32 max_size = 1;
// Maximum length for 'string' fields. Setting this is equivalent
// to setting max_size to a value of length+1.
optional int32 max_length = 14;
// Allocated number of entries in arrays ('repeated' fields)
optional int32 max_count = 2;
// Size of integer fields. Can save some memory if you don't need
// full 32 bits for the value.
optional IntSize int_size = 7 [default = IS_DEFAULT];
// Force type of field (callback or static allocation)
optional FieldType type = 3 [default = FT_DEFAULT];
// Use long names for enums, i.e. EnumName_EnumValue.
optional bool long_names = 4 [default = true];
// Add 'packed' attribute to generated structs.
// Note: this cannot be used on CPUs that break on unaligned
// accesses to variables.
optional bool packed_struct = 5 [default = false];
// Add 'packed' attribute to generated enums.
optional bool packed_enum = 10 [default = false];
// Skip this message
optional bool skip_message = 6 [default = false];
// Generate oneof fields as normal optional fields instead of union.
optional bool no_unions = 8 [default = false];
// integer type tag for a message
optional uint32 msgid = 9;
// decode oneof as anonymous union
optional bool anonymous_oneof = 11 [default = false];
// Proto3 singular field does not generate a "has_" flag
optional bool proto3 = 12 [default = false];
// Force proto3 messages to have no "has_" flag.
// This was default behavior until nanopb-0.4.0.
optional bool proto3_singular_msgs = 21 [default = false];
// Generate an enum->string mapping function (can take up lots of space).
optional bool enum_to_string = 13 [default = false];
// Generate bytes arrays with fixed length
optional bool fixed_length = 15 [default = false];
// Generate repeated field with fixed count
optional bool fixed_count = 16 [default = false];
// Generate message-level callback that is called before decoding submessages.
// This can be used to set callback fields for submsgs inside oneofs.
optional bool submsg_callback = 22 [default = false];
// Shorten or remove package names from type names.
// This option applies only on the file level.
optional TypenameMangling mangle_names = 17 [default = M_NONE];
// Data type for storage associated with callback fields.
optional string callback_datatype = 18 [default = "pb_callback_t"];
// Callback function used for encoding and decoding.
// Prior to nanopb-0.4.0, the callback was specified in per-field pb_callback_t
// structure. This is still supported, but does not work inside e.g. oneof or pointer
// fields. Instead, a new method allows specifying a per-message callback that
// will be called for all callback fields in a message type.
optional string callback_function = 19 [default = "pb_default_field_callback"];
// Select the size of field descriptors. This option has to be defined
// for the whole message, not per-field. Usually automatic selection is
// ok, but if it results in compilation errors you can increase the field
// size here.
optional DescriptorSize descriptorsize = 20 [default = DS_AUTO];
// Set default value for has_ fields.
optional bool default_has = 23 [default = false];
// Extra files to include in generated `.pb.h`
repeated string include = 24;
// Automatic includes to exclude from generated `.pb.h`
// Same as nanopb_generator.py command line flag -x.
repeated string exclude = 26;
// Package name that applies only for nanopb.
optional string package = 25;
// Override type of the field in generated C code. Only to be used with related field types
optional google.protobuf.FieldDescriptorProto.Type type_override = 27;
// Due to historical reasons, nanopb orders fields in structs by their tag number
// instead of the order in .proto. Set this to false to keep the .proto order.
// The default value will probably change to false in nanopb-0.5.0.
optional bool sort_by_tag = 28 [default = true];
// Set the FT_DEFAULT field conversion strategy.
// A field that can become a static member of a c struct (e.g. int, bool, etc)
// will be a a static field.
// Fields with dynamic length are converted to either a pointer or a callback.
optional FieldType fallback_type = 29 [default = FT_CALLBACK];
// GP2040-CE extension
// Marks a field to be excluded when performing export operations (i.e. converting to JSON)
optional bool disallow_export = 30 [default = false];
}
// Extensions to protoc 'Descriptor' type in order to define options
// inside a .proto file.
//
// Protocol Buffers extension number registry
// --------------------------------
// Project: Nanopb
// Contact: Petteri Aimonen <jpa@kapsi.fi>
// Web site: http://kapsi.fi/~jpa/nanopb
// Extensions: 1010 (all types)
// --------------------------------
extend google.protobuf.FileOptions {
optional NanoPBOptions nanopb_fileopt = 1010;
}
extend google.protobuf.MessageOptions {
optional NanoPBOptions nanopb_msgopt = 1010;
}
extend google.protobuf.EnumOptions {
optional NanoPBOptions nanopb_enumopt = 1010;
}
extend google.protobuf.FieldOptions {
optional NanoPBOptions nanopb = 1010;
}

45
tests/test_package.py Normal file
View File

@ -0,0 +1,45 @@
"""Test high level package capabilities."""
import os
import sys
import pytest
from gp2040ce_bintools import get_config_pb2
HERE = os.path.dirname(os.path.abspath(__file__))
def test_get_config_pb2_compile():
"""Without any precompiled files on the path, test we can read proto files and compile them."""
# append to path as -P would
proto_path = os.path.join(HERE, 'test-files', 'proto-files')
sys.path.append(proto_path)
# let grpc tools compile the proto files on demand and give us the module
config_pb2 = get_config_pb2()
_ = config_pb2.Config()
# clean up the path and unload config_pb2
sys.path.pop()
sys.path.pop()
del sys.modules['config_pb2']
def test_get_config_pb2_exception():
"""Without any precompiled files or proto files on the path, test we raise an exception."""
with pytest.raises(ModuleNotFoundError):
_ = get_config_pb2()
def test_get_config_pb2_precompile():
"""Test we can import precompiled protobuf files."""
proto_path = os.path.join(HERE, 'test-files', 'pb2-files')
sys.path.append(proto_path)
# let grpc tools import the proto files normally
config_pb2 = get_config_pb2()
_ = config_pb2.Config()
# clean up the path and unload config_pb2
sys.path.pop()
del sys.modules['config_pb2']