From e149a2016e3e198ccc84c8f87c1c6ec0e350e03f Mon Sep 17 00:00:00 2001 From: Damien Garros Date: Thu, 27 Feb 2025 18:34:14 +0100 Subject: [PATCH] Replace pendumum with whenever --- backend/infrahub/core/attribute.py | 2 +- backend/infrahub/core/diff/model/path.py | 10 +- backend/infrahub/core/timestamp.py | 6 +- backend/infrahub/graphql/queries/diff/tree.py | 25 +-- backend/infrahub/server.py | 2 +- backend/infrahub/task_manager/models.py | 4 +- .../user_workflows/test_user_worflow.py | 8 +- backend/tests/unit/api/conftest.py | 74 ++++---- .../api/diff/test_diff_query_validation.py | 5 +- backend/tests/unit/conftest.py | 70 ++++---- .../diff/repository/test_diff_repository.py | 168 +++++++++--------- .../unit/core/diff/test_diff_combiner.py | 11 +- backend/tests/unit/core/test_branch.py | 3 +- backend/tests/unit/core/test_branch_diff.py | 7 +- backend/tests/unit/core/test_query.py | 22 +-- .../unit/graphql/diff/test_diff_tree_query.py | 92 ++++++---- .../tests/unit/graphql/queries/test_task.py | 17 +- .../tests/unit/graphql/test_graphql_query.py | 12 +- poetry.lock | 85 ++++++++- pyproject.toml | 1 + python_sdk | 2 +- 21 files changed, 362 insertions(+), 264 deletions(-) diff --git a/backend/infrahub/core/attribute.py b/backend/infrahub/core/attribute.py index e2a2d82607..3c246605e9 100644 --- a/backend/infrahub/core/attribute.py +++ b/backend/infrahub/core/attribute.py @@ -7,7 +7,7 @@ import netaddr import ujson -from infrahub_sdk.timestamp import TimestampFormatError +from infrahub_sdk.exceptions import TimestampFormatError from infrahub_sdk.utils import is_valid_url from infrahub_sdk.uuidt import UUIDT from pydantic import BaseModel, Field diff --git a/backend/infrahub/core/diff/model/path.py b/backend/infrahub/core/diff/model/path.py index 881a053d8d..7eb9250d81 100644 --- a/backend/infrahub/core/diff/model/path.py +++ b/backend/infrahub/core/diff/model/path.py @@ -20,7 +20,7 @@ from neo4j.graph import Node as Neo4jNode from neo4j.graph import Path as Neo4jPath from neo4j.graph import Relationship as Neo4jRelationship - from pendulum import Interval + from whenever import TimeDelta from infrahub.graphql.initialization import GraphqlContext @@ -417,8 +417,8 @@ def __hash__(self) -> int: return hash(self.uuid) @property - def time_range(self) -> Interval: - return self.to_time.obj - self.from_time.obj + def time_range(self) -> TimeDelta: + return self.to_time.get_obj() - self.from_time.get_obj() def update_metadata( self, @@ -447,8 +447,8 @@ def __hash__(self) -> int: return hash(self.uuid) @property - def time_range(self) -> Interval: - return self.to_time.obj - self.from_time.obj + def time_range(self) -> TimeDelta: + return self.to_time.get_obj() - self.from_time.get_obj() def get_nodes_without_parents(self) -> set[EnrichedDiffNode]: nodes_with_parent_uuids = set() diff --git a/backend/infrahub/core/timestamp.py b/backend/infrahub/core/timestamp.py index 76f6a36b85..e3c920beeb 100644 --- a/backend/infrahub/core/timestamp.py +++ b/backend/infrahub/core/timestamp.py @@ -5,12 +5,12 @@ from infrahub_sdk.timestamp import Timestamp as BaseTimestamp if TYPE_CHECKING: - from pendulum.datetime import DateTime + from datetime import datetime class Timestamp(BaseTimestamp): - async def to_graphql(self, *args: Any, **kwargs: Any) -> DateTime: # noqa: ARG002 - return self.obj + async def to_graphql(self, *args: Any, **kwargs: Any) -> datetime: # noqa: ARG002 + return self.to_datetime() def get_query_filter_path(self, rel_name: str = "r") -> tuple[str, dict]: """ diff --git a/backend/infrahub/graphql/queries/diff/tree.py b/backend/infrahub/graphql/queries/diff/tree.py index 2f6d89b7bc..9308b7b4ca 100644 --- a/backend/infrahub/graphql/queries/diff/tree.py +++ b/backend/infrahub/graphql/queries/diff/tree.py @@ -193,7 +193,7 @@ def to_diff_node(self, enriched_node: EnrichedDiffNode, graphql_context: Graphql label=enriched_node.label, status=enriched_node.action, parent=parent, - last_changed_at=enriched_node.changed_at.obj if enriched_node.changed_at else None, + last_changed_at=enriched_node.changed_at.to_datetime() if enriched_node.changed_at else None, path_identifier=enriched_node.path_identifier, attributes=diff_attributes, relationships=diff_relationships, @@ -219,7 +219,7 @@ def to_diff_attribute( diff_prop.conflict = None return DiffAttribute( name=enriched_attribute.name, - last_changed_at=enriched_attribute.changed_at.obj, + last_changed_at=enriched_attribute.changed_at.to_datetime(), status=enriched_attribute.action, path_identifier=enriched_attribute.path_identifier, properties=diff_properties, @@ -241,7 +241,9 @@ def to_diff_relationship( return DiffRelationship( name=enriched_relationship.name, label=enriched_relationship.label, - last_changed_at=enriched_relationship.changed_at.obj if enriched_relationship.changed_at else None, + last_changed_at=enriched_relationship.changed_at.to_datetime() + if enriched_relationship.changed_at + else None, status=enriched_relationship.action, cardinality=enriched_relationship.cardinality, path_identifier=enriched_relationship.path_identifier, @@ -263,7 +265,7 @@ def to_diff_relationship_element( enriched_conflict=enriched_element.conflict, graphql_context=graphql_context ) return DiffSingleRelationship( - last_changed_at=enriched_element.changed_at.obj, + last_changed_at=enriched_element.changed_at.to_datetime(), status=enriched_element.action, peer_id=enriched_element.peer_id, peer_label=enriched_element.peer_label, @@ -287,7 +289,7 @@ def to_diff_property( ) return DiffProperty( property_type=enriched_property.property_type.value, - last_changed_at=enriched_property.changed_at.obj, + last_changed_at=enriched_property.changed_at.to_datetime(), previous_value=enriched_property.previous_value, new_value=enriched_property.new_value, previous_label=enriched_property.previous_label, @@ -306,13 +308,13 @@ def to_diff_conflict( uuid=enriched_conflict.uuid, base_branch_action=enriched_conflict.base_branch_action, base_branch_value=enriched_conflict.base_branch_value, - base_branch_changed_at=enriched_conflict.base_branch_changed_at.obj + base_branch_changed_at=enriched_conflict.base_branch_changed_at.to_datetime() if enriched_conflict.base_branch_changed_at else None, base_branch_label=enriched_conflict.base_branch_label, diff_branch_action=enriched_conflict.diff_branch_action, diff_branch_value=enriched_conflict.diff_branch_value, - diff_branch_changed_at=enriched_conflict.diff_branch_changed_at.obj + diff_branch_changed_at=enriched_conflict.diff_branch_changed_at.to_datetime() if enriched_conflict.diff_branch_changed_at else None, diff_branch_label=enriched_conflict.diff_branch_label, @@ -426,7 +428,10 @@ async def resolve( # take the one with the longest duration that covers multiple branches enriched_diff = sorted( enriched_diffs, - key=lambda d: (d.base_branch_name != d.diff_branch_name, d.to_time.obj - d.from_time.obj), + key=lambda d: ( + d.base_branch_name != d.diff_branch_name, + d.to_time.to_datetime() - d.from_time.to_datetime(), + ), reverse=True, )[0] else: @@ -485,8 +490,8 @@ async def summary( diff_tree_summary = DiffTreeSummary( base_branch=base_branch.name, diff_branch=diff_branch.name, - from_time=summary.from_time.obj, - to_time=summary.to_time.obj, + from_time=summary.from_time.to_datetime(), + to_time=summary.to_time.to_datetime(), **summary.model_dump(exclude={"from_time", "to_time"}), ) full_fields = await extract_fields(info.field_nodes[0].selection_set) diff --git a/backend/infrahub/server.py b/backend/infrahub/server.py index 33ca98d249..6305c17dab 100644 --- a/backend/infrahub/server.py +++ b/backend/infrahub/server.py @@ -14,7 +14,7 @@ from fastapi.responses import RedirectResponse from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates -from infrahub_sdk.timestamp import TimestampFormatError +from infrahub_sdk.exceptions import TimestampFormatError from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor from opentelemetry.trace import Span from pydantic import ValidationError diff --git a/backend/infrahub/task_manager/models.py b/backend/infrahub/task_manager/models.py index 9c6a3334c9..651d42cd93 100644 --- a/backend/infrahub/task_manager/models.py +++ b/backend/infrahub/task_manager/models.py @@ -180,10 +180,10 @@ def from_filters( ) -> InfrahubEventFilter: occurred_filter = {} if since: - occurred_filter["since"] = Timestamp(since.isoformat()).obj + occurred_filter["since"] = Timestamp(since.isoformat()).to_datetime() if until: - occurred_filter["until"] = Timestamp(until.isoformat()).obj + occurred_filter["until"] = Timestamp(until.isoformat()).to_datetime() if occurred_filter: filters = cls(occurred=EventOccurredFilter(**occurred_filter)) diff --git a/backend/tests/integration/user_workflows/test_user_worflow.py b/backend/tests/integration/user_workflows/test_user_worflow.py index 61cd760ac1..1b221a9187 100644 --- a/backend/tests/integration/user_workflows/test_user_worflow.py +++ b/backend/tests/integration/user_workflows/test_user_worflow.py @@ -1,6 +1,6 @@ -import pendulum import pytest from deepdiff import DeepDiff +from whenever import Instant from infrahub.database import InfrahubDatabase from infrahub.graphql.manager import GraphQLSchemaManager @@ -251,7 +251,7 @@ async def test_query_all_devices(self, test_client, integration_helper): if device["node"]["name"]["value"] == "spine1": state.data["spine1_id"] = device["node"]["id"] # Initialize the start time - state.data["time_start"] = pendulum.now(tz="UTC") + state.data["time_start"] = Instant.now() async def test_query_spine1_loobpack0(self, test_client, integration_helper): """ @@ -374,7 +374,7 @@ async def test_update_intf_description_branch1( assert intfs[0]["node"]["description"]["value"] == new_description - state.data["time_after_intf_update_branch1"] = pendulum.now("UTC").to_iso8601_string() + state.data["time_after_intf_update_branch1"] = Instant.now().format_common_iso() async def test_update_intf_description_main(self, test_client, integration_helper): """ @@ -781,7 +781,7 @@ async def test_query_spine1_lo0_at_start_time(self, test_client, integration_hel "intf_name": intf_name, }, }, - params={"at": state.data["time_start"].to_iso8601_string()}, + params={"at": state.data["time_start"].format_common_iso()}, headers=headers, ) assert response.status_code == 200 diff --git a/backend/tests/unit/api/conftest.py b/backend/tests/unit/api/conftest.py index bd1af84de3..38fd69aa9a 100644 --- a/backend/tests/unit/api/conftest.py +++ b/backend/tests/unit/api/conftest.py @@ -1,4 +1,3 @@ -import pendulum import pytest from fastapi.testclient import TestClient @@ -7,6 +6,7 @@ from infrahub.core.initialization import create_branch from infrahub.core.manager import NodeManager from infrahub.core.node import Node +from infrahub.core.timestamp import Timestamp from infrahub.database import InfrahubDatabase from infrahub.services.adapters.workflow.local import WorkflowLocalExecution from infrahub.workflows.initialization import setup_task_manager @@ -140,7 +140,7 @@ async def car_person_data_diff(db: InfrahubDatabase, default_branch, car_person_ branch2 = await create_branch(branch_name="branch2", db=db) # Time post Branch Creation - time0 = pendulum.now(tz="UTC") + time0 = Timestamp() persons_list = await NodeManager.query(db=db, schema="Person", branch=branch2) persons = {item.name.value: item for item in persons_list} @@ -166,7 +166,7 @@ async def car_person_data_diff(db: InfrahubDatabase, default_branch, car_person_ await p1.save(db=db) # Time in-between the 2 batch of changes - time1 = pendulum.now(tz="UTC") + time1 = Timestamp() # Update Repo 01 in Branch2 repo01 = repos["repo01"] @@ -181,7 +181,7 @@ async def car_person_data_diff(db: InfrahubDatabase, default_branch, car_person_ await cars_main["bolt"].save(db=db) # Time After the changes - time2 = pendulum.now(tz="UTC") + time2 = Timestamp() params = { "branch": branch2, @@ -198,7 +198,7 @@ async def car_person_data_generic_diff(db: InfrahubDatabase, default_branch, car branch2 = await create_branch(branch_name="branch2", db=db) # Time After Creation of branch2 - time0 = pendulum.now(tz="UTC") + time0 = Timestamp() persons_list = await NodeManager.query(db=db, schema="TestPerson", branch=branch2) persons = {item.name.value: item for item in persons_list} @@ -213,34 +213,34 @@ async def car_person_data_generic_diff(db: InfrahubDatabase, default_branch, car gcars = {item.name.value: item for item in gcars_list} # Add a new Person P3 in Branch2 and assign him as the owner of C1 - time10 = pendulum.now(tz="UTC") + time10 = Timestamp() p3 = await Node.init(db=db, schema="TestPerson", branch=branch2) await p3.new(db=db, name="Bill", height=160) await p3.save(db=db, at=time10) persons["Bill"] = p3 - time11 = pendulum.now(tz="UTC") + time11 = Timestamp() await ecars["volt"].owner.update(data=p3, db=db) await ecars["volt"].save(db=db, at=time11) # Update Repo 01 in Branch2 a first time - time12 = pendulum.now(tz="UTC") + time12 = Timestamp() repo01 = repos["repo01"] repo01.commit.value = "bbbbbbbbbbbbbbb" repo01.description.value = "First change in branch" await repo01.save(db=db, at=time12) # Update P1 height in main - time13 = pendulum.now(tz="UTC") + time13 = Timestamp() p1 = await NodeManager.get_one(id=persons["John"].id, db=db) p1.height.value = 120 await p1.save(db=db, at=time13) # Time in-between the 2 batch of changes - time20 = pendulum.now(tz="UTC") + time20 = Timestamp() # Update Repo 01 in Branch2 a second time - time21 = pendulum.now(tz="UTC") + time21 = Timestamp() repo01 = repos["repo01"] repo01.commit.value = "dddddddddd" repo01.description.value = "Second change in branch" @@ -257,7 +257,7 @@ async def car_person_data_generic_diff(db: InfrahubDatabase, default_branch, car await ecars_main["bolt"].save(db=db) # Time After the changes - time30 = pendulum.now(tz="UTC") + time30 = Timestamp() params = { "branch": branch2, @@ -414,7 +414,7 @@ async def data_diff_attribute(db: InfrahubDatabase, default_branch, car_person_d branch2 = await create_branch(branch_name="branch2", db=db) # Time After Creation of branch2 - time0 = pendulum.now(tz="UTC") + time0 = Timestamp() persons_list = await NodeManager.query(db=db, schema="TestPerson", branch=branch2) persons = {item.name.value: item for item in persons_list} @@ -429,23 +429,23 @@ async def data_diff_attribute(db: InfrahubDatabase, default_branch, car_person_d gcars = {item.name.value: item for item in gcars_list} # Update Repo 01 in Branch2 a first time - time12 = pendulum.now(tz="UTC") + time12 = Timestamp() repo01 = repos["repo01"] repo01.commit.value = "bbbbbbbbbbbbbbb" repo01.description.value = "First update in Branch" await repo01.save(db=db, at=time12) # Update P1 height in main - time13 = pendulum.now(tz="UTC") + time13 = Timestamp() p1 = await NodeManager.get_one(id=persons["John"].id, db=db) p1.height.value = 120 await p1.save(db=db, at=time13) # Time in-between the 2 batch of changes - time20 = pendulum.now(tz="UTC") + time20 = Timestamp() # Update Repo 01 in Branch2 a second time - time21 = pendulum.now(tz="UTC") + time21 = Timestamp() repo01 = repos["repo01"] repo01.commit.value = "dddddddddd" repo01.description.value = "Second update in Branch" @@ -459,7 +459,7 @@ async def data_diff_attribute(db: InfrahubDatabase, default_branch, car_person_d await ecars_main["bolt"].save(db=db) # Time After the changes - time30 = pendulum.now(tz="UTC") + time30 = Timestamp() params = { "branch": branch2, @@ -486,7 +486,7 @@ async def data_conflict_attribute(db: InfrahubDatabase, default_branch, car_pers branch2 = await create_branch(branch_name="branch2", db=db) # Time After Creation of branch2 - time0 = pendulum.now(tz="UTC") + time0 = Timestamp() persons_list_branch = await NodeManager.query(db=db, schema="TestPerson", branch=branch2) persons_branch = {item.name.value: item for item in persons_list_branch} @@ -501,13 +501,13 @@ async def data_conflict_attribute(db: InfrahubDatabase, default_branch, car_pers repos_main = {item.name.value: item for item in repos_list_main} # Update Repo 01 in Branch2 a first time - time12 = pendulum.now(tz="UTC") + time12 = Timestamp() repos_branch["repo01"].commit.value = "bbbbbbbbbbbbbbb" repos_branch["repo01"].description.value = "First update in Branch" await repos_branch["repo01"].save(db=db, at=time12) # Update P1 height in branch2 - time13 = pendulum.now(tz="UTC") + time13 = Timestamp() persons_branch["John"].height.value = 666 await persons_branch["John"].save(db=db, at=time13) @@ -516,22 +516,22 @@ async def data_conflict_attribute(db: InfrahubDatabase, default_branch, car_pers await persons_main["John"].save(db=db, at=time13) # Time in-between the 2 batch of changes - time20 = pendulum.now(tz="UTC") + time20 = Timestamp() # Update Repo 01 in Branch2 a second time - time21 = pendulum.now(tz="UTC") + time21 = Timestamp() repos_branch["repo01"].commit.value = "dddddddddd" repos_branch["repo01"].description.value = "Second update in Branch" await repos_branch["repo01"].save(db=db, at=time21) # Update Repo 01 in main - time22 = pendulum.now(tz="UTC") + time22 = Timestamp() repos_main["repo01"].commit.value = "mmmmmmmmmmmmm" repos_main["repo01"].description.value = "update in main" await repos_main["repo01"].save(db=db, at=time12) # Time After the changes - time30 = pendulum.now(tz="UTC") + time30 = Timestamp() params = { "branch": branch2, @@ -553,7 +553,7 @@ async def data_conflict_attribute(db: InfrahubDatabase, default_branch, car_pers @pytest.fixture async def data_diff_relationship_one(db: InfrahubDatabase, default_branch, car_person_data_generic, first_account): # Set some values in C1 in Main before creating the branch - time_minus1 = pendulum.now(tz="UTC") + time_minus1 = Timestamp() c1_main = await NodeManager.get_one_by_id_or_default_filter( db=db, id="volt", kind="TestElectricCar", branch=default_branch @@ -569,7 +569,7 @@ async def data_diff_relationship_one(db: InfrahubDatabase, default_branch, car_p branch2 = await create_branch(branch_name="branch2", db=db) # Time After Creation of branch2 - time0 = pendulum.now(tz="UTC") + time0 = Timestamp() persons_list = await NodeManager.query(db=db, schema="TestPerson", branch=branch2) persons = {item.name.value: item for item in persons_list} @@ -578,19 +578,19 @@ async def data_diff_relationship_one(db: InfrahubDatabase, default_branch, car_p ecars = {item.name.value: item for item in ecars_list} # Change previous owner of C1 from P1 to P2 in branch - time11 = pendulum.now(tz="UTC") + time11 = Timestamp() await ecars["volt"].previous_owner.update(data=persons["John"], db=db) await ecars["volt"].save(db=db, at=time11) # Time in-between the 2 batch of changes - time20 = pendulum.now(tz="UTC") + time20 = Timestamp() # Set previous owner for C2 in branch await ecars["bolt"].previous_owner.update(data=persons["Jane"], db=db) await ecars["bolt"].save(db=db, at=time20) # Time After the changes - time30 = pendulum.now(tz="UTC") + time30 = Timestamp() params = { "branch": branch2, @@ -610,7 +610,7 @@ async def data_diff_relationship_one(db: InfrahubDatabase, default_branch, car_p @pytest.fixture async def data_conflict_relationship_one(db: InfrahubDatabase, default_branch, car_person_data_generic, first_account): # Set some values in C1 in Main before creating the branch - time_minus1 = pendulum.now(tz="UTC") + time_minus1 = Timestamp() ecars_list_main = await NodeManager.query(db=db, schema="TestElectricCar", branch=default_branch) ecars_main = {item.name.value: item for item in ecars_list_main} @@ -624,7 +624,7 @@ async def data_conflict_relationship_one(db: InfrahubDatabase, default_branch, c branch2 = await create_branch(branch_name="branch2", db=db) # Time After Creation of branch2 - time0 = pendulum.now(tz="UTC") + time0 = Timestamp() persons_list_branch = await NodeManager.query(db=db, schema="TestPerson", branch=branch2) persons_branch = {item.name.value: item for item in persons_list_branch} @@ -633,30 +633,30 @@ async def data_conflict_relationship_one(db: InfrahubDatabase, default_branch, c ecars_branch = {item.name.value: item for item in ecars_list_branch} # Change previous owner of C1 from P1 to P2 in branch - time11 = pendulum.now(tz="UTC") + time11 = Timestamp() await ecars_branch["volt"].previous_owner.update(data=persons_branch["John"], db=db) await ecars_branch["volt"].save(db=db, at=time11) # Change previous owner of C1 from P1 to Null in main - time12 = pendulum.now(tz="UTC") + time12 = Timestamp() await ecars_main["volt"].previous_owner.update(data=None, db=db) await ecars_main["volt"].save(db=db, at=time12) # Time in-between the 2 batch of changes - time20 = pendulum.now(tz="UTC") + time20 = Timestamp() # Set previous owner for C2 in branch await ecars_branch["bolt"].previous_owner.update(data=persons_branch["Jane"], db=db) await ecars_branch["bolt"].save(db=db, at=time20) # Set previous owner for C2 in main - time21 = pendulum.now(tz="UTC") + time21 = Timestamp() await ecars_main["bolt"].previous_owner.update(data=persons_branch["John"], db=db) await ecars_main["bolt"].save(db=db, at=time21) # Time After the changes - time30 = pendulum.now(tz="UTC") + time30 = Timestamp() params = { "branch": branch2, diff --git a/backend/tests/unit/api/diff/test_diff_query_validation.py b/backend/tests/unit/api/diff/test_diff_query_validation.py index 14c44c4428..f038ca047a 100644 --- a/backend/tests/unit/api/diff/test_diff_query_validation.py +++ b/backend/tests/unit/api/diff/test_diff_query_validation.py @@ -1,4 +1,5 @@ import pytest +from infrahub_sdk.exceptions import TimestampFormatError from pydantic import ValidationError from infrahub.api.diff.validation_models import DiffQueryValidated @@ -22,11 +23,11 @@ def test_valid_query(self): assert query.branch_only is True def test_invalid_time_from(self): - with pytest.raises(ValidationError): + with pytest.raises(TimestampFormatError): DiffQueryValidated(branch=self.branch, time_from="notatime") def test_invalid_time_to(self): - with pytest.raises(ValidationError): + with pytest.raises(TimestampFormatError): DiffQueryValidated(branch=self.branch, time_to="notatime") def test_invalid_time_range(self): diff --git a/backend/tests/unit/conftest.py b/backend/tests/unit/conftest.py index 421a8544b3..4651d64d54 100644 --- a/backend/tests/unit/conftest.py +++ b/backend/tests/unit/conftest.py @@ -7,7 +7,6 @@ from typing import Any from unittest.mock import patch -import pendulum import pytest from infrahub_sdk import Config, InfrahubClient from infrahub_sdk.uuidt import UUIDT @@ -57,6 +56,7 @@ core_models, ) from infrahub.core.schema.schema_branch import SchemaBranch +from infrahub.core.timestamp import Timestamp from infrahub.core.utils import delete_all_nodes from infrahub.database import InfrahubDatabase from infrahub.dependencies.registry import build_component_registry @@ -206,8 +206,8 @@ async def simple_dataset_01(db: InfrahubDatabase, empty_database) -> dict: params = { "branch": "main", - "time1": pendulum.now(tz="UTC").to_iso8601_string(), - "time2": pendulum.now(tz="UTC").subtract(seconds=5).to_iso8601_string(), + "time1": Timestamp().to_string(), + "time2": Timestamp().subtract(seconds=5).to_string(), } query = """ @@ -264,20 +264,20 @@ async def base_dataset_02(db: InfrahubDatabase, default_branch: Branch, car_pers """ - time0 = pendulum.now(tz="UTC") + time0 = Timestamp() params = { "main_branch": "main", "branch1": "branch1", - "time0": time0.to_iso8601_string(), - "time_m10": time0.subtract(seconds=10).to_iso8601_string(), - "time_m20": time0.subtract(seconds=20).to_iso8601_string(), - "time_m25": time0.subtract(seconds=25).to_iso8601_string(), - "time_m30": time0.subtract(seconds=30).to_iso8601_string(), - "time_m35": time0.subtract(seconds=35).to_iso8601_string(), - "time_m40": time0.subtract(seconds=40).to_iso8601_string(), - "time_m45": time0.subtract(seconds=45).to_iso8601_string(), - "time_m50": time0.subtract(seconds=50).to_iso8601_string(), - "time_m60": time0.subtract(seconds=60).to_iso8601_string(), + "time0": time0.to_string(), + "time_m10": time0.subtract(seconds=10).to_string(), + "time_m20": time0.subtract(seconds=20).to_string(), + "time_m25": time0.subtract(seconds=25).to_string(), + "time_m30": time0.subtract(seconds=30).to_string(), + "time_m35": time0.subtract(seconds=35).to_string(), + "time_m40": time0.subtract(seconds=40).to_string(), + "time_m45": time0.subtract(seconds=45).to_string(), + "time_m50": time0.subtract(seconds=50).to_string(), + "time_m60": time0.subtract(seconds=60).to_string(), } # Update Main Branch and Create new Branch1 @@ -485,21 +485,21 @@ async def base_dataset_12(db: InfrahubDatabase, default_branch: Branch, car_pers """ - time0 = pendulum.now(tz="UTC") + time0 = Timestamp() params = { "main_branch": "main", "branch1": "branch1", "global_branch": GLOBAL_BRANCH_NAME, - "time0": time0.to_iso8601_string(), - "time_m10": time0.subtract(seconds=10).to_iso8601_string(), - "time_m20": time0.subtract(seconds=20).to_iso8601_string(), - "time_m25": time0.subtract(seconds=25).to_iso8601_string(), - "time_m30": time0.subtract(seconds=30).to_iso8601_string(), - "time_m35": time0.subtract(seconds=35).to_iso8601_string(), - "time_m40": time0.subtract(seconds=40).to_iso8601_string(), - "time_m45": time0.subtract(seconds=45).to_iso8601_string(), - "time_m50": time0.subtract(seconds=50).to_iso8601_string(), - "time_m60": time0.subtract(seconds=60).to_iso8601_string(), + "time0": time0.to_string(), + "time_m10": time0.subtract(seconds=10).to_string(), + "time_m20": time0.subtract(seconds=20).to_string(), + "time_m25": time0.subtract(seconds=25).to_string(), + "time_m30": time0.subtract(seconds=30).to_string(), + "time_m35": time0.subtract(seconds=35).to_string(), + "time_m40": time0.subtract(seconds=40).to_string(), + "time_m45": time0.subtract(seconds=45).to_string(), + "time_m50": time0.subtract(seconds=50).to_string(), + "time_m60": time0.subtract(seconds=60).to_string(), } # Update Main Branch and Create new Branch1 @@ -710,15 +710,15 @@ async def base_dataset_03(db: InfrahubDatabase, default_branch: Branch, person_t """ # ---- Create all timestamps and save them in Params ----------------- - time0 = pendulum.now(tz="UTC") + time0 = Timestamp() params = { "main_branch": "main", - "time0": time0.to_iso8601_string(), + "time0": time0.to_string(), } for cnt in range(1, 30): nbr_sec = cnt * 5 - params[f"time_m{nbr_sec}"] = time0.subtract(seconds=nbr_sec).to_iso8601_string() + params[f"time_m{nbr_sec}"] = time0.subtract(seconds=nbr_sec).to_string() # ---- Create all Branches and register them in the Registry ----------------- # Update Main Branch @@ -1028,16 +1028,16 @@ async def base_dataset_03(db: InfrahubDatabase, default_branch: Branch, person_t async def base_dataset_04( db: InfrahubDatabase, default_branch: Branch, register_core_models_schema, register_organization_schema ) -> dict: - time0 = pendulum.now(tz="UTC") + time0 = Timestamp() params = { "main_branch": "main", "branch1": "branch1", - "time0": time0.to_iso8601_string(), - "time_m5": time0.subtract(seconds=5).to_iso8601_string(), - "time_m10": time0.subtract(seconds=10).to_iso8601_string(), - "time_m20": time0.subtract(seconds=20).to_iso8601_string(), - "time_m30": time0.subtract(seconds=30).to_iso8601_string(), - "time_m35": time0.subtract(seconds=35).to_iso8601_string(), + "time0": time0.to_string(), + "time_m5": time0.subtract(seconds=5).to_string(), + "time_m10": time0.subtract(seconds=10).to_string(), + "time_m20": time0.subtract(seconds=20).to_string(), + "time_m30": time0.subtract(seconds=30).to_string(), + "time_m35": time0.subtract(seconds=35).to_string(), } blue = await Node.init(db=db, schema=InfrahubKind.TAG, branch=default_branch) diff --git a/backend/tests/unit/core/diff/repository/test_diff_repository.py b/backend/tests/unit/core/diff/repository/test_diff_repository.py index 9e1a268862..fcada6a97d 100644 --- a/backend/tests/unit/core/diff/repository/test_diff_repository.py +++ b/backend/tests/unit/core/diff/repository/test_diff_repository.py @@ -1,12 +1,10 @@ import random from collections import defaultdict from dataclasses import replace -from datetime import UTC from typing import Generator from uuid import uuid4 import pytest -from pendulum.datetime import DateTime from infrahub import config from infrahub.core.constants import DiffAction @@ -37,10 +35,10 @@ class TestDiffRepositorySaveAndLoad(DiffRepositoryTestBase): - base_branch_name = "main" - diff_branch_name = "diff" - diff_from_time = DateTime.create(2024, 6, 15, 18, 35, 20, tz=UTC) - diff_to_time = DateTime.create(2024, 6, 15, 18, 49, 40, tz=UTC) + base_branch_name: str = "main" + diff_branch_name: str = "diff" + diff_from_time = Timestamp("2024-06-15T18:35:20Z") + diff_to_time = Timestamp("2024-06-15T18:49:40Z") @pytest.fixture def diff_repository(self, db: InfrahubDatabase) -> Generator[DiffRepository, None, None]: @@ -60,7 +58,7 @@ async def test_get_non_existent_diff(self, diff_repository: DiffRepository, rese base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], from_time=right_now, - to_time=right_now.add_delta(hours=1), + to_time=right_now.add(hours=1), ) assert len(enriched_diffs) == 0 @@ -68,8 +66,8 @@ async def test_save_and_retrieve(self, diff_repository: DiffRepository, reset_da enriched_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=self.diff_branch_name, - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, nodes=self._build_nodes(num_nodes=5, num_sub_fields=2), tracking_id=NameTrackingId(name="the-best-diff"), ) @@ -81,8 +79,8 @@ async def test_save_and_retrieve(self, diff_repository: DiffRepository, reset_da retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, ) assert len(retrieved) == 1 diff_root = retrieved[0] @@ -95,16 +93,16 @@ async def test_save_and_retrieve_large_diff(self, diff_repository: DiffRepositor enriched_branch_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=self.diff_branch_name, - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, nodes=self._build_nodes(num_nodes=20, num_sub_fields=2), tracking_id=NameTrackingId(name="the-best-diff"), ) enriched_base_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=self.base_branch_name, - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, nodes=self._build_nodes(num_nodes=18, num_sub_fields=1), tracking_id=NameTrackingId(name="the-best-diff"), ) @@ -122,8 +120,8 @@ async def test_save_and_retrieve_large_diff(self, diff_repository: DiffRepositor retrieved = await diff_repository.get_pairs( base_branch_name=self.base_branch_name, diff_branch_name=self.diff_branch_name, - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, ) assert len(retrieved) == 1 retrieved_pair = retrieved[0] @@ -139,8 +137,8 @@ async def test_base_branch_name_filter(self, diff_repository: DiffRepository, re enriched_diff = EnrichedRootFactory.build( base_branch_name=base_branch_name, diff_branch_name=self.diff_branch_name, - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, uuid=root_uuid, nodes={EnrichedNodeFactory.build(relationships={})}, ) @@ -151,8 +149,8 @@ async def test_base_branch_name_filter(self, diff_repository: DiffRepository, re retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, ) assert len(retrieved) == 1 assert retrieved[0].base_branch_name == self.base_branch_name @@ -162,7 +160,7 @@ async def test_diff_branch_name_filter(self, diff_repository: DiffRepository, re diff_branch_1, diff_branch_2, diff_branch_3 = "diff1", "diff2", "diff3" diff_uuids_by_name = {diff_branch_1: set(), diff_branch_2: set(), diff_branch_3: set()} for diff_branch_name in (diff_branch_1, diff_branch_2, diff_branch_3): - start_time = DateTime.create(2024, 6, 15, 18, 35, 20, tz=UTC) + start_time = Timestamp("2024-06-15T18:35:20Z") for _ in range(5): start_time = start_time.add(seconds=random.randint(150_000, 300_000)) end_time = start_time.add(seconds=random.randint(25_000, 100_000)) @@ -171,8 +169,8 @@ async def test_diff_branch_name_filter(self, diff_repository: DiffRepository, re enriched_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=diff_branch_name, - from_time=Timestamp(start_time), - to_time=Timestamp(end_time), + from_time=start_time, + to_time=end_time, uuid=root_uuid, nodes={EnrichedNodeFactory.build(relationships={})}, ) @@ -180,14 +178,14 @@ async def test_diff_branch_name_filter(self, diff_repository: DiffRepository, re diff_repository=diff_repository, enriched_diff=enriched_diff, do_summary_counts=False ) - start_time = DateTime.create(2024, 6, 15, 18, 35, 20, tz=UTC) + start_time = Timestamp("2024-06-15T18:35:20Z") end_time = start_time.add(months=1) for diff_name, expected_uuids in diff_uuids_by_name.items(): retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[diff_name], - from_time=Timestamp(start_time), - to_time=Timestamp(end_time), + from_time=start_time, + to_time=end_time, ) retrieved_uuids = {root_diff.uuid for root_diff in retrieved} assert retrieved_uuids == expected_uuids @@ -195,8 +193,8 @@ async def test_diff_branch_name_filter(self, diff_repository: DiffRepository, re retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[diff_branch_1, diff_branch_2], - from_time=Timestamp(start_time), - to_time=Timestamp(end_time), + from_time=start_time, + to_time=end_time, ) expected_uuids = diff_uuids_by_name[diff_branch_1] | diff_uuids_by_name[diff_branch_2] retrieved_uuids = {root_diff.uuid for root_diff in retrieved} @@ -207,8 +205,8 @@ async def test_filter_time_ranges(self, diff_repository: DiffRepository, reset_d enriched_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=self.diff_branch_name, - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, uuid=root_uuid, nodes={EnrichedNodeFactory.build(relationships={})}, ) @@ -220,24 +218,24 @@ async def test_filter_time_ranges(self, diff_repository: DiffRepository, reset_d retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(self.diff_from_time.subtract(minutes=100)), - to_time=Timestamp(self.diff_from_time.subtract(minutes=50)), + from_time=self.diff_from_time.subtract(minutes=100), + to_time=self.diff_from_time.subtract(minutes=50), ) assert len(retrieved) == 0 # one before, one during retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(self.diff_from_time.subtract(minutes=100)), - to_time=Timestamp(self.diff_to_time.subtract(minutes=1)), + from_time=self.diff_from_time.subtract(minutes=100), + to_time=self.diff_to_time.subtract(minutes=1), ) assert len(retrieved) == 0 # one before, one after retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(self.diff_from_time.subtract(minutes=100)), - to_time=Timestamp(self.diff_to_time.add(minutes=100)), + from_time=self.diff_from_time.subtract(minutes=100), + to_time=self.diff_to_time.add(minutes=100), ) assert len(retrieved) == 1 assert retrieved[0].uuid == root_uuid @@ -245,24 +243,24 @@ async def test_filter_time_ranges(self, diff_repository: DiffRepository, reset_d retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(self.diff_from_time.add(minutes=1)), - to_time=Timestamp(self.diff_to_time.subtract(minutes=1)), + from_time=self.diff_from_time.add(minutes=1), + to_time=self.diff_to_time.subtract(minutes=1), ) assert len(retrieved) == 0 # one during, one after retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(self.diff_from_time.add(minutes=1)), - to_time=Timestamp(self.diff_to_time.add(minutes=1)), + from_time=self.diff_from_time.add(minutes=1), + to_time=self.diff_to_time.add(minutes=1), ) assert len(retrieved) == 0 # both after retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(self.diff_to_time.add(minutes=1)), - to_time=Timestamp(self.diff_to_time.add(minutes=10)), + from_time=self.diff_to_time.add(minutes=1), + to_time=self.diff_to_time.add(minutes=10), ) assert len(retrieved) == 0 @@ -273,8 +271,8 @@ async def test_filter_root_node_uuids(self, diff_repository: DiffRepository, res enriched_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=f"branch{i}", - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, nodes=nodes, ) enriched_diffs.append(enriched_diff) @@ -293,8 +291,8 @@ async def test_filter_root_node_uuids(self, diff_repository: DiffRepository, res this_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name="diff", - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, nodes=other_nodes | {parent_node, middle_node, leaf_node}, ) await self._save_single_diff(diff_repository=diff_repository, enriched_diff=this_diff, do_summary_counts=False) @@ -304,8 +302,8 @@ async def test_filter_root_node_uuids(self, diff_repository: DiffRepository, res retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=diff_branch_names, - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, filters={"ids": [parent_node.uuid]}, ) assert len(retrieved) == 1 @@ -328,8 +326,8 @@ async def test_filter_root_node_uuids(self, diff_repository: DiffRepository, res retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=diff_branch_names, - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, filters={"ids": [middle_node.uuid]}, ) assert len(retrieved) == 1 @@ -360,8 +358,8 @@ async def test_filter_root_node_uuids(self, diff_repository: DiffRepository, res retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=diff_branch_names, - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, filters={"ids": [leaf_node.uuid]}, ) assert len(retrieved) == 1 @@ -422,8 +420,8 @@ async def test_save_and_retrieve_many_diffs(self, diff_repository: DiffRepositor enriched_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=self.diff_branch_name, - from_time=Timestamp(start_time.add(minutes=i * 30)), - to_time=Timestamp(start_time.add(minutes=(i * 30) + 29)), + from_time=start_time.add(minutes=i * 30), + to_time=start_time.add(minutes=(i * 30) + 29), nodes=nodes, ) await self._save_single_diff( @@ -435,8 +433,8 @@ async def test_save_and_retrieve_many_diffs(self, diff_repository: DiffRepositor enriched_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=self.diff_branch_name, - from_time=Timestamp(start_time.add(days=3, minutes=(i * 30))), - to_time=Timestamp(start_time.add(days=3, minutes=(i * 30) + 29)), + from_time=start_time.add(days=3, minutes=(i * 30)), + to_time=start_time.add(days=3, minutes=(i * 30) + 29), nodes=nodes, ) await self._save_single_diff( @@ -446,8 +444,8 @@ async def test_save_and_retrieve_many_diffs(self, diff_repository: DiffRepositor retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(start_time), - to_time=Timestamp(start_time.add(minutes=150)), + from_time=start_time, + to_time=start_time.add(minutes=150), ) assert len(retrieved) == 5 for r in retrieved: @@ -463,8 +461,8 @@ async def test_delete_diff_by_uuid(self, diff_repository: DiffRepository, reset_ enriched_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=self.diff_branch_name, - from_time=Timestamp(start_time.add(minutes=i * 30)), - to_time=Timestamp(start_time.add(minutes=(i * 30) + 29)), + from_time=start_time.add(minutes=i * 30), + to_time=start_time.add(minutes=(i * 30) + 29), nodes=nodes, ) await self._save_single_diff( @@ -480,8 +478,8 @@ async def test_delete_diff_by_uuid(self, diff_repository: DiffRepository, reset_ retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_from_time.add(minutes=(4 * 30) + 29)), + from_time=self.diff_from_time, + to_time=self.diff_from_time.add(minutes=(4 * 30) + 29), ) assert len(retrieved) == len(diffs) for r in retrieved: @@ -498,8 +496,8 @@ async def test_get_by_tracking_id(self, diff_repository: DiffRepository, reset_d enriched_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=self.diff_branch_name, - from_time=Timestamp(self.diff_from_time.add(minutes=i * 30)), - to_time=Timestamp(end_time.add(minutes=(i * 30) + 29)), + from_time=self.diff_from_time.add(minutes=i * 30), + to_time=end_time.add(minutes=(i * 30) + 29), nodes=nodes, ) await self._save_single_diff( @@ -509,8 +507,8 @@ async def test_get_by_tracking_id(self, diff_repository: DiffRepository, reset_d branch_tracked_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=self.diff_branch_name, - from_time=Timestamp(self.diff_from_time.add(minutes=i * 30)), - to_time=Timestamp(end_time.add(minutes=(i * 30) + 29)), + from_time=self.diff_from_time.add(minutes=i * 30), + to_time=end_time.add(minutes=(i * 30) + 29), nodes=nodes, tracking_id=branch_tracking_id, ) @@ -520,8 +518,8 @@ async def test_get_by_tracking_id(self, diff_repository: DiffRepository, reset_d name_tracked_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=self.diff_branch_name, - from_time=Timestamp(self.diff_from_time.add(minutes=i * 30)), - to_time=Timestamp(end_time.add(minutes=(i * 30) + 29)), + from_time=self.diff_from_time.add(minutes=i * 30), + to_time=end_time.add(minutes=(i * 30) + 29), nodes=nodes, tracking_id=name_tracking_id, ) @@ -640,16 +638,16 @@ async def test_limit_and_offset(self, diff_repository: DiffRepository, reset_dat enriched_branch_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=self.diff_branch_name, - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, nodes=all_nodes, tracking_id=NameTrackingId(name="the-best-diff"), ) enriched_base_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=self.base_branch_name, - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, nodes=set(), tracking_id=NameTrackingId(name="the-best-diff"), ) @@ -668,8 +666,8 @@ async def test_limit_and_offset(self, diff_repository: DiffRepository, reset_dat retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, limit=7, ) assert len(retrieved) == 1 @@ -681,8 +679,8 @@ async def test_limit_and_offset(self, diff_repository: DiffRepository, reset_dat retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, limit=7, offset=7, ) @@ -695,8 +693,8 @@ async def test_limit_and_offset(self, diff_repository: DiffRepository, reset_dat retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, limit=7, filters={"kind": {"includes": ["KindOne"]}}, ) @@ -711,8 +709,8 @@ async def test_limit_and_offset(self, diff_repository: DiffRepository, reset_dat retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, limit=7, offset=7, filters={"kind": {"includes": ["KindOne"]}}, @@ -743,8 +741,8 @@ async def test_update_existing(self, db: InfrahubDatabase, diff_repository: Diff enriched_diff = EnrichedRootFactory.build( base_branch_name=self.base_branch_name, diff_branch_name=self.diff_branch_name, - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, nodes={node_with_removes, node_with_updates, node_with_adds}, tracking_id=NameTrackingId(name="the-best-diff"), ) @@ -854,8 +852,8 @@ async def test_update_existing(self, db: InfrahubDatabase, diff_repository: Diff retrieved = await diff_repository.get( base_branch_name=self.base_branch_name, diff_branch_names=[self.diff_branch_name], - from_time=Timestamp(self.diff_from_time), - to_time=Timestamp(self.diff_to_time), + from_time=self.diff_from_time, + to_time=self.diff_to_time, ) assert len(retrieved) == 1 retrieved_diff_root = retrieved[0] diff --git a/backend/tests/unit/core/diff/test_diff_combiner.py b/backend/tests/unit/core/diff/test_diff_combiner.py index 86a60c73a2..10db5edd7e 100644 --- a/backend/tests/unit/core/diff/test_diff_combiner.py +++ b/backend/tests/unit/core/diff/test_diff_combiner.py @@ -1,10 +1,9 @@ from dataclasses import replace -from datetime import UTC from unittest.mock import AsyncMock, MagicMock from uuid import uuid4 import pytest -from pendulum.datetime import DateTime +from whenever import Instant from infrahub.core import registry from infrahub.core.constants import DiffAction, RelationshipCardinality @@ -36,10 +35,10 @@ class TestDiffCombiner: def setup_method(self): - self.diff_from_1 = Timestamp(DateTime(2024, 3, 5, 7, 9, 11, tzinfo=UTC)) - self.diff_to_1 = Timestamp(DateTime(2024, 3, 5, 9, 11, 13, tzinfo=UTC)) - self.diff_from_2 = Timestamp(DateTime(2024, 3, 5, 7, 9, 14, tzinfo=UTC)) - self.diff_to_2 = Timestamp(DateTime(2024, 3, 5, 11, 13, 15, tzinfo=UTC)) + self.diff_from_1 = Timestamp(Instant.from_utc(2024, 3, 5, 7, 9, 11)) + self.diff_to_1 = Timestamp(Instant.from_utc(2024, 3, 5, 9, 11, 13)) + self.diff_from_2 = Timestamp(Instant.from_utc(2024, 3, 5, 7, 9, 14)) + self.diff_to_2 = Timestamp(Instant.from_utc(2024, 3, 5, 11, 13, 15)) self.base_branch = "main" self.diff_branch = "branch" self.diff_root_1 = EnrichedRootFactory.build( diff --git a/backend/tests/unit/core/test_branch.py b/backend/tests/unit/core/test_branch.py index 46f3514d16..813bea3204 100644 --- a/backend/tests/unit/core/test_branch.py +++ b/backend/tests/unit/core/test_branch.py @@ -1,4 +1,5 @@ import pytest +from infrahub_sdk.exceptions import TimestampFormatError from pydantic import ValidationError as PydanticValidationError from infrahub.core.branch import Branch @@ -111,7 +112,7 @@ async def test_branch_branched_form_format_validator(db: InfrahubDatabase): time1 = Timestamp().to_string() assert Branch(name="cr1234", branched_from=time1).branched_from == time1 - with pytest.raises(PydanticValidationError): + with pytest.raises(TimestampFormatError): Branch(name="cr1234", branched_from="not a date") diff --git a/backend/tests/unit/core/test_branch_diff.py b/backend/tests/unit/core/test_branch_diff.py index 7aa670e935..3a5d2d76a6 100644 --- a/backend/tests/unit/core/test_branch_diff.py +++ b/backend/tests/unit/core/test_branch_diff.py @@ -1,6 +1,5 @@ from unittest.mock import patch -import pendulum import pytest from deepdiff import DeepDiff from pydantic import Field @@ -710,7 +709,7 @@ async def test_diff_relationship_one_conflict(db: InfrahubDatabase, default_bran p1_main = car_person_data_generic["p1"] p2_main = car_person_data_generic["p2"] - time_minus1 = pendulum.now(tz="UTC") + time_minus1 = Timestamp() await c1_main.previous_owner.update(data=p2_main, db=db) await c1_main.save(db=db, at=time_minus1) @@ -721,12 +720,12 @@ async def test_diff_relationship_one_conflict(db: InfrahubDatabase, default_bran p1_branch = await NodeManager.get_one(db=db, id=p1_main.id, branch=branch2) # Change previous owner of C1 from P2 to P1 in branch - time11 = pendulum.now(tz="UTC") + time11 = Timestamp() await c1_branch.previous_owner.update(data=p1_branch, db=db) await c1_branch.save(db=db, at=time11) # Change previous owner of C1 from P2 to Null in main - time12 = pendulum.now(tz="UTC") + time12 = Timestamp() c1_main = await NodeManager.get_one(db=db, id=c1_main.id) await c1_main.previous_owner.update(data=[], db=db) await c1_main.save(db=db, at=time12) diff --git a/backend/tests/unit/core/test_query.py b/backend/tests/unit/core/test_query.py index 80138f9e96..d3f568cf8f 100644 --- a/backend/tests/unit/core/test_query.py +++ b/backend/tests/unit/core/test_query.py @@ -1,4 +1,3 @@ -import pendulum import pytest from infrahub.core.query import ( @@ -11,6 +10,7 @@ cleanup_return_labels, sort_results_by_time, ) +from infrahub.core.timestamp import Timestamp from infrahub.database import InfrahubDatabase @@ -148,7 +148,7 @@ async def test_query_count(db: InfrahubDatabase, simple_dataset_01): async def test_query_result_getters(neo4j_factory): - time0 = pendulum.now(tz="UTC") + time0 = Timestamp() n1 = neo4j_factory.hydrate_node(111, {"Car"}, {"uuid": "n1"}, "111") n2 = neo4j_factory.hydrate_node(222, {"AttributeValue"}, {"uuid": "n1a1", "name": "name"}, "222") @@ -159,8 +159,8 @@ async def test_query_result_getters(neo4j_factory): "HAS_ATTRIBUTE", { "branch": "main", - "from": time0.subtract(seconds=60).to_iso8601_string(), - "to": time0.subtract(seconds=30).to_iso8601_string(), + "from": time0.subtract(seconds=60).to_string(), + "to": time0.subtract(seconds=30).to_string(), "status": "active", }, ) @@ -169,7 +169,7 @@ async def test_query_result_getters(neo4j_factory): 111, 222, "HAS_ATTRIBUTE", - {"branch": "main", "from": time0.subtract(seconds=30).to_iso8601_string(), "to": None, "status": "active"}, + {"branch": "main", "from": time0.subtract(seconds=30).to_string(), "to": None, "status": "active"}, ) qr = QueryResult( @@ -194,7 +194,7 @@ async def test_query_result_getters(neo4j_factory): async def test_sort_results_by_time(neo4j_factory): - time0 = pendulum.now(tz="UTC") + time0 = Timestamp() n1 = neo4j_factory.hydrate_node(111, {"Car"}, {"uuid": "n1"}, "111") n2 = neo4j_factory.hydrate_node(222, {"AttributeValue"}, {"uuid": "n1a1", "name": "name"}, "222") @@ -205,8 +205,8 @@ async def test_sort_results_by_time(neo4j_factory): "HAS_ATTRIBUTE", { "branch": "main", - "from": time0.subtract(seconds=60).to_iso8601_string(), - "to": time0.subtract(seconds=30).to_iso8601_string(), + "from": time0.subtract(seconds=60).to_string(), + "to": time0.subtract(seconds=30).to_string(), "status": "active", }, ) @@ -215,7 +215,7 @@ async def test_sort_results_by_time(neo4j_factory): 111, 222, "HAS_ATTRIBUTE", - {"branch": "main", "from": time0.subtract(seconds=30).to_iso8601_string(), "to": None, "status": "active"}, + {"branch": "main", "from": time0.subtract(seconds=30).to_string(), "to": None, "status": "active"}, ) r3 = neo4j_factory.hydrate_relationship( 1112223, @@ -224,8 +224,8 @@ async def test_sort_results_by_time(neo4j_factory): "HAS_ATTRIBUTE", { "branch": "main", - "from": time0.subtract(seconds=90).to_iso8601_string(), - "to": time0.subtract(seconds=60).to_iso8601_string(), + "from": time0.subtract(seconds=90).to_string(), + "to": time0.subtract(seconds=60).to_string(), "status": "active", }, ) diff --git a/backend/tests/unit/graphql/diff/test_diff_tree_query.py b/backend/tests/unit/graphql/diff/test_diff_tree_query.py index bf90049ecd..0af3b26740 100644 --- a/backend/tests/unit/graphql/diff/test_diff_tree_query.py +++ b/backend/tests/unit/graphql/diff/test_diff_tree_query.py @@ -1,4 +1,4 @@ -from datetime import UTC, datetime +from datetime import datetime, timezone from unittest.mock import AsyncMock import pytest @@ -21,6 +21,8 @@ from infrahub.graphql.initialization import prepare_graphql_params from tests.helpers.graphql import graphql +UTC = timezone.utc # Required for older versions of Python + ADDED_ACTION = "ADDED" UPDATED_ACTION = "UPDATED" REMOVED_ACTION = "REMOVED" @@ -217,8 +219,8 @@ async def test_diff_tree_no_changes( enriched_diff_metadata = await diff_coordinator.update_branch_diff( base_branch=default_branch, diff_branch=diff_branch ) - from_time = datetime.fromisoformat(diff_branch.branched_from) - to_time = datetime.fromisoformat(enriched_diff_metadata.to_time.to_string()) + from_time = Timestamp(diff_branch.branched_from) + to_time = enriched_diff_metadata.to_time params = await prepare_graphql_params( db=db, include_mutation=False, include_subscription=False, branch=default_branch @@ -235,8 +237,8 @@ async def test_diff_tree_no_changes( assert result.data["DiffTree"] == { "base_branch": default_branch.name, "diff_branch": diff_branch.name, - "from_time": from_time.isoformat(), - "to_time": to_time.isoformat(), + "from_time": from_time.to_datetime().isoformat(), + "to_time": to_time.to_datetime().isoformat(), "num_added": 0, "num_removed": 0, "num_updated": 0, @@ -294,10 +296,10 @@ async def test_diff_tree_one_attr_change( main_crit.color.value = "#fedcba" branch_crit = await NodeManager.get_one(db=db, id=criticality_low.id, branch=diff_branch) branch_crit.color.value = "#abcdef" - before_change_datetime = datetime.now(tz=UTC) + before_change_datetime = Timestamp() await main_crit.save(db=db) await branch_crit.save(db=db) - after_change_datetime = datetime.now(tz=UTC) + after_change_datetime = Timestamp() enriched_diff_metadata = await diff_coordinator.update_branch_diff( base_branch=default_branch, diff_branch=diff_branch @@ -329,8 +331,8 @@ async def test_diff_tree_one_attr_change( root_value=None, variable_values={"branch": diff_branch.name}, ) - from_time = datetime.fromisoformat(diff_branch.branched_from) - to_time = datetime.fromisoformat(enriched_diff_metadata.to_time.to_string()) + from_time = Timestamp(diff_branch.branched_from) + to_time = enriched_diff_metadata.to_time assert result.errors is None @@ -338,20 +340,20 @@ async def test_diff_tree_one_attr_change( assert result.data["DiffTree"]["nodes"] node_diff = result.data["DiffTree"]["nodes"][0] node_changed_at = node_diff["last_changed_at"] - assert datetime.fromisoformat(node_changed_at) < before_change_datetime + assert Timestamp(node_changed_at) < before_change_datetime assert node_diff["attributes"] attribute_diff = node_diff["attributes"][0] attribute_changed_at = attribute_diff["last_changed_at"] - assert datetime.fromisoformat(attribute_changed_at) < before_change_datetime + assert Timestamp(attribute_changed_at) < before_change_datetime assert attribute_diff["properties"] property_diff = attribute_diff["properties"][0] property_changed_at = property_diff["last_changed_at"] - assert before_change_datetime < datetime.fromisoformat(property_changed_at) < after_change_datetime + assert before_change_datetime < Timestamp(property_changed_at) < after_change_datetime assert result.data["DiffTree"] == { "base_branch": "main", "diff_branch": diff_branch.name, - "from_time": from_time.isoformat(), - "to_time": to_time.isoformat(), + "from_time": from_time.to_datetime().isoformat(), + "to_time": to_time.to_datetime().isoformat(), "num_added": 0, "num_removed": 0, "num_updated": 1, @@ -426,9 +428,9 @@ async def test_diff_tree_one_relationship_change( ): branch_car = await NodeManager.get_one(db=db, id=car_accord_main.id, branch=diff_branch) await branch_car.owner.update(db=db, data=[person_jane_main]) - before_change_datetime = datetime.now(tz=UTC) + before_change_datetime = Timestamp() await branch_car.save(db=db) - after_change_datetime = datetime.now(tz=UTC) + after_change_datetime = Timestamp() accord_label = await branch_car.render_display_label(db=db) john_label = await person_john_main.render_display_label(db=db) jane_label = await person_jane_main.render_display_label(db=db) @@ -446,8 +448,8 @@ async def test_diff_tree_one_relationship_change( root_value=None, variable_values={"branch": diff_branch.name}, ) - from_time = datetime.fromisoformat(diff_branch.branched_from) - to_time = datetime.fromisoformat(enriched_diff_metadata.to_time.to_string()) + from_time = Timestamp(diff_branch.branched_from) + to_time = enriched_diff_metadata.to_time assert result.errors is None @@ -457,8 +459,8 @@ async def test_diff_tree_one_relationship_change( assert diff_tree_response == { "base_branch": "main", "diff_branch": diff_branch.name, - "from_time": from_time.isoformat(), - "to_time": to_time.isoformat(), + "from_time": from_time.to_datetime().isoformat(), + "to_time": to_time.to_datetime().isoformat(), "num_added": 0, "num_removed": 0, "num_updated": 3, @@ -473,7 +475,7 @@ async def test_diff_tree_one_relationship_change( car_response = node_response_by_id[car_accord_main.id] car_relationship_response = car_response.pop("relationships") car_changed_at = car_response["last_changed_at"] - assert datetime.fromisoformat(car_changed_at) < before_change_datetime + assert Timestamp(car_changed_at) < before_change_datetime assert car_response == { "uuid": car_accord_main.id, "kind": car_accord_main.get_kind(), @@ -492,7 +494,7 @@ async def test_diff_tree_one_relationship_change( assert set(car_relationships_by_name.keys()) == {"owner"} owner_rel = car_relationships_by_name["owner"] owner_changed_at = owner_rel["last_changed_at"] - assert before_change_datetime < datetime.fromisoformat(owner_changed_at) < after_change_datetime + assert before_change_datetime < Timestamp(owner_changed_at) < after_change_datetime owner_elements = owner_rel.pop("elements") assert owner_rel == { "name": "owner", @@ -504,7 +506,7 @@ async def test_diff_tree_one_relationship_change( assert len(owner_elements) == 1 owner_element = owner_elements[0] owner_element_changed_at = owner_element["last_changed_at"] - assert before_change_datetime < datetime.fromisoformat(owner_element_changed_at) < after_change_datetime + assert before_change_datetime < Timestamp(owner_element_changed_at) < after_change_datetime owner_properties = owner_element.pop("properties") assert owner_element == { "status": UPDATED_ACTION, @@ -517,7 +519,7 @@ async def test_diff_tree_one_relationship_change( assert set(owner_properties_by_type.keys()) == {IS_RELATED_TYPE, IS_PROTECTED_TYPE, IS_VISIBLE_TYPE} owner_prop = owner_properties_by_type[IS_RELATED_TYPE] owner_prop_changed_at = owner_prop["last_changed_at"] - assert before_change_datetime < datetime.fromisoformat(owner_prop_changed_at) < after_change_datetime + assert before_change_datetime < Timestamp(owner_prop_changed_at) < after_change_datetime assert owner_prop == { "property_type": IS_RELATED_TYPE, "last_changed_at": owner_prop_changed_at, @@ -530,7 +532,7 @@ async def test_diff_tree_one_relationship_change( } owner_prop = owner_properties_by_type[IS_RELATED_TYPE] owner_prop_changed_at = owner_prop["last_changed_at"] - assert before_change_datetime < datetime.fromisoformat(owner_prop_changed_at) < after_change_datetime + assert before_change_datetime < Timestamp(owner_prop_changed_at) < after_change_datetime assert owner_prop == { "property_type": IS_RELATED_TYPE, "last_changed_at": owner_prop_changed_at, @@ -545,7 +547,7 @@ async def test_diff_tree_one_relationship_change( john_response = node_response_by_id[person_john_main.id] john_relationship_response = john_response.pop("relationships") john_changed_at = john_response["last_changed_at"] - assert datetime.fromisoformat(john_changed_at) < before_change_datetime + assert Timestamp(john_changed_at) < before_change_datetime assert john_response == { "uuid": person_john_main.id, "kind": person_john_main.get_kind(), @@ -564,7 +566,7 @@ async def test_diff_tree_one_relationship_change( assert set(john_relationships_by_name.keys()) == {"cars"} cars_rel = john_relationships_by_name["cars"] cars_changed_at = cars_rel["last_changed_at"] - assert before_change_datetime < datetime.fromisoformat(cars_changed_at) < after_change_datetime + assert before_change_datetime < Timestamp(cars_changed_at) < after_change_datetime cars_elements = cars_rel.pop("elements") assert cars_rel == { "name": "cars", @@ -576,7 +578,7 @@ async def test_diff_tree_one_relationship_change( assert len(cars_elements) == 1 cars_element = cars_elements[0] cars_element_changed_at = cars_element["last_changed_at"] - assert before_change_datetime < datetime.fromisoformat(cars_element_changed_at) < after_change_datetime + assert before_change_datetime < Timestamp(cars_element_changed_at) < after_change_datetime cars_properties = cars_element.pop("properties") assert cars_element == { "status": REMOVED_ACTION, @@ -594,7 +596,7 @@ async def test_diff_tree_one_relationship_change( ]: cars_prop = cars_properties_by_type[property_type] cars_prop_changed_at = cars_prop["last_changed_at"] - assert before_change_datetime < datetime.fromisoformat(cars_prop_changed_at) < after_change_datetime + assert before_change_datetime < Timestamp(cars_prop_changed_at) < after_change_datetime assert cars_prop == { "property_type": property_type, "last_changed_at": cars_prop_changed_at, @@ -609,7 +611,7 @@ async def test_diff_tree_one_relationship_change( jane_response = node_response_by_id[person_jane_main.id] jane_relationship_response = jane_response.pop("relationships") jane_changed_at = jane_response["last_changed_at"] - assert datetime.fromisoformat(jane_changed_at) < before_change_datetime + assert Timestamp(jane_changed_at) < before_change_datetime assert jane_response == { "uuid": person_jane_main.id, "kind": person_jane_main.get_kind(), @@ -628,7 +630,7 @@ async def test_diff_tree_one_relationship_change( assert set(jane_relationships_by_name.keys()) == {"cars"} cars_rel = jane_relationships_by_name["cars"] cars_changed_at = cars_rel["last_changed_at"] - assert before_change_datetime < datetime.fromisoformat(cars_changed_at) < after_change_datetime + assert before_change_datetime < Timestamp(cars_changed_at) < after_change_datetime cars_elements = cars_rel.pop("elements") assert cars_rel == { "name": "cars", @@ -640,7 +642,7 @@ async def test_diff_tree_one_relationship_change( assert len(cars_elements) == 1 cars_element = cars_elements[0] cars_element_changed_at = cars_element["last_changed_at"] - assert before_change_datetime < datetime.fromisoformat(cars_element_changed_at) < after_change_datetime + assert before_change_datetime < Timestamp(cars_element_changed_at) < after_change_datetime cars_properties = cars_element.pop("properties") assert cars_element == { "status": ADDED_ACTION, @@ -658,7 +660,7 @@ async def test_diff_tree_one_relationship_change( ]: cars_prop = cars_properties_by_type[property_type] cars_prop_changed_at = cars_prop["last_changed_at"] - assert before_change_datetime < datetime.fromisoformat(cars_prop_changed_at) < after_change_datetime + assert before_change_datetime < Timestamp(cars_prop_changed_at) < after_change_datetime assert cars_prop == { "property_type": property_type, "last_changed_at": cars_prop_changed_at, @@ -745,8 +747,8 @@ async def test_diff_tree_summary_no_changes( enriched_diff_metadata = await diff_coordinator.update_branch_diff( base_branch=default_branch, diff_branch=diff_branch ) - from_time = datetime.fromisoformat(diff_branch.branched_from) - to_time = datetime.fromisoformat(enriched_diff_metadata.to_time.to_string()) + from_time = Timestamp(diff_branch.branched_from) + to_time = enriched_diff_metadata.to_time params = await prepare_graphql_params( db=db, include_mutation=False, include_subscription=False, branch=default_branch @@ -763,8 +765,8 @@ async def test_diff_tree_summary_no_changes( assert result.data["DiffTreeSummary"] == { "base_branch": default_branch.name, "diff_branch": diff_branch.name, - "from_time": from_time.isoformat(), - "to_time": to_time.isoformat(), + "from_time": from_time.to_datetime().isoformat(), + "to_time": to_time.to_datetime().isoformat(), "num_added": 0, "num_removed": 0, "num_updated": 0, @@ -780,12 +782,24 @@ async def test_diff_tree_summary_no_changes( [ pytest.param( {}, - DiffSummaryCounters(num_added=2, num_updated=5, num_removed=2, from_time=Timestamp(), to_time=Timestamp()), + DiffSummaryCounters( + num_added=2, + num_updated=5, + num_removed=2, + from_time=Timestamp(datetime.now(UTC).isoformat()), + to_time=Timestamp(datetime.now(UTC).isoformat()), + ), id="no-filters", ), pytest.param( {"kind": {"includes": ["TestThing"]}}, - DiffSummaryCounters(num_added=2, num_updated=1, num_removed=2, from_time=Timestamp(), to_time=Timestamp()), + DiffSummaryCounters( + num_added=2, + num_updated=1, + num_removed=2, + from_time=Timestamp(datetime.now(UTC).isoformat()), + to_time=Timestamp(datetime.now(UTC).isoformat()), + ), id="kind-includes", ), ], diff --git a/backend/tests/unit/graphql/queries/test_task.py b/backend/tests/unit/graphql/queries/test_task.py index f74c03336f..9e9c7ab62c 100644 --- a/backend/tests/unit/graphql/queries/test_task.py +++ b/backend/tests/unit/graphql/queries/test_task.py @@ -6,6 +6,7 @@ from infrahub_sdk.graphql import Query from prefect.artifacts import ArtifactRequest from prefect.client.orchestration import PrefectClient, get_client +from prefect.flows import FlowRun from prefect.states import State from infrahub.core.branch import Branch @@ -131,7 +132,7 @@ async def delete_flow_runs(prefect_client: PrefectClient): @pytest.fixture -async def flow_runs_data(prefect_client: PrefectClient, tag_blue, tag_red, account_bob): +async def flow_runs_data(prefect_client: PrefectClient, tag_blue, tag_red, account_bob) -> dict[str, FlowRun]: branch1_tag = WorkflowTag.BRANCH.render(identifier="branch1") db_tag = WorkflowTag.DATABASE_CHANGE.render() items = [ @@ -225,7 +226,7 @@ async def test_task_query_prefect( default_branch: Branch, register_core_models_schema: None, delete_flow_runs, - flow_runs_data, + flow_runs_data: dict[str, FlowRun], ): result = await run_query( db=db, @@ -254,7 +255,7 @@ async def test_task_query_filter_workflow( default_branch: Branch, register_core_models_schema: None, delete_flow_runs, - flow_runs_data, + flow_runs_data: dict[str, FlowRun], ): QUERY = """ query { @@ -473,7 +474,7 @@ async def test_task_query_filter_node( account_bob, account_bill, delete_flow_runs, - flow_runs_data, + flow_runs_data: dict[str, FlowRun], ): result = await run_query( db=db, @@ -580,7 +581,7 @@ async def test_task_query_both( tag_blue, account_bob, delete_flow_runs, - flow_runs_data, + flow_runs_data: dict[str, FlowRun], ): result = await run_query( db=db, @@ -611,7 +612,7 @@ async def test_task_branch_status( tag_blue, account_bob, delete_flow_runs, - flow_runs_data, + flow_runs_data: dict[str, FlowRun], ): QUERY = """ query TaskQuery( @@ -710,7 +711,7 @@ async def test_task_no_count( tag_blue, account_bob, delete_flow_runs, - flow_runs_data, + flow_runs_data: dict[str, FlowRun], ): QUERY = """ query TaskQuery { @@ -753,7 +754,7 @@ async def test_task_only_count( tag_blue, account_bob, delete_flow_runs, - flow_runs_data, + flow_runs_data: dict[str, FlowRun], ): QUERY = """ query TaskQuery { diff --git a/backend/tests/unit/graphql/test_graphql_query.py b/backend/tests/unit/graphql/test_graphql_query.py index 624a41dc7d..0fe97aa990 100644 --- a/backend/tests/unit/graphql/test_graphql_query.py +++ b/backend/tests/unit/graphql/test_graphql_query.py @@ -2048,10 +2048,9 @@ async def test_query_node_updated_at(db: InfrahubDatabase, default_branch: Branc assert result2.errors is None assert result2.data["TestPerson"]["edges"][0]["node"]["_updated_at"] assert result2.data["TestPerson"]["edges"][1]["node"]["_updated_at"] - assert ( + assert result2.data["TestPerson"]["edges"][1]["node"]["_updated_at"] == Timestamp( result2.data["TestPerson"]["edges"][1]["node"]["_updated_at"] - == Timestamp(result2.data["TestPerson"]["edges"][1]["node"]["_updated_at"]).to_string() - ) + ).to_string(with_z=False) assert ( result2.data["TestPerson"]["edges"][0]["node"]["_updated_at"] != result2.data["TestPerson"]["edges"][1]["node"]["_updated_at"] @@ -2125,12 +2124,9 @@ async def test_query_relationship_updated_at(db: InfrahubDatabase, default_branc result2.data["TestPerson"]["edges"][0]["node"]["tags"]["edges"][0]["node"]["_updated_at"] != result2.data["TestPerson"]["edges"][0]["node"]["tags"]["edges"][0]["properties"]["updated_at"] ) - assert ( + assert result2.data["TestPerson"]["edges"][0]["node"]["tags"]["edges"][0]["node"]["_updated_at"] == Timestamp( result2.data["TestPerson"]["edges"][0]["node"]["tags"]["edges"][0]["node"]["_updated_at"] - == Timestamp( - result2.data["TestPerson"]["edges"][0]["node"]["tags"]["edges"][0]["node"]["_updated_at"] - ).to_string() - ) + ).to_string(with_z=False) async def test_query_attribute_node_property_source( diff --git a/poetry.lock b/poetry.lock index ddbab21d17..08b2b85ff7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -5668,6 +5668,89 @@ files = [ {file = "websockets-13.1.tar.gz", hash = "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878"}, ] +[[package]] +name = "whenever" +version = "0.7.2" +description = "Modern datetime library for Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "whenever-0.7.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a87864d3e7679dbedc55d3aa8c6cef5ffdc45520e16805f4c5a3cf71241fb986"}, + {file = "whenever-0.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f37dc37d1bea611af16a3aaba5960038604ddfb4a592b1d72a3efccd5853b6da"}, + {file = "whenever-0.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3da602b9fb80f8c6495e0495638c54a8b9a43362769199fcfe4e4fc6df33697"}, + {file = "whenever-0.7.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:54c7afaeaada1d244016ce38252f0c0340bd7d199b4a240ba986efaab66b02f2"}, + {file = "whenever-0.7.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f71fd077601c27830e202ed652bd89b46ae6f1ba0f96d29897038dae9c80eead"}, + {file = "whenever-0.7.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40c74e8f0f3a9a540f580d44a22f2f9dc54b17b68d64abb1c0c961ab1343d43b"}, + {file = "whenever-0.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de72b15de311b28e6fcdb45bd436fbb0bde0d4596e0c446f9301bb523b6f2369"}, + {file = "whenever-0.7.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a84ff30d230e56250f89e99f5442d51a5215e10f6b7902d0d7ec51d8b06b6b2"}, + {file = "whenever-0.7.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2af28fa6c8446f513ed3c71275349831e79df021dadb0051fb5b6cbd353d16d6"}, + {file = "whenever-0.7.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:7f65c163f80b397f532d6dd9f56ead5b5d8b76bc24b1587dbb152bb466bd7de0"}, + {file = "whenever-0.7.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ef6c83a20b9ccfe10623596dda19d666cc95c0e83260a6568d767bc926da3781"}, + {file = "whenever-0.7.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6322b78dd97b295164f0d59115be71e9242f74c100899736876b1e8f19b2ff0f"}, + {file = "whenever-0.7.2-cp310-cp310-win32.whl", hash = "sha256:b9a2fc32a8914771d994d6349dcf25208c82d0eb6cf33f27b2309d9e8f58a51a"}, + {file = "whenever-0.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:1440b8e1ef507c318a741bede7a43263f84909c43cf48f110de509233b89d77c"}, + {file = "whenever-0.7.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:0b5aaa62551213b3b099b460331fce75c7dbabc2f6696fe3be845cb4ecc8a856"}, + {file = "whenever-0.7.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a4720cc7bf704e92b89bf60329f21084256b4b4a9dcc47a782461f7918d7e1fb"}, + {file = "whenever-0.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91a18c81e517124463200b7fcde40ddcc18c959791b219dd681dc5fdec04f050"}, + {file = "whenever-0.7.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:85ef3850f6a9ce3d5349a4f5a1d7fda14c68d3f18c0d18a890bcb11955709a8c"}, + {file = "whenever-0.7.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9af47e5ff5d8528a7149f253276e1094bb944335074241d7e9f6c26ea12aa9ac"}, + {file = "whenever-0.7.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:389afeb92b6272f35132a428884ba03f52ca5a9e80c1b28e0f9699f6098abf34"}, + {file = "whenever-0.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:825a9567ba0b91f1e970cd59f0bbf7b6c2c12c41621fd3264e2d1a0f596c3efe"}, + {file = "whenever-0.7.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9d303cb0c691784219b7539e537167ea573cf58acc42696159585d27dacd10af"}, + {file = "whenever-0.7.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6194cf9bf76cb0e3c8593d757b73b41cb33c1137ce1a79795812d43be8a29a95"}, + {file = "whenever-0.7.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:59c0fb56aed72a0ec10a83b99f8eee2e96e4b32045e4ecfe85027129295cde6a"}, + {file = "whenever-0.7.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f50068f98c85706e384a84e6a6e5d0d38760bbcb770fbd140596d2228f101c2e"}, + {file = "whenever-0.7.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:993c98e9956597b61e21c3c65da8d5e9eb342fe6c6efc2135432be56aa64a116"}, + {file = "whenever-0.7.2-cp311-cp311-win32.whl", hash = "sha256:e1d0ea62becd437ae9c911303cbcc5ba66107a79c9e60a4e0f965537878a3c77"}, + {file = "whenever-0.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:c70a6ab84a4d7bb44e86fa9ebec2ea36a456457d211dcb48f16f54487774ec45"}, + {file = "whenever-0.7.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:acaedfa0327e8859c078c40c2e17a3d169ce9f784c3735c09fd701d4035b7432"}, + {file = "whenever-0.7.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38de1c34ab4e42eda4006e8635cadc0c526094a546aa5ebf6a903c61d33053f3"}, + {file = "whenever-0.7.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87e62291c4a0f212a13053f021b9255e0b820e57303c96e94b48304b84a1849d"}, + {file = "whenever-0.7.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e0cbf68b2833e6766fb4898ebe432406ce6ead7ac846f7b15427bfbd560d5939"}, + {file = "whenever-0.7.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2220cf0d818d960d4a7ec1b05ffbed7b81e482807be0b4bb7a5466418a4c8f79"}, + {file = "whenever-0.7.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7395c69109113eb1666bac29b6207caf28e38e25d332c57649a7e710f0d863db"}, + {file = "whenever-0.7.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efcbffe9a510f310f019fe5bfe877e591ea8cdad90ac8fe6868a80659d411ac5"}, + {file = "whenever-0.7.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e2d836ad37f4333e938779eae6e64f532f27ce19529ee9c09bfb62f796e41db1"}, + {file = "whenever-0.7.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:59f1949d1efe4a85cfe81130159dc2c871ea5b56bae6e9782d5e344a747a758e"}, + {file = "whenever-0.7.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:030836f2cb15eb33631c3d3c2f904d481edc797df063814f9c77d060db5db17d"}, + {file = "whenever-0.7.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b25d8fd6ade64cf1492707c019cccb726aa07dfb20f79a4751eccb56555c2012"}, + {file = "whenever-0.7.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:247e0255c6c8ded48a6d3734aabf448f2bf07bb2abb65b2828104df1eaab82cf"}, + {file = "whenever-0.7.2-cp312-cp312-win32.whl", hash = "sha256:81fcef2c6917333d3aa8d24043e01323d8831c1354cabcb935e29b2a1f6a7a4f"}, + {file = "whenever-0.7.2-cp312-cp312-win_amd64.whl", hash = "sha256:2cdb4ddd2b2e908a076232a60577e4616096d4cf166da9373c4a03bf9d81721e"}, + {file = "whenever-0.7.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:c35f47f613a7816d602fd39594400bfe7fff70a3bd7272cd9b8c736ffc13feed"}, + {file = "whenever-0.7.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0cb7515e180aa2fea6c2d1855607011dd08d14acaba750b0673d7d6f536b0f5e"}, + {file = "whenever-0.7.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fac40aed9be0bc1aeba2662e17f145987f84e8a0bafbfa5f938b40db82fc7aba"}, + {file = "whenever-0.7.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ccd0840d04648dad3c5ae81a53a56e08a971a316d4167921665a7aa5fa8f0085"}, + {file = "whenever-0.7.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bf5199ffa1da783207b0c75d478ab6d808309cc0cbb2631640393bd943b6167e"}, + {file = "whenever-0.7.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7be787eeb542f86cc2d0081c541e89e4417261976a50a7824f6e43248fadb294"}, + {file = "whenever-0.7.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d78e13c648ce246dbaa54f78faf1d2f3d8107619f3c598d3d127ca45fd5d792a"}, + {file = "whenever-0.7.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cc490b577f38bb55957e04d6a1b594c5365f01a6f3429c38b26243d3cf473d80"}, + {file = "whenever-0.7.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bf322daa4184e7d89a4549498c8408e6c4a0bd2309eacd4b21151020bf51870c"}, + {file = "whenever-0.7.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:00b60a9af13e4c6b618f52a55ae7c15c36eb3ff42bfc6cb050981e8a2402bc9f"}, + {file = "whenever-0.7.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a2f82fd85a6521090d3f44412f4c76687a0e141df215541f6f0f6691276257e7"}, + {file = "whenever-0.7.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a386df7b5e08f56a49f8a00991e54c3f5ebb218570d7a98c726d793859a2b0ea"}, + {file = "whenever-0.7.2-cp313-cp313-win32.whl", hash = "sha256:46e51abd495c91fd586828401884750d7eb96ca3658d3d9f228f62beb140c758"}, + {file = "whenever-0.7.2-cp313-cp313-win_amd64.whl", hash = "sha256:af67395516ed16a8423735a4dd5a8795353f39e758b7428178dbe8de06977f21"}, + {file = "whenever-0.7.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a8b25304ffc9563bf17914a9a9bf6642456923c727d330fcfa483d303f549805"}, + {file = "whenever-0.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2978fb80700e583e2f957cd47c51d6b161f38a50b85a1744fcf3b13e53acf113"}, + {file = "whenever-0.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:246ce04d18469169582cd492b6a4f74f6c166ed2caa869679522b02228c0bbf8"}, + {file = "whenever-0.7.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6d464feea543f36dd712eee0f47ea690cf1a4d474c39ddaafe30254434ac9b2e"}, + {file = "whenever-0.7.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:253460d1194a1dcb27a47a0c6cead61cbf0a29d5bb795e7f42caa0e7be32cae9"}, + {file = "whenever-0.7.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a6b35953ca90ef5f0f2a7f3e951d110239fcccde5eccf08c4a0872821d41066"}, + {file = "whenever-0.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6c9bb2528c345d552e0e25ab82276dd9765185718dfdf2654f0d84771eb3fa9"}, + {file = "whenever-0.7.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bc0a7e6e5bfa15531910ca4a062fdc20c071747f016599999eac3d8fef7ea4db"}, + {file = "whenever-0.7.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8c16c03a556819c8f1738dbcfa2793c8c0d2a9a496e0ec1524fea8a124d20037"}, + {file = "whenever-0.7.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:43c2f1be68f638c7f3f27c60e5851b5b94aa3ba0186e84bc2010c880e71f7f84"}, + {file = "whenever-0.7.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:715c4da7fbef766bfb5511017782873c98adac9f5f982806ead9b4a99f7bb086"}, + {file = "whenever-0.7.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d3daadd03d392048a4041969132ae2a6b57941b172870c526b14c8343721967d"}, + {file = "whenever-0.7.2-cp39-cp39-win32.whl", hash = "sha256:7b3c1d9ec5dc844686aad66bb0e14dda7d9667a113757c1f566a8e8036e4585f"}, + {file = "whenever-0.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:166f4d31f0be9ee59d00670f52a724c4d1090688b46e3531d0ccb74ae3157032"}, + {file = "whenever-0.7.2.tar.gz", hash = "sha256:a292dddd4d635a5b597686117e455d41e6134716a7be66b3903554514df8729c"}, +] + +[package.dependencies] +tzdata = {version = ">=2020.1", markers = "sys_platform == \"win32\""} + [[package]] name = "wrapt" version = "1.16.0" @@ -5892,4 +5975,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.10, < 3.13" -content-hash = "bdd843d7a3883db24d3a6e3a540f21106b46536dc32986abfd9393585f823763" +content-hash = "968fcfd928f83db998e06ebe96fd8221136fad5d0808d59f02c536a5345900bf" diff --git a/pyproject.toml b/pyproject.toml index a60e85f377..c759e95482 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,6 +72,7 @@ numpy = [ { version = "^1.26.2", python = ">=3.12" }, ] dulwich = "^0.22.7" +whenever = "0.7.2" [tool.poetry.group.dev.dependencies] diff --git a/python_sdk b/python_sdk index 1a6f3cdaf9..55be7bb23e 160000 --- a/python_sdk +++ b/python_sdk @@ -1 +1 @@ -Subproject commit 1a6f3cdaf9cdf84ad679f1a2e98cf14a6f79eeca +Subproject commit 55be7bb23ee83201f3bbf6f5508b4bb869ffecf5