From 66883dc2b42267fec8d55e668afd679acfecb437 Mon Sep 17 00:00:00 2001 From: Lin Yang Date: Fri, 23 Dec 2016 18:05:53 -0800 Subject: [PATCH] Auto add timestamp fields into db model Created new class ModelBaseWithTimeStamp() to automatically handle these timestamp fields: created_at and updated_at when user create/update key-value pair in database. Change-Id: I8fe69e2ec9866d0ccf020f3687af754d96242f46 Closes-Bug: #1652390 --- test-requirements.txt | 1 + valence/db/models.py | 49 ++++++++++++++++++++++++---- valence/tests/unit/db/test_db_api.py | 9 +++++ valence/tests/unit/db/utils.py | 4 +-- 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/test-requirements.txt b/test-requirements.txt index 8a03d8e..18e83d8 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -5,6 +5,7 @@ hacking<0.11,>=0.10.0 coverage>=3.6 +freezegun>=0.3.6 # Apache-2.0 python-subunit>=0.0.18 sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 oslosphinx>=2.5.0 # Apache-2.0 diff --git a/valence/db/models.py b/valence/db/models.py index 3291d21..fc800ae 100644 --- a/valence/db/models.py +++ b/valence/db/models.py @@ -11,6 +11,7 @@ # License for the specific language governing permissions and limitations # under the License. +import datetime import json import os @@ -80,7 +81,47 @@ class ModelBase(base.ObjectBase): client.delete(path) -class PodManager(ModelBase): +class ModelBaseWithTimeStamp(ModelBase): + + def __init__(self, *args, **kwargs): + """Inject 'created_at' and 'updated_at' fields""" + timestamp_fields = { + 'created_at': { + 'validate': types.Text.validate + }, + 'updated_at': { + 'validate': types.Text.validate + } + } + self.fields.update(timestamp_fields) + + super(ModelBaseWithTimeStamp, self).__init__(*args, **kwargs) + + def save(self, *args, **kwargs): + """Update all timestamp fields when save new object + + Set current utc time to 'created_at' and 'updated_at' fields when + save this key-value pair at the first time. + """ + utcnow = datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC") + self.created_at = utcnow + self.updated_at = utcnow + + super(ModelBaseWithTimeStamp, self).save(*args, **kwargs) + + def update(self, *args, **kwargs): + """Update 'updated_at' timestamp when udpate object + + Set current utc time to 'updated_at' field when update this + key-value pair. + """ + utcnow = datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC") + self.updated_at = utcnow + + super(ModelBaseWithTimeStamp, self).update(*args, **kwargs) + + +class PodManager(ModelBaseWithTimeStamp): path = "/pod_managers" @@ -111,11 +152,5 @@ class PodManager(ModelBase): }, 'bookmark_link': { 'validate': types.Text.validate - }, - 'created_at': { - 'validate': types.Text.validate - }, - 'updated_at': { - 'validate': types.Text.validate } } diff --git a/valence/tests/unit/db/test_db_api.py b/valence/tests/unit/db/test_db_api.py index fdcecad..6d0c27f 100644 --- a/valence/tests/unit/db/test_db_api.py +++ b/valence/tests/unit/db/test_db_api.py @@ -16,6 +16,7 @@ import mock import unittest import etcd +import freezegun from valence.db import api as db_api from valence.tests.unit.db import utils @@ -23,10 +24,14 @@ from valence.tests.unit.db import utils class TestDBAPI(unittest.TestCase): + @freezegun.freeze_time("2017-01-01") @mock.patch('etcd.Client.write') @mock.patch('etcd.Client.read') def test_create_podmanager(self, mock_etcd_read, mock_etcd_write): podmanager = utils.get_test_podmanager() + fake_utcnow = '2017-01-01 00:00:00 UTC' + podmanager['created_at'] = fake_utcnow + podmanager['updated_at'] = fake_utcnow # Mark this uuid don't exist in etcd db mock_etcd_read.side_effect = etcd.EtcdKeyNotFound @@ -76,6 +81,7 @@ class TestDBAPI(unittest.TestCase): mock_etcd_delete.assert_called_with( '/pod_managers/' + podmanager['uuid']) + @freezegun.freeze_time("2017-01-01") @mock.patch('etcd.Client.write') @mock.patch('etcd.Client.read') def test_update_podmanager(self, mock_etcd_read, mock_etcd_write): @@ -84,7 +90,10 @@ class TestDBAPI(unittest.TestCase): mock_etcd_read.return_value = utils.get_etcd_read_result( podmanager['uuid'], json.dumps(podmanager)) + fake_utcnow = '2017-01-01 00:00:00 UTC' + podmanager['updated_at'] = fake_utcnow podmanager.update({'url': 'new_url'}) + result = db_api.Connection.update_podmanager( podmanager['uuid'], {'url': 'new_url'}) diff --git a/valence/tests/unit/db/utils.py b/valence/tests/unit/db/utils.py index 770d50f..08c2cce 100644 --- a/valence/tests/unit/db/utils.py +++ b/valence/tests/unit/db/utils.py @@ -53,6 +53,6 @@ def get_test_podmanager(**kwargs): 'location': kwargs.get('location', 'fake_location'), 'redfish_link': kwargs.get('redfish_link', 'fake_redfish_link'), 'bookmark_link': kwargs.get('bookmark_link', 'fake_bookmark_link'), - 'created_at': kwargs.get('created_at', '2017-01-01 00:0:00'), - 'updated_at': kwargs.get('updated_at', '2017-01-01 00:0:00'), + 'created_at': kwargs.get('created_at', '2016-01-01 00:00:00 UTC'), + 'updated_at': kwargs.get('updated_at', '2016-01-01 00:00:00 UTC'), }