add more s3 functions
This commit is contained in:
parent
e20ae8e91c
commit
28a46a5a3a
@ -19,7 +19,7 @@ class FakeKey(object):
|
||||
class FakeBucket(object):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.keys = []
|
||||
self.keys = {}
|
||||
|
||||
|
||||
class S3Backend(BaseBackend):
|
||||
@ -36,22 +36,33 @@ class S3Backend(BaseBackend):
|
||||
def get_bucket(self, bucket_name):
|
||||
return self.buckets.get(bucket_name)
|
||||
|
||||
def delete_bucket(self, bucket_name):
|
||||
bucket = self.buckets.get(bucket_name)
|
||||
if bucket:
|
||||
if bucket.keys:
|
||||
# Can't delete a bucket with keys
|
||||
return False
|
||||
else:
|
||||
return self.buckets.pop(bucket_name)
|
||||
else:
|
||||
# implement this
|
||||
import pdb;pdb.set_trace()
|
||||
|
||||
|
||||
def set_key(self, bucket_name, key_name, value):
|
||||
bucket = self.buckets[bucket_name]
|
||||
new_key = FakeKey(name=key_name, value=value)
|
||||
bucket.keys.append(new_key)
|
||||
bucket.keys[key_name] = new_key
|
||||
|
||||
return new_key
|
||||
|
||||
def get_key(self, bucket_name, key_name):
|
||||
bucket = self.buckets[bucket_name]
|
||||
found_key = None
|
||||
for key in bucket.keys:
|
||||
if key.name == key_name:
|
||||
found_key = key
|
||||
break
|
||||
return bucket.keys.get(key_name)
|
||||
|
||||
return found_key
|
||||
def delete_key(self, bucket_name, key_name):
|
||||
bucket = self.buckets[bucket_name]
|
||||
return bucket.keys.pop(key_name)
|
||||
|
||||
|
||||
s3_backend = S3Backend()
|
||||
|
@ -5,18 +5,31 @@ from .models import s3_backend
|
||||
def bucket_response(uri, body, headers):
|
||||
hostname = uri.hostname
|
||||
bucket_name = hostname.replace(".s3.amazonaws.com", "")
|
||||
method = uri.method
|
||||
|
||||
if uri.method == 'GET':
|
||||
if method == 'GET':
|
||||
bucket = s3_backend.get_bucket(bucket_name)
|
||||
if bucket:
|
||||
template = Template(S3_BUCKET_GET_RESPONSE)
|
||||
return template.render(bucket=bucket)
|
||||
else:
|
||||
return "", dict(status=404)
|
||||
else:
|
||||
elif method == 'PUT':
|
||||
new_bucket = s3_backend.create_bucket(bucket_name)
|
||||
template = Template(S3_BUCKET_CREATE_RESPONSE)
|
||||
return template.render(bucket=new_bucket)
|
||||
elif method == 'DELETE':
|
||||
removed_bucket = s3_backend.delete_bucket(bucket_name)
|
||||
if removed_bucket:
|
||||
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()
|
||||
|
||||
|
||||
def key_response(uri_info, body, headers):
|
||||
@ -24,15 +37,16 @@ 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
|
||||
|
||||
if uri_info.method == 'GET':
|
||||
if method == 'GET':
|
||||
key = s3_backend.get_key(bucket_name, key_name)
|
||||
if key:
|
||||
return key.value
|
||||
else:
|
||||
return "", dict(status=404)
|
||||
|
||||
if uri_info.method == 'PUT':
|
||||
if method == 'PUT':
|
||||
if body:
|
||||
new_key = s3_backend.set_key(bucket_name, key_name, body)
|
||||
return S3_OBJECT_RESPONSE, dict(etag=new_key.etag)
|
||||
@ -41,9 +55,13 @@ def key_response(uri_info, body, headers):
|
||||
return "", dict(etag=key.etag)
|
||||
else:
|
||||
return ""
|
||||
elif uri_info.method == 'HEAD':
|
||||
elif method == 'HEAD':
|
||||
key = s3_backend.get_key(bucket_name, key_name)
|
||||
return S3_OBJECT_RESPONSE, dict(etag=key.etag)
|
||||
elif method == 'DELETE':
|
||||
removed_key = s3_backend.delete_key(bucket_name, key_name)
|
||||
template = Template(S3_DELETE_OBJECT_SUCCESS)
|
||||
return template.render(bucket=removed_key), dict(status=204)
|
||||
else:
|
||||
import pdb;pdb.set_trace()
|
||||
|
||||
@ -64,6 +82,28 @@ S3_BUCKET_CREATE_RESPONSE = """<CreateBucketResponse xmlns="http://s3.amazonaws.
|
||||
</CreateBucketResponse>
|
||||
</CreateBucketResponse>"""
|
||||
|
||||
S3_DELETE_BUCKET_SUCCESS = """<DeleteBucketResponse xmlns="http://s3.amazonaws.com/doc/2006-03-01">
|
||||
<DeleteBucketResponse>
|
||||
<Code>204</Code>
|
||||
<Description>No Content</Description>
|
||||
</DeleteBucketResponse>
|
||||
</DeleteBucketResponse>"""
|
||||
|
||||
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>
|
||||
<BucketName>{{ bucket.name }}</BucketName>
|
||||
<RequestId>asdfasdfsdafds</RequestId>
|
||||
<HostId>sdfgdsfgdsfgdfsdsfgdfs</HostId>
|
||||
</Error>"""
|
||||
|
||||
S3_DELETE_OBJECT_SUCCESS = """<DeleteObjectResponse xmlns="http://s3.amazonaws.com/doc/2006-03-01">
|
||||
<DeleteObjectResponse>
|
||||
<Code>200</Code>
|
||||
<Description>OK</Description>
|
||||
</DeleteObjectResponse>
|
||||
</DeleteObjectResponse>"""
|
||||
|
||||
S3_OBJECT_RESPONSE = """<PutObjectResponse xmlns="http://s3.amazonaws.com/doc/2006-03-01">
|
||||
<PutObjectResponse>
|
||||
<ETag>"asdlfkdalsjfsalfkjsadlfjsdjkk"</ETag>
|
||||
|
@ -1,6 +1,9 @@
|
||||
import boto
|
||||
from boto.exception import S3ResponseError
|
||||
from boto.s3.key import Key
|
||||
|
||||
import sure
|
||||
|
||||
from moto import mock_s3
|
||||
|
||||
|
||||
@ -28,3 +31,25 @@ def test_my_model_save():
|
||||
model_instance.save()
|
||||
|
||||
assert conn.get_bucket('mybucket').get_key('steve').get_contents_as_string() == 'is awesome'
|
||||
|
||||
@mock_s3
|
||||
def test_missing_bucket():
|
||||
conn = boto.connect_s3('the_key', 'the_secret')
|
||||
conn.get_bucket.when.called_with('mybucket').should.throw(S3ResponseError)
|
||||
|
||||
|
||||
@mock_s3
|
||||
def test_bucket_deletion():
|
||||
conn = boto.connect_s3('the_key', 'the_secret')
|
||||
bucket = conn.create_bucket("foobar")
|
||||
|
||||
key = Key(bucket)
|
||||
key.key = "the-key"
|
||||
key.set_contents_from_string("some value")
|
||||
|
||||
conn.delete_bucket.when.called_with("foobar").should.throw(S3ResponseError)
|
||||
|
||||
bucket.delete_key("the-key")
|
||||
conn.delete_bucket("foobar")
|
||||
|
||||
conn.get_bucket.when.called_with("foobar").should.throw(S3ResponseError)
|
||||
|
Loading…
Reference in New Issue
Block a user