clean up urls. start to clean up responses
This commit is contained in:
parent
ba360daa0f
commit
4283cca63c
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
|
.coverage
|
||||||
*.pyc
|
*.pyc
|
||||||
|
2
Makefile
2
Makefile
@ -5,7 +5,7 @@ init:
|
|||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
|
|
||||||
test:
|
test:
|
||||||
nosetests ./tests/
|
nosetests --with-coverage ./tests/ --cover-package=moto
|
||||||
|
|
||||||
travis:
|
travis:
|
||||||
nosetests ./tests/
|
nosetests ./tests/
|
||||||
|
@ -5,7 +5,6 @@ from httpretty import HTTPretty
|
|||||||
|
|
||||||
|
|
||||||
class BaseBackend(object):
|
class BaseBackend(object):
|
||||||
base_url = None
|
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self = self.__class__()
|
self = self.__class__()
|
||||||
@ -30,7 +29,7 @@ class BaseBackend(object):
|
|||||||
for key, value in self.urls.iteritems():
|
for key, value in self.urls.iteritems():
|
||||||
HTTPretty.register_uri(
|
HTTPretty.register_uri(
|
||||||
method=method,
|
method=method,
|
||||||
uri=re.compile(self.base_url + key),
|
uri=re.compile(key),
|
||||||
body=value,
|
body=value,
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
|
@ -5,7 +5,6 @@ from .utils import random_instance_id, random_reservation_id
|
|||||||
|
|
||||||
|
|
||||||
class EC2Backend(BaseBackend):
|
class EC2Backend(BaseBackend):
|
||||||
base_url = "https://ec2.us-east-1.amazonaws.com"
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.reservations = {}
|
self.reservations = {}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from .responses import instances
|
from .responses import instances
|
||||||
|
|
||||||
urls = {
|
urls = {
|
||||||
'/': instances,
|
"https://ec2.us-east-1.amazonaws.com/": instances,
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ class FakeBucket(object):
|
|||||||
|
|
||||||
|
|
||||||
class S3Backend(BaseBackend):
|
class S3Backend(BaseBackend):
|
||||||
base_url = "https://(.*)s3.amazonaws.com"
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.buckets = {}
|
self.buckets = {}
|
||||||
@ -47,9 +46,7 @@ class S3Backend(BaseBackend):
|
|||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return self.buckets.pop(bucket_name)
|
return self.buckets.pop(bucket_name)
|
||||||
else:
|
return None
|
||||||
# implement this
|
|
||||||
import pdb;pdb.set_trace()
|
|
||||||
|
|
||||||
|
|
||||||
def set_key(self, bucket_name, key_name, value):
|
def set_key(self, bucket_name, key_name, value):
|
||||||
|
@ -1,19 +1,28 @@
|
|||||||
from jinja2 import Template
|
from jinja2 import Template
|
||||||
|
|
||||||
from .models import s3_backend
|
from .models import s3_backend
|
||||||
|
from .utils import bucket_name_from_hostname
|
||||||
|
|
||||||
def bucket_response(uri, body, headers):
|
|
||||||
hostname = uri.hostname
|
|
||||||
method = uri.method
|
|
||||||
|
|
||||||
s3_base_url = "s3.amazonaws.com"
|
def all_buckets(uri, body, method):
|
||||||
if hostname == s3_base_url:
|
|
||||||
# No bucket specified. Listing all buckets
|
# No bucket specified. Listing all buckets
|
||||||
all_buckets = s3_backend.get_all_buckets()
|
all_buckets = s3_backend.get_all_buckets()
|
||||||
template = Template(S3_ALL_BUCKETS)
|
template = Template(S3_ALL_BUCKETS)
|
||||||
return template.render(buckets=all_buckets)
|
return template.render(buckets=all_buckets)
|
||||||
|
|
||||||
bucket_name = hostname.replace(".s3.amazonaws.com", "")
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
bucket_name = bucket_name_from_hostname(hostname)
|
||||||
|
|
||||||
if method == 'GET':
|
if method == 'GET':
|
||||||
bucket = s3_backend.get_bucket(bucket_name)
|
bucket = s3_backend.get_bucket(bucket_name)
|
||||||
@ -28,14 +37,18 @@ def bucket_response(uri, body, headers):
|
|||||||
return template.render(bucket=new_bucket)
|
return template.render(bucket=new_bucket)
|
||||||
elif method == 'DELETE':
|
elif method == 'DELETE':
|
||||||
removed_bucket = s3_backend.delete_bucket(bucket_name)
|
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)
|
template = Template(S3_DELETE_BUCKET_SUCCESS)
|
||||||
return template.render(bucket=removed_bucket), dict(status=204)
|
return template.render(bucket=removed_bucket), dict(status=204)
|
||||||
else:
|
else:
|
||||||
# Tried to delete a bucket that still has keys
|
# Tried to delete a bucket that still has keys
|
||||||
template = Template(S3_DELETE_BUCKET_WITH_ITEMS_ERROR)
|
template = Template(S3_DELETE_BUCKET_WITH_ITEMS_ERROR)
|
||||||
return template.render(bucket=removed_bucket), dict(status=409)
|
return template.render(bucket=removed_bucket), dict(status=409)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
import pdb;pdb.set_trace()
|
import pdb;pdb.set_trace()
|
||||||
|
|
||||||
@ -44,15 +57,13 @@ def key_response(uri_info, body, headers):
|
|||||||
|
|
||||||
key_name = uri_info.path.lstrip('/')
|
key_name = uri_info.path.lstrip('/')
|
||||||
hostname = uri_info.hostname
|
hostname = uri_info.hostname
|
||||||
bucket_name = hostname.replace(".s3.amazonaws.com", "")
|
|
||||||
method = uri_info.method
|
method = uri_info.method
|
||||||
|
|
||||||
|
bucket_name = bucket_name_from_hostname(hostname)
|
||||||
|
|
||||||
if method == 'GET':
|
if method == 'GET':
|
||||||
key = s3_backend.get_key(bucket_name, key_name)
|
key = s3_backend.get_key(bucket_name, key_name)
|
||||||
if key:
|
|
||||||
return key.value
|
return key.value
|
||||||
else:
|
|
||||||
return "", dict(status=404)
|
|
||||||
|
|
||||||
if method == 'PUT':
|
if method == 'PUT':
|
||||||
if body:
|
if body:
|
||||||
@ -65,7 +76,10 @@ def key_response(uri_info, body, headers):
|
|||||||
return ""
|
return ""
|
||||||
elif method == 'HEAD':
|
elif method == 'HEAD':
|
||||||
key = s3_backend.get_key(bucket_name, key_name)
|
key = s3_backend.get_key(bucket_name, key_name)
|
||||||
|
if key:
|
||||||
return S3_OBJECT_RESPONSE, dict(etag=key.etag)
|
return S3_OBJECT_RESPONSE, dict(etag=key.etag)
|
||||||
|
else:
|
||||||
|
return "", dict(status=404)
|
||||||
elif method == 'DELETE':
|
elif method == 'DELETE':
|
||||||
removed_key = s3_backend.delete_key(bucket_name, key_name)
|
removed_key = s3_backend.delete_key(bucket_name, key_name)
|
||||||
template = Template(S3_DELETE_OBJECT_SUCCESS)
|
template = Template(S3_DELETE_OBJECT_SUCCESS)
|
||||||
@ -112,6 +126,14 @@ S3_DELETE_BUCKET_SUCCESS = """<DeleteBucketResponse xmlns="http://s3.amazonaws.c
|
|||||||
</DeleteBucketResponse>
|
</DeleteBucketResponse>
|
||||||
</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"?>
|
S3_DELETE_BUCKET_WITH_ITEMS_ERROR = """<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Error><Code>BucketNotEmpty</Code>
|
<Error><Code>BucketNotEmpty</Code>
|
||||||
<Message>The bucket you tried to delete is not empty</Message>
|
<Message>The bucket you tried to delete is not empty</Message>
|
||||||
|
@ -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 = {
|
urls = {
|
||||||
'/$': bucket_response,
|
'https://s3.amazonaws.com/$': all_buckets,
|
||||||
'/(.+)': key_response,
|
'{0}/$'.format(base_url): bucket_response,
|
||||||
|
'{}/(.+)'.format(base_url): key_response,
|
||||||
}
|
}
|
||||||
|
8
moto/s3/utils.py
Normal file
8
moto/s3/utils.py
Normal 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]
|
@ -1,4 +1,5 @@
|
|||||||
boto
|
boto
|
||||||
|
coverage
|
||||||
#httpretty
|
#httpretty
|
||||||
Jinja2
|
Jinja2
|
||||||
mock
|
mock
|
||||||
|
@ -32,6 +32,14 @@ def test_my_model_save():
|
|||||||
|
|
||||||
assert conn.get_bucket('mybucket').get_key('steve').get_contents_as_string() == 'is awesome'
|
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
|
@mock_s3
|
||||||
def test_missing_bucket():
|
def test_missing_bucket():
|
||||||
conn = boto.connect_s3('the_key', 'the_secret')
|
conn = boto.connect_s3('the_key', 'the_secret')
|
||||||
@ -47,13 +55,18 @@ def test_bucket_deletion():
|
|||||||
key.key = "the-key"
|
key.key = "the-key"
|
||||||
key.set_contents_from_string("some value")
|
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)
|
conn.delete_bucket.when.called_with("foobar").should.throw(S3ResponseError)
|
||||||
|
|
||||||
bucket.delete_key("the-key")
|
bucket.delete_key("the-key")
|
||||||
conn.delete_bucket("foobar")
|
conn.delete_bucket("foobar")
|
||||||
|
|
||||||
|
# Get non-existing bucket
|
||||||
conn.get_bucket.when.called_with("foobar").should.throw(S3ResponseError)
|
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
|
@mock_s3
|
||||||
def test_get_all_buckets():
|
def test_get_all_buckets():
|
||||||
|
Loading…
Reference in New Issue
Block a user