odoo_mqtt/iot_bridge/tests/unit/test_bootstrap.py

114 lines
3.6 KiB
Python

"""Unit tests for bootstrap configuration loading behavior."""
import importlib
from pathlib import Path
from unittest.mock import Mock
import yaml
from config.schema import (
BridgeConfig,
DeviceStatusConfig,
EventQueueConfig,
LoggingConfig,
MQTTConfig,
OdooConfig,
)
from core.bootstrap import get_mqtt_config, load_bridge_config
from exceptions import ConfigurationError
def _base_config() -> BridgeConfig:
return BridgeConfig(
mqtt=MQTTConfig(broker="yaml-broker", port=1883, client_id="bridge"),
odoo=OdooConfig(use_mock=True),
logging=LoggingConfig(),
event_queue=EventQueueConfig(),
device_status=DeviceStatusConfig(),
devices=[],
)
def test_load_bridge_config_returns_none_on_missing_main_config(monkeypatch):
bootstrap_module = importlib.import_module("core.bootstrap")
def fail_load_config(_path):
raise ConfigurationError("missing")
monkeypatch.setattr(bootstrap_module, "load_config", fail_load_config)
config = load_bridge_config("missing.yaml", Path("/tmp/no-active.yaml"), logger=None)
assert config is None
def test_load_bridge_config_merges_persisted_mqtt_and_devices(monkeypatch, tmp_path):
bootstrap_module = importlib.import_module("core.bootstrap")
active_path = tmp_path / "config-active.yaml"
active_path.write_text(
yaml.safe_dump(
{
"mqtt": {
"broker": "persisted-broker",
"port": 1884,
"username": "mqtt-user",
"password": "secret",
"client_id": "persisted-client",
"keepalive": 30,
"use_tls": True,
},
"devices": [
{
"device_id": "dev-1",
"mqtt_topic": "shelly/dev-1/status",
"parser_type": "shelly_pm",
"machine_name": "Machine 1",
"session_config": {
"standby_threshold_w": 5,
"working_threshold_w": 20,
"start_debounce_s": 3,
"stop_debounce_s": 15,
"message_timeout_s": 20,
"heartbeat_interval_s": 60,
},
}
],
}
)
)
expected_devices = [Mock(device_id="dev-1")]
monkeypatch.setattr(bootstrap_module, "load_config", lambda _path: _base_config())
monkeypatch.setattr(
bootstrap_module,
"load_devices_from_config",
lambda _path: expected_devices,
)
config = load_bridge_config("config.yaml", active_path, logger=None)
assert config is not None
assert config.devices == expected_devices
assert config.mqtt.broker == "persisted-broker"
assert config.mqtt.port == 1884
assert config.mqtt.use_tls is True
def test_get_mqtt_config_falls_back_to_environment(monkeypatch):
monkeypatch.setenv("MQTT_BROKER", "env-broker")
monkeypatch.setenv("MQTT_PORT", "1999")
monkeypatch.setenv("MQTT_USERNAME", "env-user")
monkeypatch.setenv("MQTT_PASSWORD", "env-password")
monkeypatch.setenv("MQTT_CLIENT_ID", "env-client")
monkeypatch.setenv("MQTT_USE_TLS", "true")
mqtt_config = get_mqtt_config(config=None)
assert mqtt_config.broker == "env-broker"
assert mqtt_config.port == 1999
assert mqtt_config.username == "env-user"
assert mqtt_config.password == "env-password"
assert mqtt_config.client_id == "env-client"
assert mqtt_config.use_tls is True