mirror of
https://github.com/esphome/esphome.git
synced 2025-10-03 18:42:23 +01:00
[psram] raise instead of returning invalid object (#10954)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
This commit is contained in:
194
tests/component_tests/psram/test_psram.py
Normal file
194
tests/component_tests/psram/test_psram.py
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
"""Tests for PSRAM component."""
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from esphome.components.esp32.const import (
|
||||||
|
KEY_VARIANT,
|
||||||
|
VARIANT_ESP32,
|
||||||
|
VARIANT_ESP32C2,
|
||||||
|
VARIANT_ESP32C3,
|
||||||
|
VARIANT_ESP32C5,
|
||||||
|
VARIANT_ESP32C6,
|
||||||
|
VARIANT_ESP32H2,
|
||||||
|
VARIANT_ESP32P4,
|
||||||
|
VARIANT_ESP32S2,
|
||||||
|
VARIANT_ESP32S3,
|
||||||
|
)
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.const import CONF_ESPHOME, PlatformFramework
|
||||||
|
from tests.component_tests.types import SetCoreConfigCallable
|
||||||
|
|
||||||
|
UNSUPPORTED_PSRAM_VARIANTS = [
|
||||||
|
VARIANT_ESP32C2,
|
||||||
|
VARIANT_ESP32C3,
|
||||||
|
VARIANT_ESP32C5,
|
||||||
|
VARIANT_ESP32C6,
|
||||||
|
VARIANT_ESP32H2,
|
||||||
|
]
|
||||||
|
|
||||||
|
SUPPORTED_PSRAM_VARIANTS = [
|
||||||
|
VARIANT_ESP32,
|
||||||
|
VARIANT_ESP32S2,
|
||||||
|
VARIANT_ESP32S3,
|
||||||
|
VARIANT_ESP32P4,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("config", "error_match"),
|
||||||
|
[
|
||||||
|
pytest.param(
|
||||||
|
{},
|
||||||
|
r"PSRAM is not supported on this chip",
|
||||||
|
id="psram_not_supported",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize("variant", UNSUPPORTED_PSRAM_VARIANTS)
|
||||||
|
def test_psram_configuration_errors_unsupported_variants(
|
||||||
|
config: Any,
|
||||||
|
error_match: str,
|
||||||
|
variant: str,
|
||||||
|
set_core_config: SetCoreConfigCallable,
|
||||||
|
) -> None:
|
||||||
|
set_core_config(
|
||||||
|
PlatformFramework.ESP32_IDF,
|
||||||
|
platform_data={KEY_VARIANT: variant},
|
||||||
|
full_config={CONF_ESPHOME: {}},
|
||||||
|
)
|
||||||
|
"""Test detection of invalid PSRAM configuration on unsupported variants."""
|
||||||
|
from esphome.components.psram import CONFIG_SCHEMA
|
||||||
|
|
||||||
|
with pytest.raises(cv.Invalid, match=error_match):
|
||||||
|
CONFIG_SCHEMA(config)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("variant", SUPPORTED_PSRAM_VARIANTS)
|
||||||
|
def test_psram_configuration_valid_supported_variants(
|
||||||
|
variant: str,
|
||||||
|
set_core_config: SetCoreConfigCallable,
|
||||||
|
) -> None:
|
||||||
|
set_core_config(
|
||||||
|
PlatformFramework.ESP32_IDF,
|
||||||
|
platform_data={KEY_VARIANT: variant},
|
||||||
|
full_config={
|
||||||
|
CONF_ESPHOME: {},
|
||||||
|
"esp32": {
|
||||||
|
"variant": variant,
|
||||||
|
"cpu_frequency": "160MHz",
|
||||||
|
"framework": {"type": "esp-idf"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
"""Test that PSRAM configuration is valid on supported variants."""
|
||||||
|
from esphome.components.psram import CONFIG_SCHEMA, FINAL_VALIDATE_SCHEMA
|
||||||
|
|
||||||
|
# This should not raise an exception
|
||||||
|
config = CONFIG_SCHEMA({})
|
||||||
|
FINAL_VALIDATE_SCHEMA(config)
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_psram_final_validation_test(
|
||||||
|
esp32_config: dict,
|
||||||
|
set_core_config: SetCoreConfigCallable,
|
||||||
|
set_component_config: Any,
|
||||||
|
) -> str:
|
||||||
|
"""Helper function to set up ESP32 configuration for PSRAM final validation tests."""
|
||||||
|
# Use ESP32S3 for schema validation to allow all options, then override for final validation
|
||||||
|
schema_variant = "ESP32S3"
|
||||||
|
final_variant = esp32_config.get("variant", "ESP32S3")
|
||||||
|
full_esp32_config = {
|
||||||
|
"variant": final_variant,
|
||||||
|
"cpu_frequency": esp32_config.get("cpu_frequency", "240MHz"),
|
||||||
|
"framework": {"type": "esp-idf"},
|
||||||
|
}
|
||||||
|
|
||||||
|
set_core_config(
|
||||||
|
PlatformFramework.ESP32_IDF,
|
||||||
|
platform_data={KEY_VARIANT: schema_variant},
|
||||||
|
full_config={
|
||||||
|
CONF_ESPHOME: {},
|
||||||
|
"esp32": full_esp32_config,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
set_component_config("esp32", full_esp32_config)
|
||||||
|
|
||||||
|
return final_variant
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("config", "esp32_config", "expect_error", "error_match"),
|
||||||
|
[
|
||||||
|
pytest.param(
|
||||||
|
{"speed": "120MHz"},
|
||||||
|
{"cpu_frequency": "160MHz"},
|
||||||
|
True,
|
||||||
|
r"PSRAM 120MHz requires 240MHz CPU frequency",
|
||||||
|
id="120mhz_requires_240mhz_cpu",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{"mode": "octal"},
|
||||||
|
{"variant": "ESP32"},
|
||||||
|
True,
|
||||||
|
r"Octal PSRAM is only supported on ESP32-S3",
|
||||||
|
id="octal_mode_only_esp32s3",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{"mode": "quad", "enable_ecc": True},
|
||||||
|
{},
|
||||||
|
True,
|
||||||
|
r"ECC is only available in octal mode",
|
||||||
|
id="ecc_only_in_octal_mode",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{"speed": "120MHZ"},
|
||||||
|
{"cpu_frequency": "240MHZ"},
|
||||||
|
False,
|
||||||
|
None,
|
||||||
|
id="120mhz_with_240mhz_cpu",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{"mode": "octal"},
|
||||||
|
{"variant": "ESP32S3"},
|
||||||
|
False,
|
||||||
|
None,
|
||||||
|
id="octal_mode_on_esp32s3",
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
{"mode": "octal", "enable_ecc": True},
|
||||||
|
{"variant": "ESP32S3"},
|
||||||
|
False,
|
||||||
|
None,
|
||||||
|
id="ecc_in_octal_mode",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_psram_final_validation(
|
||||||
|
config: Any,
|
||||||
|
esp32_config: dict,
|
||||||
|
expect_error: bool,
|
||||||
|
error_match: str | None,
|
||||||
|
set_core_config: SetCoreConfigCallable,
|
||||||
|
set_component_config: Any,
|
||||||
|
) -> None:
|
||||||
|
"""Test PSRAM final validation for both error and valid cases."""
|
||||||
|
from esphome.components.psram import CONFIG_SCHEMA, FINAL_VALIDATE_SCHEMA
|
||||||
|
from esphome.core import CORE
|
||||||
|
|
||||||
|
final_variant = _setup_psram_final_validation_test(
|
||||||
|
esp32_config, set_core_config, set_component_config
|
||||||
|
)
|
||||||
|
|
||||||
|
validated_config = CONFIG_SCHEMA(config)
|
||||||
|
|
||||||
|
# Update CORE variant for final validation
|
||||||
|
CORE.data["esp32"][KEY_VARIANT] = final_variant
|
||||||
|
|
||||||
|
if expect_error:
|
||||||
|
with pytest.raises(cv.Invalid, match=error_match):
|
||||||
|
FINAL_VALIDATE_SCHEMA(validated_config)
|
||||||
|
else:
|
||||||
|
# This should not raise an exception
|
||||||
|
FINAL_VALIDATE_SCHEMA(validated_config)
|
Reference in New Issue
Block a user