Test out py26 with new HTTPretty

This commit is contained in:
Steve Pulec 2013-10-03 20:34:13 -04:00
parent fe1f3ec06c
commit 3bddbb4af3
23 changed files with 81 additions and 68 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
moto.egg-info/*
dist/*
.tox
.coverage
*.pyc

View File

@ -1,5 +1,6 @@
language: python
python:
- 2.6
- 2.7
env:
matrix:
@ -12,6 +13,7 @@ env:
- BOTO_VERSION=2.7
install:
- pip install boto==$BOTO_VERSION
- pip install https://github.com/gabrielfalcao/HTTPretty/tarball/8bbbdfc14326678b1aeba6a2d81af0d835a2cd6f
- pip install .
- pip install -r requirements.txt
script:

View File

@ -46,7 +46,7 @@ class BaseResponse(object):
status = new_headers.pop('status', 200)
headers.update(new_headers)
return status, headers, body
raise NotImplementedError("The {} action has not been implemented".format(action))
raise NotImplementedError("The {0} action has not been implemented".format(action))
def metadata_response(request, full_url, headers):

View File

@ -31,7 +31,7 @@ def get_random_hex(length=8):
def get_random_message_id():
return '{}-{}-{}-{}-{}'.format(get_random_hex(8), get_random_hex(4), get_random_hex(4), get_random_hex(4), get_random_hex(12))
return '{0}-{1}-{2}-{3}-{4}'.format(get_random_hex(8), get_random_hex(4), get_random_hex(4), get_random_hex(4), get_random_hex(12))
def convert_regex_to_flask_path(url_path):
@ -61,7 +61,7 @@ class convert_flask_to_httpretty_response(object):
outer = self.callback.im_class.__name__
else:
outer = self.callback.__module__
return "{}.{}".format(outer, self.callback.__name__)
return "{0}.{1}".format(outer, self.callback.__name__)
def __call__(self, args=None, **kwargs):
headers = dict(request.headers)

View File

@ -1,7 +1,14 @@
from collections import defaultdict, OrderedDict
from collections import defaultdict
import datetime
import json
try:
from collections import OrderedDict
except ImportError:
# python 2.6 or earlier, use backport
from ordereddict import OrderedDict
from moto.core import BaseBackend
from .comparisons import get_comparison_func
from .utils import unix_time
@ -36,7 +43,7 @@ class DynamoType(object):
)
def __repr__(self):
return "DynamoType: {}".format(self.to_json())
return "DynamoType: {0}".format(self.to_json())
def to_json(self):
return {self.type: self.value}
@ -62,7 +69,7 @@ class Item(object):
self.attrs[key] = DynamoType(value)
def __repr__(self):
return "Item: {}".format(self.to_json())
return "Item: {0}".format(self.to_json())
def to_json(self):
attributes = {}

View File

@ -1,7 +1,5 @@
import datetime
import calendar
def unix_time(dt):
epoch = datetime.datetime.utcfromtimestamp(0)
delta = dt - epoch
return delta.total_seconds()
return calendar.timegm(dt.timetuple())

View File

@ -280,7 +280,7 @@ class SecurityRule(object):
@property
def unique_representation(self):
return "{}-{}-{}-{}-{}".format(
return "{0}-{1}-{2}-{3}-{4}".format(
self.ip_protocol,
self.from_port,
self.to_port,

View File

@ -12,7 +12,7 @@ class AmisResponse(object):
instance_id = instance_ids[0]
image = ec2_backend.create_image(instance_id, name, description)
if not image:
return "There is not instance with id {}".format(instance_id), dict(status=404)
return "There is not instance with id {0}".format(instance_id), dict(status=404)
template = Template(CREATE_IMAGE_RESPONSE)
return template.render(image=image)

View File

@ -39,7 +39,7 @@ class ElasticBlockStore(object):
success = ec2_backend.delete_snapshot(snapshot_id)
if not success:
# Snapshot doesn't exist
return "Snapshot with id {} does not exist".format(snapshot_id), dict(status=404)
return "Snapshot with id {0} does not exist".format(snapshot_id), dict(status=404)
return DELETE_SNAPSHOT_RESPONSE
def delete_volume(self):
@ -47,7 +47,7 @@ class ElasticBlockStore(object):
success = ec2_backend.delete_volume(volume_id)
if not success:
# Volume doesn't exist
return "Volume with id {} does not exist".format(volume_id), dict(status=404)
return "Volume with id {0} does not exist".format(volume_id), dict(status=404)
return DELETE_VOLUME_RESPONSE
def describe_snapshot_attribute(self):
@ -77,7 +77,7 @@ class ElasticBlockStore(object):
attachment = ec2_backend.detach_volume(volume_id, instance_id, device_path)
if not attachment:
# Volume wasn't attached
return "Volume {} can not be detached from {} because it is not attached".format(volume_id, instance_id), dict(status=404)
return "Volume {0} can not be detached from {1} because it is not attached".format(volume_id, instance_id), dict(status=404)
template = Template(DETATCH_VOLUME_RESPONSE)
return template.render(attachment=attachment)

View File

@ -34,7 +34,7 @@ class SecurityGroups(object):
group = ec2_backend.create_security_group(name, description)
if not group:
# There was an exisitng group
return "There was an existing security group with name {}".format(name), dict(status=409)
return "There was an existing security group with name {0}".format(name), dict(status=409)
template = Template(CREATE_SECURITY_GROUP_RESPONSE)
return template.render(group=group)
@ -45,7 +45,7 @@ class SecurityGroups(object):
if not group:
# There was no such group
return "There was no security group with name {}".format(name), dict(status=404)
return "There was no security group with name {0}".format(name), dict(status=404)
return DELETE_GROUP_RESPONSE
def describe_security_groups(self):

View File

@ -7,7 +7,7 @@ def random_id(prefix=''):
chars = range(10) + ['a', 'b', 'c', 'd', 'e', 'f']
instance_tag = ''.join(unicode(random.choice(chars)) for x in range(size))
return '{}-{}'.format(prefix, instance_tag)
return '{0}-{1}'.format(prefix, instance_tag)
def random_ami_id():
@ -60,9 +60,9 @@ def resource_ids_from_querystring(querystring_dict):
for key, value in querystring_dict.iteritems():
if key.startswith(prefix):
resource_index = key.replace(prefix + ".", "")
tag_key = querystring_dict.get("Tag.{}.Key".format(resource_index))[0]
tag_key = querystring_dict.get("Tag.{0}.Key".format(resource_index))[0]
tag_value_key = "Tag.{}.Value".format(resource_index)
tag_value_key = "Tag.{0}.Value".format(resource_index)
if tag_value_key in querystring_dict:
tag_value = querystring_dict.get(tag_value_key)[0]
else:
@ -78,7 +78,7 @@ def filters_from_querystring(querystring_dict):
match = re.search("Filter.(\d).Name", key)
if match:
filter_index = match.groups()[0]
value_prefix = "Filter.{}.Value".format(filter_index)
value_prefix = "Filter.{0}.Value".format(filter_index)
filter_values = [filter_value[0] for filter_key, filter_value in querystring_dict.iteritems() if filter_key.startswith(value_prefix)]
response_values[value[0]] = filter_values
return response_values

View File

@ -16,11 +16,11 @@ class ELBResponse(BaseResponse):
port_index = 1
while True:
try:
protocol = self.querystring['Listeners.member.{}.Protocol'.format(port_index)][0]
protocol = self.querystring['Listeners.member.{0}.Protocol'.format(port_index)][0]
except KeyError:
break
lb_port = self.querystring['Listeners.member.{}.LoadBalancerPort'.format(port_index)][0]
instance_port = self.querystring['Listeners.member.{}.InstancePort'.format(port_index)][0]
lb_port = self.querystring['Listeners.member.{0}.LoadBalancerPort'.format(port_index)][0]
instance_port = self.querystring['Listeners.member.{0}.InstancePort'.format(port_index)][0]
ports.append([protocol, lb_port, instance_port])
port_index += 1
elb_backend.create_load_balancer(

View File

@ -41,7 +41,7 @@ class FakeStep(object):
arg_index = 1
while True:
arg = kwargs.get('hadoop_jar_step._args.member.{}'.format(arg_index))
arg = kwargs.get('hadoop_jar_step._args.member.{0}'.format(arg_index))
if arg:
self.args.append(arg)
arg_index += 1

View File

@ -14,23 +14,21 @@ class ElasticMapReduceResponse(BaseResponse):
return [value[0] for key, value in self.querystring.items() if key.startswith(param_prefix)]
def _get_dict_param(self, param_prefix):
return {
camelcase_to_underscores(key.replace(param_prefix, "")): value[0]
for key, value
in self.querystring.items()
if key.startswith(param_prefix)
}
params = {}
for key, value in self.querystring.items():
if key.startswith(param_prefix):
params[camelcase_to_underscores(key.replace(param_prefix, ""))] = value[0]
return params
def _get_list_prefix(self, param_prefix):
results = []
param_index = 1
while True:
index_prefix = "{}.{}.".format(param_prefix, param_index)
new_items = {
camelcase_to_underscores(key.replace(index_prefix, "")): value[0]
for key, value in self.querystring.items()
if key.startswith(index_prefix)
}
index_prefix = "{0}.{1}.".format(param_prefix, param_index)
new_items = {}
for key, value in self.querystring.items():
if key.startswith(index_prefix):
new_items[camelcase_to_underscores(key.replace(index_prefix, ""))] = value[0]
if not new_items:
break
results.append(new_items)

View File

@ -5,10 +5,10 @@ import string
def random_job_id(size=13):
chars = range(10) + list(string.uppercase)
job_tag = ''.join(unicode(random.choice(chars)) for x in range(size))
return 'j-{}'.format(job_tag)
return 'j-{0}'.format(job_tag)
def random_instance_group_id(size=13):
chars = range(10) + list(string.uppercase)
job_tag = ''.join(unicode(random.choice(chars)) for x in range(size))
return 'i-{}'.format(job_tag)
return 'i-{0}'.format(job_tag)

View File

@ -116,7 +116,7 @@ class S3Backend(BaseBackend):
if delimiter and delimiter in key_without_prefix:
# If delimiter, we need to split out folder_results
key_without_delimiter = key_without_prefix.split(delimiter)[0]
folder_results.add("{}{}{}".format(prefix, key_without_delimiter, delimiter))
folder_results.add("{0}{1}{2}".format(prefix, key_without_delimiter, delimiter))
else:
key_results.add(key)
else:

View File

@ -79,12 +79,12 @@ def _bucket_response(request, full_url, headers):
for kv in request.body.split('&'):
k, v = kv.split('=')
form[k] = v
key = form['key']
f = form['file']
new_key = s3_backend.set_key(bucket_name, key, f)
#Metadata
meta_regex = re.compile('^x-amz-meta-([a-zA-Z0-9\-_]+)$', flags=re.IGNORECASE)
for form_id in form:
@ -95,7 +95,7 @@ def _bucket_response(request, full_url, headers):
new_key.set_metadata(meta_key, metadata)
return 200, headers, ""
else:
raise NotImplementedError("Method {} has not been impelemented in the S3 backend yet".format(method))
raise NotImplementedError("Method {0} has not been impelemented in the S3 backend yet".format(method))
def key_response(request, full_url, headers):
@ -146,7 +146,7 @@ def _key_response(request, full_url, headers):
# Initial data
new_key = s3_backend.set_key(bucket_name, key_name, body)
request.streaming = True
#Metadata
meta_regex = re.compile('^x-amz-meta-([a-zA-Z0-9\-_]+)$', flags=re.IGNORECASE)
for header in request.headers:
@ -172,7 +172,7 @@ def _key_response(request, full_url, headers):
template = Template(S3_DELETE_OBJECT_SUCCESS)
return 204, headers, template.render(bucket=removed_key)
else:
raise NotImplementedError("Method {} has not been impelemented in the S3 backend yet".format(method))
raise NotImplementedError("Method {0} has not been impelemented in the S3 backend yet".format(method))
S3_ALL_BUCKETS = """<ListAllMyBucketsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">

View File

@ -42,7 +42,7 @@ class EmailResponse(BaseResponse):
destination = self.querystring.get('Destination.ToAddresses.member.1')[0]
message = ses_backend.send_email(source, subject, body, destination)
if not message:
return "Did not have authority to send from email {}".format(source), dict(status=400)
return "Did not have authority to send from email {0}".format(source), dict(status=400)
template = Template(SEND_EMAIL_RESPONSE)
return template.render(message=message)
@ -53,7 +53,7 @@ class EmailResponse(BaseResponse):
message = ses_backend.send_raw_email(source, destination, raw_data)
if not message:
return "Did not have authority to send from email {}".format(source), dict(status=400)
return "Did not have authority to send from email {0}".format(source), dict(status=400)
template = Template(SEND_RAW_EMAIL_RESPONSE)
return template.render(message=message)

View File

@ -7,7 +7,7 @@ def random_hex(length):
def get_random_message_id():
return "{}-{}-{}-{}-{}-{}-{}".format(
return "{0}-{1}-{2}-{3}-{4}-{5}-{6}".format(
random_hex(16),
random_hex(8),
random_hex(4),

View File

@ -26,7 +26,6 @@ class QueuesResponse(BaseResponse):
else:
return "", dict(status=404)
def list_queues(self):
queues = sqs_backend.list_queues()
template = Template(LIST_QUEUES_RESPONSE)
@ -51,7 +50,7 @@ class QueueResponse(BaseResponse):
queue_name = self.path.split("/")[-1]
queue = sqs_backend.delete_queue(queue_name)
if not queue:
return "A queue with name {} does not exist".format(queue_name), dict(status=404)
return "A queue with name {0} does not exist".format(queue_name), dict(status=404)
template = Template(DELETE_QUEUE_RESPONSE)
return template.render(queue=queue)
@ -79,15 +78,15 @@ class QueueResponse(BaseResponse):
messages = []
for index in range(1, 11):
# Loop through looking for messages
message_key = 'SendMessageBatchRequestEntry.{}.MessageBody'.format(index)
message_key = 'SendMessageBatchRequestEntry.{0}.MessageBody'.format(index)
message_body = self.querystring.get(message_key)
if not message_body:
# Found all messages
break
message_user_id_key = 'SendMessageBatchRequestEntry.{}.Id'.format(index)
message_user_id_key = 'SendMessageBatchRequestEntry.{0}.Id'.format(index)
message_user_id = self.querystring.get(message_user_id_key)[0]
delay_key = 'SendMessageBatchRequestEntry.{}.DelaySeconds'.format(index)
delay_key = 'SendMessageBatchRequestEntry.{0}.DelaySeconds'.format(index)
delay_seconds = self.querystring.get(delay_key, [None])[0]
message = sqs_backend.send_message(queue_name, message_body[0], delay_seconds=delay_seconds)
message.user_id = message_user_id
@ -118,7 +117,7 @@ class QueueResponse(BaseResponse):
message_ids = []
for index in range(1, 11):
# Loop through looking for messages
receipt_key = 'DeleteMessageBatchRequestEntry.{}.ReceiptHandle'.format(index)
receipt_key = 'DeleteMessageBatchRequestEntry.{0}.ReceiptHandle'.format(index)
receipt_handle = self.querystring.get(receipt_key)
if not receipt_handle:
# Found all messages
@ -126,7 +125,7 @@ class QueueResponse(BaseResponse):
sqs_backend.delete_message(queue_name, receipt_handle[0])
message_user_id_key = 'DeleteMessageBatchRequestEntry.{}.Id'.format(index)
message_user_id_key = 'DeleteMessageBatchRequestEntry.{0}.Id'.format(index)
message_user_id = self.querystring.get(message_user_id_key)[0]
message_ids.append(message_user_id)

View File

@ -2,6 +2,19 @@
from setuptools import setup, find_packages
install_requires = [
"boto",
"flask",
"httpretty>=0.6.1",
"Jinja2",
]
import sys
if sys.version_info < (2, 7):
# No buildint OrderedDict before 2.7
install_requires.append('ordereddict')
setup(
name='moto',
version='0.2.9',
@ -16,10 +29,5 @@ setup(
],
},
packages=find_packages(),
install_requires=[
"boto",
"flask",
"httpretty>=0.6.1",
"Jinja2",
],
install_requires=install_requires,
)

View File

@ -365,7 +365,7 @@ def test_scan():
'Body': 'http://url_to_lolcat.gif',
'SentBy': 'User B',
'ReceivedTime': '12/9/2011 11:36:03 PM',
'Ids': {1, 2, 3},
'Ids': set([1, 2, 3]),
'PK': 7,
}
item = table.new_item(
@ -442,7 +442,7 @@ def test_write_batch():
'Body': 'http://url_to_lolcat.gif',
'SentBy': 'User B',
'ReceivedTime': '12/9/2011 11:36:03 PM',
'Ids': {1, 2, 3},
'Ids': set([1, 2, 3]),
'PK': 7,
},
))
@ -489,7 +489,7 @@ def test_batch_read():
'Body': 'http://url_to_lolcat.gif',
'SentBy': 'User B',
'ReceivedTime': '12/9/2011 11:36:03 PM',
'Ids': {1, 2, 3},
'Ids': set([1, 2, 3]),
'PK': 7,
}
item = table.new_item(

View File

@ -282,7 +282,7 @@ def test_scan():
'Body': 'http://url_to_lolcat.gif',
'SentBy': 'User B',
'ReceivedTime': '12/9/2011 11:36:03 PM',
'Ids': {1, 2, 3},
'Ids': set([1, 2, 3]),
'PK': 7,
}
item = table.new_item(
@ -356,7 +356,7 @@ def test_write_batch():
'Body': 'http://url_to_lolcat.gif',
'SentBy': 'User B',
'ReceivedTime': '12/9/2011 11:36:03 PM',
'Ids': {1, 2, 3},
'Ids': set([1, 2, 3]),
'PK': 7,
},
))
@ -401,7 +401,7 @@ def test_batch_read():
'Body': 'http://url_to_lolcat.gif',
'SentBy': 'User B',
'ReceivedTime': '12/9/2011 11:36:03 PM',
'Ids': {1, 2, 3},
'Ids': set([1, 2, 3]),
'PK': 7,
}
item = table.new_item(