From ed8fa4bc9bd3975da027cb83c1307c7c2bea0274 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Tue, 19 Mar 2024 15:59:50 -0700 Subject: [PATCH 01/62] Starting with a simple change --- homeassistant/components/prometheus/__init__.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/prometheus/__init__.py b/homeassistant/components/prometheus/__init__.py index d3a307a66162a8..7a6f393f60ee85 100644 --- a/homeassistant/components/prometheus/__init__.py +++ b/homeassistant/components/prometheus/__init__.py @@ -287,6 +287,15 @@ def _handle_attributes(self, state: State) -> None: except (ValueError, TypeError): pass + def _get_labels( + self, + extra_labels: list[str] | None = None, + ) -> list[str]: + labels = ["entity", "friendly_name", "domain"] + if extra_labels is not None: + labels.extend(extra_labels) + return list(labels) + def _metric( self, metric: str, @@ -294,9 +303,7 @@ def _metric( documentation: str, extra_labels: list[str] | None = None, ) -> _MetricBaseT: - labels = ["entity", "friendly_name", "domain"] - if extra_labels is not None: - labels.extend(extra_labels) + labels = self._get_labels(extra_labels=extra_labels) try: return cast(_MetricBaseT, self._metrics[metric]) From fd3c636ff5695f9f271ae8167bf015d4dca8b728 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Tue, 19 Mar 2024 16:11:22 -0700 Subject: [PATCH 02/62] And trying again but actually adding the new area to this --- homeassistant/components/prometheus/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/homeassistant/components/prometheus/__init__.py b/homeassistant/components/prometheus/__init__.py index 7a6f393f60ee85..181da4977f0c44 100644 --- a/homeassistant/components/prometheus/__init__.py +++ b/homeassistant/components/prometheus/__init__.py @@ -31,6 +31,7 @@ from homeassistant.components.light import ATTR_BRIGHTNESS from homeassistant.components.sensor import SensorDeviceClass from homeassistant.const import ( + ATTR_AREA_ID, ATTR_BATTERY_LEVEL, ATTR_DEVICE_CLASS, ATTR_FRIENDLY_NAME, @@ -352,6 +353,7 @@ def _labels(state: State) -> dict[str, Any]: "entity": state.entity_id, "domain": state.domain, "friendly_name": state.attributes.get(ATTR_FRIENDLY_NAME), + "area": state.attributes.get(ATTR_AREA_ID), } def _battery(self, state: State) -> None: From ba32cbd1224c56eb571404a677df449956f8c489 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Tue, 19 Mar 2024 16:20:12 -0700 Subject: [PATCH 03/62] And that's getting interesting --- .../components/prometheus/__init__.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/prometheus/__init__.py b/homeassistant/components/prometheus/__init__.py index 181da4977f0c44..5287390305cde2 100644 --- a/homeassistant/components/prometheus/__init__.py +++ b/homeassistant/components/prometheus/__init__.py @@ -288,11 +288,19 @@ def _handle_attributes(self, state: State) -> None: except (ValueError, TypeError): pass - def _get_labels( + def _get_label_keys( self, extra_labels: list[str] | None = None, ) -> list[str]: - labels = ["entity", "friendly_name", "domain"] + labels = [ + "entity", + "friendly_name", + "domain", + "area", + # "zone", + "entity_id", + "device_class", + ] if extra_labels is not None: labels.extend(extra_labels) return list(labels) @@ -304,7 +312,7 @@ def _metric( documentation: str, extra_labels: list[str] | None = None, ) -> _MetricBaseT: - labels = self._get_labels(extra_labels=extra_labels) + labels = self._get_label_keys(extra_labels=extra_labels) try: return cast(_MetricBaseT, self._metrics[metric]) @@ -354,6 +362,10 @@ def _labels(state: State) -> dict[str, Any]: "domain": state.domain, "friendly_name": state.attributes.get(ATTR_FRIENDLY_NAME), "area": state.attributes.get(ATTR_AREA_ID), + # TODO: how to get zone here? + # "zone": state.attributes.get(ATTR_AREA_ID), + "entity_id": state.object_id, + "device_class": state.attributes.get(ATTR_DEVICE_CLASS), } def _battery(self, state: State) -> None: From a44a9f00c9caeae3c2180e27e685bcbe7ce9007d Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 27 Mar 2024 21:41:02 -0700 Subject: [PATCH 04/62] Wanted to add some small things to gitignore too --- .dockerignore | 3 +++ .gitignore | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.dockerignore b/.dockerignore index 7fde7f33fa5587..f12c66a11d2bf7 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,6 +4,9 @@ config docs +# asdf +.tool-versions + # Development .devcontainer .vscode diff --git a/.gitignore b/.gitignore index 8a4154e4769964..64641d54a68b85 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,9 @@ Icon .idea *.iml +# asdf +.tool-versions + # pytest .pytest_cache .cache From 629cca48ed8aed7fffa077cf95663ca63dfb911d Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Thu, 28 Mar 2024 00:26:37 -0700 Subject: [PATCH 05/62] More metrics clean up --- homeassistant/components/prometheus/__init__.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/prometheus/__init__.py b/homeassistant/components/prometheus/__init__.py index 5287390305cde2..3108c609d7fbc9 100644 --- a/homeassistant/components/prometheus/__init__.py +++ b/homeassistant/components/prometheus/__init__.py @@ -289,16 +289,15 @@ def _handle_attributes(self, state: State) -> None: pass def _get_label_keys( - self, - extra_labels: list[str] | None = None, + self, + extra_labels: list[str] | None = None, ) -> list[str]: labels = [ "entity", "friendly_name", "domain", "area", - # "zone", - "entity_id", + "object_id", "device_class", ] if extra_labels is not None: @@ -361,11 +360,9 @@ def _labels(state: State) -> dict[str, Any]: "entity": state.entity_id, "domain": state.domain, "friendly_name": state.attributes.get(ATTR_FRIENDLY_NAME), - "area": state.attributes.get(ATTR_AREA_ID), - # TODO: how to get zone here? - # "zone": state.attributes.get(ATTR_AREA_ID), - "entity_id": state.object_id, - "device_class": state.attributes.get(ATTR_DEVICE_CLASS), + "area": state.attributes.get(ATTR_AREA_ID) or "", + "object_id": state.object_id, + "device_class": state.attributes.get(ATTR_DEVICE_CLASS) or "", } def _battery(self, state: State) -> None: From 7fc9217a7c04d5e33493f4de3ead67ceb0091b08 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Thu, 28 Mar 2024 01:26:39 -0700 Subject: [PATCH 06/62] The linter is harsh --- tests/components/prometheus/test_init.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 99b73209ad7437..5174239d043d64 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -143,9 +143,14 @@ async def test_setup_enumeration( client = await hass_client() body = await generate_latest_metrics(client) assert ( - 'homeassistant_sensor_temperature_celsius{domain="sensor",' + "homeassistant_sensor_temperature_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 12.3' in body + 'friendly_name="Outside Temperature",' + 'object_id="outside_temperature"' + "} 12.3" in body ) From 9de61870935dd2f44561f5a3669c9809aac5a97b Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Thu, 28 Mar 2024 02:09:58 -0700 Subject: [PATCH 07/62] Need to adjust a ton of tests --- tests/components/prometheus/test_init.py | 498 ++++++++++++++++++----- 1 file changed, 397 insertions(+), 101 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 5174239d043d64..41db57d655a720 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -168,15 +168,25 @@ async def test_view_empty_namespace( ) assert ( - 'entity_available{domain="sensor",' + "entity_available{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.radio_energy",' - 'friendly_name="Radio Energy"} 1.0' in body + 'friendly_name="Radio Energy",' + 'object_id="radio_energy"' + "} 1.0" in body ) assert ( - 'last_updated_time_seconds{domain="sensor",' + "last_updated_time_seconds{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.radio_energy",' - 'friendly_name="Radio Energy"} 86400.0' in body + 'friendly_name="Radio Energy",' + 'object_id="radio_energy' + "} 86400.0" in body ) @@ -194,9 +204,14 @@ async def test_view_default_namespace( ) assert ( - 'homeassistant_sensor_temperature_celsius{domain="sensor",' + "homeassistant_sensor_temperature_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 15.6' in body + 'friendly_name="Outside Temperature",' + 'object_id="outside_temperature"' + "} 15.6" in body ) @@ -208,27 +223,47 @@ async def test_sensor_unit( body = await generate_latest_metrics(client) assert ( - 'sensor_unit_kwh{domain="sensor",' + "sensor_unit_kwh{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.television_energy",' - 'friendly_name="Television Energy"} 74.0' in body + 'friendly_name="Television Energy",' + 'object_id="televisin_energy"' + "} 74.0" in body ) assert ( - 'sensor_unit_sek_per_kwh{domain="sensor",' + "sensor_unit_sek_per_kwh{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.electricity_price",' - 'friendly_name="Electricity price"} 0.123' in body + 'friendly_name="Electricity price",' + 'object_id="electricity_price"' + "} 0.123" in body ) assert ( - 'sensor_unit_u0xb0{domain="sensor",' + "sensor_unit_u0xb0{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.wind_direction",' - 'friendly_name="Wind Direction"} 25.0' in body + 'friendly_name="Wind Direction",' + 'object_id="wind_direction"' + "} 25.0" in body ) assert ( - 'sensor_unit_u0xb5g_per_mu0xb3{domain="sensor",' + "sensor_unit_u0xb5g_per_mu0xb3{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.sps30_pm_1um_weight_concentration",' - 'friendly_name="SPS30 PM <1µm Weight concentration"} 3.7069' in body + 'friendly_name="SPS30 PM <1µm Weight concentration",' + 'object_id="sps30_pm_1um_weight_concentration"' + "} 3.7069" in body ) @@ -240,19 +275,28 @@ async def test_sensor_without_unit( body = await generate_latest_metrics(client) assert ( - 'sensor_state{domain="sensor",' + "sensor_state{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.trend_gradient",' 'friendly_name="Trend Gradient"} 0.002' in body ) assert ( - 'sensor_state{domain="sensor",' + "sensor_state{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.text",' 'friendly_name="Text"} 0' not in body ) assert ( - 'sensor_unit_text{domain="sensor",' + "sensor_unit_text{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.text_unit",' 'friendly_name="Text Unit"} 0' not in body ) @@ -266,31 +310,46 @@ async def test_sensor_device_class( body = await generate_latest_metrics(client) assert ( - 'sensor_temperature_celsius{domain="sensor",' + "sensor_temperature_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.fahrenheit",' 'friendly_name="Fahrenheit"} 10.0' in body ) assert ( - 'sensor_temperature_celsius{domain="sensor",' + "sensor_temperature_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' 'friendly_name="Outside Temperature"} 15.6' in body ) assert ( - 'sensor_humidity_percent{domain="sensor",' + "sensor_humidity_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 54.0' in body ) assert ( - 'sensor_power_kwh{domain="sensor",' + "sensor_power_kwh{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.radio_energy",' 'friendly_name="Radio Energy"} 14.0' in body ) assert ( - 'sensor_timestamp_seconds{domain="sensor",' + "sensor_timestamp_seconds{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.timestamp",' 'friendly_name="Timestamp"} 1.691445808136036e+09' in body ) @@ -304,19 +363,28 @@ async def test_input_number( body = await generate_latest_metrics(client) assert ( - 'input_number_state{domain="input_number",' + "input_number_state{" + 'area="",' + 'device_class="temperature",' + 'domain="input_number",' 'entity="input_number.threshold",' 'friendly_name="Threshold"} 5.2' in body ) assert ( - 'input_number_state{domain="input_number",' + "input_number_state{" + 'area="",' + 'device_class="temperature",' + 'domain="input_number",' 'entity="input_number.brightness",' 'friendly_name="None"} 60.0' in body ) assert ( - 'input_number_state_celsius{domain="input_number",' + "input_number_state_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="input_number",' 'entity="input_number.target_temperature",' 'friendly_name="Target temperature"} 22.7' in body ) @@ -330,19 +398,28 @@ async def test_number( body = await generate_latest_metrics(client) assert ( - 'number_state{domain="number",' + "number_state{" + 'area="",' + 'device_class="temperature",' + 'domain="number",' 'entity="number.threshold",' 'friendly_name="Threshold"} 5.2' in body ) assert ( - 'number_state{domain="number",' + "number_state{" + 'area="",' + 'device_class="temperature",' + 'domain="number",' 'entity="number.brightness",' 'friendly_name="None"} 60.0' in body ) assert ( - 'number_state_celsius{domain="number",' + "number_state_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="number",' 'entity="number.target_temperature",' 'friendly_name="Target temperature"} 22.7' in body ) @@ -356,7 +433,10 @@ async def test_battery( body = await generate_latest_metrics(client) assert ( - 'battery_level_percent{domain="sensor",' + "battery_level_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' 'friendly_name="Outside Temperature"} 12.0' in body ) @@ -371,31 +451,46 @@ async def test_climate( body = await generate_latest_metrics(client) assert ( - 'climate_current_temperature_celsius{domain="climate",' + "climate_current_temperature_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="climate",' 'entity="climate.heatpump",' 'friendly_name="HeatPump"} 25.0' in body ) assert ( - 'climate_target_temperature_celsius{domain="climate",' + "climate_target_temperature_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="climate",' 'entity="climate.heatpump",' 'friendly_name="HeatPump"} 20.0' in body ) assert ( - 'climate_target_temperature_low_celsius{domain="climate",' + "climate_target_temperature_low_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="climate",' 'entity="climate.ecobee",' 'friendly_name="Ecobee"} 21.0' in body ) assert ( - 'climate_target_temperature_high_celsius{domain="climate",' + "climate_target_temperature_high_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="climate",' 'entity="climate.ecobee",' 'friendly_name="Ecobee"} 24.0' in body ) assert ( - 'climate_target_temperature_celsius{domain="climate",' + "climate_target_temperature_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="climate",' 'entity="climate.fritzdect",' 'friendly_name="Fritz!DECT"} 0.0' in body ) @@ -410,25 +505,37 @@ async def test_humidifier( body = await generate_latest_metrics(client) assert ( - 'humidifier_target_humidity_percent{domain="humidifier",' + "humidifier_target_humidity_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="humidifier",' 'entity="humidifier.humidifier",' 'friendly_name="Humidifier"} 68.0' in body ) assert ( - 'humidifier_state{domain="humidifier",' + "humidifier_state{" + 'area="",' + 'device_class="temperature",' + 'domain="humidifier",' 'entity="humidifier.dehumidifier",' 'friendly_name="Dehumidifier"} 1.0' in body ) assert ( - 'humidifier_mode{domain="humidifier",' + "humidifier_mode{" + 'area="",' + 'device_class="temperature",' + 'domain="humidifier",' 'entity="humidifier.hygrostat",' 'friendly_name="Hygrostat",' 'mode="home"} 1.0' in body ) assert ( - 'humidifier_mode{domain="humidifier",' + "humidifier_mode{" + 'area="",' + 'device_class="temperature",' + 'domain="humidifier",' 'entity="humidifier.hygrostat",' 'friendly_name="Hygrostat",' 'mode="eco"} 0.0' in body @@ -444,25 +551,37 @@ async def test_attributes( body = await generate_latest_metrics(client) assert ( - 'switch_state{domain="switch",' + "switch_state{" + 'area="",' + 'device_class="temperature",' + 'domain="switch",' 'entity="switch.boolean",' 'friendly_name="Boolean"} 1.0' in body ) assert ( - 'switch_attr_boolean{domain="switch",' + "switch_attr_boolean{" + 'area="",' + 'device_class="temperature",' + 'domain="switch",' 'entity="switch.boolean",' 'friendly_name="Boolean"} 1.0' in body ) assert ( - 'switch_state{domain="switch",' + "switch_state{" + 'area="",' + 'device_class="temperature",' + 'domain="switch",' 'entity="switch.number",' 'friendly_name="Number"} 0.0' in body ) assert ( - 'switch_attr_number{domain="switch",' + "switch_attr_number{" + 'area="",' + 'device_class="temperature",' + 'domain="switch",' 'entity="switch.number",' 'friendly_name="Number"} 10.2' in body ) @@ -476,13 +595,19 @@ async def test_binary_sensor( body = await generate_latest_metrics(client) assert ( - 'binary_sensor_state{domain="binary_sensor",' + "binary_sensor_state{" + 'area="",' + 'device_class="temperature",' + 'domain="binary_sensor",' 'entity="binary_sensor.door",' 'friendly_name="Door"} 1.0' in body ) assert ( - 'binary_sensor_state{domain="binary_sensor",' + "binary_sensor_state{" + 'area="",' + 'device_class="temperature",' + 'domain="binary_sensor",' 'entity="binary_sensor.window",' 'friendly_name="Window"} 0.0' in body ) @@ -496,13 +621,19 @@ async def test_input_boolean( body = await generate_latest_metrics(client) assert ( - 'input_boolean_state{domain="input_boolean",' + "input_boolean_state{" + 'area="",' + 'device_class="temperature",' + 'domain="input_boolean",' 'entity="input_boolean.test",' 'friendly_name="Test"} 1.0' in body ) assert ( - 'input_boolean_state{domain="input_boolean",' + "input_boolean_state{" + 'area="",' + 'device_class="temperature",' + 'domain="input_boolean",' 'entity="input_boolean.helper",' 'friendly_name="Helper"} 0.0' in body ) @@ -516,31 +647,46 @@ async def test_light( body = await generate_latest_metrics(client) assert ( - 'light_brightness_percent{domain="light",' + "light_brightness_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="light",' 'entity="light.desk",' 'friendly_name="Desk"} 100.0' in body ) assert ( - 'light_brightness_percent{domain="light",' + "light_brightness_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="light",' 'entity="light.wall",' 'friendly_name="Wall"} 0.0' in body ) assert ( - 'light_brightness_percent{domain="light",' + "light_brightness_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="light",' 'entity="light.tv",' 'friendly_name="TV"} 100.0' in body ) assert ( - 'light_brightness_percent{domain="light",' + "light_brightness_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="light",' 'entity="light.pc",' 'friendly_name="PC"} 70.58823529411765' in body ) assert ( - 'light_brightness_percent{domain="light",' + "light_brightness_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="light",' 'entity="light.hallway",' 'friendly_name="Hallway"} 100.0' in body ) @@ -554,13 +700,19 @@ async def test_lock( body = await generate_latest_metrics(client) assert ( - 'lock_state{domain="lock",' + "lock_state{" + 'area="",' + 'device_class="temperature",' + 'domain="lock",' 'entity="lock.front_door",' 'friendly_name="Front Door"} 1.0' in body ) assert ( - 'lock_state{domain="lock",' + "lock_state{" + 'area="",' + 'device_class="temperature",' + 'domain="lock",' 'entity="lock.kitchen_door",' 'friendly_name="Kitchen Door"} 0.0' in body ) @@ -577,7 +729,10 @@ async def test_cover( open_covers = ["cover_open", "cover_position", "cover_tilt_position"] for testcover in data: open_metric = ( - f'cover_state{{domain="cover",' + f"cover_state{{" + 'area="",' + 'device_class="temperature",' + f'domain="cover",' f'entity="{cover_entities[testcover].entity_id}",' f'friendly_name="{cover_entities[testcover].original_name}",' f'state="open"}} {1.0 if cover_entities[testcover].unique_id in open_covers else 0.0}' @@ -585,7 +740,10 @@ async def test_cover( assert open_metric in body closed_metric = ( - f'cover_state{{domain="cover",' + f'cover_state{{' + 'area="",' + 'device_class="temperature",' + f'domain="cover",' f'entity="{cover_entities[testcover].entity_id}",' f'friendly_name="{cover_entities[testcover].original_name}",' f'state="closed"}} {1.0 if cover_entities[testcover].unique_id == "cover_closed" else 0.0}' @@ -593,7 +751,10 @@ async def test_cover( assert closed_metric in body opening_metric = ( - f'cover_state{{domain="cover",' + f'cover_state{{' + 'area="",' + 'device_class="temperature",' + f'domain="cover",' f'entity="{cover_entities[testcover].entity_id}",' f'friendly_name="{cover_entities[testcover].original_name}",' f'state="opening"}} {1.0 if cover_entities[testcover].unique_id == "cover_opening" else 0.0}' @@ -601,7 +762,10 @@ async def test_cover( assert opening_metric in body closing_metric = ( - f'cover_state{{domain="cover",' + f'cover_state{{' + 'area="",' + 'device_class="temperature",' + f'domain="cover",' f'entity="{cover_entities[testcover].entity_id}",' f'friendly_name="{cover_entities[testcover].original_name}",' f'state="closing"}} {1.0 if cover_entities[testcover].unique_id == "cover_closing" else 0.0}' @@ -610,7 +774,10 @@ async def test_cover( if testcover == "cover_position": position_metric = ( - f'cover_position{{domain="cover",' + f"cover_position{{" + 'area="",' + 'device_class="temperature",' + f'domain="cover",' f'entity="{cover_entities[testcover].entity_id}",' f'friendly_name="{cover_entities[testcover].original_name}"' f"}} 50.0" @@ -619,7 +786,10 @@ async def test_cover( if testcover == "cover_tilt_position": tilt_position_metric = ( - f'cover_tilt_position{{domain="cover",' + f"cover_tilt_position{{" + 'area="",' + 'device_class="temperature",' + f'domain="cover",' f'entity="{cover_entities[testcover].entity_id}",' f'friendly_name="{cover_entities[testcover].original_name}"' f"}} 50.0" @@ -635,12 +805,18 @@ async def test_device_tracker( body = await generate_latest_metrics(client) assert ( - 'device_tracker_state{domain="device_tracker",' + "device_tracker_state{" + 'area="",' + 'device_class="temperature",' + 'domain="device_tracker",' 'entity="device_tracker.phone",' 'friendly_name="Phone"} 1.0' in body ) assert ( - 'device_tracker_state{domain="device_tracker",' + "device_tracker_state{" + 'area="",' + 'device_class="temperature",' + 'domain="device_tracker",' 'entity="device_tracker.watch",' 'friendly_name="Watch"} 0.0' in body ) @@ -654,7 +830,10 @@ async def test_counter( body = await generate_latest_metrics(client) assert ( - 'counter_value{domain="counter",' + "counter_value{" + 'area="",' + 'device_class="temperature",' + 'domain="counter",' 'entity="counter.counter",' 'friendly_name="None"} 2.0' in body ) @@ -668,12 +847,18 @@ async def test_update( body = await generate_latest_metrics(client) assert ( - 'update_state{domain="update",' + "update_state{" + 'area="",' + 'device_class="temperature",' + 'domain="update",' 'entity="update.firmware",' 'friendly_name="Firmware"} 1.0' in body ) assert ( - 'update_state{domain="update",' + "update_state{" + 'area="",' + 'device_class="temperature",' + 'domain="update",' 'entity="update.addon",' 'friendly_name="Addon"} 0.0' in body ) @@ -692,38 +877,56 @@ async def test_renaming_entity_name( body = await generate_latest_metrics(client) assert ( - 'sensor_temperature_celsius{domain="sensor",' + "sensor_temperature_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' 'friendly_name="Outside Temperature"} 15.6' in body ) assert ( - 'entity_available{domain="sensor",' + "entity_available{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' 'friendly_name="Outside Temperature"} 1.0' in body ) assert ( - 'sensor_humidity_percent{domain="sensor",' + "sensor_humidity_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 54.0' in body ) assert ( - 'entity_available{domain="sensor",' + "entity_available{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 1.0' in body ) assert ( - 'climate_action{action="heating",' + "climate_action{" + 'area="",' + 'device_class="temperature",' + 'action="heating",' 'domain="climate",' 'entity="climate.heatpump",' 'friendly_name="HeatPump"} 1.0' in body ) assert ( - 'climate_action{action="cooling",' + "climate_action{" + 'area="",' + 'device_class="temperature",' + 'action="cooling",' 'domain="climate",' 'entity="climate.heatpump",' 'friendly_name="HeatPump"} 0.0' in body @@ -766,26 +969,38 @@ async def test_renaming_entity_name( # Check if new metrics created assert ( - 'sensor_temperature_celsius{domain="sensor",' + "sensor_temperature_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' 'friendly_name="Outside Temperature Renamed"} 15.6' in body ) assert ( - 'entity_available{domain="sensor",' + "entity_available{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' 'friendly_name="Outside Temperature Renamed"} 1.0' in body ) assert ( - 'climate_action{action="heating",' + "climate_action{" + 'area="",' + 'device_class="temperature",' + 'action="heating",' 'domain="climate",' 'entity="climate.heatpump",' 'friendly_name="HeatPump Renamed"} 1.0' in body ) assert ( - 'climate_action{action="cooling",' + "climate_action{" + 'area="",' + 'device_class="temperature",' + 'action="cooling",' 'domain="climate",' 'entity="climate.heatpump",' 'friendly_name="HeatPump Renamed"} 0.0' in body @@ -793,13 +1008,19 @@ async def test_renaming_entity_name( # Keep other sensors assert ( - 'sensor_humidity_percent{domain="sensor",' + "sensor_humidity_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 54.0' in body ) assert ( - 'entity_available{domain="sensor",' + "entity_available{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 1.0' in body ) @@ -818,25 +1039,37 @@ async def test_renaming_entity_id( body = await generate_latest_metrics(client) assert ( - 'sensor_temperature_celsius{domain="sensor",' + "sensor_temperature_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' 'friendly_name="Outside Temperature"} 15.6' in body ) assert ( - 'entity_available{domain="sensor",' + "entity_available{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' 'friendly_name="Outside Temperature"} 1.0' in body ) assert ( - 'sensor_humidity_percent{domain="sensor",' + "sensor_humidity_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 54.0' in body ) assert ( - 'entity_available{domain="sensor",' + "entity_available{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 1.0' in body ) @@ -860,26 +1093,38 @@ async def test_renaming_entity_id( # Check if new metrics created assert ( - 'sensor_temperature_celsius{domain="sensor",' + "sensor_temperature_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature_renamed",' 'friendly_name="Outside Temperature"} 15.6' in body ) assert ( - 'entity_available{domain="sensor",' + "entity_available{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature_renamed",' 'friendly_name="Outside Temperature"} 1.0' in body ) # Keep other sensors assert ( - 'sensor_humidity_percent{domain="sensor",' + "sensor_humidity_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 54.0' in body ) assert ( - 'entity_available{domain="sensor",' + "entity_available{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 1.0' in body ) @@ -898,38 +1143,56 @@ async def test_deleting_entity( body = await generate_latest_metrics(client) assert ( - 'sensor_temperature_celsius{domain="sensor",' + "sensor_temperature_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' 'friendly_name="Outside Temperature"} 15.6' in body ) assert ( - 'entity_available{domain="sensor",' + "entity_available{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' 'friendly_name="Outside Temperature"} 1.0' in body ) assert ( - 'sensor_humidity_percent{domain="sensor",' + "sensor_humidity_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 54.0' in body ) assert ( - 'entity_available{domain="sensor",' + "entity_available{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 1.0' in body ) assert ( - 'climate_action{action="heating",' + "climate_action{" + 'area="",' + 'device_class="temperature",' + 'action="heating",' 'domain="climate",' 'entity="climate.heatpump",' 'friendly_name="HeatPump"} 1.0' in body ) assert ( - 'climate_action{action="cooling",' + "climate_action{" + 'area="",' + 'device_class="temperature",' + 'action="cooling",' 'domain="climate",' 'entity="climate.heatpump",' 'friendly_name="HeatPump"} 0.0' in body @@ -952,13 +1215,19 @@ async def test_deleting_entity( # Keep other sensors assert ( - 'sensor_humidity_percent{domain="sensor",' + "sensor_humidity_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 54.0' in body ) assert ( - 'entity_available{domain="sensor",' + "entity_available{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 1.0' in body ) @@ -979,45 +1248,66 @@ async def test_disabling_entity( body = await generate_latest_metrics(client) assert ( - 'sensor_temperature_celsius{domain="sensor",' + "sensor_temperature_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' 'friendly_name="Outside Temperature"} 15.6' in body ) assert ( - 'state_change_total{domain="sensor",' + "state_change_total{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' 'friendly_name="Outside Temperature"} 1.0' in body ) assert any( - 'state_change_created{domain="sensor",' + "state_change_created{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_temperature",' 'friendly_name="Outside Temperature"}' in metric for metric in body ) assert ( - 'sensor_humidity_percent{domain="sensor",' + "sensor_humidity_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 54.0' in body ) assert ( - 'entity_available{domain="sensor",' + "entity_available{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 1.0' in body ) assert ( - 'climate_action{action="heating",' + "climate_action{" + 'area="",' + 'device_class="temperature",' + 'action="heating",' 'domain="climate",' 'entity="climate.heatpump",' 'friendly_name="HeatPump"} 1.0' in body ) assert ( - 'climate_action{action="cooling",' + "climate_action{" + 'area="",' + 'device_class="temperature",' + 'action="cooling",' 'domain="climate",' 'entity="climate.heatpump",' 'friendly_name="HeatPump"} 0.0' in body @@ -1046,13 +1336,19 @@ async def test_disabling_entity( # Keep other sensors assert ( - 'sensor_humidity_percent{domain="sensor",' + "sensor_humidity_percent{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 54.0' in body ) assert ( - 'entity_available{domain="sensor",' + "entity_available{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' 'entity="sensor.outside_humidity",' 'friendly_name="Outside Humidity"} 1.0' in body ) From 8e1271d42d87a6819e638f5b68ba1f1ba13dde77 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Thu, 28 Mar 2024 12:23:52 -0700 Subject: [PATCH 08/62] I was finally able to commit --- tests/components/prometheus/test_init.py | 196 +++++++++++++++++------ 1 file changed, 147 insertions(+), 49 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 41db57d655a720..c777f6287af6bb 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -79,6 +79,89 @@ class FilterTest: should_pass: bool +class MetricsTestHelper: + """Initialize an hass_client with Prometheus component.""" + + @classmethod + def _perform_metric_assert( + cls, + metric_name, + domain, + friendly_name, + object_id, + device_class, + metric_value, + body, + area=None, + ): + # assert ( + # "homeassistant_sensor_temperature_celsius{" + # 'area="",' + # 'device_class="temperature",' + # 'domain="sensor",' + # 'entity="sensor.outside_temperature",' + # 'friendly_name="Outside Temperature",' + # 'object_id="outside_temperature"' + # "} 12.3" in body + # ) + assert ( + f"{metric_name}{{" + f'area="{area or ""}",' + f'device_class="{device_class}",' + f'domain="{domain}",' + f'entity="{domain}.{object_id}",' + f'friendly_name="{friendly_name}",' + f'object_id="{object_id}"' + f"}} {metric_value}" in body + ) + + @classmethod + def _perform_sensor_metric_assert( + cls, + metric_name, + metric_value, + friendly_name, + device_class, + object_id, + body, + area=None, + ): + cls._perform_metric_assert( + metric_name, + "sensor", + friendly_name, + object_id, + device_class, + metric_value, + body, + area=area, + ) + + @classmethod + def _perform_temperature_metric_assert( + cls, metric_value, friendly_name, object_id, body, area=None + ): + cls._perform_sensor_metric_assert( + "homeassistant_sensor_temperature_celsius", + friendly_name, + object_id, + "temperature", + metric_value, + body, + area=area, + ) + + @classmethod + def _perform_default_temperature_metric_assert(cls, metric_value, body): + cls._perform_temperature_metric_assert( + metric_value, + "sensor.outside_temperature", + "Outside Temperature", + "outside_temperature", + body, + ) + + @pytest.fixture(name="client") async def setup_prometheus_client( hass: HomeAssistant, @@ -137,21 +220,23 @@ async def test_setup_enumeration( suggested_object_id="outside_temperature", original_name="Outside Temperature", ) - set_state_with_entry(hass, sensor_1, 12.3, {}) + state = 12.3 + set_state_with_entry(hass, sensor_1, state, {}) assert await async_setup_component(hass, prometheus.DOMAIN, {prometheus.DOMAIN: {}}) client = await hass_client() body = await generate_latest_metrics(client) - assert ( - "homeassistant_sensor_temperature_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature",' - 'object_id="outside_temperature"' - "} 12.3" in body - ) + MetricsTestHelper._perform_default_temperature_metric_assert(state, body) + # assert ( + # "homeassistant_sensor_temperature_celsius{" + # 'area="",' + # 'device_class="temperature",' + # 'domain="sensor",' + # 'entity="sensor.outside_temperature",' + # 'friendly_name="Outside Temperature",' + # 'object_id="outside_temperature"' + # "} 12.3" in body + # ) @pytest.mark.parametrize("namespace", [""]) @@ -167,26 +252,37 @@ async def test_view_empty_namespace( "Objects collected during gc" in body ) - assert ( - "entity_available{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.radio_energy",' - 'friendly_name="Radio Energy",' - 'object_id="radio_energy"' - "} 1.0" in body - ) - - assert ( - "last_updated_time_seconds{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.radio_energy",' - 'friendly_name="Radio Energy",' - 'object_id="radio_energy' - "} 86400.0" in body + MetricsTestHelper._perform_sensor_metric_assert( + "entity_available", "1.0", "Radio Energy", "temperature", "radio_energy", body + ) + # assert ( + # "entity_available{" + # 'area="",' + # 'device_class="temperature",' + # 'domain="sensor",' + # 'entity="sensor.radio_energy",' + # 'friendly_name="Radio Energy",' + # 'object_id="radio_energy"' + # "} 1.0" in body + # ) + + # assert ( + # "last_updated_time_seconds{" + # 'area="",' + # 'device_class="temperature",' + # 'domain="sensor",' + # 'entity="sensor.radio_energy",' + # 'friendly_name="Radio Energy",' + # 'object_id="radio_energy' + # "} 86400.0" in body + # ) + MetricsTestHelper._perform_sensor_metric_assert( + "last_updated_time_seconds", + "86400.0", + "Radio Energy", + "temperature", + "radio_energy", + body, ) @@ -203,16 +299,17 @@ async def test_view_default_namespace( "Objects collected during gc" in body ) - assert ( - "homeassistant_sensor_temperature_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature",' - 'object_id="outside_temperature"' - "} 15.6" in body - ) + MetricsTestHelper._perform_default_temperature_metric_assert("15.6", body) + # assert ( + # "homeassistant_sensor_temperature_celsius{" + # 'area="",' + # 'device_class="temperature",' + # 'domain="sensor",' + # 'entity="sensor.outside_temperature",' + # 'friendly_name="Outside Temperature",' + # 'object_id="outside_temperature"' + # "} 15.6" in body + # ) @pytest.mark.parametrize("namespace", [""]) @@ -318,14 +415,15 @@ async def test_sensor_device_class( 'friendly_name="Fahrenheit"} 10.0' in body ) - assert ( - "sensor_temperature_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 15.6' in body - ) + # assert ( + # "sensor_temperature_celsius{" + # 'area="",' + # 'device_class="temperature",' + # 'domain="sensor",' + # 'entity="sensor.outside_temperature",' + # 'friendly_name="Outside Temperature"} 15.6' in body + # ) + MetricsTestHelper._perform_default_temperature_metric_assert("15.6", body) assert ( "sensor_humidity_percent{" From 4760a088a86b0d785d4482695e7576f76fe636f2 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Thu, 28 Mar 2024 12:24:53 -0700 Subject: [PATCH 09/62] Trying to abstract metrics into a helper class --- tests/components/prometheus/test_init.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index c777f6287af6bb..910849f3bf2c1c 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -80,7 +80,7 @@ class FilterTest: class MetricsTestHelper: - """Initialize an hass_client with Prometheus component.""" + """Helps with formatting prometheus metrics and future-proof label changes.""" @classmethod def _perform_metric_assert( From b3c7cc6d0e0ffdd0a3d70079c27b44043ffd7c89 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Thu, 28 Mar 2024 12:32:45 -0700 Subject: [PATCH 10/62] Fixed some tests at least --- tests/components/prometheus/test_init.py | 38 +++--------------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 910849f3bf2c1c..84fe65267e18de 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -94,16 +94,6 @@ def _perform_metric_assert( body, area=None, ): - # assert ( - # "homeassistant_sensor_temperature_celsius{" - # 'area="",' - # 'device_class="temperature",' - # 'domain="sensor",' - # 'entity="sensor.outside_temperature",' - # 'friendly_name="Outside Temperature",' - # 'object_id="outside_temperature"' - # "} 12.3" in body - # ) assert ( f"{metric_name}{{" f'area="{area or ""}",' @@ -143,22 +133,22 @@ def _perform_temperature_metric_assert( ): cls._perform_sensor_metric_assert( "homeassistant_sensor_temperature_celsius", + metric_value, friendly_name, - object_id, "temperature", - metric_value, + object_id, body, area=area, ) @classmethod - def _perform_default_temperature_metric_assert(cls, metric_value, body): + def _perform_default_temperature_metric_assert(cls, metric_value, body, area=None): cls._perform_temperature_metric_assert( metric_value, - "sensor.outside_temperature", "Outside Temperature", "outside_temperature", body, + area=area, ) @@ -227,16 +217,6 @@ async def test_setup_enumeration( client = await hass_client() body = await generate_latest_metrics(client) MetricsTestHelper._perform_default_temperature_metric_assert(state, body) - # assert ( - # "homeassistant_sensor_temperature_celsius{" - # 'area="",' - # 'device_class="temperature",' - # 'domain="sensor",' - # 'entity="sensor.outside_temperature",' - # 'friendly_name="Outside Temperature",' - # 'object_id="outside_temperature"' - # "} 12.3" in body - # ) @pytest.mark.parametrize("namespace", [""]) @@ -300,16 +280,6 @@ async def test_view_default_namespace( ) MetricsTestHelper._perform_default_temperature_metric_assert("15.6", body) - # assert ( - # "homeassistant_sensor_temperature_celsius{" - # 'area="",' - # 'device_class="temperature",' - # 'domain="sensor",' - # 'entity="sensor.outside_temperature",' - # 'friendly_name="Outside Temperature",' - # 'object_id="outside_temperature"' - # "} 15.6" in body - # ) @pytest.mark.parametrize("namespace", [""]) From 679f8748c84c36c1f05fb2884f6c98f1b220fadc Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Thu, 28 Mar 2024 17:58:01 -0700 Subject: [PATCH 11/62] Making progress on tests --- .../components/prometheus/__init__.py | 4 +- tests/components/prometheus/test_init.py | 496 ++++++++++-------- 2 files changed, 266 insertions(+), 234 deletions(-) diff --git a/homeassistant/components/prometheus/__init__.py b/homeassistant/components/prometheus/__init__.py index 3108c609d7fbc9..277b8a0f065674 100644 --- a/homeassistant/components/prometheus/__init__.py +++ b/homeassistant/components/prometheus/__init__.py @@ -298,7 +298,7 @@ def _get_label_keys( "domain", "area", "object_id", - "device_class", + # "device_class", ] if extra_labels is not None: labels.extend(extra_labels) @@ -362,7 +362,7 @@ def _labels(state: State) -> dict[str, Any]: "friendly_name": state.attributes.get(ATTR_FRIENDLY_NAME), "area": state.attributes.get(ATTR_AREA_ID) or "", "object_id": state.object_id, - "device_class": state.attributes.get(ATTR_DEVICE_CLASS) or "", + # "device_class": state.attributes.get(ATTR_DEVICE_CLASS) or "", } def _battery(self, state: State) -> None: diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 84fe65267e18de..f428a958717c26 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -86,24 +86,39 @@ class MetricsTestHelper: def _perform_metric_assert( cls, metric_name, + metric_value, domain, friendly_name, object_id, device_class, - metric_value, body, area=None, + positive_comparison=True, ): - assert ( + full_metric_string = ( f"{metric_name}{{" f'area="{area or ""}",' - f'device_class="{device_class}",' + # f'device_class="{device_class}",' f'domain="{domain}",' f'entity="{domain}.{object_id}",' f'friendly_name="{friendly_name}",' f'object_id="{object_id}"' - f"}} {metric_value}" in body + f"}} {metric_value}" ) + if positive_comparison: + assert full_metric_string in body + else: + assert full_metric_string not in body + # assert ( + # f"{metric_name}{{" + # f'area="{area or ""}",' + # # f'device_class="{device_class}",' + # f'domain="{domain}",' + # f'entity="{domain}.{object_id}",' + # f'friendly_name="{friendly_name}",' + # f'object_id="{object_id}"' + # f"}} {metric_value}" in body + # ) @classmethod def _perform_sensor_metric_assert( @@ -115,14 +130,117 @@ def _perform_sensor_metric_assert( object_id, body, area=None, + positive_comparison=True, ): cls._perform_metric_assert( metric_name, + metric_value, "sensor", friendly_name, object_id, device_class, + body, + area=area, + positive_comparison=positive_comparison, + ) + + @classmethod + def _perform_climate_metric_assert( + cls, + metric_name, + metric_value, + friendly_name, + device_class, + object_id, + body, + area=None, + ): + cls._perform_metric_assert( + metric_name, + metric_value, + "climate", + friendly_name, + object_id, + device_class, + body, + area=area, + ) + + @classmethod + def _perform_humidifier_metric_assert( + cls, + metric_name, + metric_value, + friendly_name, + device_class, + object_id, + body, + area=None, + mode=None, + ): + domain = "humidifier" + assert ( + f"{metric_name}{{" + f'area="{area or ""}",' + # f'device_class="{device_class}",' + f'domain="{domain}",' + f'entity="{domain}.{object_id}",' + f'friendly_name="{friendly_name}",' + f'mode="{mode}",' + if mode + else "" f'object_id="{object_id}"' f"}} {metric_value}" in body + ) + # cls._perform_metric_assert( + # metric_name, + # metric_value, + # "humidifier", + # friendly_name, + # object_id, + # device_class, + # body, + # area=area, + # ) + + @classmethod + def _perform_number_metric_assert( + cls, + metric_name, + metric_value, + friendly_name, + device_class, + object_id, + body, + area=None, + ): + cls._perform_metric_assert( + metric_name, + metric_value, + "number", + friendly_name, + object_id, + device_class, + body, + area=area, + ) + + @classmethod + def _perform_input_number_metric_assert( + cls, + metric_name, + metric_value, + friendly_name, + device_class, + object_id, + body, + area=None, + ): + cls._perform_metric_assert( + metric_name, metric_value, + "input_number", + friendly_name, + object_id, + device_class, body, area=area, ) @@ -235,27 +353,7 @@ async def test_view_empty_namespace( MetricsTestHelper._perform_sensor_metric_assert( "entity_available", "1.0", "Radio Energy", "temperature", "radio_energy", body ) - # assert ( - # "entity_available{" - # 'area="",' - # 'device_class="temperature",' - # 'domain="sensor",' - # 'entity="sensor.radio_energy",' - # 'friendly_name="Radio Energy",' - # 'object_id="radio_energy"' - # "} 1.0" in body - # ) - # assert ( - # "last_updated_time_seconds{" - # 'area="",' - # 'device_class="temperature",' - # 'domain="sensor",' - # 'entity="sensor.radio_energy",' - # 'friendly_name="Radio Energy",' - # 'object_id="radio_energy' - # "} 86400.0" in body - # ) MetricsTestHelper._perform_sensor_metric_assert( "last_updated_time_seconds", "86400.0", @@ -289,48 +387,30 @@ async def test_sensor_unit( """Test prometheus metrics for sensors with a unit.""" body = await generate_latest_metrics(client) - assert ( - "sensor_unit_kwh{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.television_energy",' - 'friendly_name="Television Energy",' - 'object_id="televisin_energy"' - "} 74.0" in body + MetricsTestHelper._perform_sensor_metric_assert( + "sensor_unit_kwh", "74.0", "Television Energy", "", "television_energy", body ) - assert ( - "sensor_unit_sek_per_kwh{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.electricity_price",' - 'friendly_name="Electricity price",' - 'object_id="electricity_price"' - "} 0.123" in body + MetricsTestHelper._perform_sensor_metric_assert( + "sensor_unit_sek_per_kwh", + "0.123", + "Electricity price", + "", + "electricity_price", + body, ) - assert ( - "sensor_unit_u0xb0{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.wind_direction",' - 'friendly_name="Wind Direction",' - 'object_id="wind_direction"' - "} 25.0" in body + MetricsTestHelper._perform_sensor_metric_assert( + "sensor_unit_u0xb0", "25.0", "Wind Direction", "", "wind_direction", body ) - assert ( - "sensor_unit_u0xb5g_per_mu0xb3{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.sps30_pm_1um_weight_concentration",' - 'friendly_name="SPS30 PM <1µm Weight concentration",' - 'object_id="sps30_pm_1um_weight_concentration"' - "} 3.7069" in body + MetricsTestHelper._perform_sensor_metric_assert( + "sensor_unit_u0xb5g_per_mu0xb3", + "3.7069", + "SPS30 PM <1µm Weight concentration", + "", + "sps30_pm_1um_weight_concentration", + body, ) @@ -341,31 +421,22 @@ async def test_sensor_without_unit( """Test prometheus metrics for sensors without a unit.""" body = await generate_latest_metrics(client) - assert ( - "sensor_state{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.trend_gradient",' - 'friendly_name="Trend Gradient"} 0.002' in body + MetricsTestHelper._perform_sensor_metric_assert( + "sensor_state", "0.002", "Trend Gradient", "", "trend_gradient", body ) - assert ( - "sensor_state{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.text",' - 'friendly_name="Text"} 0' not in body + MetricsTestHelper._perform_sensor_metric_assert( + "sensor_state", "0", "Text", "", "text", body, positive_comparison=False ) - assert ( - "sensor_unit_text{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.text_unit",' - 'friendly_name="Text Unit"} 0' not in body + MetricsTestHelper._perform_sensor_metric_assert( + "sensor_unit_text", + "0", + "Text Unit", + "", + "text_unit", + body, + positive_comparison=False, ) @@ -376,50 +447,39 @@ async def test_sensor_device_class( """Test prometheus metrics for sensor with a device_class.""" body = await generate_latest_metrics(client) - assert ( - "sensor_temperature_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.fahrenheit",' - 'friendly_name="Fahrenheit"} 10.0' in body + MetricsTestHelper._perform_sensor_metric_assert( + "sensor_temperature_celsius", "10.0", "Fahrenheit", "", "fahrenheit", body ) - # assert ( - # "sensor_temperature_celsius{" - # 'area="",' - # 'device_class="temperature",' - # 'domain="sensor",' - # 'entity="sensor.outside_temperature",' - # 'friendly_name="Outside Temperature"} 15.6' in body - # ) - MetricsTestHelper._perform_default_temperature_metric_assert("15.6", body) + MetricsTestHelper._perform_sensor_metric_assert( + "sensor_temperature_celsius", + "15.6", + "Outside Temperature", + "", + "outside_temperature", + body, + ) - assert ( - "sensor_humidity_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 54.0' in body + MetricsTestHelper._perform_sensor_metric_assert( + "sensor_humidity_percent", + "54.0", + "Outside Humidity", + "", + "outside_humidity", + body, ) - assert ( - "sensor_power_kwh{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.radio_energy",' - 'friendly_name="Radio Energy"} 14.0' in body + MetricsTestHelper._perform_sensor_metric_assert( + "sensor_power_kwh", "14.0", "Radio Energy", "", "radio_energy", body ) - assert ( - "sensor_timestamp_seconds{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.timestamp",' - 'friendly_name="Timestamp"} 1.691445808136036e+09' in body + MetricsTestHelper._perform_sensor_metric_assert( + "sensor_timestamp_seconds", + "1.691445808136036e+09", + "Timestamp", + "", + "timestamp", + body, ) @@ -430,31 +490,21 @@ async def test_input_number( """Test prometheus metrics for input_number.""" body = await generate_latest_metrics(client) - assert ( - "input_number_state{" - 'area="",' - 'device_class="temperature",' - 'domain="input_number",' - 'entity="input_number.threshold",' - 'friendly_name="Threshold"} 5.2' in body + MetricsTestHelper._perform_input_number_metric_assert( + "input_number_state", "5.2", "Threshold", "", "threshold", body ) - assert ( - "input_number_state{" - 'area="",' - 'device_class="temperature",' - 'domain="input_number",' - 'entity="input_number.brightness",' - 'friendly_name="None"} 60.0' in body + MetricsTestHelper._perform_input_number_metric_assert( + "input_number_state", "60.0", "None", "", "brightness", body ) - assert ( - "input_number_state_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="input_number",' - 'entity="input_number.target_temperature",' - 'friendly_name="Target temperature"} 22.7' in body + MetricsTestHelper._perform_input_number_metric_assert( + "input_number_state_celsius", + "22.7", + "Target temperature", + "", + "target_temperature", + body, ) @@ -465,31 +515,21 @@ async def test_number( """Test prometheus metrics for number.""" body = await generate_latest_metrics(client) - assert ( - "number_state{" - 'area="",' - 'device_class="temperature",' - 'domain="number",' - 'entity="number.threshold",' - 'friendly_name="Threshold"} 5.2' in body + MetricsTestHelper._perform_number_metric_assert( + "number_state", "5.2", "Threshold", "", "threshold", body ) - assert ( - "number_state{" - 'area="",' - 'device_class="temperature",' - 'domain="number",' - 'entity="number.brightness",' - 'friendly_name="None"} 60.0' in body + MetricsTestHelper._perform_number_metric_assert( + "number_state", "60.0", "None", "", "brightness", body ) - assert ( - "number_state_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="number",' - 'entity="number.target_temperature",' - 'friendly_name="Target temperature"} 22.7' in body + MetricsTestHelper._perform_number_metric_assert( + "number_state_celsius", + "22.7", + "Target temperature", + "", + "target_temperature", + body, ) @@ -500,13 +540,13 @@ async def test_battery( """Test prometheus metrics for battery.""" body = await generate_latest_metrics(client) - assert ( - "battery_level_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 12.0' in body + MetricsTestHelper._perform_sensor_metric_assert( + "battery_level_percent", + "12.0", + "Outside Temperature", + "", + "outside_temperature", + body, ) @@ -518,49 +558,24 @@ async def test_climate( """Test prometheus metrics for climate entities.""" body = await generate_latest_metrics(client) - assert ( - "climate_current_temperature_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="climate",' - 'entity="climate.heatpump",' - 'friendly_name="HeatPump"} 25.0' in body + MetricsTestHelper._perform_climate_metric_assert( + "climate_current_temperature_celsius", "25.0", "HeatPump", "", "heatpump", body ) - assert ( - "climate_target_temperature_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="climate",' - 'entity="climate.heatpump",' - 'friendly_name="HeatPump"} 20.0' in body + MetricsTestHelper._perform_climate_metric_assert( + "climate_target_temperature_celsius", "20.0", "HeatPump", "", "heatpump", body ) - assert ( - "climate_target_temperature_low_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="climate",' - 'entity="climate.ecobee",' - 'friendly_name="Ecobee"} 21.0' in body + MetricsTestHelper._perform_climate_metric_assert( + "climate_target_temperature_low_celsius", "21.0", "Ecobee", "", "ecobee", body ) - assert ( - "climate_target_temperature_high_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="climate",' - 'entity="climate.ecobee",' - 'friendly_name="Ecobee"} 24.0' in body + MetricsTestHelper._perform_climate_metric_assert( + "climate_target_temperature_high_celsius", "24.0", "Ecobee", "", "ecobee", body ) - assert ( - "climate_target_temperature_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="climate",' - 'entity="climate.fritzdect",' - 'friendly_name="Fritz!DECT"} 0.0' in body + MetricsTestHelper._perform_climate_metric_assert( + "climate_target_temperature_celsius", "0.0", "Fritz!DECT", "", "fritzdect", body ) @@ -572,42 +587,59 @@ async def test_humidifier( """Test prometheus metrics for humidifier entities.""" body = await generate_latest_metrics(client) - assert ( - "humidifier_target_humidity_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="humidifier",' - 'entity="humidifier.humidifier",' - 'friendly_name="Humidifier"} 68.0' in body + MetricsTestHelper._perform_humidifier_metric_assert( + "humidifier_target_humidity_percent", + "68.0", + "Humidifier", + "", + "humidifier", + body, ) + # assert ( + # "humidifier_target_humidity_percent{" + # 'area="",' + # 'device_class="temperature",' + # 'domain="humidifier",' + # 'entity="humidifier.humidifier",' + # 'friendly_name="Humidifier"} 68.0' in body + # ) - assert ( - "humidifier_state{" - 'area="",' - 'device_class="temperature",' - 'domain="humidifier",' - 'entity="humidifier.dehumidifier",' - 'friendly_name="Dehumidifier"} 1.0' in body + MetricsTestHelper._perform_humidifier_metric_assert( + "humidifier_state", "1.0", "Dehumidifier", "", "dehumidifier", body ) + # assert ( + # "humidifier_state{" + # 'area="",' + # 'device_class="temperature",' + # 'domain="humidifier",' + # 'entity="humidifier.dehumidifier",' + # 'friendly_name="Dehumidifier"} 1.0' in body + # ) - assert ( - "humidifier_mode{" - 'area="",' - 'device_class="temperature",' - 'domain="humidifier",' - 'entity="humidifier.hygrostat",' - 'friendly_name="Hygrostat",' - 'mode="home"} 1.0' in body + MetricsTestHelper._perform_humidifier_metric_assert( + "humidifier_mode", "1.0", "Hygrostat", "", "hygrostat", body, mode="home" ) - assert ( - "humidifier_mode{" - 'area="",' - 'device_class="temperature",' - 'domain="humidifier",' - 'entity="humidifier.hygrostat",' - 'friendly_name="Hygrostat",' - 'mode="eco"} 0.0' in body + # assert ( + # "humidifier_mode{" + # 'area="",' + # 'device_class="temperature",' + # 'domain="humidifier",' + # 'entity="humidifier.hygrostat",' + # 'friendly_name="Hygrostat",' + # 'mode="home"} 1.0' in body + # ) + MetricsTestHelper._perform_humidifier_metric_assert( + "humidifier_mode", "0.0", "Hygrostat", "", "hygrostat", body, mode="eco" ) + # assert ( + # "humidifier_mode{" + # 'area="",' + # 'device_class="temperature",' + # 'domain="humidifier",' + # 'entity="humidifier.hygrostat",' + # 'friendly_name="Hygrostat",' + # 'mode="eco"} 0.0' in body + # ) @pytest.mark.parametrize("namespace", [""]) From e1249981c0432a1c529e31b895e87340b6dc0ed9 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 00:07:11 -0700 Subject: [PATCH 12/62] Getting really close now --- tests/components/prometheus/test_init.py | 458 +++++++++-------------- 1 file changed, 177 insertions(+), 281 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index f428a958717c26..5c9e3e9050c001 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -89,8 +89,8 @@ def _perform_metric_assert( metric_value, domain, friendly_name, - object_id, device_class, + object_id, body, area=None, positive_comparison=True, @@ -137,8 +137,8 @@ def _perform_sensor_metric_assert( metric_value, "sensor", friendly_name, - object_id, device_class, + object_id, body, area=area, positive_comparison=positive_comparison, @@ -154,14 +154,50 @@ def _perform_climate_metric_assert( object_id, body, area=None, + action=None, + ): + domain = "climate" + action_label_line = f'action="{action}",' if action else "" + assert ( + f"{metric_name}{{" + f'{action_label_line}' + f'area="{area or ""}",' + # f'device_class="{device_class}",' + f'domain="{domain}",' + f'entity="{domain}.{object_id}",' + f'friendly_name="{friendly_name}",' + f'object_id="{object_id}"' + f"}} {metric_value}" in body + ) + # cls._perform_metric_assert( + # metric_name, + # metric_value, + # "climate", + # friendly_name, + # device_class, + # object_id, + # body, + # area=area, + # ) + + @classmethod + def _perform_switch_metric_assert( + cls, + metric_name, + metric_value, + friendly_name, + device_class, + object_id, + body, + area=None, ): cls._perform_metric_assert( metric_name, metric_value, - "climate", + "switch", friendly_name, - object_id, device_class, + object_id, body, area=area, ) @@ -179,6 +215,7 @@ def _perform_humidifier_metric_assert( mode=None, ): domain = "humidifier" + mode_label_line = f'mode="{mode}",' if mode else "" assert ( f"{metric_name}{{" f'area="{area or ""}",' @@ -186,20 +223,10 @@ def _perform_humidifier_metric_assert( f'domain="{domain}",' f'entity="{domain}.{object_id}",' f'friendly_name="{friendly_name}",' - f'mode="{mode}",' - if mode - else "" f'object_id="{object_id}"' f"}} {metric_value}" in body + f'{mode_label_line}' + f'object_id="{object_id}"' + f"}} {metric_value}" in body ) - # cls._perform_metric_assert( - # metric_name, - # metric_value, - # "humidifier", - # friendly_name, - # object_id, - # device_class, - # body, - # area=area, - # ) @classmethod def _perform_number_metric_assert( @@ -217,8 +244,8 @@ def _perform_number_metric_assert( metric_value, "number", friendly_name, - object_id, device_class, + object_id, body, area=area, ) @@ -239,8 +266,8 @@ def _perform_input_number_metric_assert( metric_value, "input_number", friendly_name, - object_id, device_class, + object_id, body, area=area, ) @@ -595,51 +622,17 @@ async def test_humidifier( "humidifier", body, ) - # assert ( - # "humidifier_target_humidity_percent{" - # 'area="",' - # 'device_class="temperature",' - # 'domain="humidifier",' - # 'entity="humidifier.humidifier",' - # 'friendly_name="Humidifier"} 68.0' in body - # ) MetricsTestHelper._perform_humidifier_metric_assert( "humidifier_state", "1.0", "Dehumidifier", "", "dehumidifier", body ) - # assert ( - # "humidifier_state{" - # 'area="",' - # 'device_class="temperature",' - # 'domain="humidifier",' - # 'entity="humidifier.dehumidifier",' - # 'friendly_name="Dehumidifier"} 1.0' in body - # ) MetricsTestHelper._perform_humidifier_metric_assert( "humidifier_mode", "1.0", "Hygrostat", "", "hygrostat", body, mode="home" ) - # assert ( - # "humidifier_mode{" - # 'area="",' - # 'device_class="temperature",' - # 'domain="humidifier",' - # 'entity="humidifier.hygrostat",' - # 'friendly_name="Hygrostat",' - # 'mode="home"} 1.0' in body - # ) MetricsTestHelper._perform_humidifier_metric_assert( "humidifier_mode", "0.0", "Hygrostat", "", "hygrostat", body, mode="eco" ) - # assert ( - # "humidifier_mode{" - # 'area="",' - # 'device_class="temperature",' - # 'domain="humidifier",' - # 'entity="humidifier.hygrostat",' - # 'friendly_name="Hygrostat",' - # 'mode="eco"} 0.0' in body - # ) @pytest.mark.parametrize("namespace", [""]) @@ -650,40 +643,20 @@ async def test_attributes( """Test prometheus metrics for entity attributes.""" body = await generate_latest_metrics(client) - assert ( - "switch_state{" - 'area="",' - 'device_class="temperature",' - 'domain="switch",' - 'entity="switch.boolean",' - 'friendly_name="Boolean"} 1.0' in body + MetricsTestHelper._perform_switch_metric_assert( + "switch_state", "1.0", "Boolean", "", "boolean", body ) - assert ( - "switch_attr_boolean{" - 'area="",' - 'device_class="temperature",' - 'domain="switch",' - 'entity="switch.boolean",' - 'friendly_name="Boolean"} 1.0' in body + MetricsTestHelper._perform_switch_metric_assert( + "switch_attr_boolean", "1.0", "Boolean", "", "boolean", body ) - assert ( - "switch_state{" - 'area="",' - 'device_class="temperature",' - 'domain="switch",' - 'entity="switch.number",' - 'friendly_name="Number"} 0.0' in body + MetricsTestHelper._perform_switch_metric_assert( + "switch_state", "0.0", "Number", "", "number", body ) - assert ( - "switch_attr_number{" - 'area="",' - 'device_class="temperature",' - 'domain="switch",' - 'entity="switch.number",' - 'friendly_name="Number"} 10.2' in body + MetricsTestHelper._perform_switch_metric_assert( + "switch_attr_number", "10.2", "Number", "", "number", body ) @@ -694,22 +667,13 @@ async def test_binary_sensor( """Test prometheus metrics for binary_sensor.""" body = await generate_latest_metrics(client) - assert ( - "binary_sensor_state{" - 'area="",' - 'device_class="temperature",' - 'domain="binary_sensor",' - 'entity="binary_sensor.door",' - 'friendly_name="Door"} 1.0' in body + domain = "binary_sensor" + MetricsTestHelper._perform_metric_assert( + "binary_sensor_state", "1.0", domain, "Door", "", "door", body ) - assert ( - "binary_sensor_state{" - 'area="",' - 'device_class="temperature",' - 'domain="binary_sensor",' - 'entity="binary_sensor.window",' - 'friendly_name="Window"} 0.0' in body + MetricsTestHelper._perform_metric_assert( + "binary_sensor_state", "0.0", domain, "Window", "", "window", body ) @@ -720,22 +684,13 @@ async def test_input_boolean( """Test prometheus metrics for input_boolean.""" body = await generate_latest_metrics(client) - assert ( - "input_boolean_state{" - 'area="",' - 'device_class="temperature",' - 'domain="input_boolean",' - 'entity="input_boolean.test",' - 'friendly_name="Test"} 1.0' in body + domain = "input_boolean" + MetricsTestHelper._perform_metric_assert( + "input_boolean_state", "1.0", domain, "Test", "", "test", body ) - assert ( - "input_boolean_state{" - 'area="",' - 'device_class="temperature",' - 'domain="input_boolean",' - 'entity="input_boolean.helper",' - 'friendly_name="Helper"} 0.0' in body + MetricsTestHelper._perform_metric_assert( + "input_boolean_state", "0.0", domain, "Helper", "", "helper", body ) @@ -746,49 +701,25 @@ async def test_light( """Test prometheus metrics for lights.""" body = await generate_latest_metrics(client) - assert ( - "light_brightness_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="light",' - 'entity="light.desk",' - 'friendly_name="Desk"} 100.0' in body + domain = "light" + MetricsTestHelper._perform_metric_assert( + "light_brightness_percent", "100.0", domain, "Desk", "", "desk", body ) - assert ( - "light_brightness_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="light",' - 'entity="light.wall",' - 'friendly_name="Wall"} 0.0' in body + MetricsTestHelper._perform_metric_assert( + "light_brightness_percent", "0.0", domain, "Wall", "", "wall", body ) - assert ( - "light_brightness_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="light",' - 'entity="light.tv",' - 'friendly_name="TV"} 100.0' in body + MetricsTestHelper._perform_metric_assert( + "light_brightness_percent", "100.0", domain, "TV", "", "tv", body ) - assert ( - "light_brightness_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="light",' - 'entity="light.pc",' - 'friendly_name="PC"} 70.58823529411765' in body + MetricsTestHelper._perform_metric_assert( + "light_brightness_percent", "70.58823529411765", domain, "PC", "", "pc", body ) - assert ( - "light_brightness_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="light",' - 'entity="light.hallway",' - 'friendly_name="Hallway"} 100.0' in body + MetricsTestHelper._perform_metric_assert( + "light_brightness_percent", "100.0", domain, "Hallway", "", "hallway", body ) @@ -799,22 +730,13 @@ async def test_lock( """Test prometheus metrics for lock.""" body = await generate_latest_metrics(client) - assert ( - "lock_state{" - 'area="",' - 'device_class="temperature",' - 'domain="lock",' - 'entity="lock.front_door",' - 'friendly_name="Front Door"} 1.0' in body + domain = "lock" + MetricsTestHelper._perform_metric_assert( + "lock_state", "1.0", domain, "Front Door", "", "front_door", body ) - assert ( - "lock_state{" - 'area="",' - 'device_class="temperature",' - 'domain="lock",' - 'entity="lock.kitchen_door",' - 'friendly_name="Kitchen Door"} 0.0' in body + MetricsTestHelper._perform_metric_assert( + "lock_state", "0.0", domain, "Kitchen Door", "", "kitchen_door", body ) @@ -904,21 +826,12 @@ async def test_device_tracker( """Test prometheus metrics for device_tracker.""" body = await generate_latest_metrics(client) - assert ( - "device_tracker_state{" - 'area="",' - 'device_class="temperature",' - 'domain="device_tracker",' - 'entity="device_tracker.phone",' - 'friendly_name="Phone"} 1.0' in body + domain = "device_tracker" + MetricsTestHelper._perform_metric_assert( + "device_tracker_state", "1.0", domain, "Phone", "", "phone", body ) - assert ( - "device_tracker_state{" - 'area="",' - 'device_class="temperature",' - 'domain="device_tracker",' - 'entity="device_tracker.watch",' - 'friendly_name="Watch"} 0.0' in body + MetricsTestHelper._perform_metric_assert( + "device_tracker_state", "0.0", domain, "Watch", "", "watch", body ) @@ -929,13 +842,9 @@ async def test_counter( """Test prometheus metrics for counter.""" body = await generate_latest_metrics(client) - assert ( - "counter_value{" - 'area="",' - 'device_class="temperature",' - 'domain="counter",' - 'entity="counter.counter",' - 'friendly_name="None"} 2.0' in body + domain = "counter" + MetricsTestHelper._perform_metric_assert( + "counter_value", "2.0", domain, "None", "", "counter", body ) @@ -946,21 +855,12 @@ async def test_update( """Test prometheus metrics for update.""" body = await generate_latest_metrics(client) - assert ( - "update_state{" - 'area="",' - 'device_class="temperature",' - 'domain="update",' - 'entity="update.firmware",' - 'friendly_name="Firmware"} 1.0' in body + domain = "update" + MetricsTestHelper._perform_metric_assert( + "update_state", "1.0", domain, "Firmware", "", "firmware", body ) - assert ( - "update_state{" - 'area="",' - 'device_class="temperature",' - 'domain="update",' - 'entity="update.addon",' - 'friendly_name="Addon"} 0.0' in body + MetricsTestHelper._perform_metric_assert( + "update_state", "0.0", domain, "Addon", "", "addon", body ) @@ -976,60 +876,52 @@ async def test_renaming_entity_name( data = {**sensor_entities, **climate_entities} body = await generate_latest_metrics(client) - assert ( - "sensor_temperature_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 15.6' in body + MetricsTestHelper._perform_metric_assert( + "sensor_temperature_celsius", + "15.6", + "sensor", + "Outside Temperature", + "", + "outside_temperature", + body, ) - assert ( - "entity_available{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 1.0' in body + MetricsTestHelper._perform_metric_assert( + "entity_available", + "1.0", + "sensor", + "Outside Temperature", + "", + "outside_temperature", + body, ) - assert ( - "sensor_humidity_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 54.0' in body + MetricsTestHelper._perform_metric_assert( + "sensor_humidity_percent", + "54.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) - assert ( - "entity_available{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 1.0' in body + MetricsTestHelper._perform_metric_assert( + "entity_available", + "1.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) - assert ( - "climate_action{" - 'area="",' - 'device_class="temperature",' - 'action="heating",' - 'domain="climate",' - 'entity="climate.heatpump",' - 'friendly_name="HeatPump"} 1.0' in body + MetricsTestHelper._perform_climate_metric_assert( + "climate_action", "1.0", "HeatPump", "", "heatpump", body, action="heating" ) - assert ( - "climate_action{" - 'area="",' - 'device_class="temperature",' - 'action="cooling",' - 'domain="climate",' - 'entity="climate.heatpump",' - 'friendly_name="HeatPump"} 0.0' in body + MetricsTestHelper._perform_climate_metric_assert( + "climate_action", "0.0", "HeatPump", "", "heatpump", body, action="cooling" ) assert "sensor.outside_temperature" in entity_registry.entities @@ -1068,61 +960,65 @@ async def test_renaming_entity_name( assert 'friendly_name="HeatPump"' not in body_line # Check if new metrics created - assert ( - "sensor_temperature_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature Renamed"} 15.6' in body + MetricsTestHelper._perform_metric_assert( + "sensor_temperature_celsius", + "15.6", + "sensor", + "Outside Temperature Renamed", + "", + "outside_temperature", + body, ) - assert ( - "entity_available{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature Renamed"} 1.0' in body + MetricsTestHelper._perform_metric_assert( + "entity_available", + "1.0", + "sensor", + "Outside Temperature Renamed", + "", + "outside_temperature", + body, ) - assert ( - "climate_action{" - 'area="",' - 'device_class="temperature",' - 'action="heating",' - 'domain="climate",' - 'entity="climate.heatpump",' - 'friendly_name="HeatPump Renamed"} 1.0' in body + MetricsTestHelper._perform_climate_metric_assert( + "climate_action", + "1.0", + "HeatPump Renamed", + "", + "heatpump", + body, + action="heating", ) - assert ( - "climate_action{" - 'area="",' - 'device_class="temperature",' - 'action="cooling",' - 'domain="climate",' - 'entity="climate.heatpump",' - 'friendly_name="HeatPump Renamed"} 0.0' in body + MetricsTestHelper._perform_climate_metric_assert( + "climate_action", + "0.0", + "HeatPump Renamed", + "", + "heatpump", + body, + action="cooling", ) # Keep other sensors - assert ( - "sensor_humidity_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 54.0' in body + MetricsTestHelper._perform_metric_assert( + "sensor_humidity_percent", + "54.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) - assert ( - "entity_available{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 1.0' in body + MetricsTestHelper._perform_metric_assert( + "entity_available", + "1.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) From b74a4a729ba069b1329b0247e2953476d66bdcef Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 00:31:34 -0700 Subject: [PATCH 13/62] Only 1 or 2 tests left to fix --- tests/components/prometheus/test_init.py | 368 ++++++++++++----------- 1 file changed, 187 insertions(+), 181 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 5c9e3e9050c001..c01b0da5926132 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -1034,40 +1034,44 @@ async def test_renaming_entity_id( data = {**sensor_entities, **climate_entities} body = await generate_latest_metrics(client) - assert ( - "sensor_temperature_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 15.6' in body + MetricsTestHelper._perform_metric_assert( + "sensor_temperature_celsius", + "15.6", + "sensor", + "Outside Temperature", + "", + "outside_temperature", + body, ) - assert ( - "entity_available{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 1.0' in body + MetricsTestHelper._perform_metric_assert( + "entity_available", + "1.0", + "sensor", + "Outside Temperature", + "", + "outside_temperature", + body, ) - assert ( - "sensor_humidity_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 54.0' in body + MetricsTestHelper._perform_metric_assert( + "sensor_humidity_percent", + "54.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) - assert ( - "entity_available{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 1.0' in body + MetricsTestHelper._perform_metric_assert( + "entity_available", + "1.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) assert "sensor.outside_temperature" in entity_registry.entities @@ -1088,41 +1092,45 @@ async def test_renaming_entity_id( assert 'entity="sensor.outside_temperature"' not in body_line # Check if new metrics created - assert ( - "sensor_temperature_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature_renamed",' - 'friendly_name="Outside Temperature"} 15.6' in body + MetricsTestHelper._perform_metric_assert( + "sensor_temperature_celsius", + "15.6", + "sensor", + "Outside Temperature", + "", + "outside_temperature_renamed", + body, ) - assert ( - "entity_available{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature_renamed",' - 'friendly_name="Outside Temperature"} 1.0' in body + MetricsTestHelper._perform_metric_assert( + "entity_available", + "1.0", + "sensor", + "Outside Temperature", + "", + "outside_temperature_renamed", + body, ) # Keep other sensors - assert ( - "sensor_humidity_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 54.0' in body + MetricsTestHelper._perform_metric_assert( + "sensor_humidity_percent", + "54.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) - assert ( - "entity_available{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 1.0' in body + MetricsTestHelper._perform_metric_assert( + "entity_available", + "1.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) @@ -1138,60 +1146,52 @@ async def test_deleting_entity( data = {**sensor_entities, **climate_entities} body = await generate_latest_metrics(client) - assert ( - "sensor_temperature_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 15.6' in body + MetricsTestHelper._perform_metric_assert( + "sensor_temperature_celsius", + "15.6", + "sensor", + "Outside Temperature", + "", + "outside_temperature", + body, ) - assert ( - "entity_available{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 1.0' in body + MetricsTestHelper._perform_metric_assert( + "entity_available", + "1.0", + "sensor", + "Outside Temperature", + "", + "outside_temperature", + body, ) - assert ( - "sensor_humidity_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 54.0' in body + MetricsTestHelper._perform_metric_assert( + "sensor_humidity_percent", + "54.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) - assert ( - "entity_available{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 1.0' in body + MetricsTestHelper._perform_metric_assert( + "entity_available", + "1.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) - assert ( - "climate_action{" - 'area="",' - 'device_class="temperature",' - 'action="heating",' - 'domain="climate",' - 'entity="climate.heatpump",' - 'friendly_name="HeatPump"} 1.0' in body + MetricsTestHelper._perform_climate_metric_assert( + "climate_action", "1.0", "HeatPump", "", "heatpump", body, action="heating" ) - assert ( - "climate_action{" - 'area="",' - 'device_class="temperature",' - 'action="cooling",' - 'domain="climate",' - 'entity="climate.heatpump",' - 'friendly_name="HeatPump"} 0.0' in body + MetricsTestHelper._perform_climate_metric_assert( + "climate_action", "0.0", "HeatPump", "", "heatpump", body, action="cooling" ) assert "sensor.outside_temperature" in entity_registry.entities @@ -1210,22 +1210,24 @@ async def test_deleting_entity( assert 'friendly_name="HeatPump"' not in body_line # Keep other sensors - assert ( - "sensor_humidity_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 54.0' in body + MetricsTestHelper._perform_metric_assert( + "sensor_humidity_percent", + "54.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) - assert ( - "entity_available{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 1.0' in body + MetricsTestHelper._perform_metric_assert( + "entity_available", + "1.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) @@ -1243,70 +1245,72 @@ async def test_disabling_entity( await hass.async_block_till_done() body = await generate_latest_metrics(client) - assert ( - "sensor_temperature_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 15.6' in body + MetricsTestHelper._perform_metric_assert( + "sensor_temperature_celsius", + "15.6", + "sensor", + "Outside Temperature", + "", + "outside_temperature", + body, ) - assert ( - "state_change_total{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 1.0' in body + MetricsTestHelper._perform_metric_assert( + "state_change_total", + "1.0", + "sensor", + "Outside Temperature", + "", + "outside_temperature", + body, ) - assert any( - "state_change_created{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"}' in metric - for metric in body - ) + # FIXME: redo this assertion + # MetricsTestHelper._perform_metric_assert( + # "state_change_created", + # "15.6", + # "sensor", + # "Outside Temperature", + # "", + # "outside_temperature", + # body, + # ) + # assert any( + # "state_change_created{" + # 'area="",' + # 'device_class="temperature",' + # 'domain="sensor",' + # 'entity="sensor.outside_temperature",' + # 'friendly_name="Outside Temperature"}' in metric + # for metric in body + # ) - assert ( - "sensor_humidity_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 54.0' in body + MetricsTestHelper._perform_metric_assert( + "sensor_humidity_percent", + "54.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) - assert ( - "entity_available{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 1.0' in body + MetricsTestHelper._perform_metric_assert( + "entity_available", + "1.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) - assert ( - "climate_action{" - 'area="",' - 'device_class="temperature",' - 'action="heating",' - 'domain="climate",' - 'entity="climate.heatpump",' - 'friendly_name="HeatPump"} 1.0' in body + MetricsTestHelper._perform_climate_metric_assert( + "climate_action", "1.0", "HeatPump", "", "heatpump", body, action="heating" ) - assert ( - "climate_action{" - 'area="",' - 'device_class="temperature",' - 'action="cooling",' - 'domain="climate",' - 'entity="climate.heatpump",' - 'friendly_name="HeatPump"} 0.0' in body + MetricsTestHelper._perform_climate_metric_assert( + "climate_action", "0.0", "HeatPump", "", "heatpump", body, action="cooling" ) assert "sensor.outside_temperature" in entity_registry.entities @@ -1331,22 +1335,24 @@ async def test_disabling_entity( assert 'friendly_name="HeatPump"' not in body_line # Keep other sensors - assert ( - "sensor_humidity_percent{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 54.0' in body + MetricsTestHelper._perform_metric_assert( + "sensor_humidity_percent", + "54.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) - assert ( - "entity_available{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 1.0' in body + MetricsTestHelper._perform_metric_assert( + "entity_available", + "1.0", + "sensor", + "Outside Humidity", + "", + "outside_humidity", + body, ) From 047f3958977afa9299af37cd8cc571306ef8d0bc Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 00:50:50 -0700 Subject: [PATCH 14/62] Only 1.5 tests left --- tests/components/prometheus/test_init.py | 192 ++++++++++++++++------- 1 file changed, 135 insertions(+), 57 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index c01b0da5926132..9a759369d4e892 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -180,6 +180,32 @@ def _perform_climate_metric_assert( # area=area, # ) + @classmethod + def _perform_cover_metric_assert( + cls, + metric_name, + metric_value, + friendly_name, + device_class, + object_id, + body, + area=None, + state=None, + ): + domain = "cover" + state_label_line = f',state="{state}"' if state else "" + assert ( + f"{metric_name}{{" + f'area="{area or ""}",' + # f'device_class="{device_class}",' + f'domain="{domain}",' + f'entity="{domain}.{object_id}",' + f'friendly_name="{friendly_name}",' + f'object_id="{object_id}"' + f'{state_label_line}' + f"}} {metric_value}" in body + ) + @classmethod def _perform_switch_metric_assert( cls, @@ -750,73 +776,125 @@ async def test_cover( open_covers = ["cover_open", "cover_position", "cover_tilt_position"] for testcover in data: - open_metric = ( - f"cover_state{{" - 'area="",' - 'device_class="temperature",' - f'domain="cover",' - f'entity="{cover_entities[testcover].entity_id}",' - f'friendly_name="{cover_entities[testcover].original_name}",' - f'state="open"}} {1.0 if cover_entities[testcover].unique_id in open_covers else 0.0}' + MetricsTestHelper._perform_cover_metric_assert( + "cover_state", + f"{1.0 if cover_entities[testcover].unique_id in open_covers else 0.0}", + f"{cover_entities[testcover].original_name}", + "", + f"{cover_entities[testcover].entity_id}", + body, + state="open", ) - assert open_metric in body - - closed_metric = ( - f'cover_state{{' - 'area="",' - 'device_class="temperature",' - f'domain="cover",' - f'entity="{cover_entities[testcover].entity_id}",' - f'friendly_name="{cover_entities[testcover].original_name}",' - f'state="closed"}} {1.0 if cover_entities[testcover].unique_id == "cover_closed" else 0.0}' + # open_metric = ( + # f"cover_state{{" + # 'area="",' + # 'device_class="temperature",' + # f'domain="cover",' + # f'entity="{cover_entities[testcover].entity_id}",' + # f'friendly_name="{cover_entities[testcover].original_name}",' + # f'state="open"}} {1.0 if cover_entities[testcover].unique_id in open_covers else 0.0}' + # ) + # assert open_metric in body + + MetricsTestHelper._perform_cover_metric_assert( + "cover_state", + 1.0 if cover_entities[testcover].unique_id == "cover_closed" else 0.0, + cover_entities[testcover].original_name, + "", + cover_entities[testcover].entity_id, + body, + state="closed", ) - assert closed_metric in body - - opening_metric = ( - f'cover_state{{' - 'area="",' - 'device_class="temperature",' - f'domain="cover",' - f'entity="{cover_entities[testcover].entity_id}",' - f'friendly_name="{cover_entities[testcover].original_name}",' - f'state="opening"}} {1.0 if cover_entities[testcover].unique_id == "cover_opening" else 0.0}' + # closed_metric = ( + # f'cover_state{{' + # 'area="",' + # 'device_class="temperature",' + # f'domain="cover",' + # f'entity="{cover_entities[testcover].entity_id}",' + # f'friendly_name="{cover_entities[testcover].original_name}",' + # f'state="closed"}} {1.0 if cover_entities[testcover].unique_id == "cover_closed" else 0.0}' + # ) + # assert closed_metric in body + + MetricsTestHelper._perform_cover_metric_assert( + "cover_state", + 1.0 if cover_entities[testcover].unique_id == "cover_opening" else 0.0, + cover_entities[testcover].original_name, + "", + cover_entities[testcover].entity_id, + body, + state="opening", ) - assert opening_metric in body - - closing_metric = ( - f'cover_state{{' - 'area="",' - 'device_class="temperature",' - f'domain="cover",' - f'entity="{cover_entities[testcover].entity_id}",' - f'friendly_name="{cover_entities[testcover].original_name}",' - f'state="closing"}} {1.0 if cover_entities[testcover].unique_id == "cover_closing" else 0.0}' + # opening_metric = ( + # f'cover_state{{' + # 'area="",' + # 'device_class="temperature",' + # f'domain="cover",' + # f'entity="{cover_entities[testcover].entity_id}",' + # f'friendly_name="{cover_entities[testcover].original_name}",' + # f'state="opening"}} {1.0 if cover_entities[testcover].unique_id == "cover_opening" else 0.0}' + # ) + # assert opening_metric in body + + MetricsTestHelper._perform_cover_metric_assert( + "cover_state", + 1.0 if cover_entities[testcover].unique_id == "cover_closing" else 0.0, + cover_entities[testcover].original_name, + "", + cover_entities[testcover].entity_id, + body, + state="closing", ) - assert closing_metric in body + # closing_metric = ( + # f'cover_state{{' + # 'area="",' + # 'device_class="temperature",' + # f'domain="cover",' + # f'entity="{cover_entities[testcover].entity_id}",' + # f'friendly_name="{cover_entities[testcover].original_name}",' + # f'state="closing"}} {1.0 if cover_entities[testcover].unique_id == "cover_closing" else 0.0}' + # ) + # assert closing_metric in body if testcover == "cover_position": - position_metric = ( - f"cover_position{{" - 'area="",' - 'device_class="temperature",' - f'domain="cover",' - f'entity="{cover_entities[testcover].entity_id}",' - f'friendly_name="{cover_entities[testcover].original_name}"' - f"}} 50.0" + MetricsTestHelper._perform_cover_metric_assert( + "cover_position", + "50.0", + cover_entities[testcover].original_name, + "", + cover_entities[testcover].entity_id, + body, ) - assert position_metric in body + # position_metric = ( + # f"cover_position{{" + # 'area="",' + # 'device_class="temperature",' + # f'domain="cover",' + # f'entity="{cover_entities[testcover].entity_id}",' + # f'friendly_name="{cover_entities[testcover].original_name}"' + # f"}} 50.0" + # ) + # assert position_metric in body if testcover == "cover_tilt_position": - tilt_position_metric = ( - f"cover_tilt_position{{" - 'area="",' - 'device_class="temperature",' - f'domain="cover",' - f'entity="{cover_entities[testcover].entity_id}",' - f'friendly_name="{cover_entities[testcover].original_name}"' - f"}} 50.0" + MetricsTestHelper._perform_cover_metric_assert( + "cover_tilt_position", + "50.0", + cover_entities[testcover].original_name, + "", + cover_entities[testcover].entity_id, + body, ) - assert tilt_position_metric in body + # tilt_position_metric = ( + # f"cover_tilt_position{{" + # 'area="",' + # 'device_class="temperature",' + # f'domain="cover",' + # f'entity="{cover_entities[testcover].entity_id}",' + # f'friendly_name="{cover_entities[testcover].original_name}"' + # f"}} 50.0" + # ) + # assert tilt_position_metric in body @pytest.mark.parametrize("namespace", [""]) From f56ffcce7d3f7c0da641121838e66d03763220ca Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 01:02:39 -0700 Subject: [PATCH 15/62] That's more than enough for tonight --- tests/components/prometheus/test_init.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 9a759369d4e892..cf5fa118eefa1b 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -776,12 +776,16 @@ async def test_cover( open_covers = ["cover_open", "cover_position", "cover_tilt_position"] for testcover in data: + # print(testcover) MetricsTestHelper._perform_cover_metric_assert( "cover_state", - f"{1.0 if cover_entities[testcover].unique_id in open_covers else 0.0}", - f"{cover_entities[testcover].original_name}", + 1.0 if cover_entities[testcover].unique_id in open_covers else 0.0, + # f"{1.0 if cover_entities[testcover].unique_id in open_covers else 0.0}", + # f"{cover_entities[testcover].original_name}", + cover_entities[testcover].original_name, "", - f"{cover_entities[testcover].entity_id}", + # f"{cover_entities[testcover].unique_id}", + cover_entities[testcover].unique_id, body, state="open", ) From a2625ef1276498089ddbe1e0fb12345f04dd9dbe Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 11:41:14 -0700 Subject: [PATCH 16/62] Got all the tests passing! --- tests/components/prometheus/test_init.py | 81 +++--------------------- 1 file changed, 9 insertions(+), 72 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index cf5fa118eefa1b..23b797eac9169d 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -185,21 +185,22 @@ def _perform_cover_metric_assert( cls, metric_name, metric_value, + entity_id, friendly_name, device_class, - object_id, body, area=None, state=None, ): domain = "cover" + object_id = entity_id.replace(f"{domain}.", "") state_label_line = f',state="{state}"' if state else "" assert ( f"{metric_name}{{" f'area="{area or ""}",' # f'device_class="{device_class}",' f'domain="{domain}",' - f'entity="{domain}.{object_id}",' + f'entity="{entity_id}",' f'friendly_name="{friendly_name}",' f'object_id="{object_id}"' f'{state_label_line}' @@ -776,129 +777,65 @@ async def test_cover( open_covers = ["cover_open", "cover_position", "cover_tilt_position"] for testcover in data: - # print(testcover) MetricsTestHelper._perform_cover_metric_assert( "cover_state", 1.0 if cover_entities[testcover].unique_id in open_covers else 0.0, - # f"{1.0 if cover_entities[testcover].unique_id in open_covers else 0.0}", - # f"{cover_entities[testcover].original_name}", + cover_entities[testcover].entity_id, cover_entities[testcover].original_name, "", - # f"{cover_entities[testcover].unique_id}", - cover_entities[testcover].unique_id, body, state="open", ) - # open_metric = ( - # f"cover_state{{" - # 'area="",' - # 'device_class="temperature",' - # f'domain="cover",' - # f'entity="{cover_entities[testcover].entity_id}",' - # f'friendly_name="{cover_entities[testcover].original_name}",' - # f'state="open"}} {1.0 if cover_entities[testcover].unique_id in open_covers else 0.0}' - # ) - # assert open_metric in body MetricsTestHelper._perform_cover_metric_assert( "cover_state", 1.0 if cover_entities[testcover].unique_id == "cover_closed" else 0.0, + cover_entities[testcover].entity_id, cover_entities[testcover].original_name, "", - cover_entities[testcover].entity_id, body, state="closed", ) - # closed_metric = ( - # f'cover_state{{' - # 'area="",' - # 'device_class="temperature",' - # f'domain="cover",' - # f'entity="{cover_entities[testcover].entity_id}",' - # f'friendly_name="{cover_entities[testcover].original_name}",' - # f'state="closed"}} {1.0 if cover_entities[testcover].unique_id == "cover_closed" else 0.0}' - # ) - # assert closed_metric in body MetricsTestHelper._perform_cover_metric_assert( "cover_state", 1.0 if cover_entities[testcover].unique_id == "cover_opening" else 0.0, + cover_entities[testcover].entity_id, cover_entities[testcover].original_name, "", - cover_entities[testcover].entity_id, body, state="opening", ) - # opening_metric = ( - # f'cover_state{{' - # 'area="",' - # 'device_class="temperature",' - # f'domain="cover",' - # f'entity="{cover_entities[testcover].entity_id}",' - # f'friendly_name="{cover_entities[testcover].original_name}",' - # f'state="opening"}} {1.0 if cover_entities[testcover].unique_id == "cover_opening" else 0.0}' - # ) - # assert opening_metric in body MetricsTestHelper._perform_cover_metric_assert( "cover_state", 1.0 if cover_entities[testcover].unique_id == "cover_closing" else 0.0, + cover_entities[testcover].entity_id, cover_entities[testcover].original_name, "", - cover_entities[testcover].entity_id, body, state="closing", ) - # closing_metric = ( - # f'cover_state{{' - # 'area="",' - # 'device_class="temperature",' - # f'domain="cover",' - # f'entity="{cover_entities[testcover].entity_id}",' - # f'friendly_name="{cover_entities[testcover].original_name}",' - # f'state="closing"}} {1.0 if cover_entities[testcover].unique_id == "cover_closing" else 0.0}' - # ) - # assert closing_metric in body if testcover == "cover_position": MetricsTestHelper._perform_cover_metric_assert( "cover_position", "50.0", + cover_entities[testcover].entity_id, cover_entities[testcover].original_name, "", - cover_entities[testcover].entity_id, body, ) - # position_metric = ( - # f"cover_position{{" - # 'area="",' - # 'device_class="temperature",' - # f'domain="cover",' - # f'entity="{cover_entities[testcover].entity_id}",' - # f'friendly_name="{cover_entities[testcover].original_name}"' - # f"}} 50.0" - # ) - # assert position_metric in body if testcover == "cover_tilt_position": MetricsTestHelper._perform_cover_metric_assert( "cover_tilt_position", "50.0", + cover_entities[testcover].entity_id, cover_entities[testcover].original_name, "", - cover_entities[testcover].entity_id, body, ) - # tilt_position_metric = ( - # f"cover_tilt_position{{" - # 'area="",' - # 'device_class="temperature",' - # f'domain="cover",' - # f'entity="{cover_entities[testcover].entity_id}",' - # f'friendly_name="{cover_entities[testcover].original_name}"' - # f"}} 50.0" - # ) - # assert tilt_position_metric in body @pytest.mark.parametrize("namespace", [""]) From 97186c494ca7b38c9ed7f04fdddee330be0f1dc1 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 11:46:36 -0700 Subject: [PATCH 17/62] Another pass at test clean up --- tests/components/prometheus/test_init.py | 127 ++++------------------- 1 file changed, 23 insertions(+), 104 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 23b797eac9169d..80601058ae120f 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -109,16 +109,6 @@ def _perform_metric_assert( assert full_metric_string in body else: assert full_metric_string not in body - # assert ( - # f"{metric_name}{{" - # f'area="{area or ""}",' - # # f'device_class="{device_class}",' - # f'domain="{domain}",' - # f'entity="{domain}.{object_id}",' - # f'friendly_name="{friendly_name}",' - # f'object_id="{object_id}"' - # f"}} {metric_value}" in body - # ) @classmethod def _perform_sensor_metric_assert( @@ -169,16 +159,6 @@ def _perform_climate_metric_assert( f'object_id="{object_id}"' f"}} {metric_value}" in body ) - # cls._perform_metric_assert( - # metric_name, - # metric_value, - # "climate", - # friendly_name, - # device_class, - # object_id, - # body, - # area=area, - # ) @classmethod def _perform_cover_metric_assert( @@ -207,28 +187,6 @@ def _perform_cover_metric_assert( f"}} {metric_value}" in body ) - @classmethod - def _perform_switch_metric_assert( - cls, - metric_name, - metric_value, - friendly_name, - device_class, - object_id, - body, - area=None, - ): - cls._perform_metric_assert( - metric_name, - metric_value, - "switch", - friendly_name, - device_class, - object_id, - body, - area=area, - ) - @classmethod def _perform_humidifier_metric_assert( cls, @@ -255,50 +213,6 @@ def _perform_humidifier_metric_assert( f"}} {metric_value}" in body ) - @classmethod - def _perform_number_metric_assert( - cls, - metric_name, - metric_value, - friendly_name, - device_class, - object_id, - body, - area=None, - ): - cls._perform_metric_assert( - metric_name, - metric_value, - "number", - friendly_name, - device_class, - object_id, - body, - area=area, - ) - - @classmethod - def _perform_input_number_metric_assert( - cls, - metric_name, - metric_value, - friendly_name, - device_class, - object_id, - body, - area=None, - ): - cls._perform_metric_assert( - metric_name, - metric_value, - "input_number", - friendly_name, - device_class, - object_id, - body, - area=area, - ) - @classmethod def _perform_temperature_metric_assert( cls, metric_value, friendly_name, object_id, body, area=None @@ -543,18 +457,20 @@ async def test_input_number( ) -> None: """Test prometheus metrics for input_number.""" body = await generate_latest_metrics(client) + domain = "input_number" - MetricsTestHelper._perform_input_number_metric_assert( - "input_number_state", "5.2", "Threshold", "", "threshold", body + MetricsTestHelper._perform_metric_assert( + "input_number_state", "5.2", domain, "Threshold", "", "threshold", body ) - MetricsTestHelper._perform_input_number_metric_assert( - "input_number_state", "60.0", "None", "", "brightness", body + MetricsTestHelper._perform_metric_assert( + "input_number_state", "60.0", domain, "None", "", "brightness", body ) - MetricsTestHelper._perform_input_number_metric_assert( + MetricsTestHelper._perform_metric_assert( "input_number_state_celsius", "22.7", + domain, "Target temperature", "", "target_temperature", @@ -568,18 +484,20 @@ async def test_number( ) -> None: """Test prometheus metrics for number.""" body = await generate_latest_metrics(client) + domain = "number" - MetricsTestHelper._perform_number_metric_assert( - "number_state", "5.2", "Threshold", "", "threshold", body + MetricsTestHelper._perform_metric_assert( + "number_state", "5.2", domain, "Threshold", "", "threshold", body ) - MetricsTestHelper._perform_number_metric_assert( - "number_state", "60.0", "None", "", "brightness", body + MetricsTestHelper._perform_metric_assert( + "number_state", "60.0", domain, "None", "", "brightness", body ) - MetricsTestHelper._perform_number_metric_assert( + MetricsTestHelper._perform_metric_assert( "number_state_celsius", "22.7", + domain, "Target temperature", "", "target_temperature", @@ -669,21 +587,22 @@ async def test_attributes( ) -> None: """Test prometheus metrics for entity attributes.""" body = await generate_latest_metrics(client) + domain = "switch" - MetricsTestHelper._perform_switch_metric_assert( - "switch_state", "1.0", "Boolean", "", "boolean", body + MetricsTestHelper._perform_metric_assert( + "switch_state", "1.0", domain, "Boolean", "", "boolean", body ) - MetricsTestHelper._perform_switch_metric_assert( - "switch_attr_boolean", "1.0", "Boolean", "", "boolean", body + MetricsTestHelper._perform_metric_assert( + "switch_attr_boolean", "1.0", domain, "Boolean", "", "boolean", body ) - MetricsTestHelper._perform_switch_metric_assert( - "switch_state", "0.0", "Number", "", "number", body + MetricsTestHelper._perform_metric_assert( + "switch_state", "0.0", domain, "Number", "", "number", body ) - MetricsTestHelper._perform_switch_metric_assert( - "switch_attr_number", "10.2", "Number", "", "number", body + MetricsTestHelper._perform_metric_assert( + "switch_attr_number", "10.2", domain, "Number", "", "number", body ) From 5bf7af500ceaf6f96056cf3e59d3a89c69b2da17 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 12:42:37 -0700 Subject: [PATCH 18/62] Fixed up all the tests, again --- tests/components/prometheus/test_init.py | 205 +++++++++-------------- 1 file changed, 77 insertions(+), 128 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 80601058ae120f..60e3c1c30461bf 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -82,6 +82,10 @@ class FilterTest: class MetricsTestHelper: """Helps with formatting prometheus metrics and future-proof label changes.""" + @classmethod + def _get_device_class_label_line(cls, device_class): + return f'device_class="{device_class}",' if device_class else "" + @classmethod def _perform_metric_assert( cls, @@ -89,16 +93,17 @@ def _perform_metric_assert( metric_value, domain, friendly_name, - device_class, object_id, body, area=None, + device_class=None, positive_comparison=True, ): + device_class_label_line = cls.get_device_class_label_line(device_class) full_metric_string = ( f"{metric_name}{{" f'area="{area or ""}",' - # f'device_class="{device_class}",' + f"{device_class_label_line}" f'domain="{domain}",' f'entity="{domain}.{object_id}",' f'friendly_name="{friendly_name}",' @@ -116,10 +121,10 @@ def _perform_sensor_metric_assert( metric_name, metric_value, friendly_name, - device_class, object_id, body, area=None, + device_class=None, positive_comparison=True, ): cls._perform_metric_assert( @@ -127,10 +132,10 @@ def _perform_sensor_metric_assert( metric_value, "sensor", friendly_name, - device_class, object_id, body, area=area, + device_class=device_class, positive_comparison=positive_comparison, ) @@ -140,19 +145,20 @@ def _perform_climate_metric_assert( metric_name, metric_value, friendly_name, - device_class, object_id, body, area=None, + device_class=None, action=None, ): domain = "climate" + device_class_label_line = cls.get_device_class_label_line(device_class) action_label_line = f'action="{action}",' if action else "" assert ( f"{metric_name}{{" f'{action_label_line}' f'area="{area or ""}",' - # f'device_class="{device_class}",' + f"{device_class_label_line}" f'domain="{domain}",' f'entity="{domain}.{object_id}",' f'friendly_name="{friendly_name}",' @@ -167,18 +173,19 @@ def _perform_cover_metric_assert( metric_value, entity_id, friendly_name, - device_class, body, area=None, + device_class=None, state=None, ): domain = "cover" + device_class_label_line = cls.get_device_class_label_line(device_class) object_id = entity_id.replace(f"{domain}.", "") state_label_line = f',state="{state}"' if state else "" assert ( f"{metric_name}{{" f'area="{area or ""}",' - # f'device_class="{device_class}",' + f"{device_class_label_line}" f'domain="{domain}",' f'entity="{entity_id}",' f'friendly_name="{friendly_name}",' @@ -193,18 +200,19 @@ def _perform_humidifier_metric_assert( metric_name, metric_value, friendly_name, - device_class, object_id, body, area=None, + device_class=None, mode=None, ): domain = "humidifier" + device_class_label_line = cls.get_device_class_label_line(device_class) mode_label_line = f'mode="{mode}",' if mode else "" assert ( f"{metric_name}{{" f'area="{area or ""}",' - # f'device_class="{device_class}",' + f"{device_class_label_line}" f'domain="{domain}",' f'entity="{domain}.{object_id}",' f'friendly_name="{friendly_name}",' @@ -213,30 +221,6 @@ def _perform_humidifier_metric_assert( f"}} {metric_value}" in body ) - @classmethod - def _perform_temperature_metric_assert( - cls, metric_value, friendly_name, object_id, body, area=None - ): - cls._perform_sensor_metric_assert( - "homeassistant_sensor_temperature_celsius", - metric_value, - friendly_name, - "temperature", - object_id, - body, - area=area, - ) - - @classmethod - def _perform_default_temperature_metric_assert(cls, metric_value, body, area=None): - cls._perform_temperature_metric_assert( - metric_value, - "Outside Temperature", - "outside_temperature", - body, - area=area, - ) - @pytest.fixture(name="client") async def setup_prometheus_client( @@ -302,7 +286,13 @@ async def test_setup_enumeration( client = await hass_client() body = await generate_latest_metrics(client) - MetricsTestHelper._perform_default_temperature_metric_assert(state, body) + MetricsTestHelper._perform_sensor_metric_assert( + "homeassistant_sensor_temperature_celsius", + "12.3", + "Outside Temperature", + "outside_temperature", + body, + ) @pytest.mark.parametrize("namespace", [""]) @@ -319,14 +309,13 @@ async def test_view_empty_namespace( ) MetricsTestHelper._perform_sensor_metric_assert( - "entity_available", "1.0", "Radio Energy", "temperature", "radio_energy", body + "entity_available", "1.0", "Radio Energy", "radio_energy", body ) MetricsTestHelper._perform_sensor_metric_assert( "last_updated_time_seconds", "86400.0", "Radio Energy", - "temperature", "radio_energy", body, ) @@ -345,7 +334,13 @@ async def test_view_default_namespace( "Objects collected during gc" in body ) - MetricsTestHelper._perform_default_temperature_metric_assert("15.6", body) + MetricsTestHelper._perform_sensor_metric_assert( + "homeassistant_sensor_temperature_celsius", + "15.6", + "Outside Temperature", + "outside_temperature", + body, + ) @pytest.mark.parametrize("namespace", [""]) @@ -356,27 +351,25 @@ async def test_sensor_unit( body = await generate_latest_metrics(client) MetricsTestHelper._perform_sensor_metric_assert( - "sensor_unit_kwh", "74.0", "Television Energy", "", "television_energy", body + "sensor_unit_kwh", "74.0", "Television Energy", "television_energy", body ) MetricsTestHelper._perform_sensor_metric_assert( "sensor_unit_sek_per_kwh", "0.123", "Electricity price", - "", "electricity_price", body, ) MetricsTestHelper._perform_sensor_metric_assert( - "sensor_unit_u0xb0", "25.0", "Wind Direction", "", "wind_direction", body + "sensor_unit_u0xb0", "25.0", "Wind Direction", "wind_direction", body ) MetricsTestHelper._perform_sensor_metric_assert( "sensor_unit_u0xb5g_per_mu0xb3", "3.7069", "SPS30 PM <1µm Weight concentration", - "", "sps30_pm_1um_weight_concentration", body, ) @@ -390,18 +383,17 @@ async def test_sensor_without_unit( body = await generate_latest_metrics(client) MetricsTestHelper._perform_sensor_metric_assert( - "sensor_state", "0.002", "Trend Gradient", "", "trend_gradient", body + "sensor_state", "0.002", "Trend Gradient", "trend_gradient", body ) MetricsTestHelper._perform_sensor_metric_assert( - "sensor_state", "0", "Text", "", "text", body, positive_comparison=False + "sensor_state", "0", "Text", "text", body, positive_comparison=False ) MetricsTestHelper._perform_sensor_metric_assert( "sensor_unit_text", "0", "Text Unit", - "", "text_unit", body, positive_comparison=False, @@ -416,14 +408,13 @@ async def test_sensor_device_class( body = await generate_latest_metrics(client) MetricsTestHelper._perform_sensor_metric_assert( - "sensor_temperature_celsius", "10.0", "Fahrenheit", "", "fahrenheit", body + "sensor_temperature_celsius", "10.0", "Fahrenheit", "fahrenheit", body ) MetricsTestHelper._perform_sensor_metric_assert( "sensor_temperature_celsius", "15.6", "Outside Temperature", - "", "outside_temperature", body, ) @@ -432,20 +423,18 @@ async def test_sensor_device_class( "sensor_humidity_percent", "54.0", "Outside Humidity", - "", "outside_humidity", body, ) MetricsTestHelper._perform_sensor_metric_assert( - "sensor_power_kwh", "14.0", "Radio Energy", "", "radio_energy", body + "sensor_power_kwh", "14.0", "Radio Energy", "radio_energy", body ) MetricsTestHelper._perform_sensor_metric_assert( "sensor_timestamp_seconds", "1.691445808136036e+09", "Timestamp", - "", "timestamp", body, ) @@ -460,11 +449,11 @@ async def test_input_number( domain = "input_number" MetricsTestHelper._perform_metric_assert( - "input_number_state", "5.2", domain, "Threshold", "", "threshold", body + "input_number_state", "5.2", domain, "Threshold", "threshold", body ) MetricsTestHelper._perform_metric_assert( - "input_number_state", "60.0", domain, "None", "", "brightness", body + "input_number_state", "60.0", domain, "None", "brightness", body ) MetricsTestHelper._perform_metric_assert( @@ -472,7 +461,6 @@ async def test_input_number( "22.7", domain, "Target temperature", - "", "target_temperature", body, ) @@ -487,11 +475,11 @@ async def test_number( domain = "number" MetricsTestHelper._perform_metric_assert( - "number_state", "5.2", domain, "Threshold", "", "threshold", body + "number_state", "5.2", domain, "Threshold", "threshold", body ) MetricsTestHelper._perform_metric_assert( - "number_state", "60.0", domain, "None", "", "brightness", body + "number_state", "60.0", domain, "None", "brightness", body ) MetricsTestHelper._perform_metric_assert( @@ -499,7 +487,6 @@ async def test_number( "22.7", domain, "Target temperature", - "", "target_temperature", body, ) @@ -516,7 +503,6 @@ async def test_battery( "battery_level_percent", "12.0", "Outside Temperature", - "", "outside_temperature", body, ) @@ -531,23 +517,23 @@ async def test_climate( body = await generate_latest_metrics(client) MetricsTestHelper._perform_climate_metric_assert( - "climate_current_temperature_celsius", "25.0", "HeatPump", "", "heatpump", body + "climate_current_temperature_celsius", "25.0", "HeatPump", "heatpump", body ) MetricsTestHelper._perform_climate_metric_assert( - "climate_target_temperature_celsius", "20.0", "HeatPump", "", "heatpump", body + "climate_target_temperature_celsius", "20.0", "HeatPump", "heatpump", body ) MetricsTestHelper._perform_climate_metric_assert( - "climate_target_temperature_low_celsius", "21.0", "Ecobee", "", "ecobee", body + "climate_target_temperature_low_celsius", "21.0", "Ecobee", "ecobee", body ) MetricsTestHelper._perform_climate_metric_assert( - "climate_target_temperature_high_celsius", "24.0", "Ecobee", "", "ecobee", body + "climate_target_temperature_high_celsius", "24.0", "Ecobee", "ecobee", body ) MetricsTestHelper._perform_climate_metric_assert( - "climate_target_temperature_celsius", "0.0", "Fritz!DECT", "", "fritzdect", body + "climate_target_temperature_celsius", "0.0", "Fritz!DECT", "fritzdect", body ) @@ -563,20 +549,19 @@ async def test_humidifier( "humidifier_target_humidity_percent", "68.0", "Humidifier", - "", "humidifier", body, ) MetricsTestHelper._perform_humidifier_metric_assert( - "humidifier_state", "1.0", "Dehumidifier", "", "dehumidifier", body + "humidifier_state", "1.0", "Dehumidifier", "dehumidifier", body ) MetricsTestHelper._perform_humidifier_metric_assert( - "humidifier_mode", "1.0", "Hygrostat", "", "hygrostat", body, mode="home" + "humidifier_mode", "1.0", "Hygrostat", "hygrostat", body, mode="home" ) MetricsTestHelper._perform_humidifier_metric_assert( - "humidifier_mode", "0.0", "Hygrostat", "", "hygrostat", body, mode="eco" + "humidifier_mode", "0.0", "Hygrostat", "hygrostat", body, mode="eco" ) @@ -590,19 +575,19 @@ async def test_attributes( domain = "switch" MetricsTestHelper._perform_metric_assert( - "switch_state", "1.0", domain, "Boolean", "", "boolean", body + "switch_state", "1.0", domain, "Boolean", "boolean", body ) MetricsTestHelper._perform_metric_assert( - "switch_attr_boolean", "1.0", domain, "Boolean", "", "boolean", body + "switch_attr_boolean", "1.0", domain, "Boolean", "boolean", body ) MetricsTestHelper._perform_metric_assert( - "switch_state", "0.0", domain, "Number", "", "number", body + "switch_state", "0.0", domain, "Number", "number", body ) MetricsTestHelper._perform_metric_assert( - "switch_attr_number", "10.2", domain, "Number", "", "number", body + "switch_attr_number", "10.2", domain, "Number", "number", body ) @@ -615,11 +600,11 @@ async def test_binary_sensor( domain = "binary_sensor" MetricsTestHelper._perform_metric_assert( - "binary_sensor_state", "1.0", domain, "Door", "", "door", body + "binary_sensor_state", "1.0", domain, "Door", "door", body ) MetricsTestHelper._perform_metric_assert( - "binary_sensor_state", "0.0", domain, "Window", "", "window", body + "binary_sensor_state", "0.0", domain, "Window", "window", body ) @@ -632,11 +617,11 @@ async def test_input_boolean( domain = "input_boolean" MetricsTestHelper._perform_metric_assert( - "input_boolean_state", "1.0", domain, "Test", "", "test", body + "input_boolean_state", "1.0", domain, "Test", "test", body ) MetricsTestHelper._perform_metric_assert( - "input_boolean_state", "0.0", domain, "Helper", "", "helper", body + "input_boolean_state", "0.0", domain, "Helper", "helper", body ) @@ -649,23 +634,23 @@ async def test_light( domain = "light" MetricsTestHelper._perform_metric_assert( - "light_brightness_percent", "100.0", domain, "Desk", "", "desk", body + "light_brightness_percent", "100.0", domain, "Desk", "desk", body ) MetricsTestHelper._perform_metric_assert( - "light_brightness_percent", "0.0", domain, "Wall", "", "wall", body + "light_brightness_percent", "0.0", domain, "Wall", "wall", body ) MetricsTestHelper._perform_metric_assert( - "light_brightness_percent", "100.0", domain, "TV", "", "tv", body + "light_brightness_percent", "100.0", domain, "TV", "tv", body ) MetricsTestHelper._perform_metric_assert( - "light_brightness_percent", "70.58823529411765", domain, "PC", "", "pc", body + "light_brightness_percent", "70.58823529411765", domain, "PC", "pc", body ) MetricsTestHelper._perform_metric_assert( - "light_brightness_percent", "100.0", domain, "Hallway", "", "hallway", body + "light_brightness_percent", "100.0", domain, "Hallway", "hallway", body ) @@ -678,11 +663,11 @@ async def test_lock( domain = "lock" MetricsTestHelper._perform_metric_assert( - "lock_state", "1.0", domain, "Front Door", "", "front_door", body + "lock_state", "1.0", domain, "Front Door", "front_door", body ) MetricsTestHelper._perform_metric_assert( - "lock_state", "0.0", domain, "Kitchen Door", "", "kitchen_door", body + "lock_state", "0.0", domain, "Kitchen Door", "kitchen_door", body ) @@ -701,7 +686,6 @@ async def test_cover( 1.0 if cover_entities[testcover].unique_id in open_covers else 0.0, cover_entities[testcover].entity_id, cover_entities[testcover].original_name, - "", body, state="open", ) @@ -711,7 +695,6 @@ async def test_cover( 1.0 if cover_entities[testcover].unique_id == "cover_closed" else 0.0, cover_entities[testcover].entity_id, cover_entities[testcover].original_name, - "", body, state="closed", ) @@ -721,7 +704,6 @@ async def test_cover( 1.0 if cover_entities[testcover].unique_id == "cover_opening" else 0.0, cover_entities[testcover].entity_id, cover_entities[testcover].original_name, - "", body, state="opening", ) @@ -731,7 +713,6 @@ async def test_cover( 1.0 if cover_entities[testcover].unique_id == "cover_closing" else 0.0, cover_entities[testcover].entity_id, cover_entities[testcover].original_name, - "", body, state="closing", ) @@ -742,7 +723,6 @@ async def test_cover( "50.0", cover_entities[testcover].entity_id, cover_entities[testcover].original_name, - "", body, ) @@ -752,7 +732,6 @@ async def test_cover( "50.0", cover_entities[testcover].entity_id, cover_entities[testcover].original_name, - "", body, ) @@ -766,10 +745,10 @@ async def test_device_tracker( domain = "device_tracker" MetricsTestHelper._perform_metric_assert( - "device_tracker_state", "1.0", domain, "Phone", "", "phone", body + "device_tracker_state", "1.0", domain, "Phone", "phone", body ) MetricsTestHelper._perform_metric_assert( - "device_tracker_state", "0.0", domain, "Watch", "", "watch", body + "device_tracker_state", "0.0", domain, "Watch", "watch", body ) @@ -782,7 +761,7 @@ async def test_counter( domain = "counter" MetricsTestHelper._perform_metric_assert( - "counter_value", "2.0", domain, "None", "", "counter", body + "counter_value", "2.0", domain, "None", "counter", body ) @@ -795,10 +774,10 @@ async def test_update( domain = "update" MetricsTestHelper._perform_metric_assert( - "update_state", "1.0", domain, "Firmware", "", "firmware", body + "update_state", "1.0", domain, "Firmware", "firmware", body ) MetricsTestHelper._perform_metric_assert( - "update_state", "0.0", domain, "Addon", "", "addon", body + "update_state", "0.0", domain, "Addon", "addon", body ) @@ -819,7 +798,6 @@ async def test_renaming_entity_name( "15.6", "sensor", "Outside Temperature", - "", "outside_temperature", body, ) @@ -829,7 +807,6 @@ async def test_renaming_entity_name( "1.0", "sensor", "Outside Temperature", - "", "outside_temperature", body, ) @@ -839,7 +816,6 @@ async def test_renaming_entity_name( "54.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) @@ -849,17 +825,16 @@ async def test_renaming_entity_name( "1.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) MetricsTestHelper._perform_climate_metric_assert( - "climate_action", "1.0", "HeatPump", "", "heatpump", body, action="heating" + "climate_action", "1.0", "HeatPump", "heatpump", body, action="heating" ) MetricsTestHelper._perform_climate_metric_assert( - "climate_action", "0.0", "HeatPump", "", "heatpump", body, action="cooling" + "climate_action", "0.0", "HeatPump", "heatpump", body, action="cooling" ) assert "sensor.outside_temperature" in entity_registry.entities @@ -903,7 +878,6 @@ async def test_renaming_entity_name( "15.6", "sensor", "Outside Temperature Renamed", - "", "outside_temperature", body, ) @@ -913,7 +887,6 @@ async def test_renaming_entity_name( "1.0", "sensor", "Outside Temperature Renamed", - "", "outside_temperature", body, ) @@ -922,7 +895,6 @@ async def test_renaming_entity_name( "climate_action", "1.0", "HeatPump Renamed", - "", "heatpump", body, action="heating", @@ -932,7 +904,6 @@ async def test_renaming_entity_name( "climate_action", "0.0", "HeatPump Renamed", - "", "heatpump", body, action="cooling", @@ -944,7 +915,6 @@ async def test_renaming_entity_name( "54.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) @@ -954,7 +924,6 @@ async def test_renaming_entity_name( "1.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) @@ -977,7 +946,6 @@ async def test_renaming_entity_id( "15.6", "sensor", "Outside Temperature", - "", "outside_temperature", body, ) @@ -987,7 +955,6 @@ async def test_renaming_entity_id( "1.0", "sensor", "Outside Temperature", - "", "outside_temperature", body, ) @@ -997,7 +964,6 @@ async def test_renaming_entity_id( "54.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) @@ -1007,7 +973,6 @@ async def test_renaming_entity_id( "1.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) @@ -1035,7 +1000,6 @@ async def test_renaming_entity_id( "15.6", "sensor", "Outside Temperature", - "", "outside_temperature_renamed", body, ) @@ -1045,7 +1009,6 @@ async def test_renaming_entity_id( "1.0", "sensor", "Outside Temperature", - "", "outside_temperature_renamed", body, ) @@ -1056,7 +1019,6 @@ async def test_renaming_entity_id( "54.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) @@ -1066,7 +1028,6 @@ async def test_renaming_entity_id( "1.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) @@ -1089,7 +1050,6 @@ async def test_deleting_entity( "15.6", "sensor", "Outside Temperature", - "", "outside_temperature", body, ) @@ -1099,7 +1059,6 @@ async def test_deleting_entity( "1.0", "sensor", "Outside Temperature", - "", "outside_temperature", body, ) @@ -1109,7 +1068,6 @@ async def test_deleting_entity( "54.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) @@ -1119,17 +1077,16 @@ async def test_deleting_entity( "1.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) MetricsTestHelper._perform_climate_metric_assert( - "climate_action", "1.0", "HeatPump", "", "heatpump", body, action="heating" + "climate_action", "1.0", "HeatPump", "heatpump", body, action="heating" ) MetricsTestHelper._perform_climate_metric_assert( - "climate_action", "0.0", "HeatPump", "", "heatpump", body, action="cooling" + "climate_action", "0.0", "HeatPump", "heatpump", body, action="cooling" ) assert "sensor.outside_temperature" in entity_registry.entities @@ -1153,7 +1110,6 @@ async def test_deleting_entity( "54.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) @@ -1163,7 +1119,6 @@ async def test_deleting_entity( "1.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) @@ -1188,7 +1143,6 @@ async def test_disabling_entity( "15.6", "sensor", "Outside Temperature", - "", "outside_temperature", body, ) @@ -1198,7 +1152,6 @@ async def test_disabling_entity( "1.0", "sensor", "Outside Temperature", - "", "outside_temperature", body, ) @@ -1228,7 +1181,6 @@ async def test_disabling_entity( "54.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) @@ -1238,17 +1190,16 @@ async def test_disabling_entity( "1.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) MetricsTestHelper._perform_climate_metric_assert( - "climate_action", "1.0", "HeatPump", "", "heatpump", body, action="heating" + "climate_action", "1.0", "HeatPump", "heatpump", body, action="heating" ) MetricsTestHelper._perform_climate_metric_assert( - "climate_action", "0.0", "HeatPump", "", "heatpump", body, action="cooling" + "climate_action", "0.0", "HeatPump", "heatpump", body, action="cooling" ) assert "sensor.outside_temperature" in entity_registry.entities @@ -1278,7 +1229,6 @@ async def test_disabling_entity( "54.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) @@ -1288,7 +1238,6 @@ async def test_disabling_entity( "1.0", "sensor", "Outside Humidity", - "", "outside_humidity", body, ) From 57d30b2df3b0b94191ae555214f4c183bcedb1aa Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 12:43:24 -0700 Subject: [PATCH 19/62] More clean up needed --- tests/components/prometheus/test_init.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 60e3c1c30461bf..ae8b183d0d803f 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -99,7 +99,7 @@ def _perform_metric_assert( device_class=None, positive_comparison=True, ): - device_class_label_line = cls.get_device_class_label_line(device_class) + device_class_label_line = cls._get_device_class_label_line(device_class) full_metric_string = ( f"{metric_name}{{" f'area="{area or ""}",' @@ -152,7 +152,7 @@ def _perform_climate_metric_assert( action=None, ): domain = "climate" - device_class_label_line = cls.get_device_class_label_line(device_class) + device_class_label_line = cls._get_device_class_label_line(device_class) action_label_line = f'action="{action}",' if action else "" assert ( f"{metric_name}{{" @@ -179,7 +179,7 @@ def _perform_cover_metric_assert( state=None, ): domain = "cover" - device_class_label_line = cls.get_device_class_label_line(device_class) + device_class_label_line = cls._get_device_class_label_line(device_class) object_id = entity_id.replace(f"{domain}.", "") state_label_line = f',state="{state}"' if state else "" assert ( @@ -207,7 +207,7 @@ def _perform_humidifier_metric_assert( mode=None, ): domain = "humidifier" - device_class_label_line = cls.get_device_class_label_line(device_class) + device_class_label_line = cls._get_device_class_label_line(device_class) mode_label_line = f'mode="{mode}",' if mode else "" assert ( f"{metric_name}{{" From 641fd2ade26299fafaeff8a7dae502edb4b3f25e Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 13:08:45 -0700 Subject: [PATCH 20/62] Got device_class working just need to fix one test I broke --- .../components/prometheus/__init__.py | 4 +- tests/components/prometheus/test_init.py | 69 +++++++++++++++++-- 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/prometheus/__init__.py b/homeassistant/components/prometheus/__init__.py index 277b8a0f065674..3108c609d7fbc9 100644 --- a/homeassistant/components/prometheus/__init__.py +++ b/homeassistant/components/prometheus/__init__.py @@ -298,7 +298,7 @@ def _get_label_keys( "domain", "area", "object_id", - # "device_class", + "device_class", ] if extra_labels is not None: labels.extend(extra_labels) @@ -362,7 +362,7 @@ def _labels(state: State) -> dict[str, Any]: "friendly_name": state.attributes.get(ATTR_FRIENDLY_NAME), "area": state.attributes.get(ATTR_AREA_ID) or "", "object_id": state.object_id, - # "device_class": state.attributes.get(ATTR_DEVICE_CLASS) or "", + "device_class": state.attributes.get(ATTR_DEVICE_CLASS) or "", } def _battery(self, state: State) -> None: diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index ae8b183d0d803f..bce4d071903c5f 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -84,7 +84,9 @@ class MetricsTestHelper: @classmethod def _get_device_class_label_line(cls, device_class): - return f'device_class="{device_class}",' if device_class else "" + if device_class: + device_class = str(device_class) + return f'device_class="{device_class or ""}",' @classmethod def _perform_metric_assert( @@ -292,6 +294,7 @@ async def test_setup_enumeration( "Outside Temperature", "outside_temperature", body, + device_class=SensorDeviceClass.TEMPERATURE, ) @@ -309,7 +312,12 @@ async def test_view_empty_namespace( ) MetricsTestHelper._perform_sensor_metric_assert( - "entity_available", "1.0", "Radio Energy", "radio_energy", body + "entity_available", + "1.0", + "Radio Energy", + "radio_energy", + body, + device_class=SensorDeviceClass.POWER, ) MetricsTestHelper._perform_sensor_metric_assert( @@ -318,6 +326,7 @@ async def test_view_empty_namespace( "Radio Energy", "radio_energy", body, + device_class=SensorDeviceClass.POWER, ) @@ -340,6 +349,7 @@ async def test_view_default_namespace( "Outside Temperature", "outside_temperature", body, + device_class=SensorDeviceClass.TEMPERATURE, ) @@ -408,7 +418,12 @@ async def test_sensor_device_class( body = await generate_latest_metrics(client) MetricsTestHelper._perform_sensor_metric_assert( - "sensor_temperature_celsius", "10.0", "Fahrenheit", "fahrenheit", body + "sensor_temperature_celsius", + "10.0", + "Fahrenheit", + "fahrenheit", + body, + device_class=SensorDeviceClass.TEMPERATURE, ) MetricsTestHelper._perform_sensor_metric_assert( @@ -417,6 +432,7 @@ async def test_sensor_device_class( "Outside Temperature", "outside_temperature", body, + device_class=SensorDeviceClass.TEMPERATURE, ) MetricsTestHelper._perform_sensor_metric_assert( @@ -425,10 +441,16 @@ async def test_sensor_device_class( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) MetricsTestHelper._perform_sensor_metric_assert( - "sensor_power_kwh", "14.0", "Radio Energy", "radio_energy", body + "sensor_power_kwh", + "14.0", + "Radio Energy", + "radio_energy", + body, + device_class=SensorDeviceClass.POWER, ) MetricsTestHelper._perform_sensor_metric_assert( @@ -437,6 +459,7 @@ async def test_sensor_device_class( "Timestamp", "timestamp", body, + device_class=SensorDeviceClass.TIMESTAMP, ) @@ -505,6 +528,7 @@ async def test_battery( "Outside Temperature", "outside_temperature", body, + device_class=SensorDeviceClass.TEMPERATURE, ) @@ -551,10 +575,17 @@ async def test_humidifier( "Humidifier", "humidifier", body, + # TODO: where is this humidifier device_class? + device_class="humidifier", ) MetricsTestHelper._perform_humidifier_metric_assert( - "humidifier_state", "1.0", "Dehumidifier", "dehumidifier", body + "humidifier_state", + "1.0", + "Dehumidifier", + "dehumidifier", + body, + device_class="dehumidifier", ) MetricsTestHelper._perform_humidifier_metric_assert( @@ -800,6 +831,7 @@ async def test_renaming_entity_name( "Outside Temperature", "outside_temperature", body, + device_class=SensorDeviceClass.TEMPERATURE, ) MetricsTestHelper._perform_metric_assert( @@ -809,6 +841,7 @@ async def test_renaming_entity_name( "Outside Temperature", "outside_temperature", body, + device_class=SensorDeviceClass.TEMPERATURE, ) MetricsTestHelper._perform_metric_assert( @@ -818,6 +851,7 @@ async def test_renaming_entity_name( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) MetricsTestHelper._perform_metric_assert( @@ -827,6 +861,7 @@ async def test_renaming_entity_name( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) MetricsTestHelper._perform_climate_metric_assert( @@ -880,6 +915,7 @@ async def test_renaming_entity_name( "Outside Temperature Renamed", "outside_temperature", body, + device_class=SensorDeviceClass.TEMPERATURE, ) MetricsTestHelper._perform_metric_assert( @@ -889,6 +925,7 @@ async def test_renaming_entity_name( "Outside Temperature Renamed", "outside_temperature", body, + device_class=SensorDeviceClass.TEMPERATURE, ) MetricsTestHelper._perform_climate_metric_assert( @@ -917,6 +954,7 @@ async def test_renaming_entity_name( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) MetricsTestHelper._perform_metric_assert( @@ -926,6 +964,7 @@ async def test_renaming_entity_name( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) @@ -948,6 +987,7 @@ async def test_renaming_entity_id( "Outside Temperature", "outside_temperature", body, + device_class=SensorDeviceClass.TEMPERATURE, ) MetricsTestHelper._perform_metric_assert( @@ -957,6 +997,7 @@ async def test_renaming_entity_id( "Outside Temperature", "outside_temperature", body, + device_class=SensorDeviceClass.TEMPERATURE, ) MetricsTestHelper._perform_metric_assert( @@ -966,6 +1007,7 @@ async def test_renaming_entity_id( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) MetricsTestHelper._perform_metric_assert( @@ -975,6 +1017,7 @@ async def test_renaming_entity_id( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) assert "sensor.outside_temperature" in entity_registry.entities @@ -1002,6 +1045,7 @@ async def test_renaming_entity_id( "Outside Temperature", "outside_temperature_renamed", body, + device_class=SensorDeviceClass.TEMPERATURE, ) MetricsTestHelper._perform_metric_assert( @@ -1011,6 +1055,7 @@ async def test_renaming_entity_id( "Outside Temperature", "outside_temperature_renamed", body, + device_class=SensorDeviceClass.TEMPERATURE, ) # Keep other sensors @@ -1021,6 +1066,7 @@ async def test_renaming_entity_id( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) MetricsTestHelper._perform_metric_assert( @@ -1030,6 +1076,7 @@ async def test_renaming_entity_id( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) @@ -1052,6 +1099,7 @@ async def test_deleting_entity( "Outside Temperature", "outside_temperature", body, + device_class=SensorDeviceClass.TEMPERATURE, ) MetricsTestHelper._perform_metric_assert( @@ -1061,6 +1109,7 @@ async def test_deleting_entity( "Outside Temperature", "outside_temperature", body, + device_class=SensorDeviceClass.TEMPERATURE, ) MetricsTestHelper._perform_metric_assert( @@ -1070,6 +1119,7 @@ async def test_deleting_entity( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) MetricsTestHelper._perform_metric_assert( @@ -1079,6 +1129,7 @@ async def test_deleting_entity( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) MetricsTestHelper._perform_climate_metric_assert( @@ -1112,6 +1163,7 @@ async def test_deleting_entity( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) MetricsTestHelper._perform_metric_assert( @@ -1121,6 +1173,7 @@ async def test_deleting_entity( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) @@ -1145,6 +1198,7 @@ async def test_disabling_entity( "Outside Temperature", "outside_temperature", body, + device_class=SensorDeviceClass.TEMPERATURE, ) MetricsTestHelper._perform_metric_assert( @@ -1154,6 +1208,7 @@ async def test_disabling_entity( "Outside Temperature", "outside_temperature", body, + device_class=SensorDeviceClass.TEMPERATURE, ) # FIXME: redo this assertion @@ -1183,6 +1238,7 @@ async def test_disabling_entity( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) MetricsTestHelper._perform_metric_assert( @@ -1192,6 +1248,7 @@ async def test_disabling_entity( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) MetricsTestHelper._perform_climate_metric_assert( @@ -1231,6 +1288,7 @@ async def test_disabling_entity( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) MetricsTestHelper._perform_metric_assert( @@ -1240,6 +1298,7 @@ async def test_disabling_entity( "Outside Humidity", "outside_humidity", body, + device_class=SensorDeviceClass.HUMIDITY, ) From f8d65d2746909f869f8db3a1784b6818099844e0 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 13:23:39 -0700 Subject: [PATCH 21/62] Got all the existing tests working! --- tests/components/prometheus/test_init.py | 60 ++++++++++++++---------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index bce4d071903c5f..4554843ceb8ded 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -89,19 +89,18 @@ def _get_device_class_label_line(cls, device_class): return f'device_class="{device_class or ""}",' @classmethod - def _perform_metric_assert( + def _get_metric_string( cls, metric_name, - metric_value, domain, friendly_name, object_id, - body, + metric_value=None, area=None, device_class=None, - positive_comparison=True, ): device_class_label_line = cls._get_device_class_label_line(device_class) + final_metric_value = f" {metric_value}" if metric_value else "" full_metric_string = ( f"{metric_name}{{" f'area="{area or ""}",' @@ -110,7 +109,31 @@ def _perform_metric_assert( f'entity="{domain}.{object_id}",' f'friendly_name="{friendly_name}",' f'object_id="{object_id}"' - f"}} {metric_value}" + f"}}{final_metric_value}" + ) + return full_metric_string + + @classmethod + def _perform_metric_assert( + cls, + metric_name, + metric_value, + domain, + friendly_name, + object_id, + body, + area=None, + device_class=None, + positive_comparison=True, + ): + full_metric_string = cls._get_metric_string( + metric_name, + domain, + friendly_name, + object_id, + area=area, + device_class=device_class, + metric_value=metric_value, ) if positive_comparison: assert full_metric_string in body @@ -1211,25 +1234,14 @@ async def test_disabling_entity( device_class=SensorDeviceClass.TEMPERATURE, ) - # FIXME: redo this assertion - # MetricsTestHelper._perform_metric_assert( - # "state_change_created", - # "15.6", - # "sensor", - # "Outside Temperature", - # "", - # "outside_temperature", - # body, - # ) - # assert any( - # "state_change_created{" - # 'area="",' - # 'device_class="temperature",' - # 'domain="sensor",' - # 'entity="sensor.outside_temperature",' - # 'friendly_name="Outside Temperature"}' in metric - # for metric in body - # ) + state_change_metric_string = MetricsTestHelper._get_metric_string( + "state_change_created", + "sensor", + "Outside Temperature", + "outside_temperature", + device_class=SensorDeviceClass.TEMPERATURE, + ) + assert any(state_change_metric_string for metric in body) MetricsTestHelper._perform_metric_assert( "sensor_humidity_percent", From ce38cbaa415cae0bd2dab8aad55a3a9ba62dc6e6 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 13:36:55 -0700 Subject: [PATCH 22/62] Refactored helpers into a separate file --- tests/components/prometheus/helpers.py | 170 +++++++++++++++++++++++ tests/components/prometheus/test_init.py | 170 +---------------------- 2 files changed, 172 insertions(+), 168 deletions(-) create mode 100644 tests/components/prometheus/helpers.py diff --git a/tests/components/prometheus/helpers.py b/tests/components/prometheus/helpers.py new file mode 100644 index 00000000000000..14d146123bec17 --- /dev/null +++ b/tests/components/prometheus/helpers.py @@ -0,0 +1,170 @@ +"""Helper methods for prometheus tests.""" + + +class MetricsTestHelper: + """Helps with formatting prometheus metrics and future-proof label changes.""" + + @classmethod + def get_device_class_label_line(cls, device_class): + """Format the device_class label line (tries to account for enum class).""" + if device_class: + device_class = str(device_class) + return f'device_class="{device_class or ""}",' + + @classmethod + def _get_metric_string( + cls, + metric_name, + domain, + friendly_name, + object_id, + metric_value=None, + area=None, + device_class=None, + ): + device_class_label_line = cls.get_device_class_label_line(device_class) + final_metric_value = f" {metric_value}" if metric_value else "" + full_metric_string = ( + f"{metric_name}{{" + f'area="{area or ""}",' + f"{device_class_label_line}" + f'domain="{domain}",' + f'entity="{domain}.{object_id}",' + f'friendly_name="{friendly_name}",' + f'object_id="{object_id}"' + f"}}{final_metric_value}" + ) + return full_metric_string + + @classmethod + def _perform_metric_assert( + cls, + metric_name, + metric_value, + domain, + friendly_name, + object_id, + body, + area=None, + device_class=None, + positive_comparison=True, + ): + full_metric_string = cls._get_metric_string( + metric_name, + domain, + friendly_name, + object_id, + area=area, + device_class=device_class, + metric_value=metric_value, + ) + if positive_comparison: + assert full_metric_string in body + else: + assert full_metric_string not in body + + @classmethod + def _perform_sensor_metric_assert( + cls, + metric_name, + metric_value, + friendly_name, + object_id, + body, + area=None, + device_class=None, + positive_comparison=True, + ): + cls._perform_metric_assert( + metric_name, + metric_value, + "sensor", + friendly_name, + object_id, + body, + area=area, + device_class=device_class, + positive_comparison=positive_comparison, + ) + + @classmethod + def _perform_climate_metric_assert( + cls, + metric_name, + metric_value, + friendly_name, + object_id, + body, + area=None, + device_class=None, + action=None, + ): + domain = "climate" + device_class_label_line = cls.get_device_class_label_line(device_class) + action_label_line = f'action="{action}",' if action else "" + assert ( + f"{metric_name}{{" + f'{action_label_line}' + f'area="{area or ""}",' + f"{device_class_label_line}" + f'domain="{domain}",' + f'entity="{domain}.{object_id}",' + f'friendly_name="{friendly_name}",' + f'object_id="{object_id}"' + f"}} {metric_value}" in body + ) + + @classmethod + def _perform_cover_metric_assert( + cls, + metric_name, + metric_value, + entity_id, + friendly_name, + body, + area=None, + device_class=None, + state=None, + ): + domain = "cover" + device_class_label_line = cls.get_device_class_label_line(device_class) + object_id = entity_id.replace(f"{domain}.", "") + state_label_line = f',state="{state}"' if state else "" + assert ( + f"{metric_name}{{" + f'area="{area or ""}",' + f"{device_class_label_line}" + f'domain="{domain}",' + f'entity="{entity_id}",' + f'friendly_name="{friendly_name}",' + f'object_id="{object_id}"' + f'{state_label_line}' + f"}} {metric_value}" in body + ) + + @classmethod + def _perform_humidifier_metric_assert( + cls, + metric_name, + metric_value, + friendly_name, + object_id, + body, + area=None, + device_class=None, + mode=None, + ): + domain = "humidifier" + device_class_label_line = cls.get_device_class_label_line(device_class) + mode_label_line = f'mode="{mode}",' if mode else "" + assert ( + f"{metric_name}{{" + f'area="{area or ""}",' + f"{device_class_label_line}" + f'domain="{domain}",' + f'entity="{domain}.{object_id}",' + f'friendly_name="{friendly_name}",' + f'{mode_label_line}' + f'object_id="{object_id}"' + f"}} {metric_value}" in body + ) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 4554843ceb8ded..6e7d9832343f12 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -66,6 +66,8 @@ from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util +from .helpers import MetricsTestHelper + from tests.typing import ClientSessionGenerator PROMETHEUS_PATH = "homeassistant.components.prometheus" @@ -79,174 +81,6 @@ class FilterTest: should_pass: bool -class MetricsTestHelper: - """Helps with formatting prometheus metrics and future-proof label changes.""" - - @classmethod - def _get_device_class_label_line(cls, device_class): - if device_class: - device_class = str(device_class) - return f'device_class="{device_class or ""}",' - - @classmethod - def _get_metric_string( - cls, - metric_name, - domain, - friendly_name, - object_id, - metric_value=None, - area=None, - device_class=None, - ): - device_class_label_line = cls._get_device_class_label_line(device_class) - final_metric_value = f" {metric_value}" if metric_value else "" - full_metric_string = ( - f"{metric_name}{{" - f'area="{area or ""}",' - f"{device_class_label_line}" - f'domain="{domain}",' - f'entity="{domain}.{object_id}",' - f'friendly_name="{friendly_name}",' - f'object_id="{object_id}"' - f"}}{final_metric_value}" - ) - return full_metric_string - - @classmethod - def _perform_metric_assert( - cls, - metric_name, - metric_value, - domain, - friendly_name, - object_id, - body, - area=None, - device_class=None, - positive_comparison=True, - ): - full_metric_string = cls._get_metric_string( - metric_name, - domain, - friendly_name, - object_id, - area=area, - device_class=device_class, - metric_value=metric_value, - ) - if positive_comparison: - assert full_metric_string in body - else: - assert full_metric_string not in body - - @classmethod - def _perform_sensor_metric_assert( - cls, - metric_name, - metric_value, - friendly_name, - object_id, - body, - area=None, - device_class=None, - positive_comparison=True, - ): - cls._perform_metric_assert( - metric_name, - metric_value, - "sensor", - friendly_name, - object_id, - body, - area=area, - device_class=device_class, - positive_comparison=positive_comparison, - ) - - @classmethod - def _perform_climate_metric_assert( - cls, - metric_name, - metric_value, - friendly_name, - object_id, - body, - area=None, - device_class=None, - action=None, - ): - domain = "climate" - device_class_label_line = cls._get_device_class_label_line(device_class) - action_label_line = f'action="{action}",' if action else "" - assert ( - f"{metric_name}{{" - f'{action_label_line}' - f'area="{area or ""}",' - f"{device_class_label_line}" - f'domain="{domain}",' - f'entity="{domain}.{object_id}",' - f'friendly_name="{friendly_name}",' - f'object_id="{object_id}"' - f"}} {metric_value}" in body - ) - - @classmethod - def _perform_cover_metric_assert( - cls, - metric_name, - metric_value, - entity_id, - friendly_name, - body, - area=None, - device_class=None, - state=None, - ): - domain = "cover" - device_class_label_line = cls._get_device_class_label_line(device_class) - object_id = entity_id.replace(f"{domain}.", "") - state_label_line = f',state="{state}"' if state else "" - assert ( - f"{metric_name}{{" - f'area="{area or ""}",' - f"{device_class_label_line}" - f'domain="{domain}",' - f'entity="{entity_id}",' - f'friendly_name="{friendly_name}",' - f'object_id="{object_id}"' - f'{state_label_line}' - f"}} {metric_value}" in body - ) - - @classmethod - def _perform_humidifier_metric_assert( - cls, - metric_name, - metric_value, - friendly_name, - object_id, - body, - area=None, - device_class=None, - mode=None, - ): - domain = "humidifier" - device_class_label_line = cls._get_device_class_label_line(device_class) - mode_label_line = f'mode="{mode}",' if mode else "" - assert ( - f"{metric_name}{{" - f'area="{area or ""}",' - f"{device_class_label_line}" - f'domain="{domain}",' - f'entity="{domain}.{object_id}",' - f'friendly_name="{friendly_name}",' - f'{mode_label_line}' - f'object_id="{object_id}"' - f"}} {metric_value}" in body - ) - - @pytest.fixture(name="client") async def setup_prometheus_client( hass: HomeAssistant, From 2e8e08947ab27ff7f2e0cc7439d274d5a058e2c6 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 13:51:35 -0700 Subject: [PATCH 23/62] I added some new tests! For the helpers, ironically --- tests/components/prometheus/test_helpers.py | 61 +++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 tests/components/prometheus/test_helpers.py diff --git a/tests/components/prometheus/test_helpers.py b/tests/components/prometheus/test_helpers.py new file mode 100644 index 00000000000000..046ea5ae58a30f --- /dev/null +++ b/tests/components/prometheus/test_helpers.py @@ -0,0 +1,61 @@ +"""Tests for prometheus test helpers.""" + +from __future__ import annotations + +from .helpers import MetricsTestHelper + + +def test_metric_test_helper_formats_simple_metric_string() -> None: + """Test using helper to format a simple metric string with no value included.""" + assert MetricsTestHelper._get_metric_string( + "homeassistant_sensor_temperature_celsius", + "sensor", + "Outside Temperature", + "outside_temperature", + ) == ( + "homeassistant_sensor_temperature_celsius{" + 'area="",' + 'device_class="",' + 'domain="sensor",' + 'entity="sensor.outside_temperature",' + 'friendly_name="Outside Temperature",' + 'object_id="outside_temperature"}' + ) + + +def test_metric_test_helper_formats_simple_metric_string_with_value() -> None: + """Test using helper to format a simple metric string but with a value included.""" + assert MetricsTestHelper._get_metric_string( + "homeassistant_sensor_temperature_celsius", + "sensor", + "Outside Temperature", + "outside_temperature", + metric_value="17.2", + ) == ( + "homeassistant_sensor_temperature_celsius{" + 'area="",' + 'device_class="",' + 'domain="sensor",' + 'entity="sensor.outside_temperature",' + 'friendly_name="Outside Temperature",' + 'object_id="outside_temperature"} 17.2' + ) + + +def test_metric_test_helper_formats_simple_metric_string_with_device_class() -> None: + """Test using helper to format a simple metric string and set a string device_class.""" + assert MetricsTestHelper._get_metric_string( + "homeassistant_sensor_temperature_celsius", + "sensor", + "Outside Temperature", + "outside_temperature", + device_class="temperature", + ) == ( + "homeassistant_sensor_temperature_celsius{" + 'area="",' + 'device_class="temperature",' + 'domain="sensor",' + 'entity="sensor.outside_temperature",' + 'friendly_name="Outside Temperature",' + 'object_id="outside_temperature"}' + ) From 90586f0c430e6dfefa25b35dcb882ac56638fb3a Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 14:24:47 -0700 Subject: [PATCH 24/62] Don't touch those files --- .dockerignore | 3 --- .gitignore | 3 --- .tool-versions | 1 + 3 files changed, 1 insertion(+), 6 deletions(-) create mode 100644 .tool-versions diff --git a/.dockerignore b/.dockerignore index f12c66a11d2bf7..7fde7f33fa5587 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,9 +4,6 @@ config docs -# asdf -.tool-versions - # Development .devcontainer .vscode diff --git a/.gitignore b/.gitignore index 64641d54a68b85..8a4154e4769964 100644 --- a/.gitignore +++ b/.gitignore @@ -28,9 +28,6 @@ Icon .idea *.iml -# asdf -.tool-versions - # pytest .pytest_cache .cache diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 00000000000000..69e5cf784af074 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +python 3.12.2 From 95c8a055813a8f566c3f970f62b9bc492514861d Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 14:25:14 -0700 Subject: [PATCH 25/62] Don't include that either --- .tool-versions | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .tool-versions diff --git a/.tool-versions b/.tool-versions deleted file mode 100644 index 69e5cf784af074..00000000000000 --- a/.tool-versions +++ /dev/null @@ -1 +0,0 @@ -python 3.12.2 From 6fde6341d254897c53aa8df52ef571a5fddf061b Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Fri, 29 Mar 2024 18:12:15 -0700 Subject: [PATCH 26/62] Added my first real test --- .../components/prometheus/__init__.py | 2 +- tests/components/prometheus/test_init.py | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/prometheus/__init__.py b/homeassistant/components/prometheus/__init__.py index 3108c609d7fbc9..35dc2117efc4ea 100644 --- a/homeassistant/components/prometheus/__init__.py +++ b/homeassistant/components/prometheus/__init__.py @@ -288,8 +288,8 @@ def _handle_attributes(self, state: State) -> None: except (ValueError, TypeError): pass + @staticmethod def _get_label_keys( - self, extra_labels: list[str] | None = None, ) -> list[str]: labels = [ diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 6e7d9832343f12..98fa41e5e3071b 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -36,6 +36,7 @@ ATTR_TARGET_TEMP_LOW, ) from homeassistant.components.humidifier import ATTR_AVAILABLE_MODES +from homeassistant.components.prometheus import PrometheusMetrics from homeassistant.components.sensor import SensorDeviceClass from homeassistant.const import ( ATTR_BATTERY_LEVEL, @@ -118,6 +119,25 @@ async def generate_latest_metrics(client): return body +@pytest.mark.parametrize("namespace", [""]) +async def test_metrics_labels_list( + hass: HomeAssistant, + hass_client: ClientSessionGenerator, + entity_registry: er.EntityRegistry, + namespace: str, +) -> None: + """Test that the common labels list is as expected.""" + expected_list = [ + "entity", + "friendly_name", + "domain", + "area", + "object_id", + "device_class", + ] + assert expected_list == PrometheusMetrics._get_label_keys() + + @pytest.mark.parametrize("namespace", [""]) async def test_setup_enumeration( hass: HomeAssistant, From 06ab90cb415d8e10f6964a2e7e8c7da68a73e0d9 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 12:19:13 -0700 Subject: [PATCH 27/62] Rolling back some logic changes to focus solely on tests --- .../components/prometheus/__init__.py | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/homeassistant/components/prometheus/__init__.py b/homeassistant/components/prometheus/__init__.py index 7215a41eb4f927..8cc0a8f4b6a6db 100644 --- a/homeassistant/components/prometheus/__init__.py +++ b/homeassistant/components/prometheus/__init__.py @@ -42,7 +42,6 @@ from homeassistant.components.light import ATTR_BRIGHTNESS from homeassistant.components.sensor import SensorDeviceClass from homeassistant.const import ( - ATTR_AREA_ID, ATTR_BATTERY_LEVEL, ATTR_DEVICE_CLASS, ATTR_FRIENDLY_NAME, @@ -307,22 +306,6 @@ def _handle_attributes(self, state: State) -> None: except (ValueError, TypeError): pass - @staticmethod - def _get_label_keys( - extra_labels: list[str] | None = None, - ) -> list[str]: - labels = [ - "entity", - "friendly_name", - "domain", - "area", - "object_id", - "device_class", - ] - if extra_labels is not None: - labels.extend(extra_labels) - return list(labels) - def _metric[_MetricBaseT: MetricWrapperBase]( self, metric: str, @@ -330,7 +313,9 @@ def _metric[_MetricBaseT: MetricWrapperBase]( documentation: str, extra_labels: list[str] | None = None, ) -> _MetricBaseT: - labels = self._get_label_keys(extra_labels=extra_labels) + labels = ["entity", "friendly_name", "domain"] + if extra_labels is not None: + labels.extend(extra_labels) try: return cast(_MetricBaseT, self._metrics[metric]) @@ -376,9 +361,6 @@ def _labels(state: State) -> dict[str, Any]: "entity": state.entity_id, "domain": state.domain, "friendly_name": state.attributes.get(ATTR_FRIENDLY_NAME), - "area": state.attributes.get(ATTR_AREA_ID) or "", - "object_id": state.object_id, - "device_class": state.attributes.get(ATTR_DEVICE_CLASS) or "", } def _battery(self, state: State) -> None: From eaffe1f924a3d79e92e1e50fbeaa8950f6d09eff Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 12:42:09 -0700 Subject: [PATCH 28/62] Curious what happens when I run the tests now --- tests/components/prometheus/test_init.py | 96 ++++++++++++++---------- 1 file changed, 56 insertions(+), 40 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 25936ea172e62c..e05355a1008920 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -50,7 +50,6 @@ DIRECTION_REVERSE, ) from homeassistant.components.humidifier import ATTR_AVAILABLE_MODES -from homeassistant.components.prometheus import PrometheusMetrics from homeassistant.components.lock import LockState from homeassistant.components.sensor import SensorDeviceClass from homeassistant.const import ( @@ -90,6 +89,37 @@ PROMETHEUS_PATH = "homeassistant.components.prometheus" +@dataclass(frozen=True) +class MetricInfo: + """Class for all data in a single prometheus metric.""" + + metric_name: str + domain: str + friendly_name: str + object_id: str + metric_value: Any | None = None + + @property + def entity(self): + """Generate entity_id from components.""" + return f"{self.domain}.{self.object_id}" + + def get_full_metric_string(self): + """Convert metric info into a valid prometheus text string.""" + final_metric_value = f" {self.metric_value}" if self.metric_value else "" + return ( + f"{self.metric_name}{{" + f'domain="{self.domain}",' + f'entity="{self.entity}",' + f'friendly_name="{self.friendly_name}",' + f"}}{final_metric_value}" + ) + + +def _assert_metric_present(body, metric_info: MetricInfo): + assert metric_info.get_full_metric_string() in body + + @dataclass class FilterTest: """Class for capturing a filter test.""" @@ -135,25 +165,6 @@ async def generate_latest_metrics(client): return body -@pytest.mark.parametrize("namespace", [""]) -async def test_metrics_labels_list( - hass: HomeAssistant, - hass_client: ClientSessionGenerator, - entity_registry: er.EntityRegistry, - namespace: str, -) -> None: - """Test that the common labels list is as expected.""" - expected_list = [ - "entity", - "friendly_name", - "domain", - "area", - "object_id", - "device_class", - ] - assert expected_list == PrometheusMetrics._get_label_keys() - - @pytest.mark.parametrize("namespace", [""]) async def test_setup_enumeration( hass: HomeAssistant, @@ -181,13 +192,15 @@ async def test_setup_enumeration( client = await hass_client() body = await generate_latest_metrics(client) - MetricsTestHelper._perform_sensor_metric_assert( - "homeassistant_sensor_temperature_celsius", - "12.3", - "Outside Temperature", - "outside_temperature", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="homeassistant_sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value=state, + ), ) @@ -204,22 +217,26 @@ async def test_view_empty_namespace( "Objects collected during gc" in body ) - MetricsTestHelper._perform_sensor_metric_assert( - "entity_available", - "1.0", - "Radio Energy", - "radio_energy", + _assert_metric_present( body, - device_class=SensorDeviceClass.POWER, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Radio Energy", + object_id="radio_energy", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_sensor_metric_assert( - "last_updated_time_seconds", - "86400.0", - "Radio Energy", - "radio_energy", + _assert_metric_present( body, - device_class=SensorDeviceClass.POWER, + MetricInfo( + metric_name="last_updated_time_seconds", + domain="sensor", + friendly_name="Radio Energy", + object_id="radio_energy", + metric_value="86400.0", + ), ) @@ -480,8 +497,7 @@ async def test_humidifier( "Humidifier", "humidifier", body, - # TODO: where is this humidifier device_class? - device_class="humidifier", + device_class=humidifier.HumidifierDeviceClass.HUMIDIFIER, ) MetricsTestHelper._perform_humidifier_metric_assert( From e13ec5e9e0005f3d39e83ccc27f329634ed25091 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 13:36:27 -0700 Subject: [PATCH 29/62] Getting closer to making things pass --- tests/components/prometheus/test_init.py | 100 ++++++++++++++++++----- 1 file changed, 78 insertions(+), 22 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index e05355a1008920..bdb7550c1d62ce 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -106,12 +106,14 @@ def entity(self): def get_full_metric_string(self): """Convert metric info into a valid prometheus text string.""" - final_metric_value = f" {self.metric_value}" if self.metric_value else "" + final_metric_value = ( + f" {self.metric_value}" if self.metric_value is not None else "" + ) return ( f"{self.metric_name}{{" f'domain="{self.domain}",' f'entity="{self.entity}",' - f'friendly_name="{self.friendly_name}",' + f'friendly_name="{self.friendly_name}"' f"}}{final_metric_value}" ) @@ -128,6 +130,38 @@ class FilterTest: should_pass: bool +def test_metric_info_generates_entity() -> None: + """Test using MetricInfo to format a simple metric string but with a value included.""" + domain = "sensor" + object_id = "outside_temperature" + metric_info = MetricInfo( + metric_name="homeassistant_sensor_temperature_celsius", + domain=domain, + friendly_name="Outside Temperature", + object_id=object_id, + metric_value=12.3, + ) + assert metric_info.entity == f"{domain}.{object_id}" + + +def test_metric_info_generates_metric_string_with_value() -> None: + """Test using MetricInfo to format a simple metric string but with a value included.""" + metric_info = MetricInfo( + metric_name="homeassistant_sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value=17.2, + ) + assert metric_info.get_full_metric_string() == ( + "homeassistant_sensor_temperature_celsius{" + 'domain="sensor",' + 'entity="sensor.outside_temperature",' + 'friendly_name="Outside Temperature"}' + " 17.2" + ) + + @pytest.fixture(name="client") async def setup_prometheus_client( hass: HomeAssistant, @@ -253,13 +287,15 @@ async def test_view_default_namespace( "Objects collected during gc" in body ) - MetricsTestHelper._perform_sensor_metric_assert( - "homeassistant_sensor_temperature_celsius", - "15.6", - "Outside Temperature", - "outside_temperature", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="homeassistant_sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="15.6", + ), ) @@ -270,28 +306,48 @@ async def test_sensor_unit( """Test prometheus metrics for sensors with a unit.""" body = await generate_latest_metrics(client) - MetricsTestHelper._perform_sensor_metric_assert( - "sensor_unit_kwh", "74.0", "Television Energy", "television_energy", body + _assert_metric_present( + body, + MetricInfo( + metric_name="sensor_unit_kwh", + domain="sensor", + friendly_name="Television Energy", + object_id="television_energy", + metric_value="74.0", + ), ) - MetricsTestHelper._perform_sensor_metric_assert( - "sensor_unit_sek_per_kwh", - "0.123", - "Electricity price", - "electricity_price", + _assert_metric_present( body, + MetricInfo( + metric_name="sensor_unit_sek_per_kwh", + domain="sensor", + friendly_name="Electricity price", + object_id="electricity_price", + metric_value="0.123", + ), ) - MetricsTestHelper._perform_sensor_metric_assert( - "sensor_unit_u0xb0", "25.0", "Wind Direction", "wind_direction", body + _assert_metric_present( + body, + MetricInfo( + metric_name="sensor_unit_u0xb0", + domain="sensor", + friendly_name="Wind Direction", + object_id="wind_direction", + metric_value="25.0", + ), ) - MetricsTestHelper._perform_sensor_metric_assert( - "sensor_unit_u0xb5g_per_mu0xb3", - "3.7069", - "SPS30 PM <1µm Weight concentration", - "sps30_pm_1um_weight_concentration", + _assert_metric_present( body, + MetricInfo( + metric_name="sensor_unit_u0xb5g_per_mu0xb3", + domain="sensor", + friendly_name="SPS30 PM <1µm Weight concentration", + object_id="sps30_pm_1um_weight_concentration", + metric_value="3.7069", + ), ) From 91dfc1ba890c33cf60909410a4e28806ea2ddf09 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 13:43:15 -0700 Subject: [PATCH 30/62] Getting closer to a working pr now --- tests/components/prometheus/test_init.py | 110 ++++++++++++++--------- 1 file changed, 70 insertions(+), 40 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index bdb7550c1d62ce..e8800b3dad9ed3 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -122,6 +122,10 @@ def _assert_metric_present(body, metric_info: MetricInfo): assert metric_info.get_full_metric_string() in body +def _assert_metric_not_present(body, metric_info: MetricInfo): + assert metric_info.get_full_metric_string() not in body + + @dataclass class FilterTest: """Class for capturing a filter test.""" @@ -358,21 +362,37 @@ async def test_sensor_without_unit( """Test prometheus metrics for sensors without a unit.""" body = await generate_latest_metrics(client) - MetricsTestHelper._perform_sensor_metric_assert( - "sensor_state", "0.002", "Trend Gradient", "trend_gradient", body + _assert_metric_present( + body, + MetricInfo( + metric_name="sensor_state", + domain="sensor", + friendly_name="Trend Gradient", + object_id="trend_gradient", + metric_value="0.002", + ), ) - MetricsTestHelper._perform_sensor_metric_assert( - "sensor_state", "0", "Text", "text", body, positive_comparison=False + _assert_metric_not_present( + body, + MetricInfo( + metric_name="sensor_state", + domain="sensor", + friendly_name="Text", + object_id="text", + metric_value="0", + ), ) - MetricsTestHelper._perform_sensor_metric_assert( - "sensor_unit_text", - "0", - "Text Unit", - "text_unit", + _assert_metric_not_present( body, - positive_comparison=False, + MetricInfo( + metric_name="sensor_unit_text", + domain="sensor", + friendly_name="Text Unit", + object_id="text_unit", + metric_value="0", + ), ) @@ -383,49 +403,59 @@ async def test_sensor_device_class( """Test prometheus metrics for sensor with a device_class.""" body = await generate_latest_metrics(client) - MetricsTestHelper._perform_sensor_metric_assert( - "sensor_temperature_celsius", - "10.0", - "Fahrenheit", - "fahrenheit", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Fahrenheit", + object_id="fahrenheit", + metric_value="10.0", + ), ) - MetricsTestHelper._perform_sensor_metric_assert( - "sensor_temperature_celsius", - "15.6", - "Outside Temperature", - "outside_temperature", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="15.6", + ), ) - MetricsTestHelper._perform_sensor_metric_assert( - "sensor_humidity_percent", - "54.0", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="54.0", + ), ) - MetricsTestHelper._perform_sensor_metric_assert( - "sensor_power_kwh", - "14.0", - "Radio Energy", - "radio_energy", + _assert_metric_present( body, - device_class=SensorDeviceClass.POWER, + MetricInfo( + metric_name="sensor_power_kwh", + domain="sensor", + friendly_name="Radio Energy", + object_id="radio_energy", + metric_value="14.0", + ), ) - MetricsTestHelper._perform_sensor_metric_assert( - "sensor_timestamp_seconds", - "1.691445808136036e+09", - "Timestamp", - "timestamp", + _assert_metric_present( body, - device_class=SensorDeviceClass.TIMESTAMP, + MetricInfo( + metric_name="sensor_timestamp_seconds", + domain="sensor", + friendly_name="Timestamp", + object_id="timestamp", + metric_value="1.691445808136036e+09", + ), ) From 3fc92d2c4cebeb0962cdc1ef99dec726baf3ea89 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 13:52:01 -0700 Subject: [PATCH 31/62] Keeping up with test fixes --- tests/components/prometheus/test_init.py | 143 +++++++++++++++++------ 1 file changed, 107 insertions(+), 36 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index e8800b3dad9ed3..2067cbd7dc6fb7 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -467,21 +467,37 @@ async def test_input_number( body = await generate_latest_metrics(client) domain = "input_number" - MetricsTestHelper._perform_metric_assert( - "input_number_state", "5.2", domain, "Threshold", "threshold", body + _assert_metric_present( + body, + MetricInfo( + metric_name="input_number_state", + domain=domain, + friendly_name="Threshold", + object_id="threshold", + metric_value="5.2", + ), ) - MetricsTestHelper._perform_metric_assert( - "input_number_state", "60.0", domain, "None", "brightness", body + _assert_metric_present( + body, + MetricInfo( + metric_name="input_number_state", + domain=domain, + friendly_name="None", + object_id="brightness", + metric_value="60.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "input_number_state_celsius", - "22.7", - domain, - "Target temperature", - "target_temperature", + _assert_metric_present( body, + MetricInfo( + metric_name="input_number_state_celsius", + domain=domain, + friendly_name="Target temperature", + object_id="target_temperature", + metric_value="22.7", + ), ) @@ -493,21 +509,37 @@ async def test_number( body = await generate_latest_metrics(client) domain = "number" - MetricsTestHelper._perform_metric_assert( - "number_state", "5.2", domain, "Threshold", "threshold", body + _assert_metric_present( + body, + MetricInfo( + metric_name="number_state", + domain=domain, + friendly_name="Threshold", + object_id="threshold", + metric_value="5.2", + ), ) - MetricsTestHelper._perform_metric_assert( - "number_state", "60.0", domain, "None", "brightness", body + _assert_metric_present( + body, + MetricInfo( + metric_name="number_state", + domain=domain, + friendly_name="None", + object_id="brightness", + metric_value="60.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "number_state_celsius", - "22.7", - domain, - "Target temperature", - "target_temperature", + _assert_metric_present( body, + MetricInfo( + metric_name="number_state_celsius", + domain=domain, + friendly_name="Target temperature", + object_id="target_temperature", + metric_value="22.7", + ), ) @@ -518,13 +550,15 @@ async def test_battery( """Test prometheus metrics for battery.""" body = await generate_latest_metrics(client) - MetricsTestHelper._perform_sensor_metric_assert( - "battery_level_percent", - "12.0", - "Outside Temperature", - "outside_temperature", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="battery_level_percent", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="12.0", + ), ) @@ -535,26 +569,63 @@ async def test_climate( ) -> None: """Test prometheus metrics for climate entities.""" body = await generate_latest_metrics(client) + domain = "climate" - MetricsTestHelper._perform_climate_metric_assert( - "climate_current_temperature_celsius", "25.0", "HeatPump", "heatpump", body + _assert_metric_present( + body, + MetricInfo( + metric_name="climate_current_temperature_celsius", + domain=domain, + friendly_name="HeatPump", + object_id="heatpump", + metric_value="25.0", + ), ) - MetricsTestHelper._perform_climate_metric_assert( - "climate_target_temperature_celsius", "20.0", "HeatPump", "heatpump", body + _assert_metric_present( + body, + MetricInfo( + metric_name="climate_target_temperature_celsius", + domain=domain, + friendly_name="HeatPump", + object_id="heatpump", + metric_value="20.0", + ), ) - MetricsTestHelper._perform_climate_metric_assert( - "climate_target_temperature_low_celsius", "21.0", "Ecobee", "ecobee", body + _assert_metric_present( + body, + MetricInfo( + metric_name="climate_target_temperature_low_celsius", + domain=domain, + friendly_name="Ecobee", + object_id="ecobee", + metric_value="21.0", + ), ) - MetricsTestHelper._perform_climate_metric_assert( - "climate_target_temperature_high_celsius", "24.0", "Ecobee", "ecobee", body + _assert_metric_present( + body, + MetricInfo( + metric_name="climate_target_temperature_high_celsius", + domain=domain, + friendly_name="Ecobee", + object_id="ecobee", + metric_value="24.0", + ), ) - MetricsTestHelper._perform_climate_metric_assert( - "climate_target_temperature_celsius", "0.0", "Fritz!DECT", "fritzdect", body + _assert_metric_present( + body, + MetricInfo( + metric_name="climate_target_temperature_celsius", + domain=domain, + friendly_name="Fritz!DECT", + object_id="fritzdect", + metric_value="0.0", + ), ) + assert ( 'climate_preset_mode{domain="climate",' 'entity="climate.ecobee",' From 59902f566c21736861ed946cad2d96d21a6251ed Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 14:03:01 -0700 Subject: [PATCH 32/62] Getting much closer to something useful --- tests/components/prometheus/test_init.py | 108 +++++++++++++++++------ 1 file changed, 82 insertions(+), 26 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 2067cbd7dc6fb7..08f0018059cab3 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -98,6 +98,7 @@ class MetricInfo: friendly_name: str object_id: str metric_value: Any | None = None + mode: str | None = None @property def entity(self): @@ -109,11 +110,13 @@ def get_full_metric_string(self): final_metric_value = ( f" {self.metric_value}" if self.metric_value is not None else "" ) + final_mode_value = f',mode="{self.mode}"' if self.mode is not None else "" return ( f"{self.metric_name}{{" f'domain="{self.domain}",' f'entity="{self.entity}",' f'friendly_name="{self.friendly_name}"' + f"{final_mode_value}" f"}}{final_metric_value}" ) @@ -166,6 +169,27 @@ def test_metric_info_generates_metric_string_with_value() -> None: ) +def test_metric_info_generates_metric_string_with_mode_value() -> None: + """Test using MetricInfo to format a simple metric string but with a value included.""" + metric_info = MetricInfo( + metric_name="climate_preset_mode", + domain="climate", + friendly_name="Ecobee", + object_id="ecobee", + metric_value="1.0", + mode="away", + ) + assert metric_info.get_full_metric_string() == ( + "climate_preset_mode{" + 'domain="climate",' + 'entity="climate.ecobee",' + 'friendly_name="Ecobee",' + 'mode="away"' + "}" + " 1.0" + ) + + @pytest.fixture(name="client") async def setup_prometheus_client( hass: HomeAssistant, @@ -626,17 +650,27 @@ async def test_climate( ), ) - assert ( - 'climate_preset_mode{domain="climate",' - 'entity="climate.ecobee",' - 'friendly_name="Ecobee",' - 'mode="away"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="climate_preset_mode", + domain=domain, + friendly_name="Ecobee", + object_id="ecobee", + metric_value="1.0", + mode="away", + ), ) - assert ( - 'climate_fan_mode{domain="climate",' - 'entity="climate.ecobee",' - 'friendly_name="Ecobee",' - 'mode="auto"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="climate_fan_mode", + domain=domain, + friendly_name="Ecobee", + object_id="ecobee", + metric_value="1.0", + mode="auto", + ), ) @@ -647,30 +681,52 @@ async def test_humidifier( ) -> None: """Test prometheus metrics for humidifier entities.""" body = await generate_latest_metrics(client) + domain = "humidifier" - MetricsTestHelper._perform_humidifier_metric_assert( - "humidifier_target_humidity_percent", - "68.0", - "Humidifier", - "humidifier", + _assert_metric_present( body, - device_class=humidifier.HumidifierDeviceClass.HUMIDIFIER, + MetricInfo( + metric_name="humidifier_target_humidity_percent", + domain=domain, + friendly_name="Humidifier", + object_id="humidifier", + metric_value="68.0", + ), ) - MetricsTestHelper._perform_humidifier_metric_assert( - "humidifier_state", - "1.0", - "Dehumidifier", - "dehumidifier", + _assert_metric_present( body, - device_class="dehumidifier", + MetricInfo( + metric_name="humidifier_state", + domain=domain, + friendly_name="Dehumidifier", + object_id="dehumidifier", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_humidifier_metric_assert( - "humidifier_mode", "1.0", "Hygrostat", "hygrostat", body, mode="home" + _assert_metric_present( + body, + MetricInfo( + metric_name="humidifier_mode", + domain=domain, + friendly_name="Hygrostat", + object_id="hygrostat", + metric_value="1.0", + mode="home", + ), ) - MetricsTestHelper._perform_humidifier_metric_assert( - "humidifier_mode", "0.0", "Hygrostat", "hygrostat", body, mode="eco" + + _assert_metric_present( + body, + MetricInfo( + metric_name="humidifier_mode", + domain=domain, + friendly_name="Hygrostat", + object_id="hygrostat", + metric_value="0.0", + mode="eco", + ), ) From 92ebb923c91ea3ee13a339e73877be58f4a77e5a Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 14:08:09 -0700 Subject: [PATCH 33/62] Saving piecemeal --- tests/components/prometheus/test_init.py | 91 +++++++++++++++++++----- 1 file changed, 74 insertions(+), 17 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 08f0018059cab3..aac54551d4cae4 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -739,20 +739,48 @@ async def test_attributes( body = await generate_latest_metrics(client) domain = "switch" - MetricsTestHelper._perform_metric_assert( - "switch_state", "1.0", domain, "Boolean", "boolean", body + _assert_metric_present( + body, + MetricInfo( + metric_name="switch_state", + domain=domain, + friendly_name="Boolean", + object_id="boolean", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "switch_attr_boolean", "1.0", domain, "Boolean", "boolean", body + _assert_metric_present( + body, + MetricInfo( + metric_name="switch_attr_boolean", + domain=domain, + friendly_name="Boolean", + object_id="boolean", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "switch_state", "0.0", domain, "Number", "number", body + _assert_metric_present( + body, + MetricInfo( + metric_name="switch_state", + domain=domain, + friendly_name="Number", + object_id="number", + metric_value="0.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "switch_attr_number", "10.2", domain, "Number", "number", body + _assert_metric_present( + body, + MetricInfo( + metric_name="switch_attr_number", + domain=domain, + friendly_name="Number", + object_id="number", + metric_value="10.2", + ), ) @@ -764,12 +792,27 @@ async def test_binary_sensor( body = await generate_latest_metrics(client) domain = "binary_sensor" - MetricsTestHelper._perform_metric_assert( - "binary_sensor_state", "1.0", domain, "Door", "door", body + + _assert_metric_present( + body, + MetricInfo( + metric_name="binary_sensor_state", + domain=domain, + friendly_name="Door", + object_id="door", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "binary_sensor_state", "0.0", domain, "Window", "window", body + _assert_metric_present( + body, + MetricInfo( + metric_name="binary_sensor_state", + domain=domain, + friendly_name="Window", + object_id="window", + metric_value="0.0", + ), ) @@ -781,12 +824,26 @@ async def test_input_boolean( body = await generate_latest_metrics(client) domain = "input_boolean" - MetricsTestHelper._perform_metric_assert( - "input_boolean_state", "1.0", domain, "Test", "test", body - ) - MetricsTestHelper._perform_metric_assert( - "input_boolean_state", "0.0", domain, "Helper", "helper", body + _assert_metric_present( + body, + MetricInfo( + metric_name="input_boolean_state", + domain=domain, + friendly_name="Test", + object_id="test", + metric_value="1.0", + ), + ) + _assert_metric_present( + body, + MetricInfo( + metric_name="input_boolean_state", + domain=domain, + friendly_name="Helper", + object_id="helper", + metric_value="0.0", + ), ) From 452b565176ad55fe52a437387d8a89cd783b4ef1 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 14:14:18 -0700 Subject: [PATCH 34/62] Getting closer to a final working version --- tests/components/prometheus/test_init.py | 158 +++++++++++++++++------ 1 file changed, 119 insertions(+), 39 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index aac54551d4cae4..e3f77a2dc6dd82 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -855,24 +855,59 @@ async def test_light( body = await generate_latest_metrics(client) domain = "light" - MetricsTestHelper._perform_metric_assert( - "light_brightness_percent", "100.0", domain, "Desk", "desk", body + _assert_metric_present( + body, + MetricInfo( + metric_name="light_brightness_percent", + domain=domain, + friendly_name="Desk", + object_id="desk", + metric_value="100.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "light_brightness_percent", "0.0", domain, "Wall", "wall", body + _assert_metric_present( + body, + MetricInfo( + metric_name="light_brightness_percent", + domain=domain, + friendly_name="Wall", + object_id="wall", + metric_value="0.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "light_brightness_percent", "100.0", domain, "TV", "tv", body + _assert_metric_present( + body, + MetricInfo( + metric_name="light_brightness_percent", + domain=domain, + friendly_name="TV", + object_id="tv", + metric_value="100.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "light_brightness_percent", "70.58823529411765", domain, "PC", "pc", body + _assert_metric_present( + body, + MetricInfo( + metric_name="light_brightness_percent", + domain=domain, + friendly_name="PC", + object_id="pc", + metric_value="70.58823529411765", + ), ) - MetricsTestHelper._perform_metric_assert( - "light_brightness_percent", "100.0", domain, "Hallway", "hallway", body + _assert_metric_present( + body, + MetricInfo( + metric_name="light_brightness_percent", + domain=domain, + friendly_name="Hallway", + object_id="hallway", + metric_value="100.0", + ), ) @@ -884,12 +919,26 @@ async def test_lock( body = await generate_latest_metrics(client) domain = "lock" - MetricsTestHelper._perform_metric_assert( - "lock_state", "1.0", domain, "Front Door", "front_door", body + _assert_metric_present( + body, + MetricInfo( + metric_name="lock_state", + domain=domain, + friendly_name="Front Door", + object_id="front_door", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "lock_state", "0.0", domain, "Kitchen Door", "kitchen_door", body + _assert_metric_present( + body, + MetricInfo( + metric_name="lock_state", + domain=domain, + friendly_name="Kitchen Door", + object_id="kitchen_door", + metric_value="0.0", + ), ) @@ -899,42 +948,73 @@ async def test_fan( ) -> None: """Test prometheus metrics for fan.""" body = await generate_latest_metrics(client) + domain = "fan" - assert ( - 'fan_state{domain="fan",' - 'entity="fan.fan_1",' - 'friendly_name="Fan 1"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="fan_state", + domain=domain, + friendly_name="Fan 1", + object_id="fan_1", + metric_value="1.0", + ), ) - assert ( - 'fan_speed_percent{domain="fan",' - 'entity="fan.fan_1",' - 'friendly_name="Fan 1"} 33.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="fan_speed_percent", + domain=domain, + friendly_name="Fan 1", + object_id="fan_1", + metric_value="33.0", + ), ) - assert ( - 'fan_is_oscillating{domain="fan",' - 'entity="fan.fan_1",' - 'friendly_name="Fan 1"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="fan_is_oscillating", + domain=domain, + friendly_name="Fan 1", + object_id="fan_1", + metric_value="1.0", + ), ) - assert ( - 'fan_direction_reversed{domain="fan",' - 'entity="fan.fan_1",' - 'friendly_name="Fan 1"} 0.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="fan_direction_reversed", + domain=domain, + friendly_name="Fan 1", + object_id="fan_1", + metric_value="0.0", + ), ) - assert ( - 'fan_preset_mode{domain="fan",' - 'entity="fan.fan_1",' - 'friendly_name="Fan 1",' - 'mode="LO"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="fan_preset_mode", + domain=domain, + friendly_name="Fan 1", + object_id="fan_1", + metric_value="1.0", + mode="LO", + ), ) - assert ( - 'fan_direction_reversed{domain="fan",' - 'entity="fan.fan_2",' - 'friendly_name="Reverse Fan"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="fan_direction_reversed", + domain=domain, + friendly_name="Reverse Fan", + object_id="fan_2", + metric_value="1.0", + ), ) From 79c227f9c3e568e7de0183dcb26e1c54ec024ae6 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 14:20:52 -0700 Subject: [PATCH 35/62] Now that's an improvement --- tests/components/prometheus/test_init.py | 28 ++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index e3f77a2dc6dd82..90cf125a1c1a22 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -99,6 +99,7 @@ class MetricInfo: object_id: str metric_value: Any | None = None mode: str | None = None + state: str | None = None @property def entity(self): @@ -111,12 +112,14 @@ def get_full_metric_string(self): f" {self.metric_value}" if self.metric_value is not None else "" ) final_mode_value = f',mode="{self.mode}"' if self.mode is not None else "" + final_state_value = f',state="{self.state}"' if self.state is not None else "" return ( f"{self.metric_name}{{" f'domain="{self.domain}",' f'entity="{self.entity}",' f'friendly_name="{self.friendly_name}"' f"{final_mode_value}" + f"{final_state_value}" f"}}{final_metric_value}" ) @@ -152,7 +155,7 @@ def test_metric_info_generates_entity() -> None: def test_metric_info_generates_metric_string_with_value() -> None: - """Test using MetricInfo to format a simple metric string but with a value included.""" + """Test using MetricInfo to format a simple metric string but with a metric value included.""" metric_info = MetricInfo( metric_name="homeassistant_sensor_temperature_celsius", domain="sensor", @@ -170,7 +173,7 @@ def test_metric_info_generates_metric_string_with_value() -> None: def test_metric_info_generates_metric_string_with_mode_value() -> None: - """Test using MetricInfo to format a simple metric string but with a value included.""" + """Test using MetricInfo to format a simple metric string but with a mode value included.""" metric_info = MetricInfo( metric_name="climate_preset_mode", domain="climate", @@ -190,6 +193,27 @@ def test_metric_info_generates_metric_string_with_mode_value() -> None: ) +def test_metric_info_generates_metric_string_with_state_value() -> None: + """Test using MetricInfo to format a simple metric string but with a state value included.""" + metric_info = MetricInfo( + metric_name="cover_state", + domain="cover", + friendly_name="Curtain", + object_id="curtain", + metric_value="1.0", + state="open", + ) + assert metric_info.get_full_metric_string() == ( + "cover_state{" + 'domain="cover",' + 'entity="cover.curtain",' + 'friendly_name="Curtain",' + 'state="open"' + "}" + " 1.0" + ) + + @pytest.fixture(name="client") async def setup_prometheus_client( hass: HomeAssistant, From 1d87379ecbdaf2c4cdf14fbfb32c92412335e897 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 14:27:48 -0700 Subject: [PATCH 36/62] And moving a little forward --- tests/components/prometheus/test_init.py | 61 ++++++++++++++++-------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 90cf125a1c1a22..6bd3f6fcfe5614 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -1049,33 +1049,54 @@ async def test_alarm_control_panel( ) -> None: """Test prometheus metrics for alarm control panel.""" body = await generate_latest_metrics(client) + domain = "alarm_control_panel" - assert ( - 'alarm_control_panel_state{domain="alarm_control_panel",' - 'entity="alarm_control_panel.alarm_control_panel_1",' - 'friendly_name="Alarm Control Panel 1",' - 'state="armed_away"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="alarm_control_panel_state", + domain=domain, + friendly_name="Alarm Control Panel 1", + object_id="alarm_control_panel_1", + metric_value="1.0", + state="armed_away", + ), ) - assert ( - 'alarm_control_panel_state{domain="alarm_control_panel",' - 'entity="alarm_control_panel.alarm_control_panel_1",' - 'friendly_name="Alarm Control Panel 1",' - 'state="disarmed"} 0.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="alarm_control_panel_state", + domain=domain, + friendly_name="Alarm Control Panel 1", + object_id="alarm_control_panel_1", + metric_value="0.0", + state="disarmed", + ), ) - assert ( - 'alarm_control_panel_state{domain="alarm_control_panel",' - 'entity="alarm_control_panel.alarm_control_panel_2",' - 'friendly_name="Alarm Control Panel 2",' - 'state="armed_home"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="alarm_control_panel_state", + domain=domain, + friendly_name="Alarm Control Panel 2", + object_id="alarm_control_panel_2", + metric_value="1.0", + state="armed_home", + ), ) - assert ( - 'alarm_control_panel_state{domain="alarm_control_panel",' - 'entity="alarm_control_panel.alarm_control_panel_2",' - 'friendly_name="Alarm Control Panel 2",' - 'state="armed_away"} 0.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="alarm_control_panel_state", + domain=domain, + friendly_name="Alarm Control Panel 2", + object_id="alarm_control_panel_2", + metric_value="0.0", + state="armed_away", + ), ) From 5a9c7b5f0055bba3a9363b193c05e71806c52e45 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 14:30:32 -0700 Subject: [PATCH 37/62] And now I'm really inching closer --- tests/components/prometheus/test_init.py | 55 +++++++++++++++++++----- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 6bd3f6fcfe5614..da2855109ffbf7 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -1173,11 +1173,25 @@ async def test_device_tracker( body = await generate_latest_metrics(client) domain = "device_tracker" - MetricsTestHelper._perform_metric_assert( - "device_tracker_state", "1.0", domain, "Phone", "phone", body + _assert_metric_present( + body, + MetricInfo( + metric_name="device_tracker_state", + domain=domain, + friendly_name="Phone", + object_id="phone", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "device_tracker_state", "0.0", domain, "Watch", "watch", body + _assert_metric_present( + body, + MetricInfo( + metric_name="device_tracker_state", + domain=domain, + friendly_name="Watch", + object_id="watch", + metric_value="0.0", + ), ) @@ -1189,8 +1203,15 @@ async def test_counter( body = await generate_latest_metrics(client) domain = "counter" - MetricsTestHelper._perform_metric_assert( - "counter_value", "2.0", domain, "None", "counter", body + _assert_metric_present( + body, + MetricInfo( + metric_name="counter_value", + domain=domain, + friendly_name="None", + object_id="counter", + metric_value="2.0", + ), ) @@ -1202,11 +1223,25 @@ async def test_update( body = await generate_latest_metrics(client) domain = "update" - MetricsTestHelper._perform_metric_assert( - "update_state", "1.0", domain, "Firmware", "firmware", body + _assert_metric_present( + body, + MetricInfo( + metric_name="update_state", + domain=domain, + friendly_name="Firmware", + object_id="firmware", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "update_state", "0.0", domain, "Addon", "addon", body + _assert_metric_present( + body, + MetricInfo( + metric_name="update_state", + domain=domain, + friendly_name="Addon", + object_id="addon", + metric_value="0.0", + ), ) From f139969c7b865e634d38d186adf780c37c9eb233 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 14:46:09 -0700 Subject: [PATCH 38/62] Saving more complex test case fix --- tests/components/prometheus/test_init.py | 200 +++++++++++++++-------- 1 file changed, 128 insertions(+), 72 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index da2855109ffbf7..12421fc8c37c43 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -100,6 +100,7 @@ class MetricInfo: metric_value: Any | None = None mode: str | None = None state: str | None = None + action: str | None = None @property def entity(self): @@ -111,10 +112,14 @@ def get_full_metric_string(self): final_metric_value = ( f" {self.metric_value}" if self.metric_value is not None else "" ) + final_action_value = ( + f'action="{self.action}",' if self.action is not None else "" + ) final_mode_value = f',mode="{self.mode}"' if self.mode is not None else "" final_state_value = f',state="{self.state}"' if self.state is not None else "" return ( f"{self.metric_name}{{" + f"{final_action_value}" f'domain="{self.domain}",' f'entity="{self.entity}",' f'friendly_name="{self.friendly_name}"' @@ -193,6 +198,27 @@ def test_metric_info_generates_metric_string_with_mode_value() -> None: ) +def test_metric_info_generates_metric_string_with_action_value() -> None: + """Test using MetricInfo to format a simple metric string but with an action value included.""" + metric_info = MetricInfo( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump", + object_id="heatpump", + metric_value="1.0", + action="heating", + ) + assert metric_info.get_full_metric_string() == ( + "climate_action{" + 'action="heating",' + 'domain="climate",' + 'entity="climate.heatpump",' + 'friendly_name="HeatPump"' + "}" + " 1.0" + ) + + def test_metric_info_generates_metric_string_with_state_value() -> None: """Test using MetricInfo to format a simple metric string but with a state value included.""" metric_info = MetricInfo( @@ -1257,52 +1283,72 @@ async def test_renaming_entity_name( data = {**sensor_entities, **climate_entities} body = await generate_latest_metrics(client) - MetricsTestHelper._perform_metric_assert( - "sensor_temperature_celsius", - "15.6", - "sensor", - "Outside Temperature", - "outside_temperature", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="15.6", + ), ) - MetricsTestHelper._perform_metric_assert( - "entity_available", - "1.0", - "sensor", - "Outside Temperature", - "outside_temperature", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "sensor_humidity_percent", - "54.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="54.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "entity_available", - "1.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_climate_metric_assert( - "climate_action", "1.0", "HeatPump", "heatpump", body, action="heating" + _assert_metric_present( + body, + MetricInfo( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump", + object_id="heatpump", + metric_value="1.0", + action="heating", + ), ) - MetricsTestHelper._perform_climate_metric_assert( - "climate_action", "0.0", "HeatPump", "heatpump", body, action="cooling" + _assert_metric_present( + body, + MetricInfo( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump", + object_id="heatpump", + metric_value="0.0", + action="cooling", + ), ) assert "sensor.outside_temperature" in entity_registry.entities @@ -1341,63 +1387,73 @@ async def test_renaming_entity_name( assert 'friendly_name="HeatPump"' not in body_line # Check if new metrics created - MetricsTestHelper._perform_metric_assert( - "sensor_temperature_celsius", - "15.6", - "sensor", - "Outside Temperature Renamed", - "outside_temperature", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature Renamed", + object_id="outside_temperature", + metric_value="15.6", + ), ) - MetricsTestHelper._perform_metric_assert( - "entity_available", - "1.0", - "sensor", - "Outside Temperature Renamed", - "outside_temperature", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature Renamed", + object_id="outside_temperature", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_climate_metric_assert( - "climate_action", - "1.0", - "HeatPump Renamed", - "heatpump", + _assert_metric_present( body, - action="heating", + MetricInfo( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump Renamed", + object_id="heatpump", + metric_value="1.0", + action="heating", + ), ) - MetricsTestHelper._perform_climate_metric_assert( - "climate_action", - "0.0", - "HeatPump Renamed", - "heatpump", + _assert_metric_present( body, - action="cooling", + MetricInfo( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump Renamed", + object_id="heatpump", + metric_value="0.0", + action="cooling", + ), ) # Keep other sensors - MetricsTestHelper._perform_metric_assert( - "sensor_humidity_percent", - "54.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="54.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "entity_available", - "1.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="1.0", + ), ) From 8a9452f7a9b67acfb2c9a70a8463c18bb67204e7 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 14:54:55 -0700 Subject: [PATCH 39/62] And now only 3 tests left --- tests/components/prometheus/test_init.py | 121 ++++++++++++----------- 1 file changed, 64 insertions(+), 57 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 12421fc8c37c43..5db6e2b2b08870 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -1469,44 +1469,48 @@ async def test_renaming_entity_id( data = {**sensor_entities, **climate_entities} body = await generate_latest_metrics(client) - MetricsTestHelper._perform_metric_assert( - "sensor_temperature_celsius", - "15.6", - "sensor", - "Outside Temperature", - "outside_temperature", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="15.6", + ), ) - MetricsTestHelper._perform_metric_assert( - "entity_available", - "1.0", - "sensor", - "Outside Temperature", - "outside_temperature", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "sensor_humidity_percent", - "54.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="54.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "entity_available", - "1.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="1.0", + ), ) assert "sensor.outside_temperature" in entity_registry.entities @@ -1527,45 +1531,48 @@ async def test_renaming_entity_id( assert 'entity="sensor.outside_temperature"' not in body_line # Check if new metrics created - MetricsTestHelper._perform_metric_assert( - "sensor_temperature_celsius", - "15.6", - "sensor", - "Outside Temperature", - "outside_temperature_renamed", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature_renamed", + metric_value="15.6", + ), ) - MetricsTestHelper._perform_metric_assert( - "entity_available", - "1.0", - "sensor", - "Outside Temperature", - "outside_temperature_renamed", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature_renamed", + metric_value="1.0", + ), ) # Keep other sensors - MetricsTestHelper._perform_metric_assert( - "sensor_humidity_percent", - "54.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="54.0", + ), ) - - MetricsTestHelper._perform_metric_assert( - "entity_available", - "1.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="1.0", + ), ) From 01a579768365371578472a8b10d54bf6892ba92f Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 15:04:26 -0700 Subject: [PATCH 40/62] Getting close and only a few tests left --- tests/components/prometheus/test_init.py | 241 +++++++++++++---------- 1 file changed, 142 insertions(+), 99 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 5db6e2b2b08870..3588613a464d11 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -1588,52 +1588,72 @@ async def test_deleting_entity( data = {**sensor_entities, **climate_entities} body = await generate_latest_metrics(client) - MetricsTestHelper._perform_metric_assert( - "sensor_temperature_celsius", - "15.6", - "sensor", - "Outside Temperature", - "outside_temperature", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="15.6", + ), ) - MetricsTestHelper._perform_metric_assert( - "entity_available", - "1.0", - "sensor", - "Outside Temperature", - "outside_temperature", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "sensor_humidity_percent", - "54.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="54.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "entity_available", - "1.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_climate_metric_assert( - "climate_action", "1.0", "HeatPump", "heatpump", body, action="heating" + _assert_metric_present( + body, + MetricInfo( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump", + object_id="heatpump", + metric_value="1.0", + action="heating", + ), ) - MetricsTestHelper._perform_climate_metric_assert( - "climate_action", "0.0", "HeatPump", "heatpump", body, action="cooling" + _assert_metric_present( + body, + MetricInfo( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump", + object_id="heatpump", + metric_value="0.0", + action="cooling", + ), ) assert "sensor.outside_temperature" in entity_registry.entities @@ -1652,24 +1672,26 @@ async def test_deleting_entity( assert 'friendly_name="HeatPump"' not in body_line # Keep other sensors - MetricsTestHelper._perform_metric_assert( - "sensor_humidity_percent", - "54.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="54.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "entity_available", - "1.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="1.0", + ), ) @@ -1687,61 +1709,80 @@ async def test_disabling_entity( await hass.async_block_till_done() body = await generate_latest_metrics(client) - MetricsTestHelper._perform_metric_assert( - "sensor_temperature_celsius", - "15.6", - "sensor", - "Outside Temperature", - "outside_temperature", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="15.6", + ), ) - MetricsTestHelper._perform_metric_assert( - "state_change_total", - "1.0", - "sensor", - "Outside Temperature", - "outside_temperature", + _assert_metric_present( body, - device_class=SensorDeviceClass.TEMPERATURE, + MetricInfo( + metric_name="state_change_total", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="1.0", + ), ) - state_change_metric_string = MetricsTestHelper._get_metric_string( - "state_change_created", - "sensor", - "Outside Temperature", - "outside_temperature", - device_class=SensorDeviceClass.TEMPERATURE, - ) + state_change_metric_string = MetricInfo( + metric_name="state_change_created", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + ).get_full_metric_string() assert any(state_change_metric_string for metric in body) - MetricsTestHelper._perform_metric_assert( - "sensor_humidity_percent", - "54.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="54.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "entity_available", - "1.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="1.0", + ), ) - MetricsTestHelper._perform_climate_metric_assert( - "climate_action", "1.0", "HeatPump", "heatpump", body, action="heating" + _assert_metric_present( + body, + MetricInfo( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump", + object_id="heatpump", + metric_value="1.0", + action="heating", + ), ) - MetricsTestHelper._perform_climate_metric_assert( - "climate_action", "0.0", "HeatPump", "heatpump", body, action="cooling" + _assert_metric_present( + body, + MetricInfo( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump", + object_id="heatpump", + metric_value="0.0", + action="cooling", + ), ) assert "sensor.outside_temperature" in entity_registry.entities @@ -1766,24 +1807,26 @@ async def test_disabling_entity( assert 'friendly_name="HeatPump"' not in body_line # Keep other sensors - MetricsTestHelper._perform_metric_assert( - "sensor_humidity_percent", - "54.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="54.0", + ), ) - MetricsTestHelper._perform_metric_assert( - "entity_available", - "1.0", - "sensor", - "Outside Humidity", - "outside_humidity", + _assert_metric_present( body, - device_class=SensorDeviceClass.HUMIDITY, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="1.0", + ), ) From 89d81467f1262baa30675c16dff768b9e53419b3 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 15:11:03 -0700 Subject: [PATCH 41/62] I think I'm close with only 1 test left --- tests/components/prometheus/test_init.py | 195 ++++++++++++++++------- 1 file changed, 135 insertions(+), 60 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 3588613a464d11..8ca9e19d18ab2f 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -1843,40 +1843,70 @@ async def test_entity_becomes_unavailable_with_export( await hass.async_block_till_done() body = await generate_latest_metrics(client) - assert ( - 'sensor_temperature_celsius{domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 15.6' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="15.6", + ), ) - assert ( - 'state_change_total{domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="state_change_total", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="1.0", + ), ) - assert ( - 'entity_available{domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="1.0", + ), ) - assert ( - 'sensor_humidity_percent{domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 54.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="54.0", + ), ) - assert ( - 'state_change_total{domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="state_change_total", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="1.0", + ), ) - assert ( - 'entity_available{domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="1.0", + ), ) # Make sensor_1 unavailable. @@ -1888,41 +1918,71 @@ async def test_entity_becomes_unavailable_with_export( body = await generate_latest_metrics(client) # Check that only the availability changed on sensor_1. - assert ( - 'sensor_temperature_celsius{domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 15.6' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="15.6", + ), ) - assert ( - 'state_change_total{domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 2.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="state_change_total", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="2.0", + ), ) - assert ( - 'entity_available{domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 0.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="0.0", + ), ) # The other sensor should be unchanged. - assert ( - 'sensor_humidity_percent{domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 54.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="54.0", + ), ) - assert ( - 'state_change_total{domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="state_change_total", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="1.0", + ), ) - assert ( - 'entity_available{domain="sensor",' - 'entity="sensor.outside_humidity",' - 'friendly_name="Outside Humidity"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + object_id="outside_humidity", + metric_value="1.0", + ), ) # Bring sensor_1 back and check that it is correct. @@ -1931,22 +1991,37 @@ async def test_entity_becomes_unavailable_with_export( await hass.async_block_till_done() body = await generate_latest_metrics(client) - assert ( - 'sensor_temperature_celsius{domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 200.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="200.0", + ), ) - assert ( - 'state_change_total{domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 3.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="state_change_total", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="3.0", + ), ) - assert ( - 'entity_available{domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"} 1.0' in body + _assert_metric_present( + body, + MetricInfo( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature", + object_id="outside_temperature", + metric_value="1.0", + ), ) From 22f54f8a695e6081ca5b2d7d08f539fbf896d5b9 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 15:33:43 -0700 Subject: [PATCH 42/62] Does this mean the tests actually work now --- tests/components/prometheus/test_init.py | 134 +++++++++++++++++------ 1 file changed, 98 insertions(+), 36 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 8ca9e19d18ab2f..480c0855832d41 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -82,8 +82,6 @@ from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from .helpers import MetricsTestHelper - from tests.typing import ClientSessionGenerator PROMETHEUS_PATH = "homeassistant.components.prometheus" @@ -102,6 +100,21 @@ class MetricInfo: state: str | None = None action: str | None = None + @classmethod + def from_entity_id(cls, entity_id, **kwargs): + """Construct MetricInfo using full entity_id instead of parts.""" + domain, object_id = entity_id.split(".") + return cls( + metric_name=kwargs["metric_name"], + domain=domain, + friendly_name=kwargs["friendly_name"], + object_id=object_id, + metric_value=kwargs.get("metric_value"), + mode=kwargs.get("mode"), + state=kwargs.get("state"), + action=kwargs.get("action"), + ) + @property def entity(self): """Generate entity_id from components.""" @@ -177,6 +190,35 @@ def test_metric_info_generates_metric_string_with_value() -> None: ) +def test_metric_info_generates_info_from_entity_id() -> None: + """Test using MetricInfo from entity_id matches constructor MetricInfo.""" + domain = "sensor" + object_id = "outside_temperature" + entity_id = f"{domain}.{object_id}" + assert f"{domain}.{object_id}" == entity_id + metric_name = "homeassistant_sensor_temperature_celsius" + friendly_name = "Outside Temperature" + metric_value = "12.3" + metric_info_from_entity_id = MetricInfo.from_entity_id( + entity_id, + metric_name=metric_name, + friendly_name=friendly_name, + metric_value=metric_value, + ) + assert metric_info_from_entity_id.entity == entity_id + + metric_info_with_constructor = MetricInfo( + metric_name=metric_name, + domain=domain, + friendly_name=friendly_name, + object_id=object_id, + metric_value=metric_value, + ) + assert metric_info_with_constructor.entity == entity_id + + assert metric_info_from_entity_id == metric_info_with_constructor + + def test_metric_info_generates_metric_string_with_mode_value() -> None: """Test using MetricInfo to format a simple metric string but with a mode value included.""" metric_info = MetricInfo( @@ -1136,58 +1178,78 @@ async def test_cover( open_covers = ["cover_open", "cover_position", "cover_tilt_position"] for testcover in data: - MetricsTestHelper._perform_cover_metric_assert( - "cover_state", - 1.0 if cover_entities[testcover].unique_id in open_covers else 0.0, - cover_entities[testcover].entity_id, - cover_entities[testcover].original_name, + _assert_metric_present( body, - state="open", + MetricInfo.from_entity_id( + cover_entities[testcover].entity_id, + metric_name="cover_state", + friendly_name=cover_entities[testcover].original_name, + metric_value=1.0 + if cover_entities[testcover].unique_id in open_covers + else 0.0, + state="open", + ), ) - MetricsTestHelper._perform_cover_metric_assert( - "cover_state", - 1.0 if cover_entities[testcover].unique_id == "cover_closed" else 0.0, - cover_entities[testcover].entity_id, - cover_entities[testcover].original_name, + _assert_metric_present( body, - state="closed", + MetricInfo.from_entity_id( + cover_entities[testcover].entity_id, + metric_name="cover_state", + friendly_name=cover_entities[testcover].original_name, + metric_value=1.0 + if cover_entities[testcover].unique_id == "cover_closed" + else 0.0, + state="closed", + ), ) - MetricsTestHelper._perform_cover_metric_assert( - "cover_state", - 1.0 if cover_entities[testcover].unique_id == "cover_opening" else 0.0, - cover_entities[testcover].entity_id, - cover_entities[testcover].original_name, + _assert_metric_present( body, - state="opening", + MetricInfo.from_entity_id( + cover_entities[testcover].entity_id, + metric_name="cover_state", + friendly_name=cover_entities[testcover].original_name, + metric_value=1.0 + if cover_entities[testcover].unique_id == "cover_opening" + else 0.0, + state="opening", + ), ) - MetricsTestHelper._perform_cover_metric_assert( - "cover_state", - 1.0 if cover_entities[testcover].unique_id == "cover_closing" else 0.0, - cover_entities[testcover].entity_id, - cover_entities[testcover].original_name, + _assert_metric_present( body, - state="closing", + MetricInfo.from_entity_id( + cover_entities[testcover].entity_id, + metric_name="cover_state", + friendly_name=cover_entities[testcover].original_name, + metric_value=1.0 + if cover_entities[testcover].unique_id == "cover_closing" + else 0.0, + state="closing", + ), ) if testcover == "cover_position": - MetricsTestHelper._perform_cover_metric_assert( - "cover_position", - "50.0", - cover_entities[testcover].entity_id, - cover_entities[testcover].original_name, + _assert_metric_present( body, + MetricInfo.from_entity_id( + cover_entities[testcover].entity_id, + metric_name="cover_position", + friendly_name=cover_entities[testcover].original_name, + metric_value="50.0", + ), ) if testcover == "cover_tilt_position": - MetricsTestHelper._perform_cover_metric_assert( - "cover_tilt_position", - "50.0", - cover_entities[testcover].entity_id, - cover_entities[testcover].original_name, + _assert_metric_present( body, + MetricInfo.from_entity_id( + cover_entities[testcover].entity_id, + metric_name="cover_tilt_position", + friendly_name=cover_entities[testcover].original_name, + metric_value="50.0", + ), ) From 80d4482977e4fe11b8e18872659c9f10eaf413e9 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 15:35:18 -0700 Subject: [PATCH 43/62] Was not using the helper classes anymore --- tests/components/prometheus/helpers.py | 170 -------------------- tests/components/prometheus/test_helpers.py | 61 ------- 2 files changed, 231 deletions(-) delete mode 100644 tests/components/prometheus/helpers.py delete mode 100644 tests/components/prometheus/test_helpers.py diff --git a/tests/components/prometheus/helpers.py b/tests/components/prometheus/helpers.py deleted file mode 100644 index 14d146123bec17..00000000000000 --- a/tests/components/prometheus/helpers.py +++ /dev/null @@ -1,170 +0,0 @@ -"""Helper methods for prometheus tests.""" - - -class MetricsTestHelper: - """Helps with formatting prometheus metrics and future-proof label changes.""" - - @classmethod - def get_device_class_label_line(cls, device_class): - """Format the device_class label line (tries to account for enum class).""" - if device_class: - device_class = str(device_class) - return f'device_class="{device_class or ""}",' - - @classmethod - def _get_metric_string( - cls, - metric_name, - domain, - friendly_name, - object_id, - metric_value=None, - area=None, - device_class=None, - ): - device_class_label_line = cls.get_device_class_label_line(device_class) - final_metric_value = f" {metric_value}" if metric_value else "" - full_metric_string = ( - f"{metric_name}{{" - f'area="{area or ""}",' - f"{device_class_label_line}" - f'domain="{domain}",' - f'entity="{domain}.{object_id}",' - f'friendly_name="{friendly_name}",' - f'object_id="{object_id}"' - f"}}{final_metric_value}" - ) - return full_metric_string - - @classmethod - def _perform_metric_assert( - cls, - metric_name, - metric_value, - domain, - friendly_name, - object_id, - body, - area=None, - device_class=None, - positive_comparison=True, - ): - full_metric_string = cls._get_metric_string( - metric_name, - domain, - friendly_name, - object_id, - area=area, - device_class=device_class, - metric_value=metric_value, - ) - if positive_comparison: - assert full_metric_string in body - else: - assert full_metric_string not in body - - @classmethod - def _perform_sensor_metric_assert( - cls, - metric_name, - metric_value, - friendly_name, - object_id, - body, - area=None, - device_class=None, - positive_comparison=True, - ): - cls._perform_metric_assert( - metric_name, - metric_value, - "sensor", - friendly_name, - object_id, - body, - area=area, - device_class=device_class, - positive_comparison=positive_comparison, - ) - - @classmethod - def _perform_climate_metric_assert( - cls, - metric_name, - metric_value, - friendly_name, - object_id, - body, - area=None, - device_class=None, - action=None, - ): - domain = "climate" - device_class_label_line = cls.get_device_class_label_line(device_class) - action_label_line = f'action="{action}",' if action else "" - assert ( - f"{metric_name}{{" - f'{action_label_line}' - f'area="{area or ""}",' - f"{device_class_label_line}" - f'domain="{domain}",' - f'entity="{domain}.{object_id}",' - f'friendly_name="{friendly_name}",' - f'object_id="{object_id}"' - f"}} {metric_value}" in body - ) - - @classmethod - def _perform_cover_metric_assert( - cls, - metric_name, - metric_value, - entity_id, - friendly_name, - body, - area=None, - device_class=None, - state=None, - ): - domain = "cover" - device_class_label_line = cls.get_device_class_label_line(device_class) - object_id = entity_id.replace(f"{domain}.", "") - state_label_line = f',state="{state}"' if state else "" - assert ( - f"{metric_name}{{" - f'area="{area or ""}",' - f"{device_class_label_line}" - f'domain="{domain}",' - f'entity="{entity_id}",' - f'friendly_name="{friendly_name}",' - f'object_id="{object_id}"' - f'{state_label_line}' - f"}} {metric_value}" in body - ) - - @classmethod - def _perform_humidifier_metric_assert( - cls, - metric_name, - metric_value, - friendly_name, - object_id, - body, - area=None, - device_class=None, - mode=None, - ): - domain = "humidifier" - device_class_label_line = cls.get_device_class_label_line(device_class) - mode_label_line = f'mode="{mode}",' if mode else "" - assert ( - f"{metric_name}{{" - f'area="{area or ""}",' - f"{device_class_label_line}" - f'domain="{domain}",' - f'entity="{domain}.{object_id}",' - f'friendly_name="{friendly_name}",' - f'{mode_label_line}' - f'object_id="{object_id}"' - f"}} {metric_value}" in body - ) diff --git a/tests/components/prometheus/test_helpers.py b/tests/components/prometheus/test_helpers.py deleted file mode 100644 index 046ea5ae58a30f..00000000000000 --- a/tests/components/prometheus/test_helpers.py +++ /dev/null @@ -1,61 +0,0 @@ -"""Tests for prometheus test helpers.""" - -from __future__ import annotations - -from .helpers import MetricsTestHelper - - -def test_metric_test_helper_formats_simple_metric_string() -> None: - """Test using helper to format a simple metric string with no value included.""" - assert MetricsTestHelper._get_metric_string( - "homeassistant_sensor_temperature_celsius", - "sensor", - "Outside Temperature", - "outside_temperature", - ) == ( - "homeassistant_sensor_temperature_celsius{" - 'area="",' - 'device_class="",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature",' - 'object_id="outside_temperature"}' - ) - - -def test_metric_test_helper_formats_simple_metric_string_with_value() -> None: - """Test using helper to format a simple metric string but with a value included.""" - assert MetricsTestHelper._get_metric_string( - "homeassistant_sensor_temperature_celsius", - "sensor", - "Outside Temperature", - "outside_temperature", - metric_value="17.2", - ) == ( - "homeassistant_sensor_temperature_celsius{" - 'area="",' - 'device_class="",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature",' - 'object_id="outside_temperature"} 17.2' - ) - - -def test_metric_test_helper_formats_simple_metric_string_with_device_class() -> None: - """Test using helper to format a simple metric string and set a string device_class.""" - assert MetricsTestHelper._get_metric_string( - "homeassistant_sensor_temperature_celsius", - "sensor", - "Outside Temperature", - "outside_temperature", - device_class="temperature", - ) == ( - "homeassistant_sensor_temperature_celsius{" - 'area="",' - 'device_class="temperature",' - 'domain="sensor",' - 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature",' - 'object_id="outside_temperature"}' - ) From 02402183cabd117de9fa7c1a1736c83f3bbc883c Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 15:40:21 -0700 Subject: [PATCH 44/62] Now I'm really curious --- tests/components/prometheus/test_init.py | 286 +++++++++++------------ 1 file changed, 143 insertions(+), 143 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 480c0855832d41..8b2f894fc6d7ce 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -3,7 +3,7 @@ from dataclasses import dataclass import datetime from http import HTTPStatus -from typing import Any +from typing import Any, Self from unittest import mock from freezegun import freeze_time @@ -88,7 +88,7 @@ @dataclass(frozen=True) -class MetricInfo: +class TestMetricInfo: """Class for all data in a single prometheus metric.""" metric_name: str @@ -101,8 +101,8 @@ class MetricInfo: action: str | None = None @classmethod - def from_entity_id(cls, entity_id, **kwargs): - """Construct MetricInfo using full entity_id instead of parts.""" + def from_entity_id(cls, entity_id: str, **kwargs) -> Self: + """Construct TestMetricInfo using full entity_id instead of parts.""" domain, object_id = entity_id.split(".") return cls( metric_name=kwargs["metric_name"], @@ -116,11 +116,11 @@ def from_entity_id(cls, entity_id, **kwargs): ) @property - def entity(self): + def entity(self) -> str: """Generate entity_id from components.""" return f"{self.domain}.{self.object_id}" - def get_full_metric_string(self): + def get_full_metric_string(self) -> str: """Convert metric info into a valid prometheus text string.""" final_metric_value = ( f" {self.metric_value}" if self.metric_value is not None else "" @@ -142,11 +142,11 @@ def get_full_metric_string(self): ) -def _assert_metric_present(body, metric_info: MetricInfo): +def _assert_metric_present(body, metric_info: TestMetricInfo) -> None: assert metric_info.get_full_metric_string() in body -def _assert_metric_not_present(body, metric_info: MetricInfo): +def _assert_metric_not_present(body, metric_info: TestMetricInfo) -> None: assert metric_info.get_full_metric_string() not in body @@ -159,10 +159,10 @@ class FilterTest: def test_metric_info_generates_entity() -> None: - """Test using MetricInfo to format a simple metric string but with a value included.""" + """Test using TestMetricInfo to format a simple metric string but with a value included.""" domain = "sensor" object_id = "outside_temperature" - metric_info = MetricInfo( + metric_info = TestMetricInfo( metric_name="homeassistant_sensor_temperature_celsius", domain=domain, friendly_name="Outside Temperature", @@ -173,8 +173,8 @@ def test_metric_info_generates_entity() -> None: def test_metric_info_generates_metric_string_with_value() -> None: - """Test using MetricInfo to format a simple metric string but with a metric value included.""" - metric_info = MetricInfo( + """Test using TestMetricInfo to format a simple metric string but with a metric value included.""" + metric_info = TestMetricInfo( metric_name="homeassistant_sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -191,7 +191,7 @@ def test_metric_info_generates_metric_string_with_value() -> None: def test_metric_info_generates_info_from_entity_id() -> None: - """Test using MetricInfo from entity_id matches constructor MetricInfo.""" + """Test using TestMetricInfo from entity_id matches constructor TestMetricInfo.""" domain = "sensor" object_id = "outside_temperature" entity_id = f"{domain}.{object_id}" @@ -199,7 +199,7 @@ def test_metric_info_generates_info_from_entity_id() -> None: metric_name = "homeassistant_sensor_temperature_celsius" friendly_name = "Outside Temperature" metric_value = "12.3" - metric_info_from_entity_id = MetricInfo.from_entity_id( + metric_info_from_entity_id = TestMetricInfo.from_entity_id( entity_id, metric_name=metric_name, friendly_name=friendly_name, @@ -207,7 +207,7 @@ def test_metric_info_generates_info_from_entity_id() -> None: ) assert metric_info_from_entity_id.entity == entity_id - metric_info_with_constructor = MetricInfo( + metric_info_with_constructor = TestMetricInfo( metric_name=metric_name, domain=domain, friendly_name=friendly_name, @@ -220,8 +220,8 @@ def test_metric_info_generates_info_from_entity_id() -> None: def test_metric_info_generates_metric_string_with_mode_value() -> None: - """Test using MetricInfo to format a simple metric string but with a mode value included.""" - metric_info = MetricInfo( + """Test using TestMetricInfo to format a simple metric string but with a mode value included.""" + metric_info = TestMetricInfo( metric_name="climate_preset_mode", domain="climate", friendly_name="Ecobee", @@ -241,8 +241,8 @@ def test_metric_info_generates_metric_string_with_mode_value() -> None: def test_metric_info_generates_metric_string_with_action_value() -> None: - """Test using MetricInfo to format a simple metric string but with an action value included.""" - metric_info = MetricInfo( + """Test using TestMetricInfo to format a simple metric string but with an action value included.""" + metric_info = TestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -262,8 +262,8 @@ def test_metric_info_generates_metric_string_with_action_value() -> None: def test_metric_info_generates_metric_string_with_state_value() -> None: - """Test using MetricInfo to format a simple metric string but with a state value included.""" - metric_info = MetricInfo( + """Test using TestMetricInfo to format a simple metric string but with a state value included.""" + metric_info = TestMetricInfo( metric_name="cover_state", domain="cover", friendly_name="Curtain", @@ -348,7 +348,7 @@ async def test_setup_enumeration( body = await generate_latest_metrics(client) _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="homeassistant_sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -373,7 +373,7 @@ async def test_view_empty_namespace( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Radio Energy", @@ -384,7 +384,7 @@ async def test_view_empty_namespace( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="last_updated_time_seconds", domain="sensor", friendly_name="Radio Energy", @@ -409,7 +409,7 @@ async def test_view_default_namespace( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="homeassistant_sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -428,7 +428,7 @@ async def test_sensor_unit( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_unit_kwh", domain="sensor", friendly_name="Television Energy", @@ -439,7 +439,7 @@ async def test_sensor_unit( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_unit_sek_per_kwh", domain="sensor", friendly_name="Electricity price", @@ -450,7 +450,7 @@ async def test_sensor_unit( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_unit_u0xb0", domain="sensor", friendly_name="Wind Direction", @@ -461,7 +461,7 @@ async def test_sensor_unit( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_unit_u0xb5g_per_mu0xb3", domain="sensor", friendly_name="SPS30 PM <1µm Weight concentration", @@ -480,7 +480,7 @@ async def test_sensor_without_unit( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_state", domain="sensor", friendly_name="Trend Gradient", @@ -491,7 +491,7 @@ async def test_sensor_without_unit( _assert_metric_not_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_state", domain="sensor", friendly_name="Text", @@ -502,7 +502,7 @@ async def test_sensor_without_unit( _assert_metric_not_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_unit_text", domain="sensor", friendly_name="Text Unit", @@ -521,7 +521,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Fahrenheit", @@ -532,7 +532,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -543,7 +543,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -554,7 +554,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_power_kwh", domain="sensor", friendly_name="Radio Energy", @@ -565,7 +565,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_timestamp_seconds", domain="sensor", friendly_name="Timestamp", @@ -585,7 +585,7 @@ async def test_input_number( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="input_number_state", domain=domain, friendly_name="Threshold", @@ -596,7 +596,7 @@ async def test_input_number( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="input_number_state", domain=domain, friendly_name="None", @@ -607,7 +607,7 @@ async def test_input_number( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="input_number_state_celsius", domain=domain, friendly_name="Target temperature", @@ -627,7 +627,7 @@ async def test_number( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="number_state", domain=domain, friendly_name="Threshold", @@ -638,7 +638,7 @@ async def test_number( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="number_state", domain=domain, friendly_name="None", @@ -649,7 +649,7 @@ async def test_number( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="number_state_celsius", domain=domain, friendly_name="Target temperature", @@ -668,7 +668,7 @@ async def test_battery( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="battery_level_percent", domain="sensor", friendly_name="Outside Temperature", @@ -689,7 +689,7 @@ async def test_climate( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_current_temperature_celsius", domain=domain, friendly_name="HeatPump", @@ -700,7 +700,7 @@ async def test_climate( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_target_temperature_celsius", domain=domain, friendly_name="HeatPump", @@ -711,7 +711,7 @@ async def test_climate( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_target_temperature_low_celsius", domain=domain, friendly_name="Ecobee", @@ -722,7 +722,7 @@ async def test_climate( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_target_temperature_high_celsius", domain=domain, friendly_name="Ecobee", @@ -733,7 +733,7 @@ async def test_climate( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_target_temperature_celsius", domain=domain, friendly_name="Fritz!DECT", @@ -744,7 +744,7 @@ async def test_climate( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_preset_mode", domain=domain, friendly_name="Ecobee", @@ -755,7 +755,7 @@ async def test_climate( ) _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_fan_mode", domain=domain, friendly_name="Ecobee", @@ -777,7 +777,7 @@ async def test_humidifier( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="humidifier_target_humidity_percent", domain=domain, friendly_name="Humidifier", @@ -788,7 +788,7 @@ async def test_humidifier( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="humidifier_state", domain=domain, friendly_name="Dehumidifier", @@ -799,7 +799,7 @@ async def test_humidifier( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="humidifier_mode", domain=domain, friendly_name="Hygrostat", @@ -811,7 +811,7 @@ async def test_humidifier( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="humidifier_mode", domain=domain, friendly_name="Hygrostat", @@ -833,7 +833,7 @@ async def test_attributes( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="switch_state", domain=domain, friendly_name="Boolean", @@ -844,7 +844,7 @@ async def test_attributes( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="switch_attr_boolean", domain=domain, friendly_name="Boolean", @@ -855,7 +855,7 @@ async def test_attributes( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="switch_state", domain=domain, friendly_name="Number", @@ -866,7 +866,7 @@ async def test_attributes( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="switch_attr_number", domain=domain, friendly_name="Number", @@ -887,7 +887,7 @@ async def test_binary_sensor( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="binary_sensor_state", domain=domain, friendly_name="Door", @@ -898,7 +898,7 @@ async def test_binary_sensor( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="binary_sensor_state", domain=domain, friendly_name="Window", @@ -919,7 +919,7 @@ async def test_input_boolean( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="input_boolean_state", domain=domain, friendly_name="Test", @@ -929,7 +929,7 @@ async def test_input_boolean( ) _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="input_boolean_state", domain=domain, friendly_name="Helper", @@ -949,7 +949,7 @@ async def test_light( domain = "light" _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="light_brightness_percent", domain=domain, friendly_name="Desk", @@ -960,7 +960,7 @@ async def test_light( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="light_brightness_percent", domain=domain, friendly_name="Wall", @@ -971,7 +971,7 @@ async def test_light( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="light_brightness_percent", domain=domain, friendly_name="TV", @@ -982,7 +982,7 @@ async def test_light( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="light_brightness_percent", domain=domain, friendly_name="PC", @@ -993,7 +993,7 @@ async def test_light( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="light_brightness_percent", domain=domain, friendly_name="Hallway", @@ -1013,7 +1013,7 @@ async def test_lock( domain = "lock" _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="lock_state", domain=domain, friendly_name="Front Door", @@ -1024,7 +1024,7 @@ async def test_lock( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="lock_state", domain=domain, friendly_name="Kitchen Door", @@ -1044,7 +1044,7 @@ async def test_fan( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="fan_state", domain=domain, friendly_name="Fan 1", @@ -1055,7 +1055,7 @@ async def test_fan( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="fan_speed_percent", domain=domain, friendly_name="Fan 1", @@ -1066,7 +1066,7 @@ async def test_fan( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="fan_is_oscillating", domain=domain, friendly_name="Fan 1", @@ -1077,7 +1077,7 @@ async def test_fan( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="fan_direction_reversed", domain=domain, friendly_name="Fan 1", @@ -1088,7 +1088,7 @@ async def test_fan( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="fan_preset_mode", domain=domain, friendly_name="Fan 1", @@ -1100,7 +1100,7 @@ async def test_fan( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="fan_direction_reversed", domain=domain, friendly_name="Reverse Fan", @@ -1121,7 +1121,7 @@ async def test_alarm_control_panel( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="alarm_control_panel_state", domain=domain, friendly_name="Alarm Control Panel 1", @@ -1133,7 +1133,7 @@ async def test_alarm_control_panel( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="alarm_control_panel_state", domain=domain, friendly_name="Alarm Control Panel 1", @@ -1145,7 +1145,7 @@ async def test_alarm_control_panel( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="alarm_control_panel_state", domain=domain, friendly_name="Alarm Control Panel 2", @@ -1157,7 +1157,7 @@ async def test_alarm_control_panel( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="alarm_control_panel_state", domain=domain, friendly_name="Alarm Control Panel 2", @@ -1180,7 +1180,7 @@ async def test_cover( for testcover in data: _assert_metric_present( body, - MetricInfo.from_entity_id( + TestMetricInfo.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_state", friendly_name=cover_entities[testcover].original_name, @@ -1193,7 +1193,7 @@ async def test_cover( _assert_metric_present( body, - MetricInfo.from_entity_id( + TestMetricInfo.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_state", friendly_name=cover_entities[testcover].original_name, @@ -1206,7 +1206,7 @@ async def test_cover( _assert_metric_present( body, - MetricInfo.from_entity_id( + TestMetricInfo.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_state", friendly_name=cover_entities[testcover].original_name, @@ -1219,7 +1219,7 @@ async def test_cover( _assert_metric_present( body, - MetricInfo.from_entity_id( + TestMetricInfo.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_state", friendly_name=cover_entities[testcover].original_name, @@ -1233,7 +1233,7 @@ async def test_cover( if testcover == "cover_position": _assert_metric_present( body, - MetricInfo.from_entity_id( + TestMetricInfo.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_position", friendly_name=cover_entities[testcover].original_name, @@ -1244,7 +1244,7 @@ async def test_cover( if testcover == "cover_tilt_position": _assert_metric_present( body, - MetricInfo.from_entity_id( + TestMetricInfo.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_tilt_position", friendly_name=cover_entities[testcover].original_name, @@ -1263,7 +1263,7 @@ async def test_device_tracker( domain = "device_tracker" _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="device_tracker_state", domain=domain, friendly_name="Phone", @@ -1273,7 +1273,7 @@ async def test_device_tracker( ) _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="device_tracker_state", domain=domain, friendly_name="Watch", @@ -1293,7 +1293,7 @@ async def test_counter( domain = "counter" _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="counter_value", domain=domain, friendly_name="None", @@ -1313,7 +1313,7 @@ async def test_update( domain = "update" _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="update_state", domain=domain, friendly_name="Firmware", @@ -1323,7 +1323,7 @@ async def test_update( ) _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="update_state", domain=domain, friendly_name="Addon", @@ -1347,7 +1347,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1358,7 +1358,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1369,7 +1369,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1380,7 +1380,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1391,7 +1391,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1403,7 +1403,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1451,7 +1451,7 @@ async def test_renaming_entity_name( # Check if new metrics created _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature Renamed", @@ -1462,7 +1462,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature Renamed", @@ -1473,7 +1473,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump Renamed", @@ -1485,7 +1485,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump Renamed", @@ -1498,7 +1498,7 @@ async def test_renaming_entity_name( # Keep other sensors _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1509,7 +1509,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1533,7 +1533,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1544,7 +1544,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1555,7 +1555,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1566,7 +1566,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1595,7 +1595,7 @@ async def test_renaming_entity_id( # Check if new metrics created _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1606,7 +1606,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1618,7 +1618,7 @@ async def test_renaming_entity_id( # Keep other sensors _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1628,7 +1628,7 @@ async def test_renaming_entity_id( ) _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1652,7 +1652,7 @@ async def test_deleting_entity( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1663,7 +1663,7 @@ async def test_deleting_entity( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1674,7 +1674,7 @@ async def test_deleting_entity( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1685,7 +1685,7 @@ async def test_deleting_entity( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1696,7 +1696,7 @@ async def test_deleting_entity( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1708,7 +1708,7 @@ async def test_deleting_entity( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1736,7 +1736,7 @@ async def test_deleting_entity( # Keep other sensors _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1747,7 +1747,7 @@ async def test_deleting_entity( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1773,7 +1773,7 @@ async def test_disabling_entity( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1784,7 +1784,7 @@ async def test_disabling_entity( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", @@ -1793,7 +1793,7 @@ async def test_disabling_entity( ), ) - state_change_metric_string = MetricInfo( + state_change_metric_string = TestMetricInfo( metric_name="state_change_created", domain="sensor", friendly_name="Outside Temperature", @@ -1803,7 +1803,7 @@ async def test_disabling_entity( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1814,7 +1814,7 @@ async def test_disabling_entity( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1825,7 +1825,7 @@ async def test_disabling_entity( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1837,7 +1837,7 @@ async def test_disabling_entity( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1871,7 +1871,7 @@ async def test_disabling_entity( # Keep other sensors _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1882,7 +1882,7 @@ async def test_disabling_entity( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1907,7 +1907,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1918,7 +1918,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", @@ -1929,7 +1929,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1940,7 +1940,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1951,7 +1951,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="state_change_total", domain="sensor", friendly_name="Outside Humidity", @@ -1962,7 +1962,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1982,7 +1982,7 @@ async def test_entity_becomes_unavailable_with_export( # Check that only the availability changed on sensor_1. _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1993,7 +1993,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", @@ -2004,7 +2004,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -2016,7 +2016,7 @@ async def test_entity_becomes_unavailable_with_export( # The other sensor should be unchanged. _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -2027,7 +2027,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="state_change_total", domain="sensor", friendly_name="Outside Humidity", @@ -2038,7 +2038,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -2055,7 +2055,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -2066,7 +2066,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", @@ -2077,7 +2077,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - MetricInfo( + TestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", From 90cb90b9adcdca68adb2531330502f3a96f338e6 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 15:52:00 -0700 Subject: [PATCH 45/62] Need to rename the recently renamed class --- tests/components/prometheus/test_init.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 8b2f894fc6d7ce..d9f476bdba95b8 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -1799,7 +1799,7 @@ async def test_disabling_entity( friendly_name="Outside Temperature", object_id="outside_temperature", ).get_full_metric_string() - assert any(state_change_metric_string for metric in body) + assert any(state_change_metric_string in metric for metric in body) _assert_metric_present( body, From 0eb2dad8bbca095ba7af05af260b1860852298dd Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 15:53:12 -0700 Subject: [PATCH 46/62] Was it really that easy? (No, it wasn't) --- tests/components/prometheus/test_init.py | 280 +++++++++++------------ 1 file changed, 140 insertions(+), 140 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index d9f476bdba95b8..ccad906a904060 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -88,8 +88,8 @@ @dataclass(frozen=True) -class TestMetricInfo: - """Class for all data in a single prometheus metric.""" +class EntityTestMetricInfo: + """Class for all entity data in a single prometheus metric.""" metric_name: str domain: str @@ -102,7 +102,7 @@ class TestMetricInfo: @classmethod def from_entity_id(cls, entity_id: str, **kwargs) -> Self: - """Construct TestMetricInfo using full entity_id instead of parts.""" + """Construct EntityTestMetricInfo using full entity_id instead of parts.""" domain, object_id = entity_id.split(".") return cls( metric_name=kwargs["metric_name"], @@ -142,11 +142,11 @@ def get_full_metric_string(self) -> str: ) -def _assert_metric_present(body, metric_info: TestMetricInfo) -> None: +def _assert_metric_present(body, metric_info: EntityTestMetricInfo) -> None: assert metric_info.get_full_metric_string() in body -def _assert_metric_not_present(body, metric_info: TestMetricInfo) -> None: +def _assert_metric_not_present(body, metric_info: EntityTestMetricInfo) -> None: assert metric_info.get_full_metric_string() not in body @@ -159,10 +159,10 @@ class FilterTest: def test_metric_info_generates_entity() -> None: - """Test using TestMetricInfo to format a simple metric string but with a value included.""" + """Test using EntityTestMetricInfo to format a simple metric string but with a value included.""" domain = "sensor" object_id = "outside_temperature" - metric_info = TestMetricInfo( + metric_info = EntityTestMetricInfo( metric_name="homeassistant_sensor_temperature_celsius", domain=domain, friendly_name="Outside Temperature", @@ -173,8 +173,8 @@ def test_metric_info_generates_entity() -> None: def test_metric_info_generates_metric_string_with_value() -> None: - """Test using TestMetricInfo to format a simple metric string but with a metric value included.""" - metric_info = TestMetricInfo( + """Test using EntityTestMetricInfo to format a simple metric string but with a metric value included.""" + metric_info = EntityTestMetricInfo( metric_name="homeassistant_sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -191,7 +191,7 @@ def test_metric_info_generates_metric_string_with_value() -> None: def test_metric_info_generates_info_from_entity_id() -> None: - """Test using TestMetricInfo from entity_id matches constructor TestMetricInfo.""" + """Test using EntityTestMetricInfo from entity_id matches constructor EntityTestMetricInfo.""" domain = "sensor" object_id = "outside_temperature" entity_id = f"{domain}.{object_id}" @@ -199,7 +199,7 @@ def test_metric_info_generates_info_from_entity_id() -> None: metric_name = "homeassistant_sensor_temperature_celsius" friendly_name = "Outside Temperature" metric_value = "12.3" - metric_info_from_entity_id = TestMetricInfo.from_entity_id( + metric_info_from_entity_id = EntityTestMetricInfo.from_entity_id( entity_id, metric_name=metric_name, friendly_name=friendly_name, @@ -207,7 +207,7 @@ def test_metric_info_generates_info_from_entity_id() -> None: ) assert metric_info_from_entity_id.entity == entity_id - metric_info_with_constructor = TestMetricInfo( + metric_info_with_constructor = EntityTestMetricInfo( metric_name=metric_name, domain=domain, friendly_name=friendly_name, @@ -220,8 +220,8 @@ def test_metric_info_generates_info_from_entity_id() -> None: def test_metric_info_generates_metric_string_with_mode_value() -> None: - """Test using TestMetricInfo to format a simple metric string but with a mode value included.""" - metric_info = TestMetricInfo( + """Test using EntityTestMetricInfo to format a simple metric string but with a mode value included.""" + metric_info = EntityTestMetricInfo( metric_name="climate_preset_mode", domain="climate", friendly_name="Ecobee", @@ -241,8 +241,8 @@ def test_metric_info_generates_metric_string_with_mode_value() -> None: def test_metric_info_generates_metric_string_with_action_value() -> None: - """Test using TestMetricInfo to format a simple metric string but with an action value included.""" - metric_info = TestMetricInfo( + """Test using EntityTestMetricInfo to format a simple metric string but with an action value included.""" + metric_info = EntityTestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -262,8 +262,8 @@ def test_metric_info_generates_metric_string_with_action_value() -> None: def test_metric_info_generates_metric_string_with_state_value() -> None: - """Test using TestMetricInfo to format a simple metric string but with a state value included.""" - metric_info = TestMetricInfo( + """Test using EntityTestMetricInfo to format a simple metric string but with a state value included.""" + metric_info = EntityTestMetricInfo( metric_name="cover_state", domain="cover", friendly_name="Curtain", @@ -348,7 +348,7 @@ async def test_setup_enumeration( body = await generate_latest_metrics(client) _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="homeassistant_sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -373,7 +373,7 @@ async def test_view_empty_namespace( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Radio Energy", @@ -384,7 +384,7 @@ async def test_view_empty_namespace( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="last_updated_time_seconds", domain="sensor", friendly_name="Radio Energy", @@ -409,7 +409,7 @@ async def test_view_default_namespace( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="homeassistant_sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -428,7 +428,7 @@ async def test_sensor_unit( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_unit_kwh", domain="sensor", friendly_name="Television Energy", @@ -439,7 +439,7 @@ async def test_sensor_unit( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_unit_sek_per_kwh", domain="sensor", friendly_name="Electricity price", @@ -450,7 +450,7 @@ async def test_sensor_unit( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_unit_u0xb0", domain="sensor", friendly_name="Wind Direction", @@ -461,7 +461,7 @@ async def test_sensor_unit( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_unit_u0xb5g_per_mu0xb3", domain="sensor", friendly_name="SPS30 PM <1µm Weight concentration", @@ -480,7 +480,7 @@ async def test_sensor_without_unit( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_state", domain="sensor", friendly_name="Trend Gradient", @@ -491,7 +491,7 @@ async def test_sensor_without_unit( _assert_metric_not_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_state", domain="sensor", friendly_name="Text", @@ -502,7 +502,7 @@ async def test_sensor_without_unit( _assert_metric_not_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_unit_text", domain="sensor", friendly_name="Text Unit", @@ -521,7 +521,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Fahrenheit", @@ -532,7 +532,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -543,7 +543,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -554,7 +554,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_power_kwh", domain="sensor", friendly_name="Radio Energy", @@ -565,7 +565,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_timestamp_seconds", domain="sensor", friendly_name="Timestamp", @@ -585,7 +585,7 @@ async def test_input_number( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="input_number_state", domain=domain, friendly_name="Threshold", @@ -596,7 +596,7 @@ async def test_input_number( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="input_number_state", domain=domain, friendly_name="None", @@ -607,7 +607,7 @@ async def test_input_number( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="input_number_state_celsius", domain=domain, friendly_name="Target temperature", @@ -627,7 +627,7 @@ async def test_number( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="number_state", domain=domain, friendly_name="Threshold", @@ -638,7 +638,7 @@ async def test_number( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="number_state", domain=domain, friendly_name="None", @@ -649,7 +649,7 @@ async def test_number( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="number_state_celsius", domain=domain, friendly_name="Target temperature", @@ -668,7 +668,7 @@ async def test_battery( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="battery_level_percent", domain="sensor", friendly_name="Outside Temperature", @@ -689,7 +689,7 @@ async def test_climate( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_current_temperature_celsius", domain=domain, friendly_name="HeatPump", @@ -700,7 +700,7 @@ async def test_climate( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_target_temperature_celsius", domain=domain, friendly_name="HeatPump", @@ -711,7 +711,7 @@ async def test_climate( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_target_temperature_low_celsius", domain=domain, friendly_name="Ecobee", @@ -722,7 +722,7 @@ async def test_climate( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_target_temperature_high_celsius", domain=domain, friendly_name="Ecobee", @@ -733,7 +733,7 @@ async def test_climate( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_target_temperature_celsius", domain=domain, friendly_name="Fritz!DECT", @@ -744,7 +744,7 @@ async def test_climate( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_preset_mode", domain=domain, friendly_name="Ecobee", @@ -755,7 +755,7 @@ async def test_climate( ) _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_fan_mode", domain=domain, friendly_name="Ecobee", @@ -777,7 +777,7 @@ async def test_humidifier( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="humidifier_target_humidity_percent", domain=domain, friendly_name="Humidifier", @@ -788,7 +788,7 @@ async def test_humidifier( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="humidifier_state", domain=domain, friendly_name="Dehumidifier", @@ -799,7 +799,7 @@ async def test_humidifier( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="humidifier_mode", domain=domain, friendly_name="Hygrostat", @@ -811,7 +811,7 @@ async def test_humidifier( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="humidifier_mode", domain=domain, friendly_name="Hygrostat", @@ -833,7 +833,7 @@ async def test_attributes( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="switch_state", domain=domain, friendly_name="Boolean", @@ -844,7 +844,7 @@ async def test_attributes( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="switch_attr_boolean", domain=domain, friendly_name="Boolean", @@ -855,7 +855,7 @@ async def test_attributes( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="switch_state", domain=domain, friendly_name="Number", @@ -866,7 +866,7 @@ async def test_attributes( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="switch_attr_number", domain=domain, friendly_name="Number", @@ -887,7 +887,7 @@ async def test_binary_sensor( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="binary_sensor_state", domain=domain, friendly_name="Door", @@ -898,7 +898,7 @@ async def test_binary_sensor( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="binary_sensor_state", domain=domain, friendly_name="Window", @@ -919,7 +919,7 @@ async def test_input_boolean( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="input_boolean_state", domain=domain, friendly_name="Test", @@ -929,7 +929,7 @@ async def test_input_boolean( ) _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="input_boolean_state", domain=domain, friendly_name="Helper", @@ -949,7 +949,7 @@ async def test_light( domain = "light" _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="light_brightness_percent", domain=domain, friendly_name="Desk", @@ -960,7 +960,7 @@ async def test_light( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="light_brightness_percent", domain=domain, friendly_name="Wall", @@ -971,7 +971,7 @@ async def test_light( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="light_brightness_percent", domain=domain, friendly_name="TV", @@ -982,7 +982,7 @@ async def test_light( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="light_brightness_percent", domain=domain, friendly_name="PC", @@ -993,7 +993,7 @@ async def test_light( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="light_brightness_percent", domain=domain, friendly_name="Hallway", @@ -1013,7 +1013,7 @@ async def test_lock( domain = "lock" _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="lock_state", domain=domain, friendly_name="Front Door", @@ -1024,7 +1024,7 @@ async def test_lock( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="lock_state", domain=domain, friendly_name="Kitchen Door", @@ -1044,7 +1044,7 @@ async def test_fan( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="fan_state", domain=domain, friendly_name="Fan 1", @@ -1055,7 +1055,7 @@ async def test_fan( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="fan_speed_percent", domain=domain, friendly_name="Fan 1", @@ -1066,7 +1066,7 @@ async def test_fan( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="fan_is_oscillating", domain=domain, friendly_name="Fan 1", @@ -1077,7 +1077,7 @@ async def test_fan( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="fan_direction_reversed", domain=domain, friendly_name="Fan 1", @@ -1088,7 +1088,7 @@ async def test_fan( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="fan_preset_mode", domain=domain, friendly_name="Fan 1", @@ -1100,7 +1100,7 @@ async def test_fan( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="fan_direction_reversed", domain=domain, friendly_name="Reverse Fan", @@ -1121,7 +1121,7 @@ async def test_alarm_control_panel( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="alarm_control_panel_state", domain=domain, friendly_name="Alarm Control Panel 1", @@ -1133,7 +1133,7 @@ async def test_alarm_control_panel( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="alarm_control_panel_state", domain=domain, friendly_name="Alarm Control Panel 1", @@ -1145,7 +1145,7 @@ async def test_alarm_control_panel( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="alarm_control_panel_state", domain=domain, friendly_name="Alarm Control Panel 2", @@ -1157,7 +1157,7 @@ async def test_alarm_control_panel( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="alarm_control_panel_state", domain=domain, friendly_name="Alarm Control Panel 2", @@ -1180,7 +1180,7 @@ async def test_cover( for testcover in data: _assert_metric_present( body, - TestMetricInfo.from_entity_id( + EntityTestMetricInfo.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_state", friendly_name=cover_entities[testcover].original_name, @@ -1193,7 +1193,7 @@ async def test_cover( _assert_metric_present( body, - TestMetricInfo.from_entity_id( + EntityTestMetricInfo.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_state", friendly_name=cover_entities[testcover].original_name, @@ -1206,7 +1206,7 @@ async def test_cover( _assert_metric_present( body, - TestMetricInfo.from_entity_id( + EntityTestMetricInfo.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_state", friendly_name=cover_entities[testcover].original_name, @@ -1219,7 +1219,7 @@ async def test_cover( _assert_metric_present( body, - TestMetricInfo.from_entity_id( + EntityTestMetricInfo.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_state", friendly_name=cover_entities[testcover].original_name, @@ -1233,7 +1233,7 @@ async def test_cover( if testcover == "cover_position": _assert_metric_present( body, - TestMetricInfo.from_entity_id( + EntityTestMetricInfo.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_position", friendly_name=cover_entities[testcover].original_name, @@ -1244,7 +1244,7 @@ async def test_cover( if testcover == "cover_tilt_position": _assert_metric_present( body, - TestMetricInfo.from_entity_id( + EntityTestMetricInfo.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_tilt_position", friendly_name=cover_entities[testcover].original_name, @@ -1263,7 +1263,7 @@ async def test_device_tracker( domain = "device_tracker" _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="device_tracker_state", domain=domain, friendly_name="Phone", @@ -1273,7 +1273,7 @@ async def test_device_tracker( ) _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="device_tracker_state", domain=domain, friendly_name="Watch", @@ -1293,7 +1293,7 @@ async def test_counter( domain = "counter" _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="counter_value", domain=domain, friendly_name="None", @@ -1313,7 +1313,7 @@ async def test_update( domain = "update" _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="update_state", domain=domain, friendly_name="Firmware", @@ -1323,7 +1323,7 @@ async def test_update( ) _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="update_state", domain=domain, friendly_name="Addon", @@ -1347,7 +1347,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1358,7 +1358,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1369,7 +1369,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1380,7 +1380,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1391,7 +1391,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1403,7 +1403,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1451,7 +1451,7 @@ async def test_renaming_entity_name( # Check if new metrics created _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature Renamed", @@ -1462,7 +1462,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature Renamed", @@ -1473,7 +1473,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump Renamed", @@ -1485,7 +1485,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump Renamed", @@ -1498,7 +1498,7 @@ async def test_renaming_entity_name( # Keep other sensors _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1509,7 +1509,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1533,7 +1533,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1544,7 +1544,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1555,7 +1555,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1566,7 +1566,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1595,7 +1595,7 @@ async def test_renaming_entity_id( # Check if new metrics created _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1606,7 +1606,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1618,7 +1618,7 @@ async def test_renaming_entity_id( # Keep other sensors _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1628,7 +1628,7 @@ async def test_renaming_entity_id( ) _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1652,7 +1652,7 @@ async def test_deleting_entity( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1663,7 +1663,7 @@ async def test_deleting_entity( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1674,7 +1674,7 @@ async def test_deleting_entity( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1685,7 +1685,7 @@ async def test_deleting_entity( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1696,7 +1696,7 @@ async def test_deleting_entity( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1708,7 +1708,7 @@ async def test_deleting_entity( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1736,7 +1736,7 @@ async def test_deleting_entity( # Keep other sensors _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1747,7 +1747,7 @@ async def test_deleting_entity( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1773,7 +1773,7 @@ async def test_disabling_entity( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1784,7 +1784,7 @@ async def test_disabling_entity( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", @@ -1793,7 +1793,7 @@ async def test_disabling_entity( ), ) - state_change_metric_string = TestMetricInfo( + state_change_metric_string = EntityTestMetricInfo( metric_name="state_change_created", domain="sensor", friendly_name="Outside Temperature", @@ -1803,7 +1803,7 @@ async def test_disabling_entity( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1814,7 +1814,7 @@ async def test_disabling_entity( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1825,7 +1825,7 @@ async def test_disabling_entity( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1837,7 +1837,7 @@ async def test_disabling_entity( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1871,7 +1871,7 @@ async def test_disabling_entity( # Keep other sensors _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1882,7 +1882,7 @@ async def test_disabling_entity( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1907,7 +1907,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1918,7 +1918,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", @@ -1929,7 +1929,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1940,7 +1940,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1951,7 +1951,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="state_change_total", domain="sensor", friendly_name="Outside Humidity", @@ -1962,7 +1962,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1982,7 +1982,7 @@ async def test_entity_becomes_unavailable_with_export( # Check that only the availability changed on sensor_1. _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1993,7 +1993,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", @@ -2004,7 +2004,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -2016,7 +2016,7 @@ async def test_entity_becomes_unavailable_with_export( # The other sensor should be unchanged. _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -2027,7 +2027,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="state_change_total", domain="sensor", friendly_name="Outside Humidity", @@ -2038,7 +2038,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -2055,7 +2055,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -2066,7 +2066,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", @@ -2077,7 +2077,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - TestMetricInfo( + EntityTestMetricInfo( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", From 5480b231a598a3bff8baff8f1c3532712686fff5 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 25 Sep 2024 15:56:32 -0700 Subject: [PATCH 47/62] Is this finally enough --- tests/components/prometheus/test_init.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index ccad906a904060..e09759e2ca033c 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -143,10 +143,12 @@ def get_full_metric_string(self) -> str: def _assert_metric_present(body, metric_info: EntityTestMetricInfo) -> None: + """Assert metrics text body contains metric for entity.""" assert metric_info.get_full_metric_string() in body def _assert_metric_not_present(body, metric_info: EntityTestMetricInfo) -> None: + """Assert metrics text body does not contain metric for entity.""" assert metric_info.get_full_metric_string() not in body From 2bd2a853754927f48143ee33441e289d0e9f6535 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Thu, 26 Sep 2024 00:29:47 -0700 Subject: [PATCH 48/62] Also added another full percentage point of tests --- tests/components/prometheus/test_init.py | 90 ++++++++++++++++-------- 1 file changed, 60 insertions(+), 30 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index e09759e2ca033c..9cde78f6a3607f 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -1285,6 +1285,36 @@ async def test_device_tracker( ) +@pytest.mark.parametrize("namespace", [""]) +async def test_person( + client: ClientSessionGenerator, person_entities: dict[str, er.RegistryEntry] +) -> None: + """Test prometheus metrics for person.""" + body = await generate_latest_metrics(client) + + domain = "person" + _assert_metric_present( + body, + EntityTestMetricInfo( + metric_name="person_state", + domain=domain, + friendly_name="Arthur", + object_id="arthur", + metric_value="1.0", + ), + ) + _assert_metric_present( + body, + EntityTestMetricInfo( + metric_name="person_state", + domain=domain, + friendly_name="Ford", + object_id="ford", + metric_value="0.0", + ), + ) + + @pytest.mark.parametrize("namespace", [""]) async def test_counter( client: ClientSessionGenerator, counter_entities: dict[str, er.RegistryEntry] @@ -2778,36 +2808,6 @@ async def alarm_control_panel_fixture( return data -@pytest.fixture(name="person_entities") -async def person_fixture( - hass: HomeAssistant, entity_registry: er.EntityRegistry -) -> dict[str, er.RegistryEntry]: - """Simulate person entities.""" - data = {} - person_1 = entity_registry.async_get_or_create( - domain=person.DOMAIN, - platform="test", - unique_id="person_1", - suggested_object_id="bob", - original_name="Bob", - ) - set_state_with_entry(hass, person_1, STATE_HOME) - data["person_1"] = person_1 - - person_2 = entity_registry.async_get_or_create( - domain=person.DOMAIN, - platform="test", - unique_id="person_2", - suggested_object_id="alice", - original_name="Alice", - ) - set_state_with_entry(hass, person_2, STATE_NOT_HOME) - data["person_2"] = person_2 - - await hass.async_block_till_done() - return data - - @pytest.fixture(name="device_tracker_entities") async def device_tracker_fixture( hass: HomeAssistant, entity_registry: er.EntityRegistry @@ -2838,6 +2838,36 @@ async def device_tracker_fixture( return data +@pytest.fixture(name="person_entities") +async def person_fixture( + hass: HomeAssistant, entity_registry: er.EntityRegistry +) -> dict[str, er.RegistryEntry]: + """Simulate person entities.""" + data = {} + person_1 = entity_registry.async_get_or_create( + domain=person.DOMAIN, + platform="test", + unique_id="person_1", + suggested_object_id="arthur", + original_name="Arthur", + ) + set_state_with_entry(hass, person_1, STATE_HOME) + data["person_1"] = person_1 + + person_2 = entity_registry.async_get_or_create( + domain=person.DOMAIN, + platform="test", + unique_id="person_2", + suggested_object_id="ford", + original_name="Ford", + ) + set_state_with_entry(hass, person_2, STATE_NOT_HOME) + data["person_2"] = person_2 + + await hass.async_block_till_done() + return data + + @pytest.fixture(name="counter_entities") async def counter_fixture( hass: HomeAssistant, entity_registry: er.EntityRegistry From c7648d2e6fb4035c5e58aee0b63b3d99954828c0 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Mon, 30 Sep 2024 12:39:04 -0700 Subject: [PATCH 49/62] Trying to clean things up a bit more --- tests/components/prometheus/test_init.py | 282 +++++++++++------------ 1 file changed, 141 insertions(+), 141 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 9cde78f6a3607f..47aa013f965851 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -88,7 +88,7 @@ @dataclass(frozen=True) -class EntityTestMetricInfo: +class EntityMetric: """Class for all entity data in a single prometheus metric.""" metric_name: str @@ -102,7 +102,7 @@ class EntityTestMetricInfo: @classmethod def from_entity_id(cls, entity_id: str, **kwargs) -> Self: - """Construct EntityTestMetricInfo using full entity_id instead of parts.""" + """Construct EntityMetric using full entity_id instead of parts.""" domain, object_id = entity_id.split(".") return cls( metric_name=kwargs["metric_name"], @@ -142,12 +142,12 @@ def get_full_metric_string(self) -> str: ) -def _assert_metric_present(body, metric_info: EntityTestMetricInfo) -> None: +def _assert_metric_present(body, metric_info: EntityMetric) -> None: """Assert metrics text body contains metric for entity.""" assert metric_info.get_full_metric_string() in body -def _assert_metric_not_present(body, metric_info: EntityTestMetricInfo) -> None: +def _assert_metric_not_present(body, metric_info: EntityMetric) -> None: """Assert metrics text body does not contain metric for entity.""" assert metric_info.get_full_metric_string() not in body @@ -161,10 +161,10 @@ class FilterTest: def test_metric_info_generates_entity() -> None: - """Test using EntityTestMetricInfo to format a simple metric string but with a value included.""" + """Test using EntityMetric to format a simple metric string but with a value included.""" domain = "sensor" object_id = "outside_temperature" - metric_info = EntityTestMetricInfo( + metric_info = EntityMetric( metric_name="homeassistant_sensor_temperature_celsius", domain=domain, friendly_name="Outside Temperature", @@ -175,8 +175,8 @@ def test_metric_info_generates_entity() -> None: def test_metric_info_generates_metric_string_with_value() -> None: - """Test using EntityTestMetricInfo to format a simple metric string but with a metric value included.""" - metric_info = EntityTestMetricInfo( + """Test using EntityMetric to format a simple metric string but with a metric value included.""" + metric_info = EntityMetric( metric_name="homeassistant_sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -193,7 +193,7 @@ def test_metric_info_generates_metric_string_with_value() -> None: def test_metric_info_generates_info_from_entity_id() -> None: - """Test using EntityTestMetricInfo from entity_id matches constructor EntityTestMetricInfo.""" + """Test using EntityMetric from entity_id matches constructor EntityMetric.""" domain = "sensor" object_id = "outside_temperature" entity_id = f"{domain}.{object_id}" @@ -201,7 +201,7 @@ def test_metric_info_generates_info_from_entity_id() -> None: metric_name = "homeassistant_sensor_temperature_celsius" friendly_name = "Outside Temperature" metric_value = "12.3" - metric_info_from_entity_id = EntityTestMetricInfo.from_entity_id( + metric_info_from_entity_id = EntityMetric.from_entity_id( entity_id, metric_name=metric_name, friendly_name=friendly_name, @@ -209,7 +209,7 @@ def test_metric_info_generates_info_from_entity_id() -> None: ) assert metric_info_from_entity_id.entity == entity_id - metric_info_with_constructor = EntityTestMetricInfo( + metric_info_with_constructor = EntityMetric( metric_name=metric_name, domain=domain, friendly_name=friendly_name, @@ -222,8 +222,8 @@ def test_metric_info_generates_info_from_entity_id() -> None: def test_metric_info_generates_metric_string_with_mode_value() -> None: - """Test using EntityTestMetricInfo to format a simple metric string but with a mode value included.""" - metric_info = EntityTestMetricInfo( + """Test using EntityMetric to format a simple metric string but with a mode value included.""" + metric_info = EntityMetric( metric_name="climate_preset_mode", domain="climate", friendly_name="Ecobee", @@ -243,8 +243,8 @@ def test_metric_info_generates_metric_string_with_mode_value() -> None: def test_metric_info_generates_metric_string_with_action_value() -> None: - """Test using EntityTestMetricInfo to format a simple metric string but with an action value included.""" - metric_info = EntityTestMetricInfo( + """Test using EntityMetric to format a simple metric string but with an action value included.""" + metric_info = EntityMetric( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -264,8 +264,8 @@ def test_metric_info_generates_metric_string_with_action_value() -> None: def test_metric_info_generates_metric_string_with_state_value() -> None: - """Test using EntityTestMetricInfo to format a simple metric string but with a state value included.""" - metric_info = EntityTestMetricInfo( + """Test using EntityMetric to format a simple metric string but with a state value included.""" + metric_info = EntityMetric( metric_name="cover_state", domain="cover", friendly_name="Curtain", @@ -350,7 +350,7 @@ async def test_setup_enumeration( body = await generate_latest_metrics(client) _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="homeassistant_sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -375,7 +375,7 @@ async def test_view_empty_namespace( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Radio Energy", @@ -386,7 +386,7 @@ async def test_view_empty_namespace( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="last_updated_time_seconds", domain="sensor", friendly_name="Radio Energy", @@ -411,7 +411,7 @@ async def test_view_default_namespace( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="homeassistant_sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -430,7 +430,7 @@ async def test_sensor_unit( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_unit_kwh", domain="sensor", friendly_name="Television Energy", @@ -441,7 +441,7 @@ async def test_sensor_unit( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_unit_sek_per_kwh", domain="sensor", friendly_name="Electricity price", @@ -452,7 +452,7 @@ async def test_sensor_unit( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_unit_u0xb0", domain="sensor", friendly_name="Wind Direction", @@ -463,7 +463,7 @@ async def test_sensor_unit( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_unit_u0xb5g_per_mu0xb3", domain="sensor", friendly_name="SPS30 PM <1µm Weight concentration", @@ -482,7 +482,7 @@ async def test_sensor_without_unit( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_state", domain="sensor", friendly_name="Trend Gradient", @@ -493,7 +493,7 @@ async def test_sensor_without_unit( _assert_metric_not_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_state", domain="sensor", friendly_name="Text", @@ -504,7 +504,7 @@ async def test_sensor_without_unit( _assert_metric_not_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_unit_text", domain="sensor", friendly_name="Text Unit", @@ -523,7 +523,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Fahrenheit", @@ -534,7 +534,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -545,7 +545,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -556,7 +556,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_power_kwh", domain="sensor", friendly_name="Radio Energy", @@ -567,7 +567,7 @@ async def test_sensor_device_class( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_timestamp_seconds", domain="sensor", friendly_name="Timestamp", @@ -587,7 +587,7 @@ async def test_input_number( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="input_number_state", domain=domain, friendly_name="Threshold", @@ -598,7 +598,7 @@ async def test_input_number( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="input_number_state", domain=domain, friendly_name="None", @@ -609,7 +609,7 @@ async def test_input_number( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="input_number_state_celsius", domain=domain, friendly_name="Target temperature", @@ -629,7 +629,7 @@ async def test_number( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="number_state", domain=domain, friendly_name="Threshold", @@ -640,7 +640,7 @@ async def test_number( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="number_state", domain=domain, friendly_name="None", @@ -651,7 +651,7 @@ async def test_number( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="number_state_celsius", domain=domain, friendly_name="Target temperature", @@ -670,7 +670,7 @@ async def test_battery( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="battery_level_percent", domain="sensor", friendly_name="Outside Temperature", @@ -691,7 +691,7 @@ async def test_climate( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_current_temperature_celsius", domain=domain, friendly_name="HeatPump", @@ -702,7 +702,7 @@ async def test_climate( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_target_temperature_celsius", domain=domain, friendly_name="HeatPump", @@ -713,7 +713,7 @@ async def test_climate( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_target_temperature_low_celsius", domain=domain, friendly_name="Ecobee", @@ -724,7 +724,7 @@ async def test_climate( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_target_temperature_high_celsius", domain=domain, friendly_name="Ecobee", @@ -735,7 +735,7 @@ async def test_climate( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_target_temperature_celsius", domain=domain, friendly_name="Fritz!DECT", @@ -746,7 +746,7 @@ async def test_climate( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_preset_mode", domain=domain, friendly_name="Ecobee", @@ -757,7 +757,7 @@ async def test_climate( ) _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_fan_mode", domain=domain, friendly_name="Ecobee", @@ -779,7 +779,7 @@ async def test_humidifier( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="humidifier_target_humidity_percent", domain=domain, friendly_name="Humidifier", @@ -790,7 +790,7 @@ async def test_humidifier( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="humidifier_state", domain=domain, friendly_name="Dehumidifier", @@ -801,7 +801,7 @@ async def test_humidifier( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="humidifier_mode", domain=domain, friendly_name="Hygrostat", @@ -813,7 +813,7 @@ async def test_humidifier( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="humidifier_mode", domain=domain, friendly_name="Hygrostat", @@ -835,7 +835,7 @@ async def test_attributes( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="switch_state", domain=domain, friendly_name="Boolean", @@ -846,7 +846,7 @@ async def test_attributes( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="switch_attr_boolean", domain=domain, friendly_name="Boolean", @@ -857,7 +857,7 @@ async def test_attributes( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="switch_state", domain=domain, friendly_name="Number", @@ -868,7 +868,7 @@ async def test_attributes( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="switch_attr_number", domain=domain, friendly_name="Number", @@ -889,7 +889,7 @@ async def test_binary_sensor( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="binary_sensor_state", domain=domain, friendly_name="Door", @@ -900,7 +900,7 @@ async def test_binary_sensor( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="binary_sensor_state", domain=domain, friendly_name="Window", @@ -921,7 +921,7 @@ async def test_input_boolean( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="input_boolean_state", domain=domain, friendly_name="Test", @@ -931,7 +931,7 @@ async def test_input_boolean( ) _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="input_boolean_state", domain=domain, friendly_name="Helper", @@ -951,7 +951,7 @@ async def test_light( domain = "light" _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="light_brightness_percent", domain=domain, friendly_name="Desk", @@ -962,7 +962,7 @@ async def test_light( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="light_brightness_percent", domain=domain, friendly_name="Wall", @@ -973,7 +973,7 @@ async def test_light( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="light_brightness_percent", domain=domain, friendly_name="TV", @@ -984,7 +984,7 @@ async def test_light( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="light_brightness_percent", domain=domain, friendly_name="PC", @@ -995,7 +995,7 @@ async def test_light( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="light_brightness_percent", domain=domain, friendly_name="Hallway", @@ -1015,7 +1015,7 @@ async def test_lock( domain = "lock" _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="lock_state", domain=domain, friendly_name="Front Door", @@ -1026,7 +1026,7 @@ async def test_lock( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="lock_state", domain=domain, friendly_name="Kitchen Door", @@ -1046,7 +1046,7 @@ async def test_fan( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="fan_state", domain=domain, friendly_name="Fan 1", @@ -1057,7 +1057,7 @@ async def test_fan( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="fan_speed_percent", domain=domain, friendly_name="Fan 1", @@ -1068,7 +1068,7 @@ async def test_fan( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="fan_is_oscillating", domain=domain, friendly_name="Fan 1", @@ -1079,7 +1079,7 @@ async def test_fan( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="fan_direction_reversed", domain=domain, friendly_name="Fan 1", @@ -1090,7 +1090,7 @@ async def test_fan( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="fan_preset_mode", domain=domain, friendly_name="Fan 1", @@ -1102,7 +1102,7 @@ async def test_fan( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="fan_direction_reversed", domain=domain, friendly_name="Reverse Fan", @@ -1123,7 +1123,7 @@ async def test_alarm_control_panel( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="alarm_control_panel_state", domain=domain, friendly_name="Alarm Control Panel 1", @@ -1135,7 +1135,7 @@ async def test_alarm_control_panel( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="alarm_control_panel_state", domain=domain, friendly_name="Alarm Control Panel 1", @@ -1147,7 +1147,7 @@ async def test_alarm_control_panel( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="alarm_control_panel_state", domain=domain, friendly_name="Alarm Control Panel 2", @@ -1159,7 +1159,7 @@ async def test_alarm_control_panel( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="alarm_control_panel_state", domain=domain, friendly_name="Alarm Control Panel 2", @@ -1182,7 +1182,7 @@ async def test_cover( for testcover in data: _assert_metric_present( body, - EntityTestMetricInfo.from_entity_id( + EntityMetric.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_state", friendly_name=cover_entities[testcover].original_name, @@ -1195,7 +1195,7 @@ async def test_cover( _assert_metric_present( body, - EntityTestMetricInfo.from_entity_id( + EntityMetric.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_state", friendly_name=cover_entities[testcover].original_name, @@ -1208,7 +1208,7 @@ async def test_cover( _assert_metric_present( body, - EntityTestMetricInfo.from_entity_id( + EntityMetric.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_state", friendly_name=cover_entities[testcover].original_name, @@ -1221,7 +1221,7 @@ async def test_cover( _assert_metric_present( body, - EntityTestMetricInfo.from_entity_id( + EntityMetric.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_state", friendly_name=cover_entities[testcover].original_name, @@ -1235,7 +1235,7 @@ async def test_cover( if testcover == "cover_position": _assert_metric_present( body, - EntityTestMetricInfo.from_entity_id( + EntityMetric.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_position", friendly_name=cover_entities[testcover].original_name, @@ -1246,7 +1246,7 @@ async def test_cover( if testcover == "cover_tilt_position": _assert_metric_present( body, - EntityTestMetricInfo.from_entity_id( + EntityMetric.from_entity_id( cover_entities[testcover].entity_id, metric_name="cover_tilt_position", friendly_name=cover_entities[testcover].original_name, @@ -1265,7 +1265,7 @@ async def test_device_tracker( domain = "device_tracker" _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="device_tracker_state", domain=domain, friendly_name="Phone", @@ -1275,7 +1275,7 @@ async def test_device_tracker( ) _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="device_tracker_state", domain=domain, friendly_name="Watch", @@ -1295,7 +1295,7 @@ async def test_person( domain = "person" _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="person_state", domain=domain, friendly_name="Arthur", @@ -1305,7 +1305,7 @@ async def test_person( ) _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="person_state", domain=domain, friendly_name="Ford", @@ -1325,7 +1325,7 @@ async def test_counter( domain = "counter" _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="counter_value", domain=domain, friendly_name="None", @@ -1345,7 +1345,7 @@ async def test_update( domain = "update" _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="update_state", domain=domain, friendly_name="Firmware", @@ -1355,7 +1355,7 @@ async def test_update( ) _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="update_state", domain=domain, friendly_name="Addon", @@ -1379,7 +1379,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1390,7 +1390,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1401,7 +1401,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1412,7 +1412,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1423,7 +1423,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1435,7 +1435,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1483,7 +1483,7 @@ async def test_renaming_entity_name( # Check if new metrics created _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature Renamed", @@ -1494,7 +1494,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature Renamed", @@ -1505,7 +1505,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_action", domain="climate", friendly_name="HeatPump Renamed", @@ -1517,7 +1517,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_action", domain="climate", friendly_name="HeatPump Renamed", @@ -1530,7 +1530,7 @@ async def test_renaming_entity_name( # Keep other sensors _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1541,7 +1541,7 @@ async def test_renaming_entity_name( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1565,7 +1565,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1576,7 +1576,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1587,7 +1587,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1598,7 +1598,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1627,7 +1627,7 @@ async def test_renaming_entity_id( # Check if new metrics created _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1638,7 +1638,7 @@ async def test_renaming_entity_id( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1650,7 +1650,7 @@ async def test_renaming_entity_id( # Keep other sensors _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1660,7 +1660,7 @@ async def test_renaming_entity_id( ) _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1684,7 +1684,7 @@ async def test_deleting_entity( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1695,7 +1695,7 @@ async def test_deleting_entity( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1706,7 +1706,7 @@ async def test_deleting_entity( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1717,7 +1717,7 @@ async def test_deleting_entity( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1728,7 +1728,7 @@ async def test_deleting_entity( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1740,7 +1740,7 @@ async def test_deleting_entity( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1768,7 +1768,7 @@ async def test_deleting_entity( # Keep other sensors _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1779,7 +1779,7 @@ async def test_deleting_entity( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1805,7 +1805,7 @@ async def test_disabling_entity( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1816,7 +1816,7 @@ async def test_disabling_entity( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", @@ -1825,7 +1825,7 @@ async def test_disabling_entity( ), ) - state_change_metric_string = EntityTestMetricInfo( + state_change_metric_string = EntityMetric( metric_name="state_change_created", domain="sensor", friendly_name="Outside Temperature", @@ -1835,7 +1835,7 @@ async def test_disabling_entity( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1846,7 +1846,7 @@ async def test_disabling_entity( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1857,7 +1857,7 @@ async def test_disabling_entity( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1869,7 +1869,7 @@ async def test_disabling_entity( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="climate_action", domain="climate", friendly_name="HeatPump", @@ -1903,7 +1903,7 @@ async def test_disabling_entity( # Keep other sensors _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1914,7 +1914,7 @@ async def test_disabling_entity( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -1939,7 +1939,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -1950,7 +1950,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", @@ -1961,7 +1961,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -1972,7 +1972,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -1983,7 +1983,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="state_change_total", domain="sensor", friendly_name="Outside Humidity", @@ -1994,7 +1994,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -2014,7 +2014,7 @@ async def test_entity_becomes_unavailable_with_export( # Check that only the availability changed on sensor_1. _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -2025,7 +2025,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", @@ -2036,7 +2036,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", @@ -2048,7 +2048,7 @@ async def test_entity_becomes_unavailable_with_export( # The other sensor should be unchanged. _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", @@ -2059,7 +2059,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="state_change_total", domain="sensor", friendly_name="Outside Humidity", @@ -2070,7 +2070,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", @@ -2087,7 +2087,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", @@ -2098,7 +2098,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", @@ -2109,7 +2109,7 @@ async def test_entity_becomes_unavailable_with_export( _assert_metric_present( body, - EntityTestMetricInfo( + EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", From 04d991c953c01faa4025fcf8af57f7115d8a3cff Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Mon, 30 Sep 2024 14:22:18 -0700 Subject: [PATCH 50/62] Now how does this look? --- tests/components/prometheus/test_init.py | 2279 +++++++++------------- 1 file changed, 873 insertions(+), 1406 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 47aa013f965851..00063f113779cc 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -3,11 +3,12 @@ from dataclasses import dataclass import datetime from http import HTTPStatus -from typing import Any, Self +from typing import Any from unittest import mock from freezegun import freeze_time import prometheus_client +from prometheus_client.utils import floatToGoString import pytest from homeassistant.components import ( @@ -87,69 +88,62 @@ PROMETHEUS_PATH = "homeassistant.components.prometheus" -@dataclass(frozen=True) class EntityMetric: - """Class for all entity data in a single prometheus metric.""" + """Represents a Prometheus metric for a Home Assistant entity.""" metric_name: str - domain: str - friendly_name: str - object_id: str - metric_value: Any | None = None - mode: str | None = None - state: str | None = None - action: str | None = None - - @classmethod - def from_entity_id(cls, entity_id: str, **kwargs) -> Self: - """Construct EntityMetric using full entity_id instead of parts.""" - domain, object_id = entity_id.split(".") - return cls( - metric_name=kwargs["metric_name"], - domain=domain, - friendly_name=kwargs["friendly_name"], - object_id=object_id, - metric_value=kwargs.get("metric_value"), - mode=kwargs.get("mode"), - state=kwargs.get("state"), - action=kwargs.get("action"), - ) + labels: dict[str, str] + + def __init__(self, metric_name: str, **kwargs) -> None: + """Create a new EntityMetric based on metric name and labels.""" + self.metric_name = metric_name + self.labels = kwargs + + # Labels that are required for all entities. + for labelname in ("domain", "friendly_name", "entity"): + assert labelname in self.labels + assert self.labels[labelname] != "" + + def withValue(self, value: float): + """Return a metric with value.""" + return EntityMetricWithValue(self, value) @property - def entity(self) -> str: - """Generate entity_id from components.""" - return f"{self.domain}.{self.object_id}" - - def get_full_metric_string(self) -> str: - """Convert metric info into a valid prometheus text string.""" - final_metric_value = ( - f" {self.metric_value}" if self.metric_value is not None else "" - ) - final_action_value = ( - f'action="{self.action}",' if self.action is not None else "" - ) - final_mode_value = f',mode="{self.mode}"' if self.mode is not None else "" - final_state_value = f',state="{self.state}"' if self.state is not None else "" - return ( - f"{self.metric_name}{{" - f"{final_action_value}" - f'domain="{self.domain}",' - f'entity="{self.entity}",' - f'friendly_name="{self.friendly_name}"' - f"{final_mode_value}" - f"{final_state_value}" - f"}}{final_metric_value}" + def _metric_name_string(self) -> str: + """Return a full metric name as a string.""" + labels = ",".join( + f'{key}="{value}"' for key, value in sorted(self.labels.items()) ) + return f"{self.metric_name}{{{labels}}}" + + def assertInBody(self, body: list[str]): + """Assert that this metric exists in the provided Prometheus output.""" + assert any(line.startswith(self._metric_name_string) for line in body) + def assertNotInBody(self, body: list[str]): + """Assert that this metric does not exist in Prometheus output.""" + assert self._metric_name_string not in body -def _assert_metric_present(body, metric_info: EntityMetric) -> None: - """Assert metrics text body contains metric for entity.""" - assert metric_info.get_full_metric_string() in body +class EntityMetricWithValue(EntityMetric): + """Represents a Prometheus metric with a value.""" -def _assert_metric_not_present(body, metric_info: EntityMetric) -> None: - """Assert metrics text body does not contain metric for entity.""" - assert metric_info.get_full_metric_string() not in body + value: float + + def __init__(self, metric: EntityMetric, value: float) -> None: + """Create a new metric with a value based on a metric.""" + super().__init__(metric.metric_name, **metric.labels) + self.value = value + + @property + def _metric_string(self) -> str: + """Return a full metric string.""" + value = floatToGoString(self.value) + return f"{self._metric_name_string} {value}" + + def assertInBody(self, body: list[str]): + """Assert that this metric exists in the provided Prometheus output.""" + assert self._metric_string in body @dataclass @@ -160,78 +154,53 @@ class FilterTest: should_pass: bool -def test_metric_info_generates_entity() -> None: - """Test using EntityMetric to format a simple metric string but with a value included.""" +def test_entity_metric_generates_metric_name_string_without_value() -> None: + """Test using EntityMetric to format a simple metric string without any value.""" domain = "sensor" object_id = "outside_temperature" - metric_info = EntityMetric( + entity_metric = EntityMetric( metric_name="homeassistant_sensor_temperature_celsius", domain=domain, friendly_name="Outside Temperature", - object_id=object_id, - metric_value=12.3, + entity=f"{domain}.{object_id}", ) - assert metric_info.entity == f"{domain}.{object_id}" - - -def test_metric_info_generates_metric_string_with_value() -> None: - """Test using EntityMetric to format a simple metric string but with a metric value included.""" - metric_info = EntityMetric( - metric_name="homeassistant_sensor_temperature_celsius", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value=17.2, - ) - assert metric_info.get_full_metric_string() == ( + assert entity_metric._metric_name_string == ( "homeassistant_sensor_temperature_celsius{" 'domain="sensor",' 'entity="sensor.outside_temperature",' 'friendly_name="Outside Temperature"}' - " 17.2" ) -def test_metric_info_generates_info_from_entity_id() -> None: - """Test using EntityMetric from entity_id matches constructor EntityMetric.""" +def test_entity_metric_generates_metric_string_with_value() -> None: + """Test using EntityMetric to format a simple metric string but with a metric value included.""" domain = "sensor" object_id = "outside_temperature" - entity_id = f"{domain}.{object_id}" - assert f"{domain}.{object_id}" == entity_id - metric_name = "homeassistant_sensor_temperature_celsius" - friendly_name = "Outside Temperature" - metric_value = "12.3" - metric_info_from_entity_id = EntityMetric.from_entity_id( - entity_id, - metric_name=metric_name, - friendly_name=friendly_name, - metric_value=metric_value, - ) - assert metric_info_from_entity_id.entity == entity_id - - metric_info_with_constructor = EntityMetric( - metric_name=metric_name, + entity_metric = EntityMetric( + metric_name="homeassistant_sensor_temperature_celsius", domain=domain, - friendly_name=friendly_name, - object_id=object_id, - metric_value=metric_value, + friendly_name="Outside Temperature", + entity=f"{domain}.{object_id}", + ).withValue(17.2) + assert entity_metric._metric_string == ( + "homeassistant_sensor_temperature_celsius{" + 'domain="sensor",' + 'entity="sensor.outside_temperature",' + 'friendly_name="Outside Temperature"}' + " 17.2" ) - assert metric_info_with_constructor.entity == entity_id - assert metric_info_from_entity_id == metric_info_with_constructor - -def test_metric_info_generates_metric_string_with_mode_value() -> None: +def test_entity_metric_generates_metric_string_with_mode_value() -> None: """Test using EntityMetric to format a simple metric string but with a mode value included.""" - metric_info = EntityMetric( + entity_metric = EntityMetric( metric_name="climate_preset_mode", domain="climate", friendly_name="Ecobee", - object_id="ecobee", - metric_value="1.0", + entity="climate.ecobee", mode="away", - ) - assert metric_info.get_full_metric_string() == ( + ).withValue(1.0) + assert entity_metric._metric_string == ( "climate_preset_mode{" 'domain="climate",' 'entity="climate.ecobee",' @@ -242,17 +211,16 @@ def test_metric_info_generates_metric_string_with_mode_value() -> None: ) -def test_metric_info_generates_metric_string_with_action_value() -> None: +def test_entity_metric_generates_metric_string_with_action_value() -> None: """Test using EntityMetric to format a simple metric string but with an action value included.""" - metric_info = EntityMetric( + entity_metric = EntityMetric( metric_name="climate_action", domain="climate", friendly_name="HeatPump", - object_id="heatpump", - metric_value="1.0", + entity="climate.heatpump", action="heating", - ) - assert metric_info.get_full_metric_string() == ( + ).withValue(1.0) + assert entity_metric._metric_string == ( "climate_action{" 'action="heating",' 'domain="climate",' @@ -263,17 +231,16 @@ def test_metric_info_generates_metric_string_with_action_value() -> None: ) -def test_metric_info_generates_metric_string_with_state_value() -> None: +def test_entity_metric_generates_metric_string_with_state_value() -> None: """Test using EntityMetric to format a simple metric string but with a state value included.""" - metric_info = EntityMetric( + entity_metric = EntityMetric( metric_name="cover_state", domain="cover", friendly_name="Curtain", - object_id="curtain", - metric_value="1.0", + entity="cover.curtain", state="open", - ) - assert metric_info.get_full_metric_string() == ( + ).withValue(1.0) + assert entity_metric._metric_string == ( "cover_state{" 'domain="cover",' 'entity="cover.curtain",' @@ -348,16 +315,12 @@ async def test_setup_enumeration( client = await hass_client() body = await generate_latest_metrics(client) - _assert_metric_present( - body, - EntityMetric( - metric_name="homeassistant_sensor_temperature_celsius", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value=state, - ), - ) + EntityMetric( + metric_name="homeassistant_sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(state).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -373,27 +336,19 @@ async def test_view_empty_namespace( "Objects collected during gc" in body ) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Radio Energy", - object_id="radio_energy", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Radio Energy", + entity="sensor.radio_energy", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="last_updated_time_seconds", - domain="sensor", - friendly_name="Radio Energy", - object_id="radio_energy", - metric_value="86400.0", - ), - ) + EntityMetric( + metric_name="last_updated_time_seconds", + domain="sensor", + friendly_name="Radio Energy", + entity="sensor.radio_energy", + ).withValue(86400.0).assertInBody(body) @pytest.mark.parametrize("namespace", [None]) @@ -409,16 +364,12 @@ async def test_view_default_namespace( "Objects collected during gc" in body ) - _assert_metric_present( - body, - EntityMetric( - metric_name="homeassistant_sensor_temperature_celsius", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="15.6", - ), - ) + EntityMetric( + metric_name="homeassistant_sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(15.6).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -428,49 +379,33 @@ async def test_sensor_unit( """Test prometheus metrics for sensors with a unit.""" body = await generate_latest_metrics(client) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_unit_kwh", - domain="sensor", - friendly_name="Television Energy", - object_id="television_energy", - metric_value="74.0", - ), - ) + EntityMetric( + metric_name="sensor_unit_kwh", + domain="sensor", + friendly_name="Television Energy", + entity="sensor.television_energy", + ).withValue(74.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_unit_sek_per_kwh", - domain="sensor", - friendly_name="Electricity price", - object_id="electricity_price", - metric_value="0.123", - ), - ) + EntityMetric( + metric_name="sensor_unit_sek_per_kwh", + domain="sensor", + friendly_name="Electricity price", + entity="sensor.electricity_price", + ).withValue(0.123).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_unit_u0xb0", - domain="sensor", - friendly_name="Wind Direction", - object_id="wind_direction", - metric_value="25.0", - ), - ) + EntityMetric( + metric_name="sensor_unit_u0xb0", + domain="sensor", + friendly_name="Wind Direction", + entity="sensor.wind_direction", + ).withValue(25.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_unit_u0xb5g_per_mu0xb3", - domain="sensor", - friendly_name="SPS30 PM <1µm Weight concentration", - object_id="sps30_pm_1um_weight_concentration", - metric_value="3.7069", - ), - ) + EntityMetric( + metric_name="sensor_unit_u0xb5g_per_mu0xb3", + domain="sensor", + friendly_name="SPS30 PM <1µm Weight concentration", + entity="sensor.sps30_pm_1um_weight_concentration", + ).withValue(3.7069).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -480,38 +415,26 @@ async def test_sensor_without_unit( """Test prometheus metrics for sensors without a unit.""" body = await generate_latest_metrics(client) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_state", - domain="sensor", - friendly_name="Trend Gradient", - object_id="trend_gradient", - metric_value="0.002", - ), - ) + EntityMetric( + metric_name="sensor_state", + domain="sensor", + friendly_name="Trend Gradient", + entity="sensor.trend_gradient", + ).withValue(0.002).assertInBody(body) - _assert_metric_not_present( - body, - EntityMetric( - metric_name="sensor_state", - domain="sensor", - friendly_name="Text", - object_id="text", - metric_value="0", - ), - ) + EntityMetric( + metric_name="sensor_state", + domain="sensor", + friendly_name="Text", + entity="sensor.text", + ).withValue(0.0).assertNotInBody(body) - _assert_metric_not_present( - body, - EntityMetric( - metric_name="sensor_unit_text", - domain="sensor", - friendly_name="Text Unit", - object_id="text_unit", - metric_value="0", - ), - ) + EntityMetric( + metric_name="sensor_unit_text", + domain="sensor", + friendly_name="Text Unit", + entity="sensor.text_unit", + ).withValue(0.0).assertNotInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -521,60 +444,40 @@ async def test_sensor_device_class( """Test prometheus metrics for sensor with a device_class.""" body = await generate_latest_metrics(client) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_temperature_celsius", - domain="sensor", - friendly_name="Fahrenheit", - object_id="fahrenheit", - metric_value="10.0", - ), - ) + EntityMetric( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Fahrenheit", + entity="sensor.fahrenheit", + ).withValue(10.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_temperature_celsius", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="15.6", - ), - ) + EntityMetric( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(15.6).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_humidity_percent", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="54.0", - ), - ) + EntityMetric( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(54.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_power_kwh", - domain="sensor", - friendly_name="Radio Energy", - object_id="radio_energy", - metric_value="14.0", - ), - ) + EntityMetric( + metric_name="sensor_power_kwh", + domain="sensor", + friendly_name="Radio Energy", + entity="sensor.radio_energy", + ).withValue(14.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_timestamp_seconds", - domain="sensor", - friendly_name="Timestamp", - object_id="timestamp", - metric_value="1.691445808136036e+09", - ), - ) + EntityMetric( + metric_name="sensor_timestamp_seconds", + domain="sensor", + friendly_name="Timestamp", + entity="sensor.timestamp", + ).withValue(1.691445808136036e09).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -583,40 +486,27 @@ async def test_input_number( ) -> None: """Test prometheus metrics for input_number.""" body = await generate_latest_metrics(client) - domain = "input_number" - _assert_metric_present( - body, - EntityMetric( - metric_name="input_number_state", - domain=domain, - friendly_name="Threshold", - object_id="threshold", - metric_value="5.2", - ), - ) + EntityMetric( + metric_name="input_number_state", + domain="input_number", + friendly_name="Threshold", + entity="input_number.threshold", + ).withValue(5.2).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="input_number_state", - domain=domain, - friendly_name="None", - object_id="brightness", - metric_value="60.0", - ), - ) + EntityMetric( + metric_name="input_number_state", + domain="input_number", + friendly_name="None", + entity="input_number.brightness", + ).withValue(60.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="input_number_state_celsius", - domain=domain, - friendly_name="Target temperature", - object_id="target_temperature", - metric_value="22.7", - ), - ) + EntityMetric( + metric_name="input_number_state_celsius", + domain="input_number", + friendly_name="Target temperature", + entity="input_number.target_temperature", + ).withValue(22.7).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -625,40 +515,27 @@ async def test_number( ) -> None: """Test prometheus metrics for number.""" body = await generate_latest_metrics(client) - domain = "number" - _assert_metric_present( - body, - EntityMetric( - metric_name="number_state", - domain=domain, - friendly_name="Threshold", - object_id="threshold", - metric_value="5.2", - ), - ) + EntityMetric( + metric_name="number_state", + domain="number", + friendly_name="Threshold", + entity="number.threshold", + ).withValue(5.2).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="number_state", - domain=domain, - friendly_name="None", - object_id="brightness", - metric_value="60.0", - ), - ) + EntityMetric( + metric_name="number_state", + domain="number", + friendly_name="None", + entity="number.brightness", + ).withValue(60.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="number_state_celsius", - domain=domain, - friendly_name="Target temperature", - object_id="target_temperature", - metric_value="22.7", - ), - ) + EntityMetric( + metric_name="number_state_celsius", + domain="number", + friendly_name="Target temperature", + entity="number.target_temperature", + ).withValue(22.7).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -668,16 +545,12 @@ async def test_battery( """Test prometheus metrics for battery.""" body = await generate_latest_metrics(client) - _assert_metric_present( - body, - EntityMetric( - metric_name="battery_level_percent", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="12.0", - ), - ) + EntityMetric( + metric_name="battery_level_percent", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(12.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -687,85 +560,57 @@ async def test_climate( ) -> None: """Test prometheus metrics for climate entities.""" body = await generate_latest_metrics(client) - domain = "climate" - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_current_temperature_celsius", - domain=domain, - friendly_name="HeatPump", - object_id="heatpump", - metric_value="25.0", - ), - ) + EntityMetric( + metric_name="climate_current_temperature_celsius", + domain="climate", + friendly_name="HeatPump", + entity="climate.heatpump", + ).withValue(25.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_target_temperature_celsius", - domain=domain, - friendly_name="HeatPump", - object_id="heatpump", - metric_value="20.0", - ), - ) + EntityMetric( + metric_name="climate_target_temperature_celsius", + domain="climate", + friendly_name="HeatPump", + entity="climate.heatpump", + ).withValue(20.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_target_temperature_low_celsius", - domain=domain, - friendly_name="Ecobee", - object_id="ecobee", - metric_value="21.0", - ), - ) + EntityMetric( + metric_name="climate_target_temperature_low_celsius", + domain="climate", + friendly_name="Ecobee", + entity="climate.ecobee", + ).withValue(21.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_target_temperature_high_celsius", - domain=domain, - friendly_name="Ecobee", - object_id="ecobee", - metric_value="24.0", - ), - ) + EntityMetric( + metric_name="climate_target_temperature_high_celsius", + domain="climate", + friendly_name="Ecobee", + entity="climate.ecobee", + ).withValue(24.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_target_temperature_celsius", - domain=domain, - friendly_name="Fritz!DECT", - object_id="fritzdect", - metric_value="0.0", - ), - ) + EntityMetric( + metric_name="climate_target_temperature_celsius", + domain="climate", + friendly_name="Fritz!DECT", + entity="climate.fritzdect", + ).withValue(0.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_preset_mode", - domain=domain, - friendly_name="Ecobee", - object_id="ecobee", - metric_value="1.0", - mode="away", - ), - ) - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_fan_mode", - domain=domain, - friendly_name="Ecobee", - object_id="ecobee", - metric_value="1.0", - mode="auto", - ), - ) + EntityMetric( + metric_name="climate_preset_mode", + domain="climate", + friendly_name="Ecobee", + entity="climate.ecobee", + mode="away", + ).withValue(1.0).assertInBody(body) + + EntityMetric( + metric_name="climate_fan_mode", + domain="climate", + friendly_name="Ecobee", + entity="climate.ecobee", + mode="auto", + ).withValue(1.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -775,53 +620,36 @@ async def test_humidifier( ) -> None: """Test prometheus metrics for humidifier entities.""" body = await generate_latest_metrics(client) - domain = "humidifier" - _assert_metric_present( - body, - EntityMetric( - metric_name="humidifier_target_humidity_percent", - domain=domain, - friendly_name="Humidifier", - object_id="humidifier", - metric_value="68.0", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="humidifier_state", - domain=domain, - friendly_name="Dehumidifier", - object_id="dehumidifier", - metric_value="1.0", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="humidifier_mode", - domain=domain, - friendly_name="Hygrostat", - object_id="hygrostat", - metric_value="1.0", - mode="home", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="humidifier_mode", - domain=domain, - friendly_name="Hygrostat", - object_id="hygrostat", - metric_value="0.0", - mode="eco", - ), - ) + EntityMetric( + metric_name="humidifier_target_humidity_percent", + domain="humidifier", + friendly_name="Humidifier", + entity="humidifier.humidifier", + ).withValue(68.0).assertInBody(body) + + EntityMetric( + metric_name="humidifier_state", + domain="humidifier", + friendly_name="Dehumidifier", + entity="humidifier.dehumidifier", + ).withValue(1.0).assertInBody(body) + + EntityMetric( + metric_name="humidifier_mode", + domain="humidifier", + friendly_name="Hygrostat", + entity="humidifier.hygrostat", + mode="home", + ).withValue(1.0).assertInBody(body) + + EntityMetric( + metric_name="humidifier_mode", + domain="humidifier", + friendly_name="Hygrostat", + entity="humidifier.hygrostat", + mode="eco", + ).withValue(0.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -831,51 +659,34 @@ async def test_attributes( ) -> None: """Test prometheus metrics for entity attributes.""" body = await generate_latest_metrics(client) - domain = "switch" - - _assert_metric_present( - body, - EntityMetric( - metric_name="switch_state", - domain=domain, - friendly_name="Boolean", - object_id="boolean", - metric_value="1.0", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="switch_attr_boolean", - domain=domain, - friendly_name="Boolean", - object_id="boolean", - metric_value="1.0", - ), - ) - _assert_metric_present( - body, - EntityMetric( - metric_name="switch_state", - domain=domain, - friendly_name="Number", - object_id="number", - metric_value="0.0", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="switch_attr_number", - domain=domain, - friendly_name="Number", - object_id="number", - metric_value="10.2", - ), - ) + EntityMetric( + metric_name="switch_state", + domain="switch", + friendly_name="Boolean", + entity="switch.boolean", + ).withValue(1.0).assertInBody(body) + + EntityMetric( + metric_name="switch_attr_boolean", + domain="switch", + friendly_name="Boolean", + entity="switch.boolean", + ).withValue(1.0).assertInBody(body) + + EntityMetric( + metric_name="switch_state", + domain="switch", + friendly_name="Number", + entity="switch.number", + ).withValue(0.0).assertInBody(body) + + EntityMetric( + metric_name="switch_attr_number", + domain="switch", + friendly_name="Number", + entity="switch.number", + ).withValue(10.2).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -885,29 +696,19 @@ async def test_binary_sensor( """Test prometheus metrics for binary_sensor.""" body = await generate_latest_metrics(client) - domain = "binary_sensor" + EntityMetric( + metric_name="binary_sensor_state", + domain="binary_sensor", + friendly_name="Door", + entity="binary_sensor.door", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="binary_sensor_state", - domain=domain, - friendly_name="Door", - object_id="door", - metric_value="1.0", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="binary_sensor_state", - domain=domain, - friendly_name="Window", - object_id="window", - metric_value="0.0", - ), - ) + EntityMetric( + metric_name="binary_sensor_state", + domain="binary_sensor", + friendly_name="Window", + entity="binary_sensor.window", + ).withValue(0.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -917,28 +718,19 @@ async def test_input_boolean( """Test prometheus metrics for input_boolean.""" body = await generate_latest_metrics(client) - domain = "input_boolean" + EntityMetric( + metric_name="input_boolean_state", + domain="input_boolean", + friendly_name="Test", + entity="input_boolean.test", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="input_boolean_state", - domain=domain, - friendly_name="Test", - object_id="test", - metric_value="1.0", - ), - ) - _assert_metric_present( - body, - EntityMetric( - metric_name="input_boolean_state", - domain=domain, - friendly_name="Helper", - object_id="helper", - metric_value="0.0", - ), - ) + EntityMetric( + metric_name="input_boolean_state", + domain="input_boolean", + friendly_name="Helper", + entity="input_boolean.helper", + ).withValue(0.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -948,61 +740,40 @@ async def test_light( """Test prometheus metrics for lights.""" body = await generate_latest_metrics(client) - domain = "light" - _assert_metric_present( - body, - EntityMetric( - metric_name="light_brightness_percent", - domain=domain, - friendly_name="Desk", - object_id="desk", - metric_value="100.0", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="light_brightness_percent", - domain=domain, - friendly_name="Wall", - object_id="wall", - metric_value="0.0", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="light_brightness_percent", - domain=domain, - friendly_name="TV", - object_id="tv", - metric_value="100.0", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="light_brightness_percent", - domain=domain, - friendly_name="PC", - object_id="pc", - metric_value="70.58823529411765", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="light_brightness_percent", - domain=domain, - friendly_name="Hallway", - object_id="hallway", - metric_value="100.0", - ), - ) + EntityMetric( + metric_name="light_brightness_percent", + domain="light", + friendly_name="Desk", + entity="light.desk", + ).withValue(100.0).assertInBody(body) + + EntityMetric( + metric_name="light_brightness_percent", + domain="light", + friendly_name="Wall", + entity="light.wall", + ).withValue(0.0).assertInBody(body) + + EntityMetric( + metric_name="light_brightness_percent", + domain="light", + friendly_name="TV", + entity="light.tv", + ).withValue(100.0).assertInBody(body) + + EntityMetric( + metric_name="light_brightness_percent", + domain="light", + friendly_name="PC", + entity="light.pc", + ).withValue(70.58823529411765).assertInBody(body) + + EntityMetric( + metric_name="light_brightness_percent", + domain="light", + friendly_name="Hallway", + entity="light.hallway", + ).withValue(100.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1012,28 +783,19 @@ async def test_lock( """Test prometheus metrics for lock.""" body = await generate_latest_metrics(client) - domain = "lock" - _assert_metric_present( - body, - EntityMetric( - metric_name="lock_state", - domain=domain, - friendly_name="Front Door", - object_id="front_door", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="lock_state", + domain="lock", + friendly_name="Front Door", + entity="lock.front_door", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="lock_state", - domain=domain, - friendly_name="Kitchen Door", - object_id="kitchen_door", - metric_value="0.0", - ), - ) + EntityMetric( + metric_name="lock_state", + domain="lock", + friendly_name="Kitchen Door", + entity="lock.kitchen_door", + ).withValue(0.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1042,74 +804,49 @@ async def test_fan( ) -> None: """Test prometheus metrics for fan.""" body = await generate_latest_metrics(client) - domain = "fan" - - _assert_metric_present( - body, - EntityMetric( - metric_name="fan_state", - domain=domain, - friendly_name="Fan 1", - object_id="fan_1", - metric_value="1.0", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="fan_speed_percent", - domain=domain, - friendly_name="Fan 1", - object_id="fan_1", - metric_value="33.0", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="fan_is_oscillating", - domain=domain, - friendly_name="Fan 1", - object_id="fan_1", - metric_value="1.0", - ), - ) - _assert_metric_present( - body, - EntityMetric( - metric_name="fan_direction_reversed", - domain=domain, - friendly_name="Fan 1", - object_id="fan_1", - metric_value="0.0", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="fan_preset_mode", - domain=domain, - friendly_name="Fan 1", - object_id="fan_1", - metric_value="1.0", - mode="LO", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="fan_direction_reversed", - domain=domain, - friendly_name="Reverse Fan", - object_id="fan_2", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="fan_state", + domain="fan", + friendly_name="Fan 1", + entity="fan.fan_1", + ).withValue(1.0).assertInBody(body) + + EntityMetric( + metric_name="fan_speed_percent", + domain="fan", + friendly_name="Fan 1", + entity="fan.fan_1", + ).withValue(33.0).assertInBody(body) + + EntityMetric( + metric_name="fan_is_oscillating", + domain="fan", + friendly_name="Fan 1", + entity="fan.fan_1", + ).withValue(1.0).assertInBody(body) + + EntityMetric( + metric_name="fan_direction_reversed", + domain="fan", + friendly_name="Fan 1", + entity="fan.fan_1", + ).withValue(0.0).assertInBody(body) + + EntityMetric( + metric_name="fan_preset_mode", + domain="fan", + friendly_name="Fan 1", + entity="fan.fan_1", + mode="LO", + ).withValue(1.0).assertInBody(body) + + EntityMetric( + metric_name="fan_direction_reversed", + domain="fan", + friendly_name="Reverse Fan", + entity="fan.fan_2", + ).withValue(1.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1119,55 +856,38 @@ async def test_alarm_control_panel( ) -> None: """Test prometheus metrics for alarm control panel.""" body = await generate_latest_metrics(client) - domain = "alarm_control_panel" - - _assert_metric_present( - body, - EntityMetric( - metric_name="alarm_control_panel_state", - domain=domain, - friendly_name="Alarm Control Panel 1", - object_id="alarm_control_panel_1", - metric_value="1.0", - state="armed_away", - ), - ) - _assert_metric_present( - body, - EntityMetric( - metric_name="alarm_control_panel_state", - domain=domain, - friendly_name="Alarm Control Panel 1", - object_id="alarm_control_panel_1", - metric_value="0.0", - state="disarmed", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="alarm_control_panel_state", - domain=domain, - friendly_name="Alarm Control Panel 2", - object_id="alarm_control_panel_2", - metric_value="1.0", - state="armed_home", - ), - ) - - _assert_metric_present( - body, - EntityMetric( - metric_name="alarm_control_panel_state", - domain=domain, - friendly_name="Alarm Control Panel 2", - object_id="alarm_control_panel_2", - metric_value="0.0", - state="armed_away", - ), - ) + EntityMetric( + metric_name="alarm_control_panel_state", + domain="alarm_control_panel", + friendly_name="Alarm Control Panel 1", + entity="alarm_control_panel.alarm_control_panel_1", + state="armed_away", + ).withValue(1.0).assertInBody(body) + + EntityMetric( + metric_name="alarm_control_panel_state", + domain="alarm_control_panel", + friendly_name="Alarm Control Panel 1", + entity="alarm_control_panel.alarm_control_panel_1", + state="disarmed", + ).withValue(0.0).assertInBody(body) + + EntityMetric( + metric_name="alarm_control_panel_state", + domain="alarm_control_panel", + friendly_name="Alarm Control Panel 2", + entity="alarm_control_panel.alarm_control_panel_2", + state="armed_home", + ).withValue(1.0).assertInBody(body) + + EntityMetric( + metric_name="alarm_control_panel_state", + domain="alarm_control_panel", + friendly_name="Alarm Control Panel 2", + entity="alarm_control_panel.alarm_control_panel_2", + state="armed_away", + ).withValue(0.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1180,79 +900,61 @@ async def test_cover( open_covers = ["cover_open", "cover_position", "cover_tilt_position"] for testcover in data: - _assert_metric_present( - body, - EntityMetric.from_entity_id( - cover_entities[testcover].entity_id, - metric_name="cover_state", - friendly_name=cover_entities[testcover].original_name, - metric_value=1.0 - if cover_entities[testcover].unique_id in open_covers - else 0.0, - state="open", - ), - ) - - _assert_metric_present( - body, - EntityMetric.from_entity_id( - cover_entities[testcover].entity_id, - metric_name="cover_state", - friendly_name=cover_entities[testcover].original_name, - metric_value=1.0 - if cover_entities[testcover].unique_id == "cover_closed" - else 0.0, - state="closed", - ), - ) - - _assert_metric_present( - body, - EntityMetric.from_entity_id( - cover_entities[testcover].entity_id, - metric_name="cover_state", - friendly_name=cover_entities[testcover].original_name, - metric_value=1.0 - if cover_entities[testcover].unique_id == "cover_opening" - else 0.0, - state="opening", - ), - ) - - _assert_metric_present( - body, - EntityMetric.from_entity_id( - cover_entities[testcover].entity_id, - metric_name="cover_state", - friendly_name=cover_entities[testcover].original_name, - metric_value=1.0 - if cover_entities[testcover].unique_id == "cover_closing" - else 0.0, - state="closing", - ), - ) + EntityMetric( + metric_name="cover_state", + domain="cover", + friendly_name=cover_entities[testcover].original_name, + entity=cover_entities[testcover].entity_id, + state="open", + ).withValue( + 1.0 if cover_entities[testcover].unique_id in open_covers else 0.0 + ).assertInBody(body) + + EntityMetric( + metric_name="cover_state", + domain="cover", + friendly_name=cover_entities[testcover].original_name, + entity=cover_entities[testcover].entity_id, + state="closed", + ).withValue( + 1.0 if cover_entities[testcover].unique_id == "cover_closed" else 0.0 + ).assertInBody(body) + + EntityMetric( + metric_name="cover_state", + domain="cover", + friendly_name=cover_entities[testcover].original_name, + entity=cover_entities[testcover].entity_id, + state="opening", + ).withValue( + 1.0 if cover_entities[testcover].unique_id == "cover_opening" else 0.0 + ).assertInBody(body) + + EntityMetric( + metric_name="cover_state", + domain="cover", + friendly_name=cover_entities[testcover].original_name, + entity=cover_entities[testcover].entity_id, + state="closing", + ).withValue( + 1.0 if cover_entities[testcover].unique_id == "cover_closing" else 0.0 + ).assertInBody(body) if testcover == "cover_position": - _assert_metric_present( - body, - EntityMetric.from_entity_id( - cover_entities[testcover].entity_id, - metric_name="cover_position", - friendly_name=cover_entities[testcover].original_name, - metric_value="50.0", - ), - ) + EntityMetric( + metric_name="cover_position", + domain="cover", + friendly_name=cover_entities[testcover].original_name, + entity=cover_entities[testcover].entity_id, + ).withValue(50.0).assertInBody(body) if testcover == "cover_tilt_position": - _assert_metric_present( - body, - EntityMetric.from_entity_id( - cover_entities[testcover].entity_id, - metric_name="cover_tilt_position", - friendly_name=cover_entities[testcover].original_name, - metric_value="50.0", - ), - ) + EntityMetric( + metric_name="cover_tilt_position", + domain="cover", + friendly_name=cover_entities[testcover].original_name, + entity=cover_entities[testcover].entity_id, + ).withValue(50.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1262,27 +964,19 @@ async def test_device_tracker( """Test prometheus metrics for device_tracker.""" body = await generate_latest_metrics(client) - domain = "device_tracker" - _assert_metric_present( - body, - EntityMetric( - metric_name="device_tracker_state", - domain=domain, - friendly_name="Phone", - object_id="phone", - metric_value="1.0", - ), - ) - _assert_metric_present( - body, - EntityMetric( - metric_name="device_tracker_state", - domain=domain, - friendly_name="Watch", - object_id="watch", - metric_value="0.0", - ), - ) + EntityMetric( + metric_name="device_tracker_state", + domain="device_tracker", + friendly_name="Phone", + entity="device_tracker.phone", + ).withValue(1.0).assertInBody(body) + + EntityMetric( + metric_name="device_tracker_state", + domain="device_tracker", + friendly_name="Watch", + entity="device_tracker.watch", + ).withValue(0.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1292,27 +986,18 @@ async def test_person( """Test prometheus metrics for person.""" body = await generate_latest_metrics(client) - domain = "person" - _assert_metric_present( - body, - EntityMetric( - metric_name="person_state", - domain=domain, - friendly_name="Arthur", - object_id="arthur", - metric_value="1.0", - ), - ) - _assert_metric_present( - body, - EntityMetric( - metric_name="person_state", - domain=domain, - friendly_name="Ford", - object_id="ford", - metric_value="0.0", - ), - ) + EntityMetric( + metric_name="person_state", + domain="person", + friendly_name="Arthur", + entity="person.arthur", + ).withValue(1.0).assertInBody(body) + EntityMetric( + metric_name="person_state", + domain="person", + friendly_name="Ford", + entity="person.ford", + ).withValue(0.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1322,17 +1007,12 @@ async def test_counter( """Test prometheus metrics for counter.""" body = await generate_latest_metrics(client) - domain = "counter" - _assert_metric_present( - body, - EntityMetric( - metric_name="counter_value", - domain=domain, - friendly_name="None", - object_id="counter", - metric_value="2.0", - ), - ) + EntityMetric( + metric_name="counter_value", + domain="counter", + friendly_name="None", + entity="counter.counter", + ).withValue(2.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1342,27 +1022,18 @@ async def test_update( """Test prometheus metrics for update.""" body = await generate_latest_metrics(client) - domain = "update" - _assert_metric_present( - body, - EntityMetric( - metric_name="update_state", - domain=domain, - friendly_name="Firmware", - object_id="firmware", - metric_value="1.0", - ), - ) - _assert_metric_present( - body, - EntityMetric( - metric_name="update_state", - domain=domain, - friendly_name="Addon", - object_id="addon", - metric_value="0.0", - ), - ) + EntityMetric( + metric_name="update_state", + domain="update", + friendly_name="Firmware", + entity="update.firmware", + ).withValue(1.0).assertInBody(body) + EntityMetric( + metric_name="update_state", + domain="update", + friendly_name="Addon", + entity="update.addon", + ).withValue(0.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1377,73 +1048,49 @@ async def test_renaming_entity_name( data = {**sensor_entities, **climate_entities} body = await generate_latest_metrics(client) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_temperature_celsius", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="15.6", - ), - ) + EntityMetric( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(15.6).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_humidity_percent", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="54.0", - ), - ) + EntityMetric( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(54.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_action", - domain="climate", - friendly_name="HeatPump", - object_id="heatpump", - metric_value="1.0", - action="heating", - ), - ) + EntityMetric( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump", + entity="climate.heatpump", + action="heating", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_action", - domain="climate", - friendly_name="HeatPump", - object_id="heatpump", - metric_value="0.0", - action="cooling", - ), - ) + EntityMetric( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump", + entity="climate.heatpump", + action="cooling", + ).withValue(0.0).assertInBody(body) assert "sensor.outside_temperature" in entity_registry.entities assert "climate.heatpump" in entity_registry.entities @@ -1481,74 +1128,50 @@ async def test_renaming_entity_name( assert 'friendly_name="HeatPump"' not in body_line # Check if new metrics created - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_temperature_celsius", - domain="sensor", - friendly_name="Outside Temperature Renamed", - object_id="outside_temperature", - metric_value="15.6", - ), - ) + EntityMetric( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature Renamed", + entity="sensor.outside_temperature", + ).withValue(15.6).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Temperature Renamed", - object_id="outside_temperature", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature Renamed", + entity="sensor.outside_temperature", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_action", - domain="climate", - friendly_name="HeatPump Renamed", - object_id="heatpump", - metric_value="1.0", - action="heating", - ), - ) + EntityMetric( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump Renamed", + entity="climate.heatpump", + action="heating", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_action", - domain="climate", - friendly_name="HeatPump Renamed", - object_id="heatpump", - metric_value="0.0", - action="cooling", - ), - ) + EntityMetric( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump Renamed", + entity="climate.heatpump", + action="cooling", + ).withValue(0.0).assertInBody(body) # Keep other sensors - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_humidity_percent", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="54.0", - ), - ) + EntityMetric( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(54.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(1.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1563,49 +1186,33 @@ async def test_renaming_entity_id( data = {**sensor_entities, **climate_entities} body = await generate_latest_metrics(client) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_temperature_celsius", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="15.6", - ), - ) + EntityMetric( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(15.6).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_humidity_percent", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="54.0", - ), - ) + EntityMetric( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(54.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(1.0).assertInBody(body) assert "sensor.outside_temperature" in entity_registry.entities assert "climate.heatpump" in entity_registry.entities @@ -1625,49 +1232,33 @@ async def test_renaming_entity_id( assert 'entity="sensor.outside_temperature"' not in body_line # Check if new metrics created - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_temperature_celsius", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature_renamed", - metric_value="15.6", - ), - ) + EntityMetric( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature_renamed", + ).withValue(15.6).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature_renamed", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature_renamed", + ).withValue(1.0).assertInBody(body) # Keep other sensors - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_humidity_percent", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="54.0", - ), - ) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(54.0).assertInBody(body) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(1.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1682,73 +1273,49 @@ async def test_deleting_entity( data = {**sensor_entities, **climate_entities} body = await generate_latest_metrics(client) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_temperature_celsius", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="15.6", - ), - ) + EntityMetric( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(15.6).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_humidity_percent", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="54.0", - ), - ) + EntityMetric( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(54.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_action", - domain="climate", - friendly_name="HeatPump", - object_id="heatpump", - metric_value="1.0", - action="heating", - ), - ) + EntityMetric( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump", + entity="climate.heatpump", + action="heating", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_action", - domain="climate", - friendly_name="HeatPump", - object_id="heatpump", - metric_value="0.0", - action="cooling", - ), - ) + EntityMetric( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump", + entity="climate.heatpump", + action="cooling", + ).withValue(0.0).assertInBody(body) assert "sensor.outside_temperature" in entity_registry.entities assert "climate.heatpump" in entity_registry.entities @@ -1766,27 +1333,19 @@ async def test_deleting_entity( assert 'friendly_name="HeatPump"' not in body_line # Keep other sensors - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_humidity_percent", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="54.0", - ), - ) + EntityMetric( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(54.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(1.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1803,81 +1362,57 @@ async def test_disabling_entity( await hass.async_block_till_done() body = await generate_latest_metrics(client) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_temperature_celsius", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="15.6", - ), - ) + EntityMetric( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(15.6).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="state_change_total", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="state_change_total", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(1.0).assertInBody(body) state_change_metric_string = EntityMetric( metric_name="state_change_created", domain="sensor", friendly_name="Outside Temperature", - object_id="outside_temperature", - ).get_full_metric_string() + entity="sensor.outside_temperature", + )._metric_name_string assert any(state_change_metric_string in metric for metric in body) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_humidity_percent", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="54.0", - ), - ) + EntityMetric( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(54.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_action", - domain="climate", - friendly_name="HeatPump", - object_id="heatpump", - metric_value="1.0", - action="heating", - ), - ) + EntityMetric( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump", + entity="climate.heatpump", + action="heating", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="climate_action", - domain="climate", - friendly_name="HeatPump", - object_id="heatpump", - metric_value="0.0", - action="cooling", - ), - ) + EntityMetric( + metric_name="climate_action", + domain="climate", + friendly_name="HeatPump", + entity="climate.heatpump", + action="cooling", + ).withValue(0.0).assertInBody(body) assert "sensor.outside_temperature" in entity_registry.entities assert "climate.heatpump" in entity_registry.entities @@ -1901,27 +1436,19 @@ async def test_disabling_entity( assert 'friendly_name="HeatPump"' not in body_line # Keep other sensors - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_humidity_percent", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="54.0", - ), - ) + EntityMetric( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(54.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(1.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1937,71 +1464,47 @@ async def test_entity_becomes_unavailable_with_export( await hass.async_block_till_done() body = await generate_latest_metrics(client) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_temperature_celsius", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="15.6", - ), - ) + EntityMetric( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(15.6).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="state_change_total", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="state_change_total", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_humidity_percent", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="54.0", - ), - ) + EntityMetric( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(54.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="state_change_total", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="state_change_total", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(1.0).assertInBody(body) # Make sensor_1 unavailable. set_state_with_entry( @@ -2012,72 +1515,48 @@ async def test_entity_becomes_unavailable_with_export( body = await generate_latest_metrics(client) # Check that only the availability changed on sensor_1. - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_temperature_celsius", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="15.6", - ), - ) + EntityMetric( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(15.6).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="state_change_total", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="2.0", - ), - ) + EntityMetric( + metric_name="state_change_total", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(2.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="0.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(0.0).assertInBody(body) # The other sensor should be unchanged. - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_humidity_percent", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="54.0", - ), - ) + EntityMetric( + metric_name="sensor_humidity_percent", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(54.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="state_change_total", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="state_change_total", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(1.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Humidity", - object_id="outside_humidity", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Humidity", + entity="sensor.outside_humidity", + ).withValue(1.0).assertInBody(body) # Bring sensor_1 back and check that it is correct. set_state_with_entry(hass, data["sensor_1"], 200.0, data["sensor_1_attributes"]) @@ -2085,38 +1564,26 @@ async def test_entity_becomes_unavailable_with_export( await hass.async_block_till_done() body = await generate_latest_metrics(client) - _assert_metric_present( - body, - EntityMetric( - metric_name="sensor_temperature_celsius", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="200.0", - ), - ) + EntityMetric( + metric_name="sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(200.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="state_change_total", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="3.0", - ), - ) + EntityMetric( + metric_name="state_change_total", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(3.0).assertInBody(body) - _assert_metric_present( - body, - EntityMetric( - metric_name="entity_available", - domain="sensor", - friendly_name="Outside Temperature", - object_id="outside_temperature", - metric_value="1.0", - ), - ) + EntityMetric( + metric_name="entity_available", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + ).withValue(1.0).assertInBody(body) @pytest.fixture(name="sensor_entities") From 00d29bd3fea14dd8796d9f7e88473ff639ac4d52 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Mon, 30 Sep 2024 14:51:09 -0700 Subject: [PATCH 51/62] Just a little more clean up --- tests/components/prometheus/test_init.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 00063f113779cc..a949fd66c3650b 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -1376,13 +1376,12 @@ async def test_disabling_entity( entity="sensor.outside_temperature", ).withValue(1.0).assertInBody(body) - state_change_metric_string = EntityMetric( + EntityMetric( metric_name="state_change_created", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - )._metric_name_string - assert any(state_change_metric_string in metric for metric in body) + ).assertInBody(body) EntityMetric( metric_name="sensor_humidity_percent", From 110f8e005b6bb49178f3fbe63fec0f9395245ffc Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Mon, 30 Sep 2024 15:20:39 -0700 Subject: [PATCH 52/62] Added a few more tests for the new helper functions --- tests/components/prometheus/test_init.py | 58 +++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index a949fd66c3650b..e98573c588e8d6 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -94,7 +94,7 @@ class EntityMetric: metric_name: str labels: dict[str, str] - def __init__(self, metric_name: str, **kwargs) -> None: + def __init__(self, metric_name: str, **kwargs: Any) -> None: """Create a new EntityMetric based on metric name and labels.""" self.metric_name = metric_name self.labels = kwargs @@ -191,6 +191,62 @@ def test_entity_metric_generates_metric_string_with_value() -> None: ) +def test_entity_metric_raises_exception_without_required_labels() -> None: + """Test using EntityMetric to raise exception when required labels are missing.""" + domain = "sensor" + object_id = "outside_temperature" + with pytest.raises(AssertionError): + EntityMetric( + metric_name="homeassistant_sensor_temperature_celsius", + friendly_name="Outside Temperature", + entity=f"{domain}.{object_id}", + ).withValue(17.2) + + with pytest.raises(AssertionError): + EntityMetric( + metric_name="homeassistant_sensor_temperature_celsius", + domain=domain, + entity=f"{domain}.{object_id}", + ).withValue(17.2) + + with pytest.raises(AssertionError): + EntityMetric( + metric_name="homeassistant_sensor_temperature_celsius", + domain=domain, + friendly_name="Outside Temperature", + ).withValue(17.2) + + +def test_entity_metric_generates_alphabetically_ordered_labels() -> None: + """Test using EntityMetric to format a simple metric string with labels alphabetically ordered.""" + domain = "sensor" + object_id = "outside_temperature" + + static_metric_string = ( + "homeassistant_sensor_temperature_celsius{" + 'domain="sensor",' + 'entity="sensor.outside_temperature",' + 'friendly_name="Outside Temperature"}' + " 17.2" + ) + + ordered_entity_metric = EntityMetric( + metric_name="homeassistant_sensor_temperature_celsius", + domain=domain, + entity=f"{domain}.{object_id}", + friendly_name="Outside Temperature", + ).withValue(17.2) + assert ordered_entity_metric._metric_string == static_metric_string + + unordered_entity_metric = EntityMetric( + metric_name="homeassistant_sensor_temperature_celsius", + friendly_name="Outside Temperature", + entity=f"{domain}.{object_id}", + domain=domain, + ).withValue(17.2) + assert unordered_entity_metric._metric_string == static_metric_string + + def test_entity_metric_generates_metric_string_with_mode_value() -> None: """Test using EntityMetric to format a simple metric string but with a mode value included.""" entity_metric = EntityMetric( From c9fbcef15c09b48c768db365a8b487ecf3e1f177 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Mon, 30 Sep 2024 15:35:41 -0700 Subject: [PATCH 53/62] Last pass on much better tests for this --- tests/components/prometheus/test_init.py | 47 +++++++++++++++++------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index e98573c588e8d6..3a63498459d95b 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -247,16 +247,16 @@ def test_entity_metric_generates_alphabetically_ordered_labels() -> None: assert unordered_entity_metric._metric_string == static_metric_string -def test_entity_metric_generates_metric_string_with_mode_value() -> None: - """Test using EntityMetric to format a simple metric string but with a mode value included.""" - entity_metric = EntityMetric( +def test_entity_metric_generates_metric_string_with_non_required_labels() -> None: + """Test using EntityMetric to format a simple metric string but with extra labels and values included.""" + mode_entity_metric = EntityMetric( metric_name="climate_preset_mode", domain="climate", friendly_name="Ecobee", entity="climate.ecobee", mode="away", ).withValue(1.0) - assert entity_metric._metric_string == ( + assert mode_entity_metric._metric_string == ( "climate_preset_mode{" 'domain="climate",' 'entity="climate.ecobee",' @@ -266,17 +266,14 @@ def test_entity_metric_generates_metric_string_with_mode_value() -> None: " 1.0" ) - -def test_entity_metric_generates_metric_string_with_action_value() -> None: - """Test using EntityMetric to format a simple metric string but with an action value included.""" - entity_metric = EntityMetric( + action_entity_metric = EntityMetric( metric_name="climate_action", domain="climate", friendly_name="HeatPump", entity="climate.heatpump", action="heating", ).withValue(1.0) - assert entity_metric._metric_string == ( + assert action_entity_metric._metric_string == ( "climate_action{" 'action="heating",' 'domain="climate",' @@ -286,17 +283,14 @@ def test_entity_metric_generates_metric_string_with_action_value() -> None: " 1.0" ) - -def test_entity_metric_generates_metric_string_with_state_value() -> None: - """Test using EntityMetric to format a simple metric string but with a state value included.""" - entity_metric = EntityMetric( + state_entity_metric = EntityMetric( metric_name="cover_state", domain="cover", friendly_name="Curtain", entity="cover.curtain", state="open", ).withValue(1.0) - assert entity_metric._metric_string == ( + assert state_entity_metric._metric_string == ( "cover_state{" 'domain="cover",' 'entity="cover.curtain",' @@ -306,6 +300,31 @@ def test_entity_metric_generates_metric_string_with_state_value() -> None: " 1.0" ) + foo_entity_metric = EntityMetric( + metric_name="homeassistant_sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + foo="bar", + ).withValue(17.2) + assert foo_entity_metric._metric_string == ( + "homeassistant_sensor_temperature_celsius{" + 'domain="sensor",' + 'entity="sensor.outside_temperature",' + 'foo="bar",' + 'friendly_name="Outside Temperature"' + "}" + " 17.2" + ) + + +def test_entity_metric_generates_metric_string_with_action_value() -> None: + """Test using EntityMetric to format a simple metric string but with an action value included.""" + + +def test_entity_metric_generates_metric_string_with_state_value() -> None: + """Test using EntityMetric to format a simple metric string but with a state value included.""" + @pytest.fixture(name="client") async def setup_prometheus_client( From 381f62846e3682ada0e38653d65c2e4df0f69c6f Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Mon, 30 Sep 2024 15:41:26 -0700 Subject: [PATCH 54/62] Oops, forgot to remove redundant tests --- tests/components/prometheus/test_init.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 3a63498459d95b..119940a0390b41 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -318,14 +318,6 @@ def test_entity_metric_generates_metric_string_with_non_required_labels() -> Non ) -def test_entity_metric_generates_metric_string_with_action_value() -> None: - """Test using EntityMetric to format a simple metric string but with an action value included.""" - - -def test_entity_metric_generates_metric_string_with_state_value() -> None: - """Test using EntityMetric to format a simple metric string but with a state value included.""" - - @pytest.fixture(name="client") async def setup_prometheus_client( hass: HomeAssistant, From 8c49f3526b2a8a5e84177e40b1ee2810cb36cd73 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Mon, 30 Sep 2024 15:50:35 -0700 Subject: [PATCH 55/62] Fix the fixtures --- tests/components/prometheus/test_init.py | 68 ++++++++++++------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 119940a0390b41..6483e33ef3f557 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -1056,14 +1056,14 @@ async def test_person( EntityMetric( metric_name="person_state", domain="person", - friendly_name="Arthur", - entity="person.arthur", + friendly_name="Bob", + entity="person.bob", ).withValue(1.0).assertInBody(body) EntityMetric( metric_name="person_state", domain="person", - friendly_name="Ford", - entity="person.ford", + friendly_name="Alice", + entity="person.alice", ).withValue(0.0).assertInBody(body) @@ -2341,6 +2341,36 @@ async def alarm_control_panel_fixture( return data +@pytest.fixture(name="person_entities") +async def person_fixture( + hass: HomeAssistant, entity_registry: er.EntityRegistry +) -> dict[str, er.RegistryEntry]: + """Simulate person entities.""" + data = {} + person_1 = entity_registry.async_get_or_create( + domain=person.DOMAIN, + platform="test", + unique_id="person_1", + suggested_object_id="bob", + original_name="Bob", + ) + set_state_with_entry(hass, person_1, STATE_HOME) + data["person_1"] = person_1 + + person_2 = entity_registry.async_get_or_create( + domain=person.DOMAIN, + platform="test", + unique_id="person_2", + suggested_object_id="alice", + original_name="Alice", + ) + set_state_with_entry(hass, person_2, STATE_NOT_HOME) + data["person_2"] = person_2 + + await hass.async_block_till_done() + return data + + @pytest.fixture(name="device_tracker_entities") async def device_tracker_fixture( hass: HomeAssistant, entity_registry: er.EntityRegistry @@ -2371,36 +2401,6 @@ async def device_tracker_fixture( return data -@pytest.fixture(name="person_entities") -async def person_fixture( - hass: HomeAssistant, entity_registry: er.EntityRegistry -) -> dict[str, er.RegistryEntry]: - """Simulate person entities.""" - data = {} - person_1 = entity_registry.async_get_or_create( - domain=person.DOMAIN, - platform="test", - unique_id="person_1", - suggested_object_id="arthur", - original_name="Arthur", - ) - set_state_with_entry(hass, person_1, STATE_HOME) - data["person_1"] = person_1 - - person_2 = entity_registry.async_get_or_create( - domain=person.DOMAIN, - platform="test", - unique_id="person_2", - suggested_object_id="ford", - original_name="Ford", - ) - set_state_with_entry(hass, person_2, STATE_NOT_HOME) - data["person_2"] = person_2 - - await hass.async_block_till_done() - return data - - @pytest.fixture(name="counter_entities") async def counter_fixture( hass: HomeAssistant, entity_registry: er.EntityRegistry From 8bd85ef86f2a170554f1e1a55b50030ffd898067 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Tue, 1 Oct 2024 12:41:15 -0700 Subject: [PATCH 56/62] Getting closer to something decent, I hope --- tests/components/prometheus/test_init.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 6483e33ef3f557..f6526206d67eef 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -116,13 +116,17 @@ def _metric_name_string(self) -> str: ) return f"{self.metric_name}{{{labels}}}" - def assertInBody(self, body: list[str]): + def _in_metrics(self, metrics: list[str]) -> bool: + """Report whether this metric exists in the provided Prometheus output.""" + return any(line.startswith(self._metric_name_string) for line in metrics) + + def assertInBody(self, metrics: list[str]): """Assert that this metric exists in the provided Prometheus output.""" - assert any(line.startswith(self._metric_name_string) for line in body) + assert self._in_metrics(metrics) - def assertNotInBody(self, body: list[str]): + def assertNotInBody(self, metrics: list[str]): """Assert that this metric does not exist in Prometheus output.""" - assert self._metric_name_string not in body + assert not self._in_metrics(metrics) class EntityMetricWithValue(EntityMetric): @@ -141,9 +145,9 @@ def _metric_string(self) -> str: value = floatToGoString(self.value) return f"{self._metric_name_string} {value}" - def assertInBody(self, body: list[str]): + def assertInBody(self, metrics: list[str]): """Assert that this metric exists in the provided Prometheus output.""" - assert self._metric_string in body + assert self._metric_string in metrics @dataclass @@ -501,7 +505,7 @@ async def test_sensor_without_unit( domain="sensor", friendly_name="Text Unit", entity="sensor.text_unit", - ).withValue(0.0).assertNotInBody(body) + ).withValue(0.0).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) From f3a2a4db581b7880b46d0d9cec12268c2e64c321 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Tue, 1 Oct 2024 12:43:02 -0700 Subject: [PATCH 57/62] Another pass on the formatting of the number 1 --- tests/components/prometheus/test_init.py | 94 ++++++++++++------------ 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index f6526206d67eef..fd897581434c8e 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -259,7 +259,7 @@ def test_entity_metric_generates_metric_string_with_non_required_labels() -> Non friendly_name="Ecobee", entity="climate.ecobee", mode="away", - ).withValue(1.0) + ).withValue(1) assert mode_entity_metric._metric_string == ( "climate_preset_mode{" 'domain="climate",' @@ -276,7 +276,7 @@ def test_entity_metric_generates_metric_string_with_non_required_labels() -> Non friendly_name="HeatPump", entity="climate.heatpump", action="heating", - ).withValue(1.0) + ).withValue(1) assert action_entity_metric._metric_string == ( "climate_action{" 'action="heating",' @@ -293,7 +293,7 @@ def test_entity_metric_generates_metric_string_with_non_required_labels() -> Non friendly_name="Curtain", entity="cover.curtain", state="open", - ).withValue(1.0) + ).withValue(1) assert state_entity_metric._metric_string == ( "cover_state{" 'domain="cover",' @@ -412,7 +412,7 @@ async def test_view_empty_namespace( domain="sensor", friendly_name="Radio Energy", entity="sensor.radio_energy", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="last_updated_time_seconds", @@ -673,7 +673,7 @@ async def test_climate( friendly_name="Ecobee", entity="climate.ecobee", mode="away", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="climate_fan_mode", @@ -681,7 +681,7 @@ async def test_climate( friendly_name="Ecobee", entity="climate.ecobee", mode="auto", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -704,7 +704,7 @@ async def test_humidifier( domain="humidifier", friendly_name="Dehumidifier", entity="humidifier.dehumidifier", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="humidifier_mode", @@ -712,7 +712,7 @@ async def test_humidifier( friendly_name="Hygrostat", entity="humidifier.hygrostat", mode="home", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="humidifier_mode", @@ -736,14 +736,14 @@ async def test_attributes( domain="switch", friendly_name="Boolean", entity="switch.boolean", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="switch_attr_boolean", domain="switch", friendly_name="Boolean", entity="switch.boolean", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="switch_state", @@ -772,7 +772,7 @@ async def test_binary_sensor( domain="binary_sensor", friendly_name="Door", entity="binary_sensor.door", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="binary_sensor_state", @@ -794,7 +794,7 @@ async def test_input_boolean( domain="input_boolean", friendly_name="Test", entity="input_boolean.test", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="input_boolean_state", @@ -859,7 +859,7 @@ async def test_lock( domain="lock", friendly_name="Front Door", entity="lock.front_door", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="lock_state", @@ -881,7 +881,7 @@ async def test_fan( domain="fan", friendly_name="Fan 1", entity="fan.fan_1", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="fan_speed_percent", @@ -895,7 +895,7 @@ async def test_fan( domain="fan", friendly_name="Fan 1", entity="fan.fan_1", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="fan_direction_reversed", @@ -910,14 +910,14 @@ async def test_fan( friendly_name="Fan 1", entity="fan.fan_1", mode="LO", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="fan_direction_reversed", domain="fan", friendly_name="Reverse Fan", entity="fan.fan_2", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -934,7 +934,7 @@ async def test_alarm_control_panel( friendly_name="Alarm Control Panel 1", entity="alarm_control_panel.alarm_control_panel_1", state="armed_away", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="alarm_control_panel_state", @@ -950,7 +950,7 @@ async def test_alarm_control_panel( friendly_name="Alarm Control Panel 2", entity="alarm_control_panel.alarm_control_panel_2", state="armed_home", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="alarm_control_panel_state", @@ -1040,7 +1040,7 @@ async def test_device_tracker( domain="device_tracker", friendly_name="Phone", entity="device_tracker.phone", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="device_tracker_state", @@ -1062,7 +1062,7 @@ async def test_person( domain="person", friendly_name="Bob", entity="person.bob", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="person_state", domain="person", @@ -1098,7 +1098,7 @@ async def test_update( domain="update", friendly_name="Firmware", entity="update.firmware", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="update_state", domain="update", @@ -1131,7 +1131,7 @@ async def test_renaming_entity_name( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="sensor_humidity_percent", @@ -1145,7 +1145,7 @@ async def test_renaming_entity_name( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="climate_action", @@ -1153,7 +1153,7 @@ async def test_renaming_entity_name( friendly_name="HeatPump", entity="climate.heatpump", action="heating", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="climate_action", @@ -1211,7 +1211,7 @@ async def test_renaming_entity_name( domain="sensor", friendly_name="Outside Temperature Renamed", entity="sensor.outside_temperature", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="climate_action", @@ -1219,7 +1219,7 @@ async def test_renaming_entity_name( friendly_name="HeatPump Renamed", entity="climate.heatpump", action="heating", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="climate_action", @@ -1242,7 +1242,7 @@ async def test_renaming_entity_name( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1269,7 +1269,7 @@ async def test_renaming_entity_id( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="sensor_humidity_percent", @@ -1283,7 +1283,7 @@ async def test_renaming_entity_id( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) assert "sensor.outside_temperature" in entity_registry.entities assert "climate.heatpump" in entity_registry.entities @@ -1315,7 +1315,7 @@ async def test_renaming_entity_id( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature_renamed", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) # Keep other sensors EntityMetric( @@ -1329,7 +1329,7 @@ async def test_renaming_entity_id( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1356,7 +1356,7 @@ async def test_deleting_entity( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="sensor_humidity_percent", @@ -1370,7 +1370,7 @@ async def test_deleting_entity( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="climate_action", @@ -1378,7 +1378,7 @@ async def test_deleting_entity( friendly_name="HeatPump", entity="climate.heatpump", action="heating", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="climate_action", @@ -1416,7 +1416,7 @@ async def test_deleting_entity( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1445,7 +1445,7 @@ async def test_disabling_entity( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="state_change_created", @@ -1466,7 +1466,7 @@ async def test_disabling_entity( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="climate_action", @@ -1474,7 +1474,7 @@ async def test_disabling_entity( friendly_name="HeatPump", entity="climate.heatpump", action="heating", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="climate_action", @@ -1518,7 +1518,7 @@ async def test_disabling_entity( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) @pytest.mark.parametrize("namespace", [""]) @@ -1546,14 +1546,14 @@ async def test_entity_becomes_unavailable_with_export( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="sensor_humidity_percent", @@ -1567,14 +1567,14 @@ async def test_entity_becomes_unavailable_with_export( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) # Make sensor_1 unavailable. set_state_with_entry( @@ -1619,14 +1619,14 @@ async def test_entity_becomes_unavailable_with_export( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) # Bring sensor_1 back and check that it is correct. set_state_with_entry(hass, data["sensor_1"], 200.0, data["sensor_1_attributes"]) @@ -1653,7 +1653,7 @@ async def test_entity_becomes_unavailable_with_export( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(1.0).assertInBody(body) + ).withValue(1).assertInBody(body) @pytest.fixture(name="sensor_entities") From 17520ac7e692d6c804541dcf2d296a4debe655df Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Tue, 1 Oct 2024 12:44:42 -0700 Subject: [PATCH 58/62] And yet another pass on these tests --- tests/components/prometheus/test_init.py | 254 +++++++++++------------ 1 file changed, 127 insertions(+), 127 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index fd897581434c8e..e43d3fc539d386 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -120,11 +120,11 @@ def _in_metrics(self, metrics: list[str]) -> bool: """Report whether this metric exists in the provided Prometheus output.""" return any(line.startswith(self._metric_name_string) for line in metrics) - def assertInBody(self, metrics: list[str]): + def assert_in_metrics(self, metrics: list[str]): """Assert that this metric exists in the provided Prometheus output.""" assert self._in_metrics(metrics) - def assertNotInBody(self, metrics: list[str]): + def assert_not_in_metrics(self, metrics: list[str]): """Assert that this metric does not exist in Prometheus output.""" assert not self._in_metrics(metrics) @@ -145,7 +145,7 @@ def _metric_string(self) -> str: value = floatToGoString(self.value) return f"{self._metric_name_string} {value}" - def assertInBody(self, metrics: list[str]): + def assert_in_metrics(self, metrics: list[str]): """Assert that this metric exists in the provided Prometheus output.""" assert self._metric_string in metrics @@ -391,7 +391,7 @@ async def test_setup_enumeration( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(state).assertInBody(body) + ).withValue(state).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -412,14 +412,14 @@ async def test_view_empty_namespace( domain="sensor", friendly_name="Radio Energy", entity="sensor.radio_energy", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="last_updated_time_seconds", domain="sensor", friendly_name="Radio Energy", entity="sensor.radio_energy", - ).withValue(86400.0).assertInBody(body) + ).withValue(86400.0).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [None]) @@ -440,7 +440,7 @@ async def test_view_default_namespace( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(15.6).assertInBody(body) + ).withValue(15.6).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -455,28 +455,28 @@ async def test_sensor_unit( domain="sensor", friendly_name="Television Energy", entity="sensor.television_energy", - ).withValue(74.0).assertInBody(body) + ).withValue(74.0).assert_in_metrics(body) EntityMetric( metric_name="sensor_unit_sek_per_kwh", domain="sensor", friendly_name="Electricity price", entity="sensor.electricity_price", - ).withValue(0.123).assertInBody(body) + ).withValue(0.123).assert_in_metrics(body) EntityMetric( metric_name="sensor_unit_u0xb0", domain="sensor", friendly_name="Wind Direction", entity="sensor.wind_direction", - ).withValue(25.0).assertInBody(body) + ).withValue(25.0).assert_in_metrics(body) EntityMetric( metric_name="sensor_unit_u0xb5g_per_mu0xb3", domain="sensor", friendly_name="SPS30 PM <1µm Weight concentration", entity="sensor.sps30_pm_1um_weight_concentration", - ).withValue(3.7069).assertInBody(body) + ).withValue(3.7069).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -491,21 +491,21 @@ async def test_sensor_without_unit( domain="sensor", friendly_name="Trend Gradient", entity="sensor.trend_gradient", - ).withValue(0.002).assertInBody(body) + ).withValue(0.002).assert_in_metrics(body) EntityMetric( metric_name="sensor_state", domain="sensor", friendly_name="Text", entity="sensor.text", - ).withValue(0.0).assertNotInBody(body) + ).withValue(0.0).assert_not_in_metrics(body) EntityMetric( metric_name="sensor_unit_text", domain="sensor", friendly_name="Text Unit", entity="sensor.text_unit", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -520,35 +520,35 @@ async def test_sensor_device_class( domain="sensor", friendly_name="Fahrenheit", entity="sensor.fahrenheit", - ).withValue(10.0).assertInBody(body) + ).withValue(10.0).assert_in_metrics(body) EntityMetric( metric_name="sensor_temperature_celsius", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(15.6).assertInBody(body) + ).withValue(15.6).assert_in_metrics(body) EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(54.0).assertInBody(body) + ).withValue(54.0).assert_in_metrics(body) EntityMetric( metric_name="sensor_power_kwh", domain="sensor", friendly_name="Radio Energy", entity="sensor.radio_energy", - ).withValue(14.0).assertInBody(body) + ).withValue(14.0).assert_in_metrics(body) EntityMetric( metric_name="sensor_timestamp_seconds", domain="sensor", friendly_name="Timestamp", entity="sensor.timestamp", - ).withValue(1.691445808136036e09).assertInBody(body) + ).withValue(1.691445808136036e09).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -563,21 +563,21 @@ async def test_input_number( domain="input_number", friendly_name="Threshold", entity="input_number.threshold", - ).withValue(5.2).assertInBody(body) + ).withValue(5.2).assert_in_metrics(body) EntityMetric( metric_name="input_number_state", domain="input_number", friendly_name="None", entity="input_number.brightness", - ).withValue(60.0).assertInBody(body) + ).withValue(60.0).assert_in_metrics(body) EntityMetric( metric_name="input_number_state_celsius", domain="input_number", friendly_name="Target temperature", entity="input_number.target_temperature", - ).withValue(22.7).assertInBody(body) + ).withValue(22.7).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -592,21 +592,21 @@ async def test_number( domain="number", friendly_name="Threshold", entity="number.threshold", - ).withValue(5.2).assertInBody(body) + ).withValue(5.2).assert_in_metrics(body) EntityMetric( metric_name="number_state", domain="number", friendly_name="None", entity="number.brightness", - ).withValue(60.0).assertInBody(body) + ).withValue(60.0).assert_in_metrics(body) EntityMetric( metric_name="number_state_celsius", domain="number", friendly_name="Target temperature", entity="number.target_temperature", - ).withValue(22.7).assertInBody(body) + ).withValue(22.7).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -621,7 +621,7 @@ async def test_battery( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(12.0).assertInBody(body) + ).withValue(12.0).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -637,35 +637,35 @@ async def test_climate( domain="climate", friendly_name="HeatPump", entity="climate.heatpump", - ).withValue(25.0).assertInBody(body) + ).withValue(25.0).assert_in_metrics(body) EntityMetric( metric_name="climate_target_temperature_celsius", domain="climate", friendly_name="HeatPump", entity="climate.heatpump", - ).withValue(20.0).assertInBody(body) + ).withValue(20.0).assert_in_metrics(body) EntityMetric( metric_name="climate_target_temperature_low_celsius", domain="climate", friendly_name="Ecobee", entity="climate.ecobee", - ).withValue(21.0).assertInBody(body) + ).withValue(21.0).assert_in_metrics(body) EntityMetric( metric_name="climate_target_temperature_high_celsius", domain="climate", friendly_name="Ecobee", entity="climate.ecobee", - ).withValue(24.0).assertInBody(body) + ).withValue(24.0).assert_in_metrics(body) EntityMetric( metric_name="climate_target_temperature_celsius", domain="climate", friendly_name="Fritz!DECT", entity="climate.fritzdect", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) EntityMetric( metric_name="climate_preset_mode", @@ -673,7 +673,7 @@ async def test_climate( friendly_name="Ecobee", entity="climate.ecobee", mode="away", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="climate_fan_mode", @@ -681,7 +681,7 @@ async def test_climate( friendly_name="Ecobee", entity="climate.ecobee", mode="auto", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -697,14 +697,14 @@ async def test_humidifier( domain="humidifier", friendly_name="Humidifier", entity="humidifier.humidifier", - ).withValue(68.0).assertInBody(body) + ).withValue(68.0).assert_in_metrics(body) EntityMetric( metric_name="humidifier_state", domain="humidifier", friendly_name="Dehumidifier", entity="humidifier.dehumidifier", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="humidifier_mode", @@ -712,7 +712,7 @@ async def test_humidifier( friendly_name="Hygrostat", entity="humidifier.hygrostat", mode="home", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="humidifier_mode", @@ -720,7 +720,7 @@ async def test_humidifier( friendly_name="Hygrostat", entity="humidifier.hygrostat", mode="eco", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -736,28 +736,28 @@ async def test_attributes( domain="switch", friendly_name="Boolean", entity="switch.boolean", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="switch_attr_boolean", domain="switch", friendly_name="Boolean", entity="switch.boolean", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="switch_state", domain="switch", friendly_name="Number", entity="switch.number", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) EntityMetric( metric_name="switch_attr_number", domain="switch", friendly_name="Number", entity="switch.number", - ).withValue(10.2).assertInBody(body) + ).withValue(10.2).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -772,14 +772,14 @@ async def test_binary_sensor( domain="binary_sensor", friendly_name="Door", entity="binary_sensor.door", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="binary_sensor_state", domain="binary_sensor", friendly_name="Window", entity="binary_sensor.window", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -794,14 +794,14 @@ async def test_input_boolean( domain="input_boolean", friendly_name="Test", entity="input_boolean.test", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="input_boolean_state", domain="input_boolean", friendly_name="Helper", entity="input_boolean.helper", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -816,35 +816,35 @@ async def test_light( domain="light", friendly_name="Desk", entity="light.desk", - ).withValue(100.0).assertInBody(body) + ).withValue(100.0).assert_in_metrics(body) EntityMetric( metric_name="light_brightness_percent", domain="light", friendly_name="Wall", entity="light.wall", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) EntityMetric( metric_name="light_brightness_percent", domain="light", friendly_name="TV", entity="light.tv", - ).withValue(100.0).assertInBody(body) + ).withValue(100.0).assert_in_metrics(body) EntityMetric( metric_name="light_brightness_percent", domain="light", friendly_name="PC", entity="light.pc", - ).withValue(70.58823529411765).assertInBody(body) + ).withValue(70.58823529411765).assert_in_metrics(body) EntityMetric( metric_name="light_brightness_percent", domain="light", friendly_name="Hallway", entity="light.hallway", - ).withValue(100.0).assertInBody(body) + ).withValue(100.0).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -859,14 +859,14 @@ async def test_lock( domain="lock", friendly_name="Front Door", entity="lock.front_door", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="lock_state", domain="lock", friendly_name="Kitchen Door", entity="lock.kitchen_door", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -881,28 +881,28 @@ async def test_fan( domain="fan", friendly_name="Fan 1", entity="fan.fan_1", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="fan_speed_percent", domain="fan", friendly_name="Fan 1", entity="fan.fan_1", - ).withValue(33.0).assertInBody(body) + ).withValue(33.0).assert_in_metrics(body) EntityMetric( metric_name="fan_is_oscillating", domain="fan", friendly_name="Fan 1", entity="fan.fan_1", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="fan_direction_reversed", domain="fan", friendly_name="Fan 1", entity="fan.fan_1", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) EntityMetric( metric_name="fan_preset_mode", @@ -910,14 +910,14 @@ async def test_fan( friendly_name="Fan 1", entity="fan.fan_1", mode="LO", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="fan_direction_reversed", domain="fan", friendly_name="Reverse Fan", entity="fan.fan_2", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -934,7 +934,7 @@ async def test_alarm_control_panel( friendly_name="Alarm Control Panel 1", entity="alarm_control_panel.alarm_control_panel_1", state="armed_away", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="alarm_control_panel_state", @@ -942,7 +942,7 @@ async def test_alarm_control_panel( friendly_name="Alarm Control Panel 1", entity="alarm_control_panel.alarm_control_panel_1", state="disarmed", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) EntityMetric( metric_name="alarm_control_panel_state", @@ -950,7 +950,7 @@ async def test_alarm_control_panel( friendly_name="Alarm Control Panel 2", entity="alarm_control_panel.alarm_control_panel_2", state="armed_home", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="alarm_control_panel_state", @@ -958,7 +958,7 @@ async def test_alarm_control_panel( friendly_name="Alarm Control Panel 2", entity="alarm_control_panel.alarm_control_panel_2", state="armed_away", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -979,7 +979,7 @@ async def test_cover( state="open", ).withValue( 1.0 if cover_entities[testcover].unique_id in open_covers else 0.0 - ).assertInBody(body) + ).assert_in_metrics(body) EntityMetric( metric_name="cover_state", @@ -989,7 +989,7 @@ async def test_cover( state="closed", ).withValue( 1.0 if cover_entities[testcover].unique_id == "cover_closed" else 0.0 - ).assertInBody(body) + ).assert_in_metrics(body) EntityMetric( metric_name="cover_state", @@ -999,7 +999,7 @@ async def test_cover( state="opening", ).withValue( 1.0 if cover_entities[testcover].unique_id == "cover_opening" else 0.0 - ).assertInBody(body) + ).assert_in_metrics(body) EntityMetric( metric_name="cover_state", @@ -1009,7 +1009,7 @@ async def test_cover( state="closing", ).withValue( 1.0 if cover_entities[testcover].unique_id == "cover_closing" else 0.0 - ).assertInBody(body) + ).assert_in_metrics(body) if testcover == "cover_position": EntityMetric( @@ -1017,7 +1017,7 @@ async def test_cover( domain="cover", friendly_name=cover_entities[testcover].original_name, entity=cover_entities[testcover].entity_id, - ).withValue(50.0).assertInBody(body) + ).withValue(50.0).assert_in_metrics(body) if testcover == "cover_tilt_position": EntityMetric( @@ -1025,7 +1025,7 @@ async def test_cover( domain="cover", friendly_name=cover_entities[testcover].original_name, entity=cover_entities[testcover].entity_id, - ).withValue(50.0).assertInBody(body) + ).withValue(50.0).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -1040,14 +1040,14 @@ async def test_device_tracker( domain="device_tracker", friendly_name="Phone", entity="device_tracker.phone", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="device_tracker_state", domain="device_tracker", friendly_name="Watch", entity="device_tracker.watch", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -1062,13 +1062,13 @@ async def test_person( domain="person", friendly_name="Bob", entity="person.bob", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="person_state", domain="person", friendly_name="Alice", entity="person.alice", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -1083,7 +1083,7 @@ async def test_counter( domain="counter", friendly_name="None", entity="counter.counter", - ).withValue(2.0).assertInBody(body) + ).withValue(2.0).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -1098,13 +1098,13 @@ async def test_update( domain="update", friendly_name="Firmware", entity="update.firmware", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="update_state", domain="update", friendly_name="Addon", entity="update.addon", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -1124,28 +1124,28 @@ async def test_renaming_entity_name( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(15.6).assertInBody(body) + ).withValue(15.6).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(54.0).assertInBody(body) + ).withValue(54.0).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="climate_action", @@ -1153,7 +1153,7 @@ async def test_renaming_entity_name( friendly_name="HeatPump", entity="climate.heatpump", action="heating", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="climate_action", @@ -1161,7 +1161,7 @@ async def test_renaming_entity_name( friendly_name="HeatPump", entity="climate.heatpump", action="cooling", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) assert "sensor.outside_temperature" in entity_registry.entities assert "climate.heatpump" in entity_registry.entities @@ -1204,14 +1204,14 @@ async def test_renaming_entity_name( domain="sensor", friendly_name="Outside Temperature Renamed", entity="sensor.outside_temperature", - ).withValue(15.6).assertInBody(body) + ).withValue(15.6).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature Renamed", entity="sensor.outside_temperature", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="climate_action", @@ -1219,7 +1219,7 @@ async def test_renaming_entity_name( friendly_name="HeatPump Renamed", entity="climate.heatpump", action="heating", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="climate_action", @@ -1227,7 +1227,7 @@ async def test_renaming_entity_name( friendly_name="HeatPump Renamed", entity="climate.heatpump", action="cooling", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) # Keep other sensors EntityMetric( @@ -1235,14 +1235,14 @@ async def test_renaming_entity_name( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(54.0).assertInBody(body) + ).withValue(54.0).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -1262,28 +1262,28 @@ async def test_renaming_entity_id( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(15.6).assertInBody(body) + ).withValue(15.6).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(54.0).assertInBody(body) + ).withValue(54.0).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) assert "sensor.outside_temperature" in entity_registry.entities assert "climate.heatpump" in entity_registry.entities @@ -1308,14 +1308,14 @@ async def test_renaming_entity_id( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature_renamed", - ).withValue(15.6).assertInBody(body) + ).withValue(15.6).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature_renamed", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) # Keep other sensors EntityMetric( @@ -1323,13 +1323,13 @@ async def test_renaming_entity_id( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(54.0).assertInBody(body) + ).withValue(54.0).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -1349,28 +1349,28 @@ async def test_deleting_entity( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(15.6).assertInBody(body) + ).withValue(15.6).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(54.0).assertInBody(body) + ).withValue(54.0).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="climate_action", @@ -1378,7 +1378,7 @@ async def test_deleting_entity( friendly_name="HeatPump", entity="climate.heatpump", action="heating", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="climate_action", @@ -1386,7 +1386,7 @@ async def test_deleting_entity( friendly_name="HeatPump", entity="climate.heatpump", action="cooling", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) assert "sensor.outside_temperature" in entity_registry.entities assert "climate.heatpump" in entity_registry.entities @@ -1409,14 +1409,14 @@ async def test_deleting_entity( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(54.0).assertInBody(body) + ).withValue(54.0).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -1438,35 +1438,35 @@ async def test_disabling_entity( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(15.6).assertInBody(body) + ).withValue(15.6).assert_in_metrics(body) EntityMetric( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="state_change_created", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).assertInBody(body) + ).assert_in_metrics(body) EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(54.0).assertInBody(body) + ).withValue(54.0).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="climate_action", @@ -1474,7 +1474,7 @@ async def test_disabling_entity( friendly_name="HeatPump", entity="climate.heatpump", action="heating", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="climate_action", @@ -1482,7 +1482,7 @@ async def test_disabling_entity( friendly_name="HeatPump", entity="climate.heatpump", action="cooling", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) assert "sensor.outside_temperature" in entity_registry.entities assert "climate.heatpump" in entity_registry.entities @@ -1511,14 +1511,14 @@ async def test_disabling_entity( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(54.0).assertInBody(body) + ).withValue(54.0).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) @pytest.mark.parametrize("namespace", [""]) @@ -1539,42 +1539,42 @@ async def test_entity_becomes_unavailable_with_export( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(15.6).assertInBody(body) + ).withValue(15.6).assert_in_metrics(body) EntityMetric( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="sensor_humidity_percent", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(54.0).assertInBody(body) + ).withValue(54.0).assert_in_metrics(body) EntityMetric( metric_name="state_change_total", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) # Make sensor_1 unavailable. set_state_with_entry( @@ -1590,21 +1590,21 @@ async def test_entity_becomes_unavailable_with_export( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(15.6).assertInBody(body) + ).withValue(15.6).assert_in_metrics(body) EntityMetric( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(2.0).assertInBody(body) + ).withValue(2.0).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(0.0).assertInBody(body) + ).withValue(0.0).assert_in_metrics(body) # The other sensor should be unchanged. EntityMetric( @@ -1612,21 +1612,21 @@ async def test_entity_becomes_unavailable_with_export( domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(54.0).assertInBody(body) + ).withValue(54.0).assert_in_metrics(body) EntityMetric( metric_name="state_change_total", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Humidity", entity="sensor.outside_humidity", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) # Bring sensor_1 back and check that it is correct. set_state_with_entry(hass, data["sensor_1"], 200.0, data["sensor_1_attributes"]) @@ -1639,21 +1639,21 @@ async def test_entity_becomes_unavailable_with_export( domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(200.0).assertInBody(body) + ).withValue(200.0).assert_in_metrics(body) EntityMetric( metric_name="state_change_total", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(3.0).assertInBody(body) + ).withValue(3.0).assert_in_metrics(body) EntityMetric( metric_name="entity_available", domain="sensor", friendly_name="Outside Temperature", entity="sensor.outside_temperature", - ).withValue(1).assertInBody(body) + ).withValue(1).assert_in_metrics(body) @pytest.fixture(name="sensor_entities") From e44dcce0e4e9e6077d14ad915ecd7bec0cd962b8 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Tue, 1 Oct 2024 15:51:41 -0700 Subject: [PATCH 59/62] Tests cleaned up a bit more --- tests/components/prometheus/test_init.py | 81 ++++++++++++++++-------- 1 file changed, 55 insertions(+), 26 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index e43d3fc539d386..4a98a76b4a06d5 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -3,7 +3,7 @@ from dataclasses import dataclass import datetime from http import HTTPStatus -from typing import Any +from typing import Any, Self from unittest import mock from freezegun import freeze_time @@ -94,17 +94,26 @@ class EntityMetric: metric_name: str labels: dict[str, str] + @classmethod + def required_labels(cls) -> list[str]: + """List of all required labels for a Prometheus metric.""" + return [ + "domain", + "friendly_name", + "entity", + ] + def __init__(self, metric_name: str, **kwargs: Any) -> None: """Create a new EntityMetric based on metric name and labels.""" self.metric_name = metric_name self.labels = kwargs # Labels that are required for all entities. - for labelname in ("domain", "friendly_name", "entity"): + for labelname in self.required_labels(): assert labelname in self.labels assert self.labels[labelname] != "" - def withValue(self, value: float): + def withValue(self, value: float) -> Self: """Return a metric with value.""" return EntityMetricWithValue(self, value) @@ -120,11 +129,11 @@ def _in_metrics(self, metrics: list[str]) -> bool: """Report whether this metric exists in the provided Prometheus output.""" return any(line.startswith(self._metric_name_string) for line in metrics) - def assert_in_metrics(self, metrics: list[str]): + def assert_in_metrics(self, metrics: list[str]) -> None: """Assert that this metric exists in the provided Prometheus output.""" assert self._in_metrics(metrics) - def assert_not_in_metrics(self, metrics: list[str]): + def assert_not_in_metrics(self, metrics: list[str]) -> None: """Assert that this metric does not exist in Prometheus output.""" assert not self._in_metrics(metrics) @@ -145,7 +154,7 @@ def _metric_string(self) -> str: value = floatToGoString(self.value) return f"{self._metric_name_string} {value}" - def assert_in_metrics(self, metrics: list[str]): + def assert_in_metrics(self, metrics: list[str]) -> None: """Assert that this metric exists in the provided Prometheus output.""" assert self._metric_string in metrics @@ -199,26 +208,42 @@ def test_entity_metric_raises_exception_without_required_labels() -> None: """Test using EntityMetric to raise exception when required labels are missing.""" domain = "sensor" object_id = "outside_temperature" - with pytest.raises(AssertionError): - EntityMetric( - metric_name="homeassistant_sensor_temperature_celsius", - friendly_name="Outside Temperature", - entity=f"{domain}.{object_id}", - ).withValue(17.2) + test_kwargs = { + "metric_name": "homeassistant_sensor_temperature_celsius", + "domain": domain, + "friendly_name": "Outside Temperature", + "entity": f"{domain}.{object_id}", + } - with pytest.raises(AssertionError): - EntityMetric( - metric_name="homeassistant_sensor_temperature_celsius", - domain=domain, - entity=f"{domain}.{object_id}", - ).withValue(17.2) + assert len(EntityMetric.required_labels()) > 0 - with pytest.raises(AssertionError): - EntityMetric( - metric_name="homeassistant_sensor_temperature_celsius", - domain=domain, - friendly_name="Outside Temperature", - ).withValue(17.2) + for labelname in EntityMetric.required_labels(): + label_kwargs = dict(test_kwargs) + # Delete the required label and ensure we get an exception + del label_kwargs[labelname] + with pytest.raises(AssertionError): + EntityMetric(**label_kwargs) + + +def test_entity_metric_raises_exception_if_required_label_is_empty_string() -> None: + """Test using EntityMetric to raise exception when required label value is empty string.""" + domain = "sensor" + object_id = "outside_temperature" + test_kwargs = { + "metric_name": "homeassistant_sensor_temperature_celsius", + "domain": domain, + "friendly_name": "Outside Temperature", + "entity": f"{domain}.{object_id}", + } + + assert len(EntityMetric.required_labels()) > 0 + + for labelname in EntityMetric.required_labels(): + label_kwargs = dict(test_kwargs) + # Replace the required label with "" and ensure we get an exception + label_kwargs[labelname] = "" + with pytest.raises(AssertionError): + EntityMetric(**label_kwargs) def test_entity_metric_generates_alphabetically_ordered_labels() -> None: @@ -230,7 +255,9 @@ def test_entity_metric_generates_alphabetically_ordered_labels() -> None: "homeassistant_sensor_temperature_celsius{" 'domain="sensor",' 'entity="sensor.outside_temperature",' - 'friendly_name="Outside Temperature"}' + 'friendly_name="Outside Temperature",' + 'zed_label="foo"' + "}" " 17.2" ) @@ -239,13 +266,15 @@ def test_entity_metric_generates_alphabetically_ordered_labels() -> None: domain=domain, entity=f"{domain}.{object_id}", friendly_name="Outside Temperature", + zed_label="foo", ).withValue(17.2) assert ordered_entity_metric._metric_string == static_metric_string unordered_entity_metric = EntityMetric( metric_name="homeassistant_sensor_temperature_celsius", - friendly_name="Outside Temperature", + zed_label="foo", entity=f"{domain}.{object_id}", + friendly_name="Outside Temperature", domain=domain, ).withValue(17.2) assert unordered_entity_metric._metric_string == static_metric_string From 714375a2da27845d5d7655cb67142f54f7a93afa Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 2 Oct 2024 09:44:56 -0700 Subject: [PATCH 60/62] Minor updates as suggested --- tests/components/prometheus/test_init.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 4a98a76b4a06d5..d9423906f6f6e6 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -527,7 +527,7 @@ async def test_sensor_without_unit( domain="sensor", friendly_name="Text", entity="sensor.text", - ).withValue(0.0).assert_not_in_metrics(body) + ).assert_not_in_metrics(body) EntityMetric( metric_name="sensor_unit_text", From a1b93499645603b8baae127b3d734e3c69a3e2fe Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 2 Oct 2024 22:52:08 -0700 Subject: [PATCH 61/62] Another pass on assert with metrics helper --- tests/components/prometheus/test_init.py | 45 ++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index d9423906f6f6e6..3aedf1a413177a 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -351,6 +351,51 @@ def test_entity_metric_generates_metric_string_with_non_required_labels() -> Non ) +def test_entity_metric_with_value_assert_in_metrics() -> None: + """Test using EntityMetricWithValue assert_in_metrics.""" + temp_metric = ( + "homeassistant_sensor_temperature_celsius{" + 'domain="sensor",' + 'entity="sensor.outside_temperature",' + 'foo="bar",' + 'friendly_name="Outside Temperature"' + "}" + " 17.2" + ) + climate_metric = ( + "climate_preset_mode{" + 'domain="climate",' + 'entity="climate.ecobee",' + 'friendly_name="Ecobee",' + 'mode="away"' + "}" + " 1.0" + ) + metrics = [ + temp_metric, + climate_metric, + ] + temp_entity_metric = EntityMetric( + metric_name="homeassistant_sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + foo="bar", + ).withValue(17.2) + assert temp_entity_metric._metric_string == temp_metric + temp_entity_metric.assert_in_metrics(metrics) + + climate_entity_metric = EntityMetric( + metric_name="climate_preset_mode", + domain="climate", + friendly_name="Ecobee", + entity="climate.ecobee", + mode="away", + ).withValue(1) + assert climate_entity_metric._metric_string == climate_metric + climate_entity_metric.assert_in_metrics(metrics) + + @pytest.fixture(name="client") async def setup_prometheus_client( hass: HomeAssistant, From dbd3d0fbcd0f34aad4e297facb2c3e650cd18938 Mon Sep 17 00:00:00 2001 From: Jordan Zucker Date: Wed, 2 Oct 2024 23:00:39 -0700 Subject: [PATCH 62/62] Now this is fully tested --- tests/components/prometheus/test_init.py | 68 +++++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/tests/components/prometheus/test_init.py b/tests/components/prometheus/test_init.py index 3aedf1a413177a..5952bd25558240 100644 --- a/tests/components/prometheus/test_init.py +++ b/tests/components/prometheus/test_init.py @@ -351,8 +351,72 @@ def test_entity_metric_generates_metric_string_with_non_required_labels() -> Non ) -def test_entity_metric_with_value_assert_in_metrics() -> None: - """Test using EntityMetricWithValue assert_in_metrics.""" +def test_entity_metric_assert_helpers() -> None: + """Test using EntityMetric for both assert_in_metrics and assert_not_in_metrics.""" + temp_metric = ( + "homeassistant_sensor_temperature_celsius{" + 'domain="sensor",' + 'entity="sensor.outside_temperature",' + 'foo="bar",' + 'friendly_name="Outside Temperature"' + "}" + ) + climate_metric = ( + "climate_preset_mode{" + 'domain="climate",' + 'entity="climate.ecobee",' + 'friendly_name="Ecobee",' + 'mode="away"' + "}" + ) + excluded_cover_metric = ( + "cover_state{" + 'domain="cover",' + 'entity="cover.curtain",' + 'friendly_name="Curtain",' + 'state="open"' + "}" + ) + metrics = [ + temp_metric, + climate_metric, + ] + # First make sure the excluded metric is not present + assert excluded_cover_metric not in metrics + # now check for actual metrics + temp_entity_metric = EntityMetric( + metric_name="homeassistant_sensor_temperature_celsius", + domain="sensor", + friendly_name="Outside Temperature", + entity="sensor.outside_temperature", + foo="bar", + ) + assert temp_entity_metric._metric_name_string == temp_metric + temp_entity_metric.assert_in_metrics(metrics) + + climate_entity_metric = EntityMetric( + metric_name="climate_preset_mode", + domain="climate", + friendly_name="Ecobee", + entity="climate.ecobee", + mode="away", + ) + assert climate_entity_metric._metric_name_string == climate_metric + climate_entity_metric.assert_in_metrics(metrics) + + excluded_cover_entity_metric = EntityMetric( + metric_name="cover_state", + domain="cover", + friendly_name="Curtain", + entity="cover.curtain", + state="open", + ) + assert excluded_cover_entity_metric._metric_name_string == excluded_cover_metric + excluded_cover_entity_metric.assert_not_in_metrics(metrics) + + +def test_entity_metric_with_value_assert_helpers() -> None: + """Test using EntityMetricWithValue helpers, which is only assert_in_metrics.""" temp_metric = ( "homeassistant_sensor_temperature_celsius{" 'domain="sensor",'