Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions homeassistant/components/recorder/system_health/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Provide info to system health."""

from typing import Any
from urllib.parse import urlparse

from sqlalchemy.engine.url import make_url

from homeassistant.components import system_health
from homeassistant.core import HomeAssistant, callback
Expand Down Expand Up @@ -58,7 +59,7 @@ async def system_health_info(hass: HomeAssistant) -> dict[str, Any]:
instance = get_instance(hass)

recorder_runs_manager = instance.recorder_runs_manager
database_name = urlparse(instance.db_url).path.lstrip("/")
database_name = make_url(instance.db_url).database or ""
db_engine_info = _async_get_db_engine_info(instance)
db_stats: dict[str, Any] = {}

Expand Down
39 changes: 39 additions & 0 deletions tests/components/recorder/test_system_health.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,42 @@ async def test_recorder_system_health_crashed_recorder_runs_table(
"database_engine": SupportedDialect.SQLITE.value,
"database_version": ANY,
}


@pytest.mark.parametrize("db_engine", [SupportedDialect.POSTGRESQL])
@pytest.mark.parametrize(
"db_url",
[
"postgresql://homeassistant:secret@192.168.0.2:5432/home_assistant",
"postgresql://homeassistant:pa#ss@192.168.0.2:5432/home_assistant",
"postgresql://homeassistant:pa?ss@192.168.0.2:5432/home_assistant",
"postgresql://homeassistant:pa/ss@192.168.0.2:5432/home_assistant",
],
ids=["plain", "hash", "question_mark", "slash"],
)
@pytest.mark.usefixtures("recorder_mock")
async def test_recorder_system_health_db_name_with_special_characters(
hass: HomeAssistant,
db_engine: SupportedDialect,
db_url: str,
recorder_dialect_name: None,
) -> None:
"""Test the database name is read correctly when the password needs escaping.

Characters that are structural in a generic URL, such as ``#`` and ``?``,
must not be allowed to swallow the database name that follows them.
"""
assert await async_setup_component(hass, "system_health", {})
await async_wait_recording_done(hass)

instance = get_instance(hass)
with (
patch.object(instance, "db_url", db_url),
patch(
"sqlalchemy.orm.session.Session.execute",
return_value=Mock(scalar=Mock(return_value=("1048576"))),
) as execute_mock,
):
await get_system_health_info(hass, "recorder")

assert execute_mock.call_args.args[1] == {"database_name": "home_assistant"}
Loading