mirror of
https://github.com/home-assistant/core.git
synced 2025-12-24 12:59:34 +00:00
Downgrade logging previously reported asyncio block to debug (#120942)
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
"""Tests for async util methods from Python source."""
|
||||
|
||||
from collections.abc import Generator
|
||||
import contextlib
|
||||
import threading
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
@@ -15,57 +17,14 @@ def banned_function():
|
||||
"""Mock banned function."""
|
||||
|
||||
|
||||
async def test_raise_for_blocking_call_async() -> None:
|
||||
"""Test raise_for_blocking_call detects when called from event loop without integration context."""
|
||||
with pytest.raises(RuntimeError):
|
||||
haloop.raise_for_blocking_call(banned_function)
|
||||
|
||||
|
||||
async def test_raise_for_blocking_call_async_non_strict_core(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test non_strict_core raise_for_blocking_call detects from event loop without integration context."""
|
||||
haloop.raise_for_blocking_call(banned_function, strict_core=False)
|
||||
assert "Detected blocking call to banned_function" in caplog.text
|
||||
assert "Traceback (most recent call last)" in caplog.text
|
||||
assert (
|
||||
"Please create a bug report at https://github.com/home-assistant/core/issues"
|
||||
in caplog.text
|
||||
)
|
||||
assert (
|
||||
"For developers, please see "
|
||||
"https://developers.home-assistant.io/docs/asyncio_blocking_operations/#banned_function"
|
||||
) in caplog.text
|
||||
|
||||
|
||||
async def test_raise_for_blocking_call_async_integration(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test raise_for_blocking_call detects and raises when called from event loop from integration context."""
|
||||
frames = extract_stack_to_frame(
|
||||
[
|
||||
Mock(
|
||||
filename="/home/paulus/homeassistant/core.py",
|
||||
lineno="23",
|
||||
line="do_something()",
|
||||
),
|
||||
Mock(
|
||||
filename="/home/paulus/homeassistant/components/hue/light.py",
|
||||
lineno="23",
|
||||
line="self.light.is_on",
|
||||
),
|
||||
Mock(
|
||||
filename="/home/paulus/aiohue/lights.py",
|
||||
lineno="2",
|
||||
line="something()",
|
||||
),
|
||||
]
|
||||
)
|
||||
@contextlib.contextmanager
|
||||
def patch_get_current_frame(stack: list[Mock]) -> Generator[None, None, None]:
|
||||
"""Patch get_current_frame."""
|
||||
frames = extract_stack_to_frame(stack)
|
||||
with (
|
||||
pytest.raises(RuntimeError),
|
||||
patch(
|
||||
"homeassistant.helpers.frame.linecache.getline",
|
||||
return_value="self.light.is_on",
|
||||
return_value=stack[1].line,
|
||||
),
|
||||
patch(
|
||||
"homeassistant.util.loop._get_line_from_cache",
|
||||
@@ -79,13 +38,104 @@ async def test_raise_for_blocking_call_async_integration(
|
||||
"homeassistant.helpers.frame.get_current_frame",
|
||||
return_value=frames,
|
||||
),
|
||||
):
|
||||
yield
|
||||
|
||||
|
||||
async def test_raise_for_blocking_call_async() -> None:
|
||||
"""Test raise_for_blocking_call detects when called from event loop without integration context."""
|
||||
with pytest.raises(RuntimeError):
|
||||
haloop.raise_for_blocking_call(banned_function)
|
||||
|
||||
|
||||
async def test_raise_for_blocking_call_async_non_strict_core(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test non_strict_core raise_for_blocking_call detects from event loop without integration context."""
|
||||
stack = [
|
||||
Mock(
|
||||
filename="/home/paulus/homeassistant/core.py",
|
||||
lineno="12",
|
||||
line="do_something()",
|
||||
),
|
||||
Mock(
|
||||
filename="/home/paulus/homeassistant/core.py",
|
||||
lineno="12",
|
||||
line="self.light.is_on",
|
||||
),
|
||||
Mock(
|
||||
filename="/home/paulus/aiohue/lights.py",
|
||||
lineno="2",
|
||||
line="something()",
|
||||
),
|
||||
]
|
||||
with patch_get_current_frame(stack):
|
||||
haloop.raise_for_blocking_call(banned_function, strict_core=False)
|
||||
assert "Detected blocking call to banned_function" in caplog.text
|
||||
assert "Traceback (most recent call last)" in caplog.text
|
||||
assert (
|
||||
"Please create a bug report at https://github.com/home-assistant/core/issues"
|
||||
in caplog.text
|
||||
)
|
||||
assert (
|
||||
"For developers, please see "
|
||||
"https://developers.home-assistant.io/docs/asyncio_blocking_operations/#banned_function"
|
||||
) in caplog.text
|
||||
|
||||
warnings = [
|
||||
record for record in caplog.get_records("call") if record.levelname == "WARNING"
|
||||
]
|
||||
assert len(warnings) == 1
|
||||
caplog.clear()
|
||||
|
||||
# Second call should log at debug
|
||||
with patch_get_current_frame(stack):
|
||||
haloop.raise_for_blocking_call(banned_function, strict_core=False)
|
||||
|
||||
warnings = [
|
||||
record for record in caplog.get_records("call") if record.levelname == "WARNING"
|
||||
]
|
||||
assert len(warnings) == 0
|
||||
assert (
|
||||
"For developers, please see "
|
||||
"https://developers.home-assistant.io/docs/asyncio_blocking_operations/#banned_function"
|
||||
) in caplog.text
|
||||
|
||||
# no expensive traceback on debug
|
||||
assert "Traceback (most recent call last)" not in caplog.text
|
||||
|
||||
|
||||
async def test_raise_for_blocking_call_async_integration(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test raise_for_blocking_call detects and raises when called from event loop from integration context."""
|
||||
stack = [
|
||||
Mock(
|
||||
filename="/home/paulus/homeassistant/core.py",
|
||||
lineno="18",
|
||||
line="do_something()",
|
||||
),
|
||||
Mock(
|
||||
filename="/home/paulus/homeassistant/components/hue/light.py",
|
||||
lineno="18",
|
||||
line="self.light.is_on",
|
||||
),
|
||||
Mock(
|
||||
filename="/home/paulus/aiohue/lights.py",
|
||||
lineno="8",
|
||||
line="something()",
|
||||
),
|
||||
]
|
||||
with (
|
||||
pytest.raises(RuntimeError),
|
||||
patch_get_current_frame(stack),
|
||||
):
|
||||
haloop.raise_for_blocking_call(banned_function)
|
||||
assert (
|
||||
"Detected blocking call to banned_function with args None"
|
||||
" inside the event loop by integration"
|
||||
" 'hue' at homeassistant/components/hue/light.py, line 23: self.light.is_on "
|
||||
"(offender: /home/paulus/aiohue/lights.py, line 2: mock_line), please create "
|
||||
" 'hue' at homeassistant/components/hue/light.py, line 18: self.light.is_on "
|
||||
"(offender: /home/paulus/aiohue/lights.py, line 8: mock_line), please create "
|
||||
"a bug report at https://github.com/home-assistant/core/issues?"
|
||||
"q=is%3Aopen+is%3Aissue+label%3A%22integration%3A+hue%22" in caplog.text
|
||||
)
|
||||
@@ -99,55 +149,37 @@ async def test_raise_for_blocking_call_async_integration_non_strict(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test raise_for_blocking_call detects when called from event loop from integration context."""
|
||||
frames = extract_stack_to_frame(
|
||||
[
|
||||
Mock(
|
||||
filename="/home/paulus/homeassistant/core.py",
|
||||
lineno="23",
|
||||
line="do_something()",
|
||||
),
|
||||
Mock(
|
||||
filename="/home/paulus/homeassistant/components/hue/light.py",
|
||||
lineno="23",
|
||||
line="self.light.is_on",
|
||||
),
|
||||
Mock(
|
||||
filename="/home/paulus/aiohue/lights.py",
|
||||
lineno="2",
|
||||
line="something()",
|
||||
),
|
||||
]
|
||||
)
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.helpers.frame.linecache.getline",
|
||||
return_value="self.light.is_on",
|
||||
stack = [
|
||||
Mock(
|
||||
filename="/home/paulus/homeassistant/core.py",
|
||||
lineno="15",
|
||||
line="do_something()",
|
||||
),
|
||||
patch(
|
||||
"homeassistant.util.loop._get_line_from_cache",
|
||||
return_value="mock_line",
|
||||
Mock(
|
||||
filename="/home/paulus/homeassistant/components/hue/light.py",
|
||||
lineno="15",
|
||||
line="self.light.is_on",
|
||||
),
|
||||
patch(
|
||||
"homeassistant.util.loop.get_current_frame",
|
||||
return_value=frames,
|
||||
Mock(
|
||||
filename="/home/paulus/aiohue/lights.py",
|
||||
lineno="1",
|
||||
line="something()",
|
||||
),
|
||||
patch(
|
||||
"homeassistant.helpers.frame.get_current_frame",
|
||||
return_value=frames,
|
||||
),
|
||||
):
|
||||
]
|
||||
with patch_get_current_frame(stack):
|
||||
haloop.raise_for_blocking_call(banned_function, strict=False)
|
||||
|
||||
assert (
|
||||
"Detected blocking call to banned_function with args None"
|
||||
" inside the event loop by integration"
|
||||
" 'hue' at homeassistant/components/hue/light.py, line 23: self.light.is_on "
|
||||
"(offender: /home/paulus/aiohue/lights.py, line 2: mock_line), "
|
||||
" 'hue' at homeassistant/components/hue/light.py, line 15: self.light.is_on "
|
||||
"(offender: /home/paulus/aiohue/lights.py, line 1: mock_line), "
|
||||
"please create a bug report at https://github.com/home-assistant/core/issues?"
|
||||
"q=is%3Aopen+is%3Aissue+label%3A%22integration%3A+hue%22" in caplog.text
|
||||
)
|
||||
assert "Traceback (most recent call last)" in caplog.text
|
||||
assert (
|
||||
'File "/home/paulus/homeassistant/components/hue/light.py", line 23'
|
||||
'File "/home/paulus/homeassistant/components/hue/light.py", line 15'
|
||||
in caplog.text
|
||||
)
|
||||
assert (
|
||||
@@ -158,62 +190,62 @@ async def test_raise_for_blocking_call_async_integration_non_strict(
|
||||
"For developers, please see "
|
||||
"https://developers.home-assistant.io/docs/asyncio_blocking_operations/#banned_function"
|
||||
) in caplog.text
|
||||
warnings = [
|
||||
record for record in caplog.get_records("call") if record.levelname == "WARNING"
|
||||
]
|
||||
assert len(warnings) == 1
|
||||
caplog.clear()
|
||||
|
||||
# Second call should log at debug
|
||||
with patch_get_current_frame(stack):
|
||||
haloop.raise_for_blocking_call(banned_function, strict=False)
|
||||
|
||||
warnings = [
|
||||
record for record in caplog.get_records("call") if record.levelname == "WARNING"
|
||||
]
|
||||
assert len(warnings) == 0
|
||||
assert (
|
||||
"For developers, please see "
|
||||
"https://developers.home-assistant.io/docs/asyncio_blocking_operations/#banned_function"
|
||||
) in caplog.text
|
||||
# no expensive traceback on debug
|
||||
assert "Traceback (most recent call last)" not in caplog.text
|
||||
|
||||
|
||||
async def test_raise_for_blocking_call_async_custom(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test raise_for_blocking_call detects when called from event loop with custom component context."""
|
||||
frames = extract_stack_to_frame(
|
||||
[
|
||||
Mock(
|
||||
filename="/home/paulus/homeassistant/core.py",
|
||||
lineno="23",
|
||||
line="do_something()",
|
||||
),
|
||||
Mock(
|
||||
filename="/home/paulus/config/custom_components/hue/light.py",
|
||||
lineno="23",
|
||||
line="self.light.is_on",
|
||||
),
|
||||
Mock(
|
||||
filename="/home/paulus/aiohue/lights.py",
|
||||
lineno="2",
|
||||
line="something()",
|
||||
),
|
||||
]
|
||||
)
|
||||
with (
|
||||
pytest.raises(RuntimeError),
|
||||
patch(
|
||||
"homeassistant.helpers.frame.linecache.getline",
|
||||
return_value="self.light.is_on",
|
||||
stack = [
|
||||
Mock(
|
||||
filename="/home/paulus/homeassistant/core.py",
|
||||
lineno="12",
|
||||
line="do_something()",
|
||||
),
|
||||
patch(
|
||||
"homeassistant.util.loop._get_line_from_cache",
|
||||
return_value="mock_line",
|
||||
Mock(
|
||||
filename="/home/paulus/config/custom_components/hue/light.py",
|
||||
lineno="12",
|
||||
line="self.light.is_on",
|
||||
),
|
||||
patch(
|
||||
"homeassistant.util.loop.get_current_frame",
|
||||
return_value=frames,
|
||||
Mock(
|
||||
filename="/home/paulus/aiohue/lights.py",
|
||||
lineno="3",
|
||||
line="something()",
|
||||
),
|
||||
patch(
|
||||
"homeassistant.helpers.frame.get_current_frame",
|
||||
return_value=frames,
|
||||
),
|
||||
):
|
||||
]
|
||||
with pytest.raises(RuntimeError), patch_get_current_frame(stack):
|
||||
haloop.raise_for_blocking_call(banned_function)
|
||||
assert (
|
||||
"Detected blocking call to banned_function with args None"
|
||||
" inside the event loop by custom "
|
||||
"integration 'hue' at custom_components/hue/light.py, line 23: self.light.is_on"
|
||||
" (offender: /home/paulus/aiohue/lights.py, line 2: mock_line), "
|
||||
"integration 'hue' at custom_components/hue/light.py, line 12: self.light.is_on"
|
||||
" (offender: /home/paulus/aiohue/lights.py, line 3: mock_line), "
|
||||
"please create a bug report at https://github.com/home-assistant/core/issues?"
|
||||
"q=is%3Aopen+is%3Aissue+label%3A%22integration%3A+hue%22"
|
||||
) in caplog.text
|
||||
assert "Traceback (most recent call last)" in caplog.text
|
||||
assert (
|
||||
'File "/home/paulus/config/custom_components/hue/light.py", line 23'
|
||||
'File "/home/paulus/config/custom_components/hue/light.py", line 12'
|
||||
in caplog.text
|
||||
)
|
||||
assert (
|
||||
|
||||
Reference in New Issue
Block a user