Testing new version of decorator.
This commit is contained in:
parent
d3df810065
commit
fde721bed7
123 changed files with 2740 additions and 1114 deletions
|
|
@ -1,22 +1,23 @@
|
|||
from __future__ import unicode_literals
|
||||
from __future__ import absolute_import
|
||||
|
||||
import functools
|
||||
import inspect
|
||||
import re
|
||||
|
||||
from httpretty import HTTPretty
|
||||
from moto.packages.responses import responses
|
||||
from moto.packages.httpretty import HTTPretty
|
||||
from .responses import metadata_response
|
||||
from .utils import convert_regex_to_flask_path
|
||||
from .utils import convert_regex_to_flask_path, convert_flask_to_responses_response
|
||||
|
||||
|
||||
class MockAWS(object):
|
||||
class BaseMockAWS(object):
|
||||
nested_count = 0
|
||||
|
||||
def __init__(self, backends):
|
||||
self.backends = backends
|
||||
|
||||
if self.__class__.nested_count == 0:
|
||||
HTTPretty.reset()
|
||||
self.reset()
|
||||
|
||||
def __call__(self, func, reset=True):
|
||||
if inspect.isclass(func):
|
||||
|
|
@ -35,24 +36,7 @@ class MockAWS(object):
|
|||
for backend in self.backends.values():
|
||||
backend.reset()
|
||||
|
||||
if not HTTPretty.is_enabled():
|
||||
HTTPretty.enable()
|
||||
|
||||
for method in HTTPretty.METHODS:
|
||||
backend = list(self.backends.values())[0]
|
||||
for key, value in backend.urls.items():
|
||||
HTTPretty.register_uri(
|
||||
method=method,
|
||||
uri=re.compile(key),
|
||||
body=value,
|
||||
)
|
||||
|
||||
# Mock out localhost instance metadata
|
||||
HTTPretty.register_uri(
|
||||
method=method,
|
||||
uri=re.compile('http://169.254.169.254/latest/meta-data/.*'),
|
||||
body=metadata_response
|
||||
)
|
||||
self.enable_patching()
|
||||
|
||||
def stop(self):
|
||||
self.__class__.nested_count -= 1
|
||||
|
|
@ -60,9 +44,7 @@ class MockAWS(object):
|
|||
if self.__class__.nested_count < 0:
|
||||
raise RuntimeError('Called stop() before start().')
|
||||
|
||||
if self.__class__.nested_count == 0:
|
||||
HTTPretty.disable()
|
||||
HTTPretty.reset()
|
||||
self.disable_patching()
|
||||
|
||||
def decorate_callable(self, func, reset):
|
||||
def wrapper(*args, **kwargs):
|
||||
|
|
@ -97,6 +79,73 @@ class MockAWS(object):
|
|||
return klass
|
||||
|
||||
|
||||
class HttprettyMockAWS(BaseMockAWS):
|
||||
def reset(self):
|
||||
HTTPretty.reset()
|
||||
|
||||
def enable_patching(self):
|
||||
if not HTTPretty.is_enabled():
|
||||
HTTPretty.enable()
|
||||
|
||||
for method in HTTPretty.METHODS:
|
||||
backend = list(self.backends.values())[0]
|
||||
for key, value in backend.urls.items():
|
||||
HTTPretty.register_uri(
|
||||
method=method,
|
||||
uri=re.compile(key),
|
||||
body=value,
|
||||
)
|
||||
|
||||
# Mock out localhost instance metadata
|
||||
HTTPretty.register_uri(
|
||||
method=method,
|
||||
uri=re.compile('http://169.254.169.254/latest/meta-data/.*'),
|
||||
body=metadata_response
|
||||
)
|
||||
|
||||
def disable_patching(self):
|
||||
if self.__class__.nested_count == 0:
|
||||
HTTPretty.disable()
|
||||
HTTPretty.reset()
|
||||
|
||||
|
||||
RESPONSES_METHODS = [responses.GET, responses.DELETE, responses.HEAD,
|
||||
responses.OPTIONS, responses.PATCH, responses.POST, responses.PUT]
|
||||
|
||||
|
||||
class ResponsesMockAWS(BaseMockAWS):
|
||||
def reset(self):
|
||||
responses.reset()
|
||||
|
||||
def enable_patching(self):
|
||||
responses.start()
|
||||
for method in RESPONSES_METHODS:
|
||||
backend = list(self.backends.values())[0]
|
||||
for key, value in backend.urls.items():
|
||||
responses.add_callback(
|
||||
method=method,
|
||||
url=re.compile(key),
|
||||
callback=convert_flask_to_responses_response(value),
|
||||
)
|
||||
|
||||
# Mock out localhost instance metadata
|
||||
responses.add_callback(
|
||||
method=method,
|
||||
url=re.compile('http://169.254.169.254/latest/meta-data/.*'),
|
||||
callback=convert_flask_to_responses_response(metadata_response),
|
||||
)
|
||||
for pattern in responses.mock._urls:
|
||||
pattern['stream'] = True
|
||||
|
||||
def disable_patching(self):
|
||||
if self.__class__.nested_count == 0:
|
||||
try:
|
||||
responses.stop()
|
||||
except AttributeError:
|
||||
pass
|
||||
responses.reset()
|
||||
MockAWS = ResponsesMockAWS
|
||||
|
||||
class Model(type):
|
||||
def __new__(self, clsname, bases, namespace):
|
||||
cls = super(Model, self).__new__(self, clsname, bases, namespace)
|
||||
|
|
@ -187,6 +236,12 @@ class BaseBackend(object):
|
|||
else:
|
||||
return MockAWS({'global': self})
|
||||
|
||||
def deprecated_decorator(self, func=None):
|
||||
if func:
|
||||
return HttprettyMockAWS({'global': self})(func)
|
||||
else:
|
||||
return HttprettyMockAWS({'global': self})
|
||||
|
||||
|
||||
class base_decorator(object):
|
||||
mock_backend = MockAWS
|
||||
|
|
@ -199,3 +254,7 @@ class base_decorator(object):
|
|||
return self.mock_backend(self.backends)(func)
|
||||
else:
|
||||
return self.mock_backend(self.backends)
|
||||
|
||||
|
||||
class deprecated_base_decorator(base_decorator):
|
||||
mock_backend = HttprettyMockAWS
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ class BaseResponse(_TemplateEnvironmentMixin):
|
|||
flat = flatten_json_request_body('', decoded, input_spec)
|
||||
for key, value in flat.items():
|
||||
querystring[key] = [value]
|
||||
else:
|
||||
elif self.body:
|
||||
querystring.update(parse_qs(self.body, keep_blank_values=True))
|
||||
if not querystring:
|
||||
querystring.update(headers)
|
||||
|
|
@ -152,6 +152,8 @@ class BaseResponse(_TemplateEnvironmentMixin):
|
|||
self.region = self.get_region_from_url(full_url)
|
||||
|
||||
self.headers = request.headers
|
||||
if 'host' not in self.headers:
|
||||
self.headers['host'] = urlparse(full_url).netloc
|
||||
self.response_headers = headers
|
||||
|
||||
def get_region_from_url(self, full_url):
|
||||
|
|
@ -189,6 +191,9 @@ class BaseResponse(_TemplateEnvironmentMixin):
|
|||
body, new_headers = response
|
||||
status = new_headers.get('status', 200)
|
||||
headers.update(new_headers)
|
||||
# Cast status to string
|
||||
if "status" in headers:
|
||||
headers['status'] = str(headers['status'])
|
||||
return status, headers, body
|
||||
raise NotImplementedError("The {0} action has not been implemented".format(action))
|
||||
|
||||
|
|
@ -327,6 +332,7 @@ def metadata_response(request, full_url, headers):
|
|||
|
||||
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html
|
||||
"""
|
||||
|
||||
parsed_url = urlparse(full_url)
|
||||
tomorrow = datetime.datetime.utcnow() + datetime.timedelta(days=1)
|
||||
credentials = dict(
|
||||
|
|
|
|||
|
|
@ -103,6 +103,28 @@ class convert_flask_to_httpretty_response(object):
|
|||
return response, status, headers
|
||||
|
||||
|
||||
class convert_flask_to_responses_response(object):
|
||||
|
||||
def __init__(self, callback):
|
||||
self.callback = callback
|
||||
|
||||
@property
|
||||
def __name__(self):
|
||||
# For instance methods, use class and method names. Otherwise
|
||||
# use module and method name
|
||||
if inspect.ismethod(self.callback):
|
||||
outer = self.callback.__self__.__class__.__name__
|
||||
else:
|
||||
outer = self.callback.__module__
|
||||
return "{0}.{1}".format(outer, self.callback.__name__)
|
||||
|
||||
def __call__(self, request, *args, **kwargs):
|
||||
result = self.callback(request, request.url, request.headers)
|
||||
# result is a status, headers, response tuple
|
||||
status, headers, response = result
|
||||
return status, headers, response
|
||||
|
||||
|
||||
def iso_8601_datetime_with_milliseconds(datetime):
|
||||
return datetime.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + 'Z'
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue