From b8b4855b8e8f919d31987df272832605c90f0ff6 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Tue, 7 Dec 2021 00:26:31 +0100 Subject: [PATCH] Prevent log flooding in frame helper (#61085) Co-authored-by: epenet --- homeassistant/helpers/frame.py | 9 +++++++++ tests/helpers/test_frame.py | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/homeassistant/helpers/frame.py b/homeassistant/helpers/frame.py index 3995f24102d..13ffea48f81 100644 --- a/homeassistant/helpers/frame.py +++ b/homeassistant/helpers/frame.py @@ -12,6 +12,9 @@ from homeassistant.exceptions import HomeAssistantError _LOGGER = logging.getLogger(__name__) +# Keep track of integrations already reported to prevent flooding +_REPORTED_INTEGRATIONS: set[str] = set() + CALLABLE_T = TypeVar("CALLABLE_T", bound=Callable) # pylint: disable=invalid-name @@ -85,6 +88,12 @@ def report_integration( """ found_frame, integration, path = integration_frame + # Keep track of integrations already reported to prevent flooding + key = f"{found_frame.filename}:{found_frame.lineno}" + if key in _REPORTED_INTEGRATIONS: + return + _REPORTED_INTEGRATIONS.add(key) + index = found_frame.filename.index(path) if path == "custom_components/": extra = " to the custom component author" diff --git a/tests/helpers/test_frame.py b/tests/helpers/test_frame.py index 5e48b2aec5f..37f3e7ec95f 100644 --- a/tests/helpers/test_frame.py +++ b/tests/helpers/test_frame.py @@ -1,4 +1,5 @@ """Test the frame helper.""" +# pylint: disable=protected-access from unittest.mock import Mock, patch import pytest @@ -70,3 +71,24 @@ async def test_extract_frame_no_integration(caplog): ], ), pytest.raises(frame.MissingIntegrationFrame): frame.get_integration_frame() + + +@pytest.mark.usefixtures("mock_integration_frame") +@patch.object(frame, "_REPORTED_INTEGRATIONS", set()) +async def test_prevent_flooding(caplog): + """Test to ensure a report is only written once to the log.""" + + what = "accessed hi instead of hello" + key = "/home/paulus/homeassistant/components/hue/light.py:23" + + frame.report(what, error_if_core=False) + assert what in caplog.text + assert key in frame._REPORTED_INTEGRATIONS + assert len(frame._REPORTED_INTEGRATIONS) == 1 + + caplog.clear() + + frame.report(what, error_if_core=False) + assert what not in caplog.text + assert key in frame._REPORTED_INTEGRATIONS + assert len(frame._REPORTED_INTEGRATIONS) == 1