Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 61 additions & 2 deletions tests/actor/_power_managing/test_matryoshka.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
"""Tests for the Matryoshka power manager algorithm."""

import asyncio
import re
from datetime import datetime, timedelta, timezone

import pytest
from frequenz.quantities import Power

from frequenz.sdk import timeseries
Expand Down Expand Up @@ -36,13 +38,14 @@ def tgt_power( # pylint: disable=too-many-arguments,too-many-positional-argumen
expected: float | None,
creation_time: float | None = None,
must_send: bool = False,
batteries: frozenset[int] | None = None,
) -> None:
"""Test the target power calculation."""
self._call_count += 1
tgt_power = self.algorithm.calculate_target_power(
self._batteries,
self._batteries if batteries is None else batteries,
Proposal(
component_ids=self._batteries,
component_ids=self._batteries if batteries is None else batteries,
source_id=f"actor-{priority}",
preferred_power=None if power is None else Power.from_watts(power),
bounds=timeseries.Bounds(
Expand Down Expand Up @@ -368,6 +371,7 @@ async def test_matryoshka_drop_old_proposals() -> None:
With inclusion bounds, and exclusion bounds -30.0 to 30.0.
"""
batteries = frozenset({2, 5})
overlapping_batteries = frozenset({5, 8})

system_bounds = _base_types.SystemBounds(
timestamp=datetime.now(tz=timezone.utc),
Expand Down Expand Up @@ -424,3 +428,58 @@ async def test_matryoshka_drop_old_proposals() -> None:
tester.tgt_power(
priority=1, power=20.0, bounds=(20.0, 50.0), expected=25.0, must_send=True
)

# When all proposals are too old, they are dropped, and the buckets are dropped as
# well. After that, sending a request for a different but overlapping bucket will
# succeed. And it will fail until then.
with pytest.raises(
NotImplementedError,
match=re.escape(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL: re.escape. :D

"PowerManagingActor: component IDs frozenset({8, 5}) are already "
+ "part of another bucket. Overlapping buckets are not yet supported."
),
):
tester.tgt_power(
priority=1,
power=25.0,
bounds=(25.0, 50.0),
expected=25.0,
must_send=True,
batteries=overlapping_batteries,
)

tester.tgt_power(
priority=1,
power=25.0,
bounds=(25.0, 50.0),
creation_time=now - 70.0,
expected=25.0,
must_send=True,
)
tester.tgt_power(
priority=2,
power=25.0,
bounds=(25.0, 50.0),
creation_time=now - 70.0,
expected=25.0,
must_send=True,
)
tester.tgt_power(
priority=3,
power=25.0,
bounds=(25.0, 50.0),
creation_time=now - 70.0,
expected=25.0,
must_send=True,
)

tester.algorithm.drop_old_proposals(now)

tester.tgt_power(
priority=1,
power=25.0,
bounds=(25.0, 50.0),
expected=25.0,
must_send=True,
batteries=overlapping_batteries,
)