Detect unsupported system in CPU Speed integration (#63012)

This commit is contained in:
Franck Nijhof 2021-12-29 18:54:47 +01:00 committed by GitHub
parent 1547a046db
commit 2f7fa962b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 5 deletions

View File

@ -1,12 +1,21 @@
"""The CPU Speed integration.""" """The CPU Speed integration."""
from cpuinfo import cpuinfo
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from .const import PLATFORMS from .const import LOGGER, PLATFORMS
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up from a config entry.""" """Set up from a config entry."""
if not await hass.async_add_executor_job(cpuinfo.get_cpu_info):
LOGGER.error(
"Unable to get CPU information, the CPU Speed integration "
"is not compatible with your system"
)
return False
hass.config_entries.async_setup_platforms(entry, PLATFORMS) hass.config_entries.async_setup_platforms(entry, PLATFORMS)
return True return True

View File

@ -3,6 +3,8 @@ from __future__ import annotations
from typing import Any from typing import Any
from cpuinfo import cpuinfo
from homeassistant.config_entries import ConfigFlow from homeassistant.config_entries import ConfigFlow
from homeassistant.const import CONF_NAME from homeassistant.const import CONF_NAME
from homeassistant.data_entry_flow import FlowResult from homeassistant.data_entry_flow import FlowResult
@ -27,6 +29,9 @@ class CPUSpeedFlowHandler(ConfigFlow, domain=DOMAIN):
if user_input is None: if user_input is None:
return self.async_show_form(step_id="user") return self.async_show_form(step_id="user")
if not await self.hass.async_add_executor_job(cpuinfo.get_cpu_info):
return self.async_abort(reason="not_compatible")
return self.async_create_entry( return self.async_create_entry(
title=self._imported_name or "CPU Speed", title=self._imported_name or "CPU Speed",
data={}, data={},

View File

@ -8,7 +8,8 @@
} }
}, },
"abort": { "abort": {
"alread_configured": "[%key:common::config_flow::abort::single_instance_allowed%]" "alread_configured": "[%key:common::config_flow::abort::single_instance_allowed%]",
"not_compatible": "Unable to get CPU information, this integration is not compatible with your system"
} }
} }
} }

View File

@ -1,7 +1,8 @@
{ {
"config": { "config": {
"abort": { "abort": {
"alread_configured": "Already configured. Only a single configuration possible." "alread_configured": "Already configured. Only a single configuration possible.",
"not_compatible": "Unable to get CPU information, this integration is not compatible with your system"
}, },
"step": { "step": {
"user": { "user": {

View File

@ -2,7 +2,7 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Generator from collections.abc import Generator
from unittest.mock import AsyncMock, patch from unittest.mock import AsyncMock, MagicMock, patch
import pytest import pytest
@ -22,6 +22,20 @@ def mock_config_entry() -> MockConfigEntry:
) )
@pytest.fixture
def mock_cpuinfo_config_flow() -> Generator[MagicMock, None, None]:
"""Return a mocked get_cpu_info.
It is only used to check thruthy or falsy values, so it is mocked
to return True.
"""
with patch(
"homeassistant.components.cpuspeed.config_flow.cpuinfo.get_cpu_info",
return_value=True,
) as cpuinfo_mock:
yield cpuinfo_mock
@pytest.fixture @pytest.fixture
def mock_setup_entry() -> Generator[AsyncMock, None, None]: def mock_setup_entry() -> Generator[AsyncMock, None, None]:
"""Mock setting up a config entry.""" """Mock setting up a config entry."""

View File

@ -1,6 +1,6 @@
"""Tests for the CPU Speed config flow.""" """Tests for the CPU Speed config flow."""
from unittest.mock import AsyncMock from unittest.mock import AsyncMock, MagicMock
from homeassistant.components.cpuspeed.const import DOMAIN from homeassistant.components.cpuspeed.const import DOMAIN
from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_USER from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_USER
@ -17,6 +17,7 @@ from tests.common import MockConfigEntry
async def test_full_user_flow( async def test_full_user_flow(
hass: HomeAssistant, hass: HomeAssistant,
mock_cpuinfo_config_flow: MagicMock,
mock_setup_entry: AsyncMock, mock_setup_entry: AsyncMock,
) -> None: ) -> None:
"""Test the full user configuration flow.""" """Test the full user configuration flow."""
@ -38,10 +39,12 @@ async def test_full_user_flow(
assert result2.get("data") == {} assert result2.get("data") == {}
assert len(mock_setup_entry.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1
assert len(mock_cpuinfo_config_flow.mock_calls) == 1
async def test_already_configured( async def test_already_configured(
hass: HomeAssistant, hass: HomeAssistant,
mock_cpuinfo_config_flow: MagicMock,
mock_setup_entry: AsyncMock, mock_setup_entry: AsyncMock,
mock_config_entry: MockConfigEntry, mock_config_entry: MockConfigEntry,
) -> None: ) -> None:
@ -56,10 +59,12 @@ async def test_already_configured(
assert result.get("reason") == "already_configured" assert result.get("reason") == "already_configured"
assert len(mock_setup_entry.mock_calls) == 0 assert len(mock_setup_entry.mock_calls) == 0
assert len(mock_cpuinfo_config_flow.mock_calls) == 0
async def test_import_flow( async def test_import_flow(
hass: HomeAssistant, hass: HomeAssistant,
mock_cpuinfo_config_flow: MagicMock,
mock_setup_entry: AsyncMock, mock_setup_entry: AsyncMock,
) -> None: ) -> None:
"""Test the import configuration flow.""" """Test the import configuration flow."""
@ -74,3 +79,31 @@ async def test_import_flow(
assert result.get("data") == {} assert result.get("data") == {}
assert len(mock_setup_entry.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1
assert len(mock_cpuinfo_config_flow.mock_calls) == 1
async def test_not_compatible(
hass: HomeAssistant,
mock_cpuinfo_config_flow: MagicMock,
mock_setup_entry: AsyncMock,
) -> None:
"""Test we abort the configuration flow when incompatible."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result.get("type") == RESULT_TYPE_FORM
assert result.get("step_id") == SOURCE_USER
assert "flow_id" in result
mock_cpuinfo_config_flow.return_value = {}
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={},
)
assert result2.get("type") == RESULT_TYPE_ABORT
assert result2.get("reason") == "not_compatible"
assert len(mock_setup_entry.mock_calls) == 0
assert len(mock_cpuinfo_config_flow.mock_calls) == 1