2013-02-18 21:09:40 +00:00
|
|
|
import functools
|
|
|
|
import re
|
|
|
|
|
2013-05-03 23:33:13 +00:00
|
|
|
from httpretty import HTTPretty
|
2013-03-10 20:55:34 +00:00
|
|
|
from .responses import metadata_response
|
2013-03-05 13:14:43 +00:00
|
|
|
from .utils import convert_regex_to_flask_path
|
2013-02-18 21:09:40 +00:00
|
|
|
|
|
|
|
|
2013-02-28 03:25:15 +00:00
|
|
|
class MockAWS(object):
|
|
|
|
def __init__(self, backend):
|
|
|
|
self.backend = backend
|
|
|
|
|
|
|
|
def __call__(self, func):
|
|
|
|
return self.decorate_callable(func)
|
|
|
|
|
|
|
|
def __enter__(self):
|
|
|
|
self.start()
|
|
|
|
|
|
|
|
def __exit__(self, *args):
|
|
|
|
self.stop()
|
|
|
|
|
|
|
|
def start(self):
|
|
|
|
self.backend.reset()
|
|
|
|
HTTPretty.enable()
|
|
|
|
|
|
|
|
for method in HTTPretty.METHODS:
|
|
|
|
for key, value in self.backend.urls.iteritems():
|
|
|
|
HTTPretty.register_uri(
|
|
|
|
method=method,
|
|
|
|
uri=re.compile(key),
|
|
|
|
body=value,
|
|
|
|
)
|
|
|
|
|
2013-03-10 20:55:34 +00:00
|
|
|
# Mock out localhost instance metadata
|
|
|
|
HTTPretty.register_uri(
|
|
|
|
method=method,
|
|
|
|
uri=re.compile('http://169.254.169.254/latest/meta-data/.*'),
|
|
|
|
body=metadata_response
|
|
|
|
)
|
|
|
|
|
2013-02-28 03:25:15 +00:00
|
|
|
def stop(self):
|
|
|
|
HTTPretty.disable()
|
|
|
|
|
|
|
|
def decorate_callable(self, func):
|
|
|
|
def wrapper(*args, **kwargs):
|
|
|
|
with self:
|
|
|
|
result = func(*args, **kwargs)
|
|
|
|
return result
|
|
|
|
functools.update_wrapper(wrapper, func)
|
|
|
|
return wrapper
|
|
|
|
|
|
|
|
|
2013-02-18 21:09:40 +00:00
|
|
|
class BaseBackend(object):
|
|
|
|
|
|
|
|
def reset(self):
|
2013-02-26 04:48:17 +00:00
|
|
|
self.__dict__ = {}
|
2013-02-20 03:27:36 +00:00
|
|
|
self.__init__()
|
2013-02-18 21:09:40 +00:00
|
|
|
|
|
|
|
@property
|
2013-03-05 13:14:43 +00:00
|
|
|
def _url_module(self):
|
2013-02-18 21:09:40 +00:00
|
|
|
backend_module = self.__class__.__module__
|
|
|
|
backend_urls_module_name = backend_module.replace("models", "urls")
|
2013-03-05 13:14:43 +00:00
|
|
|
backend_urls_module = __import__(backend_urls_module_name, fromlist=['url_bases', 'url_paths'])
|
|
|
|
return backend_urls_module
|
|
|
|
|
|
|
|
@property
|
|
|
|
def urls(self):
|
|
|
|
"""
|
|
|
|
A dictionary of the urls to be mocked with this service and the handlers
|
|
|
|
that should be called in their place
|
|
|
|
"""
|
|
|
|
url_bases = self._url_module.url_bases
|
|
|
|
unformatted_paths = self._url_module.url_paths
|
|
|
|
|
|
|
|
urls = {}
|
|
|
|
for url_base in url_bases:
|
|
|
|
for url_path, handler in unformatted_paths.iteritems():
|
|
|
|
url = url_path.format(url_base)
|
|
|
|
urls[url] = handler
|
|
|
|
|
2013-02-18 21:09:40 +00:00
|
|
|
return urls
|
|
|
|
|
2013-03-05 13:14:43 +00:00
|
|
|
@property
|
|
|
|
def url_paths(self):
|
|
|
|
"""
|
|
|
|
A dictionary of the paths of the urls to be mocked with this service and
|
|
|
|
the handlers that should be called in their place
|
|
|
|
"""
|
|
|
|
unformatted_paths = self._url_module.url_paths
|
|
|
|
|
|
|
|
paths = {}
|
|
|
|
for unformatted_path, handler in unformatted_paths.iteritems():
|
|
|
|
path = unformatted_path.format("")
|
|
|
|
paths[path] = handler
|
|
|
|
|
|
|
|
return paths
|
|
|
|
|
|
|
|
@property
|
|
|
|
def flask_paths(self):
|
|
|
|
"""
|
|
|
|
The url paths that will be used for the flask server
|
|
|
|
"""
|
|
|
|
paths = {}
|
|
|
|
for url_path, handler in self.url_paths.iteritems():
|
|
|
|
url_path = convert_regex_to_flask_path(url_path)
|
|
|
|
paths[url_path] = handler
|
|
|
|
|
|
|
|
return paths
|
|
|
|
|
2013-02-28 03:25:15 +00:00
|
|
|
def decorator(self, func=None):
|
|
|
|
if func:
|
|
|
|
return MockAWS(self)(func)
|
|
|
|
else:
|
|
|
|
return MockAWS(self)
|