Cleanup different places using unix_time()

This commit is contained in:
Steve Pulec 2015-11-27 14:14:40 -05:00
parent eabcb3d39c
commit 705ec314a3
15 changed files with 60 additions and 82 deletions

View File

@ -1,4 +1,6 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime
import inspect import inspect
import random import random
import re import re
@ -103,3 +105,14 @@ def iso_8601_datetime_with_milliseconds(datetime):
def rfc_1123_datetime(datetime): def rfc_1123_datetime(datetime):
RFC1123 = '%a, %d %b %Y %H:%M:%S GMT' RFC1123 = '%a, %d %b %Y %H:%M:%S GMT'
return datetime.strftime(RFC1123) return datetime.strftime(RFC1123)
def unix_time(dt=None):
dt = dt or datetime.datetime.utcnow()
epoch = datetime.datetime.utcfromtimestamp(0)
delta = dt - epoch
return (delta.days * 86400) + (delta.seconds + (delta.microseconds / 1e6))
def unix_time_millis(dt=None):
return unix_time(dt) * 1000.0

View File

@ -5,8 +5,8 @@ import json
from moto.compat import OrderedDict from moto.compat import OrderedDict
from moto.core import BaseBackend from moto.core import BaseBackend
from moto.core.utils import unix_time
from .comparisons import get_comparison_func from .comparisons import get_comparison_func
from .utils import unix_time
class DynamoJsonEncoder(json.JSONEncoder): class DynamoJsonEncoder(json.JSONEncoder):

View File

@ -1,6 +0,0 @@
from __future__ import unicode_literals
import calendar
def unix_time(dt):
return calendar.timegm(dt.timetuple())

View File

