Skip to content

Commit 2cb41c4

Browse files
Add a test for power partial failure result
The test covers the case where the microgrid, for any reason, fails to set power for one of the batteries in the power request. Signed-off-by: Daniel Zullo <[email protected]>
1 parent dedd6d4 commit 2cb41c4

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

tests/actor/power_distributing/test_power_distributing.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from frequenz.sdk.actor.power_distributing.result import (
2525
Error,
2626
OutOfBounds,
27+
PartialFailure,
2728
PowerBounds,
2829
Result,
2930
Success,
@@ -1249,3 +1250,65 @@ async def test_not_all_batteries_are_working(self, mocker: MockerFixture) -> Non
12491250
assert result.request == request
12501251

12511252
await mockgrid.cleanup()
1253+
1254+
async def test_partial_failure_result(self, mocker: MockerFixture) -> None:
1255+
"""Test power results when the microgrid failed to set power for one of the batteries."""
1256+
mockgrid = MockMicrogrid(grid_meter=False)
1257+
mockgrid.add_batteries(3)
1258+
await mockgrid.start(mocker)
1259+
await self.init_component_data(mockgrid)
1260+
1261+
mocker.patch("asyncio.sleep", new_callable=AsyncMock)
1262+
1263+
batteries = {9, 19, 29}
1264+
failed_batteries = {9}
1265+
failed_power = 500.0
1266+
1267+
attrs = {"get_working_batteries.return_value": batteries}
1268+
mocker.patch(
1269+
"frequenz.sdk.actor.power_distributing.power_distributing.BatteryPoolStatus",
1270+
return_value=MagicMock(
1271+
spec=BatteryPoolStatus,
1272+
**attrs,
1273+
),
1274+
)
1275+
1276+
mocker.patch(
1277+
"frequenz.sdk.actor.power_distributing.PowerDistributingActor._parse_result",
1278+
return_value=(failed_power, failed_batteries),
1279+
)
1280+
1281+
requests_channel = Broadcast[Request]("power_distributor requests")
1282+
results_channel = Broadcast[Result]("power_distributor results")
1283+
1284+
battery_status_channel = Broadcast[BatteryStatus]("battery_status")
1285+
async with PowerDistributingActor(
1286+
requests_receiver=requests_channel.new_receiver(),
1287+
results_sender=results_channel.new_sender(),
1288+
battery_status_sender=battery_status_channel.new_sender(),
1289+
):
1290+
request = Request(
1291+
power=Power.from_kilowatts(1.70),
1292+
batteries=batteries,
1293+
request_timeout=SAFETY_TIMEOUT,
1294+
)
1295+
1296+
await requests_channel.new_sender().send(request)
1297+
result_rx = results_channel.new_receiver()
1298+
1299+
done, pending = await asyncio.wait(
1300+
[asyncio.create_task(result_rx.receive())],
1301+
timeout=SAFETY_TIMEOUT.total_seconds(),
1302+
)
1303+
assert len(pending) == 0
1304+
assert len(done) == 1
1305+
result = done.pop().result()
1306+
assert isinstance(result, PartialFailure)
1307+
assert result.succeeded_batteries == batteries - failed_batteries
1308+
assert result.failed_batteries == failed_batteries
1309+
assert result.succeeded_power.isclose(Power.from_watts(1000.0))
1310+
assert result.failed_power.isclose(Power.from_watts(failed_power))
1311+
assert result.excess_power.isclose(Power.from_watts(200.0))
1312+
assert result.request == request
1313+
1314+
await mockgrid.cleanup()

0 commit comments

Comments
 (0)