Repository: getmoto/moto

Issue:
no error or warning when creating s3 bucket that already exists in standalone server
Python 3.6.3
boto3==1.4.8
moto==1.1.25

I know I should be using the decorators and not the standalone server, but this still seems like a bug. After starting the standalone server: 

```
moto_server s3
```

I run this code:

```python
import boto3
boto3.setup_default_session()
s3 = boto3.client(service_name="s3", region_name="us-west-2", endpoint_url="http://localhost:5000")
result = s3.create_bucket(Bucket='mybucket')
print(result)
result = s3.create_bucket(Bucket='mybucket')
print(result)
```
I expect that last line to return a stack trace with the message `BucketAlreadyOwnedByYou: An error occurred (BucketAlreadyOwnedByYou) when calling the CreateBucket operation: Your previous request to create the named bucket succeeded and you already own it.` That's what I get in actual S3 when trying to create a bucket I have already created.

But instead it succeeds without comment just like the first call to `create_bucket`.

This is what it outputs:

```
{'ResponseMetadata': {'HTTPStatusCode': 200, 'HTTPHeaders': {'content-type': 'text/html; charset=utf-8', 'content-length': '174', 'server': 'Werkzeug/0.12.2 Python/3.6.3', 'date': 'Mon, 04 Dec 2017 04:24:04 GMT'}, 'RetryAttempts': 0}}
{'ResponseMetadata': {'HTTPStatusCode': 200, 'HTTPHeaders': {'content-type': 'text/html; charset=utf-8', 'content-length': '174', 'server': 'Werkzeug/0.12.2 Python/3.6.3', 'date': 'Mon, 04 Dec 2017 04:24:04 GMT'}, 'RetryAttempts': 0}}
```

If I upload a file to the bucket after the first bucket creation, that file is still there after the second creation. So it's not overwriting the original bucket, it's just not telling me that bucket already exists.

I'm trying to test code that relies on the correct behavior, so...



Discussion:
FWIW this happens with the decorator as well:

```python
"test harness"
from moto import mock_s3
import boto3

@mock_s3
def testit():
    "testit!"
    boto3.setup_default_session()
    s3 = boto3.client(service_name="s3", region_name="us-west-2")
    result = s3.create_bucket(Bucket='mybucket')
    print(result)
    result = s3.create_bucket(Bucket='mybucket')
    print(result)

if __name__ == '__main__':
    testit()

```

Output:

```
{'ResponseMetadata': {'HTTPStatusCode': 200, 'HTTPHeaders': {'Content-Type': 'text/plain'}, 'RetryAttempts': 0}}
{'ResponseMetadata': {'HTTPStatusCode': 200, 'HTTPHeaders': {'Content-Type': 'text/plain'}, 'RetryAttempts': 0}}
```
https://github.com/spulec/moto/issues/273 - added a special behaviour to mimic the actual behaviour of AWS.

Creating a bucket in us-east-1 will actually succeed and return the original bucket in that region only.

Now the thing this is also more confusing because setting the region_name on the S3 client doesn't change the region that the bucket it is created in, so we are defaulting to us-east-1 which has this behaviour.

 If you set a bucket location constraint to a non us-east-1 region on the dupe create bucket requests then the exception is raised as expected. I have done a few tests and the behaviour is pretty much the same as boto3 for real, except for the following case:
* if you create the s3 client in a region (for example eu-west-1) then called create-bucket without a location constraint to the same region, then it will raise an IllegalConstraintException (The unspecified location constraint is incompatible for the region specific endpoint this request was sent to).

So this isn't a moto bug just very odd corner case behaviour for the actual S3 service in us-east-1.

Updated version of your example which shows the dupe bucket being reported in eu-west-1:
```
from moto import mock_s3
import boto3

@mock_s3
def testit():
    "testit!"
    boto3.setup_default_session()
    s3 = boto3.client(service_name="s3", region_name="eu-west-1")
    result = s3.create_bucket(Bucket='mybucket', CreateBucketConfiguration={'LocationConstraint': 'eu-west-1'})
    print s3.list_buckets()
    print(result)
    result = s3.create_bucket(Bucket='mybucket', CreateBucketConfiguration={'LocationConstraint': 'eu-west-1'})
    print(result)

    print s3.list_buckets()
if __name__ == '__main__':
    testit()
```

Resolving patch:
diff --git a/moto/s3/exceptions.py b/moto/s3/exceptions.py
--- a/moto/s3/exceptions.py
+++ b/moto/s3/exceptions.py
@@ -63,6 +63,8 @@ class BucketAlreadyExists(BucketError):
     code = 409
 
     def __init__(self, *args, **kwargs):
