From 705ec314a3df4659b6ac07a5b6eddc3028713d89 Mon Sep 17 00:00:00 2001 From: Steve Pulec Date: Fri, 27 Nov 2015 14:14:40 -0500 Subject: [PATCH] Cleanup different places using unix_time() --- moto/core/utils.py | 13 +++++++++++++ moto/dynamodb/models.py | 2 +- moto/dynamodb/utils.py | 6 ------ moto/dynamodb2/models.py | 12 ++++++------ moto/dynamodb2/utils.py | 6 ------ moto/sqs/models.py | 4 ++-- moto/sqs/utils.py | 12 ------------ moto/swf/models/activity_task.py | 11 +++++------ moto/swf/models/decision_task.py | 4 ++-- moto/swf/models/history_event.py | 13 ++++++------- moto/swf/models/timeout.py | 4 ++-- moto/swf/models/workflow_execution.py | 26 ++++++++++++-------------- moto/swf/utils.py | 6 ------ tests/test_core/test_utils.py | 11 +++++++++-- tests/test_swf/test_utils.py | 12 ++---------- 15 files changed, 60 insertions(+), 82 deletions(-) delete mode 100644 moto/dynamodb/utils.py delete mode 100644 moto/dynamodb2/utils.py diff --git a/moto/core/utils.py b/moto/core/utils.py index 81acdd6d..65f0f457 100644 --- a/moto/core/utils.py +++ b/moto/core/utils.py @@ -1,4 +1,6 @@ from __future__ import unicode_literals + +import datetime import inspect import random import re @@ -103,3 +105,14 @@ def iso_8601_datetime_with_milliseconds(datetime): def rfc_1123_datetime(datetime): RFC1123 = '%a, %d %b %Y %H:%M:%S GMT' 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 diff --git a/moto/dynamodb/models.py b/moto/dynamodb/models.py index 6039238e..db595c28 100644 --- a/moto/dynamodb/models.py +++ b/moto/dynamodb/models.py @@ -5,8 +5,8 @@ import json from moto.compat import OrderedDict from moto.core import BaseBackend +from moto.core.utils import unix_time from .comparisons import get_comparison_func -from .utils import unix_time class DynamoJsonEncoder(json.JSONEncoder): diff --git a/moto/dynamodb/utils.py b/moto/dynamodb/utils.py deleted file mode 100644 index 1adee245..00000000 --- a/moto/dynamodb/utils.py +++ /dev/null @@ -1,6 +0,0 @@ -from __future__ import unicode_literals -import calendar - - -def unix_time(dt): - return calendar.timegm(dt.timetuple()) diff --git a/moto/dynamodb2/models.py b/moto/dynamodb2/models.py index 612a0c3d..2b1a1b5e 100644 --- a/moto/dynamodb2/models.py +++ b/moto/dynamodb2/models.py @@ -5,8 +5,8 @@ import json from moto.compat import OrderedDict from moto.core import BaseBackend +from moto.core.utils import unix_time from .comparisons import get_comparison_func -from .utils import unix_time class DynamoJsonEncoder(json.JSONEncoder): @@ -82,7 +82,7 @@ class Item(object): attributes = {} for attribute_key, attribute in self.attrs.items(): attributes[attribute_key] = { - attribute.type : attribute.value + attribute.type: attribute.value } return { @@ -204,7 +204,7 @@ class Table(object): keys.append(key['AttributeName']) 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)) if self.has_range_key: range_value = DynamoType(item_attrs.get(self.range_key_attr)) @@ -228,13 +228,13 @@ class Table(object): if current is None: current_attr = {} - elif hasattr(current,'attrs'): + elif hasattr(current, 'attrs'): current_attr = current.attrs else: current_attr = current 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: raise ValueError("The conditional request failed") elif key not in current_attr: @@ -361,7 +361,7 @@ class DynamoDBBackend(BaseBackend): table.throughput = throughput 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) if not table: return None diff --git a/moto/dynamodb2/utils.py b/moto/dynamodb2/utils.py deleted file mode 100644 index 1adee245..00000000 --- a/moto/dynamodb2/utils.py +++ /dev/null @@ -1,6 +0,0 @@ -from __future__ import unicode_literals -import calendar - - -def unix_time(dt): - return calendar.timegm(dt.timetuple()) diff --git a/moto/sqs/models.py b/moto/sqs/models.py index efb75dd9..19268d51 100644 --- a/moto/sqs/models.py +++ b/moto/sqs/models.py @@ -8,8 +8,8 @@ from xml.sax.saxutils import escape import boto.sqs from moto.core import BaseBackend -from moto.core.utils import camelcase_to_underscores, get_random_message_id -from .utils import generate_receipt_handle, unix_time_millis +from moto.core.utils import camelcase_to_underscores, get_random_message_id, unix_time_millis +from .utils import generate_receipt_handle from .exceptions import ( ReceiptHandleIsInvalid, MessageNotInflight diff --git a/moto/sqs/utils.py b/moto/sqs/utils.py index 8dee7003..a00ec1c7 100644 --- a/moto/sqs/utils.py +++ b/moto/sqs/utils.py @@ -1,5 +1,4 @@ from __future__ import unicode_literals -import datetime import random import string @@ -12,17 +11,6 @@ def generate_receipt_handle(): 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.'): message_attributes = {} index = 1 diff --git a/moto/swf/models/activity_task.py b/moto/swf/models/activity_task.py index 1a72d344..eb361d25 100644 --- a/moto/swf/models/activity_task.py +++ b/moto/swf/models/activity_task.py @@ -2,8 +2,8 @@ from __future__ import unicode_literals from datetime import datetime import uuid +from moto.core.utils import unix_time from ..exceptions import SWFWorkflowExecutionClosedError -from ..utils import now_timestamp from .timeout import Timeout @@ -15,7 +15,7 @@ class ActivityTask(object): self.activity_type = activity_type self.details = None self.input = input - self.last_heartbeat_timestamp = now_timestamp() + self.last_heartbeat_timestamp = unix_time() self.scheduled_event_id = scheduled_event_id self.started_event_id = None self.state = "SCHEDULED" @@ -60,19 +60,18 @@ class ActivityTask(object): self.state = "FAILED" def reset_heartbeat_clock(self): - self.last_heartbeat_timestamp = now_timestamp() + self.last_heartbeat_timestamp = unix_time() def first_timeout(self): if not self.open or not self.workflow_execution.open: return None # TODO: handle the "NONE" case - heartbeat_timeout_at = self.last_heartbeat_timestamp + \ - int(self.timeouts["heartbeatTimeout"]) + heartbeat_timeout_at = (self.last_heartbeat_timestamp + + int(self.timeouts["heartbeatTimeout"])) _timeout = Timeout(self, heartbeat_timeout_at, "HEARTBEAT") if _timeout.reached: return _timeout - def process_timeouts(self): _timeout = self.first_timeout() if _timeout: diff --git a/moto/swf/models/decision_task.py b/moto/swf/models/decision_task.py index b7688840..bcd28f37 100644 --- a/moto/swf/models/decision_task.py +++ b/moto/swf/models/decision_task.py @@ -2,8 +2,8 @@ from __future__ import unicode_literals from datetime import datetime import uuid +from moto.core.utils import unix_time from ..exceptions import SWFWorkflowExecutionClosedError -from ..utils import now_timestamp from .timeout import Timeout @@ -49,7 +49,7 @@ class DecisionTask(object): def start(self, started_event_id): self.state = "STARTED" - self.started_timestamp = now_timestamp() + self.started_timestamp = unix_time() self.started_event_id = started_event_id def complete(self): diff --git a/moto/swf/models/history_event.py b/moto/swf/models/history_event.py index c602abee..b181297f 100644 --- a/moto/swf/models/history_event.py +++ b/moto/swf/models/history_event.py @@ -1,10 +1,8 @@ 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 @@ -28,6 +26,7 @@ SUPPORTED_HISTORY_EVENT_TYPES = ( "WorkflowExecutionTimedOut", ) + class HistoryEvent(object): def __init__(self, event_id, event_type, event_timestamp=None, **kwargs): if event_type not in SUPPORTED_HISTORY_EVENT_TYPES: @@ -39,16 +38,16 @@ class HistoryEvent(object): if event_timestamp: self.event_timestamp = event_timestamp else: - self.event_timestamp = now_timestamp() + self.event_timestamp = unix_time() # pre-populate a dict: {"camelCaseKey": value} self.event_attributes = {} for key, value in kwargs.items(): if value: camel_key = underscores_to_camelcase(key) if key == "task_list": - value = { "name": value } + value = {"name": value} elif key == "workflow_type": - value = { "name": value.name, "version": value.version } + value = {"name": value.name, "version": value.version} elif key == "activity_type": value = value.to_short_dict() self.event_attributes[camel_key] = value diff --git a/moto/swf/models/timeout.py b/moto/swf/models/timeout.py index 66cb3b84..cf028376 100644 --- a/moto/swf/models/timeout.py +++ b/moto/swf/models/timeout.py @@ -1,4 +1,4 @@ -from ..utils import now_timestamp +from moto.core.utils import unix_time class Timeout(object): @@ -9,4 +9,4 @@ class Timeout(object): @property def reached(self): - return now_timestamp() >= self.timestamp + return unix_time() >= self.timestamp diff --git a/moto/swf/models/workflow_execution.py b/moto/swf/models/workflow_execution.py index aa08d8e9..b241debc 100644 --- a/moto/swf/models/workflow_execution.py +++ b/moto/swf/models/workflow_execution.py @@ -1,9 +1,7 @@ from __future__ import unicode_literals -from datetime import datetime -from time import mktime import uuid -from moto.core.utils import camelcase_to_underscores +from moto.core.utils import camelcase_to_underscores, unix_time from ..constants import ( DECISIONS_FIELDS, @@ -13,7 +11,7 @@ from ..exceptions import ( SWFValidationException, SWFDecisionValidationException, ) -from ..utils import decapitalize, now_timestamp +from ..utils import decapitalize from .activity_task import ActivityTask from .activity_type import ActivityType from .decision_task import DecisionTask @@ -59,7 +57,7 @@ class WorkflowExecution(object): self.latest_execution_context = None self.parent = None self.start_timestamp = None - self.tag_list = [] # TODO + self.tag_list = [] # TODO self.timeout_type = None self.workflow_type = workflow_type # args processing @@ -89,7 +87,7 @@ class WorkflowExecution(object): def _set_from_kwargs_or_workflow_type(self, kwargs, local_key, workflow_type_key=None): if workflow_type_key is None: - workflow_type_key = "default_"+local_key + workflow_type_key = "default_" + local_key value = kwargs.get(local_key) if not value and hasattr(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} } } - #configuration + # configuration for key in self._configuration_keys: attr = camelcase_to_underscores(key) if not hasattr(self, attr): @@ -139,9 +137,9 @@ class WorkflowExecution(object): if not getattr(self, attr): continue hsh["executionConfiguration"][key] = getattr(self, attr) - #counters + # counters hsh["openCounts"] = self.open_counts - #latest things + # latest things if self.latest_execution_context: hsh["latestExecutionContext"] = self.latest_execution_context if self.latest_activity_task_timestamp: @@ -225,7 +223,7 @@ class WorkflowExecution(object): return evt def start(self): - self.start_timestamp = now_timestamp() + self.start_timestamp = unix_time() self._add_event( "WorkflowExecutionStarted", child_policy=self.child_policy, @@ -403,7 +401,7 @@ class WorkflowExecution(object): def complete(self, event_id, result=None): self.execution_status = "CLOSED" self.close_status = "COMPLETED" - self.close_timestamp = now_timestamp() + self.close_timestamp = unix_time() self._add_event( "WorkflowExecutionCompleted", decision_task_completed_event_id=event_id, @@ -414,7 +412,7 @@ class WorkflowExecution(object): # TODO: implement lenght constraints on details/reason self.execution_status = "CLOSED" self.close_status = "FAILED" - self.close_timestamp = now_timestamp() + self.close_timestamp = unix_time() self._add_event( "WorkflowExecutionFailed", decision_task_completed_event_id=event_id, @@ -470,7 +468,7 @@ class WorkflowExecution(object): # find timeouts or default timeout, else fail timeouts = {} 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) timeouts[_type] = attributes.get(_type, default_value) if not timeouts[_type]: @@ -504,7 +502,7 @@ class WorkflowExecution(object): ) self.domain.add_to_activity_task_list(task_list, task) 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): for task in self.activity_tasks: diff --git a/moto/swf/utils.py b/moto/swf/utils.py index a9c54ee3..de628ce5 100644 --- a/moto/swf/utils.py +++ b/moto/swf/utils.py @@ -1,9 +1,3 @@ -from datetime import datetime -from time import mktime - def decapitalize(key): return key[0].lower() + key[1:] - -def now_timestamp(): - return float(mktime(datetime.utcnow().timetuple())) diff --git a/tests/test_core/test_utils.py b/tests/test_core/test_utils.py index 6e27e6f4..76f0645a 100644 --- a/tests/test_core/test_utils.py +++ b/tests/test_core/test_utils.py @@ -1,7 +1,9 @@ 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(): @@ -20,3 +22,8 @@ def test_underscores_to_camelcase(): } for arg, expected in cases.items(): 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) diff --git a/tests/test_swf/test_utils.py b/tests/test_swf/test_utils.py index f8ff08f2..ffa14703 100644 --- a/tests/test_swf/test_utils.py +++ b/tests/test_swf/test_utils.py @@ -1,10 +1,6 @@ -from freezegun import freeze_time -from sure import expect +import sure # noqa -from moto.swf.utils import ( - decapitalize, - now_timestamp, -) +from moto.swf.utils import decapitalize def test_decapitalize(): @@ -15,7 +11,3 @@ def test_decapitalize(): } for before, after in cases.items(): decapitalize(before).should.equal(after) - -@freeze_time("2015-01-01 12:00:00") -def test_now_timestamp(): - now_timestamp().should.equal(1420113600.0)