Skip to content

Commit e2444b4

Browse files
authored
Properly await for AddInclusionBounds (#47)
Without this, the function call will never actually run. I'm not sure if this was working anyways because of some obscure implementation detail in grpcio, but in normal python a not awaited async function should never actually run. Besides this, for sure errors can't be really caught without the await either. This was detected while migrating to betterproto, as betterproto has correct type hints.
2 parents 7325c98 + 4e97c7a commit e2444b4

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

RELEASE_NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@
1616

1717
- Fix a leakage of `GrpcStreamBroadcaster` instances.
1818
- The user-passed retry strategy was not properly used by the data streaming methods.
19+
- The client `set_bounds()` method might have not done anything and if it did, errors were not properly raised.

src/frequenz/client/microgrid/_client.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from frequenz.channels import Receiver
3333
from frequenz.client.base import retry, streaming
3434
from google.protobuf.empty_pb2 import Empty # pylint: disable=no-name-in-module
35+
from google.protobuf.timestamp_pb2 import Timestamp # pylint: disable=no-name-in-module
3536

3637
from ._component import (
3738
Component,
@@ -425,7 +426,7 @@ async def set_power(self, component_id: int, power_w: float) -> None:
425426
"""
426427
try:
427428
await cast(
428-
Awaitable[PbSetPowerActiveParam],
429+
Awaitable[Empty],
429430
self.api.SetPowerActive(
430431
PbSetPowerActiveParam(component_id=component_id, power=power_w),
431432
timeout=int(DEFAULT_GRPC_CALL_TIMEOUT),
@@ -469,11 +470,15 @@ async def set_bounds(
469470

470471
target_metric = PbSetBoundsParam.TargetMetric.TARGET_METRIC_POWER_ACTIVE
471472
try:
472-
self.api.AddInclusionBounds(
473-
PbSetBoundsParam(
474-
component_id=component_id,
475-
target_metric=target_metric,
476-
bounds=PbBounds(lower=lower, upper=upper),
473+
await cast(
474+
Awaitable[Timestamp],
475+
self.api.AddInclusionBounds(
476+
PbSetBoundsParam(
477+
component_id=component_id,
478+
target_metric=target_metric,
479+
bounds=PbBounds(lower=lower, upper=upper),
480+
),
481+
timeout=int(DEFAULT_GRPC_CALL_TIMEOUT),
477482
),
478483
)
479484
except grpc.aio.AioRpcError as err:

tests/test_timeout.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
ConnectionFilter,
1818
ConnectionList,
1919
PowerLevelParam,
20+
SetBoundsParam,
2021
)
2122
from google.protobuf.empty_pb2 import Empty
23+
from google.protobuf.timestamp_pb2 import Timestamp
2224

2325
# pylint: enable=no-name-in-module
2426
from pytest_mock import MockerFixture
@@ -119,3 +121,31 @@ def mock_set_power(
119121
assert err_ctx.value.code() == grpc.StatusCode.DEADLINE_EXCEEDED
120122

121123
assert await server.graceful_shutdown()
124+
125+
126+
async def test_set_bounds_timeout(mocker: MockerFixture) -> None:
127+
"""Test if the set_power() method properly raises a timeout AioRpcError."""
128+
servicer = MockMicrogridServicer()
129+
130+
def mock_add_inclusion_bounds(
131+
request: SetBoundsParam, context: Any # pylint: disable=unused-argument
132+
) -> Timestamp:
133+
time.sleep(GRPC_SERVER_DELAY)
134+
return Timestamp()
135+
136+
mocker.patch.object(servicer, "AddInclusionBounds", mock_add_inclusion_bounds)
137+
server = MockGrpcServer(servicer, port=57809)
138+
await server.start()
139+
140+
target = "[::]:57809"
141+
grpc_channel = grpc.aio.insecure_channel(target)
142+
client = ApiClient(grpc_channel=grpc_channel, target=target)
143+
144+
bounds_values = [{"lower": 0.0, "upper": 100.0}, {"lower": -10.0, "upper": 1.0}]
145+
146+
for bounds in bounds_values:
147+
with pytest.raises(grpc.aio.AioRpcError) as err_ctx:
148+
await client.set_bounds(component_id=1, **bounds)
149+
assert err_ctx.value.code() == grpc.StatusCode.DEADLINE_EXCEEDED
150+
151+
assert await server.graceful_shutdown()

0 commit comments

Comments
 (0)