+        kwargs.setdefault("template", "bucket_error")
+        self.templates["bucket_error"] = ERROR_WITH_BUCKET_NAME
         super(BucketAlreadyExists, self).__init__(
             "BucketAlreadyExists",
             (
diff --git a/moto/s3/responses.py b/moto/s3/responses.py
--- a/moto/s3/responses.py
+++ b/moto/s3/responses.py
@@ -811,11 +811,16 @@ def _bucket_response_put(
             try:
                 new_bucket = self.backend.create_bucket(bucket_name, region_name)
             except BucketAlreadyExists:
-                if region_name == DEFAULT_REGION_NAME:
-                    # us-east-1 has different behavior
-                    new_bucket = self.backend.get_bucket(bucket_name)
+                new_bucket = self.backend.get_bucket(bucket_name)
+                if (
+                    new_bucket.region_name == DEFAULT_REGION_NAME
+                    and region_name == DEFAULT_REGION_NAME
+                ):
+                    # us-east-1 has different behavior - creating a bucket there is an idempotent operation
+                    pass
                 else:
-                    raise
+                    template = self.response_template(S3_DUPLICATE_BUCKET_ERROR)
+                    return 409, {}, template.render(bucket_name=bucket_name)
 
             if "x-amz-acl" in request.headers:
                 # TODO: Support the XML-based ACL format
@@ -2662,3 +2667,13 @@ def _invalid_headers(self, url, headers):
     #</Rule>
 </ObjectLockConfiguration>
 """
+
+S3_DUPLICATE_BUCKET_ERROR = """<?xml version="1.0" encoding="UTF-8"?>
+<Error>
+  <Code>BucketAlreadyOwnedByYou</Code>
+  <Message>Your previous request to create the named bucket succeeded and you already own it.</Message>
+  <BucketName>{{ bucket_name }}</BucketName>
+  <RequestId>44425877V1D0A2F9</RequestId>
+  <HostId>9Gjjt1m+cjU4OPvX9O9/8RuvnG41MRb/18Oux2o5H5MY7ISNTlXN+Dz9IG62/ILVxhAGI0qyPfg=</HostId>
+</Error>
+"""


Test patch:
diff --git a/tests/test_s3/test_s3.py b/tests/test_s3/test_s3.py
--- a/tests/test_s3/test_s3.py
+++ b/tests/test_s3/test_s3.py
@@ -2106,19 +2106,6 @@ def test_boto3_bucket_create():
     )
 
 
-@mock_s3
-def test_bucket_create_duplicate():
-    s3 = boto3.resource("s3", region_name="us-west-2")
-    s3.create_bucket(
-        Bucket="blah", CreateBucketConfiguration={"LocationConstraint": "us-west-2"}
-    )
-    with pytest.raises(ClientError) as exc:
-        s3.create_bucket(
-            Bucket="blah", CreateBucketConfiguration={"LocationConstraint": "us-west-2"}
-        )
-    exc.value.response["Error"]["Code"].should.equal("BucketAlreadyExists")
-
-
 @mock_s3
 def test_bucket_create_force_us_east_1():
     s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME)
@@ -5353,3 +5340,74 @@ def test_get_object_versions_with_prefix():
     versions = s3_client.list_object_versions(Bucket=bucket_name, Prefix="file")
     versions["Versions"].should.have.length_of(3)
     versions["Prefix"].should.equal("file")
+
+
+@mock_s3
+def test_create_bucket_duplicate():
+    bucket_name = "same-bucket-test-1371"
+    alternate_region = "eu-north-1"
+    # Create it in the default region
+    default_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
+    default_client.create_bucket(Bucket=bucket_name)
+
+    # Create it again in the same region - should just return that same bucket
+    default_client.create_bucket(Bucket=bucket_name)
+
+    # Create the bucket in a different region - should return an error
+    diff_client = boto3.client("s3", region_name=alternate_region)
+    with pytest.raises(ClientError) as ex:
+        diff_client.create_bucket(
+            Bucket=bucket_name,
+            CreateBucketConfiguration={"LocationConstraint": alternate_region},
+        )
+    err = ex.value.response["Error"]
+    err["Code"].should.equal("BucketAlreadyOwnedByYou")
+    err["Message"].should.equal(
+        "Your previous request to create the named bucket succeeded and you already own it."
+    )
+    err["BucketName"].should.equal(bucket_name)
+
+    # Try this again - but creating the bucket in a non-default region in the first place
+    bucket_name = "same-bucket-nondefault-region-test-1371"
+    diff_client.create_bucket(
+        Bucket=bucket_name,
+        CreateBucketConfiguration={"LocationConstraint": alternate_region},
+    )
+
+    # Recreating the bucket in the same non-default region should fail
+    with pytest.raises(ClientError) as ex:
+        diff_client.create_bucket(
+            Bucket=bucket_name,
+            CreateBucketConfiguration={"LocationConstraint": alternate_region},
+        )
+    err = ex.value.response["Error"]
+    err["Code"].should.equal("BucketAlreadyOwnedByYou")
+    err["Message"].should.equal(
+        "Your previous request to create the named bucket succeeded and you already own it."
+    )
+    err["BucketName"].should.equal(bucket_name)
+
+    # Recreating the bucket in the default region should fail
+    diff_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
+    with pytest.raises(ClientError) as ex:
+        diff_client.create_bucket(Bucket=bucket_name)
+    err = ex.value.response["Error"]
+    err["Code"].should.equal("BucketAlreadyOwnedByYou")
+    err["Message"].should.equal(
+        "Your previous request to create the named bucket succeeded and you already own it."
+    )
+    err["BucketName"].should.equal(bucket_name)
+
+    # Recreating the bucket in a third region should fail
+    diff_client = boto3.client("s3", region_name="ap-northeast-1")
+    with pytest.raises(ClientError) as ex:
+        diff_client.create_bucket(
+            Bucket=bucket_name,
+            CreateBucketConfiguration={"LocationConstraint": "ap-northeast-1"},
+        )
+    err = ex.value.response["Error"]
+    err["Code"].should.equal("BucketAlreadyOwnedByYou")
+    err["Message"].should.equal(
+        "Your previous request to create the named bucket succeeded and you already own it."
+    )
+    err["BucketName"].should.equal(bucket_name)