From 310902d2212aab694743f5635cb6c63344d31ccb Mon Sep 17 00:00:00 2001 From: Isaac Na Date: Tue, 21 Dec 2021 01:46:18 -0500 Subject: [PATCH] bugfix/use-consistent-datetime-in-hash-generation (#144) * Link to test-deployment repo * Link to test deployment UI * Fix including print statements * Refresh var * Remove print statements * Add unit tests * Fix lint errors * Remove extra line * Remove redundant var * Top level conditional branches * Add datetime branch to top level --- cdp_backend/database/functions.py | 20 ++++++++++++++------ cdp_backend/tests/database/test_functions.py | 19 ++++++++++++++++++- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/cdp_backend/database/functions.py b/cdp_backend/database/functions.py index bdb6158f..15f655bb 100644 --- a/cdp_backend/database/functions.py +++ b/cdp_backend/database/functions.py @@ -43,22 +43,30 @@ def generate_and_attach_doc_hash_as_id(db_model: Model) -> Model: for pk in db_model._PRIMARY_KEYS: field = getattr(db_model, pk) + # Load the document for reference fields and add id to hasher + if isinstance(field, ReferenceDocLoader): + hasher.update(pickle.dumps(field.get().id, protocol=4)) + # Handle reference fields by using their doc path - if isinstance(field, Model): + elif isinstance(field, Model): # Ensure that the underlying model has an id # In place update to db_model for this field setattr(db_model, pk, generate_and_attach_doc_hash_as_id(field)) + # Update variable after setattr + field = getattr(db_model, pk) + # Now attach the generated hash document path hasher.update(pickle.dumps(field.id, protocol=4)) + # If datetime, hash with epoch millis to avoid timezone issues + elif isinstance(field, datetime): + field = field.timestamp() + hasher.update(pickle.dumps(field, protocol=4)) + # Otherwise just simply add the primary key value else: - # Load the document for reference fields and add id to hasher - if isinstance(field, ReferenceDocLoader): - hasher.update(pickle.dumps(field.get().id, protocol=4)) - else: - hasher.update(pickle.dumps(field, protocol=4)) + hasher.update(pickle.dumps(field, protocol=4)) # Set the id to the first twelve characters of hexdigest db_model.id = hasher.hexdigest()[:12] diff --git a/cdp_backend/tests/database/test_functions.py b/cdp_backend/tests/database/test_functions.py index a240aee9..cea92930 100644 --- a/cdp_backend/tests/database/test_functions.py +++ b/cdp_backend/tests/database/test_functions.py @@ -1,14 +1,17 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +from datetime import datetime, timezone + import pytest +import pytz from fireo.models import Model from cdp_backend.database import functions as db_functions from cdp_backend.database import models as db_models ############################################################################### -# Tests +# Test constants body_a = db_models.Body() body_a.name = "Body A" @@ -16,6 +19,17 @@ body_b = db_models.Body() body_b.name = "Body B" +a_datetime = datetime.fromisoformat("2021-08-16 07:42:10.318957+00:00") +event_a = db_models.Event.Example() +event_a.event_datetime = a_datetime + +event_b = db_models.Event.Example() +local_tz = pytz.timezone("Europe/Moscow") +modified_dt = event_a.event_datetime.replace(tzinfo=timezone.utc).astimezone( + tz=local_tz +) +event_b.event_datetime = local_tz.normalize(modified_dt) + @pytest.mark.parametrize( "model, expected_id", @@ -27,6 +41,9 @@ # Testing models differ (body_a, "0a8a8e139258"), (body_b, "1535fef479ff"), + # Testing timezone difference + (event_a, "6291946d4094"), + (event_b, "6291946d4094"), ], ) def test_generate_and_attach_doc_hash_as_id(model: Model, expected_id: str) -> None: