Skip to content
Snippets Groups Projects
Commit ab7dd9a2 authored by joe's avatar joe
Browse files

Timestamp feature and tests.

With a small change to preceding versions, now we use a "number" to store the timestamp data, as we need a little more fine-grain
and there is no reason to lose information at this stage.
parent c30cc8bc
No related branches found
No related tags found
No related merge requests found
......@@ -163,6 +163,18 @@ class GetAction(Action):
obj = conn.get(entity.name, args._name)
self.view.pprint(obj)
class TimestampAction(Action):
"""Get the timestamp of last update on an entity."""
name = 'timestamp'
def __init__(self, entity, parser):
pass
def run(self, conn, entity, args):
print conn.get_timestamp(entity.name)
class FindAction(Action):
"""Find instances."""
......@@ -211,9 +223,14 @@ class AuditAction(object):
name = 'audit'
descr = 'query audit logs'
view = JsonPlain
AUDIT_ATTRS = ('entity', 'object', 'user', 'op')
@classmethod
def set_view(cls, viewclass):
cls.view = viewclass
def __init__(self, parser):
for attr in self.AUDIT_ATTRS:
parser.add_argument('--' + attr)
......@@ -262,6 +279,7 @@ class Parser(object):
UpdateAction,
GetAction,
FindAction,
TimestampAction
)
toplevel_actions = (
......@@ -302,6 +320,8 @@ class Parser(object):
help='use with --help for additional help',
dest='_entity_name')
for entity in self.schema.get_entities():
if entity.name in self.schema.sys_schema_tables:
continue
subparser = subparsers.add_parser(entity.name,
help=entity.description)
self._init_subparser(entity, subparser)
......
......@@ -251,3 +251,16 @@ class Connection(object):
"""
return self._request(['audit'], query)
def get_timestamp(self, entity_name):
"""Fetch the timestamp of last update to a entity.
Args:
entity_name: string, entity name
Returns:
A String representing the unix epoch of last update
Raises:
None
"""
return self._call(entity_name, 'timestamp')
......@@ -118,7 +118,7 @@ class AdmDbApi(object):
#Avoid updating timestamp for tables that are not part of the schema.
return True
data = {'name': entity_name, 'ts': int(time()) }
data = {'name': entity_name, 'ts': time() }
ts = self.schema.get_entity('__timestamp')
data = self._unpack(ts, data)
......
......@@ -175,7 +175,7 @@ class Schema(object):
self.default_acl.set_acl(DEFAULT_ACL)
def _add_timestamp(self):
ts_schema = {'name': { 'type': 'string', 'size': 32}, 'ts': {'type': 'int', 'nullable': False } }
ts_schema = {'name': { 'type': 'string', 'size': 32}, 'ts': {'type': 'number', 'nullable': False } }
self.entities['__timestamp'] = Entity('__timestamp', ts_schema)
def _relation_check(self):
......
......@@ -158,6 +158,7 @@ def delete(class_name, object_name):
@api_app.route('/timestamp/<class_name>')
@authenticate
@json_response
def ts(class_name):
try:
res = g.api.get_timestamp(class_name, g.auth_ctx)
......
......@@ -347,3 +347,16 @@ class DbApiTestBase(object):
self.api.get_audit,
{'entity': 'private', 'op': 'create'},
auth_ctx)
def test_timestamp_is_updated(self):
result = self.api.update('host', 'obz', {'ip': '2.3.4.5'}, self.ctx)
self.assertTrue(result)
ts1 = self.api.get_timestamp('host', self.ctx).ts
self.assertTrue(ts1 != 0)
result = self.api.update('host', 'obz', {'ip': '3.3.3.5'}, self.ctx)
self.assertTrue(result)
ts2 = self.api.get_timestamp('host', self.ctx).ts
self.assertTrue(ts2 > ts1)
def test_timestamp_for_non_updated_entity(self):
self.assertRaises(ValueError, self.api.get_timestamp('role',self.ctx))
......@@ -8,7 +8,7 @@ class SchemaTest(TestBase):
def test_empty_schema_ok(self):
s = schema.Schema('{}')
self.assertEquals({}, s.entities)
self.assertEquals(s.sys_schema_tables, s.entities.keys())
def test_entity_without_name(self):
data = """
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment