From cef414da432e5f7afa18d29f32dbc64ad2fe42d7 Mon Sep 17 00:00:00 2001 From: "Mathias L. Baumann" Date: Wed, 9 Apr 2025 13:38:11 +0200 Subject: [PATCH 1/2] Add `Dispatch.end_time` and print it in `dispatch-cli` Signed-off-by: Mathias L. Baumann --- RELEASE_NOTES.md | 5 ++++- src/frequenz/client/dispatch/__main__.py | 1 + src/frequenz/client/dispatch/types.py | 8 ++++++++ tests/test_client.py | 1 + tests/test_proto.py | 2 ++ 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f5cfa687..eab08419 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,6 +1,9 @@ # Frequenz Dispatch Client Library Release Notes +## Features + +* `Dispatch.end_time` has been added to the `Dispatch` class, which is the time when the dispatch ended as calculated by the server. `dispatch-cli` will also print this time. + ## Bug Fixes -* Fix that duration=0 was sent & received as None. * Fix that `dispatch-cli stream` would try to print an event as dispatch, causing an exception. diff --git a/src/frequenz/client/dispatch/__main__.py b/src/frequenz/client/dispatch/__main__.py index cd9bf2d1..1d88c16f 100644 --- a/src/frequenz/client/dispatch/__main__.py +++ b/src/frequenz/client/dispatch/__main__.py @@ -148,6 +148,7 @@ def format_line(key: str, value: str, color: str = "cyan") -> str: lines.append(format_line("Recurrence", "None")) lines.append(format_line("Create Time", format_datetime(dispatch.create_time))) lines.append(format_line("Update Time", format_datetime(dispatch.update_time))) + lines.append(format_line("End Time", format_datetime(dispatch.end_time))) # Combine all lines dispatch_info: str = "\n".join(lines) diff --git a/src/frequenz/client/dispatch/types.py b/src/frequenz/client/dispatch/types.py index 8d1daf89..d47fca53 100644 --- a/src/frequenz/client/dispatch/types.py +++ b/src/frequenz/client/dispatch/types.py @@ -158,6 +158,12 @@ class Dispatch: # pylint: disable=too-many-instance-attributes update_time: datetime """The last update time of the dispatch in UTC. Set when a dispatch is modified.""" + end_time: datetime | None = None + """The end time of the dispatch in UTC. + + Calculated and sent by the backend service. + """ + @property def started(self) -> bool: """Check if the dispatch has started. @@ -290,6 +296,7 @@ def from_protobuf(cls, pb_object: PBDispatch) -> "Dispatch": type=pb_object.data.type, create_time=to_datetime(pb_object.metadata.create_time), update_time=to_datetime(pb_object.metadata.modification_time), + end_time=to_datetime(pb_object.metadata.end_time), start_time=to_datetime(pb_object.data.start_time), duration=( timedelta(seconds=pb_object.data.duration) @@ -317,6 +324,7 @@ def to_protobuf(self) -> PBDispatch: dispatch_id=self.id, create_time=to_timestamp(self.create_time), modification_time=to_timestamp(self.update_time), + end_time=to_timestamp(self.end_time), ), data=DispatchData( type=self.type, diff --git a/tests/test_client.py b/tests/test_client.py index e7fff5bb..aa6e6389 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -38,6 +38,7 @@ def _update_metadata(dispatch: Dispatch, created: Dispatch) -> Dispatch: id=created.id, create_time=created.create_time, update_time=created.update_time, + end_time=created.end_time, ) diff --git a/tests/test_proto.py b/tests/test_proto.py index 144ab46b..0d28f1fd 100644 --- a/tests/test_proto.py +++ b/tests/test_proto.py @@ -97,6 +97,7 @@ def test_dispatch() -> None: create_time=datetime(2023, 1, 1, tzinfo=timezone.utc), update_time=datetime(2023, 1, 1, tzinfo=timezone.utc), start_time=datetime(2024, 10, 10, tzinfo=timezone.utc), + end_time=datetime(2024, 10, 20, tzinfo=timezone.utc), duration=timedelta(days=10), target=[1, 2, 3], active=True, @@ -117,6 +118,7 @@ def test_dispatch() -> None: create_time=datetime(2024, 3, 10, tzinfo=timezone.utc), update_time=datetime(2024, 3, 11, tzinfo=timezone.utc), start_time=datetime(2024, 11, 10, tzinfo=timezone.utc), + end_time=datetime(2024, 11, 20, tzinfo=timezone.utc), duration=timedelta(seconds=20), target=[ComponentCategory.BATTERY], active=False, From d80afd67280b23decce317d83d80184f862cd83f Mon Sep 17 00:00:00 2001 From: "Mathias L. Baumann" Date: Tue, 15 Apr 2025 10:13:57 +0200 Subject: [PATCH 2/2] Test: Make assert more verbose Signed-off-by: Mathias L. Baumann --- tests/test_client.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/test_client.py b/tests/test_client.py index aa6e6389..8ee16eab 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -7,6 +7,7 @@ import random from dataclasses import replace from datetime import timedelta +from functools import partial import grpc from pytest import raises @@ -98,7 +99,16 @@ async def test_list_dispatches( dispatches = client.list(microgrid_id=1) async for page in dispatches: for dispatch in page: - assert dispatch in client.dispatches(microgrid_id=1) + # First find matching id in client.dispatches, then compare + service_side_dispatch = next( + filter( + partial(lambda d, md: d.id == md.id, md=dispatch), + client.dispatches(microgrid_id=1), + ), + None, + ) + + assert dispatch == service_side_dispatch async def test_list_dispatches_no_duration(