mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2026-08-30 04:06:37 +00:00
Consolidates the currently applicable dependency updates into one PR, including the closed Dependabot backlog such as #1241, plus dependency surfaces that were not covered by the repository's previous pip-only Dependabot configuration. Cleanup of test warnings. Most importent: * GitPython + pypdf security hardening. * Uvicorn WebSocket close/backpressure/header fixes for server/dashboard reliability. * FastAPI dependency-memory/OpenAPI improvements for the API process. * Bokeh WebSocket/resource-leak/prefix fixes for EOSdash and proxied deployments. * cachebox cancellation/lock cleanup fixes for long-running/concurrent work. * pandas 3.0.5 avoiding the yanked 3.0.4 datetime/segfault build. * Ruff security-lint and pydocstyle correctness fixes, plus faster release builds via PGO. * platformdirs malformed-XDG and duplicate-directory fixes for deployment portability. * CI action modernization, regenerated uv.lock, and expanded Dependabot coverage. Runtime dependencies cachebox: 6.1.2 → 6.2.2 fastapi: 0.139.2 → 0.141.1 python-fasthtml: 0.14.9 → 0.14.11 MonsterUI: 1.0.46 → 1.0.47 bokeh: 3.9.1 → 3.9.2 uvicorn: 0.51.0 → 0.52.4 (build(deps): bump uvicorn from 0.51.0 to 0.52.3 #1241, refreshed to latest patch) pandas: 3.0.3 → 3.0.5 platformdirs: 4.11.0 → 4.11.3 Development/test dependencies pandas-stubs: 3.0.3.260530 → 3.0.5.260730 types-PyYAML: 6.0.12.20260518 → 6.0.12.20260724 GitPython: 3.1.53 → 3.1.58 (security/fix releases) coverage: 7.15.2 → 7.15.4 pypdf: 6.14.2 → 6.16.1 (includes security fixes) Pre-commit/tooling ruff-pre-commit: v0.15.21 → v0.16.3 synchronize pandas-stubs, types-docutils, and types-PyYAML pins with pyproject.toml CI / repository dependencies Python 3.13.9 → 3.13.15 in CI, Docker, .env, and local Docker Make targets actions/checkout → v7 in pytest, pre-commit, CodeQL, and release workflows actions/setup-python → v7 in pytest, pre-commit, and release workflows actions/upload-artifact → v7 in pytest workflow actions/stale: v9.1.0 → v11.0.0 (SHA-pinned) regenerate uv.lock from the final dependency pins so locked/frozen installs match pyproject.toml Future update coverage Expand Dependabot from pip-only to also monitor: GitHub Actions Docker The existing open docutils 0.23 update (#1085) is intentionally excluded because it has separate compatibility/ignore handling and should remain isolated. docker-build.yml was audited and is already using the newer action generations, so no changes were needed there. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
112 lines
4.5 KiB
Python
112 lines
4.5 KiB
Python
"""Test suite for the EOS Dash configuration module.
|
|
|
|
This module contains tests for utility functions related to retrieving and processing
|
|
configuration data using Pydantic models.
|
|
"""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Union
|
|
|
|
import pytest
|
|
from pydantic.fields import FieldInfo
|
|
|
|
from akkudoktoreos.core.pydantic import PydanticBaseModel
|
|
from akkudoktoreos.prediction.pvforecast import PVForecastPlaneSetting
|
|
from akkudoktoreos.server.dash.configuration import (
|
|
create_config_details,
|
|
get_default_value,
|
|
get_nested_value,
|
|
resolve_nested_types,
|
|
)
|
|
|
|
DIR_TESTDATA = Path(__file__).absolute().parent.joinpath("testdata")
|
|
|
|
FILE_TESTDATA_EOSSERVER_CONFIG_1 = DIR_TESTDATA.joinpath("eosserver_config_1.json")
|
|
|
|
|
|
class SampleModel(PydanticBaseModel):
|
|
field1: str = "default_value"
|
|
field2: int = 10
|
|
|
|
|
|
class TestEOSdashConfig:
|
|
"""Test case for EOS Dash configuration utility functions.
|
|
|
|
This class tests functions for retrieving nested values, extracting default values,
|
|
resolving nested types, and generating configuration details from Pydantic models.
|
|
"""
|
|
|
|
def test_get_nested_value_from_dict(self):
|
|
"""Test retrieving a nested value from a dictionary using a sequence of keys."""
|
|
data = {"a": {"b": {"c": 42}}}
|
|
assert get_nested_value(data, ["a", "b", "c"]) == 42
|
|
assert get_nested_value(data, ["a", "x"], default="not found") == "not found"
|
|
with pytest.raises(TypeError):
|
|
get_nested_value("not_a_dict", ["a"]) # type: ignore
|
|
|
|
def test_get_nested_value_from_list(self):
|
|
"""Test retrieving a nested value from a list using a sequence of keys."""
|
|
data = {"a": {"b": {"c": [42]}}}
|
|
assert get_nested_value(data, ["a", "b", "c", 0]) == 42
|
|
assert get_nested_value(data, ["a", "b", "c", "0"]) == 42
|
|
|
|
def test_get_default_value(self):
|
|
"""Test retrieving the default value of a field based on FieldInfo metadata."""
|
|
field_info = FieldInfo(default="test_value")
|
|
assert get_default_value(field_info, True) == "test_value"
|
|
field_info_no_default = FieldInfo()
|
|
assert get_default_value(field_info_no_default, True) == ""
|
|
assert get_default_value(field_info, False) == "N/A"
|
|
|
|
def test_resolve_nested_types(self):
|
|
"""Test resolving nested types within a field, ensuring correct type extraction."""
|
|
nested_types = resolve_nested_types(Union[int, str], [])
|
|
assert (int, []) in nested_types
|
|
assert (str, []) in nested_types
|
|
|
|
def test_configuration(self):
|
|
"""Test extracting configuration details from a Pydantic model based on provided values."""
|
|
values = {"field1": "custom_value", "field2": 20}
|
|
config_details = create_config_details(SampleModel, values)
|
|
|
|
assert any(
|
|
item["name"] == "field1" and item["value"] == '"custom_value"'
|
|
for key, item in config_details.items()
|
|
)
|
|
assert any(
|
|
item["name"] == "field2" and item["value"] == "20"
|
|
for key, item in config_details.items()
|
|
)
|
|
|
|
def test_configuration_eos(self, config_eos):
|
|
"""Test extracting EOS configuration details from EOS config based on provided values."""
|
|
with FILE_TESTDATA_EOSSERVER_CONFIG_1.open("r", encoding="utf-8", newline=None) as fd:
|
|
values = json.load(fd)
|
|
config_details = create_config_details(type(config_eos), values)
|
|
assert any(
|
|
item["name"] == "server.eosdash_port" and item["value"] == "8504"
|
|
for key, item in config_details.items()
|
|
)
|
|
assert any(
|
|
item["name"] == "server.eosdash_host" and item["value"] == '"127.0.0.1"'
|
|
for key, item in config_details.items()
|
|
)
|
|
|
|
def test_configuration_pvforecast_plane_settings(self):
|
|
"""Test extracting EOS PV forecast plane configuration details from EOS config based on provided values."""
|
|
with FILE_TESTDATA_EOSSERVER_CONFIG_1.open("r", encoding="utf-8", newline=None) as fd:
|
|
values = json.load(fd)
|
|
config_details = create_config_details(
|
|
PVForecastPlaneSetting, values, values_prefix=["pvforecast", "planes", "0"]
|
|
)
|
|
assert any(
|
|
item["name"] == "pvforecast.planes.0.surface_azimuth" and item["value"] == "170"
|
|
for key, item in config_details.items()
|
|
)
|
|
assert any(
|
|
item["name"] == "pvforecast.planes.0.userhorizon"
|
|
and item["value"] == "[20, 27, 22, 20]"
|
|
for key, item in config_details.items()
|
|
)
|