@ -5,8 +5,8 @@ import json
from moto.compat import OrderedDict from moto.compat import OrderedDict
from moto.core import BaseBackend from moto.core import BaseBackend
from moto.core.utils import unix_time
from .comparisons import get_comparison_func from .comparisons import get_comparison_func
from .utils import unix_time
class DynamoJsonEncoder(json.JSONEncoder): class DynamoJsonEncoder(json.JSONEncoder):
@ -82,7 +82,7 @@ class Item(object):
attributes = {} attributes = {}
for attribute_key, attribute in self.attrs.items(): for attribute_key, attribute in self.attrs.items():
attributes[attribute_key] = { attributes[attribute_key] = {
attribute.type : attribute.value attribute.type: attribute.value
} }
return { return {
@ -204,7 +204,7 @@ class Table(object):
keys.append(key['AttributeName']) keys.append(key['AttributeName'])
return keys return keys
def put_item(self, item_attrs, expected = None, overwrite = False): def put_item(self, item_attrs, expected=None, overwrite=False):
hash_value = DynamoType(item_attrs.get(self.hash_key_attr)) hash_value = DynamoType(item_attrs.get(self.hash_key_attr))
if self.has_range_key: if self.has_range_key:
range_value = DynamoType(item_attrs.get(self.range_key_attr)) range_value = DynamoType(item_attrs.get(self.range_key_attr))
@ -228,13 +228,13 @@ class Table(object):
if current is None: if current is None:
current_attr = {} current_attr = {}
elif hasattr(current,'attrs'): elif hasattr(current, 'attrs'):
current_attr = current.attrs current_attr = current.attrs
else: else:
current_attr = current current_attr = current
for key, val in expected.items(): for key, val in expected.items():
if 'Exists' in val and val['Exists'] == False: if 'Exists' in val and val['Exists'] is False:
if key in current_attr: if key in current_attr:
raise ValueError("The conditional request failed") raise ValueError("The conditional request failed")
elif key not in current_attr: elif key not in current_attr:
@ -361,7 +361,7 @@ class DynamoDBBackend(BaseBackend):
table.throughput = throughput table.throughput = throughput
return table return table
def put_item(self, table_name, item_attrs, expected = None, overwrite = False): def put_item(self, table_name, item_attrs, expected=None, overwrite=False):
table = self.tables.get(table_name) table = self.tables.get(table_name)
if not table: if not table:
return None return None

View File

@ -1,6 +0,0 @@
from __future__ import unicode_literals
import calendar
def unix_time(dt):
return calendar.timegm(dt.timetuple())

View File

@ -8,8 +8,8 @@ from xml.sax.saxutils import escape
import boto.sqs import boto.sqs
from moto.core import BaseBackend from moto.core import BaseBackend
from moto.core.utils import camelcase_to_underscores, get_random_message_id from moto.core.utils import camelcase_to_underscores, get_random_message_id, unix_time_millis
from .utils import generate_receipt_handle, unix_time_millis from .utils import generate_receipt_handle
from .exceptions import ( from .exceptions import (
ReceiptHandleIsInvalid, ReceiptHandleIsInvalid,
MessageNotInflight MessageNotInflight

View File

@ -1,5 +1,4 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime
import random import random
import string import string
@ -12,17 +11,6 @@ def generate_receipt_handle():
return ''.join(random.choice(string.ascii_lowercase) for x in range(length)) return ''.join(random.choice(string.ascii_lowercase) for x in range(length))
def unix_time(dt=None):
dt = dt or datetime.datetime.utcnow()
epoch = datetime.datetime.utcfromtimestamp(0)
delta = dt - epoch
return (delta.days * 86400) + (delta.seconds + (delta.microseconds / 1e6))
def unix_time_millis(dt=None):
return unix_time(dt) * 1000.0
def parse_message_attributes(querystring, base='', value_namespace='Value.'): def parse_message_attributes(querystring, base='', value_namespace='Value.'):
message_attributes = {} message_attributes = {}
index = 1 index = 1

View File

@ -2,8 +2,8 @@ from __future__ import unicode_literals
from datetime import datetime from datetime import datetime
import uuid import uuid
from moto.core.utils import unix_time
from ..exceptions import SWFWorkflowExecutionClosedError from ..exceptions import SWFWorkflowExecutionClosedError
from ..utils import now_timestamp
from .timeout import Timeout from .timeout import Timeout
@ -15,7 +15,7 @@ class ActivityTask(object):
self.activity_type = activity_type self.activity_type = activity_type
self.details = None self.details = None
self.input = input self.input = input
self.last_heartbeat_timestamp = now_timestamp() self.last_heartbeat_timestamp = unix_time()
self.scheduled_event_id = scheduled_event_id self.scheduled_event_id = scheduled_event_id
self.started_event_id = None self.started_event_id = None
self.state = "SCHEDULED" self.state = "SCHEDULED"
@ -60,19 +60,18 @@ class ActivityTask(object):
self.state = "FAILED" self.state = "FAILED"
def reset_heartbeat_clock(self): def reset_heartbeat_clock(self):
self.last_heartbeat_timestamp = now_timestamp() self.last_heartbeat_timestamp = unix_time()
def first_timeout(self): def first_timeout(self):
if not self.open or not self.workflow_execution.open: if not self.open or not self.workflow_execution.open:
return None return None
# TODO: handle the "NONE" case # TODO: handle the "NONE" case
heartbeat_timeout_at = self.last_heartbeat_timestamp + \ heartbeat_timeout_at = (self.last_heartbeat_timestamp +
int(self.timeouts["heartbeatTimeout"]) int(self.timeouts["heartbeatTimeout"]))
_timeout = Timeout(self, heartbeat_timeout_at, "HEARTBEAT") _timeout = Timeout(self, heartbeat_timeout_at, "HEARTBEAT")
if _timeout.reached: if _timeout.reached:
return _timeout return _timeout
def process_timeouts(self): def process_timeouts(self):
_timeout = self.first_timeout() _timeout = self.first_timeout()
if _timeout: if _timeout:

View File

@ -2,8 +2,8 @@ from __future__ import unicode_literals
from datetime import datetime from datetime import datetime
import uuid import uuid
from moto.core.utils import unix_time
from ..exceptions import SWFWorkflowExecutionClosedError from ..exceptions import SWFWorkflowExecutionClosedError
from ..utils import now_timestamp
from .timeout import Timeout from .timeout import Timeout
@ -49,7 +49,7 @@ class DecisionTask(object):
def start(self, started_event_id): def start(self, started_event_id):
self.state = "STARTED" self.state = "STARTED"
self.started_timestamp = now_timestamp() self.started_timestamp = unix_time()
self.started_event_id = started_event_id self.started_event_id = started_event_id
def complete(self): def complete(self):

View File

@ -1,10 +1,8 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from datetime import datetime
from time import mktime
from moto.core.utils import underscores_to_camelcase from moto.core.utils import underscores_to_camelcase, unix_time
from ..utils import decapitalize, now_timestamp from ..utils import decapitalize
# We keep track of which history event types we support # We keep track of which history event types we support
@ -28,6 +26,7 @@ SUPPORTED_HISTORY_EVENT_TYPES = (
"WorkflowExecutionTimedOut", "WorkflowExecutionTimedOut",
) )
class HistoryEvent(object): class HistoryEvent(object):
def __init__(self, event_id, event_type, event_timestamp=None, **kwargs): def __init__(self, event_id, event_type, event_timestamp=None, **kwargs):
if event_type not in SUPPORTED_HISTORY_EVENT_TYPES: if event_type not in SUPPORTED_HISTORY_EVENT_TYPES:
@ -39,16 +38,16 @@ class HistoryEvent(object):
if event_timestamp: if event_timestamp:
self.event_timestamp = event_timestamp self.event_timestamp = event_timestamp
else: else:
self.event_timestamp = now_timestamp() self.event_timestamp = unix_time()
# pre-populate a dict: {"camelCaseKey": value} # pre-populate a dict: {"camelCaseKey": value}
self.event_attributes = {} self.event_attributes = {}
for key, value in kwargs.items(): for key, value in kwargs.items():
if value: if value:
camel_key = underscores_to_camelcase(key) camel_key = underscores_to_camelcase(key)
if key == "task_list": if key == "task_list":
value = { "name": value } value = {"name": value}
elif key == "workflow_type": elif key == "workflow_type":
value = { "name": value.name, "version": value.version } value = {"name": value.name, "version": value.version}
elif key == "activity_type": elif key == "activity_type":
value = value.to_short_dict() value = value.to_short_dict()
self.event_attributes[camel_key] = value self.event_attributes[camel_key] = value

View File

@ -1,4 +1,4 @@
from ..utils import now_timestamp from moto.core.utils import unix_time
class Timeout(object): class Timeout(object):
@ -9,4 +9,4 @@ class Timeout(object):
@property @property
def reached(self): def reached(self):
return now_timestamp() >= self.timestamp return unix_time() >= self.timestamp

View File

@ -1,9 +1,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from datetime import datetime
from time import mktime
import uuid import uuid
from moto.core.utils import camelcase_to_underscores from moto.core.utils import camelcase_to_underscores, unix_time
from ..constants import ( from ..constants import (
DECISIONS_FIELDS, DECISIONS_FIELDS,
@ -13,7 +11,7 @@ from ..exceptions import (
SWFValidationException, SWFValidationException,
SWFDecisionValidationException, SWFDecisionValidationException,
) )
from ..utils import decapitalize, now_timestamp from ..utils import decapitalize
from .activity_task import ActivityTask from .activity_task import ActivityTask
from .activity_type import ActivityType from .activity_type import ActivityType
from .decision_task import DecisionTask from .decision_task import DecisionTask
@ -59,7 +57,7 @@ class WorkflowExecution(object):
self.latest_execution_context = None self.latest_execution_context = None
self.parent = None self.parent = None
self.start_timestamp = None self.start_timestamp = None
self.tag_list = [] # TODO self.tag_list = [] # TODO
self.timeout_type = None self.timeout_type = None
self.workflow_type = workflow_type self.workflow_type = workflow_type
# args processing # args processing
@ -89,7 +87,7 @@ class WorkflowExecution(object):
def _set_from_kwargs_or_workflow_type(self, kwargs, local_key, workflow_type_key=None): def _set_from_kwargs_or_workflow_type(self, kwargs, local_key, workflow_type_key=None):
if workflow_type_key is None: if workflow_type_key is None:
workflow_type_key = "default_"+local_key workflow_type_key = "default_" + local_key
value = kwargs.get(local_key) value = kwargs.get(local_key)
if not value and hasattr(self.workflow_type, workflow_type_key): if not value and hasattr(self.workflow_type, workflow_type_key):
value = getattr(self.workflow_type, workflow_type_key) value = getattr(self.workflow_type, workflow_type_key)
@ -131,7 +129,7 @@ class WorkflowExecution(object):
"taskList": {"name": self.task_list} "taskList": {"name": self.task_list}
} }
} }
#configuration # configuration
for key in self._configuration_keys: for key in self._configuration_keys:
attr = camelcase_to_underscores(key) attr = camelcase_to_underscores(key)
if not hasattr(self, attr): if not hasattr(self, attr):
@ -139,9 +137,9 @@ class WorkflowExecution(object):
if not getattr(self, attr): if not getattr(self, attr):
continue continue
hsh["executionConfiguration"][key] = getattr(self, attr) hsh["executionConfiguration"][key] = getattr(self, attr)
#counters # counters
hsh["openCounts"] = self.open_counts hsh["openCounts"] = self.open_counts
#latest things # latest things
if self.latest_execution_context: if self.latest_execution_context:
hsh["latestExecutionContext"] = self.latest_execution_context hsh["latestExecutionContext"] = self.latest_execution_context
if self.latest_activity_task_timestamp: if self.latest_activity_task_timestamp:
@ -225,7 +223,7 @@ class WorkflowExecution(object):
return evt return evt
def start(self): def start(self):
self.start_timestamp = now_timestamp() self.start_timestamp = unix_time()
self._add_event( self._add_event(
"WorkflowExecutionStarted", "WorkflowExecutionStarted",
child_policy=self.child_policy, child_policy=self.child_policy,
@ -403,7 +401,7 @@ class WorkflowExecution(object):
def complete(self, event_id, result=None): def complete(self, event_id, result=None):
self.execution_status = "CLOSED" self.execution_status = "CLOSED"
self.close_status = "COMPLETED" self.close_status = "COMPLETED"
self.close_timestamp = now_timestamp() self.close_timestamp = unix_time()
self._add_event( self._add_event(
"WorkflowExecutionCompleted", "WorkflowExecutionCompleted",
decision_task_completed_event_id=event_id, decision_task_completed_event_id=event_id,
@ -414,7 +412,7 @@ class WorkflowExecution(object):
# TODO: implement lenght constraints on details/reason # TODO: implement lenght constraints on details/reason
self.execution_status = "CLOSED" self.execution_status = "CLOSED"
self.close_status = "FAILED" self.close_status = "FAILED"
self.close_timestamp = now_timestamp() self.close_timestamp = unix_time()
self._add_event( self._add_event(
"WorkflowExecutionFailed", "WorkflowExecutionFailed",
decision_task_completed_event_id=event_id, decision_task_completed_event_id=event_id,
@ -470,7 +468,7 @@ class WorkflowExecution(object):
# find timeouts or default timeout, else fail # find timeouts or default timeout, else fail
timeouts = {} timeouts = {}
for _type in ["scheduleToStartTimeout", "scheduleToCloseTimeout", "startToCloseTimeout", "heartbeatTimeout"]: for _type in ["scheduleToStartTimeout", "scheduleToCloseTimeout", "startToCloseTimeout", "heartbeatTimeout"]:
default_key = "default_task_"+camelcase_to_underscores(_type) default_key = "default_task_" + camelcase_to_underscores(_type)
default_value = getattr(activity_type, default_key) default_value = getattr(activity_type, default_key)
timeouts[_type] = attributes.get(_type, default_value) timeouts[_type] = attributes.get(_type, default_value)
if not timeouts[_type]: if not timeouts[_type]:
@ -504,7 +502,7 @@ class WorkflowExecution(object):
) )
self.domain.add_to_activity_task_list(task_list, task) self.domain.add_to_activity_task_list(task_list, task)
self.open_counts["openActivityTasks"] += 1 self.open_counts["openActivityTasks"] += 1
self.latest_activity_task_timestamp = now_timestamp() self.latest_activity_task_timestamp = unix_time()
def _find_activity_task(self, task_token): def _find_activity_task(self, task_token):
for task in self.activity_tasks: for task in self.activity_tasks:

View File

@ -1,9 +1,3 @@
from datetime import datetime
from time import mktime
def decapitalize(key): def decapitalize(key):
return key[0].lower() + key[1:] return key[0].lower() + key[1:]
def now_timestamp():
return float(mktime(datetime.utcnow().timetuple()))

View File

@ -1,7 +1,9 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import sure
from moto.core.utils import camelcase_to_underscores, underscores_to_camelcase import sure # noqa
from freezegun import freeze_time
from moto.core.utils import camelcase_to_underscores, underscores_to_camelcase, unix_time
def test_camelcase_to_underscores(): def test_camelcase_to_underscores():
@ -20,3 +22,8 @@ def test_underscores_to_camelcase():
} }
for arg, expected in cases.items(): for arg, expected in cases.items():
underscores_to_camelcase(arg).should.equal(expected) underscores_to_camelcase(arg).should.equal(expected)
@freeze_time("2015-01-01 12:00:00")
def test_unix_time():
unix_time().should.equal(1420113600.0)

View File

@ -1,10 +1,6 @@
from freezegun import freeze_time import sure # noqa
from sure import expect
from moto.swf.utils import ( from moto.swf.utils import decapitalize
decapitalize,
now_timestamp,
)
def test_decapitalize(): def test_decapitalize():
@ -15,7 +11,3 @@ def test_decapitalize():
} }
for before, after in cases.items(): for before, after in cases.items():
decapitalize(before).should.equal(after) decapitalize(before).should.equal(after)
@freeze_time("2015-01-01 12:00:00")
def test_now_timestamp():
now_timestamp().should.equal(1420113600.0)