Fix flaky energy tests (#89026)

This commit is contained in:
Erik Montnemery 2023-03-02 12:33:04 +01:00 committed by GitHub
parent aa92d05317
commit 28e8fae280
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,9 +2,7 @@
import copy import copy
from datetime import timedelta from datetime import timedelta
from typing import Any from typing import Any
from unittest.mock import patch
from freezegun import freeze_time
import pytest import pytest
from homeassistant.components.energy import data from homeassistant.components.energy import data
@ -31,6 +29,8 @@ from homeassistant.util.unit_system import METRIC_SYSTEM, US_CUSTOMARY_SYSTEM
from tests.components.recorder.common import async_wait_recording_done from tests.components.recorder.common import async_wait_recording_done
from tests.typing import WebSocketGenerator from tests.typing import WebSocketGenerator
TEST_TIME_ADVANCE_INTERVAL = timedelta(milliseconds=10)
@pytest.fixture @pytest.fixture
async def setup_integration(recorder_mock): async def setup_integration(recorder_mock):
@ -44,10 +44,10 @@ async def setup_integration(recorder_mock):
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
@freeze_time("2022-04-19 07:53:05") def frozen_time(freezer):
def frozen_time():
"""Freeze clock for tests.""" """Freeze clock for tests."""
return freezer.move_to("2022-04-19 07:53:05")
return freezer
def get_statistics_for_entity(statistics_results, entity_id): def get_statistics_for_entity(statistics_results, entity_id):
@ -139,6 +139,7 @@ async def test_cost_sensor_attributes(
], ],
) )
async def test_cost_sensor_price_entity_total_increasing( async def test_cost_sensor_price_entity_total_increasing(
frozen_time,
setup_integration, setup_integration,
hass: HomeAssistant, hass: HomeAssistant,
hass_storage: dict[str, Any], hass_storage: dict[str, Any],
@ -206,8 +207,7 @@ async def test_cost_sensor_price_entity_total_increasing(
) )
hass.states.async_set("sensor.energy_price", "1") hass.states.async_set("sensor.energy_price", "1")
with patch("homeassistant.util.dt.utcnow", return_value=now): await setup_integration(hass)
await setup_integration(hass)
state = hass.states.get(cost_sensor_entity_id) state = hass.states.get(cost_sensor_entity_id)
assert state.state == initial_cost assert state.state == initial_cost
@ -219,13 +219,12 @@ async def test_cost_sensor_price_entity_total_increasing(
# Optional late setup of dependent entities # Optional late setup of dependent entities
if initial_energy is None: if initial_energy is None:
with patch("homeassistant.util.dt.utcnow", return_value=now): hass.states.async_set(
hass.states.async_set( usage_sensor_entity_id,
usage_sensor_entity_id, "0",
"0", energy_attributes,
energy_attributes, )
) await hass.async_block_till_done()
await hass.async_block_till_done()
state = hass.states.get(cost_sensor_entity_id) state = hass.states.get(cost_sensor_entity_id)
assert state.state == "0.0" assert state.state == "0.0"
@ -242,6 +241,7 @@ async def test_cost_sensor_price_entity_total_increasing(
assert entry.hidden_by is er.RegistryEntryHider.INTEGRATION assert entry.hidden_by is er.RegistryEntryHider.INTEGRATION
# Energy use bumped to 10 kWh # Energy use bumped to 10 kWh
frozen_time.tick(TEST_TIME_ADVANCE_INTERVAL)
hass.states.async_set( hass.states.async_set(
usage_sensor_entity_id, usage_sensor_entity_id,
"10", "10",
@ -268,6 +268,7 @@ async def test_cost_sensor_price_entity_total_increasing(
assert state.attributes[ATTR_LAST_RESET] == last_reset_cost_sensor assert state.attributes[ATTR_LAST_RESET] == last_reset_cost_sensor
# Additional consumption is using the new price # Additional consumption is using the new price
frozen_time.tick(TEST_TIME_ADVANCE_INTERVAL)
hass.states.async_set( hass.states.async_set(
usage_sensor_entity_id, usage_sensor_entity_id,
"14.5", "14.5",
@ -285,6 +286,7 @@ async def test_cost_sensor_price_entity_total_increasing(
assert statistics["stat"]["sum"] == 19.0 assert statistics["stat"]["sum"] == 19.0
# Energy sensor has a small dip, no reset should be detected # Energy sensor has a small dip, no reset should be detected
frozen_time.tick(TEST_TIME_ADVANCE_INTERVAL)
hass.states.async_set( hass.states.async_set(
usage_sensor_entity_id, usage_sensor_entity_id,
"14", "14",
@ -296,6 +298,7 @@ async def test_cost_sensor_price_entity_total_increasing(
assert state.attributes[ATTR_LAST_RESET] == last_reset_cost_sensor assert state.attributes[ATTR_LAST_RESET] == last_reset_cost_sensor
# Energy sensor is reset, with initial state at 4kWh, 0 kWh is used as zero-point # Energy sensor is reset, with initial state at 4kWh, 0 kWh is used as zero-point
frozen_time.tick(TEST_TIME_ADVANCE_INTERVAL)
hass.states.async_set( hass.states.async_set(
usage_sensor_entity_id, usage_sensor_entity_id,
"4", "4",
@ -308,6 +311,7 @@ async def test_cost_sensor_price_entity_total_increasing(
last_reset_cost_sensor = state.attributes[ATTR_LAST_RESET] last_reset_cost_sensor = state.attributes[ATTR_LAST_RESET]
# Energy use bumped to 10 kWh # Energy use bumped to 10 kWh
frozen_time.tick(TEST_TIME_ADVANCE_INTERVAL)
hass.states.async_set( hass.states.async_set(
usage_sensor_entity_id, usage_sensor_entity_id,
"10", "10",
@ -344,6 +348,7 @@ async def test_cost_sensor_price_entity_total_increasing(
) )
@pytest.mark.parametrize("energy_state_class", ["total", "measurement"]) @pytest.mark.parametrize("energy_state_class", ["total", "measurement"])
async def test_cost_sensor_price_entity_total( async def test_cost_sensor_price_entity_total(
frozen_time,
setup_integration, setup_integration,
hass: HomeAssistant, hass: HomeAssistant,
hass_storage: dict[str, Any], hass_storage: dict[str, Any],
@ -360,7 +365,9 @@ async def test_cost_sensor_price_entity_total(
"""Test energy cost price from total type sensor entity.""" """Test energy cost price from total type sensor entity."""
def _compile_statistics(_): def _compile_statistics(_):
return compile_statistics(hass, now, now + timedelta(seconds=1)).platform_stats return compile_statistics(
hass, now, now + timedelta(seconds=0.17)
).platform_stats
energy_attributes = { energy_attributes = {
ATTR_UNIT_OF_MEASUREMENT: UnitOfEnergy.KILO_WATT_HOUR, ATTR_UNIT_OF_MEASUREMENT: UnitOfEnergy.KILO_WATT_HOUR,
@ -413,8 +420,7 @@ async def test_cost_sensor_price_entity_total(
) )
hass.states.async_set("sensor.energy_price", "1") hass.states.async_set("sensor.energy_price", "1")
with patch("homeassistant.util.dt.utcnow", return_value=now): await setup_integration(hass)
await setup_integration(hass)
state = hass.states.get(cost_sensor_entity_id) state = hass.states.get(cost_sensor_entity_id)
assert state.state == initial_cost assert state.state == initial_cost
@ -426,13 +432,12 @@ async def test_cost_sensor_price_entity_total(
# Optional late setup of dependent entities # Optional late setup of dependent entities
if initial_energy is None: if initial_energy is None:
with patch("homeassistant.util.dt.utcnow", return_value=now): hass.states.async_set(
hass.states.async_set( usage_sensor_entity_id,
usage_sensor_entity_id, "0",
"0", {**energy_attributes, **{"last_reset": last_reset}},
{**energy_attributes, **{"last_reset": last_reset}}, )
) await hass.async_block_till_done()
await hass.async_block_till_done()
state = hass.states.get(cost_sensor_entity_id) state = hass.states.get(cost_sensor_entity_id)
assert state.state == "0.0" assert state.state == "0.0"
@ -449,6 +454,7 @@ async def test_cost_sensor_price_entity_total(
assert entry.hidden_by is er.RegistryEntryHider.INTEGRATION assert entry.hidden_by is er.RegistryEntryHider.INTEGRATION
# Energy use bumped to 10 kWh # Energy use bumped to 10 kWh
frozen_time.tick(TEST_TIME_ADVANCE_INTERVAL)
hass.states.async_set( hass.states.async_set(
usage_sensor_entity_id, usage_sensor_entity_id,
"10", "10",
@ -475,6 +481,7 @@ async def test_cost_sensor_price_entity_total(
assert state.attributes[ATTR_LAST_RESET] == last_reset_cost_sensor assert state.attributes[ATTR_LAST_RESET] == last_reset_cost_sensor
# Additional consumption is using the new price # Additional consumption is using the new price
frozen_time.tick(TEST_TIME_ADVANCE_INTERVAL)
hass.states.async_set( hass.states.async_set(
usage_sensor_entity_id, usage_sensor_entity_id,
"14.5", "14.5",
@ -492,6 +499,7 @@ async def test_cost_sensor_price_entity_total(
assert statistics["stat"]["sum"] == 19.0 assert statistics["stat"]["sum"] == 19.0
# Energy sensor has a small dip # Energy sensor has a small dip
frozen_time.tick(TEST_TIME_ADVANCE_INTERVAL)
hass.states.async_set( hass.states.async_set(
usage_sensor_entity_id, usage_sensor_entity_id,
"14", "14",
@ -503,7 +511,8 @@ async def test_cost_sensor_price_entity_total(
assert state.attributes[ATTR_LAST_RESET] == last_reset_cost_sensor assert state.attributes[ATTR_LAST_RESET] == last_reset_cost_sensor
# Energy sensor is reset, with initial state at 4kWh, 0 kWh is used as zero-point # Energy sensor is reset, with initial state at 4kWh, 0 kWh is used as zero-point
last_reset = (now + timedelta(seconds=1)).isoformat() frozen_time.tick(TEST_TIME_ADVANCE_INTERVAL)
last_reset = dt_util.utcnow()
hass.states.async_set( hass.states.async_set(
usage_sensor_entity_id, usage_sensor_entity_id,
"4", "4",
@ -516,6 +525,7 @@ async def test_cost_sensor_price_entity_total(
last_reset_cost_sensor = state.attributes[ATTR_LAST_RESET] last_reset_cost_sensor = state.attributes[ATTR_LAST_RESET]
# Energy use bumped to 10 kWh # Energy use bumped to 10 kWh
frozen_time.tick(TEST_TIME_ADVANCE_INTERVAL)
hass.states.async_set( hass.states.async_set(
usage_sensor_entity_id, usage_sensor_entity_id,
"10", "10",
@ -552,6 +562,7 @@ async def test_cost_sensor_price_entity_total(
) )
@pytest.mark.parametrize("energy_state_class", ["total"]) @pytest.mark.parametrize("energy_state_class", ["total"])
async def test_cost_sensor_price_entity_total_no_reset( async def test_cost_sensor_price_entity_total_no_reset(
frozen_time,
setup_integration, setup_integration,
hass: HomeAssistant, hass: HomeAssistant,
hass_storage: dict[str, Any], hass_storage: dict[str, Any],
@ -620,8 +631,7 @@ async def test_cost_sensor_price_entity_total_no_reset(
) )
hass.states.async_set("sensor.energy_price", "1") hass.states.async_set("sensor.energy_price", "1")
with patch("homeassistant.util.dt.utcnow", return_value=now): await setup_integration(hass)
await setup_integration(hass)
state = hass.states.get(cost_sensor_entity_id) state = hass.states.get(cost_sensor_entity_id)
assert state.state == initial_cost assert state.state == initial_cost
@ -633,13 +643,12 @@ async def test_cost_sensor_price_entity_total_no_reset(
# Optional late setup of dependent entities # Optional late setup of dependent entities
if initial_energy is None: if initial_energy is None:
with patch("homeassistant.util.dt.utcnow", return_value=now): hass.states.async_set(
hass.states.async_set( usage_sensor_entity_id,
usage_sensor_entity_id, "0",
"0", energy_attributes,
energy_attributes, )
) await hass.async_block_till_done()
await hass.async_block_till_done()
state = hass.states.get(cost_sensor_entity_id) state = hass.states.get(cost_sensor_entity_id)
assert state.state == "0.0" assert state.state == "0.0"
@ -656,6 +665,7 @@ async def test_cost_sensor_price_entity_total_no_reset(
assert entry.hidden_by is er.RegistryEntryHider.INTEGRATION assert entry.hidden_by is er.RegistryEntryHider.INTEGRATION
# Energy use bumped to 10 kWh # Energy use bumped to 10 kWh
frozen_time.tick(TEST_TIME_ADVANCE_INTERVAL)
hass.states.async_set( hass.states.async_set(
usage_sensor_entity_id, usage_sensor_entity_id,
"10", "10",
@ -682,6 +692,7 @@ async def test_cost_sensor_price_entity_total_no_reset(
assert state.attributes[ATTR_LAST_RESET] == last_reset_cost_sensor assert state.attributes[ATTR_LAST_RESET] == last_reset_cost_sensor
# Additional consumption is using the new price # Additional consumption is using the new price
frozen_time.tick(TEST_TIME_ADVANCE_INTERVAL)
hass.states.async_set( hass.states.async_set(
usage_sensor_entity_id, usage_sensor_entity_id,
"14.5", "14.5",
@ -699,6 +710,7 @@ async def test_cost_sensor_price_entity_total_no_reset(
assert statistics["stat"]["sum"] == 19.0 assert statistics["stat"]["sum"] == 19.0
# Energy sensor has a small dip # Energy sensor has a small dip
frozen_time.tick(TEST_TIME_ADVANCE_INTERVAL)
hass.states.async_set( hass.states.async_set(
usage_sensor_entity_id, usage_sensor_entity_id,
"14", "14",
@ -759,8 +771,6 @@ async def test_cost_sensor_handle_energy_units(
"data": energy_data, "data": energy_data,
} }
now = dt_util.utcnow()
# Initial state: 10kWh # Initial state: 10kWh
hass.states.async_set( hass.states.async_set(
"sensor.energy_consumption", "sensor.energy_consumption",
@ -768,8 +778,7 @@ async def test_cost_sensor_handle_energy_units(
energy_attributes, energy_attributes,
) )
with patch("homeassistant.util.dt.utcnow", return_value=now): await setup_integration(hass)
await setup_integration(hass)
state = hass.states.get("sensor.energy_consumption_cost") state = hass.states.get("sensor.energy_consumption_cost")
assert state.state == "0.0" assert state.state == "0.0"
@ -833,8 +842,6 @@ async def test_cost_sensor_handle_price_units(
"data": energy_data, "data": energy_data,
} }
now = dt_util.utcnow()
# Initial state: 10kWh # Initial state: 10kWh
hass.states.async_set("sensor.energy_price", "2", price_attributes) hass.states.async_set("sensor.energy_price", "2", price_attributes)
hass.states.async_set( hass.states.async_set(
@ -843,8 +850,7 @@ async def test_cost_sensor_handle_price_units(
energy_attributes, energy_attributes,
) )
with patch("homeassistant.util.dt.utcnow", return_value=now): await setup_integration(hass)
await setup_integration(hass)
state = hass.states.get("sensor.energy_consumption_cost") state = hass.states.get("sensor.energy_consumption_cost")
assert state.state == "0.0" assert state.state == "0.0"
@ -889,16 +895,13 @@ async def test_cost_sensor_handle_gas(
"data": energy_data, "data": energy_data,
} }
now = dt_util.utcnow()
hass.states.async_set( hass.states.async_set(
"sensor.gas_consumption", "sensor.gas_consumption",
100, 100,
energy_attributes, energy_attributes,
) )
with patch("homeassistant.util.dt.utcnow", return_value=now): await setup_integration(hass)
await setup_integration(hass)
state = hass.states.get("sensor.gas_consumption_cost") state = hass.states.get("sensor.gas_consumption_cost")
assert state.state == "0.0" assert state.state == "0.0"
@ -939,16 +942,13 @@ async def test_cost_sensor_handle_gas_kwh(
"data": energy_data, "data": energy_data,
} }
now = dt_util.utcnow()
hass.states.async_set( hass.states.async_set(
"sensor.gas_consumption", "sensor.gas_consumption",
100, 100,
energy_attributes, energy_attributes,
) )
with patch("homeassistant.util.dt.utcnow", return_value=now): await setup_integration(hass)
await setup_integration(hass)
state = hass.states.get("sensor.gas_consumption_cost") state = hass.states.get("sensor.gas_consumption_cost")
assert state.state == "0.0" assert state.state == "0.0"
@ -1004,16 +1004,13 @@ async def test_cost_sensor_handle_water(
"data": energy_data, "data": energy_data,
} }
now = dt_util.utcnow()
hass.states.async_set( hass.states.async_set(
"sensor.water_consumption", "sensor.water_consumption",
100, 100,
energy_attributes, energy_attributes,
) )
with patch("homeassistant.util.dt.utcnow", return_value=now): await setup_integration(hass)
await setup_integration(hass)
state = hass.states.get("sensor.water_consumption_cost") state = hass.states.get("sensor.water_consumption_cost")
assert state.state == "0.0" assert state.state == "0.0"
@ -1065,16 +1062,13 @@ async def test_cost_sensor_wrong_state_class(
"data": energy_data, "data": energy_data,
} }
now = dt_util.utcnow()
hass.states.async_set( hass.states.async_set(
"sensor.energy_consumption", "sensor.energy_consumption",
10000, 10000,
energy_attributes, energy_attributes,
) )
with patch("homeassistant.util.dt.utcnow", return_value=now): await setup_integration(hass)
await setup_integration(hass)
state = hass.states.get("sensor.energy_consumption_cost") state = hass.states.get("sensor.energy_consumption_cost")
assert state.state == STATE_UNKNOWN assert state.state == STATE_UNKNOWN
@ -1130,16 +1124,13 @@ async def test_cost_sensor_state_class_measurement_no_reset(
"data": energy_data, "data": energy_data,
} }
now = dt_util.utcnow()
hass.states.async_set( hass.states.async_set(
"sensor.energy_consumption", "sensor.energy_consumption",
10000, 10000,
energy_attributes, energy_attributes,
) )
with patch("homeassistant.util.dt.utcnow", return_value=now): await setup_integration(hass)
await setup_integration(hass)
state = hass.states.get("sensor.energy_consumption_cost") state = hass.states.get("sensor.energy_consumption_cost")
assert state.state == STATE_UNKNOWN assert state.state == STATE_UNKNOWN
@ -1176,7 +1167,6 @@ async def test_inherit_source_unique_id(
"data": energy_data, "data": energy_data,
} }
now = dt_util.utcnow()
entity_registry = er.async_get(hass) entity_registry = er.async_get(hass)
source_entry = entity_registry.async_get_or_create( source_entry = entity_registry.async_get_or_create(
"sensor", "test", "123456", suggested_object_id="gas_consumption" "sensor", "test", "123456", suggested_object_id="gas_consumption"
@ -1191,8 +1181,7 @@ async def test_inherit_source_unique_id(
}, },
) )
with patch("homeassistant.util.dt.utcnow", return_value=now): await setup_integration(hass)
await setup_integration(hass)
state = hass.states.get("sensor.gas_consumption_cost") state = hass.states.get("sensor.gas_consumption_cost")
assert state assert state