Rework on mqtt certificate tests (#99503)

* Shared fixture on TEMP_DIR_NAME mock in MQTT tests

* Improve mqtt certificate file tests

* Update tests/components/mqtt/test_util.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Update tests/components/mqtt/conftest.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Avoid blocking code

* typo in sub function

---------

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Jan Bouwhuis 2023-09-02 19:26:11 +02:00 committed by GitHub
parent 6974d211e5
commit c3841f8734
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 77 additions and 29 deletions

View File

@ -1,5 +1,9 @@
"""Test fixtures for mqtt component."""
from collections.abc import Generator
from random import getrandbits
from unittest.mock import patch
import pytest
from tests.components.light.conftest import mock_light_profiles # noqa: F401
@ -8,3 +12,20 @@ from tests.components.light.conftest import mock_light_profiles # noqa: F401
@pytest.fixture(autouse=True)
def patch_hass_config(mock_hass_config: None) -> None:
"""Patch configuration.yaml."""
@pytest.fixture
def temp_dir_prefix() -> str:
"""Set an alternate temp dir prefix."""
return "test"
@pytest.fixture
def mock_temp_dir(temp_dir_prefix: str) -> Generator[None, None, str]:
"""Mock the certificate temp directory."""
with patch(
# Patch temp dir name to avoid tests fail running in parallel
"homeassistant.components.mqtt.util.TEMP_DIR_NAME",
f"home-assistant-mqtt-{temp_dir_prefix}-{getrandbits(10):03x}",
) as mocked_temp_dir:
yield mocked_temp_dir

View File

@ -2,7 +2,6 @@
from collections.abc import Generator, Iterator
from contextlib import contextmanager
from pathlib import Path
from random import getrandbits
from ssl import SSLError
from typing import Any
from unittest.mock import AsyncMock, MagicMock, patch
@ -131,7 +130,9 @@ def mock_try_connection_time_out() -> Generator[MagicMock, None, None]:
@pytest.fixture
def mock_process_uploaded_file(tmp_path: Path) -> Generator[MagicMock, None, None]:
def mock_process_uploaded_file(
tmp_path: Path, mock_temp_dir: str
) -> Generator[MagicMock, None, None]:
"""Mock upload certificate files."""
file_id_ca = str(uuid4())
file_id_cert = str(uuid4())
@ -159,11 +160,7 @@ def mock_process_uploaded_file(tmp_path: Path) -> Generator[MagicMock, None, Non
with patch(
"homeassistant.components.mqtt.config_flow.process_uploaded_file",
side_effect=_mock_process_uploaded_file,
) as mock_upload, patch(
# Patch temp dir name to avoid tests fail running in parallel
"homeassistant.components.mqtt.util.TEMP_DIR_NAME",
"home-assistant-mqtt" + f"-{getrandbits(10):03x}",
):
) as mock_upload:
mock_upload.file_id = {
mqtt.CONF_CERTIFICATE: file_id_ca,
mqtt.CONF_CLIENT_CERT: file_id_cert,

View File

@ -1,7 +1,9 @@
"""Test MQTT utils."""
from collections.abc import Callable
from pathlib import Path
from random import getrandbits
import tempfile
from unittest.mock import patch
import pytest
@ -14,17 +16,6 @@ from tests.common import MockConfigEntry
from tests.typing import MqttMockHAClient, MqttMockPahoClient
@pytest.fixture(autouse=True)
def mock_temp_dir():
"""Mock the certificate temp directory."""
with patch(
# Patch temp dir name to avoid tests fail running in parallel
"homeassistant.components.mqtt.util.TEMP_DIR_NAME",
"home-assistant-mqtt" + f"-{getrandbits(10):03x}",
) as mocked_temp_dir:
yield mocked_temp_dir
@pytest.mark.parametrize(
("option", "content", "file_created"),
[
@ -34,31 +25,50 @@ def mock_temp_dir():
(mqtt.CONF_CLIENT_KEY, "### PRIVATE KEY ###", True),
],
)
@pytest.mark.parametrize("temp_dir_prefix", ["create-test"])
async def test_async_create_certificate_temp_files(
hass: HomeAssistant, mock_temp_dir, option, content, file_created
hass: HomeAssistant,
mock_temp_dir: str,
option: str,
content: str,
file_created: bool,
) -> None:
"""Test creating and reading and recovery certificate files."""
config = {option: content}
await mqtt.util.async_create_certificate_temp_files(hass, config)
file_path = mqtt.util.get_file_path(option)
temp_dir = Path(tempfile.gettempdir()) / mock_temp_dir
# Create old file to be able to assert it is removed with auto option
def _ensure_old_file_exists() -> None:
if not temp_dir.exists():
temp_dir.mkdir(0o700)
temp_file = temp_dir / option
with open(temp_file, "wb") as old_file:
old_file.write(b"old content")
old_file.close()
await hass.async_add_executor_job(_ensure_old_file_exists)
await mqtt.util.async_create_certificate_temp_files(hass, config)
file_path = await hass.async_add_executor_job(mqtt.util.get_file_path, option)
assert bool(file_path) is file_created
assert (
mqtt.util.migrate_certificate_file_to_content(file_path or content) == content
await hass.async_add_executor_job(
mqtt.util.migrate_certificate_file_to_content, file_path or content
)
== content
)
# Make sure certificate temp files are recovered
if file_path:
# Overwrite content of file (except for auto option)
file = open(file_path, "wb")
file.write(b"invalid")
file.close()
await hass.async_add_executor_job(_ensure_old_file_exists)
await mqtt.util.async_create_certificate_temp_files(hass, config)
file_path2 = mqtt.util.get_file_path(option)
file_path2 = await hass.async_add_executor_job(mqtt.util.get_file_path, option)
assert bool(file_path2) is file_created
assert (
mqtt.util.migrate_certificate_file_to_content(file_path2 or content) == content
await hass.async_add_executor_job(
mqtt.util.migrate_certificate_file_to_content, file_path2 or content
)
== content
)
assert file_path == file_path2
@ -71,6 +81,26 @@ async def test_reading_non_exitisting_certificate_file() -> None:
)
@pytest.mark.parametrize("temp_dir_prefix", "unknown")
async def test_return_default_get_file_path(
hass: HomeAssistant, mock_temp_dir: str
) -> None:
"""Test get_file_path returns default."""
def _get_file_path(file_path: Path) -> bool:
return (
not file_path.exists()
and mqtt.util.get_file_path("some_option", "mydefault") == "mydefault"
)
with patch(
"homeassistant.components.mqtt.util.TEMP_DIR_NAME",
f"home-assistant-mqtt-other-{getrandbits(10):03x}",
) as mock_temp_dir:
tempdir = Path(tempfile.gettempdir()) / mock_temp_dir
assert await hass.async_add_executor_job(_get_file_path, tempdir)
@patch("homeassistant.components.mqtt.PLATFORMS", [])
async def test_waiting_for_client_not_loaded(
hass: HomeAssistant,