S3 Mock should return an HTTP 409 if trying to create a bucket that

already exists. Closes #94.
This commit is contained in:
Steve Pulec 2014-03-16 21:25:14 -04:00
parent 76553671f2
commit 60cd79c6e2
6 changed files with 33 additions and 16 deletions

2
moto/s3/exceptions.py Normal file
View File

@ -0,0 +1,2 @@
class BucketAlreadyExists(Exception):
pass

View File

@ -5,6 +5,7 @@ import hashlib
from moto.core import BaseBackend from moto.core import BaseBackend
from moto.core.utils import iso_8601_datetime, rfc_1123_datetime from moto.core.utils import iso_8601_datetime, rfc_1123_datetime
from .exceptions import BucketAlreadyExists
from .utils import clean_key_name from .utils import clean_key_name
UPLOAD_ID_BYTES = 43 UPLOAD_ID_BYTES = 43
@ -107,6 +108,8 @@ class S3Backend(BaseBackend):
self.buckets = {} self.buckets = {}
def create_bucket(self, bucket_name): def create_bucket(self, bucket_name):
if bucket_name in self.buckets:
raise BucketAlreadyExists()
new_bucket = FakeBucket(name=bucket_name) new_bucket = FakeBucket(name=bucket_name)
self.buckets[bucket_name] = new_bucket self.buckets[bucket_name] = new_bucket
return new_bucket return new_bucket

View File

@ -3,6 +3,7 @@ import re
from jinja2 import Template from jinja2 import Template
from .exceptions import BucketAlreadyExists
from .models import s3_backend from .models import s3_backend
from .utils import bucket_name_from_url from .utils import bucket_name_from_url
@ -66,7 +67,10 @@ class ResponseObject(object):
else: else:
return 404, headers, "" return 404, headers, ""
elif method == 'PUT': elif method == 'PUT':
try:
new_bucket = self.backend.create_bucket(bucket_name) new_bucket = self.backend.create_bucket(bucket_name)
except BucketAlreadyExists:
return 409, headers, ""
template = Template(S3_BUCKET_CREATE_RESPONSE) template = Template(S3_BUCKET_CREATE_RESPONSE)
return template.render(bucket=new_bucket) return template.render(bucket=new_bucket)
elif method == 'DELETE': elif method == 'DELETE':

View File

@ -2,7 +2,7 @@ import urllib2
from io import BytesIO from io import BytesIO
import boto import boto
from boto.exception import S3ResponseError from boto.exception import S3CreateError, S3ResponseError
from boto.s3.key import Key from boto.s3.key import Key
from freezegun import freeze_time from freezegun import freeze_time
import requests import requests
@ -171,6 +171,14 @@ def test_bucket_with_dash():
conn.get_bucket.when.called_with('mybucket-test').should.throw(S3ResponseError) conn.get_bucket.when.called_with('mybucket-test').should.throw(S3ResponseError)
@mock_s3
def test_create_existing_bucket():
"Trying to create a bucket that already exists should raise an Error"
conn = boto.connect_s3('the_key', 'the_secret')
conn.create_bucket("foobar")
conn.create_bucket.when.called_with('foobar').should.throw(S3CreateError)
@mock_s3 @mock_s3
def test_bucket_deletion(): def test_bucket_deletion():
conn = boto.connect_s3('the_key', 'the_secret') conn = boto.connect_s3('the_key', 'the_secret')

View File

@ -20,20 +20,20 @@ def test_s3_server_bucket_create():
backend = server.create_backend_app("s3") backend = server.create_backend_app("s3")
test_client = backend.test_client() test_client = backend.test_client()
res = test_client.put('/', 'http://foobar.localhost:5000/') res = test_client.put('/', 'http://foobaz.localhost:5000/')
res.status_code.should.equal(200) res.status_code.should.equal(200)
res = test_client.get('/') res = test_client.get('/')
res.data.should.contain('<Name>foobar</Name>') res.data.should.contain('<Name>foobaz</Name>')
res = test_client.get('/', 'http://foobar.localhost:5000/') res = test_client.get('/', 'http://foobaz.localhost:5000/')
res.status_code.should.equal(200) res.status_code.should.equal(200)
res.data.should.contain("ListBucketResult") res.data.should.contain("ListBucketResult")
res = test_client.put('/bar', 'http://foobar.localhost:5000/', data='test value') res = test_client.put('/bar', 'http://foobaz.localhost:5000/', data='test value')
res.status_code.should.equal(200) res.status_code.should.equal(200)
res = test_client.get('/bar', 'http://foobar.localhost:5000/') res = test_client.get('/bar', 'http://foobaz.localhost:5000/')
res.status_code.should.equal(200) res.status_code.should.equal(200)
res.data.should.equal("test value") res.data.should.equal("test value")
@ -42,14 +42,14 @@ def test_s3_server_post_to_bucket():
backend = server.create_backend_app("s3") backend = server.create_backend_app("s3")
test_client = backend.test_client() test_client = backend.test_client()
res = test_client.put('/', 'http://foobar.localhost:5000/') res = test_client.put('/', 'http://tester.localhost:5000/')
res.status_code.should.equal(200) res.status_code.should.equal(200)
test_client.post('/', "https://foobar.localhost:5000/", data={ test_client.post('/', "https://tester.localhost:5000/", data={
'key': 'the-key', 'key': 'the-key',
'file': 'nothing' 'file': 'nothing'
}) })
res = test_client.get('/the-key', 'http://foobar.localhost:5000/') res = test_client.get('/the-key', 'http://tester.localhost:5000/')
res.status_code.should.equal(200) res.status_code.should.equal(200)
res.data.should.equal("nothing") res.data.should.equal("nothing")

View File

@ -42,14 +42,14 @@ def test_s3_server_post_to_bucket():
backend = server.create_backend_app("s3bucket_path") backend = server.create_backend_app("s3bucket_path")
test_client = backend.test_client() test_client = backend.test_client()
res = test_client.put('/foobar', 'http://localhost:5000/') res = test_client.put('/foobar2', 'http://localhost:5000/')
res.status_code.should.equal(200) res.status_code.should.equal(200)
test_client.post('/foobar', "https://localhost:5000/", data={ test_client.post('/foobar2', "https://localhost:5000/", data={
'key': 'the-key', 'key': 'the-key',
'file': 'nothing' 'file': 'nothing'
}) })
res = test_client.get('/foobar/the-key', 'http://localhost:5000/') res = test_client.get('/foobar2/the-key', 'http://localhost:5000/')
res.status_code.should.equal(200) res.status_code.should.equal(200)
res.data.should.equal("nothing") res.data.should.equal("nothing")