mirror of
https://github.com/esphome/esphome.git
synced 2026-09-20 11:38:48 +00:00
[core] Attribute placement new storage symbols to components (#15092)
This commit is contained in:
@@ -8,7 +8,7 @@ def test_deep_sleep_setup(generate_main):
|
||||
main_cpp = generate_main("tests/component_tests/deep_sleep/test_deep_sleep1.yaml")
|
||||
|
||||
assert (
|
||||
"static deep_sleep::DeepSleepComponent *const deepsleep = reinterpret_cast<deep_sleep::DeepSleepComponent *>(deepsleep__pstorage);"
|
||||
"static deep_sleep::DeepSleepComponent *const deepsleep = reinterpret_cast<deep_sleep::DeepSleepComponent *>(deep_sleep__deepsleep__pstorage);"
|
||||
in main_cpp
|
||||
)
|
||||
assert "new(deepsleep) deep_sleep::DeepSleepComponent();" in main_cpp
|
||||
|
||||
@@ -242,11 +242,11 @@ def test_image_generation(
|
||||
main_cpp = generate_main(component_config_path("image_test.yaml"))
|
||||
assert "uint8_t_id[] PROGMEM = {0x24, 0x21, 0x24, 0x21" in main_cpp
|
||||
assert (
|
||||
"alignas(image::Image) static unsigned char cat_img__pstorage[sizeof(image::Image)];"
|
||||
"alignas(image::Image) static unsigned char image__cat_img__pstorage[sizeof(image::Image)];"
|
||||
in main_cpp
|
||||
)
|
||||
assert (
|
||||
"static image::Image *const cat_img = reinterpret_cast<image::Image *>(cat_img__pstorage);"
|
||||
"static image::Image *const cat_img = reinterpret_cast<image::Image *>(image__cat_img__pstorage);"
|
||||
in main_cpp
|
||||
)
|
||||
assert (
|
||||
|
||||
@@ -119,11 +119,11 @@ def test_code_generation(
|
||||
|
||||
main_cpp = generate_main(component_fixture_path("mipi_dsi.yaml"))
|
||||
assert (
|
||||
"alignas(mipi_dsi::MIPI_DSI) static unsigned char p4_nano__pstorage[sizeof(mipi_dsi::MIPI_DSI)];"
|
||||
"alignas(mipi_dsi::MIPI_DSI) static unsigned char mipi_dsi__p4_nano__pstorage[sizeof(mipi_dsi::MIPI_DSI)];"
|
||||
in main_cpp
|
||||
)
|
||||
assert (
|
||||
"static mipi_dsi::MIPI_DSI *const p4_nano = reinterpret_cast<mipi_dsi::MIPI_DSI *>(p4_nano__pstorage);"
|
||||
"static mipi_dsi::MIPI_DSI *const p4_nano = reinterpret_cast<mipi_dsi::MIPI_DSI *>(mipi_dsi__p4_nano__pstorage);"
|
||||
in main_cpp
|
||||
)
|
||||
assert (
|
||||
|
||||
@@ -13,11 +13,11 @@ def test_status_led_generation(
|
||||
"""Test status_led generation."""
|
||||
main_cpp = generate_main(component_config_path("status_led_test.yaml"))
|
||||
assert (
|
||||
"alignas(status_led::StatusLED) static unsigned char status_led_statusled_id__pstorage[sizeof(status_led::StatusLED)];"
|
||||
"alignas(status_led::StatusLED) static unsigned char status_led__status_led_statusled_id__pstorage[sizeof(status_led::StatusLED)];"
|
||||
in main_cpp
|
||||
)
|
||||
assert (
|
||||
"static status_led::StatusLED *const status_led_statusled_id = reinterpret_cast<status_led::StatusLED *>(status_led_statusled_id__pstorage);"
|
||||
"static status_led::StatusLED *const status_led_statusled_id = reinterpret_cast<status_led::StatusLED *>(status_led__status_led_statusled_id__pstorage);"
|
||||
in main_cpp
|
||||
)
|
||||
assert "new(status_led_statusled_id) status_led::StatusLED(" in main_cpp
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
"""Tests for __pstorage symbol attribution in memory analyzer."""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from esphome.analyze_memory import _PSTORAGE_SUFFIX, MemoryAnalyzer
|
||||
|
||||
|
||||
def _make_analyzer(external_components: set[str] | None = None) -> MemoryAnalyzer:
|
||||
"""Create a MemoryAnalyzer with mocked dependencies."""
|
||||
with patch.object(MemoryAnalyzer, "__init__", lambda self, *a, **kw: None):
|
||||
analyzer = MemoryAnalyzer.__new__(MemoryAnalyzer)
|
||||
analyzer.external_components = external_components or set()
|
||||
return analyzer
|
||||
|
||||
|
||||
def test_pstorage_suffix_constant() -> None:
|
||||
"""Verify the suffix constant matches what codegen produces."""
|
||||
assert _PSTORAGE_SUFFIX == "__pstorage"
|
||||
|
||||
|
||||
def test_match_pstorage_simple_component() -> None:
|
||||
"""Simple component name like 'logger'."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("logger__logger_id__pstorage")
|
||||
assert result == "[esphome]logger"
|
||||
|
||||
|
||||
def test_match_pstorage_underscore_component() -> None:
|
||||
"""Component with underscore like 'web_server'."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("web_server__webserver_id__pstorage")
|
||||
assert result == "[esphome]web_server"
|
||||
|
||||
|
||||
def test_match_pstorage_api() -> None:
|
||||
"""API component."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("api__apiserver_id__pstorage")
|
||||
assert result == "[esphome]api"
|
||||
|
||||
|
||||
def test_match_pstorage_deep_sleep() -> None:
|
||||
"""Component with underscore: deep_sleep."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("deep_sleep__deepsleep__pstorage")
|
||||
assert result == "[esphome]deep_sleep"
|
||||
|
||||
|
||||
def test_match_pstorage_status_led() -> None:
|
||||
"""Component with underscore: status_led."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("status_led__statusled_id__pstorage")
|
||||
assert result == "[esphome]status_led"
|
||||
|
||||
|
||||
def test_match_pstorage_external_component() -> None:
|
||||
"""External component should be attributed correctly."""
|
||||
analyzer = _make_analyzer(external_components={"my_custom"})
|
||||
result = analyzer._match_pstorage_component("my_custom__thing_id__pstorage")
|
||||
assert result == "[external]my_custom"
|
||||
|
||||
|
||||
def test_match_pstorage_no_dunder_returns_none() -> None:
|
||||
"""Symbol without double underscore separator returns None."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("something__pstorage")
|
||||
assert result is None
|
||||
|
||||
|
||||
def test_match_pstorage_unknown_component_returns_none() -> None:
|
||||
"""Unknown component namespace returns None."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("nonexistent__thing_id__pstorage")
|
||||
assert result is None
|
||||
|
||||
|
||||
def test_match_pstorage_esphome_component() -> None:
|
||||
"""esphome:: namespace types map to the esphome component."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component(
|
||||
"esphome__esphomeotacomponent_id__pstorage"
|
||||
)
|
||||
assert result == "[esphome]esphome"
|
||||
|
||||
|
||||
def test_match_pstorage_user_id_with_component_prefix() -> None:
|
||||
"""User-chosen ID that happens to contain a component name."""
|
||||
analyzer = _make_analyzer()
|
||||
result = analyzer._match_pstorage_component("logger__relay1__pstorage")
|
||||
assert result == "[esphome]logger"
|
||||
Reference in New Issue
Block a user