Skip to content

Commit bf7f91c

Browse files
authored
Fix that duration=0 was sent & received as None (frequenz-floss#126)
2 parents 2f62a10 + a0a069b commit bf7f91c

File tree

6 files changed

+45
-12
lines changed

6 files changed

+45
-12
lines changed

RELEASE_NOTES.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,4 @@
22

33
## Bug Fixes
44

5-
* Fix missing dependency in last release.
6-
* The `FakeClient.set_dispatches()` method now correctly updates `FakeService._last_id` which is used to generate unique dispatch IDs.
7-
* Fix that streams were globally shared between all clients.
8-
5+
* Fix that duration=0 was sent & received as None.

src/frequenz/client/dispatch/__main__.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,10 @@ def format_line(key: str, value: str, color: str = "cyan") -> str:
128128
lines.append(format_line("ID", str(dispatch.id)))
129129
lines.append(format_line("Type", str(dispatch.type)))
130130
lines.append(format_line("Start Time", format_datetime(dispatch.start_time)))
131-
if dispatch.duration:
131+
if dispatch.duration is not None:
132132
lines.append(format_line("Duration", str(dispatch.duration)))
133133
else:
134-
lines.append(format_line("Duration", "Infinite"))
134+
lines.append(format_line("Duration", "Indefinite"))
135135
lines.append(format_line("Target", target_str))
136136
lines.append(format_line("Active", str(dispatch.active)))
137137
lines.append(format_line("Dry Run", str(dispatch.dry_run)))
@@ -407,8 +407,7 @@ async def create(
407407
kwargs = {k: v for k, v in kwargs.items() if v is not None}
408408

409409
# Required for client.create
410-
if not kwargs.get("duration"):
411-
kwargs["duration"] = None
410+
kwargs.setdefault("duration", None)
412411

413412
dispatch = await ctx.obj["client"].create(
414413
recurrence=parse_recurrence(kwargs),

src/frequenz/client/dispatch/_internal_types.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ def to_protobuf(self) -> PBDispatchCreateRequest:
125125
else Timestamp()
126126
),
127127
duration=(
128-
round(self.duration.total_seconds()) if self.duration else None
128+
None
129+
if self.duration is None
130+
else round(self.duration.total_seconds())
129131
),
130132
target=_target_components_to_protobuf(self.target),
131133
is_active=self.active,

src/frequenz/client/dispatch/test/_service.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,12 +265,18 @@ async def UpdateMicrogridDispatch(
265265

266266
match split_path[0]:
267267
# Fields that can be assigned directly
268-
case "is_active" | "duration":
268+
case "is_active":
269269
setattr(
270270
pb_dispatch.data,
271271
split_path[0],
272272
getattr(request.update, split_path[0]),
273273
)
274+
# Duration needs extra handling for clearing
275+
case "duration":
276+
if request.update.HasField("duration"):
277+
pb_dispatch.data.duration = request.update.duration
278+
else:
279+
pb_dispatch.data.ClearField("duration")
274280
# Fields that need to be copied
275281
case "start_time" | "target" | "payload":
276282
getattr(pb_dispatch.data, split_path[0]).CopyFrom(

src/frequenz/client/dispatch/types.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ def from_protobuf(cls, pb_object: PBDispatch) -> "Dispatch":
293293
start_time=to_datetime(pb_object.data.start_time),
294294
duration=(
295295
timedelta(seconds=pb_object.data.duration)
296-
if pb_object.data.duration
296+
if pb_object.data.HasField("duration")
297297
else None
298298
),
299299
target=_target_components_from_protobuf(pb_object.data.target),
@@ -322,7 +322,9 @@ def to_protobuf(self) -> PBDispatch:
322322
type=self.type,
323323
start_time=to_timestamp(self.start_time),
324324
duration=(
325-
round(self.duration.total_seconds()) if self.duration else None
325+
None
326+
if self.duration is None
327+
else round(self.duration.total_seconds())
326328
),
327329
target=_target_components_to_protobuf(self.target),
328330
is_active=self.active,

tests/test_client.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ async def test_create_duration_none(client: FakeClient, sample: Dispatch) -> Non
7474
assert dispatch == sample
7575

7676

77+
async def test_create_duration_0(client: FakeClient, sample: Dispatch) -> None:
78+
"""Test creating a dispatch with a 0 duration."""
79+
microgrid_id = random.randint(1, 100)
80+
sample = replace(sample, duration=timedelta(minutes=0))
81+
dispatch = await client.create(**to_create_params(microgrid_id, sample))
82+
sample = _update_metadata(sample, dispatch)
83+
assert dispatch == sample
84+
85+
7786
async def test_list_dispatches(
7887
client: FakeClient, generator: DispatchGenerator
7988
) -> None:
@@ -172,6 +181,24 @@ async def test_update_dispatch_to_no_duration(
172181
assert client.dispatches(microgrid_id)[0].duration is None
173182

174183

184+
async def test_update_dispatch_to_0_duration(
185+
client: FakeClient, sample: Dispatch
186+
) -> None:
187+
"""Test updating the duration field of a dispatch to 0."""
188+
microgrid_id = random.randint(1, 100)
189+
client.set_dispatches(
190+
microgrid_id=microgrid_id,
191+
value=[replace(sample, duration=timedelta(minutes=10))],
192+
)
193+
194+
await client.update(
195+
microgrid_id=microgrid_id,
196+
dispatch_id=sample.id,
197+
new_fields={"duration": timedelta(minutes=0)},
198+
)
199+
assert client.dispatches(microgrid_id)[0].duration == timedelta(minutes=0)
200+
201+
175202
async def test_update_dispatch_from_no_duration(
176203
client: FakeClient, sample: Dispatch
177204
) -> None:

0 commit comments

Comments
 (0)