mirror of
https://github.com/esphome/esphome.git
synced 2026-08-23 06:36:23 +00:00
[esp32] refactor esp32-vfs default configs to FINAL co-routine & add some defaults (#17337)
Co-authored-by: Oliver Kleinecke <kleinecke.oliver@googlemail.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: storage split <ai@local> Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Oliver Kleinecke
Claude Sonnet 4.6
Copilot Autofix powered by AI
storage split
pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
parent
c0e70d9beb
commit
b326cefea7
@@ -10,11 +10,16 @@ from typing import Any
|
||||
import pytest
|
||||
|
||||
from esphome.components.esp32 import (
|
||||
KEY_FATFS_REQUIRED,
|
||||
KEY_VFS_DIR_REQUIRED,
|
||||
KEY_VFS_SELECT_REQUIRED,
|
||||
KEY_VFS_TERMIOS_REQUIRED,
|
||||
VARIANT_ESP32,
|
||||
VARIANTS,
|
||||
NetworkSdkconfigData,
|
||||
_ota_downgrade_protection_errors,
|
||||
_reconcile_network_sdkconfig,
|
||||
_reconcile_vfs_fatfs_sdkconfig,
|
||||
)
|
||||
from esphome.components.esp32.const import (
|
||||
KEY_ESP32,
|
||||
@@ -614,6 +619,160 @@ def test_reconcile_network_sdkconfig(
|
||||
assert CORE.data[KEY_ESP32][KEY_SDKCONFIG_OPTIONS] == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("requires", "fatfs_required", "disables", "preset", "expected"),
|
||||
[
|
||||
# Nothing required and every disable_* flag off (NOT the shipped defaults, which
|
||||
# disable everything): VFS enabled, FATFS left untouched entirely.
|
||||
pytest.param(
|
||||
{},
|
||||
False,
|
||||
(False, False, False, False),
|
||||
{},
|
||||
{
|
||||
"CONFIG_VFS_SUPPORT_TERMIOS": True,
|
||||
"CONFIG_VFS_SUPPORT_SELECT": True,
|
||||
"CONFIG_VFS_SUPPORT_DIR": True,
|
||||
},
|
||||
id="nothing_disabled_nothing_required",
|
||||
),
|
||||
# The shipped out-of-the-box path: every disable_* flag defaults to True and nothing
|
||||
# is required -- VFS off, FATFS at the smallest footprint (8.3 names, one volume).
|
||||
pytest.param(
|
||||
{},
|
||||
False,
|
||||
(True, True, True, True),
|
||||
{},
|
||||
{
|
||||
"CONFIG_VFS_SUPPORT_TERMIOS": False,
|
||||
"CONFIG_VFS_SUPPORT_SELECT": False,
|
||||
"CONFIG_VFS_SUPPORT_DIR": False,
|
||||
"CONFIG_FATFS_LFN_NONE": True,
|
||||
"CONFIG_FATFS_VOLUME_COUNT": 1,
|
||||
},
|
||||
id="all_disabled_fatfs_fallback",
|
||||
),
|
||||
# A component's require_* beats the user's disable_* flag for every VFS feature.
|
||||
pytest.param(
|
||||
{
|
||||
KEY_VFS_TERMIOS_REQUIRED: True,
|
||||
KEY_VFS_SELECT_REQUIRED: True,
|
||||
KEY_VFS_DIR_REQUIRED: True,
|
||||
},
|
||||
False,
|
||||
(True, True, True, False),
|
||||
{},
|
||||
{
|
||||
"CONFIG_VFS_SUPPORT_TERMIOS": True,
|
||||
"CONFIG_VFS_SUPPORT_SELECT": True,
|
||||
"CONFIG_VFS_SUPPORT_DIR": True,
|
||||
},
|
||||
id="require_beats_disable",
|
||||
),
|
||||
# A user sdkconfig_options preset wins over a require (the set_opt guard).
|
||||
pytest.param(
|
||||
{KEY_VFS_SELECT_REQUIRED: True},
|
||||
False,
|
||||
(False, False, False, False),
|
||||
{"CONFIG_VFS_SUPPORT_SELECT": False},
|
||||
{
|
||||
"CONFIG_VFS_SUPPORT_TERMIOS": True,
|
||||
"CONFIG_VFS_SUPPORT_SELECT": False,
|
||||
"CONFIG_VFS_SUPPORT_DIR": True,
|
||||
},
|
||||
id="user_preset_wins_over_require",
|
||||
),
|
||||
# require_fatfs() with no user preset: long filenames on the heap, 255 chars,
|
||||
# four volumes.
|
||||
pytest.param(
|
||||
{},
|
||||
True,
|
||||
(False, False, False, False),
|
||||
{},
|
||||
{
|
||||
"CONFIG_VFS_SUPPORT_TERMIOS": True,
|
||||
"CONFIG_VFS_SUPPORT_SELECT": True,
|
||||
"CONFIG_VFS_SUPPORT_DIR": True,
|
||||
"CONFIG_FATFS_LFN_NONE": False,
|
||||
"CONFIG_FATFS_LFN_HEAP": True,
|
||||
"CONFIG_FATFS_MAX_LFN": 255,
|
||||
"CONFIG_FATFS_VOLUME_COUNT": 4,
|
||||
},
|
||||
id="fatfs_required_defaults",
|
||||
),
|
||||
# CONFIG_FATFS_LONG_FILENAMES is a Kconfig choice: a user picking any member
|
||||
# (here LFN_STACK) leaves the whole group untouched -- no second =y in the choice.
|
||||
pytest.param(
|
||||
{},
|
||||
True,
|
||||
(False, False, False, False),
|
||||
{"CONFIG_FATFS_LFN_STACK": "y"},
|
||||
{
|
||||
"CONFIG_VFS_SUPPORT_TERMIOS": True,
|
||||
"CONFIG_VFS_SUPPORT_SELECT": True,
|
||||
"CONFIG_VFS_SUPPORT_DIR": True,
|
||||
"CONFIG_FATFS_LFN_STACK": "y",
|
||||
"CONFIG_FATFS_VOLUME_COUNT": 4,
|
||||
},
|
||||
id="fatfs_user_lfn_stack_untouched",
|
||||
),
|
||||
# disable_fatfs (the shipped default) with a user LFN pick: the choice group is the
|
||||
# user's -- no LFN_NONE=y written next to their member, only the volume fallback.
|
||||
pytest.param(
|
||||
{},
|
||||
False,
|
||||
(False, False, False, True),
|
||||
{"CONFIG_FATFS_LFN_HEAP": "y"},
|
||||
{
|
||||
"CONFIG_VFS_SUPPORT_TERMIOS": True,
|
||||
"CONFIG_VFS_SUPPORT_SELECT": True,
|
||||
"CONFIG_VFS_SUPPORT_DIR": True,
|
||||
"CONFIG_FATFS_LFN_HEAP": "y",
|
||||
"CONFIG_FATFS_VOLUME_COUNT": 1,
|
||||
},
|
||||
id="disable_fatfs_user_lfn_untouched",
|
||||
),
|
||||
# Same for an explicit LFN_NONE preset: the group is the user's, only the volume
|
||||
# count default is added.
|
||||
pytest.param(
|
||||
{},
|
||||
True,
|
||||
(False, False, False, False),
|
||||
{"CONFIG_FATFS_LFN_NONE": "y"},
|
||||
{
|
||||
"CONFIG_VFS_SUPPORT_TERMIOS": True,
|
||||
"CONFIG_VFS_SUPPORT_SELECT": True,
|
||||
"CONFIG_VFS_SUPPORT_DIR": True,
|
||||
"CONFIG_FATFS_LFN_NONE": "y",
|
||||
"CONFIG_FATFS_VOLUME_COUNT": 4,
|
||||
},
|
||||
id="fatfs_user_lfn_none_untouched",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_reconcile_vfs_fatfs_sdkconfig(
|
||||
set_core_config: SetCoreConfigCallable,
|
||||
requires: dict[str, bool],
|
||||
fatfs_required: bool,
|
||||
disables: tuple[bool, bool, bool, bool],
|
||||
preset: dict[str, Any],
|
||||
expected: dict[str, Any],
|
||||
) -> None:
|
||||
"""The FINAL-priority reconciler resolves the VFS feature flags and the FATFS
|
||||
defaults from the recorded require_* calls, with user sdkconfig_options winning
|
||||
and the LFN Kconfig choice treated as one group."""
|
||||
set_core_config(PlatformFramework.ESP32_IDF)
|
||||
CORE.data[KEY_ESP32] = {KEY_SDKCONFIG_OPTIONS: dict(preset)}
|
||||
if fatfs_required:
|
||||
CORE.data[KEY_ESP32][KEY_FATFS_REQUIRED] = True
|
||||
for key, value in requires.items():
|
||||
CORE.data[key] = value
|
||||
|
||||
asyncio.run(_reconcile_vfs_fatfs_sdkconfig(*disables))
|
||||
|
||||
assert CORE.data[KEY_ESP32][KEY_SDKCONFIG_OPTIONS] == expected
|
||||
|
||||
|
||||
def test_network_wifi_only_reconciles_end_to_end(
|
||||
generate_main: Callable[[str | Path], str],
|
||||
component_config_path: Callable[[str], Path],
|
||||
|
||||
Reference in New Issue
Block a user