clean up urls. start to clean up responses

This commit is contained in:
Steve Pulec 2013-02-18 21:22:03 -05:00
parent ba360daa0f
commit 4283cca63c
11 changed files with 70 additions and 27 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
.coverage
*.pyc

View File

@ -5,7 +5,7 @@ init:
pip install -r requirements.txt
test:
nosetests ./tests/
nosetests --with-coverage ./tests/ --cover-package=moto
travis:
nosetests ./tests/

View File

@ -5,7 +5,6 @@ from httpretty import HTTPretty
class BaseBackend(object):
base_url = None
def reset(self):
self = self.__class__()
@ -30,7 +29,7 @@ class BaseBackend(object):
for key, value in self.urls.iteritems():
HTTPretty.register_uri(
method=method,
uri=re.compile(self.base_url + key),
uri=re.compile(key),
body=value,
)
try:

View File

@ -5,7 +5,6 @@ from .utils import random_instance_id, random_reservation_id
class EC2Backend(BaseBackend):
base_url = "https://ec2.us-east-1.amazonaws.com"
def __init__(self):
self.reservations = {}

View File

@ -1,5 +1,5 @@
from .responses import instances
urls = {
'/': instances,
"https://ec2.us-east-1.amazonaws.com/": instances,
}

View File

@ -23,7 +23,6 @@ class FakeBucket(object):
class S3Backend(BaseBackend):
base_url = "https://(.*)s3.amazonaws.com"
def __init__(self):
self.buckets = {}
@ -47,9 +46,7 @@ class S3Backend(BaseBackend):
return False
else:
return self.buckets.pop(bucket_name)
else:
# implement this
import pdb;pdb.set_trace()
return None
def set_key(self, bucket_name, key_name, value):

View File

@ -1,19 +1,28 @@
from jinja2 import Template
from .models import s3_backend
from .utils import bucket_name_from_hostname
def all_buckets(uri, body, method):
# No bucket specified. Listing all buckets
all_buckets = s3_backend.get_all_buckets()
template = Template(S3_ALL_BUCKETS)
return template.render(buckets=all_buckets)
def bucket_response(uri, body, headers):
hostname = uri.hostname
method = uri.method
s3_base_url = "s3.amazonaws.com"
if hostname == s3_base_url:
# No bucket specified. Listing all buckets
all_buckets = s3_backend.get_all_buckets()
template = Template(S3_ALL_BUCKETS)
return template.render(buckets=all_buckets)
# s3_base_url = "s3.amazonaws.com"
# if hostname == s3_base_url:
# # No bucket specified. Listing all buckets
# all_buckets = s3_backend.get_all_buckets()
# template = Template(S3_ALL_BUCKETS)
# return template.render(buckets=all_buckets)
bucket_name = hostname.replace(".s3.amazonaws.com", "")
bucket_name = bucket_name_from_hostname(hostname)
if method == 'GET':
bucket = s3_backend.get_bucket(bucket_name)
@ -28,14 +37,18 @@ def bucket_response(uri, body, headers):
return template.render(bucket=new_bucket)
elif method == 'DELETE':
removed_bucket = s3_backend.delete_bucket(bucket_name)
if removed_bucket:
if removed_bucket is None:
# Non-existant bucket
template = Template(S3_DELETE_NON_EXISTING_BUCKET)
return template.render(bucket_name=bucket_name), dict(status=404)
elif removed_bucket:
# Bucket exists
template = Template(S3_DELETE_BUCKET_SUCCESS)
return template.render(bucket=removed_bucket), dict(status=204)
else:
# Tried to delete a bucket that still has keys
template = Template(S3_DELETE_BUCKET_WITH_ITEMS_ERROR)
return template.render(bucket=removed_bucket), dict(status=409)
else:
import pdb;pdb.set_trace()
@ -44,15 +57,13 @@ def key_response(uri_info, body, headers):
key_name = uri_info.path.lstrip('/')
hostname = uri_info.hostname
bucket_name = hostname.replace(".s3.amazonaws.com", "")
method = uri_info.method
bucket_name = bucket_name_from_hostname(hostname)
if method == 'GET':
key = s3_backend.get_key(bucket_name, key_name)
if key:
return key.value
else:
return "", dict(status=404)
return key.value
if method == 'PUT':
if body:
@ -65,7 +76,10 @@ def key_response(uri_info, body, headers):
return ""
elif method == 'HEAD':
key = s3_backend.get_key(bucket_name, key_name)
return S3_OBJECT_RESPONSE, dict(etag=key.etag)
if key:
return S3_OBJECT_RESPONSE, dict(etag=key.etag)
else:
return "", dict(status=404)
elif method == 'DELETE':
removed_key = s3_backend.delete_key(bucket_name, key_name)
template = Template(S3_DELETE_OBJECT_SUCCESS)
@ -112,6 +126,14 @@ S3_DELETE_BUCKET_SUCCESS = """<DeleteBucketResponse xmlns="http://s3.amazonaws.c
</DeleteBucketResponse>
</DeleteBucketResponse>"""
S3_DELETE_NON_EXISTING_BUCKET = """<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>NoSuchBucket</Code>
<Message>The specified bucket does not exist</Message>
<BucketName>{{ bucket_name }}</BucketName>
<RequestId>asdfasdfsadf</RequestId>
<HostId>asfasdfsfsafasdf</HostId>
</Error>"""
S3_DELETE_BUCKET_WITH_ITEMS_ERROR = """<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>BucketNotEmpty</Code>
<Message>The bucket you tried to delete is not empty</Message>

View File

@ -1,6 +1,9 @@
from .responses import bucket_response, key_response
from .responses import all_buckets, bucket_response, key_response
base_url = "https://(.*).s3.amazonaws.com"
urls = {
'/$': bucket_response,
'/(.+)': key_response,
'https://s3.amazonaws.com/$': all_buckets,
'{0}/$'.format(base_url): bucket_response,
'{}/(.+)'.format(base_url): key_response,
}

8
moto/s3/utils.py Normal file
View File

@ -0,0 +1,8 @@
import re
bucket_name_regex = re.compile("(.+).s3.amazonaws.com")
def bucket_name_from_hostname(hostname):
bucket_result = bucket_name_regex.search(hostname)
return bucket_result.groups()[0]

View File

@ -1,4 +1,5 @@
boto
coverage
#httpretty
Jinja2
mock

View File

@ -32,6 +32,14 @@ def test_my_model_save():
assert conn.get_bucket('mybucket').get_key('steve').get_contents_as_string() == 'is awesome'
@mock_s3
def test_missing_key():
conn = boto.connect_s3('the_key', 'the_secret')
bucket = conn.create_bucket("foobar")
bucket.get_key("the-key").should.equal(None)
@mock_s3
def test_missing_bucket():
conn = boto.connect_s3('the_key', 'the_secret')
@ -47,13 +55,18 @@ def test_bucket_deletion():
key.key = "the-key"
key.set_contents_from_string("some value")
# Try to delete a bucket that still has keys
conn.delete_bucket.when.called_with("foobar").should.throw(S3ResponseError)
bucket.delete_key("the-key")
conn.delete_bucket("foobar")
# Get non-existing bucket
conn.get_bucket.when.called_with("foobar").should.throw(S3ResponseError)
# Delete non-existant bucket
conn.delete_bucket.when.called_with("foobar").should.throw(S3ResponseError)
@mock_s3
def test_get_all_buckets():