From c652301a47d9172619c0d7f2b7ef99d493f583c3 Mon Sep 17 00:00:00 2001 From: qdelamea Date: Fri, 16 Feb 2024 19:17:12 +0100 Subject: [PATCH] fix: handle empty timestamps in RPC messages for Python API --- packages/python/src/armonik/common/helpers.py | 10 +++++++--- packages/python/tests/test_helpers.py | 6 ++++-- packages/python/tests/test_results.py | 9 ++------- packages/python/tests/test_sessions.py | 8 ++------ packages/python/tests/test_tasks.py | 18 +++++++++--------- 5 files changed, 24 insertions(+), 27 deletions(-) diff --git a/packages/python/src/armonik/common/helpers.py b/packages/python/src/armonik/common/helpers.py index 6de6dcce0..81cb6f943 100644 --- a/packages/python/src/armonik/common/helpers.py +++ b/packages/python/src/armonik/common/helpers.py @@ -52,7 +52,7 @@ def get_task_filter( return task_filter -def datetime_to_timestamp(time_stamp: datetime) -> timestamp.Timestamp: +def datetime_to_timestamp(time_stamp: datetime | None) -> timestamp.Timestamp: """Helper function to convert a Python Datetime to a gRPC Timestamp Args: @@ -62,11 +62,13 @@ def datetime_to_timestamp(time_stamp: datetime) -> timestamp.Timestamp: Equivalent gRPC Timestamp """ t = timestamp.Timestamp() - t.FromDatetime(dt=time_stamp) + t.FromDatetime( + dt=time_stamp if time_stamp is not None else datetime(1970, 1, 1, 0, 0, tzinfo=timezone.utc) + ) return t -def timestamp_to_datetime(time_stamp: timestamp.Timestamp) -> datetime: +def timestamp_to_datetime(time_stamp: timestamp.Timestamp) -> datetime | None: """Helper function to convert a gRPC Timestamp to a Python Datetime Note that datetime has microseconds accuracy instead of nanosecond accuracy for gRPC Timestamp Therefore, the conversion may not be lossless. @@ -76,6 +78,8 @@ def timestamp_to_datetime(time_stamp: timestamp.Timestamp) -> datetime: Returns: Equivalent Python Datetime """ + if time_stamp.seconds == 0 and time_stamp.nanos == 0: + return return time_stamp.ToDatetime(tzinfo=timezone.utc) diff --git a/packages/python/tests/test_helpers.py b/packages/python/tests/test_helpers.py index 98155cd69..d5ef2a51c 100644 --- a/packages/python/tests/test_helpers.py +++ b/packages/python/tests/test_helpers.py @@ -27,6 +27,8 @@ def timestamp(self) -> Timestamp: @property def date_time(self) -> datetime: + if self.seconds == 0 and self.nanos == 0: + return return datetime.utcfromtimestamp(self.seconds + self.nanos * 1e-9).replace( tzinfo=timezone.utc ) @@ -51,8 +53,8 @@ def test_datetime_to_timestamp(case: Case): @pytest.mark.parametrize("case", test_cases) def test_timestamp_to_datetime(case: Case): - ts = timestamp_to_datetime(case.timestamp) - assert ts.timestamp() == case.date_time.timestamp() + dt = timestamp_to_datetime(case.timestamp) + assert dt == case.date_time @pytest.mark.parametrize("case", test_cases) diff --git a/packages/python/tests/test_results.py b/packages/python/tests/test_results.py index 6ea058103..95d5f03fc 100644 --- a/packages/python/tests/test_results.py +++ b/packages/python/tests/test_results.py @@ -1,4 +1,3 @@ -import datetime import pytest import warnings @@ -18,12 +17,8 @@ def test_get_result(self): assert result.name == "result-name" assert result.owner_task_id == "owner-task-id" assert result.status == 2 - assert result.created_at == datetime.datetime( - 1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc - ) - assert result.completed_at == datetime.datetime( - 1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc - ) + assert result.created_at is None + assert result.completed_at is None assert result.result_id == "result-id" assert result.size == 0 diff --git a/packages/python/tests/test_sessions.py b/packages/python/tests/test_sessions.py index 116380779..2f3e6f208 100644 --- a/packages/python/tests/test_sessions.py +++ b/packages/python/tests/test_sessions.py @@ -37,12 +37,8 @@ def test_get_session(self): engine_type="", options={}, ) - assert session.created_at == datetime.datetime( - 1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc - ) - assert session.cancelled_at == datetime.datetime( - 1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc - ) + assert session.created_at is None + assert session.cancelled_at is None assert session.duration == datetime.timedelta(0) def test_list_session_no_filter(self): diff --git a/packages/python/tests/test_tasks.py b/packages/python/tests/test_tasks.py index 90d42c021..6c5eb4593 100644 --- a/packages/python/tests/test_tasks.py +++ b/packages/python/tests/test_tasks.py @@ -29,15 +29,15 @@ class TestArmoniKTasks: engine_type="engine-type", options={}, ), - created_at=datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - submitted_at=datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - received_at=datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - acquired_at=datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - fetched_at=datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - started_at=datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - processed_at=datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - ended_at=datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), - pod_ttl=datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc), + created_at=None, + submitted_at=None, + received_at=None, + acquired_at=None, + fetched_at=None, + started_at=None, + processed_at=None, + ended_at=None, + pod_ttl=None, output=Output(error=""), pod_hostname="", )